def check(state_engine): global zonefile_hash # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: print "namespace reveal exists" return False ns = state_engine.get_namespace("test") if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "name does not exist" return False # owned by owner_address = wallets[3].addr if name_rec['address'] != owner_address or name_rec[ 'sender'] != virtualchain.make_payment_script(owner_address): print "sender is wrong" return False # value hash if name_rec['value_hash'] != zonefile_hash: print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'], zonefile_hash) return False # replicated? zonefile = testlib.ysi_get_zonefile(zonefile_hash) if 'error' in zonefile: print "zonefile error: %s" % zonefile['error'] return False # right hash? if ysi_client.hash_zonefile(zonefile) != zonefile_hash: print "wrong zonefile: %s != %s" % (ysi_client.hash_zonefile(zonefile), zonefile_hash) return False # all queues are drained queue_info = testlib.ysi_client_queue_state() if len(queue_info) > 0: print "Still in queue:\n%s" % json.dumps( queue_info, indent=4, sort_keys=True) return False return True
def check(state_engine): global zonefile_hash # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: print "namespace reveal exists" return False ns = state_engine.get_namespace("test") if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "name does not exist" return False # owned by owner_address = wallets[4].addr if name_rec['address'] != owner_address or name_rec[ 'sender'] != virtualchain.make_payment_script(owner_address): print "sender is wrong" return False # value hash if name_rec['value_hash'] != zonefile_hash: print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'], zonefile_hash) return False # replicated? zonefile = testlib.ysi_get_zonefile(zonefile_hash) if 'error' in zonefile: print "zonefile error: %s" % zonefile['error'] return False # right hash? if ysi_client.hash_zonefile(zonefile) != zonefile_hash: print "wrong zonefile: %s != %s" % (ysi_client.hash_zonefile(zonefile), zonefile_hash) return False # latest key? if not zonefile.has_key("txt"): print "no txt:\n%s" % json.dumps(zonefile, indent=4, sort_keys=True) return False if len(zonefile['txt']) != 2: print "wrong number of txt records:\n%s" % json.dumps( zonefile, indent=4, sort_keys=True) return False for txtrec in zonefile['txt']: if txtrec['name'] == 'pubkey': if new_data_pubkey not in txtrec['txt']: print "wrong pubkey:\n%s" % json.dumps( zonefile, indent=4, sort_keys=True) print "missing %s" % new_data_pubkey return False names_owned = testlib.ysi_cli_names() if 'error' in names_owned: print "rpc names: %s" % names_owned['error'] return False # we still own the name if len(names_owned['names_owned']) != 1: print "owned: %s" % names_owned['names_owned'] return False # all queues are drained queue_info = testlib.ysi_client_queue_state() if len(queue_info) > 0: print "Still in queue:\n%s" % json.dumps( queue_info, indent=4, sort_keys=True) return False return True
def scenario( wallets, **kw ): global synchronized import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) for i in xrange(0, 10): res = testlib.ysi_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # start up a simple Atlas test network with two nodes: the main one doing the test, and a subordinate one that treats it as a seed peer. network_des = atlas_network.atlas_network_build( [17000], {17000: [16264]}, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" )) atlas_network.atlas_network_start( network_des ) time.sleep(5.0) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] ) empty_zonefile_str = ysi_zones.make_zone_file( empty_zonefile ) value_hash = ysi_client.hash_zonefile( empty_zonefile ) res = testlib.ysi_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # wait at most 10 seconds for atlas network to converge synchronized = False for i in xrange(0, 10): atlas_network.atlas_print_network_state( network_des ) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ): print "Synchronized!" synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop( network_des ) return synchronized
def scenario(wallets, **kw): global synchronized, value_hash import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) for i in xrange(0, 10): res = testlib.ysi_name_register("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer # organize nodes into a linear chain: node n is neighbor to n-1 and n+1, with the seed at one end. # nodes cannot talk to anyone else. atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007] atlas_topology = {} atlas_topology[17000] = [16264, 17001] atlas_topology[17007] = [17006] for i in xrange(1, len(atlas_nodes) - 1): atlas_topology[atlas_nodes[i]] = [ atlas_nodes[i - 1], atlas_nodes[i + 1] ] def chain_drop(src_hostport, dest_hostport): if src_hostport is None: return 0.0 src_host, src_port = ysi_client.utils.url_to_host_port(src_hostport) dest_host, dest_port = ysi_client.utils.url_to_host_port(dest_hostport) if (src_port == 16264 and dest_port == 17000) or (src_port == 17000 and dest_port == 16264): # seed end of the chain return 0.0 if abs(src_port - dest_port) <= 1: # chain link return 0.0 # drop otherwise return 1.0 network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join(testlib.working_dir(**kw), "atlas_network")) atlas_network.atlas_network_start(network_des, drop_probability=chain_drop) print "Waiting 25 seconds for the altas peers to catch up" time.sleep(25.0) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey( wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)]) empty_zonefile_str = ysi_zones.make_zone_file(empty_zonefile) value_hash = ysi_client.hash_zonefile(empty_zonefile) res = testlib.ysi_name_update("foo_{}.test".format(i), value_hash, wallets[3].privkey) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # wait at most 60 seconds for atlas network to converge synchronized = False for i in xrange(0, 60): atlas_network.atlas_print_network_state(network_des) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block(**kw) - 1, 1): print "Synchronized!" sys.stdout.flush() synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop(network_des) if not synchronized: print "Not synchronized" sys.stdout.flush() return synchronized
def scenario(wallets, **kw): global value_hashes testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) for i in xrange(0, 10): res = testlib.ysi_name_register("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = wallets[4].pubkey_hex empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)]) empty_zonefile_str = ysi_zones.make_zone_file(empty_zonefile) value_hash = ysi_client.hash_zonefile(empty_zonefile) res = testlib.ysi_name_update("foo_{}.test".format(i), value_hash, wallets[3].privkey) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False value_hashes.append(value_hash) print 'waiting for all zone files to replicate' time.sleep(10) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG") assert config_path restore_dir = os.path.join(os.path.dirname(config_path), "snapshot_dir") # snapshot the latest backup snapshot_path = os.path.join(os.path.dirname(config_path), "snapshot.bsk") rc = ysi.fast_sync_snapshot(snapshot_path, wallets[3].privkey, None) if not rc: print "Failed to fast_sync_snapshot" return False if not os.path.exists(snapshot_path): print "Failed to create snapshot {}".format(snapshot_path) return False # sign with more keys for i in xrange(4, 6): rc = ysi.fast_sync_sign_snapshot(snapshot_path, wallets[i].privkey) if not rc: print "Failed to sign with key {}".format(i) return False # restore! rc = restore( snapshot_path, restore_dir, [wallets[3].pubkey_hex, wallets[4].pubkey_hex, wallets[5].pubkey_hex], 3) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore( snapshot_path, restore_dir, [wallets[5].pubkey_hex, wallets[4].pubkey_hex, wallets[3].pubkey_hex], 3) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore(snapshot_path, restore_dir, [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 2) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore(snapshot_path, restore_dir, [wallets[3].pubkey_hex, wallets[5].pubkey_hex], 2) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore(snapshot_path, restore_dir, [wallets[4].pubkey_hex, wallets[5].pubkey_hex], 2) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore(snapshot_path, restore_dir, [wallets[3].pubkey_hex], 1) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore(snapshot_path, restore_dir, [wallets[4].pubkey_hex, wallets[0].pubkey_hex], 1) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore( snapshot_path, restore_dir, [wallets[0].pubkey_hex, wallets[1].pubkey_hex, wallets[5].pubkey_hex], 1) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False # should fail rc = restore(snapshot_path, restore_dir, [wallets[3].pubkey_hex], 2) if rc: print "restored insufficient signatures snapshot {}".format( snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore(snapshot_path, restore_dir, [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 3) if rc: print "restored insufficient signatures snapshot {}".format( snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore(snapshot_path, restore_dir, [wallets[0].pubkey_hex], 1) if rc: print "restored wrongly-signed snapshot {}".format(snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore(snapshot_path, restore_dir, [wallets[0].pubkey_hex, wallets[3].pubkey_hex], 2) if rc: print "restored wrongly-signed snapshot {}".format(snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore( snapshot_path, restore_dir, [wallets[0].pubkey_hex, wallets[3].pubkey_hex, wallets[4].pubkey_hex], 3) if rc: print "restored wrongly-signed snapshot {}".format(snapshot_path) return False shutil.rmtree(restore_dir)
def check(state_engine): global zonefile_hash, new_expire_block # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: print "namespace reveal exists" return False ns = state_engine.get_namespace("test") if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "name does not exist" return False # owned by owner_address = wallets[3].addr if name_rec['address'] != owner_address or name_rec[ 'sender'] != virtualchain.make_payment_script(owner_address): print "sender is wrong" return False # value hash if name_rec['value_hash'] != zonefile_hash: print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'], zonefile_hash) return False # replicated? zonefile = testlib.ysi_get_zonefile(zonefile_hash) if 'error' in zonefile: print "zonefile error: %s" % zonefile['error'] return False # right hash? if ysi_client.hash_zonefile(zonefile) != zonefile_hash: print "wrong zonefile: %s != %s" % (ysi_client.hash_zonefile(zonefile), zonefile_hash) return False # all queues are drained queue_info = testlib.ysi_client_queue_state() if len(queue_info) > 0: print "Still in queue:\n%s" % json.dumps( queue_info, indent=4, sort_keys=True) return False # final balance is correct? name_fee = ysi_server.price_name("foo", ns, new_expire_block) preorder_dust_fees = 3 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE register_dust_fees = 4 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE renewal_dust_fees = 3 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE total_fee = name_fee * 2 + preorder_dust_fees + register_dust_fees + renewal_dust_fees payment_address = wallets[2].addr # TODO: check return True
def scenario( wallets, **kw ): global synchronized, value_hash import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) for i in xrange(0, 10): res = testlib.ysi_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] ) empty_zonefile_str = ysi_zones.make_zone_file( empty_zonefile ) value_hash = ysi_client.hash_zonefile( empty_zonefile ) res = testlib.ysi_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer # only the seed node will be publicly routable; the other 8 will be unable to directly talk to each other. atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007] atlas_topology = {} for node_port in atlas_nodes: atlas_topology[node_port] = [16264] def nat_drop(src_hostport, dest_hostport): if dest_hostport is None: return 0.0 host, port = ysi_client.utils.url_to_host_port( dest_hostport ) if port in atlas_nodes: # connections to the above nodes will always fail, since they're NAT'ed return 1.0 else: # connections to the seed node always succeed return 0.0 network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ) ) atlas_network.atlas_network_start( network_des, drop_probability=nat_drop ) print "Waiting 60 seconds for the altas peers to catch up" time.sleep(60.0) # wait at most 60 seconds for atlas network to converge synchronized = False for i in xrange(0, 60): atlas_network.atlas_print_network_state( network_des ) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ): print "Synchronized!" synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop( network_des ) return synchronized
def scenario(wallets, **kw): global synchronized, value_hash import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) for i in xrange(0, 10): res = testlib.ysi_name_register("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey( wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)]) empty_zonefile_str = ysi_zones.make_zone_file(empty_zonefile) value_hash = ysi_client.hash_zonefile(empty_zonefile) res = testlib.ysi_name_update("foo_{}.test".format(i), value_hash, wallets[3].privkey) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # start up an atlas network with 16 peers, 8 of which will be active at once. # every second, have one peer come online, and one peer go offline. # have them all start out knowing about the same seed node. atlas_nodes = [ 17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007, 17008, 17009, 17010, 17011, 17012, 17013, 17014, 17015, 17016 ] atlas_topology = {} for i in xrange(0, 9): atlas_topology[atlas_nodes[i]] = [16264] for i in xrange(9, len(atlas_nodes)): atlas_topology[atlas_nodes[i]] = [17008] atlas_topology[atlas_nodes[-1]].append(16264) # put the seed after the first four all_peers = atlas_nodes[:4] + [16264] + atlas_nodes[4:] time_start = int(time.time()) + 60 def churn_drop(src_hostport, dest_hostport): if src_hostport is None: return 0.0 src_host, src_port = ysi_client.utils.url_to_host_port(src_hostport) dest_host, dest_port = ysi_client.utils.url_to_host_port(dest_hostport) now = int(time.time()) # offset = (now - time_start) % len(all_peers) offset = now % len(all_peers) sample = all_peers + all_peers active_range = sample[offset:offset + 8] print "Active range: %s, request (%s --> %s)" % (active_range, src_port, dest_port) if src_port not in active_range: # dead return 1.0 if dest_port not in active_range: # dead return 1.0 return 0.0 network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join(testlib.working_dir(**kw), "atlas_network")) atlas_network.atlas_network_start(network_des, drop_probability=churn_drop) print "Waiting 120 seconds for the altas peers to catch up" time.sleep(120.0) # wait at most 60 seconds for atlas network to converge synchronized = False for i in xrange(0, 60): atlas_network.atlas_print_network_state(network_des) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block(**kw) - 1, 1): print "Synchronized!" synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop(network_des) return synchronized
def check(state_engine): # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: print "namespace reveal exists" return False ns = state_engine.get_namespace("test") if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "name does not exist" return False # owned by the right address owner_address = wallets[4].addr if name_rec['address'] != owner_address or name_rec[ 'sender'] != virtualchain.make_payment_script(owner_address): print "sender is wrong" return False # all queues are drained queue_info = testlib.ysi_client_queue_state() if len(queue_info) > 0: print "Still in queue:\n%s" % json.dumps( queue_info, indent=4, sort_keys=True) return False # have an update hash if 'value_hash' not in name_rec or name_rec.get('value_hash', None) is None: print "No value hash" return False # have a zonefile zonefile = testlib.ysi_get_zonefile(name_rec['value_hash']) if zonefile is None or 'error' in zonefile: if zonefile is not None: print "zonefile lookup error: %s" % zonefile['error'] else: print "no zonefile returned" return False # hashes to this zonefile if ysi_client.hash_zonefile(zonefile) != name_rec['value_hash']: print "wrong zonefile: %s != %s" % (ysi_client.hash_zonefile(zonefile), name_rec['value_hash']) return False # zonefile has the right data public key zonefile_pubk = ysi_client.user.user_zonefile_data_pubkey(zonefile) if keylib.key_formatting.compress( zonefile_pubk) != keylib.key_formatting.compress( wallets[4].pubkey_hex) or zonefile_pubk is None: print 'pubkey mismatch: {} != {}'.format(zonefile_pubk, wallets[4].pubkey_hex) return False # zonefile has the right drivers zonefile_urls = ysi_client.user.user_zonefile_urls(zonefile) driver_urls = ysi_client.storage.make_mutable_data_urls( 'foo.test', use_only=['dht', 'disk']) if driver_urls != zonefile_urls: print 'url mismatch: {} != {}'.format(driver_urls, zonefile_urls) return False # verify that the profile is NOT there profile = testlib.ysi_get_profile("foo.test") if profile is not None and 'error' not in profile: print 'make a profile by mistake: {}'.format(profile) return False return True
def check(state_engine): # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: print "namespace reveal exists" return False ns = state_engine.get_namespace("test") if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "name does not exist" return False # owned by the right address owner_address = wallets[4].addr if name_rec['address'] != owner_address or name_rec[ 'sender'] != virtualchain.make_payment_script(owner_address): print "sender is wrong" print "%s != %s or %s != %s" % ( name_rec['address'], owner_address, name_rec['sender'], virtualchain.make_payment_script(owner_address)) return False # all queues are drained queue_info = testlib.ysi_client_queue_state() if len(queue_info) > 0: print "Still in queue:\n%s" % json.dumps( queue_info, indent=4, sort_keys=True) return False # have an update hash if 'value_hash' not in name_rec or name_rec.get('value_hash', None) is None: print "No value hash" return False # have a zonefile zonefile = testlib.ysi_get_zonefile(name_rec['value_hash']) if zonefile is None or 'error' in zonefile: if zonefile is not None: print "zonefile lookup error: %s" % zonefile['error'] else: print "no zonefile returned" return False # hashes to this zonefile if ysi_client.hash_zonefile(zonefile) != name_rec['value_hash']: print "wrong zonefile: %s != %s" % (ysi_client.hash_zonefile(zonefile), name_rec['value_hash']) return False # verify that the profile is there profile = testlib.ysi_get_profile("foo.test") if profile is None or 'error' in profile: if profile is None: print "no profile returned" else: print "profile lookup error: %s" % profile['error'] return False return True
def check( state_engine ): global preorder_info, register_info, update_info, balance_before, balance_after, names_owned_before, names_owned_after, whois, blockchain_record, deposit_info, price_info global blockchain_history, zonefile_info, all_names_info, namespace_names_info, wallet_info, lookup_info, update_history, zonefile_history, names_info # not revealed, but ready ns = state_engine.get_namespace_reveal( "test" ) if ns is not None: print "namespace reveal exists" return False ns = state_engine.get_namespace( "test" ) if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False # registered name_rec = state_engine.get_name( "foo.test" ) if name_rec is None: print "name does not exist" return False # owned by the right address owner_address = wallets[3].addr if name_rec['address'] != owner_address or name_rec['sender'] != virtualchain.make_payment_script(owner_address): print "sender is wrong" return False # all queues are drained queue_info = testlib.ysi_client_queue_state() if len(queue_info) > 0: print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True) return False # have an update hash if 'value_hash' not in name_rec or name_rec.get('value_hash', None) is None: print "No value hash" return False # have a zonefile zonefile = testlib.ysi_get_zonefile( name_rec['value_hash'] ) if zonefile is None or 'error' in zonefile: if zonefile is not None: print "zonefile lookup error: %s" % zonefile['error'] else: print "no zonefile returned" return False # hashes to this zonefile if ysi_client.hash_zonefile( zonefile ) != name_rec['value_hash']: print "wrong zonefile: %s != %s" % (ysi_client.hash_zonefile(zonefile), name_rec['value_hash']) return False # verify that the profile is there profile = testlib.ysi_get_profile( "foo.test" ) if profile is None or 'error' in profile: if profile is None: print "no profile returned" else: print "profile lookup error: %s" % profile['error'] return False # check queue operations for queue_type, queue_state in [("preorder", preorder_info), ("register", register_info), ("update", update_info)]: if not queue_state.has_key('queues'): print "missing queues:\n%s" % json.dumps(queue_state, indent=4, sort_keys=True) return False for k in ['name', 'confirmations', 'tx_hash']: for q in queue_state['queues'][queue_type]: if not q.has_key(k): print "missing key %s\n%s" % (k, json.dumps(queue_state, indent=4, sort_keys=True)) return False if q['name'] != 'foo.test': print "wrong name: %s" % queue_state['name'] return False # check price for k in ['preorder_tx_fee', 'register_tx_fee', 'total_estimated_cost', 'name_price']: if not price_info.has_key(k): print "bad price info (missing %s):\n%s" % (k, json.dumps(price_info, indent=4, sort_keys=True)) return False # deposit info if not deposit_info.has_key('address') or deposit_info['address'] != wallets[2].addr: print "bad deposit info:\n%s" % json.dumps(deposit_info, indent=4, sort_keys=True) return False # whois info for k in ['block_preordered_at', 'block_renewed_at', 'last_transaction_id', 'owner_address', 'owner_script', 'expire_block', 'has_zonefile', 'zonefile_hash']: if not whois.has_key(k): print "bad whois: missing %s\n%s" % (k, json.dumps(whois, indent=4, sort_keys=True)) return False # balance for balance_info in [balance_before, balance_after]: for k in ['total_balance', 'addresses']: if not balance_info.has_key(k): print "missing '%s'\n%s" % (k, json.dumps(balance_info, indent=4, sort_keys=True)) return False # name listing if len(names_owned_before) != 0: print "owned before: %s" % names_owned_before return False if len(names_owned_after) != 1 or names_owned_after[0] != 'foo.test': print "owned after: %s" % names_owned_after return False # blockchain record for k in ['name', 'op', 'op_fee', 'opcode', 'vtxindex', 'txid', 'value_hash', 'sender', 'address', 'history']: if not blockchain_record.has_key(k): print "missing %s\n%s" % (k, json.dumps(blockchain_record, indent=4, sort_keys=True)) return False # blockchain history (should have a preorder, register, and 2 updates) if len(blockchain_history) != 4: print "invalid history\n%s\n" % json.dumps(blockchain_history, indent=4, sort_keys=True) return False block_heights = blockchain_history.keys() block_heights.sort() expected_opcodes = ['NAME_PREORDER', 'NAME_REGISTRATION', 'NAME_UPDATE', 'NAME_UPDATE'] for bh, opcode in zip(block_heights, expected_opcodes): if len(blockchain_history[bh]) != 1: print "invalid history: multiple ops at %s\n%s" % (bh, json.dumps(blockchain_history, indent=4, sort_keys=True)) return False if blockchain_history[bh][0]['opcode'] != opcode: print "invalid history: expected %s at %s\n%s" % (opcode, bh, json.dumps(blockchain_history, indent=4, sort_keys=True)) return False # zonefile info if zonefile_info is None or type(zonefile_info) != str: print "invalid zonefile\n%s\n" % zonefile_info return False # name query if type(all_names_info) == dict and 'error' in all_names_info: print "error in all_names: %s" % all_names_info return False all_names = all_names_info if len(all_names) != 1 or all_names != ['foo.test']: print "all names: %s" % all_names return False # namespace query if type(namespace_names_info) == dict and 'error' in namespace_names_info: print "error in namesace_names: %s" % namespace_names_info return False namespace_names = namespace_names_info if len(namespace_names) != 1 or namespace_names != ['foo.test']: print "all namespace names: %s" % namespace_names return False # wallet info for k in ['payment_privkey', 'owner_privkey', 'data_privkey', 'payment_address', 'owner_address', 'data_pubkey']: if not wallet_info.has_key(k): print "missing %s\n%s" % (k, json.dumps(wallet_info, indent=4, sort_keys=True)) return False # profile info for k in ['profile', 'zonefile']: if not lookup_info.has_key(k): print "missing '%s'\n%s" % (k, json.dumps(lookup_info, indent=4, sort_keys=True)) return False if lookup_info['zonefile'] != zonefile_info: print "unequal zonefiles:\n%s\n%s" % (json.dumps(lookup_info['zonefile'], indent=4, sort_keys=True), json.dumps(zonefile_info, indent=4, sort_keys=True)) return False # update history (2 items) if len(update_history) != 2 or update_history[1] != blockchain_record['value_hash']: print "invalid update history\n%s" % json.dumps(update_history, indent=4, sort_keys=True) return False # zonefile history (expect 2 items) if len(zonefile_history) != 2 or zonefile_history[1] != zonefile_info: print "invalid zonefile history\n%s" % json.dumps(zonefile_history, indent=4, sort_keys=True) print "zonefile current:\n%s" % json.dumps(zonefile_info, indent=4, sort_keys=True) return False # names info if type(names_info) != dict: print "invalid names info: %s" % names_info return False for k in ['names_owned', 'addresses']: if not names_info.has_key(k): print "invalid names info (missing %s): %s" % (k, names_info) return False if len(names_info['addresses']) != 1: print "invalid names info (addresses): %s" % names_info return False if names_info['addresses'][0]['names_owned'] != ['foo.test']: print "invalid names info (names_owned): %s" % names_info return False if names_info['addresses'][0]['address'] != wallets[3].addr: print "invalid names info (addresses.address): %s" % names_info return False # immutable data immutable_data = testlib.ysi_cli_get_immutable( "foo.test", "hello_world" ) if 'error' in immutable_data: print "Failed to get immutable data 'hello_world'" print json.dumps(immutable_data, indent=4, sort_keys=True) return False if 'data' not in immutable_data: print "invalid immutable_data: %s" % immutable_data return False if json.loads(immutable_data['data']) != {'hello': 'world'}: print "failed to get immutable data" print 'exected %s, got %s' % ({'hello': 'world'}, immutable_data['data']) return False return True