def test_revert_works_for_fees_after_view_change(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, mint_tokens, addresses, fees): node_set = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(mint_tokens) seq_no = get_seq_no(mint_tokens) reverted_node = nodeSetWithIntegratedTokenPlugin[-1] current_amount, seq_no, _ = send_and_check_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) current_amount, seq_no, _ = send_and_check_transfer(helpers, addresses, fees, looper, current_amount, seq_no) with delay_rules_without_processing(reverted_node.nodeIbStasher, delay_3pc(view_no=0, msgs=Commit)): len_batches_before = len(reverted_node.master_replica._ordering_service.batches) current_amount, seq_no, _ = send_and_check_transfer(helpers, addresses, fees, looper, current_amount, seq_no) current_amount, seq_no, _ = send_and_check_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) looper.runFor(waits.expectedPrePrepareTime(len(nodeSetWithIntegratedTokenPlugin))) len_batches_after = len(reverted_node.master_replica._ordering_service.batches) """ Checks, that we have a 2 new batches """ assert len_batches_after - len_batches_before == 2 for n in node_set: n.view_changer.on_master_degradation() ensure_view_change(looper, nodeSetWithIntegratedTokenPlugin) looper.run(eventually(lambda: assertExp(reverted_node.mode == Mode.participating))) ensure_all_nodes_have_same_data(looper, node_set) send_and_check_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) ensure_all_nodes_have_same_data(looper, node_set)
def test_revert_xfer_before_catchup(looper, helpers, nodeSetWithIntegratedTokenPlugin, fees_set, fees, xfer_mint_tokens, xfer_addresses): nodes = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(xfer_mint_tokens) seq_no = get_seq_no(xfer_mint_tokens) lagging_node = nodes[-1] current_amount, seq_no, _ = send_and_check_transfer( helpers, xfer_addresses, fees, looper, current_amount, seq_no) with delay_rules_without_processing(lagging_node.nodeIbStasher, cDelay(), pDelay()): current_amount, seq_no, _ = send_and_check_transfer( helpers, xfer_addresses, fees, looper, current_amount, seq_no) looper.runFor(waits.expectedPrePrepareTime(len(nodes))) lagging_node.start_catchup() for n in nodes: looper.run( eventually(lambda: assertExp(n.mode == Mode.participating))) for n in nodes: looper.run( eventually(check_state, n, True, retryWait=0.2, timeout=15)) ensure_all_nodes_have_same_data(looper, nodes) current_amount, seq_no, _ = send_and_check_transfer( helpers, xfer_addresses, fees, looper, current_amount, seq_no) ensure_all_nodes_have_same_data(looper, nodes)
def test_revert_for_all_after_view_change(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, mint_tokens, addresses, fees): node_set = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(mint_tokens) seq_no = get_seq_no(mint_tokens) reverted_node = nodeSetWithIntegratedTokenPlugin[-1] current_amount, seq_no, _ = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount) current_amount, seq_no, _ = send_and_check_transfer( helpers, addresses, fees, looper, current_amount, seq_no) ensure_all_nodes_have_same_data(looper, node_set) with delay_rules([n.nodeIbStasher for n in node_set], cDelay(), pDelay()): len_batches_before = len(reverted_node.master_replica.batches) current_amount, seq_no, resp1 = send_and_check_transfer( helpers, addresses, fees, looper, current_amount, seq_no, check_reply=False) current_amount, seq_no, resp2 = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount, check_reply=False) looper.runFor( waits.expectedPrePrepareTime( len(nodeSetWithIntegratedTokenPlugin))) len_batches_after = len(reverted_node.master_replica.batches) """ Checks, that we have a 2 new batches """ assert len_batches_after - len_batches_before == 2 for n in node_set: n.view_changer.on_master_degradation() ensure_view_change_complete(looper, nodeSetWithIntegratedTokenPlugin) looper.run( eventually( lambda: assertExp(reverted_node.mode == Mode.participating))) ensure_all_nodes_have_same_data(looper, node_set) sdk_get_and_check_replies(looper, resp1) sdk_get_and_check_replies(looper, resp2) send_and_check_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) ensure_all_nodes_have_same_data(looper, node_set)
def test_first_catchup_with_not_empty_ledger(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, sdk_wallet_trustee, fees_set, mint_tokens, addresses, fees, tconf, tdir, allPluginsPath, do_post_node_creation): node_set = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(mint_tokens) seq_no = 1 reverted_node = node_set[-1] idx = node_set.index(reverted_node) current_amount, seq_no, _ = send_and_check_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) reverted_node.cleanupOnStopping = False disconnect_node_and_ensure_disconnected(looper, node_set, reverted_node.name) looper.removeProdable(name=reverted_node.name) from_a_to_b = [addresses[0], addresses[1]] from_b_to_c = [addresses[1], addresses[2]] from_c_to_d = [addresses[2], addresses[3]] from_d_to_a = [addresses[3], addresses[0]] # current_amount, seq_no, _ = add_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) current_amount, seq_no, _ = send_and_check_transfer(helpers, from_a_to_b, fees, looper, current_amount, seq_no, transfer_summ=current_amount) current_amount, seq_no, _ = send_and_check_transfer(helpers, from_b_to_c, fees, looper, current_amount, seq_no, transfer_summ=current_amount) current_amount, seq_no, _ = send_and_check_transfer(helpers, from_c_to_d, fees, looper, current_amount, seq_no, transfer_summ=current_amount) # add node_to_disconnect to pool node_to_disconnect = start_stopped_node(reverted_node, looper, tconf, tdir, allPluginsPath, start=False) do_post_node_creation(node_to_disconnect) looper.add(node_to_disconnect) node_set[idx] = node_to_disconnect looper.run(checkNodesConnected(node_set)) helpers.node.fill_auth_map_for_node(node_to_disconnect, XFER_PUBLIC) current_amount, seq_no, _ = send_and_check_transfer(helpers, from_d_to_a, fees, looper, current_amount, seq_no, transfer_summ=current_amount) ensure_all_nodes_have_same_data(looper, node_set)
def wrapped(addresses=None, check_reply=True, transfer_summ=20): addresses = _addresses if addresses is None else addresses curr_utxo['amount'], curr_utxo[ 'seq_no'], resp = send_and_check_transfer( helpers, addresses, fees, looper, curr_utxo['amount'], curr_utxo['seq_no'], check_reply=check_reply, transfer_summ=transfer_summ - fees[XFER_PUBLIC_FEES_ALIAS]) return curr_utxo, resp
def test_malicious_primary_sent_pp_with_xfer(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, fees_set, address_main, xfer_mint_tokens, fees, xfer_addresses): def raise_invalid_ex(): raise InvalidClientMessageException(1, 2, 3) nodes = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(xfer_mint_tokens) malicious_primary = getPrimaryReplica(nodes).node not_malicious_nodes = set(nodes) - {malicious_primary} seq_no = get_seq_no(xfer_mint_tokens) for n in not_malicious_nodes: n.master_replica._ordering_service._do_dynamic_validation = lambda *args, **kwargs: raise_invalid_ex() with pytest.raises(RequestRejectedException, match="client request invalid"): current_amount, seq_no, _ = send_and_check_transfer(helpers, xfer_addresses, fees, looper, current_amount, seq_no)
def test_demote_promote_restart_after_promotion( nodeSetWithIntegratedTokenPlugin, looper, sdk_pool_handle, sdk_wallet_trustee, tdir, tconf, allPluginsPath, mint_tokens, address_main, helpers, fees_set, addresses, fees, do_post_node_creation): pool = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(mint_tokens) seq_no = 1 demoted_node = pool[-1] from_a_to_b = [addresses[0], addresses[1]] current_amount, seq_no, _ = send_and_check_transfer( helpers, from_a_to_b, fees, looper, current_amount, seq_no) rest_nodes = [n for n in pool if n != demoted_node] starting_view_no = checkViewNoForNodes(pool) # Step 1. Demote for node Zeta demote_node(helpers, sdk_wallet_trustee, demoted_node) # Step 2. Waiting for view change after nodes count changing waitForViewChange(looper, rest_nodes, expectedViewNo=starting_view_no + 1) ensureElectionsDone(looper, rest_nodes) ensure_all_nodes_have_same_data( looper, rest_nodes, exclude_from_check='check_seqno_db_equality') current_amount, seq_no, _ = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount) current_amount, seq_no, _ = send_and_check_transfer( helpers, from_a_to_b, fees, looper, current_amount, seq_no) starting_view_no = checkViewNoForNodes(rest_nodes) # Step 3. Promote node back and waiting for view change promote_node(helpers, sdk_wallet_trustee, demoted_node) waitForViewChange(looper, rest_nodes, expectedViewNo=starting_view_no + 1) ensureElectionsDone(looper, rest_nodes) # Step 4. Restart promoted node only after Node txn ordering restart_node(demoted_node, pool, looper, tconf, tdir, allPluginsPath, do_post_node_creation, fees) ensure_all_nodes_have_same_data( looper, pool, custom_timeout=60, exclude_from_check='check_seqno_db_equality') ensureElectionsDone(looper, pool) # Step 5. Make sure that pool works fine current_amount, seq_no, _ = send_and_check_transfer( helpers, from_a_to_b, fees, looper, current_amount, seq_no) current_amount, seq_no, _ = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount) ensure_all_nodes_have_same_data( looper, pool, exclude_from_check='check_seqno_db_equality')
def test_chain_set_fees_and_xfer_batch_size_2(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, sdk_wallet_trustee, mint_tokens, addresses, poolConfigWTFF): """ Set FEES for XFER for 2 Send any transaction to config ledger. Send XFER with fees 2 from A to B Set FEES for XFER for 3 Send any transaction to config ledger. Send XFER with fees 3 from A to B Check that first XFER is not written and second XFER is. """ A, B = addresses current_amount = get_amount_from_token_txn(mint_tokens) seq_no = get_seq_no(mint_tokens) transfer_summ = 20 # Set fees and some config txn helpers.node.set_fees_directly({XFER_PUBLIC_FEES_ALIAS: 42}) fees_xfer_2 = {XFER_PUBLIC_FEES_ALIAS: 2} fees_2_rsp = helpers.general.set_fees_without_waiting(fees_xfer_2) sdk_pool_config_sent(looper, sdk_pool_handle, sdk_wallet_trustee, poolConfigWTFF) sdk_get_and_check_replies(looper, fees_2_rsp) # XFER with fees 2 from A to B _, _, a_b_transfer_2 = send_and_check_transfer(helpers, [A, B], fees_xfer_2, looper, current_amount, seq_no, transfer_summ=transfer_summ, check_reply=False) # Set fees for XFER to 3 fees_xfer_3 = {XFER_PUBLIC_FEES_ALIAS: 3} fees_3_rsp = helpers.general.set_fees_without_waiting(fees_xfer_3) sdk_pool_config_sent(looper, sdk_pool_handle, sdk_wallet_trustee, poolConfigWTFF) sdk_get_and_check_replies(looper, fees_3_rsp) # Send XFER with fees from A to B a_amount, seq_no, a_b_transfer_3 = send_and_check_transfer( helpers, [A, B], fees_xfer_3, looper, current_amount, seq_no, transfer_summ=transfer_summ, check_reply=False) for n in nodeSetWithIntegratedTokenPlugin: fee_rq = n.ledger_to_req_handler[CONFIG_LEDGER_ID] assert fee_rq.fees == fees_xfer_3 with pytest.raises(RequestRejectedException): sdk_get_and_check_replies(looper, a_b_transfer_2) sdk_get_and_check_replies(looper, a_b_transfer_3) a_get = helpers.general.do_get_utxo(A) assert a_get[OUTPUTS][1][AMOUNT] == a_amount assert a_get[OUTPUTS][1][SEQNO] == seq_no b_get = helpers.general.do_get_utxo(B) assert b_get[OUTPUTS][0][AMOUNT] == transfer_summ assert b_get[OUTPUTS][0][SEQNO] == seq_no ensure_all_nodes_have_same_data(looper, nodeSetWithIntegratedTokenPlugin)
def test_first_catchup_for_a_new_node(looper, helpers, nodeSetWithIntegratedTokenPlugin, sdk_pool_handle, sdk_wallet_trustee, fees_set, mint_tokens, addresses, fees, tconf, tdir, allPluginsPath, do_post_node_creation, testNodeClass): node_set = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(mint_tokens) seq_no = 1 reverted_node = node_set[-1] idx = node_set.index(reverted_node) current_amount, seq_no, _ = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount) reverted_node.cleanupOnStopping = False disconnect_node_and_ensure_disconnected(looper, node_set, reverted_node.name) looper.removeProdable(name=reverted_node.name) from_a_to_b = [addresses[0], addresses[1]] from_b_to_c = [addresses[1], addresses[2]] from_c_to_d = [addresses[2], addresses[3]] from_d_to_a = [addresses[3], addresses[0]] # current_amount, seq_no, _ = add_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) current_amount, seq_no, _ = send_and_check_transfer( helpers, from_a_to_b, fees, looper, current_amount, seq_no, transfer_summ=current_amount) current_amount, seq_no, _ = send_and_check_transfer( helpers, from_b_to_c, fees, looper, current_amount, seq_no, transfer_summ=current_amount) current_amount, seq_no, _ = send_and_check_transfer( helpers, from_c_to_d, fees, looper, current_amount, seq_no, transfer_summ=current_amount) add_new_node(helpers, looper, node_set, sdk_wallet_trustee, current_amount, seq_no, fees_set, sdk_pool_handle, tdir, tconf, allPluginsPath, addresses[3], do_post_node_creation, node_class=testNodeClass) current_amount, seq_no, _ = send_and_check_transfer( helpers, from_d_to_a, fees, looper, current_amount, seq_no, transfer_summ=current_amount) ensure_all_nodes_have_same_data(looper, node_set)
def test_state_recovery_with_xfer(looper, tconf, tdir, sdk_pool_handle, sdk_wallet_trustee, allPluginsPath, do_post_node_creation, nodeSetWithIntegratedTokenPlugin, helpers, valid_upgrade, mint_tokens, addresses, fees_set, fees, monkeypatch): version1 = "1.1.50" version2 = "1.1.88" current_amount = get_amount_from_token_txn(mint_tokens) seq_no = 1 node_set = nodeSetWithIntegratedTokenPlugin current_amount, seq_no, _ = send_and_check_nym_with_fees(helpers, fees_set, seq_no, looper, addresses, current_amount) # send POOL_UPGRADE to write in a ledger last_ordered = node_set[0].master_last_ordered_3PC[1] sdk_ensure_upgrade_sent(looper, sdk_pool_handle, sdk_wallet_trustee, valid_upgrade) looper.run(eventually(lambda: assertEquality(node_set[0].master_last_ordered_3PC[1], last_ordered + 1))) send_node_upgrades(node_set, version1, looper) for n in node_set: handler = n.write_manager.request_handlers.get(XFER_PUBLIC)[0] handler_for_1_0_0 = n.write_manager._request_handlers_with_version.get((XFER_PUBLIC, "1.0.0"))[0] monkeypatch.setattr(handler, 'update_state', handler_for_1_0_0.update_state) current_amount, seq_no, _ = send_and_check_transfer(helpers, [addresses[0], addresses[1]], fees_set, looper, current_amount, seq_no, transfer_summ=current_amount) send_node_upgrades(node_set, version2, looper) monkeypatch.undo() current_amount, seq_no, _ = send_and_check_transfer(helpers, [addresses[1], addresses[0]], fees_set, looper, current_amount, seq_no, transfer_summ=current_amount) node_to_stop = node_set[-1] state_db_pathes = [state._kv.db_path for state in node_to_stop.states.values()] node_to_stop.cleanupOnStopping = False node_to_stop.stop() looper.removeProdable(node_to_stop) ensure_node_disconnected(looper, node_to_stop, node_set[:-1]) for path in state_db_pathes: shutil.rmtree(path) config_helper = NodeConfigHelper(node_to_stop.name, tconf, chroot=tdir) restarted_node = TestNode( node_to_stop.name, config_helper=config_helper, config=tconf, pluginPaths=allPluginsPath, ha=node_to_stop.nodestack.ha, cliha=node_to_stop.clientstack.ha) do_post_node_creation(restarted_node) looper.add(restarted_node) node_set[-1] = restarted_node looper.run(checkNodesConnected(node_set)) waitNodeDataEquality(looper, restarted_node, *node_set[:-1], exclude_from_check=['check_last_ordered_3pc_backup']) current_amount, seq_no, _ = send_and_check_transfer(helpers, [addresses[0], addresses[1]], {}, looper, current_amount, seq_no, transfer_summ=1) waitNodeDataEquality(looper, restarted_node, *node_set[:-1], exclude_from_check=['check_last_ordered_3pc_backup'])
def test_chain_fees_and_xfer_batch_size_2(looper, helpers, nodeSetWithIntegratedTokenPlugin, fees_set, mint_tokens, addresses, fees): """ Set FEES for NYM transaction Send XFER from A to B Send NYM with fees from A using the UTXO as in 2 Send XFER from B to C Send NYM with fees from C Check that XFERs are written Check that first NYM is not written and the second one is written. """ a_amount = get_amount_from_token_txn(mint_tokens) seq_no = get_seq_no(mint_tokens) initial_seq_no = seq_no A, B, C = addresses transfer_summ = 20 # From A to B transfer a_amount, seq_no, a_b_transfer = send_and_check_transfer( helpers, [A, B], fees, looper, a_amount, seq_no, transfer_summ=transfer_summ, check_reply=False) # NYM with fees from A and utxo as for previous case _, _, a_nym = send_and_check_nym_with_fees(helpers, fees_set, initial_seq_no, looper, [A], a_amount + transfer_summ, check_reply=False) # From B to C transfer b_amount, seq_no, b_c_transfer = send_and_check_transfer( helpers, [B, C], fees, looper, transfer_summ, seq_no, transfer_summ=transfer_summ, check_reply=False) sdk_get_and_check_replies(looper, a_b_transfer) sdk_get_and_check_replies(looper, b_c_transfer) b_c_get = helpers.general.do_get_utxo(B) assert len(b_c_get[OUTPUTS]) == 0 # NYM with fees from C c_nym_amount, seq_no, c_nym = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, [C], transfer_summ, check_reply=False) with pytest.raises(RequestRejectedException, match="are not found in list"): sdk_get_and_check_replies(looper, a_nym) a_b_get = helpers.general.do_get_utxo(A) assert a_b_get[OUTPUTS][1][AMOUNT] == a_amount sdk_get_and_check_replies(looper, c_nym) c_nym_get = helpers.general.do_get_utxo(C) assert c_nym_get[OUTPUTS][0][ AMOUNT] == c_nym_amount == transfer_summ - fees.get(NYM_FEES_ALIAS, 0) ensure_all_nodes_have_same_data(looper, nodeSetWithIntegratedTokenPlugin)
def test_state_recover_from_ledger(looper, tconf, tdir, sdk_pool_handle, sdk_wallet_trustee, allPluginsPath, fees_set, mint_tokens, addresses, fees, do_post_node_creation, nodeSetWithIntegratedTokenPlugin, helpers): node_set = nodeSetWithIntegratedTokenPlugin current_amount = get_amount_from_token_txn(mint_tokens) seq_no = 1 current_amount, seq_no, _ = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount) current_amount, seq_no, _ = send_and_check_transfer( helpers, [addresses[0], addresses[1]], fees, looper, current_amount, seq_no, transfer_summ=current_amount) current_amount, seq_no, _ = send_and_check_transfer( helpers, [addresses[1], addresses[2]], fees, looper, current_amount, seq_no, transfer_summ=current_amount) ensure_all_nodes_have_same_data(looper, node_set) node_to_stop = node_set[-1] state_db_pathes = [ state._kv.db_path for state in node_to_stop.states.values() ] node_to_stop.cleanupOnStopping = False node_to_stop.stop() looper.removeProdable(node_to_stop) ensure_node_disconnected(looper, node_to_stop, node_set[:-1]) for path in state_db_pathes: shutil.rmtree(path) config_helper = NodeConfigHelper(node_to_stop.name, tconf, chroot=tdir) restarted_node = TestNode(node_to_stop.name, config_helper=config_helper, config=tconf, pluginPaths=allPluginsPath, ha=node_to_stop.nodestack.ha, cliha=node_to_stop.clientstack.ha) do_post_node_creation(restarted_node) looper.add(restarted_node) node_set = node_set[:-1] looper.run(checkNodesConnected(node_set)) waitNodeDataEquality(looper, restarted_node, *node_set[:-1]) ensure_all_nodes_have_same_data(looper, node_set) current_amount, seq_no, _ = send_and_check_transfer( helpers, [addresses[2], addresses[0]], fees, looper, current_amount, seq_no, transfer_summ=current_amount) current_amount, seq_no, _ = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount) current_amount, seq_no, _ = send_and_check_nym_with_fees( helpers, fees_set, seq_no, looper, addresses, current_amount) ensure_all_nodes_have_same_data(looper, node_set)