def test_node_discovery(): """ Test node discovery Assuming Carol's node only knows about Bob upon startup and that Bob's node knows Alice, Carol's node should be able to discover Alice and sync with her node. """ test_settings = settings["test_node_discovery"] alice_node = test_settings["nodes"]["alice"] bob_node = test_settings["nodes"]["bob"] carol_node = test_settings["nodes"]["carol"] alice_peer_url = node_peer_url(alice_node) bob_peer_url = node_peer_url(bob_node) carol_peer_url = node_peer_url(carol_node) # prepare a dir to hold the configs root_dir = tempfile.mkdtemp() # Alice's config: no peers alice_sys_config = make_peers_config(root_dir, "alice.config", alice_peer_url, [], mining=True) print("\nAlice has address " + alice_peer_url + " and no peers") # Bob's config: only peer is Alice bob_sys_config = make_peers_config(root_dir, "bob.config", bob_peer_url, [alice_peer_url], mining=False) print("Bob has address " + bob_peer_url + " and peers [" + alice_peer_url + "]") # Carol's config: only peer is Bob carol_sys_config = make_peers_config(root_dir, "carol.config", carol_peer_url, [bob_peer_url], mining=False) print("Carol has address " + carol_peer_url + " and peers [" + bob_peer_url + "]") # start Alice's node common.start_node(alice_node, alice_sys_config) alice_api = common.external_api(alice_node) # Insert some blocks in Alice's chain blocks_to_mine = test_settings["blocks_to_mine"] common.wait_until_height(alice_api, blocks_to_mine) alice_top = alice_api.get_top() assert_true(alice_top.height >= blocks_to_mine) # Now Alice has at least blocks_to_mine blocks # start the other nodes common.start_node(bob_node, bob_sys_config) common.start_node(carol_node, carol_sys_config) # Check that Carol syncs with Alice's chain carol_api = common.external_api(carol_node) common.wait_until_height(carol_api, alice_top.height) assert_equals( carol_api.get_block_by_hash(alice_top.hash).height, alice_top.height) # Check that Carol discovers Alice as a peer gen_hash = common.genesis_hash(carol_api) ping_obj = Ping( source="http://localhost:1234", genesis_hash=gen_hash, best_hash=gen_hash, difficulty=1, share=32, # expected peer list is small peers=[]) def carol_peers(): ps = [p.encode('utf-8') for p in carol_api.ping(ping_obj).peers] print("Carol now has peers " + str(ps)) return ps wait(lambda: common.is_among_peers(alice_peer_url, carol_peers()), timeout_seconds=120, sleep_seconds=0.25) # cleanup common.stop_node(alice_node) common.stop_node(bob_node) common.stop_node(carol_node) shutil.rmtree(root_dir)
def test_node_discovery_transitively(): """ Test node discovery (transitively) Assuming Carol's node only knows about Bob upon startup and that Bob's node knows Alice, Carol's node should be able to discover Alice and sync with her node. """ test_settings = settings["test_node_discovery_transitively"] alice_node = test_settings["nodes"]["alice"] bob_node = test_settings["nodes"]["bob"] carol_node = test_settings["nodes"]["carol"] # prepare a dir to hold the configs root_dir = tempfile.mkdtemp() # Alice's config: no peers alice_peers = "peers: []" alice_user_config = make_peers_user_config(root_dir, "alice_epoch.yaml", "node1", "3015", alice_peers, "true") # Bob's config: only peer is Alice bob_peers = """\ peers: - "aenode://pp$HdcpgTX2C1aZ5sjGGysFEuup67K9XiFsWqSPJs4RahEcSyF7X@localhost:3015" """ bob_user_config = make_peers_user_config(root_dir, "bob_epoch.yaml", "node2", "3025", bob_peers, "false") # Carol's config: only peer is Bob carol_peers = """\ peers: - "aenode://pp$28uQUgsPcsy7TQwnRxhF8GMKU4ykFLKsgf4TwDwPMNaSCXwWV8@localhost:3025" """ carol_user_config = make_peers_user_config(root_dir, "carol_epoch.yaml", "node3", "3035", carol_peers, "false") # start Alice's node common.start_node(alice_node, alice_user_config) alice_api = common.external_api(alice_node) # Insert some blocks in Alice's chain blocks_to_mine = test_settings["blocks_to_mine"] common.wait_until_height(alice_api, blocks_to_mine) alice_top = alice_api.get_top_block() assert_true(alice_top.height >= blocks_to_mine) # Now Alice has at least blocks_to_mine blocks # start the other nodes common.start_node(bob_node, bob_user_config) common.start_node(carol_node, carol_user_config) # Check that Carol syncs with Alice's chain carol_api = common.external_api(carol_node) common.wait_until_height(carol_api, alice_top.height) assert_equals( carol_api.get_block_by_hash(alice_top.hash).height, alice_top.height) # Check that Carol discovers Alice as a peer carol_int_api = common.internal_api(carol_node) wait( lambda: 'aenode://pp$HdcpgTX2C1aZ5sjGGysFEuup67K9XiFsWqSPJs4RahEcSyF7X@localhost:3015' in get_peers(carol_int_api), timeout_seconds=20, sleep_seconds=1) # cleanup common.stop_node(alice_node) common.stop_node(bob_node) common.stop_node(carol_node) shutil.rmtree(root_dir)
def test_send_by_name(): # Bob registers a name 'bob.test' # Alice should be able to send tokens to Bob using that name test_settings = settings["test_send_by_name"] beneficiary = common.setup_beneficiary() (node, (root_dir, ext_api, int_api, top)) = setup_node_with_tokens(test_settings, beneficiary, "miner") alice_private_key = keys.new_private() alice_public_key = keys.public_key(alice_private_key) alice_address = keys.address(alice_public_key) alice = {'privk': alice_private_key, 'enc_pubk': alice_address} bob_private_key = keys.new_private() bob_public_key = keys.public_key(bob_private_key) bob_address = keys.address(bob_public_key) # initial balances - amounts that the miner should send them alice_init_balance = test_settings["send_tokens"]["alice"] bob_init_balance = test_settings["send_tokens"]["bob"] spend_fee = test_settings["send_tokens"]["spend_fee"] # populate accounts with tokens common.ensure_send_tokens(beneficiary, alice_address, alice_init_balance, spend_fee, ext_api, int_api, 1) common.ensure_send_tokens(beneficiary, bob_address, bob_init_balance, spend_fee, ext_api, int_api, 1) # validate balances alice_balance0 = common.get_account_balance(ext_api, alice_address) bob_balance0 = common.get_account_balance(ext_api, bob_address) assert_equals(alice_balance0, alice_init_balance) assert_equals(bob_balance0, bob_init_balance) print("Alice balance is " + str(alice_balance0)) print("Bob balance is " + str(bob_balance0)) print("Bob address is " + bob_address) bob_name = test_settings["name_register"]["name"] fee = test_settings["name_register"]["fee"] name_fee = test_settings["name_register"]["name_fee"] register_name(bob_name, bob_address, ext_api, int_api, bob_private_key, fee, name_fee) print("Bob has registered " + bob_name) bob_balance1 = common.get_account_balance(ext_api, bob_address) print("Bob balance is " + str(bob_balance1)) tokens_to_send = test_settings["spend_tx"]["amount"] print("Alice is about to send " + str(tokens_to_send) + " to " + bob_name) resolved_address = get_address_by_name(bob_name, ext_api) common.ensure_send_tokens(alice, resolved_address, tokens_to_send, spend_fee, ext_api, int_api, 1) # validate balances alice_balance2 = common.get_account_balance(ext_api, alice_address) bob_balance2 = common.get_account_balance(ext_api, bob_address) print("Alice balance is " + str(alice_balance2)) print("Bob balance is " + str(bob_balance2)) # Alice's balance should be decresed by the amount being send and the fee (1) assert_equals(alice_balance2, alice_balance0 - tokens_to_send - spend_fee) # Bob's balance should be incresed by the amount being send assert_equals(bob_balance2, bob_balance1 + tokens_to_send) # stop node common.stop_node(node) shutil.rmtree(root_dir)
def _cleanup_node_(node_makefile_id, node_root_dir): import common import shutil common.stop_node(node_makefile_id) shutil.rmtree(node_root_dir)
def test_not_enough_tokens(): # Bob should not be able to send more tokens than he has # # Let's say Bob has 100 tokens. He should not be able to send more than # 100 tokens to Alice. # # If there's an incoming but unconfirmed deposit into Bob's account then Bob # should not be able to use the incoming tokens until the spend transaction # they are in is confirmed. test_settings = settings["test_not_enough_tokens"] beneficiary = common.setup_beneficiary() (node, (root_dir, ext_api, int_api, top)) = setup_node_with_tokens(test_settings, beneficiary, "miner") alice_address = keys.address(keys.public_key(keys.new_private())) bob_private_key = keys.new_private() bob_public_key = keys.public_key(bob_private_key) bob_address = keys.address(bob_public_key) bob = {'privk': bob_private_key, 'enc_pubk': bob_address} # initial balances - amounts that the miner should send them alice_init_balance = test_settings["send_tokens"]["alice"] bob_init_balance = test_settings["send_tokens"]["bob"] # populate accounts with tokens, and validate balances spend_tx_fee = test_settings["spend_tx"]["fee"] common.ensure_send_tokens(beneficiary, alice_address, alice_init_balance, spend_tx_fee, ext_api, int_api, 1) common.ensure_send_tokens(beneficiary, bob_address, bob_init_balance, spend_tx_fee, ext_api, int_api, 1) alice_balance0 = common.get_account_balance(ext_api, alice_address) bob_balance0 = common.get_account_balance(ext_api, bob_address) print("Alice balance is " + str(alice_balance0)) print("Bob balance is " + str(bob_balance0)) assert_equals(alice_balance0, alice_init_balance) assert_equals(bob_balance0, bob_init_balance) # check that Bob is able to send less tokens than he has few_tokens_to_send = test_settings["spend_tx"]["small_amount"] print("Bob is about to send " + str(few_tokens_to_send) + " to Alice") common.ensure_send_tokens(bob, alice_address, few_tokens_to_send, spend_tx_fee, ext_api, int_api, 1) alice_balance1 = common.get_account_balance(ext_api, pub_key=alice_address) bob_balance1 = common.get_account_balance(ext_api, pub_key=bob_address) print("Alice balance is " + str(alice_balance1)) print("Bob balance is " + str(bob_balance1)) assert_equals(alice_balance1, alice_balance0 + few_tokens_to_send) assert_equals(bob_balance1, bob_balance0 - (few_tokens_to_send + spend_tx_fee)) # check that Bob is unable to send less tokens than he has many_tokens_to_send = test_settings["spend_tx"]["large_amount"] print("Bob is about to send " + str(many_tokens_to_send) + " to Alice") common.send_tokens(bob, alice_address, many_tokens_to_send, spend_tx_fee, ext_api, int_api) current_key_block = ext_api.GetCurrentKeyBlock().response().result common.wait_until_height(ext_api, current_key_block.height + 3) alice_balance2 = common.get_account_balance(ext_api, pub_key=alice_address) bob_balance2 = common.get_account_balance(ext_api, pub_key=bob_address) print("Alice balance is " + str(alice_balance2)) print("Bob balance is " + str(bob_balance2)) assert_equals(alice_balance2, alice_balance1) assert_equals(bob_balance2, bob_balance1) # stop node common.stop_node(node) shutil.rmtree(root_dir)
transfer1 = rpc.address.list(type='transfer')[0] txid = rpc.staking.withdraw_all_unbonded(unbonded, transfer1, enckey=enckey) wait_for_tx(rpc, txid) rpc.wallet.sync() addresses = [rpc.address.create(type='transfer') for i in range(10)] amount = 100000000 for addr in addresses: txid = rpc.wallet.send(addr, amount) wait_for_tx(rpc, txid) rpc.wallet.sync() print('Stop node1') stop_node(supervisor, 'node1') last_height = latest_block_height(rpc) print('Send multiple tx') pending_txs = [rpc.wallet.send(transfer1, amount) for _ in addresses] time.sleep(1) # Wait a little bit for the tx processing print('Start node1') supervisor.supervisor.startProcessGroup('node1') print('Wait for transaction execution') for txid in pending_txs: wait_for_tx(rpc, txid, timeout=20) print('Print num_txs in recent blocks')
def cleanup(node, root_dir): common.stop_node(node) shutil.rmtree(root_dir)
def test_persistence(): """ Test persistence: Bob's downloaded blockchain should persist between restarts. He should only download updates to his blockchain when his node starts. """ test_settings = settings["test_persistence"] # prepare a dir to hold the config and DB files root_dir = tempfile.mkdtemp() p_m_conf = """\ --- chain: persist: true db_path: \"""" + root_dir + """\" mining: autostart: true expected_mine_rate: 100 beneficiary: "ak_2QLChDdERfod9QajLkCTsJnYP3RNqZJmAFWQWQZWr99fSrC55h" cuckoo: edge_bits: 15 miners: - executable: mean15-generic extra_args: "" """ p_conf = """\ --- chain: persist: true db_path: \"""" + root_dir + """\" mining: beneficiary: "ak_2QLChDdERfod9QajLkCTsJnYP3RNqZJmAFWQWQZWr99fSrC55h" """ persistence_mining_user_config = common.install_user_config( root_dir, "p_m_aeternity.yaml", p_m_conf) minimal_user_config_with_persistence = common.install_user_config( root_dir, "p_aeternity.yaml", p_conf) bob_node = test_settings["nodes"]["bob"] common.start_node(bob_node, persistence_mining_user_config) bob_api = common.external_api(bob_node) # Insert some blocks in Bob's chain blocks_to_mine = test_settings["blocks_to_mine"] common.wait_until_height(bob_api, blocks_to_mine) bob_top = bob_api.get_current_key_block() assert_equals(bob_top.height >= blocks_to_mine, True) # Now Bob has at least blocks_to_mine blocks common.stop_node(bob_node) common.start_node(bob_node, minimal_user_config_with_persistence) bob_new_top = bob_api.get_current_key_block() if (bob_new_top.height > bob_top.height): # Bob's node had mined another block(s) before being stopped bob_block = bob_api.get_key_block_by_hash( bob_top.hash) # this block is presnet assert_equals(bob_block.height, bob_top.height) else: assert_equals(bob_new_top.height, bob_top.height) assert_equals(bob_top.hash, bob_new_top.hash) common.stop_node(bob_node) shutil.rmtree(root_dir)
def test_node_discovery(): """ Test node discovery Assuming Carol's node only knows about Bob upon startup and that Bob's node knows Alice, Carol's node should be able to discover Alice and sync with her node. """ test_settings = settings["test_node_discovery"] alice_node = test_settings["nodes"]["alice"] bob_node = test_settings["nodes"]["bob"] carol_node = test_settings["nodes"]["carol"] alice_peer_url = node_peer_url(alice_node) bob_peer_url = node_peer_url(bob_node) carol_peer_url = node_peer_url(carol_node) # prepare a dir to hold the configs root_dir = tempfile.mkdtemp() # Alice's config: no peers alice_sys_config = make_peers_config(root_dir, "alice.config", alice_peer_url, [], mining=True) print("\nAlice has address " + alice_peer_url + " and no peers") # Bob's config: only peer is Alice bob_sys_config = make_peers_config(root_dir, "bob.config", bob_peer_url, [alice_peer_url], mining=False) print("Bob has address " + bob_peer_url + " and peers [" + alice_peer_url + "]") # Carol's config: only peer is Bob carol_sys_config = make_peers_config(root_dir, "carol.config", carol_peer_url, [bob_peer_url], mining=False) print("Carol has address " + carol_peer_url + " and peers [" + bob_peer_url + "]") # start Alice's node common.start_node(alice_node, alice_sys_config) alice_api = common.external_api(alice_node) # Insert some blocks in Alice's chain blocks_to_mine = test_settings["blocks_to_mine"] common.wait_until_height(alice_api, blocks_to_mine) alice_top = alice_api.get_top() assert_equals(alice_top.height >= blocks_to_mine, True) # Now Alice has at least blocks_to_mine blocks # start the other nodes common.start_node(bob_node, bob_sys_config) common.start_node(carol_node, carol_sys_config) time.sleep(1) # give some time for the data to propagate carol_api = common.external_api(carol_node) carol_top = carol_api.get_top() gen_hash = common.genesis_hash(carol_api) ping_obj = Ping(source="localhost", genesis_hash=gen_hash, best_hash=carol_top.hash, difficulty=1, share=32, peers=[]) ping = carol_api.ping(ping_obj) carol_peers = ping.peers synced = len(list(filter(lambda peer: peer == alice_peer_url, carol_peers))) == 1 print("Carol now has peers " + str(carol_peers)) assert_equals(synced, True) # for larger peer lists this might be too fragile assert_equals(carol_top.height >= blocks_to_mine, True) if carol_top.height > alice_top.height: # Alice had mined some more blocks alice_block = alice_api.get_block_by_hash(carol_top.hash) # this block is presnet assert_equals(alice_block.height, carol_top.height) else: assert_equals(alice_top.height, carol_top.height) # cleanup common.stop_node(alice_node) common.stop_node(bob_node) common.stop_node(carol_node) shutil.rmtree(root_dir)