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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) def _query_subdomains(subdomain_names, expected_sequence, expected_owner): # query each subdomain. Should get the latest proxy = testlib.make_proxy() for fqn in subdomain_names: res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res print 'failed to query {}'.format(fqn) return False # should have right sequence if res['sequence'] != expected_sequence: print 'wrong sequence; expected {}'.format(expected_sequence) print res return False # should have right owner if res['address'] != expected_owner: print 'wrong owner' print 'expected {}'.format(res['address']) print res return False return True assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off indexing and check testlib.next_block(**kw) assert _query_subdomains( ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'], 0, wallets[4].addr) expected_owners = [wallets[4].addr] # send updates too, and transfer subdomains for i in range(0, 6): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( i + 1) j = (4 + i) % 5 k = (4 + i + 1) % 5 expected_owners.append(wallets[k].addr) zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[k].addr, i + 1, zf_template.format('bar.foo1.test', zf_default_url), wallets[j].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[k].addr, i + 1, zf_template.format('bar.foo2.test', zf_default_url), wallets[j].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[k].addr, i + 1, zf_template.format('bar.foo3.test', zf_default_url), wallets[j].privkey)), } testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) # verify history assert _query_subdomains( ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'], i + 1, wallets[k].addr) # query subdomain history proxy = testlib.make_proxy() for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']: res = client.get_name_record(subd, include_history=True, proxy=proxy) if 'error' in res: print res return False for i, block_height in enumerate(sorted(res['history'])): if res['history'][block_height][0]['address'] != expected_owners[i]: print 'wrong owner at {}: expected {}'.format( block_height, expected_owners[i]) print json.dumps(res, indent=4, sort_keys=True) return False if res['history'][block_height][0]['sequence'] != i: print 'wrong sequence at {}: expected {}'.format( block_height, i) print json.dumps(res, indent=4, sort_keys=True) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zf_default_url_original = zf_default_url zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) # send these initial ones out assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) missing_zonefiles = [] # send updates too for i in range(0, 3): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( i + 1) zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, i + 1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, i + 1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, i + 1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) if i % 2 == 0: # withhold for now missing_zonefiles.append(zonefiles) else: # send these out assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) assert len(missing_zonefiles) == 2 # verify that initial subdomains are present proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False if res['sequence'] != 0: print 'wrong sequence: expected 0' print res return False expected_zonefile = zf_template.format(fqn, zf_default_url_original) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # send first batch of withheld zonefiles assert testlib.blockstack_put_zonefile(missing_zonefiles[0]['foo1.test']) assert testlib.blockstack_put_zonefile(missing_zonefiles[0]['foo2.test']) assert testlib.blockstack_put_zonefile(missing_zonefiles[0]['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) # verify that we're now up to sequence=2 proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False if res['sequence'] != 2: print 'wrong sequence: expected 2' print res return False zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index=2"' expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # send second batch of withheld zonefiles assert testlib.blockstack_put_zonefile(missing_zonefiles[1]['foo1.test']) assert testlib.blockstack_put_zonefile(missing_zonefiles[1]['foo2.test']) assert testlib.blockstack_put_zonefile(missing_zonefiles[1]['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) # query each subdomain (should all be at sequence 3) proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False if res['sequence'] != 3: print 'wrong sequence: expected 3' print res return False zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index=3"' expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) # will send these later initial_zonefiles = zonefiles # send updates too for i in range(0, 3): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( i + 1) zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, i + 1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, i + 1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, i + 1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing (nothing should happen) testlib.next_block(**kw) # store directly to Atlas zonefiles dir and wait a few seconds. Atlas should notice that they're here # and queue them for subdomain processing for name in ['foo1.test', 'foo2.test', 'foo3.test']: blockstack.lib.storage.store_atlas_zonefile_data( initial_zonefiles[name], blockstack.lib.get_blockstack_opts()['zonefiles']) print 'wait for atlas to discover that it already has the requisite zone files' time.sleep(10) # now kick it off again testlib.next_block(**kw) # query each subdomain for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
def scenario( wallets, **kw ): zonefile_batches = [] 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.blockstack_name_preorder( "foo3.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo4.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo5.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo6.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo7.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' # send initial subdomain zone files zonefiles = { 'foo1.test': zf_template.format('foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format('foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format('foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } zonefile_batches.append(zonefiles) testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.blockstack_name_register( "foo4.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo5.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo6.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo7.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.next_block( **kw ) # send updates too, but via a different name each time for i in range(0, 3): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(i+1) name = 'foo{}.test'.format(i + 4) zonefiles = { 'foo1.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo1.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo2.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo3.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } zonefile_batches.append(zonefiles) testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) # send all zonefiles at once for zfbatch in zonefile_batches: for name in zfbatch: assert testlib.blockstack_put_zonefile(zfbatch[name]) # kick off subdomain indexing testlib.next_block(**kw) # query each subdomain for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res return False # should all have domain foo6.test at this time if res['domain'] != 'foo6.test': print 'wrong domain' print res return False expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
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("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) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://gaia.blockstack.org/hub/{}/profile.json'.format( wallets[4].addr) all_zonefiles = [] # do lots and lots of subdomains for i in range(0, 20): subdomain_zonefiles = [] for j in range(0, 100): subdomain_name = 'bar{}.foo.test'.format(i * 100 + j) zf = subdomains.make_subdomain_txt( subdomain_name, 'foo.test', wallets[4].addr, 0, zf_template.format(subdomain_name, zf_default_url), wallets[4].privkey) subdomain_zonefiles.append(zf) zf = zf_template.format('foo.test', '\n'.join(subdomain_zonefiles)) assert len(zf) <= 40960, 'zonefile is too long ({})'.format(len(zf)) all_zonefiles.append(zf) testlib.blockstack_name_update('foo.test', storage.get_zonefile_data_hash(zf), wallets[3].privkey) testlib.next_block(**kw) # broadcast them all for zf in all_zonefiles: assert testlib.blockstack_put_zonefile(zf) # index them all t1 = time.time() testlib.next_block(**kw) t2 = time.time() # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder( "foo3.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' # send initial zone files zonefiles = { 'foo1.test': zf_template.format('foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format('foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format('foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block( **kw ) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # subdomain history diagram # bar.foo1.test ++ #sequence ++ @zonefile_index # # # bar.foo1.test#2@3 (1) # / # bar.foo1.test#1@1 # / \ # / bar.foo1.test#2@4 (2) # bar.foo1.test#0 # \ bar.foo1.test#2@5 (3) # \ / # bar.foo1.test#1@2 # \ # bar.foo1.test#2@6 (4) # # # Send branches (1), (2), (3), and (4) # Reveal branches (4), then (3), then (2), then (1). Verify that the subdomain record matches the leaf node's state in order of revealing. def _send_batch(zf_default_url, seq): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zonefiles = { 'foo1.test': zf_template.format('foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, seq, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format('foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, seq, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format('foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, seq, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_update('foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update('foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update('foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) return zonefiles def _query_subdomains(subdomain_names, expected_zonefiles, expected_sequence): # query each subdomain. Should get the latest for (fqn, expected_zonefile) in zip(subdomain_names, expected_zonefiles): res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res print 'failed to query {}'.format(fqn) return False if res['sequence'] != expected_sequence: print 'wrong sequence; expected {}'.format(expected_sequence) print res return False if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False return True branch_1 = [] branch_2 = [] branch_3 = [] branch_4 = [] # final branch URLs, since we're reorging only on sequence number branch_urls = [ '_https._tcp URI 10 1 "https://branch3-and-4.com"', '_https._tcp URI 10 1 "https://branch4.com"', '_https._tcp URI 10 1 "https://branch3.com"', '_https._tcp URI 10 1 "https://branch3.com"', '_https._tcp URI 10 1 "https://branch2.com"', '_https._tcp URI 10 1 "https://branch1.com"', ] # final sequence numbers, since we're reorging only on sequence number branch_sequences = [ 1, 2, 2, 2, 2, 2, ] # send branch 1 branch1_zfs = _send_batch('_https._tcp URI 10 1 "https://branch1-and-2.com"', 1) # branch_1.append(zfs) zfs = _send_batch('_https._tcp URI 10 1 "https://branch1.com"', 2) branch_1.append(zfs) # send branch 2 branch_2.append(branch1_zfs) zfs = _send_batch('_https._tcp URI 10 1 "https://branch2.com"', 2) branch_2.append(zfs) # send branch 3 branch3_zfs = _send_batch('_https._tcp URI 10 1 "https://branch3-and-4.com"', 1) # branch_3.append(zfs) zfs = _send_batch('_https._tcp URI 10 1 "https://branch3.com"', 2) branch_3.append(zfs) # send branch 4 branch_4.append(branch3_zfs) zfs = _send_batch('_https._tcp URI 10 1 "https://branch4.com"', 2) branch_4.append(zfs) # reveal in reverse. # branch_1 should be the final result b = 0 for j, branch in enumerate([branch_4, branch_3, branch_2, branch_1]): # reveal this branch, piecemeal for i, zf_batch in enumerate(branch): for name in zf_batch: print '' print 'reveal branch {}, node {}:\n{}'.format(4 - j, i+1, zf_batch[name]) print '' assert testlib.blockstack_put_zonefile(zf_batch[name]) testlib.next_block(**kw) # make sure all subdomains are consistent with this branch seq = branch_sequences[b] subdomain_names = ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'] zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = branch_urls[b] zonefiles = [ zf_template.format('bar.foo1.test', zf_default_url), zf_template.format('bar.foo2.test', zf_default_url), zf_template.format('bar.foo3.test', zf_default_url), ] print '' print 'check {} at sequence={} at branch {} node {}'.format(','.join(subdomain_names), seq, 4 - j, i+1) print '' rc = _query_subdomains(subdomain_names, zonefiles, seq) if not rc: print 'failed to query subdomains' return False b += 1 # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) working_dir = testlib.get_working_dir(**kw) sub_zf_template = '$ORIGIN {}\n$TTL 3600\n_http._tcp URI 10 1 "http://www.foo.com"\n{}' zf_template = '$ORIGIN {}\n$TTL 3600\n_http._tcp URI 10 1 "http://www.foo.com"\n_resolver URI 10 1 "http://resolver.foo"\n{}' zf_default_url = '_file URI 10 1 "file://' + working_dir + '/{}"' zf_default_url_2 = '_file URI 20 1 "file://' + working_dir + '/{}"' subdomain_zonefiles = { 'bar.foo1.test': sub_zf_template.format('bar.foo1.test', zf_default_url.format('bar.foo1.test')), 'bar.foo2.test': sub_zf_template.format('bar.foo2.test', zf_default_url.format('bar.foo2.test')), 'bar.foo3.test': sub_zf_template.format('bar.foo3.test', zf_default_url.format('bar.foo3.test')), } zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, 0, subdomain_zonefiles['bar.foo1.test'], wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, 0, subdomain_zonefiles['bar.foo2.test'], wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, 0, subdomain_zonefiles['bar.foo3.test'], wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) # sign and put profiles for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']: profile_data = { 'type': 'Person', 'name': subd, } profile_jwt = testlib.blockstack_make_profile(profile_data, wallets[4].privkey) path = os.path.join(working_dir, subd) with open(path, 'w') as f: f.write(profile_jwt) # whois for i in xrange(1, 4): name = 'foo{}.test'.format(i) res = testlib.blockstack_cli_whois(name) if 'error' in res: print res return False if not res.has_key('zonefile_hash') or res[ 'zonefile_hash'] != storage.get_zonefile_data_hash( zonefiles[name]): print res return False if res['owner_address'] != wallets[3].addr: print res return False # upload zonefile assert testlib.blockstack_put_zonefile(zonefiles[name]) subdomain_zonefiles_2 = { 'bar.foo1.test': zf_template.format('bar.foo1.test', zf_default_url_2.format('bar.foo1.test')), 'bar.foo2.test': zf_template.format('bar.foo2.test', zf_default_url_2.format('bar.foo2.test')), 'bar.foo3.test': zf_template.format('bar.foo3.test', zf_default_url_2.format('bar.foo3.test')), } zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, 1, subdomain_zonefiles['bar.foo1.test'], wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, 1, subdomain_zonefiles['bar.foo2.test'], wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, 1, subdomain_zonefiles['bar.foo3.test'], wallets[4].privkey)), } # update zone files testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) # start API daemon print 'starting API daemon' wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[0].privkey, wallets[1].privkey, wallets[2].privkey) # authenticate pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.blockstack_cli_app_signin("foo.test", pk, 'register.app', [ 'names', 'register', 'prices', 'zonefiles', 'blockchain', 'node_read', 'user_read' ]) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # query each subdomain proxy = testlib.make_proxy() # test 301 redirects. res = testlib.blockstack_REST_call('GET', '/v1/names/baz.foo1.test', ses, allow_redirects=False) if 'error' in res: res['test'] = 'Failed to query non-registered name.' print json.dumps(res) return False if res['http_status'] != 301: res['test'] = 'Failed to get a redirect.' print json.dumps(res) return False for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) # test REST whois res = testlib.blockstack_REST_call('GET', '/v1/names/{}'.format(fqn), ses) if 'error' in res: res['test'] = 'Failed to query name' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on name lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False if res['response']['zonefile'] != subdomain_zonefiles[fqn]: print 'wrong zone file' print res print 'expected' print zonefiles['foo{}.test'.format(i)] return False if res['response']['status'] != 'registered_subdomain': print 'wrong status' print res return False # test CLI lookup res = testlib.blockstack_cli_lookup(fqn) if 'error' in res: print res return False print res if res['profile'] != {'type': 'Person', 'name': fqn}: print 'wrong profile' print res['profile'] return False # test REST lookup res = testlib.blockstack_REST_call("GET", "/v1/users/{}".format(fqn), ses) if 'error' in res: res['test'] = 'Failed to query name profile' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on name profile lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False print res if res['response'] != {'type': 'Person', 'name': fqn}: print 'wrong profile on REST call' print res return False # test CLI lookup by address res = testlib.blockstack_cli_get_names_owned_by_address( wallets[4].addr) if 'error' in res: print 'failed to get subdomains owned by {}'.format( wallets[4].addr) print res return False if fqn not in res: print '{} not in list'.format(fqn) print res return False # test REST lookup by address res = testlib.blockstack_REST_call( 'GET', '/v1/addresses/bitcoin/{}'.format(wallets[4].addr), ses) if 'error' in res: res['test'] = 'Failed to query names owned by address' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on address lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False if fqn not in res['response']['names']: print '{} not in REST list'.format(fqn) print res return False # test REST get name history res = testlib.blockstack_REST_call('GET', '/v1/names/{}/history'.format(fqn), ses) if 'error' in res: res['test'] = 'Failed to query subdomain history' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on subdomain history lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False blocks = res['response'] if len(blocks.keys()) != 2: print 'expected two updates' print blocks return False # get each historic zone file for block_height in blocks: for prev_state in blocks[block_height]: value_hash = prev_state['value_hash'] res = testlib.blockstack_REST_call( 'GET', '/v1/names/{}/zonefile/{}'.format(fqn, value_hash), ses) if 'error' in res: print 'failed to query zone file {} for {}'.format( value_hash, fqn) print json.dumps(res) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo4.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo5.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo6.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo7.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } # send initial subdomains testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.blockstack_name_register("foo4.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register("foo5.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register("foo6.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register("foo7.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.next_block(**kw) # will send these later initial_zonefiles = zonefiles # send updates too, but all on the same name for i in range(0, 3): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( i + 1) name = 'foo{}.test'.format(i + 4) zonefiles = { 'foo1.test': zf_template.format( name, subdomains.make_subdomain_txt( 'bar.foo1.test', name, wallets[4].addr, i + 1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( name, subdomains.make_subdomain_txt( 'bar.foo2.test', name, wallets[4].addr, i + 1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( name, subdomains.make_subdomain_txt( 'bar.foo3.test', name, wallets[4].addr, i + 1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_update( name, storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( name, storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( name, storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing (nothing should happen) testlib.next_block(**kw) # send initial zonefiles assert testlib.blockstack_put_zonefile(initial_zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(initial_zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(initial_zonefiles['foo3.test']) # now kick it off again testlib.next_block(**kw) # query each subdomain proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) working_dir = testlib.get_working_dir(**kw) sub_zf_template = '$ORIGIN {}\n$TTL 3600\n{}' zf_template = '$ORIGIN {}\n$TTL 3600\n_http._tcp URI 10 1 "http://www.foo.com"\n_resolver URI 10 1 "http://resolver.foo"\n{}' zf_default_url = '_file URI 10 1 "http://localhost:4000/hub/{}/profile.json' zf_default_url_2 = '_file URI 20 1 "http://localhost:4000/hub/{}/profile.json' subdomain_zonefiles = { 'bar.foo1.test': sub_zf_template.format( 'bar.foo1.test', zf_default_url.format( virtualchain.address_reencode(wallets[0].addr, network='mainnet'))), 'bar.foo2.test': sub_zf_template.format( 'bar.foo2.test', zf_default_url.format( virtualchain.address_reencode(wallets[1].addr, network='mainnet'))), 'bar.foo3.test': sub_zf_template.format( 'bar.foo3.test', zf_default_url.format( virtualchain.address_reencode(wallets[2].addr, network='mainnet'))), } zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[0].addr, 0, subdomain_zonefiles['bar.foo1.test'], wallets[0].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[1].addr, 0, subdomain_zonefiles['bar.foo2.test'], wallets[1].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[2].addr, 0, subdomain_zonefiles['bar.foo3.test'], wallets[2].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) # sign and put profiles for i, subd in enumerate( ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']): profile_data = { 'type': 'Person', 'name': subd, } profile_jwt = testlib.blockstack_make_profile(profile_data, wallets[i].privkey) testlib.blockstack_put_profile(None, profile_jwt, wallets[i].privkey, 'http://localhost:4000') # whois for i in xrange(1, 4): name = 'foo{}.test'.format(i) res = testlib.blockstack_cli_whois(name) if 'error' in res: print res return False if not res.has_key('zonefile_hash') or res[ 'zonefile_hash'] != storage.get_zonefile_data_hash( zonefiles[name]): print res return False if res['owner_address'] != wallets[3].addr: print res return False # upload zonefile assert testlib.blockstack_put_zonefile(zonefiles[name]) subdomain_zonefiles_2 = { 'bar.foo1.test': sub_zf_template.format( 'bar.foo1.test', zf_default_url_2.format( virtualchain.address_reencode(wallets[0].addr, network='mainnet'))), 'bar.foo2.test': sub_zf_template.format( 'bar.foo2.test', zf_default_url_2.format( virtualchain.address_reencode(wallets[1].addr, network='mainnet'))), 'bar.foo3.test': sub_zf_template.format( 'bar.foo3.test', zf_default_url_2.format( virtualchain.address_reencode(wallets[2].addr, network='mainnet'))), } zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[0].addr, 1, subdomain_zonefiles['bar.foo1.test'], wallets[0].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[1].addr, 1, subdomain_zonefiles['bar.foo2.test'], wallets[1].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[2].addr, 1, subdomain_zonefiles['bar.foo3.test'], wallets[2].privkey)), } # update zone files testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) # query each subdomain # test 301 redirects. res = testlib.blockstack_REST_call('GET', '/v1/names/baz.foo1.test', allow_redirects=False) if 'error' in res: res['test'] = 'Failed to query non-registered name.' print json.dumps(res) return False if res['http_status'] != 301: res['test'] = 'Failed to get a redirect.' print json.dumps(res) return False for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) # test REST whois res = testlib.blockstack_REST_call('GET', '/v1/names/{}'.format(fqn)) if 'error' in res: res['test'] = 'Failed to query name' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on name lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False if res['response']['zonefile'] != subdomain_zonefiles[fqn]: print 'wrong zone file' print res print 'expected' print zonefiles['foo{}.test'.format(i)] return False if res['response']['status'] != 'registered_subdomain': print 'wrong status' print res return False # test CLI lookup res = testlib.blockstack_cli_lookup(fqn) if 'error' in res: print res return False print res if res['profile'] != {'type': 'Person', 'name': fqn}: print 'wrong profile' print res['profile'] return False # test REST lookup res = testlib.blockstack_REST_call("GET", "/v1/users/{}".format(fqn)) if 'error' in res: res['test'] = 'Failed to query name profile' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on name profile lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False print res if res['response'] != {'type': 'Person', 'name': fqn}: print 'wrong profile on REST call' print res return False # test CLI lookup by address res = testlib.blockstack_cli_get_names_owned_by_address( wallets[i - 1].addr) if 'error' in res: print 'failed to get subdomains owned by {}'.format( wallets[i - 1].addr) print res return False if fqn not in res: print '{} not in list'.format(fqn) print res return False # test REST lookup by address res = testlib.blockstack_REST_call( 'GET', '/v1/addresses/bitcoin/{}'.format(wallets[i - 1].addr)) if 'error' in res: res['test'] = 'Failed to query names owned by address' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on address lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False if fqn not in res['response']['names']: print '{} not in REST list'.format(fqn) print res return False # test REST get name history res = testlib.blockstack_REST_call('GET', '/v1/names/{}/history'.format(fqn)) if 'error' in res: res['test'] = 'Failed to query subdomain history' print json.dumps(res) return False if res['http_status'] != 200 and res['http_status'] != 404: res['test'] = 'HTTP status {}, response = {} on subdomain history lookup'.format( res['http_status'], res['response']) print json.dumps(res) return False blocks = res['response'] if len(blocks.keys()) != 2: print 'expected two updates' print blocks return False # get each historic zone file for block_height in blocks: for prev_state in blocks[block_height]: value_hash = prev_state['value_hash'] res = testlib.blockstack_REST_call( 'GET', '/v1/names/{}/zonefile/{}'.format(fqn, value_hash)) if 'error' in res: print 'failed to query zone file {} for {}'.format( value_hash, fqn) print json.dumps(res) return False # reindex assert testlib.check_subdomain_db(**kw)
def scenario(wallets, **kw): zonefile_batches = [] 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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url_0 = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody0/content/profile.md"' zf_default_url_1 = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody1/content/profile.md"' zf_default_url_2 = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody2/content/profile.md"' # initialize with sequence=1 zonefiles_1 = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 1, zf_template.format('bar.foo1.test', zf_default_url_1), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 1, zf_template.format('bar.foo2.test', zf_default_url_1), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 1, zf_template.format('bar.foo3.test', zf_default_url_1), wallets[4].privkey)), } zonefile_batches.append(zonefiles_1) testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles_1['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles_1['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles_1['foo3.test'])) testlib.next_block(**kw) for name in zonefiles_1: assert testlib.blockstack_put_zonefile(zonefiles_1[name]) testlib.next_block(**kw) # send sequence=0 zonefiles_0 = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url_0), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url_0), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url_0), wallets[4].privkey)), } zonefile_batches.append(zonefiles_0) testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles_0['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles_0['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles_0['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) for name in zonefiles_0: assert testlib.blockstack_put_zonefile(zonefiles_0[name]) testlib.next_block(**kw) # all names should now be at sequence 0 # query each subdomain for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url_0) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # send sequence=1 hashes again testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles_1['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles_1['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles_1['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) # all names should now be at sequence 1, even though we didn't re-send the zone file # query each subdomain for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url_1) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # send sequence=2 zonefiles_2 = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 2, zf_template.format('bar.foo1.test', zf_default_url_2), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 2, zf_template.format('bar.foo2.test', zf_default_url_2), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 2, zf_template.format('bar.foo3.test', zf_default_url_2), wallets[4].privkey)), } zonefile_batches.append(zonefiles_2) testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles_2['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles_2['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles_2['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) for name in zonefiles_2: assert testlib.blockstack_put_zonefile(zonefiles_2[name]) testlib.next_block(**kw) # all names should now be at sequence 2 # query each subdomain for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url_2) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo4.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo5.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo6.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo7.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" subdomain_zonefile_pattern = '$ORIGIN {}\n$TTL 3600\n_https._tcp URI 10 1 "https://raw.githubusercontent.com/bar{}/profile.md' zonefiles = { 'foo1.test': make_subdomain_zone_file('foo1.test', 'bar{}.foo1.test', subdomain_zonefile_pattern, 0, 100, 40960, wallets[4].privkey), 'foo2.test': make_subdomain_zone_file('foo2.test', 'bar{}.foo2.test', subdomain_zonefile_pattern, 0, 100, 40960, wallets[4].privkey), 'foo3.test': make_subdomain_zone_file('foo3.test', 'bar{}.foo3.test', subdomain_zonefile_pattern, 0, 100, 40960, wallets[4].privkey) } # register initial subdomains testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.blockstack_name_register("foo4.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register("foo5.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register("foo6.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register("foo7.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # send updates on different names. for i in range(0, 3): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( i + 1) name = 'foo{}.test'.format(i + 4) zonefiles = { 'foo1.test': make_subdomain_zone_file(name, 'bar{}.foo1.test', subdomain_zonefile_pattern, i + 1, 100, 40960, wallets[4].privkey), 'foo2.test': make_subdomain_zone_file(name, 'bar{}.foo2.test', subdomain_zonefile_pattern, i + 1, 100, 40960, wallets[4].privkey), 'foo3.test': make_subdomain_zone_file(name, 'bar{}.foo3.test', subdomain_zonefile_pattern, i + 1, 100, 40960, wallets[4].privkey), } testlib.blockstack_name_update( name, storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( name, storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( name, storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) # query each subdomain for domain in zonefiles: for i in range(0, 100): fqn = 'bar{}.{}'.format(i, domain) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res return False # domain should be foo6.test if res['domain'] != 'foo6.test': print 'wrong domain' print res return False expected_zonefile = subdomain_zonefile_pattern.format(fqn, i) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
def scenario( wallets, **kw ): # disable subdomains at first subdomaindb_path = None blockstack_opts = blockstack.lib.config.get_blockstack_opts() assert 'subdomaindb_path' in blockstack_opts subdomaindb_path = blockstack_opts['subdomaindb_path'] del blockstack_opts['subdomaindb_path'] blockstack.lib.config.set_blockstack_opts(blockstack_opts) 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.blockstack_name_preorder( "foo3.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo4.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo5.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo6.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo7.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format('foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format('foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format('foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } # register initial subdomains testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.blockstack_name_register( "foo4.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo5.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo6.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo7.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.next_block( **kw ) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # send updates, but only on foo1.test. for i in range(0, 3): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(i+1) name = 'foo{}.test'.format(i+4) zonefiles = { 'foo1.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo1.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo2.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo3.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # subdomains should not exist---we haven't indexed them yet for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' not in res: print 'got a subdomain' print res return False # wait until they exist testlib.next_block(**kw) testlib.next_block(**kw) testlib.next_block(**kw) blockstack_opts['subdomaindb_path'] = subdomaindb_path blockstack.lib.config.set_blockstack_opts(blockstack_opts) testlib.next_block(**kw) # query each subdomain for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, hostport='http://localhost:16264') if 'error' in res: print res return False # domain should be foo6.test if res['domain'] != 'foo6.test': print 'wrong domain' print res return False expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(firstblock=256, **kw)
def scenario(wallets, **kw): start_subdomain_registrar() 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("personal.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) registrar_zf = '$ORIGIN personal.test\n$TTL 3600\n_registrar URI 10 1 "http://localhost:%s"\n_resolver URI 10 1 "http://localhost:%s"\n' % ( registrar_port, registrar_port) registrar_zf_hash = storage.get_zonefile_data_hash(registrar_zf) testlib.blockstack_name_register("personal.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=registrar_zf_hash) testlib.next_block(**kw) testlib.blockstack_put_zonefile(registrar_zf) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' # request to register hello_XXX.personal.test for i in range(0, 3): sub_name = 'hello_{}.personal.test'.format(i) sub_zf = zf_template.format(sub_name, zf_default_url) req_json = { 'name': 'hello_{}'.format(i + 1), 'owner_address': virtualchain.address_reencode(wallets[i].addr, network='mainnet'), 'zonefile': sub_zf, } resp = requests.post( 'http://localhost:{}/register'.format(registrar_port), json=req_json, headers={'Authorization': 'bearer test_registrar'}) if resp.status_code != 202: print 'did not accept {}'.format(sub_name) print resp.text return False # try to resolve each name on the subdomain registrar for i in range(0, 3): sub_name = 'hello_{}.personal.test'.format(i) resp = requests.get('http://localhost:{}/status/{}'.format( registrar_port, sub_name)) status = resp.json() print json.dumps(status, indent=4, sort_keys=True) if resp.status_code != 200: print 'not accepted: {}'.format(sub_name) return False # test /v1/names/{} emulation on the subdomain registrar for i in range(0, 3): sub_name = 'hello_{}.personal.test'.format(i) resp = requests.get('http://localhost:{}/v1/names/{}'.format( registrar_port, sub_name)) status = resp.json() print json.dumps(status, indent=4, sort_keys=True) if 'pending_subdomain' != status['status']: print 'not pending: {}'.format(sub_name) return False if len(status['txid']) != 0: print 'not pending: {}'.format(sub_name) return False # test /v1/names/{} redirect from Blockstack Core for i in range(0, 3): sub_name = 'hello_{}.personal.test'.format(i) resp = requests.get('http://localhost:{}/v1/names/{}'.format( 16268, sub_name)) status = resp.json() print json.dumps(status, indent=4, sort_keys=True) if 'pending_subdomain' != status['status']: print 'not pending: {}'.format(sub_name) return False if len(status['txid']) != 0: print 'not pending: {}'.format(sub_name) return False # tell the registrar to flush the queue # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder( "foo3.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo4.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo5.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo6.test", wallets[2].privkey, wallets[3].addr ) testlib.blockstack_name_preorder( "foo7.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format('foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format('foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format('foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.blockstack_name_register( "foo4.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo5.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo6.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.blockstack_name_register( "foo7.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.next_block( **kw ) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # update and transfer, but if i % 2 == 0, transfer to a different address # use a different domain name in each case. # verify that only transfers on the creator domain are valid. wallet_schedule = [ (4, 0), # won't be accepted due to domain independence (4, 1), # will be accepted (1, 2), # won't be accepted due to domain independence (1, 3), # will be accepted ] sequence_schedule = [ 1, # won't be accepted due to domain independence 1, # will be accepted 2, # won't be accepted due to domain independence 2, # will be accepted ] expected_zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(4) for i in range(0, 4): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(i+1) if i % 2 == 0: names = [ 'foo{}.test'.format(i+4), 'foo{}.test'.format(i+4), 'foo{}.test'.format(i+4), ] else: names = [ 'foo1.test', 'foo2.test', 'foo3.test', ] k = wallet_schedule[i][0] k2 = wallet_schedule[i][1] s = sequence_schedule[i] zonefiles = { 'foo1.test': zf_template.format(names[0], subdomains.make_subdomain_txt('bar.foo1.test', names[0], wallets[k2].addr, s, zf_template.format('bar.foo1.test', zf_default_url), wallets[k].privkey)), 'foo2.test': zf_template.format(names[1], subdomains.make_subdomain_txt('bar.foo2.test', names[1], wallets[k2].addr, s, zf_template.format('bar.foo2.test', zf_default_url), wallets[k].privkey)), 'foo3.test': zf_template.format(names[2], subdomains.make_subdomain_txt('bar.foo3.test', names[2], wallets[k2].addr, s, zf_template.format('bar.foo3.test', zf_default_url), wallets[k].privkey)), } testlib.blockstack_name_update(names[0], storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update(names[1], storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update(names[2], storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) # query each subdomain proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False if res['sequence'] != 2: print 'wrong sequence' print res return False if virtualchain.address_reencode(str(res['address'])) != virtualchain.address_reencode(wallets[3].addr): print 'wrong owner' print res return False expected_zonefile = zf_template.format(fqn, expected_zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # there should only be three history items per name hist = client.get_name_record(fqn, proxy=proxy, include_history=True) if 'error' in hist: print res return False if len(hist['history']) != 3: print 'wrong history length' print res return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zf_default_url_initial = zf_default_url zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } initial_zonefiles = zonefiles testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://invalid.com"' zf_default_url_invalid = zf_default_url zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } # send updates for invalid initial subdomain records testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off subdomain indexing. testlib.next_block(**kw) # must all be pending proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if not res['pending']: print 'not pending: {}'.format(fqn) print res return False # broadcast initial zonefiles and re-do subdomain indexing assert testlib.blockstack_put_zonefile(initial_zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(initial_zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(initial_zonefiles['foo3.test']) testlib.next_block(**kw) proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False # right subdomain zonefile expected_zonefile = zf_template.format(fqn, zf_default_url_initial) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo4.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo5.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo6.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo7.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.blockstack_name_register("foo4.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_register("foo5.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_register("foo6.test", wallets[2].privkey, wallets[3].addr) testlib.blockstack_name_register("foo7.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # kick off indexing and check testlib.next_block(**kw) def _query_subdomains(subdomain_names, expected_sequence, expected_owner, expect_pending): # query each subdomain. Should get the latest proxy = testlib.make_proxy() for fqn in subdomain_names: res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res print 'failed to query {}'.format(fqn) return False # should have right sequence if res['sequence'] != expected_sequence: print 'wrong sequence; expected {}'.format(expected_sequence) print res return False # should have right owner if res['address'] != expected_owner: print 'wrong owner' print 'expected {}'.format(res['address']) print res return False # do we expect pending? if res['pending'] != expect_pending: print 'wrong pending (expected {})'.format(expect_pending) print res return False return True assert _query_subdomains( ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'], 0, wallets[4].addr, False) expected_owners_before = [wallets[4].addr] expected_owners_after = [wallets[4].addr] # update and transfer, but if i % 2 == 0, transfer to a different address # use a different domain name in each case. # verify that only transfers on the creator domain are valid. wallet_schedule = [ (4, 0), # not broadcast initially (4, 1), (0, 1), # not broadcast initially (1, 2), ] sequence_schedule = [ 1, 1, 2, 2, ] expected_zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( 4) expect_pending = False expect_sequence = 0 expect_owner = wallets[4].addr unsent_zonefiles = [] # send updates too, and transfer subdomains for i in range(0, 4): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( i + 1) names = [ 'foo1.test', 'foo2.test', 'foo3.test', ] k = wallet_schedule[i][0] k2 = wallet_schedule[i][1] s = sequence_schedule[i] zonefiles = { 'foo1.test': zf_template.format( names[0], subdomains.make_subdomain_txt( 'bar.foo1.test', names[0], wallets[k2].addr, s, zf_template.format('bar.foo1.test', zf_default_url), wallets[k].privkey)), 'foo2.test': zf_template.format( names[1], subdomains.make_subdomain_txt( 'bar.foo2.test', names[1], wallets[k2].addr, s, zf_template.format('bar.foo2.test', zf_default_url), wallets[k].privkey)), 'foo3.test': zf_template.format( names[2], subdomains.make_subdomain_txt( 'bar.foo3.test', names[2], wallets[k2].addr, s, zf_template.format('bar.foo3.test', zf_default_url), wallets[k].privkey)), } testlib.blockstack_name_update( names[0], storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( names[1], storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( names[2], storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) if i % 2 == 1: # only broadcast periodically assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) expect_owner = wallets[k2].addr expect_sequence += 1 expected_owners_before.append(expect_owner) else: expect_pending = True unsent_zonefiles.append(zonefiles) expected_owners_after.append(wallets[k2].addr) # kick off subdomain indexing testlib.next_block(**kw) # verify history assert _query_subdomains( ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'], expect_sequence, expect_owner, expect_pending) # query subdomain history proxy = testlib.make_proxy() for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']: res = client.get_name_record(subd, include_history=True, proxy=proxy) if 'error' in res: print res return False if not res['pending']: print 'not pending, but it should be' print res return False # should be at 2 if res['sequence'] != 2: print 'wrong sequence' print res return False if virtualchain.address_reencode(str( res['address'])) != virtualchain.address_reencode( expect_owner): print 'wrong owner' print res return False for i, block_height in enumerate(sorted(res['history'])): if virtualchain.address_reencode( str(res['history'][block_height][0]['address']) ) != virtualchain.address_reencode(expected_owners_before[i]): print 'wrong owner at {}: expected {}'.format( block_height, expected_owners_before[i]) print json.dumps(res, indent=4, sort_keys=True) print expected_owners_before return False if res['history'][block_height][0]['sequence'] != i: print 'wrong sequence at {}: expected {}'.format( block_height, i) print json.dumps(res, indent=4, sort_keys=True) return False # send all missing subdomains. # should cause a cascading owner reorg. for zfbatch in unsent_zonefiles: for k in zfbatch: assert testlib.blockstack_put_zonefile(zfbatch[k]) testlib.next_block(**kw) # query subdomain history again. pending and owner should change proxy = testlib.make_proxy() for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']: res = client.get_name_record(subd, include_history=True, proxy=proxy) if 'error' in res: print res return False if res['pending']: print 'pending, but it should not be' print res return False if res['sequence'] != 2: print 'wrong sequence' print res return False if virtualchain.address_reencode(str( res['address'])) != virtualchain.address_reencode( wallets[1].addr): print 'wrong owner again' print res return False for i, block_height in enumerate(sorted(res['history'])): if virtualchain.address_reencode( str(res['history'][block_height][0]['address']) ) != virtualchain.address_reencode(str(expected_owners_after[i])): print 'wrong owner at {}: expected {}'.format( block_height, expected_owners_after[i]) print json.dumps(res, indent=4, sort_keys=True) print expected_owners_after print expected_owners_before print[wallets[i].addr for i in range(0, len(wallets))] return False if res['history'][block_height][0]['sequence'] != i: print 'wrong sequence at {}: expected {}'.format( block_height, i) print json.dumps(res, indent=4, sort_keys=True) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) # whois for i in xrange(1, 4): name = 'foo{}.test'.format(i) res = testlib.blockstack_cli_whois(name) if 'error' in res: print res return False if not res.has_key('zonefile_hash') or res[ 'zonefile_hash'] != storage.get_zonefile_data_hash( zonefiles[name]): print res return False if res['owner_address'] != wallets[3].addr: print res return False # upload zonefile assert testlib.blockstack_put_zonefile(zonefiles[name]) # kick off subdomain indexing testlib.next_block(**kw) # query each subdomain proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # send two sequence=1 updates, but withhold the first batch. send the second batch now, and then send the first batch later to confirm # that each subdomain's history gets reorganized. # first sequence=1 update (withheld) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/withheld?index={}"'.format( 1) zf_default_url_reorg = zf_default_url zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } zonefiles_reorg = zonefiles testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) # second sequence=1 update (sent now) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( 1) zf_default_url_seq1 = zf_default_url zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } zonefiles_seq1 = zonefiles testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) # sequence=2 (send now) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( 1) zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 2, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 2, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 2, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) assert testlib.blockstack_put_zonefile(zonefiles['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles['foo3.test']) def _query_subdomains(): # query each subdomain. Should get the latest proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False return True # kick off subdomain indexing testlib.next_block(**kw) assert _query_subdomains() # query each subdomain history. sequence=1 should have test.com, but not 'withheld' for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) proxy = testlib.make_proxy() res = client.get_name_record(fqn, proxy=proxy, include_history=True) if 'error' in res: print res return False # expect zonefile expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # find historic historic_blocks = res['history'].keys() historic_blocks.sort() historic_zfhash = res['history'][str( historic_blocks[1])][0]['value_hash'] # historic zone file (sequence=1) should NOT be withheld zf = testlib.blockstack_get_zonefile(historic_zfhash, parse=False) if not zf: print 'no zone file {} for sequence=1 in atlas'.format( res['value_hash']) return False expected_zonefile = zf_template.format(fqn, zf_default_url_seq1) if zf != expected_zonefile: print 'zonefile mismatch in atlas at sequence=1' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reorg each zonefile's history assert testlib.blockstack_put_zonefile(zonefiles_reorg['foo1.test']) assert testlib.blockstack_put_zonefile(zonefiles_reorg['foo2.test']) assert testlib.blockstack_put_zonefile(zonefiles_reorg['foo3.test']) # kick off subdomain indexing testlib.next_block(**kw) assert _query_subdomains() # query each subdomain history. sequence=1 should have test.com, but with 'withheld' present in the URL for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) proxy = testlib.make_proxy() res = client.get_name_record(fqn, proxy=proxy, include_history=True) if 'error' in res: print res return False # expect zonefile expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # find historic historic_blocks = res['history'].keys() historic_blocks.sort() historic_zfhash = res['history'][str( historic_blocks[1])][0]['value_hash'] # historic zone file (sequence=1) should NOT be withheld zf = testlib.blockstack_get_zonefile(historic_zfhash, parse=False) if not zf: print 'no zone file {} for sequence=1 in atlas'.format( res['value_hash']) return False expected_zonefile = zf_template.format(fqn, zf_default_url_reorg) if zf != expected_zonefile: print 'zonefile mismatch in atlas at sequence=1' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)
def scenario(wallets, **kw): wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy(test_proxy) zonefile_batches = [] 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.blockstack_name_preorder("foo3.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } zonefile_batches.append(zonefiles) testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test'])) testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test'])) testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test'])) testlib.next_block(**kw) # send updates too for i in range(0, 3): zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format( i + 1) zonefiles = { 'foo1.test': zf_template.format( 'foo1.test', subdomains.make_subdomain_txt( 'bar.foo1.test', 'foo1.test', wallets[4].addr, i + 1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)), 'foo2.test': zf_template.format( 'foo2.test', subdomains.make_subdomain_txt( 'bar.foo2.test', 'foo2.test', wallets[4].addr, i + 1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)), 'foo3.test': zf_template.format( 'foo3.test', subdomains.make_subdomain_txt( 'bar.foo3.test', 'foo3.test', wallets[4].addr, i + 1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)), } zonefile_batches.append(zonefiles) testlib.blockstack_name_update( 'foo1.test', storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo2.test', storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey) testlib.blockstack_name_update( 'foo3.test', storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey) testlib.next_block(**kw) # send all zonefiles at once for zfbatch in zonefile_batches: for name in zfbatch: assert testlib.blockstack_put_zonefile(zfbatch[name]) # kick off subdomain indexing testlib.next_block(**kw) # query each subdomain proxy = testlib.make_proxy() for i in xrange(1, 4): fqn = 'bar.foo{}.test'.format(i) res = client.get_name_record(fqn, proxy=proxy) if 'error' in res: print res return False expected_zonefile = zf_template.format(fqn, zf_default_url) if base64.b64decode(res['zonefile']) != expected_zonefile: print 'zonefile mismatch' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # should be in atlas as well zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False) if not zf: print 'no zone file {} in atlas'.format(res['value_hash']) return False if zf != expected_zonefile: print 'zonefile mismatch in atlas' print 'expected\n{}'.format(expected_zonefile) print 'got\n{}'.format(base64.b64decode(res['zonefile'])) return False # reindex assert testlib.check_subdomain_db(**kw)