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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
def check(state_engine):

    global zonefile_hash

    # not revealed, but ready
    ns = state_engine.get_namespace_reveal("test")
    if ns is not None:
        print "namespace reveal exists"
        return False

    ns = state_engine.get_namespace("test")
    if ns is None:
        print "no namespace"
        return False

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False

    # registered
    name_rec = state_engine.get_name("foo.test")
    if name_rec is None:
        print "name does not exist"
        return False

    # owned by
    owner_address = wallets[3].addr
    if name_rec['address'] != owner_address or name_rec[
            'sender'] != pybitcoin.make_pay_to_address_script(owner_address):
        print "sender is wrong"
        return False

    # value hash
    if name_rec['value_hash'] != zonefile_hash:
        print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'],
                                                 zonefile_hash)
        return False

    # replicated?
    zonefile = testlib.blockstack_get_zonefile(zonefile_hash)
    if 'error' in zonefile:
        print "zonefile error: %s" % zonefile['error']
        return False

    # right hash?
    if blockstack_client.hash_zonefile(zonefile) != zonefile_hash:
        print "wrong zonefile: %s != %s" % (
            blockstack_client.hash_zonefile(zonefile), zonefile_hash)
        return False

    # all queues are drained
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(
            queue_info, indent=4, sort_keys=True)
        return False

    return True
def check( state_engine ):

    # not revealed, but ready 
    ns = state_engine.get_namespace_reveal( "test" )
    if ns is not None:
        print "namespace reveal exists"
        return False 

    ns = state_engine.get_namespace( "test" )
    if ns is None:
        print "no namespace"
        return False 

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False 
   
    names = ['foo.test', 'bar.test', 'baz.test', 'goo.test']
    addresses = [wallets[2].addr, wallets[3].addr, wallets[4].addr, wallets[5].addr]
    zonefiles = ["Hello foo.test!", "Hello bar.test!", "Hello baz.test!", "Hello goo.test!"]

    for i in xrange(0, len(names)):
        name = names[i]
        owner_address = addresses[i]
        zonefile = zonefiles[i]

        # registered 
        name_rec = state_engine.get_name( name )
        if name_rec is None:
            print "name {} does not exist".format(name)
            return False 

        # owned by the right address 
        if name_rec['address'] != owner_address or name_rec['sender'] != virtualchain.make_payment_script(owner_address):
            print "sender is wrong for {}".format(name)
            return False 

        # has the right zone file
        zf = testlib.blockstack_get_zonefile(name_rec['value_hash'], parse=False)
        if zf is None:
            print "no zonefile for {}".format(name)
            return False

        if zf != zonefile:
            print "zonefile mismatch: expected {}, got {}".format(zonefile, zf)
            return False

    # all queues are drained 
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True)
        return False

    return True
def check( state_engine ):

    global zonefile_hash

    # not revealed, but ready 
    ns = state_engine.get_namespace_reveal( "test" )
    if ns is not None:
        print "namespace reveal exists"
        return False 

    ns = state_engine.get_namespace( "test" )
    if ns is None:
        print "no namespace"
        return False 

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False 
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

    # owned by
    owner_address = wallets[3].addr
    if name_rec['address'] != owner_address or name_rec['sender'] != virtualchain.make_payment_script(owner_address):
        print "sender is wrong"
        return False 

    # value hash 
    if name_rec['value_hash'] != zonefile_hash:
        print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'], zonefile_hash)
        return False

    # replicated?
    zonefile = testlib.blockstack_get_zonefile( zonefile_hash )
    if 'error' in zonefile:
        print "zonefile error: %s" % zonefile['error']
        return False

    # right hash?
    if blockstack_client.hash_zonefile( zonefile ) != zonefile_hash:
        print "wrong zonefile: %s != %s" % (blockstack_client.hash_zonefile(zonefile), zonefile_hash)
        return False

    # all queues are drained 
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True)
        return False

    return True
def check( state_engine ):

    global zonefile_hash

    # not revealed, but ready 
    ns = state_engine.get_namespace_reveal( "test" )
    if ns is not None:
        print "namespace reveal exists"
        return False 

    ns = state_engine.get_namespace( "test" )
    if ns is None:
        print "no namespace"
        return False 

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False 
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

    # owned by
    owner_address = wallets[4].addr
    if name_rec['address'] != owner_address or name_rec['sender'] != pybitcoin.make_pay_to_address_script(owner_address):
        print "sender is wrong"
        return False 

    # value hash 
    if name_rec['value_hash'] != zonefile_hash:
        print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'], zonefile_hash)
        return False

    # replicated?
    zonefile = testlib.blockstack_get_zonefile( zonefile_hash )
    if 'error' in zonefile:
        print "zonefile error: %s" % zonefile['error']
        return False

    # right hash?
    if blockstack_client.hash_zonefile( zonefile ) != zonefile_hash:
        print "wrong zonefile: %s != %s" % (blockstack_client.hash_zonefile(zonefile), zonefile_hash)
        return False

    # latest key?
    if not zonefile.has_key("txt"):
        print "no txt:\n%s" % json.dumps(zonefile, indent=4, sort_keys=True)
        return False 

    if len(zonefile['txt']) != 2:
        print "wrong number of txt records:\n%s" % json.dumps(zonefile, indent=4, sort_keys=True)
        return False

    for txtrec in zonefile['txt']:
        if txtrec['name'] == 'pubkey':
            if new_data_pubkey not in txtrec['txt']:
                print "wrong pubkey:\n%s" % json.dumps(zonefile, indent=4, sort_keys=True)
                print "missing %s" % new_data_pubkey
                return False

    # doesn't show up in listing
    names_owned = testlib.blockstack_rpc_names()
    if 'error' in names_owned:
        print "rpc names: %s" % names_owned['error']
        return False

    # we updated the wallet; we should own one name
    if len(names_owned['names_owned']) != 1:
        print "owned: %s" % names_owned['names_owned']
        return False

    # all queues are drained 
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True)
        return False

    return True
def check(state_engine):

    # not revealed, but ready
    ns = state_engine.get_namespace_reveal("test")
    if ns is not None:
        print "namespace reveal exists"
        return False

    ns = state_engine.get_namespace("test")
    if ns is None:
        print "no namespace"
        return False

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False

    names = ['foo.test', 'bar.test', 'baz.test', 'goo.test']
    addresses = [
        wallets[2].addr, wallets[3].addr, wallets[4].addr, wallets[5].addr
    ]
    zonefiles = [
        "Hello foo.test!", "Hello bar.test!", "Hello baz.test!",
        "Hello goo.test!"
    ]

    for i in xrange(0, len(names)):
        name = names[i]
        owner_address = addresses[i]
        zonefile = zonefiles[i]

        # registered
        name_rec = state_engine.get_name(name)
        if name_rec is None:
            print "name {} does not exist".format(name)
            return False

        # owned by the right address
        if name_rec['address'] != owner_address or name_rec[
                'sender'] != virtualchain.make_payment_script(owner_address):
            print "sender is wrong for {}".format(name)
            return False

        # has the right zone file
        zf = testlib.blockstack_get_zonefile(name_rec['value_hash'],
                                             parse=False)
        if zf is None:
            print "no zonefile for {}".format(name)
            return False

        if zf != zonefile:
            print "zonefile mismatch: expected {}, got {}".format(zonefile, zf)
            return False

    # all queues are drained
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(
            queue_info, indent=4, sort_keys=True)
        return False

    return True
Ejemplo n.º 8
0
def check(state_engine):

    # not revealed, but ready
    ns = state_engine.get_namespace_reveal("test")
    if ns is not None:
        print "namespace reveal exists"
        return False

    ns = state_engine.get_namespace("test")
    if ns is None:
        print "no namespace"
        return False

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False

    for i in xrange(0, 5):
        # registered
        name_rec = state_engine.get_name("foo_%s.test" % i)
        if name_rec is None:
            print "name does not exist"
            return False

        # owned by
        owner_address = wallets[3].addr
        if name_rec['address'] != owner_address or name_rec[
                'sender'] != pybitcoin.make_pay_to_address_script(
                    owner_address):
            print "sender is wrong"
            return False

        # have a zonefile
        zonefile = testlib.blockstack_get_zonefile(name_rec['value_hash'])
        if zonefile is None or 'error' in zonefile:
            if zonefile is not None:
                print "zonefile lookup error: %s" % zonefile['error']
            else:
                print "no zonefile returned"
            return False

        # hashes to this zonefile
        if blockstack_client.hash_zonefile(zonefile) != name_rec['value_hash']:
            print "wrong zonefile: %s != %s" % (
                blockstack_client.hash_zonefile(zonefile),
                name_rec['value_hash'])
            return False

        # verify that the profile is there
        profile = testlib.blockstack_get_profile("foo_%s.test" % i)
        if profile is None or 'error' in profile:
            if profile is None:
                print "no profile returned"
            else:
                print "profile lookup error: %s" % profile['error']

            return False

    # all queues are drained
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(
            queue_info, indent=4, sort_keys=True)
        return False

    return True
def scenario( wallets, **kw ):

    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 ):
    
    # 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)
Ejemplo n.º 11
0
def check(state_engine):

    global preorder_info, register_info, update_info, balance_before, balance_after, names_owned_before, names_owned_after, whois, blockchain_record, deposit_info, price_info
    global blockchain_history, zonefile_info, all_names_info, namespace_names_info, wallet_info, lookup_info, update_history, zonefile_history, names_info

    # not revealed, but ready
    ns = state_engine.get_namespace_reveal("test")
    if ns is not None:
        print "namespace reveal exists"
        return False

    ns = state_engine.get_namespace("test")
    if ns is None:
        print "no namespace"
        return False

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False

    # registered
    name_rec = state_engine.get_name("foo.test")
    if name_rec is None:
        print "name does not exist"
        return False

    # owned by the right address
    owner_address = wallets[3].addr
    if name_rec['address'] != owner_address or name_rec[
            'sender'] != pybitcoin.make_pay_to_address_script(owner_address):
        print "sender is wrong"
        return False

    # all queues are drained
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(
            queue_info, indent=4, sort_keys=True)
        return False

    # have an update hash
    if 'value_hash' not in name_rec or name_rec.get('value_hash',
                                                    None) is None:
        print "No value hash"
        return False

    # have a zonefile
    zonefile = testlib.blockstack_get_zonefile(name_rec['value_hash'])
    if zonefile is None or 'error' in zonefile:
        if zonefile is not None:
            print "zonefile lookup error: %s" % zonefile['error']
        else:
            print "no zonefile returned"
        return False

    # hashes to this zonefile
    if blockstack_client.hash_zonefile(zonefile) != name_rec['value_hash']:
        print "wrong zonefile: %s != %s" % (
            blockstack_client.hash_zonefile(zonefile), name_rec['value_hash'])
        return False

    # verify that the profile is there
    profile = testlib.blockstack_get_profile("foo.test")
    if profile is None or 'error' in profile:
        if profile is None:
            print "no profile returned"
        else:
            print "profile lookup error: %s" % profile['error']

        return False

    # check queue operations
    for queue_type, queue_state in [("preorder", preorder_info),
                                    ("register", register_info),
                                    ("update", update_info)]:
        if not queue_state.has_key('queues'):
            print "missing queues:\n%s" % json.dumps(
                queue_state, indent=4, sort_keys=True)
            return False

        for k in ['name', 'confirmations', 'tx_hash']:
            for q in queue_state['queues'][queue_type]:
                if not q.has_key(k):
                    print "missing key %s\n%s" % (
                        k, json.dumps(queue_state, indent=4, sort_keys=True))
                    return False

                if q['name'] != 'foo.test':
                    print "wrong name: %s" % queue_state['name']
                    return False

    # check price
    for k in [
            'preorder_tx_fee', 'register_tx_fee', 'update_tx_fee',
            'total_estimated_cost', 'name_price'
    ]:
        if not price_info.has_key(k):
            print "bad price info (missing %s):\n%s" % (
                k, json.dumps(price_info, indent=4, sort_keys=True))
            return False

    # deposit info
    if not deposit_info.has_key(
            'address') or deposit_info['address'] != wallets[2].addr:
        print "bad deposit info:\n%s" % json.dumps(
            deposit_info, indent=4, sort_keys=True)
        return False

    # whois info
    for k in [
            'block_preordered_at', 'block_renewed_at', 'last_transaction_id',
            'owner_address', 'owner_script', 'expire_block', 'has_zonefile',
            'zonefile_hash'
    ]:
        if not whois.has_key(k):
            print "bad whois: missing %s\n%s" % (
                k, json.dumps(whois, indent=4, sort_keys=True))
            return False

    # balance
    for balance_info in [balance_before, balance_after]:
        for k in ['total_balance', 'addresses']:
            if not balance_info.has_key(k):
                print "missing '%s'\n%s" % (
                    k, json.dumps(balance_info, indent=4, sort_keys=True))
                return False

    # name listing
    if len(names_owned_before) != 0:
        print "owned before: %s" % names_owned_before
        return False

    if len(names_owned_after) != 1 or names_owned_after[0] != 'foo.test':
        print "owned after: %s" % names_owned_after
        return False

    # blockchain record
    for k in [
            'name', 'op', 'op_fee', 'opcode', 'vtxindex', 'txid', 'value_hash',
            'sender', 'address', 'history'
    ]:
        if not blockchain_record.has_key(k):
            print "missing %s\n%s" % (
                k, json.dumps(blockchain_record, indent=4, sort_keys=True))
            return False

    # blockchain history (should have a preorder, register, and 2 updates)
    if len(blockchain_history) != 4:
        print "invalid history\n%s\n" % json.dumps(
            blockchain_history, indent=4, sort_keys=True)
        return False

    block_heights = blockchain_history.keys()
    block_heights.sort()
    expected_opcodes = [
        'NAME_PREORDER', 'NAME_REGISTRATION', 'NAME_UPDATE', 'NAME_UPDATE'
    ]
    for bh, opcode in zip(block_heights, expected_opcodes):
        if len(blockchain_history[bh]) != 1:
            print "invalid history: multiple ops at %s\n%s" % (
                bh, json.dumps(blockchain_history, indent=4, sort_keys=True))
            return False

        if blockchain_history[bh][0]['opcode'] != opcode:
            print "invalid history: expected %s at %s\n%s" % (
                opcode, bh,
                json.dumps(blockchain_history, indent=4, sort_keys=True))
            return False

    # zonefile info
    if zonefile_info is None or type(zonefile_info) != dict:
        print "invalid zonefile\n%s\n" % zonefile_info
        return False

    if not zonefile_info.has_key('zonefile'):
        print "missing zonefile\n%s\n" % zonefile_info
        return False

    # name query
    if type(all_names_info) == dict and 'error' in all_names_info:
        print "error in all_names: %s" % all_names_info
        return False

    all_names = all_names_info
    if len(all_names) != 1 or all_names != ['foo.test']:
        print "all names: %s" % all_names
        return False

    # namespace query
    if type(namespace_names_info) == dict and 'error' in namespace_names_info:
        print "error in namesace_names: %s" % namespace_names_info
        return False

    namespace_names = namespace_names_info
    if len(namespace_names) != 1 or namespace_names != ['foo.test']:
        print "all namespace names: %s" % namespace_names
        return False

    # wallet info
    for k in [
            'payment_privkey', 'owner_privkey', 'data_privkey',
            'payment_address', 'owner_address', 'data_pubkey'
    ]:
        if not wallet_info.has_key(k):
            print "missing %s\n%s" % (
                k, json.dumps(wallet_info, indent=4, sort_keys=True))
            return False

    # profile info
    for k in ['profile', 'zonefile']:
        if not lookup_info.has_key(k):
            print "missing '%s'\n%s" % (
                k, json.dumps(lookup_info, indent=4, sort_keys=True))
            return False

    if lookup_info['zonefile'] != zonefile_info['zonefile']:
        print "unequal zonefiles:\n%s\n%s" % (
            json.dumps(lookup_info['zonefile'], indent=4, sort_keys=True),
            json.dumps(zonefile_info['zonefile'], indent=4, sort_keys=True))
        return False

    # update history (2 items)
    if len(update_history
           ) != 2 or update_history[1] != blockchain_record['value_hash']:
        print "invalid update history\n%s" % json.dumps(
            update_history, indent=4, sort_keys=True)
        return False

    # zonefile history (expect 2 items)
    if len(zonefile_history
           ) != 2 or zonefile_history[1] != zonefile_info['zonefile']:
        print "invalid zonefile history\n%s" % json.dumps(
            zonefile_history, indent=4, sort_keys=True)
        return False

    # names info
    if type(names_info) != dict:
        print "invalid names info: %s" % names_info
        return False

    for k in ['names_owned', 'addresses']:
        if not names_info.has_key(k):
            print "invalid names info (missing %s): %s" % (k, names_info)
            return False

    if len(names_info['addresses']) != 1:
        print "invalid names info (addresses): %s" % names_info
        return False

    if names_info['addresses'][0]['names_owned'] != ['foo.test']:
        print "invalid names info (names_owned): %s" % names_info
        return False

    if names_info['addresses'][0]['address'] != wallets[3].addr:
        print "invalid names info (addresses.address): %s" % names_info
        return False

    # immutable data
    immutable_data = testlib.blockstack_cli_get_immutable(
        "foo.test", "hello_world")
    if 'error' in immutable_data:
        print "Failed to get immutable data 'hello_world'"
        print json.dumps(immutable_data, indent=4, sort_keys=True)
        return False

    if 'data' not in immutable_data:
        print "invalid immutable_data: %s" % immutable_data
        return False

    if json.loads(immutable_data['data']) != {'hello': 'world'}:
        print "failed to get immutable data"
        print 'exected %s, got %s' % ({
            'hello': 'world'
        }, immutable_data['data'])
        return False

    return True
Ejemplo n.º 12
0
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 check( state_engine ):

    # not revealed, but ready 
    ns = state_engine.get_namespace_reveal( "test" )
    if ns is not None:
        print "namespace reveal exists"
        return False 

    ns = state_engine.get_namespace( "test" )
    if ns is None:
        print "no namespace"
        return False 

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False 
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

    # owned by the right address 
    owner_address = wallets[3].addr
    if name_rec['address'] != owner_address or name_rec['sender'] != virtualchain.make_payment_script(owner_address):
        print "sender is wrong"
        print "%s != %s or %s != %s" % (name_rec['address'], owner_address, name_rec['sender'], virtualchain.make_payment_script(owner_address))
        return False 

    # all queues are drained 
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True)
        return False

    # have an update hash 
    if 'value_hash' not in name_rec or name_rec.get('value_hash', None) is None:
        print "No value hash"
        return False 

    # have a zonefile 
    zonefile = testlib.blockstack_get_zonefile( name_rec['value_hash'] )
    if zonefile is None or 'error' in zonefile:
        if zonefile is not None:
            print "zonefile lookup error: %s" % zonefile['error']
        else:
            print "no zonefile returned"
        return False

    # hashes to this zonefile 
    if blockstack_client.hash_zonefile( zonefile ) != name_rec['value_hash']:
        print "wrong zonefile: %s != %s" % (blockstack_client.hash_zonefile(zonefile), name_rec['value_hash'])
        return False

    # verify that the profile is there 
    profile = testlib.blockstack_get_profile( "foo.test" )
    if profile is None or 'error' in profile:
        if profile is None:
            print "no profile returned"
        else:
            print "profile lookup error: %s" % profile['error']

        return False

    return True
def 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)
Ejemplo n.º 15
0
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)
Ejemplo n.º 16
0
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 check( state_engine ):

    global preorder_info, register_info, update_info, balance_before, balance_after, names_owned_before, names_owned_after, whois, blockchain_record, deposit_info, price_info
    global blockchain_history, zonefile_info, all_names_info, namespace_names_info, wallet_info, lookup_info, update_history, zonefile_history, names_info

    # not revealed, but ready 
    ns = state_engine.get_namespace_reveal( "test" )
    if ns is not None:
        print "namespace reveal exists"
        return False 

    ns = state_engine.get_namespace( "test" )
    if ns is None:
        print "no namespace"
        return False 

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False 
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

    # owned by the right address 
    owner_address = wallets[3].addr
    if name_rec['address'] != owner_address or name_rec['sender'] != pybitcoin.make_pay_to_address_script(owner_address):
        print "sender is wrong"
        return False 

    # all queues are drained 
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True)
        return False

    # have an update hash 
    if 'value_hash' not in name_rec or name_rec.get('value_hash', None) is None:
        print "No value hash"
        return False 

    # have a zonefile 
    zonefile = testlib.blockstack_get_zonefile( name_rec['value_hash'] )
    if zonefile is None or 'error' in zonefile:
        if zonefile is not None:
            print "zonefile lookup error: %s" % zonefile['error']
        else:
            print "no zonefile returned"
        return False

    # hashes to this zonefile 
    if blockstack_client.hash_zonefile( zonefile ) != name_rec['value_hash']:
        print "wrong zonefile: %s != %s" % (blockstack_client.hash_zonefile(zonefile), name_rec['value_hash'])
        return False

    # verify that the profile is there 
    profile = testlib.blockstack_get_profile( "foo.test" )
    if profile is None or 'error' in profile:
        if profile is None:
            print "no profile returned"
        else:
            print "profile lookup error: %s" % profile['error']

        return False

    # check queue operations 
    for queue_type, queue_state in [("preorder", preorder_info), ("register", register_info), ("update", update_info)]:
        if not queue_state.has_key('queues'):
            print "missing queues:\n%s" % json.dumps(queue_state, indent=4, sort_keys=True)
            return False

        for k in ['name', 'confirmations', 'tx_hash']:
            for q in queue_state['queues'][queue_type]:
                if not q.has_key(k):
                    print "missing key %s\n%s" % (k, json.dumps(queue_state, indent=4, sort_keys=True))
                    return False
            
                if q['name'] != 'foo.test':
                    print "wrong name: %s" % queue_state['name']
                    return False

    # check price
    for k in ['preorder_tx_fee', 'register_tx_fee', 'update_tx_fee', 'total_estimated_cost', 'name_price']:
        if not price_info.has_key(k):
            print "bad price info (missing %s):\n%s" % (k, json.dumps(price_info, indent=4, sort_keys=True))
            return False

    
    # deposit info 
    if not deposit_info.has_key('address') or deposit_info['address'] != wallets[2].addr:
        print "bad deposit info:\n%s" % json.dumps(deposit_info, indent=4, sort_keys=True)
        return False

    # whois info
    for k in ['block_preordered_at', 'block_renewed_at', 'last_transaction_id', 'owner_address', 'owner_script', 'expire_block', 'has_zonefile', 'zonefile_hash']:
        if not whois.has_key(k):
            print "bad whois: missing %s\n%s" % (k, json.dumps(whois, indent=4, sort_keys=True))
            return False
    
    # balance 
    for balance_info in [balance_before, balance_after]:
        for k in ['total_balance', 'addresses']:
            if not balance_info.has_key(k):
                print "missing '%s'\n%s" % (k, json.dumps(balance_info, indent=4, sort_keys=True))
                return False

    # name listing
    if len(names_owned_before) != 0:
        print "owned before: %s" % names_owned_before
        return False

    if len(names_owned_after) != 1 or names_owned_after[0] != 'foo.test':
        print "owned after: %s" % names_owned_after
        return False

    # blockchain record 
    for k in ['name', 'op', 'op_fee', 'opcode', 'vtxindex', 'txid', 'value_hash', 'sender', 'address', 'history']:
        if not blockchain_record.has_key(k):
            print "missing %s\n%s" % (k, json.dumps(blockchain_record, indent=4, sort_keys=True))
            return False

    # blockchain history (should have a preorder, register, and 2 updates)
    if len(blockchain_history) != 4:
        print "invalid history\n%s\n" % json.dumps(blockchain_history, indent=4, sort_keys=True)
        return False

    block_heights = blockchain_history.keys()
    block_heights.sort()
    expected_opcodes = ['NAME_PREORDER', 'NAME_REGISTRATION', 'NAME_UPDATE', 'NAME_UPDATE']
    for bh, opcode in zip(block_heights, expected_opcodes):
        if len(blockchain_history[bh]) != 1:
            print "invalid history: multiple ops at %s\n%s" % (bh, json.dumps(blockchain_history, indent=4, sort_keys=True))
            return False

        if blockchain_history[bh][0]['opcode'] != opcode:
            print "invalid history: expected %s at %s\n%s" % (opcode, bh, json.dumps(blockchain_history, indent=4, sort_keys=True))
            return False

    # zonefile info
    if zonefile_info is None or type(zonefile_info) != str:
        print "invalid zonefile\n%s\n" % zonefile_info
        return False

    # name query
    if type(all_names_info) == dict and 'error' in all_names_info:
        print "error in all_names: %s" % all_names_info
        return False

    all_names = all_names_info
    if len(all_names) != 1 or all_names != ['foo.test']:
        print "all names: %s" % all_names
        return False

    # namespace query
    if type(namespace_names_info) == dict and 'error' in namespace_names_info:
        print "error in namesace_names: %s" % namespace_names_info
        return False

    namespace_names = namespace_names_info
    if len(namespace_names) != 1 or namespace_names != ['foo.test']:
        print "all namespace names: %s" % namespace_names
        return False

    # wallet info
    for k in ['payment_privkey', 'owner_privkey', 'data_privkey', 'payment_address', 'owner_address', 'data_pubkey']:
        if not wallet_info.has_key(k):
            print "missing %s\n%s" % (k, json.dumps(wallet_info, indent=4, sort_keys=True))
            return False

    # profile info
    for k in ['profile', 'zonefile']:
        if not lookup_info.has_key(k):
            print "missing '%s'\n%s" % (k, json.dumps(lookup_info, indent=4, sort_keys=True))
            return False

    if lookup_info['zonefile'] != zonefile_info:
        print "unequal zonefiles:\n%s\n%s" % (json.dumps(lookup_info['zonefile'], indent=4, sort_keys=True), json.dumps(zonefile_info, indent=4, sort_keys=True))
        return False

    # update history (2 items)
    if len(update_history) != 2 or update_history[1] != blockchain_record['value_hash']:
        print "invalid update history\n%s" % json.dumps(update_history, indent=4, sort_keys=True)
        return False

    # zonefile history (expect 2 items)
    if len(zonefile_history) != 2 or zonefile_history[1] != zonefile_info:
        print "invalid zonefile history\n%s" % json.dumps(zonefile_history, indent=4, sort_keys=True)
        print "zonefile current:\n%s" % json.dumps(zonefile_info, indent=4, sort_keys=True)
        return False

    # names info
    if type(names_info) != dict:
        print "invalid names info: %s" % names_info
        return False
        
    for k in ['names_owned', 'addresses']:
        if not names_info.has_key(k):
            print "invalid names info (missing %s): %s" % (k, names_info)
            return False

    if len(names_info['addresses']) != 1:
        print "invalid names info (addresses): %s" % names_info
        return False

    if names_info['addresses'][0]['names_owned'] != ['foo.test']:
        print "invalid names info (names_owned): %s" % names_info
        return False

    if names_info['addresses'][0]['address'] != wallets[3].addr:
        print "invalid names info (addresses.address): %s" % names_info
        return False

    # immutable data 
    immutable_data = testlib.blockstack_cli_get_immutable( "foo.test", "hello_world" )
    if 'error' in immutable_data:
        print "Failed to get immutable data 'hello_world'"
        print json.dumps(immutable_data, indent=4, sort_keys=True)
        return False

    if 'data' not in immutable_data:
        print "invalid immutable_data: %s" % immutable_data
        return False 

    if json.loads(immutable_data['data']) != {'hello': 'world'}:
        print "failed to get immutable data"
        print 'exected %s, got %s' % ({'hello': 'world'}, immutable_data['data'])
        return False

    return True
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)
Ejemplo n.º 19
0
def check( state_engine ):

    global zonefile_hash, new_expire_block

    # not revealed, but ready
    ns = state_engine.get_namespace_reveal( "test" )
    if ns is not None:
        print "namespace reveal exists"
        return False

    ns = state_engine.get_namespace( "test" )
    if ns is None:
        print "no namespace"
        return False

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False

    # registered
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False

    # owned by
    owner_address = wallets[3].addr
    if name_rec['address'] != owner_address or name_rec['sender'] != virtualchain.make_payment_script(owner_address):
        print "sender is wrong"
        return False

    # value hash
    if name_rec['value_hash'] != zonefile_hash:
        print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'], zonefile_hash)
        return False

    # replicated?
    zonefile = testlib.blockstack_get_zonefile( zonefile_hash )
    if 'error' in zonefile:
        print "zonefile error: %s" % zonefile['error']
        return False

    # right hash?
    if blockstack_client.hash_zonefile( zonefile ) != zonefile_hash:
        print "wrong zonefile: %s != %s" % (blockstack_client.hash_zonefile(zonefile), zonefile_hash)
        return False

    # all queues are drained
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True)
        return False

    # final balance is correct?
    name_fee = blockstack_server.price_name( "foo", ns, new_expire_block )
    preorder_dust_fees = 3 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    register_dust_fees = 4 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    renewal_dust_fees = 3 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE

    total_fee = name_fee * 2 + preorder_dust_fees + register_dust_fees + renewal_dust_fees
    payment_address = wallets[2].addr

    # TODO: check
    return True
def scenario(wallets, **kw):

    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)
Ejemplo n.º 21
0
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 ):
    
    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)
Ejemplo n.º 23
0
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 check( state_engine ):

    global zonefile_hash, error

    if error:
        print "exiting with error"
        return False

    # not revealed, but ready 
    ns = state_engine.get_namespace_reveal( "test" )
    if ns is not None:
        print "namespace reveal exists"
        return False 

    ns = state_engine.get_namespace( "test" )
    if ns is None:
        print "no namespace"
        return False 

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False 
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

    # owned by
    owner_address = wallets[3].addr
    if name_rec['address'] != owner_address or name_rec['sender'] != virtualchain.make_payment_script(owner_address):
        print "sender is wrong"
        return False 

    # value hash 
    if name_rec['value_hash'] != zonefile_hash:
        print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'], zonefile_hash)
        return False

    # replicated?
    zonefile = testlib.blockstack_get_zonefile( zonefile_hash )
    if 'error' in zonefile:
        print "zonefile error: %s" % zonefile['error']
        return False

    # right hash?
    if blockstack_client.hash_zonefile( zonefile ) != zonefile_hash:
        print "wrong zonefile: %s != %s" % (blockstack_client.hash_zonefile(zonefile), zonefile_hash)
        return False

    # all queues are drained 
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(queue_info, indent=4, sort_keys=True)
        return False

    # renewed?

    # final balance is correct?
    name_fee = blockstack_server.price_name( "foo", ns, new_expire_block )
    preorder_dust_fees = 3 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    register_dust_fees = 4 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE
    renewal_dust_fees = 3 * DEFAULT_DUST_FEE + DEFAULT_OP_RETURN_FEE

    total_fee = name_fee * 2 + preorder_dust_fees + register_dust_fees + renewal_dust_fees 
    payment_address = wallets[2].addr
    
    # TODO: check
    return True
def check(state_engine):

    # not revealed, but ready
    ns = state_engine.get_namespace_reveal("test")
    if ns is not None:
        print "namespace reveal exists"
        return False

    ns = state_engine.get_namespace("test")
    if ns is None:
        print "no namespace"
        return False

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False

    # registered
    name_rec = state_engine.get_name("foo.test")
    if name_rec is None:
        print "name does not exist"
        return False

    # owned by the right address
    owner_address = wallets[4].addr
    if name_rec['address'] != owner_address or name_rec[
            'sender'] != virtualchain.make_payment_script(owner_address):
        print "sender is wrong"
        return False

    # all queues are drained
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(
            queue_info, indent=4, sort_keys=True)
        return False

    # have an update hash
    if 'value_hash' not in name_rec or name_rec.get('value_hash',
                                                    None) is None:
        print "No value hash"
        return False

    # have a zonefile
    zonefile = testlib.blockstack_get_zonefile(name_rec['value_hash'])
    if zonefile is None or 'error' in zonefile:
        if zonefile is not None:
            print "zonefile lookup error: %s" % zonefile['error']
        else:
            print "no zonefile returned"
        return False

    # hashes to this zonefile
    if blockstack_client.hash_zonefile(zonefile) != name_rec['value_hash']:
        print "wrong zonefile: %s != %s" % (
            blockstack_client.hash_zonefile(zonefile), name_rec['value_hash'])
        return False

    # zonefile has the right data public key
    zonefile_pubk = blockstack_client.user.user_zonefile_data_pubkey(zonefile)
    if keylib.key_formatting.compress(
            zonefile_pubk) != keylib.key_formatting.compress(
                wallets[4].pubkey_hex) or zonefile_pubk is None:
        print 'pubkey mismatch: {} != {}'.format(zonefile_pubk,
                                                 wallets[4].pubkey_hex)
        return False

    # zonefile has the right drivers
    zonefile_urls = blockstack_client.user.user_zonefile_urls(zonefile)
    driver_urls = blockstack_client.storage.make_mutable_data_urls(
        'foo.test', use_only=['dht', 'disk'])
    if driver_urls != zonefile_urls:
        print 'url mismatch: {} != {}'.format(driver_urls, zonefile_urls)
        return False

    # verify that the profile is NOT there
    profile = testlib.blockstack_get_profile("foo.test")
    if profile is not None and 'error' not in profile:
        print 'make a profile by mistake: {}'.format(profile)
        return False

    return True
Ejemplo n.º 26
0
def check(state_engine):

    global zonefile_hash

    # not revealed, but ready
    ns = state_engine.get_namespace_reveal("test")
    if ns is not None:
        print "namespace reveal exists"
        return False

    ns = state_engine.get_namespace("test")
    if ns is None:
        print "no namespace"
        return False

    if ns['namespace_id'] != 'test':
        print "wrong namespace"
        return False

    # registered
    name_rec = state_engine.get_name("foo.test")
    if name_rec is None:
        print "name does not exist"
        return False

    # owned by
    owner_address = wallets[4].addr
    if name_rec['address'] != owner_address or name_rec[
            'sender'] != virtualchain.make_payment_script(owner_address):
        print "sender is wrong"
        return False

    # value hash
    if name_rec['value_hash'] != zonefile_hash:
        print "wrong zonefile hash: %s != %s" % (name_rec['value_hash'],
                                                 zonefile_hash)
        return False

    # replicated?
    zonefile = testlib.blockstack_get_zonefile(zonefile_hash)
    if 'error' in zonefile:
        print "zonefile error: %s" % zonefile['error']
        return False

    # right hash?
    if blockstack_client.hash_zonefile(zonefile) != zonefile_hash:
        print "wrong zonefile: %s != %s" % (
            blockstack_client.hash_zonefile(zonefile), zonefile_hash)
        return False

    # latest key?
    if not zonefile.has_key("txt"):
        print "no txt:\n%s" % json.dumps(zonefile, indent=4, sort_keys=True)
        return False

    if len(zonefile['txt']) != 2:
        print "wrong number of txt records:\n%s" % json.dumps(
            zonefile, indent=4, sort_keys=True)
        return False

    for txtrec in zonefile['txt']:
        if txtrec['name'] == 'pubkey':
            if new_data_pubkey not in txtrec['txt']:
                print "wrong pubkey:\n%s" % json.dumps(
                    zonefile, indent=4, sort_keys=True)
                print "missing %s" % new_data_pubkey
                return False

    names_owned = testlib.blockstack_cli_names()
    if 'error' in names_owned:
        print "rpc names: %s" % names_owned['error']
        return False

    # we still own the name
    if len(names_owned['names_owned']) != 1:
        print "owned: %s" % names_owned['names_owned']
        return False

    # all queues are drained
    queue_info = testlib.blockstack_client_queue_state()
    if len(queue_info) > 0:
        print "Still in queue:\n%s" % json.dumps(
            queue_info, indent=4, sort_keys=True)
        return False

    return True
Ejemplo n.º 27
0
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)