def test_hook_pre_send_reply(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): def hook_add_field(*args, **kwargs): kwargs['committed_txns'][0][foo] = foo register_hook(txnPoolNodeSet, NodeHooks.PRE_SEND_REPLY, hook_add_field) # Reply on request signed_reqs = sdk_signed_random_requests(looper, sdk_wallet_client, 1) reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) reply = sdk_get_and_check_replies(looper, reqs)[0] assert foo in reply[1][f.RESULT.nm] assert reply[1][f.RESULT.nm][foo] == foo # Reply on repeated request reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) reply = sdk_get_and_check_replies(looper, reqs)[0] assert foo in reply[1][f.RESULT.nm] assert reply[1][f.RESULT.nm][foo] == foo # Reply on get_txn request _, did = sdk_wallet_client request = sdk_build_get_txn_request( looper, did, reply[1][f.RESULT.nm][TXN_METADATA][f.SEQ_NO.nm]) request_couple = sdk_sign_and_send_prepared_request(looper, sdk_wallet_client, sdk_pool_handle, request) reply = sdk_get_and_check_replies(looper, [request_couple])[0] assert foo in reply[1][f.RESULT.nm]['data'] assert reply[1][f.RESULT.nm]['data'][foo] == foo
def test_hook_pre_send_reply(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): def hook_add_field(*args, **kwargs): kwargs['committed_txns'][0][foo] = foo register_hook(txnPoolNodeSet, NodeHooks.PRE_SEND_REPLY, hook_add_field) # Reply on request signed_reqs = sdk_signed_random_requests(looper, sdk_wallet_client, 1) reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) reply = sdk_get_and_check_replies(looper, reqs)[0] assert foo in reply[1][f.RESULT.nm] assert reply[1][f.RESULT.nm][foo] == foo # Reply on repeated request reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) reply = sdk_get_and_check_replies(looper, reqs)[0] assert foo in reply[1][f.RESULT.nm] assert reply[1][f.RESULT.nm][foo] == foo # Reply on get_txn request _, did = sdk_wallet_client request = sdk_build_get_txn_request( looper, did, reply[1][f.RESULT.nm][TXN_METADATA][f.SEQ_NO.nm]) request_couple = sdk_sign_and_send_prepared_request( looper, sdk_wallet_client, sdk_pool_handle, request) reply = sdk_get_and_check_replies(looper, [request_couple])[0] assert foo in reply[1][f.RESULT.nm]['data'] assert reply[1][f.RESULT.nm]['data'][foo] == foo
def test_both_author_and_endorser_must_sign(looper, sdk_pool_handle, sdk_wallet_trustee, sdk_wallet_endorser): ''' Both author and endorser must sign the request even if the author can send the request without Endorser ''' req_json = sdk_build_schema_request(looper, sdk_wallet_trustee, ["attr1", "attr2"], "name1", "2.0") req_json = sdk_append_request_endorser(looper, req_json, sdk_wallet_endorser[1]) # sign by Author only req_json_author_only = sdk_multisign_request_object(looper, sdk_wallet_trustee, req_json) with pytest.raises(RequestNackedException): request_couple = sdk_send_signed_requests(sdk_pool_handle, [req_json_author_only])[0] sdk_get_and_check_replies(looper, [request_couple]) # sign by Endorser only req_json_endorser_only = sdk_multisign_request_object(looper, sdk_wallet_endorser, req_json) with pytest.raises(RequestNackedException): request_couple = sdk_send_signed_requests(sdk_pool_handle, [req_json_endorser_only])[0] sdk_get_and_check_replies(looper, [request_couple]) # sign by both req_json_both = sdk_multisign_request_object(looper, sdk_wallet_trustee, req_json) req_json_both = sdk_multisign_request_object(looper, sdk_wallet_endorser, req_json_both) request_couple = sdk_send_signed_requests(sdk_pool_handle, [req_json_both])[0] sdk_get_and_check_replies(looper, [request_couple])
def test_revert_works_for_fees_before_catch_up_on_all_nodes( looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, sdk_wallet_trustee, fees_set, address_main, mint_tokens): node_set = [n.nodeIbStasher for n in nodeSetWithIntegratedTokenPlugin] with delay_rules(node_set, cDelay()): request = helpers.request.nym() request = add_fees_request_with_address(helpers, fees_set, request, address_main) for n in nodeSetWithIntegratedTokenPlugin: looper.run( eventually(check_state, n, True, retryWait=0.2, timeout=15)) sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request.as_dict)]) for n in nodeSetWithIntegratedTokenPlugin: looper.run( eventually(check_state, n, False, retryWait=0.2, timeout=15)) for n in nodeSetWithIntegratedTokenPlugin: n.start_catchup() for n in nodeSetWithIntegratedTokenPlugin: looper.run( eventually(lambda: assertExp(n.mode == Mode.participating))) for n in nodeSetWithIntegratedTokenPlugin: looper.run( eventually(check_state, n, True, retryWait=0.2, timeout=15)) ensure_all_nodes_have_same_data(looper, nodeSetWithIntegratedTokenPlugin)
def test_apply_several_batches(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, address_main, mint_tokens): node_set = [n.nodeIbStasher for n in nodeSetWithIntegratedTokenPlugin] amount = get_amount_from_token_txn(mint_tokens) init_seq_no = 1 request1, request2 = nyms_with_fees(2, helpers, fees_set, address_main, amount, init_seq_no=init_seq_no) expected_txns_length = 2 txns_count_before = get_committed_txns_count_for_pool( nodeSetWithIntegratedTokenPlugin, TOKEN_LEDGER_ID) with delay_rules(node_set, cDelay()): r1 = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request1.as_dict)]) r2 = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request2.as_dict)]) for n in nodeSetWithIntegratedTokenPlugin: looper.run( eventually(check_uncommitted_txn, n, expected_txns_length, TOKEN_LEDGER_ID, retryWait=0.2, timeout=15)) sdk_get_and_check_replies(looper, r1) sdk_get_and_check_replies(looper, r2) txns_count_after = get_committed_txns_count_for_pool( nodeSetWithIntegratedTokenPlugin, TOKEN_LEDGER_ID) assert txns_count_after - txns_count_before == expected_txns_length
def test_multiple_batches_for_pool(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, address_main, mint_tokens): node_set = nodeSetWithIntegratedTokenPlugin node_stashers = [n.nodeIbStasher for n in node_set] amount = get_amount_from_token_txn(mint_tokens) init_seq_no = 1 request1, request2 = nyms_with_fees(2, helpers, fees_set, address_main, amount, init_seq_no=init_seq_no) txns_count_before = get_committed_txns_count_for_pool( node_set, TOKEN_LEDGER_ID) with delay_rules(node_stashers, cDelay()): r1 = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request1.as_dict)]) looper.runFor(waits.expectedPrePrepareTime(len(node_set))) r2 = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request2.as_dict)]) looper.runFor(waits.expectedPrePrepareTime(len(node_set))) for n in node_set: n.start_catchup() for n in node_set: looper.run( eventually(lambda: assertExp(n.mode == Mode.participating))) txns_count_after = get_committed_txns_count_for_pool( node_set, TOKEN_LEDGER_ID) assert txns_count_after == txns_count_before ensure_all_nodes_have_same_data(looper, node_set)
def test_belated_request_not_processed_if_already_in_3pc_process( looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): delta = txnPoolNodeSet[3] initial_ledger_size = delta.domainLedger.size delta.clientIbStasher.delay(req_delay(300)) for node in txnPoolNodeSet: node.nodeIbStasher.delay(cDelay(300)) one_req = sdk_signed_random_requests(looper, sdk_wallet_client, 1) sdk_send_signed_requests(sdk_pool_handle, one_req) looper.runFor( waits.expectedPropagateTime(len(txnPoolNodeSet)) + waits.expectedPrePrepareTime(len(txnPoolNodeSet)) + waits.expectedPrepareTime(len(txnPoolNodeSet)) + waits.expectedCommittedTime(len(txnPoolNodeSet))) delta.clientIbStasher.reset_delays_and_process_delayeds() looper.runFor( waits.expectedPropagateTime(len(txnPoolNodeSet)) + waits.expectedPrePrepareTime(len(txnPoolNodeSet)) + waits.expectedPrepareTime(len(txnPoolNodeSet)) + waits.expectedCommittedTime(len(txnPoolNodeSet))) for node in txnPoolNodeSet: node.nodeIbStasher.reset_delays_and_process_delayeds() looper.runFor(waits.expectedOrderingTime(delta.replicas.num_replicas)) for node in txnPoolNodeSet: assert node.domainLedger.size - initial_ledger_size == 1
def test_belated_request_not_processed_if_already_in_3pc_process( looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): delta = txnPoolNodeSet[3] initial_ledger_size = delta.domainLedger.size delta.clientIbStasher.delay(req_delay(300)) for node in txnPoolNodeSet: node.nodeIbStasher.delay(cDelay(300)) one_req = sdk_signed_random_requests(looper, sdk_wallet_client, 1) sdk_send_signed_requests(sdk_pool_handle, one_req) looper.runFor(waits.expectedPropagateTime(len(txnPoolNodeSet)) + waits.expectedPrePrepareTime(len(txnPoolNodeSet)) + waits.expectedPrepareTime(len(txnPoolNodeSet)) + waits.expectedCommittedTime(len(txnPoolNodeSet))) delta.clientIbStasher.reset_delays_and_process_delayeds() looper.runFor(waits.expectedPropagateTime(len(txnPoolNodeSet)) + waits.expectedPrePrepareTime(len(txnPoolNodeSet)) + waits.expectedPrepareTime(len(txnPoolNodeSet)) + waits.expectedCommittedTime(len(txnPoolNodeSet))) for node in txnPoolNodeSet: node.nodeIbStasher.reset_delays_and_process_delayeds() looper.runFor(waits.expectedOrderingTime(delta.replicas.num_replicas)) for node in txnPoolNodeSet: assert node.domainLedger.size - initial_ledger_size == 1
def test_all_replicas_hold_request_keys( perf_chk_patched, looper, txnPoolNodeSet, sdk_wallet_client, sdk_pool_handle): """ All replicas whether primary or non primary hold request keys of forwarded requests. Once requests are ordered, they request keys are removed from replica. """ tconf = perf_chk_patched delay_3pc = 2 delay_3pc_messages(txnPoolNodeSet, 0, delay_3pc) delay_3pc_messages(txnPoolNodeSet, 1, delay_3pc) def chk(count): # All replicas have same amount of forwarded request keys and all keys # are finalised. for node in txnPoolNodeSet: for r in node.replicas.values(): if r.isPrimary is False: assert len(r.requestQueues[DOMAIN_LEDGER_ID]) == count for i in range(count): k = r.requestQueues[DOMAIN_LEDGER_ID][i] assert r.requests[k].finalised elif r.isPrimary is True: assert len(r.requestQueues[DOMAIN_LEDGER_ID]) == 0 reqs = sdk_signed_random_requests(looper, sdk_wallet_client, tconf.Max3PCBatchSize - 1) req_resps = sdk_send_signed_requests(sdk_pool_handle, reqs) # Only non primary replicas should have all request keys with them looper.run(eventually(chk, tconf.Max3PCBatchSize - 1)) sdk_get_replies(looper, req_resps, timeout=sdk_eval_timeout( tconf.Max3PCBatchSize - 1, len(txnPoolNodeSet), add_delay_to_timeout=delay_3pc)) # Replicas should have no request keys with them since they are ordered looper.run(eventually(chk, 0)) # Need to wait since one node might not # have processed it. delay = 1 for node in txnPoolNodeSet: node.nodeIbStasher.delay(nom_delay(delay)) ensure_view_change(looper, txnPoolNodeSet) reqs = sdk_signed_random_requests(looper, sdk_wallet_client, 2 * tconf.Max3PCBatchSize) req_resps = sdk_send_signed_requests(sdk_pool_handle, reqs) looper.run(eventually(chk, 2 * tconf.Max3PCBatchSize)) # Since each nomination is delayed and there will be multiple nominations # so adding some extra time timeout = waits.expectedPoolElectionTimeout(len(txnPoolNodeSet)) + \ len(txnPoolNodeSet) * delay ensureElectionsDone(looper, txnPoolNodeSet, customTimeout=timeout) sdk_get_replies(looper, req_resps, timeout=timeout) looper.run(eventually(chk, 0))
def test_revert_works_for_fees_before_catch_up_on_one_node( looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, address_main, mint_tokens): node_set = nodeSetWithIntegratedTokenPlugin reverted_node = node_set[-1] amount = get_amount_from_token_txn(mint_tokens) init_seq_no = 1 request_1, request_2 = nyms_with_fees(2, helpers, fees_set, address_main, amount, init_seq_no=init_seq_no) c_ledger_root_before = get_committed_txn_root_for_pool([reverted_node], TOKEN_LEDGER_ID) with delay_rules(reverted_node.nodeIbStasher, cDelay()): """ Send NYM with FEES and wait for reply. All of nodes, except reverted_node will order them """ r = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request_1.as_dict)]) sdk_get_and_check_replies(looper, r) check_state(reverted_node, is_equal=False) c_ledger_root_for_other = get_committed_txn_root_for_pool( node_set[:-1], TOKEN_LEDGER_ID) """ Start catchup. Uncommitted batch for reverted_node should be rejected and it will get NYM with FEES during catchup procedure. """ reverted_node.start_catchup() looper.run( eventually( lambda: assertExp(reverted_node.mode == Mode.participating))) check_state(reverted_node, is_equal=True) """ Check, that committed txn root was changed and it's the same as for others """ c_ledger_root_after = get_committed_txn_root_for_pool([reverted_node], TOKEN_LEDGER_ID) assert c_ledger_root_after != c_ledger_root_before assert c_ledger_root_after == c_ledger_root_for_other ensure_all_nodes_have_same_data(looper, node_set) c_ledger_root_before = get_committed_txn_root_for_pool( node_set, TOKEN_LEDGER_ID) """ Send another NYM with FEES and check, that committed ledger's root was changed """ r = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request_2.as_dict)]) sdk_get_and_check_replies(looper, r) c_ledger_root_after = get_committed_txn_root_for_pool( node_set, TOKEN_LEDGER_ID) assert c_ledger_root_after != c_ledger_root_before ensure_all_nodes_have_same_data(looper, node_set) for n in node_set: check_state(n, is_equal=True)
def test_all_replicas_hold_request_keys(perf_chk_patched, looper, txnPoolNodeSet, sdk_wallet_client, sdk_pool_handle): """ All replicas whether primary or non primary hold request keys of forwarded requests. Once requests are ordered, they request keys are removed from replica. """ tconf = perf_chk_patched delay_3pc = 2 delay_3pc_messages(txnPoolNodeSet, 0, delay_3pc) delay_3pc_messages(txnPoolNodeSet, 1, delay_3pc) def chk(count): # All replicas have same amount of forwarded request keys and all keys # are finalised. for node in txnPoolNodeSet: for r in node.replicas.values(): if r.isPrimary is False: assert len(r.requestQueues[DOMAIN_LEDGER_ID]) == count for i in range(count): k = r.requestQueues[DOMAIN_LEDGER_ID][i] assert r.requests[k].finalised elif r.isPrimary is True: assert len(r.requestQueues[DOMAIN_LEDGER_ID]) == 0 reqs = sdk_signed_random_requests(looper, sdk_wallet_client, tconf.Max3PCBatchSize - 1) req_resps = sdk_send_signed_requests(sdk_pool_handle, reqs) # Only non primary replicas should have all request keys with them looper.run(eventually(chk, tconf.Max3PCBatchSize - 1)) sdk_get_replies(looper, req_resps, timeout=sdk_eval_timeout(tconf.Max3PCBatchSize - 1, len(txnPoolNodeSet), add_delay_to_timeout=delay_3pc)) # Replicas should have no request keys with them since they are ordered looper.run(eventually(chk, 0)) # Need to wait since one node might not # have processed it. delay = 1 for node in txnPoolNodeSet: node.nodeIbStasher.delay(nom_delay(delay)) ensure_view_change(looper, txnPoolNodeSet) reqs = sdk_signed_random_requests(looper, sdk_wallet_client, 2 * tconf.Max3PCBatchSize) req_resps = sdk_send_signed_requests(sdk_pool_handle, reqs) looper.run(eventually(chk, 2 * tconf.Max3PCBatchSize)) # Since each nomination is delayed and there will be multiple nominations # so adding some extra time timeout = waits.expectedPoolElectionTimeout(len(txnPoolNodeSet)) + \ len(txnPoolNodeSet) * delay ensureElectionsDone(looper, txnPoolNodeSet, customTimeout=timeout) sdk_get_replies(looper, req_resps, timeout=timeout) looper.run(eventually(chk, 0))
def test_repeated_request_not_processed_if_already_ordered( looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): delta = txnPoolNodeSet[3] initial_ledger_size = delta.domainLedger.size one_req = sdk_signed_random_requests(looper, sdk_wallet_client, 1) sdk_send_and_check(one_req, looper, txnPoolNodeSet, sdk_pool_handle) sdk_send_signed_requests(sdk_pool_handle, one_req) looper.runFor(waits.expectedTransactionExecutionTime(len(txnPoolNodeSet))) for node in txnPoolNodeSet: assert node.domainLedger.size - initial_ledger_size == 1
def test_repeated_request_not_processed_if_already_ordered( looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): delta = txnPoolNodeSet[3] initial_ledger_size = delta.domainLedger.size one_req = sdk_signed_random_requests(looper, sdk_wallet_client, 1) sdk_send_and_check(one_req, looper, txnPoolNodeSet, sdk_pool_handle) sdk_send_signed_requests(sdk_pool_handle, one_req) looper.runFor(waits.expectedTransactionExecutionTime(len(txnPoolNodeSet))) for node in txnPoolNodeSet: assert node.domainLedger.size - initial_ledger_size == 1
def test_send_same_txn_with_different_signatures_in_separate_batches( looper, txnPoolNodeSet, sdk_pool_handle, two_requests): # Send two txn with same payload digest but different signatures, # so that they could be processed in one batch, trying to break the ledger hashes req1, req2 = two_requests rep1 = sdk_send_signed_requests(sdk_pool_handle, [req1]) sdk_get_and_check_replies(looper, rep1) rep2 = sdk_send_signed_requests(sdk_pool_handle, [req2]) with pytest.raises(RequestNackedException) as e: sdk_get_and_check_replies(looper, rep2) e.match('Same txn was already ordered with different signatures or pluggable fields')
def test_send_same_txn_with_different_plugins(looper, txn_pool_node_set_post_creation, sdk_pool_handle, two_requests): req1, req2 = two_requests rep1 = sdk_send_signed_requests(sdk_pool_handle, [req1]) sdk_get_and_check_replies(looper, rep1) rep2 = sdk_send_signed_requests(sdk_pool_handle, [req2]) with pytest.raises(RequestNackedException) as e: sdk_get_and_check_replies(looper, rep2) e.match( 'Same txn was already ordered with different signatures or pluggable fields' )
def test_suspicious_primary_send_same_request_with_different_signatures( looper, txnPoolNodeSet, sdk_pool_handle, two_requests): assert txnPoolNodeSet[0].master_replica.isPrimary txnPoolNodeSet[0].doDynamicValidation = types.MethodType(malicious_dynamic_validation, txnPoolNodeSet[0]) req1, req2 = two_requests old_view = txnPoolNodeSet[0].viewNo sdk_send_signed_requests(sdk_pool_handle, [req1]) sdk_send_signed_requests(sdk_pool_handle, [req2]) waitForViewChange(looper, txnPoolNodeSet, expectedViewNo=old_view + 1) all(cll.params['msg'][1] == Suspicions.PPR_WITH_ORDERED_REQUEST.code for cll in txnPoolNodeSet[0].spylog.getAll('sendToViewChanger') if isinstance(cll.params['msg'], InstanceChange)) txnPoolNodeSet[0].doDynamicValidation = types.MethodType(Node.doDynamicValidation, txnPoolNodeSet[0])
def write(key, val, looper, sdk_pool_handle, sdk_wallet): _, idr = sdk_wallet reqs_obj = [sdk_gen_request(op, identifier=idr) for op in [write_conf_op(key, val)]] reqs = sdk_sign_request_objects(looper, sdk_wallet, reqs_obj) sent_reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) sdk_get_replies(looper, sent_reqs, timeout=10)
def sdk_sign_and_send_prepared_request(looper, sdk_wallet, sdk_pool_handle, string_req): signed_reqs = sdk_sign_request_objects( looper, sdk_wallet, [sdk_json_to_request_object(json.loads(string_req))]) request_couple = sdk_send_signed_requests(sdk_pool_handle, signed_reqs)[0] return request_couple
def test_create_did_without_endorser_sig_count_2_one_on_ledger( looper, txnPoolNodeSet, nym_txn_data, sdk_pool_handle, sdk_wallet_trustee): change_auth_rule(looper, sdk_pool_handle, sdk_wallet_trustee, constraint=AuthConstraint(role='*', sig_count=2, off_ledger_signature=True)) wh, alias, sender_did, sender_verkey = nym_txn_data nym_request = looper.loop.run_until_complete( build_nym_request(sender_did, sender_did, sender_verkey, alias, NEW_ROLE)) nym_request = sdk_multisign_request_object(looper, (wh, sender_did), nym_request) nym_request = sdk_multisign_request_object(looper, sdk_wallet_trustee, nym_request) request_couple = sdk_send_signed_requests(sdk_pool_handle, [nym_request])[0] sdk_get_and_check_replies(looper, [request_couple]) details = get_nym_details(txnPoolNodeSet[0].states[1], sender_did, is_committed=True) assert details[ROLE] == NEW_ROLE assert details[VERKEY] == sender_verkey
def test_apply_several_batches_with_several_txns( looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, address_main, mint_tokens): current_amount = get_amount_from_token_txn(mint_tokens) init_seq_no = 1 node_set = nodeSetWithIntegratedTokenPlugin all_reqs = nyms_with_fees(NUM_BATCHES * TXN_IN_BATCH, helpers, fees_set, address_main, current_amount, init_seq_no=init_seq_no) domain_txns_before = get_committed_txns_count_for_pool( node_set, DOMAIN_LEDGER_ID) token_txns_before = get_committed_txns_count_for_pool( node_set, TOKEN_LEDGER_ID) r = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(req.as_dict) for req in all_reqs]) looper.runFor(waits.expectedPrePrepareTime(len(node_set))) sdk_get_and_check_replies(looper, r) domain_txns_after = get_committed_txns_count_for_pool( node_set, DOMAIN_LEDGER_ID) token_txns_after = get_committed_txns_count_for_pool( node_set, TOKEN_LEDGER_ID) assert domain_txns_after - domain_txns_before == NUM_BATCHES * TXN_IN_BATCH assert token_txns_after - token_txns_before == NUM_BATCHES * TXN_IN_BATCH
def write(key, val, looper, sdk_pool_handle, sdk_wallet): _, idr = sdk_wallet reqs_obj = [sdk_gen_request(op, identifier=idr) for op in [write_conf_op(key, val)]] reqs = sdk_sign_request_objects(looper, sdk_wallet, reqs_obj) sent_reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) sdk_get_replies(looper, sent_reqs, timeout=10)
def test_plugin_dynamic_validation(txn_pool_node_set_post_creation, looper, sdk_wallet_steward, sdk_pool_handle): """ Check plugin dynamic validation fails and passes """ op = { TXN_TYPE: AUCTION_END, DATA: {'id': 'abcdef'} } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: AUCTION_START, DATA: {'id': 'xyz'} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle) op = { TXN_TYPE: AUCTION_END, DATA: {'id': 'xyz'} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle)
def test_malicious_primary_sent_pp(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, address_main, mint_tokens): def raise_invalid_ex(): raise InvalidClientMessageException(1, 2, 3) nodes = nodeSetWithIntegratedTokenPlugin amount = get_amount_from_token_txn(mint_tokens) init_seq_no = 1 request1, request2 = nyms_with_fees(2, helpers, fees_set, address_main, amount, init_seq_no=init_seq_no) malicious_primary = getPrimaryReplica(nodes).node not_malicious_nodes = set(nodes) - {malicious_primary} for n in not_malicious_nodes: n.doDynamicValidation = lambda *args, **kwargs: raise_invalid_ex() r1 = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request1.as_dict)]) with pytest.raises(RequestRejectedException, match="client request invalid"): sdk_get_and_check_replies(looper, r1)
def test_last_committed_after_catchup(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, address_main, mint_tokens): node_set = nodeSetWithIntegratedTokenPlugin reverted_node = node_set[-1] amount = get_amount_from_token_txn(mint_tokens) init_seq_no = 1 request_1, request_2 = nyms_with_fees(2, helpers, fees_set, address_main, amount, init_seq_no=init_seq_no) reverted_last_committed = get_last_committed_from_tracker(reverted_node) not_reverted_last_committed = get_last_committed_from_tracker(node_set[-1]) assert reverted_last_committed == not_reverted_last_committed with delay_rules(reverted_node.nodeIbStasher, cDelay()): """ Send NYM with FEES and wait for reply. """ r = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(request_1.as_dict)]) sdk_get_and_check_replies(looper, r) """ Start catchup. Uncommitted batch for reverted_node should be rejected and it will get NYM with FEES during catchup procedure. """ reverted_node.start_catchup() looper.run( eventually( lambda: assertExp(reverted_node.mode == Mode.participating))) assert get_last_committed_from_tracker(reverted_node) ==\ get_last_committed_from_tracker(node_set[0])
def send_xfer(looper, inputs, outputs, sdk_pool_handle, extra_data=None): request = xfer_request(inputs, outputs, extra_data) request = sdk_send_signed_requests(sdk_pool_handle, [ json.dumps(request.as_dict), ]) _, rep = sdk_get_and_check_replies(looper, request)[0] return rep['result']
def test_plugin_dynamic_validation(txn_pool_node_set_post_creation, looper, sdk_wallet_steward, sdk_pool_handle): """ Check plugin dynamic validation fails and passes """ op = { TXN_TYPE: AUCTION_END, DATA: {'id': 'abcdef'} } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: AUCTION_START, DATA: {'id': 'xyz'} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle) op = { TXN_TYPE: AUCTION_END, DATA: {'id': 'xyz'} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle)
def add_new_nym(looper, sdk_pool_handle, creators_wallets, alias=None, role=None, seed=None, dest=None, verkey=None, skipverkey=False, no_wait=False): seed = seed or randomString(32) alias = alias or randomString(5) wh, _ = creators_wallets[0] # filling nym request and getting steward did # if role == None, we are adding client nym_request, new_did = looper.loop.run_until_complete( prepare_nym_request(creators_wallets[0], seed, alias, role, dest, verkey, skipverkey)) # sending request using 'sdk_' functions signed_reqs = sdk_multi_sign_request_objects( looper, creators_wallets, [sdk_json_to_request_object(json.loads(nym_request))]) request_couple = sdk_send_signed_requests(sdk_pool_handle, signed_reqs)[0] if no_wait: return request_couple # waitng for replies sdk_get_and_check_replies(looper, [request_couple])
def test_plugin_client_req_fields(txn_pool_node_set_post_creation, looper, 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 _, did = sdk_wallet_steward req = sdk_gen_request(op, identifier=did, fix_length_dummy=randomString(dummy_field_length + 1)) reqs = sdk_sign_request_objects(looper, sdk_wallet_steward, [req]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(RequestNackedException) as e: sdk_get_and_check_replies(looper, reqs) assert 'should have length' in e._excinfo[1].args[0]
def test_revoc_entry_static_validation_on_size(revoc_entry, looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_steward): _expected, _req = revoc_entry results = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(_req)]) _reply = sdk_get_replies(looper, results)[0][1] assert _expected == _reply['op']
def test_plugin_client_req_fields(txn_pool_node_set_post_creation, looper, 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 _, did = sdk_wallet_steward req = sdk_gen_request(op, identifier=did, fix_length_dummy=randomString(dummy_field_length + 1)) reqs = sdk_sign_request_objects(looper, sdk_wallet_steward, [req]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(RequestNackedException) as e: sdk_get_and_check_replies(looper, reqs) assert 'should have length' in e._excinfo[1].args[0]
def send_and_check(test_body: AbstractTest, req): signed_reqs = sdk_multi_sign_request_objects(test_body.looper, [test_body.trustee_wallet], [req]) request_couple = sdk_send_signed_requests(test_body.sdk_pool_handle, signed_reqs)[0] return sdk_get_and_check_replies(test_body.looper, [request_couple])[0]
def read(key, looper, sdk_pool_handle, sdk_wallet): _, idr = sdk_wallet reqs_obj = [sdk_gen_request(op, identifier=idr) for op in [read_conf_op(key)]] reqs = sdk_sign_request_objects(looper, sdk_wallet, reqs_obj) sent_reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) (req, resp), = sdk_get_replies(looper, sent_reqs, timeout=10) return json.loads(resp['result'][DATA])[key]
def test_plugin_static_validation(txn_pool_node_set_post_creation, looper, sdk_wallet_steward, sdk_pool_handle): """ Check plugin static validation fails and passes """ op = { TXN_TYPE: AUCTION_START } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: AUCTION_START, DATA: 'should be a dict but giving a string' } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: AUCTION_START, DATA: {'id': 'abc'} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle) op = { TXN_TYPE: PLACE_BID, DATA: {'id': 'abc', AMOUNT: -3} } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: PLACE_BID, DATA: {'id': 'abc', AMOUNT: 20} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle)
def sdk_send_freeze_ledgers(looper, sdk_pool_handle, sdk_wallets, ledgers_ids: [int]): req = looper.loop.run_until_complete( build_ledgers_freeze_request(sdk_wallets[0][1], ledgers_ids)) signed_reqs = sdk_multi_sign_request_objects( looper, sdk_wallets, [sdk_json_to_request_object(json.loads(req))]) reps = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) return sdk_get_and_check_replies(looper, reps)[0]
def read(key, looper, sdk_pool_handle, sdk_wallet): _, idr = sdk_wallet reqs_obj = [sdk_gen_request(op, identifier=idr) for op in [read_conf_op(key)]] reqs = sdk_sign_request_objects(looper, sdk_wallet, reqs_obj) sent_reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) (req, resp), = sdk_get_replies(looper, sent_reqs, timeout=10) return json.loads(resp['result'][DATA])[key]
def test_plugin_static_validation(txn_pool_node_set_post_creation, looper, sdk_wallet_steward, sdk_pool_handle): """ Check plugin static validation fails and passes """ op = { TXN_TYPE: AUCTION_START } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: AUCTION_START, DATA: 'should be a dict but giving a string' } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: AUCTION_START, DATA: {'id': 'abc'} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle) op = { TXN_TYPE: PLACE_BID, DATA: {'id': 'abc', AMOUNT: -3} } reqs = sdk_sign_request_strings(looper, sdk_wallet_steward, [op, ]) reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) with pytest.raises(CommonSdkIOException) as exc_info: sdk_get_and_check_replies(looper, reqs) exc_info.match('Got an error with code 113') op = { TXN_TYPE: PLACE_BID, DATA: {'id': 'abc', AMOUNT: 20} } successful_op(looper, op, sdk_wallet_steward, sdk_pool_handle)
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)
def testSendNodeHasInvalidSyntaxIfUnknownParameterIsPassed( looper, sdk_pool_handle, nodeSet, sdk_node_theta_added, node_request): node_request['operation']['albus'] = 'severus' steward_wallet, node = sdk_node_theta_added signed_reqs = sdk_sign_request_strings(looper, steward_wallet, [node_request]) request_couple = sdk_send_signed_requests(sdk_pool_handle, signed_reqs)[0] sdk_get_and_check_replies(looper, [request_couple]) ensurePoolIsOperable(looper, sdk_pool_handle, steward_wallet)
def send_and_check(self, req, wallet): signed_reqs = sdk_sign_request_objects(self.looper, wallet, [req]) request_couple = sdk_send_signed_requests(self.sdk_pool_handle, signed_reqs)[0] return sdk_get_and_check_replies(self.looper, [request_couple])[0]
def test_request_with_correct_version(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, request_num): _, did = sdk_wallet_client reqs_obj = sdk_random_request_objects(request_num, identifier=did, protocol_version=CURRENT_PROTOCOL_VERSION) for req_obj in reqs_obj: assert req_obj.protocolVersion == CURRENT_PROTOCOL_VERSION signed_reqs = sdk_sign_request_objects(looper, sdk_wallet_client, reqs_obj) reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) sdk_get_and_check_replies(looper, reqs)
def test_request_none_protocol_version(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, request_num): _, did = sdk_wallet_client req_objs = sdk_random_request_objects(request_num, identifier=did, protocol_version=None) for req_obj in req_objs: assert req_obj.protocolVersion == None signed_reqs = sdk_sign_request_objects(looper, sdk_wallet_client, req_objs) reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) sdk_get_bad_response(looper, reqs, RequestNackedException, 'missed fields - protocolVersion. ' + error_msg)
def test_request_with_invalid_version(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, request_num): _, did = sdk_wallet_client reqs_obj = sdk_random_request_objects(request_num, identifier=did, protocol_version=-1) for req_obj in reqs_obj: assert req_obj.protocolVersion == -1 signed_reqs = sdk_sign_request_objects(looper, sdk_wallet_client, reqs_obj) reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) sdk_get_bad_response(looper, reqs, RequestNackedException, 'Unknown protocol version value. ' + error_msg)
def test_request_with_outdated_version(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, request_num): _, did = sdk_wallet_client reqs_obj = sdk_random_request_objects(request_num, identifier=did, protocol_version=CURRENT_PROTOCOL_VERSION - 1) for req_obj in reqs_obj: assert req_obj.protocolVersion == CURRENT_PROTOCOL_VERSION - 1 signed_reqs = sdk_sign_request_objects(looper, sdk_wallet_client, reqs_obj) reqs = sdk_send_signed_requests(sdk_pool_handle, signed_reqs) sdk_get_bad_response(looper, reqs, RequestNackedException, 'differs from current protocol version. ' .format(CURRENT_PROTOCOL_VERSION) + error_msg)
def testSendRequestWithoutSignatureFails(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): """ A client request sent without a signature fails with an EmptySignature exception """ # remove the client's ability to sign requests = sdk_signed_random_requests(looper, sdk_wallet_client, 1) json_req = json.loads(requests[0]) json_req['signature'] = None request = json.dumps(json_req) res = sdk_send_signed_requests(sdk_pool_handle, [request]) obj_req = sdk_json_to_request_object(res[0][0]) timeout = waits.expectedClientRequestPropagationTime(nodeCount) with pytest.raises(AssertionError): for node in txnPoolNodeSet: looper.loop.run_until_complete(eventually( checkLastClientReqForNode, node, obj_req, retryWait=1, timeout=timeout)) for n in txnPoolNodeSet: params = n.spylog.getLastParams(Node.handleInvalidClientMsg) ex = params['ex'] msg, _ = params['wrappedMsg'] assert isinstance(ex, MissingSignature) assert msg.get(f.IDENTIFIER.nm) == obj_req.identifier params = n.spylog.getLastParams(Node.discard) reason = params["reason"] (msg, frm) = params["msg"] assert msg == json_req assert msg.get(f.IDENTIFIER.nm) == obj_req.identifier assert "MissingSignature" in reason
def testDoNotBlacklistClient(looper, txnPoolNodeSet, sdk_wallet_client, sdk_pool_handle, poolTxnClientNames): """ Client should be not be blacklisted by node on sending an unsigned request """ client_name = poolTxnClientNames[0] _, did = sdk_wallet_client # No node should blacklist the client req_obj = sdk_random_request_objects(1, identifier=did, protocol_version=CURRENT_PROTOCOL_VERSION)[0] reqs = sdk_send_signed_requests(sdk_pool_handle, [json.dumps(req_obj.as_dict)]) with pytest.raises(RequestNackedException) as e: sdk_get_and_check_replies(looper, reqs) assert 'MissingSignature' in e._excinfo[1].args[0] def chk(): for node in txnPoolNodeSet: assert not node.isClientBlacklisted(client_name) timeout = waits.expectedClientToPoolConnectionTimeout(len(txnPoolNodeSet)) looper.run(eventually(chk, retryWait=1, timeout=timeout))
def test_already_processed_requests(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client): """ Client re-sending request and checking that nodes picked the reply from ledger and did not process the request again """ def get_method_call_count(method): counts = set() for node in txnPoolNodeSet: c = node.spylog.count(method) counts.add(c) assert len(counts) == 1 return counts.pop() def get_getReplyFromLedgerForRequest_call_count(): return get_method_call_count( next(iter(txnPoolNodeSet)).getReplyFromLedgerForRequest) def get_recordAndPropagate_call_count(): return get_method_call_count( next(iter(txnPoolNodeSet)).recordAndPropagate) def get_last_returned_val(): rvs = [] for node in txnPoolNodeSet: rv = getAllReturnVals(node, node.getReplyFromLedgerForRequest) rvs.append(rv[0]) # All items are same in the list assert rvs.count(rvs[0]) == len(txnPoolNodeSet) return rvs[0] rlc1 = get_getReplyFromLedgerForRequest_call_count() rpc1 = get_recordAndPropagate_call_count() # Request which will be send twice reqs = sdk_signed_random_requests(looper, sdk_wallet_client, 1) # Send, check and getting reply from first request sdk_reqs = sdk_send_signed_requests(sdk_pool_handle, reqs) total_timeout = sdk_eval_timeout(len(sdk_reqs), len(txnPoolNodeSet)) request1 = sdk_get_replies(looper, sdk_reqs, timeout=total_timeout) for req_res in request1: sdk_check_reply(req_res) first_req_id = request1[0][0]['reqId'] rlc2 = get_getReplyFromLedgerForRequest_call_count() rpc2 = get_recordAndPropagate_call_count() assert rlc2 - rlc1 == 1 # getReplyFromLedgerForRequest was called assert rpc2 - rpc1 == 1 # recordAndPropagate was called r1 = get_last_returned_val() assert r1 is None # getReplyFromLedgerForRequest returned None since had not seen request # Request which we will send only once request2 = sdk_send_random_and_check(looper, txnPoolNodeSet, sdk_pool_handle, sdk_wallet_client, 1) second_req_id = request2[0][0]['reqId'] assert second_req_id != first_req_id rlc3 = get_getReplyFromLedgerForRequest_call_count() rpc3 = get_recordAndPropagate_call_count() assert rlc3 - rlc2 == 1 # getReplyFromLedgerForRequest was called again assert rpc3 - rpc2 == 1 # recordAndPropagate was called again r2 = get_last_returned_val() assert r2 is None # getReplyFromLedgerForRequest returned None since had not seen request # Reply for the first request, which is going to be sent again rep1 = request1[0][1]['result'] # Client re-sending first request request3 = sdk_send_signed_requests(sdk_pool_handle, reqs) total_timeout = sdk_eval_timeout(len(request3), len(txnPoolNodeSet)) request3 = sdk_get_replies(looper, request3, timeout=total_timeout) third_req_id = request3[0][0]['reqId'] assert third_req_id == first_req_id rlc4 = get_getReplyFromLedgerForRequest_call_count() rpc4 = get_recordAndPropagate_call_count() assert rlc4 - rlc3 == 1 # getReplyFromLedgerForRequest was called again assert rpc4 - rpc3 == 0 # recordAndPropagate was not called r3 = get_last_returned_val() # getReplyFromLedgerForRequest did not return None this time since had seen request assert r3 is not None rep3 = request3[0][1]['result'] # Since txnTime is not stored in ledger and reading from ledger return # all possible fields from transactions rep3 = {k: v for k, v in rep3.items() if v is not None} rep1 = {k: v for k, v in rep1.items() if k in rep3} assert rep3 == rep1 # The reply client got is same as the previous one
def sdk_sign_and_send_prepared_request(looper, sdk_wallet, sdk_pool_handle, string_req): signed_reqs = sdk_sign_request_objects(looper, sdk_wallet, [sdk_json_to_request_object( json.loads(string_req))]) request_couple = sdk_send_signed_requests(sdk_pool_handle, signed_reqs)[0] return request_couple