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
    def _query_subdomains(subdomain_names, expected_sequence, expected_owner,
                          expect_pending):
        # query each subdomain.  Should get the latest
        proxy = testlib.make_proxy()
        for fqn in subdomain_names:
            res = client.get_name_record(fqn, proxy=proxy)
            if 'error' in res:
                print res
                print 'failed to query {}'.format(fqn)
                return False

            # should have right sequence
            if res['sequence'] != expected_sequence:
                print 'wrong sequence; expected {}'.format(expected_sequence)
                print res
                return False

            # should have right owner
            if res['address'] != expected_owner:
                print 'wrong owner'
                print 'expected {}'.format(res['address'])
                print res
                return False

            # do we expect pending?
            if res['pending'] != expect_pending:
                print 'wrong pending (expected {})'.format(expect_pending)
                print res
                return False

        return True
Example #3
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
Example #4
0
def get_name_record(name,
                    include_history=False,
                    include_expired=True,
                    include_grace=True,
                    proxy=None):
    """
    rpc_get_name_blockchain_record or rpc_get_name_record, depending on include_history
    Return the blockchain-extracted information on success.
    Return {'error': ...} on error
        In particular, return {'error': 'Not found.'} if the name isn't registered

    If include_expired is True, then a name record will be returned even if it expired
    If include_expired is False, but include_grace is True, then the name record will be returned even if it is expired and in the grace period
    """

    proxy = get_default_proxy() if proxy is None else proxy
    return blockstackd_client.get_name_record(name,
                                              include_history=include_history,
                                              include_expired=include_expired,
                                              include_grace=include_grace,
                                              proxy=proxy)
    def _query_subdomains(subdomain_names, expected_sequence, expected_owner):
        # query each subdomain.  Should get the latest
        for fqn in subdomain_names:
            res = client.get_name_record(fqn,
                                         hostport='http://localhost:16264')
            if 'error' in res:
                print res
                print 'failed to query {}'.format(fqn)
                return False

            # should have right sequence
            if res['sequence'] != expected_sequence:
                print 'wrong sequence; expected {}'.format(expected_sequence)
                print res
                return False

            # should have right owner
            if res['address'] != expected_owner:
                print 'wrong owner'
                print 'expected {}'.format(res['address'])
                print res
                return False

        return True
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)
Example #7
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 scenario(wallets, **kw):

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo1.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo3.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
    zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"'

    zonefiles = {
        'foo1.test':
        zf_template.format(
            'foo1.test',
            subdomains.make_subdomain_txt(
                'bar.foo1.test', 'foo1.test', wallets[4].addr, 0,
                zf_template.format('bar.foo1.test', zf_default_url),
                wallets[4].privkey)),
        'foo2.test':
        zf_template.format(
            'foo2.test',
            subdomains.make_subdomain_txt(
                'bar.foo2.test', 'foo2.test', wallets[4].addr, 0,
                zf_template.format('bar.foo2.test', zf_default_url),
                wallets[4].privkey)),
        'foo3.test':
        zf_template.format(
            'foo3.test',
            subdomains.make_subdomain_txt(
                'bar.foo3.test', 'foo3.test', wallets[4].addr, 0,
                zf_template.format('bar.foo3.test', zf_default_url),
                wallets[4].privkey)),
    }

    testlib.blockstack_name_register(
        "foo1.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test']))
    testlib.blockstack_name_register(
        "foo2.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test']))
    testlib.blockstack_name_register(
        "foo3.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test']))
    testlib.next_block(**kw)

    def _query_subdomains(subdomain_names, expected_sequence, expected_owner):
        # query each subdomain.  Should get the latest
        proxy = testlib.make_proxy()
        for fqn in subdomain_names:
            res = client.get_name_record(fqn, proxy=proxy)
            if 'error' in res:
                print res
                print 'failed to query {}'.format(fqn)
                return False

            # should have right sequence
            if res['sequence'] != expected_sequence:
                print 'wrong sequence; expected {}'.format(expected_sequence)
                print res
                return False

            # should have right owner
            if res['address'] != expected_owner:
                print 'wrong owner'
                print 'expected {}'.format(res['address'])
                print res
                return False

        return True

    assert testlib.blockstack_put_zonefile(zonefiles['foo1.test'])
    assert testlib.blockstack_put_zonefile(zonefiles['foo2.test'])
    assert testlib.blockstack_put_zonefile(zonefiles['foo3.test'])

    # kick off indexing and check
    testlib.next_block(**kw)
    assert _query_subdomains(
        ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'], 0,
        wallets[4].addr)

    expected_owners = [wallets[4].addr]

    # send updates too, and transfer subdomains
    for i in range(0, 6):
        zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
        zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(
            i + 1)

        j = (4 + i) % 5
        k = (4 + i + 1) % 5
        expected_owners.append(wallets[k].addr)

        zonefiles = {
            'foo1.test':
            zf_template.format(
                'foo1.test',
                subdomains.make_subdomain_txt(
                    'bar.foo1.test', 'foo1.test', wallets[k].addr, i + 1,
                    zf_template.format('bar.foo1.test', zf_default_url),
                    wallets[j].privkey)),
            'foo2.test':
            zf_template.format(
                'foo2.test',
                subdomains.make_subdomain_txt(
                    'bar.foo2.test', 'foo2.test', wallets[k].addr, i + 1,
                    zf_template.format('bar.foo2.test', zf_default_url),
                    wallets[j].privkey)),
            'foo3.test':
            zf_template.format(
                'foo3.test',
                subdomains.make_subdomain_txt(
                    'bar.foo3.test', 'foo3.test', wallets[k].addr, i + 1,
                    zf_template.format('bar.foo3.test', zf_default_url),
                    wallets[j].privkey)),
        }

        testlib.blockstack_name_update(
            'foo1.test',
            storage.get_zonefile_data_hash(zonefiles['foo1.test']),
            wallets[3].privkey)
        testlib.blockstack_name_update(
            'foo2.test',
            storage.get_zonefile_data_hash(zonefiles['foo2.test']),
            wallets[3].privkey)
        testlib.blockstack_name_update(
            'foo3.test',
            storage.get_zonefile_data_hash(zonefiles['foo3.test']),
            wallets[3].privkey)
        testlib.next_block(**kw)

        assert testlib.blockstack_put_zonefile(zonefiles['foo1.test'])
        assert testlib.blockstack_put_zonefile(zonefiles['foo2.test'])
        assert testlib.blockstack_put_zonefile(zonefiles['foo3.test'])

        # kick off subdomain indexing
        testlib.next_block(**kw)

        # verify history
        assert _query_subdomains(
            ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'], i + 1,
            wallets[k].addr)

    # query subdomain history
    proxy = testlib.make_proxy()
    for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']:
        res = client.get_name_record(subd, include_history=True, proxy=proxy)
        if 'error' in res:
            print res
            return False

        for i, block_height in enumerate(sorted(res['history'])):
            if res['history'][block_height][0]['address'] != expected_owners[i]:
                print 'wrong owner at {}: expected {}'.format(
                    block_height, expected_owners[i])
                print json.dumps(res, indent=4, sort_keys=True)
                return False

            if res['history'][block_height][0]['sequence'] != i:
                print 'wrong sequence at {}: expected {}'.format(
                    block_height, i)
                print json.dumps(res, indent=4, sort_keys=True)
                return False

    # reindex
    assert testlib.check_subdomain_db(**kw)
def scenario( wallets, **kw ):
    
    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)
Example #10
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 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)
Example #12
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)
Example #13
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)
def scenario( wallets, **kw ):
    
    # disable subdomains at first
    subdomaindb_path = None
    blockstack_opts = blockstack.lib.config.get_blockstack_opts()

    assert 'subdomaindb_path' in blockstack_opts
    subdomaindb_path = blockstack_opts['subdomaindb_path']
    del blockstack_opts['subdomaindb_path']

    blockstack.lib.config.set_blockstack_opts(blockstack_opts)

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstack_name_preorder( "foo1.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_preorder( "foo2.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_preorder( "foo3.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_preorder( "foo4.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_preorder( "foo5.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_preorder( "foo6.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_preorder( "foo7.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
    zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"'

    zonefiles = {
        'foo1.test': zf_template.format('foo1.test', subdomains.make_subdomain_txt('bar.foo1.test', 'foo1.test', wallets[4].addr, 0, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)),
        'foo2.test': zf_template.format('foo2.test', subdomains.make_subdomain_txt('bar.foo2.test', 'foo2.test', wallets[4].addr, 0, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)),
        'foo3.test': zf_template.format('foo3.test', subdomains.make_subdomain_txt('bar.foo3.test', 'foo3.test', wallets[4].addr, 0, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)),
    }
    
    # register initial subdomains
    testlib.blockstack_name_register( "foo1.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test']))
    testlib.blockstack_name_register( "foo2.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test']))
    testlib.blockstack_name_register( "foo3.test", wallets[2].privkey, wallets[3].addr, zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test']))
    testlib.blockstack_name_register( "foo4.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20)
    testlib.blockstack_name_register( "foo5.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20)
    testlib.blockstack_name_register( "foo6.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20)
    testlib.blockstack_name_register( "foo7.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20)
    testlib.next_block( **kw )
    
    assert testlib.blockstack_put_zonefile(zonefiles['foo1.test'])
    assert testlib.blockstack_put_zonefile(zonefiles['foo2.test'])
    assert testlib.blockstack_put_zonefile(zonefiles['foo3.test'])

    # send updates, but only on foo1.test.
    for i in range(0, 3):
        zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
        zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(i+1)
        name = 'foo{}.test'.format(i+4)

        zonefiles = {
            'foo1.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo1.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo1.test', zf_default_url), wallets[4].privkey)),
            'foo2.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo2.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo2.test', zf_default_url), wallets[4].privkey)),
            'foo3.test': zf_template.format(name, subdomains.make_subdomain_txt('bar.foo3.test', name, wallets[4].addr, i+1, zf_template.format('bar.foo3.test', zf_default_url), wallets[4].privkey)),
        }

        testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo1.test']), wallets[3].privkey)
        testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo2.test']), wallets[3].privkey)
        testlib.blockstack_name_update(name, storage.get_zonefile_data_hash(zonefiles['foo3.test']), wallets[3].privkey)
        testlib.next_block(**kw)

        assert testlib.blockstack_put_zonefile(zonefiles['foo1.test'])
        assert testlib.blockstack_put_zonefile(zonefiles['foo2.test'])
        assert testlib.blockstack_put_zonefile(zonefiles['foo3.test'])
    
    # subdomains should not exist---we haven't indexed them yet
    for i in xrange(1, 4):
        fqn = 'bar.foo{}.test'.format(i)
        res = client.get_name_record(fqn, hostport='http://localhost:16264')
        if 'error' not in res:
            print 'got a subdomain'
            print res
            return False
       
    # wait until they exist
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)

    blockstack_opts['subdomaindb_path'] = subdomaindb_path
    blockstack.lib.config.set_blockstack_opts(blockstack_opts)
    
    testlib.next_block(**kw)

    # query each subdomain
    for i in xrange(1, 4):
        fqn = 'bar.foo{}.test'.format(i)
        res = client.get_name_record(fqn, hostport='http://localhost:16264')
        if 'error' in res:
            print res
            return False
        
        # domain should be foo6.test
        if res['domain'] != 'foo6.test':
            print 'wrong domain'
            print res
            return False

        expected_zonefile = zf_template.format(fqn, zf_default_url)
        if base64.b64decode(res['zonefile']) != expected_zonefile:
            print 'zonefile mismatch'
            print 'expected\n{}'.format(expected_zonefile)
            print 'got\n{}'.format(base64.b64decode(res['zonefile']))
            return False

        # should be in atlas as well
        zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False)
        if not zf:
            print 'no zone file {} in atlas'.format(res['value_hash'])
            return False

        if zf != expected_zonefile:
            print 'zonefile mismatch in atlas'
            print 'expected\n{}'.format(expected_zonefile)
            print 'got\n{}'.format(base64.b64decode(res['zonefile']))
            return False

    # reindex
    assert testlib.check_subdomain_db(firstblock=256, **kw)
def scenario(wallets, **kw):

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo1.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo3.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo4.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo5.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo6.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo7.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
    zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"'

    zonefiles = {
        'foo1.test':
        zf_template.format(
            'foo1.test',
            subdomains.make_subdomain_txt(
                'bar.foo1.test', 'foo1.test', wallets[4].addr, 0,
                zf_template.format('bar.foo1.test', zf_default_url),
                wallets[4].privkey)),
        'foo2.test':
        zf_template.format(
            'foo2.test',
            subdomains.make_subdomain_txt(
                'bar.foo2.test', 'foo2.test', wallets[4].addr, 0,
                zf_template.format('bar.foo2.test', zf_default_url),
                wallets[4].privkey)),
        'foo3.test':
        zf_template.format(
            'foo3.test',
            subdomains.make_subdomain_txt(
                'bar.foo3.test', 'foo3.test', wallets[4].addr, 0,
                zf_template.format('bar.foo3.test', zf_default_url),
                wallets[4].privkey)),
    }

    testlib.blockstack_name_register(
        "foo1.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test']))
    testlib.blockstack_name_register(
        "foo2.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test']))
    testlib.blockstack_name_register(
        "foo3.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test']))
    testlib.blockstack_name_register("foo4.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_register("foo5.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_register("foo6.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_register("foo7.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    assert testlib.blockstack_put_zonefile(zonefiles['foo1.test'])
    assert testlib.blockstack_put_zonefile(zonefiles['foo2.test'])
    assert testlib.blockstack_put_zonefile(zonefiles['foo3.test'])

    # kick off indexing and check
    testlib.next_block(**kw)

    def _query_subdomains(subdomain_names, expected_sequence, expected_owner,
                          expect_pending):
        # query each subdomain.  Should get the latest
        proxy = testlib.make_proxy()
        for fqn in subdomain_names:
            res = client.get_name_record(fqn, proxy=proxy)
            if 'error' in res:
                print res
                print 'failed to query {}'.format(fqn)
                return False

            # should have right sequence
            if res['sequence'] != expected_sequence:
                print 'wrong sequence; expected {}'.format(expected_sequence)
                print res
                return False

            # should have right owner
            if res['address'] != expected_owner:
                print 'wrong owner'
                print 'expected {}'.format(res['address'])
                print res
                return False

            # do we expect pending?
            if res['pending'] != expect_pending:
                print 'wrong pending (expected {})'.format(expect_pending)
                print res
                return False

        return True

    assert _query_subdomains(
        ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'], 0,
        wallets[4].addr, False)

    expected_owners_before = [wallets[4].addr]
    expected_owners_after = [wallets[4].addr]

    # update and transfer, but if i % 2 == 0, transfer to a different address
    # use a different domain name in each case.
    # verify that only transfers on the creator domain are valid.
    wallet_schedule = [
        (4, 0),  # not broadcast initially 
        (4, 1),
        (0, 1),  # not broadcast initially
        (1, 2),
    ]
    sequence_schedule = [
        1,
        1,
        2,
        2,
    ]

    expected_zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(
        4)
    expect_pending = False
    expect_sequence = 0
    expect_owner = wallets[4].addr

    unsent_zonefiles = []

    # send updates too, and transfer subdomains
    for i in range(0, 4):
        zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
        zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(
            i + 1)

        names = [
            'foo1.test',
            'foo2.test',
            'foo3.test',
        ]

        k = wallet_schedule[i][0]
        k2 = wallet_schedule[i][1]
        s = sequence_schedule[i]

        zonefiles = {
            'foo1.test':
            zf_template.format(
                names[0],
                subdomains.make_subdomain_txt(
                    'bar.foo1.test', names[0], wallets[k2].addr, s,
                    zf_template.format('bar.foo1.test', zf_default_url),
                    wallets[k].privkey)),
            'foo2.test':
            zf_template.format(
                names[1],
                subdomains.make_subdomain_txt(
                    'bar.foo2.test', names[1], wallets[k2].addr, s,
                    zf_template.format('bar.foo2.test', zf_default_url),
                    wallets[k].privkey)),
            'foo3.test':
            zf_template.format(
                names[2],
                subdomains.make_subdomain_txt(
                    'bar.foo3.test', names[2], wallets[k2].addr, s,
                    zf_template.format('bar.foo3.test', zf_default_url),
                    wallets[k].privkey)),
        }

        testlib.blockstack_name_update(
            names[0], storage.get_zonefile_data_hash(zonefiles['foo1.test']),
            wallets[3].privkey)
        testlib.blockstack_name_update(
            names[1], storage.get_zonefile_data_hash(zonefiles['foo2.test']),
            wallets[3].privkey)
        testlib.blockstack_name_update(
            names[2], storage.get_zonefile_data_hash(zonefiles['foo3.test']),
            wallets[3].privkey)
        testlib.next_block(**kw)

        if i % 2 == 1:
            # only broadcast periodically
            assert testlib.blockstack_put_zonefile(zonefiles['foo1.test'])
            assert testlib.blockstack_put_zonefile(zonefiles['foo2.test'])
            assert testlib.blockstack_put_zonefile(zonefiles['foo3.test'])
            expect_owner = wallets[k2].addr
            expect_sequence += 1
            expected_owners_before.append(expect_owner)

        else:
            expect_pending = True
            unsent_zonefiles.append(zonefiles)
            expected_owners_after.append(wallets[k2].addr)

        # kick off subdomain indexing
        testlib.next_block(**kw)

        # verify history
        assert _query_subdomains(
            ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test'],
            expect_sequence, expect_owner, expect_pending)

    # query subdomain history
    proxy = testlib.make_proxy()
    for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']:
        res = client.get_name_record(subd, include_history=True, proxy=proxy)
        if 'error' in res:
            print res
            return False

        if not res['pending']:
            print 'not pending, but it should be'
            print res
            return False

        # should be at 2
        if res['sequence'] != 2:
            print 'wrong sequence'
            print res
            return False

        if virtualchain.address_reencode(str(
                res['address'])) != virtualchain.address_reencode(
                    expect_owner):
            print 'wrong owner'
            print res
            return False

        for i, block_height in enumerate(sorted(res['history'])):
            if virtualchain.address_reencode(
                    str(res['history'][block_height][0]['address'])
            ) != virtualchain.address_reencode(expected_owners_before[i]):
                print 'wrong owner at {}: expected {}'.format(
                    block_height, expected_owners_before[i])
                print json.dumps(res, indent=4, sort_keys=True)
                print expected_owners_before
                return False

            if res['history'][block_height][0]['sequence'] != i:
                print 'wrong sequence at {}: expected {}'.format(
                    block_height, i)
                print json.dumps(res, indent=4, sort_keys=True)
                return False

    # send all missing subdomains.
    # should cause a cascading owner reorg.
    for zfbatch in unsent_zonefiles:
        for k in zfbatch:
            assert testlib.blockstack_put_zonefile(zfbatch[k])

    testlib.next_block(**kw)

    # query subdomain history again.  pending and owner should change
    proxy = testlib.make_proxy()
    for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']:
        res = client.get_name_record(subd, include_history=True, proxy=proxy)
        if 'error' in res:
            print res
            return False

        if res['pending']:
            print 'pending, but it should not be'
            print res
            return False

        if res['sequence'] != 2:
            print 'wrong sequence'
            print res
            return False

        if virtualchain.address_reencode(str(
                res['address'])) != virtualchain.address_reencode(
                    wallets[1].addr):
            print 'wrong owner again'
            print res
            return False

        for i, block_height in enumerate(sorted(res['history'])):
            if virtualchain.address_reencode(
                    str(res['history'][block_height][0]['address'])
            ) != virtualchain.address_reencode(str(expected_owners_after[i])):
                print 'wrong owner at {}: expected {}'.format(
                    block_height, expected_owners_after[i])
                print json.dumps(res, indent=4, sort_keys=True)
                print expected_owners_after
                print expected_owners_before
                print[wallets[i].addr for i in range(0, len(wallets))]
                return False

            if res['history'][block_height][0]['sequence'] != i:
                print 'wrong sequence at {}: expected {}'.format(
                    block_height, i)
                print json.dumps(res, indent=4, sort_keys=True)
                return False

    # reindex
    assert testlib.check_subdomain_db(**kw)
def scenario(wallets, **kw):

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo1.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo3.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo4.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo5.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo6.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo7.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
    zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"'

    zonefiles = {
        'foo1.test':
        zf_template.format(
            'foo1.test',
            subdomains.make_subdomain_txt(
                'bar.foo1.test', 'foo1.test', wallets[4].addr, 0,
                zf_template.format('bar.foo1.test', zf_default_url),
                wallets[4].privkey)),
        'foo2.test':
        zf_template.format(
            'foo2.test',
            subdomains.make_subdomain_txt(
                'bar.foo2.test', 'foo2.test', wallets[4].addr, 0,
                zf_template.format('bar.foo2.test', zf_default_url),
                wallets[4].privkey)),
        'foo3.test':
        zf_template.format(
            'foo3.test',
            subdomains.make_subdomain_txt(
                'bar.foo3.test', 'foo3.test', wallets[4].addr, 0,
                zf_template.format('bar.foo3.test', zf_default_url),
                wallets[4].privkey)),
    }

    # send initial subdomains
    testlib.blockstack_name_register(
        "foo1.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo1.test']))
    testlib.blockstack_name_register(
        "foo2.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo2.test']))
    testlib.blockstack_name_register(
        "foo3.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=storage.get_zonefile_data_hash(zonefiles['foo3.test']))
    testlib.blockstack_name_register("foo4.test",
                                     wallets[2].privkey,
                                     wallets[3].addr,
                                     zonefile_hash='11' * 20)
    testlib.blockstack_name_register("foo5.test",
                                     wallets[2].privkey,
                                     wallets[3].addr,
                                     zonefile_hash='11' * 20)
    testlib.blockstack_name_register("foo6.test",
                                     wallets[2].privkey,
                                     wallets[3].addr,
                                     zonefile_hash='11' * 20)
    testlib.blockstack_name_register("foo7.test",
                                     wallets[2].privkey,
                                     wallets[3].addr,
                                     zonefile_hash='11' * 20)
    testlib.next_block(**kw)

    # will send these later
    initial_zonefiles = zonefiles

    # send updates too, but all on the same name
    for i in range(0, 3):
        zf_template = "$ORIGIN {}\n$TTL 3600\n{}"
        zf_default_url = '_https._tcp URI 10 1 "https://test.com/?index={}"'.format(
            i + 1)
        name = 'foo{}.test'.format(i + 4)

        zonefiles = {
            'foo1.test':
            zf_template.format(
                name,
                subdomains.make_subdomain_txt(
                    'bar.foo1.test', name, wallets[4].addr, i + 1,
                    zf_template.format('bar.foo1.test', zf_default_url),
                    wallets[4].privkey)),
            'foo2.test':
            zf_template.format(
                name,
                subdomains.make_subdomain_txt(
                    'bar.foo2.test', name, wallets[4].addr, i + 1,
                    zf_template.format('bar.foo2.test', zf_default_url),
                    wallets[4].privkey)),
            'foo3.test':
            zf_template.format(
                name,
                subdomains.make_subdomain_txt(
                    'bar.foo3.test', name, wallets[4].addr, i + 1,
                    zf_template.format('bar.foo3.test', zf_default_url),
                    wallets[4].privkey)),
        }

        testlib.blockstack_name_update(
            name, storage.get_zonefile_data_hash(zonefiles['foo1.test']),
            wallets[3].privkey)
        testlib.blockstack_name_update(
            name, storage.get_zonefile_data_hash(zonefiles['foo2.test']),
            wallets[3].privkey)
        testlib.blockstack_name_update(
            name, storage.get_zonefile_data_hash(zonefiles['foo3.test']),
            wallets[3].privkey)
        testlib.next_block(**kw)

        assert testlib.blockstack_put_zonefile(zonefiles['foo1.test'])
        assert testlib.blockstack_put_zonefile(zonefiles['foo2.test'])
        assert testlib.blockstack_put_zonefile(zonefiles['foo3.test'])

    # kick off subdomain indexing (nothing should happen)
    testlib.next_block(**kw)

    # send initial zonefiles
    assert testlib.blockstack_put_zonefile(initial_zonefiles['foo1.test'])
    assert testlib.blockstack_put_zonefile(initial_zonefiles['foo2.test'])
    assert testlib.blockstack_put_zonefile(initial_zonefiles['foo3.test'])

    # now kick it off again
    testlib.next_block(**kw)

    # query each subdomain
    proxy = testlib.make_proxy()
    for i in xrange(1, 4):
        fqn = 'bar.foo{}.test'.format(i)
        res = client.get_name_record(fqn, proxy=proxy)
        if 'error' in res:
            print res
            return False

        expected_zonefile = zf_template.format(fqn, zf_default_url)
        if base64.b64decode(res['zonefile']) != expected_zonefile:
            print 'zonefile mismatch'
            print 'expected\n{}'.format(expected_zonefile)
            print 'got\n{}'.format(base64.b64decode(res['zonefile']))
            return False

        # should be in atlas as well
        zf = testlib.blockstack_get_zonefile(res['value_hash'], parse=False)
        if not zf:
            print 'no zone file {} in atlas'.format(res['value_hash'])
            return False

        if zf != expected_zonefile:
            print 'zonefile mismatch in atlas'
            print 'expected\n{}'.format(expected_zonefile)
            print 'got\n{}'.format(base64.b64decode(res['zonefile']))
            return False

    # reindex
    assert testlib.check_subdomain_db(**kw)
def scenario(wallets, **kw):

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    testlib.blockstack_name_preorder("foo1.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo3.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    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)
Example #18
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)
Example #19
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)