def test_plugin_client_req_fields(txn_pool_node_set_post_creation, looper, stewardWallet, steward1, sdk_wallet_steward, sdk_pool_handle): """ Test that plugin's addition of request fields and their validation is successful """ op = {TXN_TYPE: GET_BAL, DATA: {'id': '123'}} # Valid field value results in successful processing req_obj = sdk_gen_request( op, identifier=sdk_wallet_steward[1], fix_length_dummy=randomString(dummy_field_length)) req = sdk_sign_and_submit_req_obj(looper, sdk_pool_handle, sdk_wallet_steward, req_obj) sdk_get_reply(looper, req) # Invalid field value results in proper failure req = Request(operation=op, reqId=Request.gen_req_id(), protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=stewardWallet.defaultId, fix_length_dummy=randomString(dummy_field_length + 1)) steward1.submitReqs(req) for node in txn_pool_node_set_post_creation: looper.run( eventually(checkReqNackWithReason, steward1, 'should have length', node.clientstack.name, retryWait=1))
def sign_using_output(self, id, seq_no, op: Dict = None, request: Request = None): assert lxor(op, request) if op: request = Request(reqId=Request.gen_req_id(), operation=op, protocolVersion=CURRENT_PROTOCOL_VERSION) # existing_inputs = request.operation.get(INPUTS, []) # request.operation[INPUTS] = [[id, seq_no], ] # payload = deepcopy(request.signingState(id)) # # TEMPORARY # payload[OPERATION].pop(SIGS) # payload.pop(f.IDENTIFIER.nm) # # signature = self.addresses[id].signer.sign(payload) # request.operation[INPUTS] = existing_inputs + [[id, seq_no], ] # TODO: Account for `extra` field payload = [[ { "address": id, "seqNo": seq_no }, ], request.operation[OUTPUTS]] signature = self.addresses[id].signer.sign(payload) request.operation[INPUTS] = request.operation.get(INPUTS, []) + [ { "address": id, "seqNo": seq_no }, ] request.operation[SIGS].append(signature) return request
def signRequest(self, req: Request, identifier: Identifier = None) -> Request: """ Signs request. Modifies reqId and signature. May modify identifier. :param req: request :param requestIdStore: request id generator :param identifier: signer identifier :return: signed request """ idr = self.requiredIdr(idr=identifier or req._identifier) # idData = self._getIdData(idr) req._identifier = idr req.reqId = req.gen_req_id() # req.digest = req.getDigest() # QUESTION: `self.ids[idr]` would be overwritten if same identifier # is used to send 2 requests, why is `IdData` persisted? # self.ids[idr] = IdData(idData.signer, req.reqId) req.signature = self.signMsg(msg=req.signingState(identifier=idr), identifier=idr, otherIdentifier=req.identifier) return req
def _create_request(self, payload, identifier=None): return Request( reqId=Request.gen_req_id(), operation=payload, protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=identifier )
def test_get_txn_response_as_expected(looper, steward1, stewardWallet): req, wallet = sendAddNewClient(STEWARD, "name", steward1, stewardWallet) timeout = waits.expectedTransactionExecutionTime(len( steward1.inBox)) + c_delay nym_response = \ looper.run(eventually(check_sufficient_replies_received, steward1, req.identifier, req.reqId, retryWait=1, timeout=timeout)) op = { TXN_TYPE: GET_TXN, f.LEDGER_ID.nm: DOMAIN_LEDGER_ID, DATA: nym_response['seqNo'] } req = Request(identifier=stewardWallet.defaultId, operation=op, reqId=Request.gen_req_id(), protocolVersion=CURRENT_PROTOCOL_VERSION) steward1.submitReqs(req) get_txn_response = \ looper.run(eventually(check_sufficient_replies_received, steward1, req.identifier, req.reqId, retryWait=1, timeout=timeout)) nym_response.pop('txnTime', None) get_txn_response[DATA].pop('txnTime', None) assert nym_response == get_txn_response[DATA]
def signRequest(self, req: Request, identifier: Identifier=None) -> Request: """ Signs request. Modifies reqId and signature. May modify identifier. :param req: request :param requestIdStore: request id generator :param identifier: signer identifier :return: signed request """ idr = self.requiredIdr(idr=identifier or req._identifier) # idData = self._getIdData(idr) req._identifier = idr req.reqId = req.gen_req_id() # req.digest = req.getDigest() # QUESTION: `self.ids[idr]` would be overwritten if same identifier # is used to send 2 requests, why is `IdData` persisted? # self.ids[idr] = IdData(idData.signer, req.reqId) req.signature = self.signMsg(msg=req.signingState(identifier=idr), identifier=idr, otherIdentifier=req.identifier) return req
def test_get_txn_for_invalid_seq_no(looper, txnPoolNodeSet, steward1, stewardWallet): op = {TXN_TYPE: GET_TXN, f.LEDGER_ID.nm: DOMAIN_LEDGER_ID, DATA: -23} req = Request(identifier=stewardWallet.defaultId, operation=op, reqId=Request.gen_req_id(), protocolVersion=CURRENT_PROTOCOL_VERSION) steward1.submitReqs(req) for node in txnPoolNodeSet: waitReqNackWithReason(looper, steward1, 'cannot be smaller', node.clientstack.name)
def test_get_txn_for_invalid_ledger_id(looper, txnPoolNodeSet, steward1, stewardWallet): op = {TXN_TYPE: GET_TXN, f.LEDGER_ID.nm: 5908, DATA: 1} req = Request(identifier=stewardWallet.defaultId, operation=op, reqId=Request.gen_req_id(), protocolVersion=CURRENT_PROTOCOL_VERSION) steward1.submitReqs(req) for node in txnPoolNodeSet: waitReqNackWithReason(looper, steward1, 'expected one of', node.clientstack.name)
def sign_using_multi_sig(self, op: Dict=None, request: Request=None, identifier=None) -> Request: # One and only 1 of `op` and `request` must be provided. # If `request` is provided it must have `reqId` assert lxor(op, request) identifier = identifier or self.defaultId if op: request = Request(reqId=Request.gen_req_id(), operation=op, protocolVersion=CURRENT_PROTOCOL_VERSION) self.do_multi_sig_on_req(request, identifier) return request
def sign_using_multi_sig(self, op: Dict=None, request: Request=None, identifier=None) -> Request: # One and only 1 of `op` and `request` must be provided. # If `request` is provided it must have `reqId` assert lxor(op, request) identifier = identifier or self.defaultId if op: request = Request(reqId=Request.gen_req_id(), operation=op, protocolVersion=CURRENT_PROTOCOL_VERSION) self.do_multi_sig_on_req(request, identifier) return request
def testNodeDiscardMessageFromUnknownView(txnPoolNodeSet, nodeSetWithNodeAddedAfterSomeTxns, newNodeCaughtUp, tdirWithPoolTxns, tconf, allPluginsPath): """ Node discards 3-phase or ViewChangeDone messages from view nos that it does not know of (view nos before it joined the pool) :return: """ looper, nodeX, client, wallet, _, _ = nodeSetWithNodeAddedAfterSomeTxns viewNo = nodeX.viewNo # Force two view changes: node discards msgs which have viewNo # at least two less than node's. Current protocol implementation # needs to hold messages from the previous view as well as # from the current view. for i in range(2): ensure_view_change(looper, txnPoolNodeSet) waitNodeDataEquality(looper, nodeX, *txnPoolNodeSet[:-1]) checkProtocolInstanceSetup(looper, txnPoolNodeSet, retryWait=1) sender = txnPoolNodeSet[0] rid_x_node = sender.nodestack.getRemote(nodeX.name).uid messageTimeout = waits.expectedNodeToNodeMessageDeliveryTime() # 3 pc msg (PrePrepare) needs to be discarded primaryRepl = getPrimaryReplica(txnPoolNodeSet) three_pc = PrePrepare( 0, viewNo, 10, get_utc_epoch(), [[wallet.defaultId, Request.gen_req_id()]], 1, "random digest", DOMAIN_LEDGER_ID, primaryRepl.stateRootHash(DOMAIN_LEDGER_ID), primaryRepl.txnRootHash(DOMAIN_LEDGER_ID), ) sender.send(three_pc, rid_x_node) looper.run( eventually(checkDiscardMsg, [ nodeX, ], three_pc, 'un-acceptable viewNo', retryWait=1, timeout=messageTimeout))
def chk(): nonlocal op req = Request(identifier=stewardWallet.defaultId, operation=op, reqId=Request.gen_req_id(), protocolVersion=CURRENT_PROTOCOL_VERSION) steward1.submitReqs(req) timeout = waits.expectedTransactionExecutionTime(len( steward1.inBox)) + c_delay get_txn_response = \ looper.run(eventually(check_sufficient_replies_received, steward1, req.identifier, req.reqId, retryWait=1, timeout=timeout)) assert get_txn_response[DATA]
def test_wallet_multisig(): wallet = Wallet() idr1, signer1 = wallet.addIdentifier() idr2, signer2 = wallet.addIdentifier() idr3, signer3 = wallet.addIdentifier() authnr = CoreAuthNr() for idr, signer in [(idr1, signer1), (idr2, signer2), (idr3, signer3)]: authnr.addIdr(idr, signer.verkey) def serz(req): return { k: v for k, v in req.as_dict.items() if k not in authnr.excluded_from_signing } op = randomOperation() request = Request(reqId=Request.gen_req_id(), operation=op, protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=idr1) req = wallet.sign_using_multi_sig(request=request, identifier=idr1) assert len(req.signatures) == 1 req_data = serz(req) assert set(authnr.authenticate_multi(req_data, req.signatures, 1)) == { idr1, } with pytest.raises(InsufficientSignatures): authnr.authenticate_multi(req_data, req.signatures, 2) req = wallet.sign_using_multi_sig(request=req, identifier=idr2) assert len(req.signatures) == 2 req_data = serz(req) assert set(authnr.authenticate_multi(req_data, req.signatures, 2)) == {idr1, idr2} with pytest.raises(InsufficientSignatures): authnr.authenticate_multi(req_data, req.signatures, 3) wallet.do_multi_sig_on_req(req, identifier=idr3) assert len(req.signatures) == 3 req_data = serz(req) assert set(authnr.authenticate_multi(req_data, req.signatures, 3)) == {idr1, idr2, idr3}
def test_get_txn_for_non_existing_seq_no(looper, steward1, stewardWallet): op = { TXN_TYPE: GET_TXN, f.LEDGER_ID.nm: DOMAIN_LEDGER_ID, DATA: randint(100, 1000) } req = Request(identifier=stewardWallet.defaultId, operation=op, reqId=Request.gen_req_id(), protocolVersion=CURRENT_PROTOCOL_VERSION) steward1.submitReqs(req) timeout = waits.expectedTransactionExecutionTime(len( steward1.inBox)) + c_delay get_txn_response = \ looper.run(eventually(check_sufficient_replies_received, steward1, req.identifier, req.reqId, retryWait=1, timeout=timeout)) assert not get_txn_response[DATA]
def build_promote_node_back_req(node_name, txn): txn_data = get_payload_data(txn) target_nym = txn_data[TARGET_NYM] txn_data = txn_data['data'] operation = { TYPE: NODE, DATA: { ALIAS: node_name, CLIENT_IP: txn_data[CLIENT_IP], CLIENT_PORT: txn_data[CLIENT_PORT], NODE_IP: txn_data[NODE_IP], NODE_PORT: txn_data[NODE_PORT], SERVICES: [VALIDATOR], }, TARGET_NYM: target_nym } return Request(operation=operation, reqId=Request.gen_req_id(), protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=get_from(txn))