def two_requests(looper, sdk_wallet_steward): wh, did = sdk_wallet_steward op = {TXN_TYPE: AUCTION_START, DATA: {'id': 'xyz'}} req1 = sdk_gen_request(op, protocol_version=CURRENT_PROTOCOL_VERSION, identifier=did).as_dict field = list(PLUGIN_CLIENT_REQUEST_FIELDS.keys())[0] req1[field] = 'x' * 10 req2 = copy.deepcopy(req1) req2[field] = 'z' * 10 req1 = sdk_multisign_request_object(looper, sdk_wallet_steward, json.dumps(req1)) req_obj1 = Request(**json.loads(req1)) req2 = sdk_multisign_request_object(looper, sdk_wallet_steward, json.dumps(req2)) req_obj2 = Request(**json.loads(req2)) assert req_obj1.payload_digest == req_obj2.payload_digest assert req_obj1.digest != req_obj2.digest return req1, req2
def test_static_validation(get_txn_author_agreement_aml_handler): request = Request(operation={TXN_TYPE: GET_TXN_AUTHOR_AGREEMENT_AML, GET_TXN_AUTHOR_AGREEMENT_AML_VERSION: "VERSION"}) get_txn_author_agreement_aml_handler.static_validation(request) request = Request(operation={TXN_TYPE: GET_TXN_AUTHOR_AGREEMENT_AML, GET_TXN_AUTHOR_AGREEMENT_AML_TIMESTAMP: 1559299045}) get_txn_author_agreement_aml_handler.static_validation(request)
def two_requests(looper, op, sdk_wallet_stewards): wh, did = sdk_wallet_stewards[0] req = json.dumps(sdk_gen_request(op, protocol_version=CURRENT_PROTOCOL_VERSION, identifier=did).as_dict) req1 = sdk_multisign_request_object(looper, sdk_wallet_stewards[0], req) req_obj1 = Request(**json.loads(req1)) req2 = sdk_multisign_request_object(looper, sdk_wallet_stewards[1], req1) req_obj2 = Request(**json.loads(req2)) assert req_obj1.payload_digest == req_obj2.payload_digest assert req_obj1.digest != req_obj2.digest return req1, req2
def testSendGetTxnReqSameAsExpected(looper, steward1, stewardWallet): req, wallet = sendAddNewClient(STEWARD, "name", steward1, stewardWallet) timeout = waits.expectedTransactionExecutionTime(len( steward1.inBox)) + c_delay nym_response = looper.run( eventually(checkSufficientRepliesReceived, steward1.inBox, req.reqId, fValue, retryWait=1, timeout=timeout)) op = {TXN_TYPE: GET_TXN, DATA: nym_response['seqNo']} req = Request(identifier=stewardWallet.defaultId, operation=op, reqId=getTimeBasedId()) steward1.submitReqs(req) get_txn_response = looper.run( eventually(checkSufficientRepliesReceived, steward1.inBox, req.reqId, fValue, retryWait=1, timeout=timeout)) get_txn_response = json.loads(get_txn_response[DATA]) del nym_response['txnTime'] del get_txn_response['txnTime'] assert nym_response == get_txn_response
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 reqToTxn(req): """ Transform a client request such that it can be stored in the ledger. Also this is what will be returned to the client in the reply :param req: :return: """ if isinstance(req, str): req = json.loads(req) if isinstance(req, dict): req = Request(identifier=req.get(f.IDENTIFIER.nm, None), reqId=req.get(f.REQ_ID.nm, None), operation=req.get(OPERATION, None), signature=req.get(f.SIG.nm, None), signatures=req.get(f.SIGS.nm, None), protocolVersion=req.get(f.PROTOCOL_VERSION.nm, None)) if isinstance(req, Request): req_data = req.as_dict req_data[f.DIGEST.nm] = req.digest else: raise TypeError("Expected dict or str as input, but got: {}".format( type(req))) req_data = deepcopy(req_data) return do_req_to_txn(req_data=req_data, req_op=req_data[OPERATION])
def test_static_validation_pass_context_w3c_example_15(): context = { "@context": { "referenceNumber": "https://example.com/vocab#referenceNumber", "favoriteFood": "https://example.com/vocab#favoriteFood" } } operation = { META: { "name": "TestContext", "version": 1, "type": CONTEXT_TYPE }, DATA: { CONTEXT_CONTEXT: context }, RS_TYPE: "200" } req = Request( "test", 1, operation, "sig", ) ch = ContextHandler(None, None) ch.static_validation(req)
def test_future_primaries_replicas_decrease(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_stewards, tdir, tconf, allPluginsPath): assert len(txnPoolNodeSet) == 7 initial_primaries = copy.copy(txnPoolNodeSet[0].primaries) last_ordered = txnPoolNodeSet[0].master_replica.last_ordered_3pc starting_view_number = checkViewNoForNodes(txnPoolNodeSet) # Decrease replicas count demote_node(looper, sdk_wallet_stewards[-1], sdk_pool_handle, txnPoolNodeSet[-2]) txnPoolNodeSet.remove(txnPoolNodeSet[-2]) ensureElectionsDone(looper=looper, nodes=txnPoolNodeSet) new_view_no = checkViewNoForNodes(txnPoolNodeSet) assert new_view_no == starting_view_number + 1 node = txnPoolNodeSet[0] with delay_rules(node.nodeIbStasher, cDelay()): req = sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_stewards[0], 1)[0][0] req = Request(**req) three_pc_batch = ThreePcBatch(DOMAIN_LEDGER_ID, 0, 0, 1, time.time(), randomString(), randomString(), ['a', 'b', 'c'], [req.digest], pp_digest='') primaries = node.write_manager.future_primary_handler.post_batch_applied(three_pc_batch) assert len(primaries) + 1 == len(initial_primaries) assert len(primaries) == len(txnPoolNodeSet[0].primaries) for node in txnPoolNodeSet: node.write_manager.future_primary_handler.commit_batch = old_commit
def sdk_gen_request(operation, protocol_version=CURRENT_PROTOCOL_VERSION, identifier=None): return Request(operation=operation, reqId=random.randint(10, 100000), protocolVersion=protocol_version, identifier=identifier)
def _create_request(self, payload, identifier=None): return Request( reqId=Request.gen_req_id(), operation=payload, protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=identifier )
def sdk_gen_request(operation, protocol_version=CURRENT_PROTOCOL_VERSION, identifier=None, **kwargs): # Question: Why this method is called sdk_gen_request? It does not use # the indy-sdk return Request(operation=operation, reqId=random.randint(10, 100000), protocolVersion=protocol_version, identifier=identifier, **kwargs)
def sdk_sign_request_from_dict(looper, sdk_wallet, op): wallet_h, did = sdk_wallet request = Request(operation=op, reqId=random.randint(10, 100000), protocolVersion=CURRENT_PROTOCOL_VERSION, identifier=did) req_str = json.dumps(request.as_dict) resp = looper.loop.run_until_complete(sign_request(wallet_h, did, req_str)) return json.loads(resp)
def aml_request(txn_author_agreement_aml_handler, creator): return Request(identifier=creator, signature="signature", operation={TXN_TYPE: TXN_AUTHOR_AGREEMENT_AML, AML_VERSION: "AML_VERSION", AML: {"test": "test"}, AML_CONTEXT: "AML_CONTEXT"})
def taa_request(creator): return Request(identifier=creator, signature="signature", operation={TXN_TYPE: TXN_AUTHOR_AGREEMENT, TXN_AUTHOR_AGREEMENT_TEXT: "text", TXN_AUTHOR_AGREEMENT_VERSION: "version", TXN_AUTHOR_AGREEMENT_RATIFICATION_TS: 0})
def get_key_from_req(req: dict): return Request(identifier=req[f.IDENTIFIER.nm], reqId=req[f.REQ_ID.nm], operation=req[OPERATION], protocolVersion=req[f.PROTOCOL_VERSION.nm], signature=req.get(f.SIG.nm), taaAcceptance=req.get(f.TAA_ACCEPTANCE)).key
def node(): n = FakeSomething() n.new_future_primaries_needed = False n.requests = { 'a': ReqState( Request( operation={ TARGET_NYM: 'nym7', TXN_TYPE: NODE, DATA: { SERVICES: ['VALIDATOR'], ALIAS: 'n7' } })) } n.nodeReg = {'n1': 1, 'n2': 1, 'n3': 1, 'n4': 1, 'n5': 1, 'n6': 1} n.nodeIds = { 'nym1': 'n1', 'nym2': 'n2', 'nym3': 'n3', 'nym4': 'n4', 'nym5': 'n5', 'nym6': 'n6' } n.primaries = {'n1', 'n2'} n.elector = FakeSomething() n.elector.process_selection = lambda a, b, c: ['n1', 'n2'] return n
def test_taa_acceptance_dynamic_validation(taa_handler, taa_aml_handler, write_manager, taa_aml_request): req = json.loads(taa_aml_request) taa_aml_handler._update_txn_author_agreement_acceptance_mechanisms(req['operation'], 1, 1) taa_aml_handler.authorize = lambda req: 0 with pytest.raises(InvalidClientRequest) as e: write_manager.dynamic_validation(Request(**req), 0) assert e.match('Version of TAA AML must be unique and it cannot be modified')
def auth_rules_request(creator): return Request(identifier=creator, reqId=5, operation={ TXN_TYPE: AUTH_RULES, RULES: [generate_auth_rule()] })
def test_taa_acceptance_static_validation(write_manager, taa_aml_request): taa_aml_request = json.loads(taa_aml_request) taa_aml_request['operation'][AML] = {} with pytest.raises(InvalidClientRequest) as e: write_manager.static_validation(Request(**taa_aml_request)) assert e.match('TXN_AUTHOR_AGREEMENT_AML request must contain at least one acceptance mechanism')
def test_future_primaries_replicas_increase(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_stewards, tdir, tconf, allPluginsPath): # Don't delete NodeStates, so we could check them. global old_commit old_commit = txnPoolNodeSet[0].write_manager.future_primary_handler.commit_batch for node in txnPoolNodeSet: node.write_manager.future_primary_handler.commit_batch = lambda three_pc_batch, prev_handler_result=None: 0 initial_primaries = copy.copy(txnPoolNodeSet[0].primaries) last_ordered = txnPoolNodeSet[0].master_replica.last_ordered_3pc starting_view_number = checkViewNoForNodes(txnPoolNodeSet) # Increase replicas count add_new_node(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_stewards[0], tdir, tconf, allPluginsPath) new_view_no = checkViewNoForNodes(txnPoolNodeSet) assert new_view_no == starting_view_number + 1 # "seq_no + 2" because 1 domain and 1 pool txn. node = txnPoolNodeSet[0] with delay_rules(node.nodeIbStasher, cDelay()): req = sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_stewards[0], 1)[0][0] req = Request(**req) three_pc_batch = ThreePcBatch(DOMAIN_LEDGER_ID, 0, 0, 1, time.time(), randomString(), randomString(), ['a', 'b', 'c'], [req.digest], pp_digest='') primaries = node.write_manager.future_primary_handler.post_batch_applied(three_pc_batch) assert len(primaries) == len(initial_primaries) + 1 assert len(primaries) == len(node.primaries)
def taa_disable_request(tconf, domain_state): identifier = "identifier" update_nym(domain_state, identifier, TRUSTEE) operation = {TXN_TYPE: TXN_AUTHOR_AGREEMENT_DISABLE} return Request(identifier=identifier, signature="sign", operation=operation)
def get_auth_rule_request(creator): return Request(identifier=creator, reqId=5, operation={ TXN_TYPE: GET_AUTH_RULE, **generate_key() })
def node(): n = FakeSomething() n.new_future_primaries_needed = False n.requests = { 'a': ReqState( Request( operation={ TARGET_NYM: 'nym7', TXN_TYPE: NODE, DATA: { SERVICES: ['VALIDATOR'], ALIAS: 'n7' } })) } n.nodeReg = {'n1': 1, 'n2': 1, 'n3': 1, 'n4': 1, 'n5': 1, 'n6': 1} n.primaries = ['n1', 'n2'] n.nodeIds = n.nodeReg n.primaries_selector = FakeSomething() n.primaries_selector.select_primaries = lambda view_no, instance_count, validators: [ 'n1', 'n2' ] n.viewNo = 0 return n
def test_static_validation_fail_context_is_list_with_dict_and_bad_uri(): context = [{ "favoriteColor": "https://example.com/vocab#favoriteColor" }, "this is a bad uri"] operation = { META: { "name": "TestContext", "version": 1, "type": CONTEXT_TYPE }, DATA: { CONTEXT_CONTEXT: context }, RS_TYPE: "200" } req = Request( "test", 1, operation, "sig", ) ch = ContextHandler(None, None) with pytest.raises(InvalidClientRequest) as e: ch.static_validation(req) assert "@context URI this is a bad uri badly formed" in str(e.value)
def testSendGetTxnReqSameAsExpected(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, DATA: nym_response['seqNo'] } req = Request(identifier=stewardWallet.defaultId, operation=op, reqId=getTimeBasedId(), 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 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 revoc_reg_entry_request(): return Request(identifier=randomString(), reqId=5, operation={ 'type': REVOC_REG_ENTRY, REVOC_REG_DEF_ID: 'sample' })
def test_suspicious_primary_send_same_request_with_same_signatures( looper, txnPoolNodeSet, sdk_pool_handle, two_requests, sdk_wallet_stewards, tconf): couple = sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_stewards[0], 1)[0] req = Request(**couple[0]) replica = getPrimaryReplica(txnPoolNodeSet) replica._ordering_service._do_dynamic_validation = types.MethodType( malicious_dynamic_validation, replica.node) txnPoolNodeSet.remove(replica.node) old_reverts = {} for i, node in enumerate(txnPoolNodeSet): old_reverts[i] = node.master_replica._ordering_service.spylog.count( OrderingService._revert) node.seqNoDB._keyValueStorage.remove(req.digest) node.seqNoDB._keyValueStorage.remove(req.payload_digest) ppReq = replica._ordering_service.create_3pc_batch(DOMAIN_LEDGER_ID) ppReq._fields['reqIdr'] = [req.digest, req.digest] replica._ordering_service.send_pre_prepare(ppReq) def reverts(): for i, node in enumerate(txnPoolNodeSet): assert old_reverts[ i] + 1 == node.master_replica._ordering_service.spylog.count( OrderingService._revert) looper.run(eventually(reverts))
def test_replica_removing_in_ordering(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, chkFreqPatched, view_change): """ 1. Start ordering (send pre-prepares on backup) 2. Remove replica 3. Finish ordering 4. Check monitor and replicas count """ node = txnPoolNodeSet[0] start_replicas_count = node.replicas.num_replicas instance_id = start_replicas_count - 1 stashers = [n.nodeIbStasher for n in txnPoolNodeSet] with delay_rules(stashers, cDelay(delay=sys.maxsize)): req = sdk_send_random_requests(looper, sdk_pool_handle, sdk_wallet_client, 1) def chk(): assert len(node.requests) > 0 looper.run(eventually(chk)) digest = Request(**req[0][0]).digest old_forwarded_to = node.requests[digest].forwardedTo node.replicas.remove_replica(instance_id) assert old_forwarded_to - 1 == node.requests[digest].forwardedTo sdk_get_replies(looper, req) looper.run(eventually(check_checkpoint_finalize, txnPoolNodeSet)) _check_replica_removed(node, start_replicas_count, instance_id) assert not node.monitor.isMasterDegraded() assert len(node.requests) == 0
def test_parts_of_nodes_have_same_request_with_different_signatures( looper, txnPoolNodeSet, sdk_pool_handle, two_requests, sdk_wallet_stewards, tconf): req1s, req2s = two_requests req1 = Request(**json.loads(req1s)) req2 = Request(**json.loads(req2s)) lo_before = (txnPoolNodeSet[0].replicas[0].last_ordered_3pc[1], txnPoolNodeSet[0].replicas[1].last_ordered_3pc[1]) for node in txnPoolNodeSet[0:2]: req_state = node.requests.add(req1) req_state.propagates['Alpha'] = req1 req_state.propagates['Beta'] = req1 req_state.propagates['Gamma'] = req1 req_state.propagates['Delta'] = req1 node.tryForwarding(req1) assert node.requests[req1.key].forwarded for node in txnPoolNodeSet[2:4]: req_state = node.requests.add(req2) req_state.propagates['Alpha'] = req2 req_state.propagates['Beta'] = req2 req_state.propagates['Gamma'] = req2 req_state.propagates['Delta'] = req2 node.tryForwarding(req2) assert node.requests[req2.key].forwarded looper.run(eventually(wait_one_batch, txnPoolNodeSet[0], lo_before)) for node in txnPoolNodeSet[0:2]: assert node.spylog.count(node.request_propagates) == 0 for node in txnPoolNodeSet[2:4]: assert node.spylog.count(node.request_propagates) >= 1 node.spylog.getAll(node.request_propagates) req1s = sdk_send_signed_requests(sdk_pool_handle, [req1s]) sdk_get_and_check_replies(looper, req1s) req2s = sdk_send_signed_requests(sdk_pool_handle, [req2s]) with pytest.raises(RequestNackedException) as e: sdk_get_and_check_replies(looper, req2s) e.match( 'Same txn was already ordered with different signatures or pluggable fields' ) ensure_all_nodes_have_same_data(looper, txnPoolNodeSet)