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 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 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 scenario(wallets, **kw): global first_name_block test_proxy = testlib.make_proxy() # make a test namespace resp = testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # end of 689 resp = testlib.ysi_namespace_reveal( "test", wallets[1].addr, 2, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # 690 # make a zonefile and a profile driver_urls = ysi_client.storage.make_mutable_data_urls( 'foo.test', use_only=['dht', 'disk']) zonefile = ysi_client.zonefile.make_empty_zonefile('foo.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = ysi_zones.make_zone_file(zonefile, origin='foo.test', ttl=4200) # make a new keyfile as well user_profile = ysi_client.user.make_empty_user_profile() ''' res = ysi_client.key_file.make_initial_key_file(user_profile, wallets[3].privkey) if 'error' in res: print res return res keyfile_txt = res['key_file'] ''' zonefile_hash = ysi_client.get_zonefile_data_hash(zonefile_txt) resp = testlib.ysi_name_import("foo.test", wallets[3].addr, zonefile_hash, wallets[1].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # 691 # broadcast zonefile res = testlib.ysi_cli_sync_zonefile('foo.test', zonefile_string=zonefile_txt) if 'error' in res: print res return False ''' # upload keyfile res = ysi_client.key_file.key_file_put('foo.test', keyfile_txt) if 'error' in res: print res return False ''' rc = ysi_client.profile.put_profile('foo.test', user_profile, blockchain_id='foo.test', user_data_privkey=wallets[4].privkey, user_zonefile=zonefile, proxy=test_proxy) if not rc: print 'failed to put profile' return False # try lookup res = testlib.ysi_cli_lookup('foo.test') if 'error' in res: print res return False first_name_block = testlib.get_current_block(**kw) resp = testlib.ysi_namespace_ready("test", wallets[1].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False # try lookup res = testlib.ysi_cli_lookup('foo.test') if 'error' in res: print res return False testlib.next_block(**kw) # end of 692 whois = testlib.ysi_cli_whois('foo.test') if 'error' in whois: print 'failed to whois foo.test' print json.dumps(whois, indent=4) return False # this should be the second-to-last block if whois['expire_block'] != testlib.get_current_block(**kw) + 2: print 'wrong expire block (expect 2 more)' print whois return False # try lookup res = testlib.ysi_cli_lookup('foo.test') if 'error' in res: print res return False testlib.next_block(**kw) # end of 693; begin epoch 2 # begin epoch 2 # try lookup res = testlib.ysi_cli_lookup('foo.test') if 'error' in res: print res return False testlib.next_block(**kw) # 694 # try lookup res = testlib.ysi_cli_lookup('foo.test') if 'error' in res: print res return False whois = testlib.ysi_cli_whois('foo.test') if 'error' in whois: print 'failed to whois foo.test' print json.dumps(whois, indent=4) return False # this should be the last block if whois['expire_block'] != testlib.get_current_block(**kw) + 2: print 'wrong expire block (expect 2 more)' print whois return False if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 2: print 'wrong renewal block (expect 2 more)' print whois return False print whois testlib.next_block(**kw) # 695 (epoch 3 begins) # try lookup res = testlib.ysi_cli_lookup('foo.test') if 'error' in res: print res return False testlib.next_block(**kw) # end of 696 # try lookup (should fail) res = testlib.ysi_cli_lookup('foo.test') if 'error' not in res: print res return False if 'expired' not in res['error']: print res return False whois = testlib.ysi_cli_whois('foo.test') if 'error' in whois: print whois return False # this should be the expire block if whois['expire_block'] != testlib.get_current_block(**kw): print 'wrong expire block (now at {})'.format( testlib.get_current_block(**kw)) print whois return False # should now be a grace period if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 5: print 'wrong renewal block (now at {})'.format( testlib.get_current_block(**kw)) print whois return False last_transaction_height = whois['last_transaction_height'] # begin epoch 3 (grace period) testlib.next_block(**kw) # end of 697 # try lookup (should fail) res = testlib.ysi_cli_lookup('foo.test') if 'error' not in res: print res return False if 'expired' not in res['error']: print res return False testlib.next_block(**kw) # 698 # try lookup (should fail) res = testlib.ysi_cli_lookup('foo.test') if 'error' not in res: print res return False if 'expired' not in res['error']: print res return False testlib.next_block(**kw) # 699 # try lookup (should fail) res = testlib.ysi_cli_lookup('foo.test') if 'error' not in res: print res return False if 'expired' not in res['error']: print res return False testlib.next_block(**kw) # 700 # try lookup (should fail) res = testlib.ysi_cli_lookup('foo.test') if 'error' not in res: print res return False if 'expired' not in res['error']: print res return False # make a zonefile and a profile driver_urls = ysi_client.storage.make_mutable_data_urls( 'foo.test', use_only=['dht', 'disk']) new_zonefile = ysi_client.zonefile.make_empty_zonefile( 'foo.test', wallets[4].pubkey_hex, urls=driver_urls) new_zonefile_txt = ysi_zones.make_zone_file(new_zonefile, origin='foo.test', ttl=4200) # make a new keyfile as well new_user_profile = ysi_client.user.make_empty_user_profile() new_user_profile['new_user'] = True ''' res = ysi_client.key_file.make_initial_key_file(new_user_profile, wallets[0].privkey) if 'error' in res: print res return res new_keyfile_txt = res['key_file'] ''' new_zonefile_hash = ysi_client.get_zonefile_data_hash(new_zonefile_txt) rc = ysi_client.profile.put_profile('foo.test', new_user_profile, blockchain_id='foo.test', user_data_privkey=wallets[4].privkey, user_zonefile=new_zonefile, proxy=test_proxy) if not rc: print 'failed to put profile' return False # renew/xfer/update resp = testlib.ysi_name_renew('foo.test', wallets[3].privkey, zonefile_hash=new_zonefile_hash, recipient_addr=wallets[0].addr) if 'error' in resp: print resp return False testlib.next_block(**kw) # end of 701 (end of grace period) # try lookup (should succeed again) res = testlib.ysi_cli_lookup('foo.test') if 'error' in res: print res return False if res['zonefile'] != new_zonefile_txt: print 'wrong zonefile' print new_zonefile_txt print res return False testlib.next_block(**kw) # 702 (name can be registered again)
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 scenario(wallets, **kw): global zonefile_hash 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) wallet = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey) resp = testlib.ysi_cli_register("foo.test", "0123456789abcdef") if 'error' in resp: print >> sys.stderr, json.dumps(resp, indent=4, sort_keys=True) return False # wait for the preorder to get confirmed for i in xrange(0, 12): testlib.next_block(**kw) # wait for the poller to pick it up print >> sys.stderr, "Waiting 10 seconds for the backend to submit the register" time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 12): # warn the serialization checker that this changes behavior from 0.13 print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge registration" time.sleep(10) # wait for initial update to get confirmed for i in xrange(0, 12): # warn the serialization checker that this changes behavior from 0.13 print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge update" time.sleep(10) # store a new zonefile data_pubkey = wallet['data_pubkey'] zonefile = ysi_client.zonefile.make_empty_zonefile("foo.test", data_pubkey) assert ysi_client.user.put_immutable_data_zonefile( zonefile, "testdata", ysi_client.get_data_hash("testdata")) zonefile_txt = ysi_zones.make_zone_file(zonefile) zonefile_hash = ysi_client.storage.get_zonefile_data_hash(zonefile_txt) print >> sys.stderr, "\n\nzonefile hash: %s\nzonefile:\n%s\n\n" % ( zonefile_hash, zonefile_txt) # will store to queue test_proxy = testlib.make_proxy() config_path = test_proxy.config_path conf = ysi_client.config.get_config(config_path) queuedb_path = conf['queue_path'] # update the zonefile hash, but not the zonefile. resp = testlib.ysi_cli_set_zonefile_hash("foo.test", zonefile_hash) if 'error' in resp: print >> sys.stderr, "\nFailed to set zonefile hash: %s\n" % resp return False txhash = resp['transaction_hash'] for i in xrange(0, 12): # warn the serialization checker that this changes behavior from 0.13 print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge update" time.sleep(10) # stop endpoint print >> sys.stderr, "\nstopping RPC daemon\n" testlib.stop_api() time.sleep(3) # store to queue res = ysi_client.backend.queue.queue_append( "update", "foo.test", txhash, payment_address=wallets[2].addr, owner_address=wallets[3].addr, config_path=test_proxy.config_path, zonefile_data=zonefile_txt, zonefile_hash=zonefile_hash, path=queuedb_path) # verify that we can sync the zonefile, using the in-queue zonefile resp = testlib.ysi_cli_sync_zonefile("foo.test") if 'error' in resp: print >> sys.stderr, "\nfailed to sync zonefile: %s\n" % resp return False ysi_client.backend.queue.queuedb_remove("update", "foo.test", txhash, path=queuedb_path) print >> sys.stderr, "\nstarting RPC daemon\n" testlib.start_api("0123456789abcdef") # store a new zonefile zonefile = ysi_client.zonefile.make_empty_zonefile("foo.test", data_pubkey) ysi_client.user.put_immutable_data_zonefile( zonefile, "testdata2", ysi_client.get_data_hash("testdata")) zonefile_txt = ysi_zones.make_zone_file(zonefile) zonefile_hash = ysi_client.storage.get_zonefile_data_hash(zonefile_txt) # store locally res = ysi_client.zonefile.store_name_zonefile("foo.test", zonefile, None, storage_drivers=['disk']) if 'error' in res: print >> sys.stderr, "\nFailed to store zonefile: %s\n" % res return False # update the zonefile hash, but not the zonefile. resp = testlib.ysi_cli_set_zonefile_hash("foo.test", zonefile_hash) if 'error' in resp: print >> sys.stderr, "\nFailed to set zonefile hash: %s\n" % resp return False for i in xrange(0, 12): # warn the serialization checker that this changes behavior from 0.13 print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) # verify that we can sync the zonefile, using the on-disk zonefile resp = testlib.ysi_cli_sync_zonefile("foo.test") if 'error' in resp: print >> sys.stderr, "update error: %s" % resp['error'] return False # wait for it to go through for i in xrange(0, 12): testlib.next_block(**kw) print >> sys.stderr, "Waiting 10 seconds for the backend to acknowedge the update" time.sleep(10)