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 cuckoo: miner: executable: mean16s-generic extra_args: "-t 5" node_bits: 16 """ p_conf = """\ --- chain: persist: true db_path: \"""" + root_dir + """\" """ persistence_mining_user_config = common.install_user_config(root_dir, "p_m_epoch.yaml", p_m_conf) only_persistence_user_config = common.install_user_config(root_dir, "p_epoch.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_top() 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, only_persistence_user_config) bob_new_top = bob_api.get_top() if(bob_new_top.height > bob_top.height): # Bob's node had mined another block(s) before being stopped bob_block = bob_api.get_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_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() persistance_mining_sys_config = os.path.join(root_dir, "p_m_sys.config") only_persistance_sys_config = os.path.join(root_dir, "p_sys.config") f = open(persistance_mining_sys_config, "w") # this should be moved to an YAML once we have YAML node configuration f.write('[{aecore, [{db_path, "' + root_dir + '"},' + \ ' {persist, true},' + \ ' {autostart, true},' + \ ' {expected_mine_rate, 100},' + \ ' {aec_pow_cuckoo, {"mean16s-generic", "-t 5", 16}}' + \ ']}].') f.close() f = open(only_persistance_sys_config, "w") # this should be moved to an YAML once we have YAML node configuration f.write('[{aecore, [{db_path, "' + root_dir + '"},' + \ ' {persist, true}' + \ ']}].') f.close() bob_node = test_settings["nodes"]["bob"] common.start_node(bob_node, persistance_mining_sys_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_top() 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, only_persistance_sys_config) bob_new_top = bob_api.get_top() if (bob_new_top.height > bob_top.height): # Bob's node had mined another block(s) before being stopped bob_block = bob_api.get_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 setup_node(test_settings, node_name): # prepare a dir to hold the configs and the keys root_dir = tempfile.mkdtemp() # setup the dir with Alice's node mining node = test_settings["nodes"][node_name] sys_config = make_mining_config(root_dir, "sys.config") common.start_node(node, sys_config) api = common.external_api(node) return (root_dir, node, api)
def test_syncing(): """ Test node syncing: Alice should be able to connect to peers on startup and download the blockchain up to the current height. """ test_settings = settings["test_syncing"] root_dir = tempfile.mkdtemp() mining_user_config = make_fast_mining_user_config(root_dir, "mining_epoch.yaml") no_mining_user_config = make_no_mining_user_config(root_dir, "no_mining_epoch.yaml") # start Bob's node bob_node = test_settings["nodes"]["bob"] common.start_node(bob_node, 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"] print("Bob is mining") common.wait_until_height(bob_api, blocks_to_mine) bob_top = bob_api.get_top_block() assert_equals(bob_top.height >= blocks_to_mine, True) # Now Bob has at least blocks_to_mine blocks print("Bob has mined " + str(bob_top.height) + " blocks") # start Alice's node and let it connect with Bob's # note: Alice doesn't mine blocks alice_node = test_settings["nodes"]["alice"] common.start_node(alice_node, no_mining_user_config) print("Alice is not mining") alice_api = common.external_api(alice_node) common.wait_until_height(alice_api, blocks_to_mine) alice_top = alice_api.get_top_block() assert_equals(alice_top.height >= blocks_to_mine, True) if alice_top.height > bob_top.height: # bob had mined more blocks bob_block = bob_api.get_block_by_hash( alice_top.hash) # this block is presnet assert_equals(bob_block.height, alice_top.height) else: assert_equals(alice_top.height, bob_top.height) assert_equals(alice_top.hash, bob_top.hash) print("Alice's had synced with Bob and now Alice's top has height " + str(alice_top.height)) # stop both nodes common.stop_node(bob_node) common.stop_node(alice_node) shutil.rmtree(root_dir)
def setup_node_with_tokens(test_settings, node_name): # prepare a dir to hold the configs and the keys root_dir = tempfile.mkdtemp() # setup the dir with Alice's node mining node = test_settings["nodes"][node_name] sys_config = make_mining_config(root_dir, "sys.config") common.start_node(node, sys_config) api = common.external_api(node) # populate the chain so Alice had mined some blocks and has tokens # to spend blocks_to_mine = test_settings["blocks_to_mine"] common.wait_until_height(api, blocks_to_mine) top = api.get_top() assert_equals(top.height >= blocks_to_mine, True) # Now the node has at least blocks_to_mine blocks mined by Alice return (root_dir, node, api, top)
def test_syncing(): """ Test node syncing: Alice should be able to connect to peers on startup and download the blockchain up to the current height. """ # start Bob's node bob_node = "dev1" common.start_node(bob_node) bob_api = common.external_api(bob_node) # Insert a block in Bob's chain common.post_fake_block(bob_api) wait(lambda: bob_api.get_top().height == 1, timeout_seconds=3, sleep_seconds=0.5) bob_top = bob_api.get_top() assert_equals(bob_top.height, 1) # Now Bob has 2 blocks: with height 0 (genesis) and 1 # start Alice's node and let it connect with Bob's alice_node = "dev2" common.start_node(alice_node) alice_api = common.external_api(alice_node) wait(lambda: alice_api.get_top().height == 1, timeout_seconds=3, sleep_seconds=0.5) alice_top = alice_api.get_top() assert_equals(alice_top.height, 1) # Alice has 2 blocks, too # ensure that both nodes have the same hash on block with height=1 assert_equals(alice_top.hash, bob_top.hash) # stop both nodes common.stop_node(bob_node) common.stop_node(alice_node)
def test_node_discovery_from_common_friend(): """ Test node discovery (from common friend peer) Assuming Carol's node only knows about Bob upon startup and that Alice's node knows Bob, Carol's node should be able to discover Alice and sync with her node. """ test_settings = settings["test_node_discovery_from_common_friend"] 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: only peer is Bob alice_peers = """\ peers: - "aenode://pp$28uQUgsPcsy7TQwnRxhF8GMKU4ykFLKsgf4TwDwPMNaSCXwWV8@localhost:3025" """ alice_user_config = make_peers_user_config(root_dir, "alice_epoch.yaml", "node1", "3015", alice_peers, "true") # Bob's config: no peers bob_peers = "peers: []" 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://[email protected]: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 setup_func(): if common.should_start_node(node): print("Node " + node + " starting") common.start_node(node)
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)
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, "node1", "3015", '{peers, []},', mining=True) print("\nAlice has address " + alice_peer_url + " and no peers") # Bob's config: only peer is Alice bob_peers = ' {peers, [<<"aenode://pp$HdcpgTX2C1aZ5sjGGysFEuup67K9XiFsWqSPJs4RahEcSyF7X@localhost:3015">>]}, ' bob_sys_config = make_peers_config(root_dir, "bob.config", bob_peer_url, "node2", "3025", bob_peers, mining=False) print("Bob has address " + bob_peer_url + " and peers [" + alice_peer_url + "]") # Carol's config: only peer is Bob carol_peers = ' {peers, [<<"aenode://pp$28uQUgsPcsy7TQwnRxhF8GMKU4ykFLKsgf4TwDwPMNaSCXwWV8@localhost:3025">>]}, ' carol_sys_config = make_peers_config(root_dir, "carol.config", carol_peer_url, "node3", "3035", carol_peers, 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 carol_int_api = common.internal_api(carol_node) def carol_peers(): peers = carol_int_api.get_peers().peers print("Peers: " + str(peers)) return peers wait( lambda: 'aenode://pp$HdcpgTX2C1aZ5sjGGysFEuup67K9XiFsWqSPJs4RahEcSyF7X@localhost:3015' in carol_peers(), 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 setup_func(): common.start_node(node)
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_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)