def scenario( wallets, **kw ): global synchronized, value_hash import blockstack_integration_tests.atlas_network as atlas_network testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_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.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # register 10 names for i in xrange(0, 10): res = testlib.blockstack_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.blockstack_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): empty_zonefile_str = testlib.make_empty_zonefile( "foo_{}.test".format(i), wallets[3].addr) value_hash = blockstack.lib.storage.get_zonefile_data_hash(empty_zonefile_str) res = testlib.blockstack_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 ) res = testlib.blockstack_put_zonefile(empty_zonefile_str) if not 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 = blockstack.lib.util.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( testlib.working_dir(**kw), 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 blockstack_integration_tests.atlas_network as atlas_network testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_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.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # register 10 names for i in xrange(0, 10): res = testlib.blockstack_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.blockstack_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): empty_zonefile_str = testlib.make_empty_zonefile( "foo_{}.test".format(i), wallets[3].addr) value_hash = blockstack.lib.storage.get_zonefile_data_hash( empty_zonefile_str) res = testlib.blockstack_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) res = testlib.blockstack_put_zonefile(empty_zonefile_str) if not 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. # the network will ensure each node can reach each other node. atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007] atlas_topology = {} for node_port in atlas_nodes: atlas_topology[node_port] = [16264] network_des = atlas_network.atlas_network_build( testlib.working_dir(**kw), atlas_nodes, atlas_topology, {}, os.path.join(testlib.working_dir(**kw), "atlas_network")) atlas_network.atlas_network_start(network_des) 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): testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_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.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.blockstack_name_preorder("foo1.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # make zonefiles: # one normal one # one with a nonstandard zonefile zf1_txt = testlib.make_empty_zonefile('foo1.test', wallets[3].addr) zf2_txt = '\x00\x01\x02\x03\x04\x05' testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash(zf1_txt)) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash(zf2_txt)) testlib.next_block(**kw) # replicate zonefiles for zf in [zf1_txt, zf2_txt]: res = testlib.blockstack_put_zonefile(zf) assert res print 'waiting for zonefiles to be saved...' time.sleep(5) # store signed profile for each working_dir = kw['working_dir'] for name in ['foo1.test', 'foo2.test']: profile = {'name': name, 'type': '@Person', 'account': []} print 'sign profile for {}'.format(name) profile_path = os.path.join(working_dir, '{}.profile'.format(name)) with open(profile_path, 'w') as f: f.write(json.dumps(profile)) jwt = testlib.blockstack_cli_sign_profile(profile_path, wallets[3].privkey) if 'error' in jwt: print jwt return False jwt_path = os.path.join(working_dir, '{}.profile.jwt'.format(name)) with open(jwt_path, 'w') as f: f.write(json.dumps(jwt)) print 'verify profile for {}'.format(name) res = testlib.blockstack_cli_verify_profile(jwt_path, wallets[3].addr) if 'error' in res: print res return False print 'store profile for {}'.format(name) # store the jwt to the right place res = testlib.blockstack_put_profile(name, json.dumps(jwt), wallets[3].privkey, 'http://localhost:4000') assert res print 'lookup profile for {}'.format(name) # lookup res = testlib.blockstack_cli_lookup(name) if name != 'foo2.test': if 'error' in res: print res return False if res['profile'] != profile: print 'profile mismatch:' print res['profile'] print profile return False else: if 'zonefile' not in res or 'error' not in res['zonefile']: print res return False
def scenario(wallets, **kw): global synchronized, value_hash import blockstack_integration_tests.atlas_network as atlas_network testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_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.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # register 10 names for i in xrange(0, 10): res = testlib.blockstack_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.blockstack_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): empty_zonefile_str = testlib.make_empty_zonefile( "foo_{}.test".format(i), wallets[3].addr) value_hash = blockstack.lib.storage.get_zonefile_data_hash( empty_zonefile_str) res = testlib.blockstack_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) res = testlib.blockstack_put_zonefile(empty_zonefile_str) if not 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 = blockstack.lib.util.url_to_host_port(src_hostport) dest_host, dest_port = blockstack.lib.util.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( testlib.working_dir(**kw), 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 synchronized, value_hash import blockstack_integration_tests.atlas_network as atlas_network testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_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.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # register 10 names for i in xrange(0, 10): res = testlib.blockstack_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.blockstack_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 = blockstack.lib.util.url_to_host_port(src_hostport) dest_host, dest_port = blockstack.lib.util.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( testlib.working_dir(**kw), 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): empty_zonefile_str = testlib.make_empty_zonefile( "foo_{}.test".format(i), wallets[3].addr) value_hash = blockstack.lib.storage.get_zonefile_data_hash( empty_zonefile_str) res = testlib.blockstack_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) res = testlib.blockstack_put_zonefile(empty_zonefile_str) if not 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): start_subdomain_registrar() testlib.blockstack_namespace_preorder("id", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "id", 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.blockstack_namespace_ready("id", wallets[1].privkey) testlib.next_block(**kw) resp = testlib.blockstack_name_preorder('foo.id', wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zfdata = testlib.make_empty_zonefile('foo.id', wallets[3].addr) zfhash = blockstack.lib.storage.get_zonefile_data_hash(zfdata) resp = testlib.blockstack_name_register('foo.id', wallets[2].privkey, wallets[3].addr, zonefile_hash=zfhash) testlib.next_block(**kw) testlib.blockstack_put_zonefile(zfdata) # now, queue a subdomain registration. requests.post('http://localhost:3000/register', json={ 'zonefile': 'hello world', 'name': 'bar', 'owner_address': '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa' }) # force a batch out of the subdomain registrar requests.post('http://localhost:3000/issue_batch', headers={'Authorization': 'bearer tester129'}) for i in xrange(0, 12): testlib.next_block(**kw) print >> sys.stderr, "Waiting 10 seconds for the backend to pickup first batch" time.sleep(10) # update the name on-chain testlib.blockstack_name_update('foo.id', '11' * 20, wallets[3].privkey) testlib.blockstack_name_update('foo.id', '22' * 20, wallets[3].privkey) testlib.blockstack_name_update('foo.id', '33' * 20, wallets[3].privkey) testlib.next_block(**kw) # now, queue another registration requests.post('http://localhost:3000/register', json={ 'zonefile': 'hello world', 'name': 'zap', 'owner_address': '1Ez69SnzzmePmZX3WpEzMKTrcBF2gpNQ55' }) res = testlib.blockstack_REST_call('GET', '/v1/names/zap.foo.id', None) if 'error' in res: res['test'] = 'Failed to query zap.foo.id' print json.dumps(res) return False if res['http_status'] != 200: res['test'] = 'HTTP status {}, response = {} on name lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False name_info = res['response'] try: if (name_info['zonefile'] != 'hello world' or name_info['address'] != '1Ez69SnzzmePmZX3WpEzMKTrcBF2gpNQ55'): res['test'] = 'Unexpected name info lookup for zap.foo.id' print 'zap.foo.id JSON:' print json.dumps(name_info) return False except: res['test'] = 'Unexpected name info lookup for zap.foo.id' print 'zap.foo.id JSON:' print json.dumps(name_info) return False # update the name on-chain again, but lots of times for i in range(0, 20): zonefile_pattern = '{:x}{:x}'.format(i / 16, i % 16) testlib.blockstack_name_update('foo.id', zonefile_pattern * 20, wallets[3].privkey) testlib.next_block(**kw) # should continue to work res = testlib.blockstack_REST_call('GET', '/v1/names/zap.foo.id', None) if res['http_status'] != 200: res['test'] = 'HTTP status {}, response = {} on name lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False SUBDOMAIN_PROC.kill()
def scenario(wallets, **kw): global synchronized import blockstack_integration_tests.atlas_network as atlas_network testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_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.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # register 10 names for i in xrange(0, 10): res = testlib.blockstack_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.blockstack_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( testlib.working_dir(**kw), [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): empty_zonefile_str = testlib.make_empty_zonefile( "foo_{}.test".format(i), wallets[3].addr) value_hash = blockstack.lib.storage.get_zonefile_data_hash( empty_zonefile_str) res = testlib.blockstack_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) res = testlib.blockstack_put_zonefile(empty_zonefile_str) if not 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, namespace_ids virtualchain_dir = kw['working_dir'] assert virtualchain_dir privkey = keylib.ECPrivateKey(wallets[4].privkey).to_hex() config_file = os.path.join(virtualchain_dir, 'snapshots.ini') privkey_path = os.path.join(virtualchain_dir, 'snapshots.pkey') snapshot_dir = os.path.join(virtualchain_dir, 'snapshots') with open(privkey_path, 'w') as f: f.write(privkey) with open(config_file, 'w') as f: f.write(""" [blockstack-snapshots] private_key = {} logfile = {} """.format(privkey_path, os.path.join(virtualchain_dir, 'snapshots.log'))) testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3) testlib.blockstack_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 ) assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3) zonefile_txt = testlib.make_empty_zonefile( "foo1.test", wallets[3].addr) zonefile_hash = blockstack.lib.storage.get_zonefile_data_hash(zonefile_txt) value_hashes.append(zonefile_hash) namespace_ids.append('test') resp = testlib.blockstack_name_import( "imported.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 ) # store zonefile res = testlib.blockstack_put_zonefile(zonefile_txt) assert res assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3) testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 3) zonefile_txt = testlib.make_empty_zonefile( "foo2.test", wallets[3].addr) zonefile_hash = blockstack.lib.storage.get_zonefile_data_hash(zonefile_txt) value_hashes.append(zonefile_hash) testlib.blockstack_name_update('foo.test', zonefile_hash, wallets[3].privkey) testlib.next_block( **kw ) time.sleep(1.0) # store zonefile res = testlib.blockstack_put_zonefile(zonefile_txt) assert res # there must be three snapshots res = os.listdir(snapshot_dir) assert len(res) == 4 assert 'snapshot.bsk' in res assert take_snapshot(config_file, virtualchain_dir, snapshot_dir, 1) # now there's only one res = os.listdir(snapshot_dir) assert len(res) == 2 assert 'snapshot.bsk' in res # restore it restore_dir = os.path.join(snapshot_dir, 'test_restore') res = restore(virtualchain_dir, os.path.join(snapshot_dir, 'snapshot.bsk'), restore_dir, [wallets[4].pubkey_hex], 1) assert res
def scenario(wallets, **kw): global value_hashes testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_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.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # register 10 names for i in xrange(0, 10): res = testlib.blockstack_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.blockstack_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): empty_zonefile_str = testlib.make_empty_zonefile( "foo_{}.test".format(i), wallets[3].addr) value_hash = blockstack.lib.storage.get_zonefile_data_hash( empty_zonefile_str) res = testlib.blockstack_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) res = testlib.blockstack_put_zonefile(empty_zonefile_str) if not res: return False value_hashes.append(value_hash) testlib.next_block(**kw) print 'waiting for all zone files to replicate' time.sleep(10) working_dir = os.environ.get("BLOCKSTACK_WORKING_DIR") restore_dir = os.path.join(working_dir, "snapshot_dir") # snapshot the latest backup snapshot_path = os.path.join(working_dir, "snapshot.bsk") rc = blockstack.fast_sync_snapshot(kw['working_dir'], 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 = blockstack.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( kw['working_dir'], 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( kw['working_dir'], 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(kw['working_dir'], 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(kw['working_dir'], 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(kw['working_dir'], 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(kw['working_dir'], snapshot_path, restore_dir, [wallets[3].pubkey_hex], 1) if not rc: print "failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], 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( kw['working_dir'], 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(kw['working_dir'], 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(kw['working_dir'], 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(kw['working_dir'], 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(kw['working_dir'], 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( kw['working_dir'], 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)