Пример #1
0
def check(state_engine):

    global wallet_keys, datasets, zonefile_hash

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

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

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

    # not preordered
    preorder = state_engine.get_name_preorder(
        "foo.test", pybitcoin.make_pay_to_address_script(wallets[2].addr),
        wallets[3].addr)
    if preorder is not None:
        print "still have preorder"
        return False

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

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

    # have right hash
    if name_rec['value_hash'] != zonefile_hash:
        print "Invalid zonefile hash"
        return False

    # have right data
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)
    res = testlib.blockstack_cli_lookup("foo.test")
    if 'error' in res:
        print 'error looking up profile: {}'.format(res)
        return False

    assert 'profile' in res
    assert 'zonefile' in res

    return True
def check( state_engine ):

    global wallet_keys, datasets, zonefile_hash

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

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

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

    # not preordered
    preorder = state_engine.get_name_preorder( "foo.test", pybitcoin.make_pay_to_address_script(wallets[2].addr), wallets[3].addr )
    if preorder is not None:
        print "still have preorder"
        return False
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

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

    # have right hash 
    if name_rec['value_hash'] != zonefile_hash:
        print "Invalid zonefile hash"
        return False 

    # have right data 
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    res = testlib.blockstack_cli_lookup("foo.test")
    if 'error' in res:
        print 'error looking up profile: {}'.format(res)
        return False

    assert 'profile' in res
    assert 'zonefile' in res

    return True
Пример #3
0
def check(state_engine):

    global wallet_keys, datasets, zonefile_hash

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

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

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

    # not preordered
    preorder = state_engine.get_name_preorder(
        "foo.test", pybitcoin.make_pay_to_address_script(wallets[2].addr),
        wallets[3].addr)
    if preorder is not None:
        print "still have preorder"
        return False

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

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

    # have right hash
    if name_rec['value_hash'] != zonefile_hash:
        print "Invalid zonefile hash"
        return False

    # have right data
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)

    for i in xrange(0, len(datasets)):
        print "get hello_world_%s" % (i + 1)
        dat = testlib.blockstack_cli_get_mutable(
            "foo.test", "hello_world_{}".format(i + 1))
        if dat is None:
            print "No data '%s'" % ("hello_world_%s" % (i + 1))
            return False

        if 'error' in dat:
            print json.dumps(dat, indent=4, sort_keys=True)
            return False

        if json.loads(dat['data']) != datasets[i]:
            print "Mismatch %s: %s != %s" % (i, dat, datasets[i])
            return False

    res = testlib.blockstack_cli_lookup("foo.test")
    if 'error' in res:
        print 'error looking up profile: {}'.format(res)
        return False

    assert 'profile' in res
    assert 'zonefile' in res

    return True
def check( state_engine ):

    global wallet_keys, datasets, zonefile_hash

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

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

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

    # not preordered
    preorder = state_engine.get_name_preorder( "foo.test", pybitcoin.make_pay_to_address_script(wallets[2].addr), wallets[3].addr )
    if preorder is not None:
        print "still have preorder"
        return False
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

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

    # have right hash 
    if name_rec['value_hash'] != zonefile_hash:
        print "Invalid zonefile hash"
        return False 

    # zonefile is NOT legacy 
    user_zonefile = blockstack_client.zonefile.load_name_zonefile( 'foo.test', zonefile_hash )
    if 'error' in user_zonefile:
        print json.dumps(user_zonefile, indent=4, sort_keys=True)
        return False 

    if blockstack_profiles.is_profile_in_legacy_format( user_zonefile ):
        print "legacy still"
        print json.dumps(user_zonefile, indent=4, sort_keys=True)
        return False

    # zonefile has no key 
    zonefile_key = blockstack_client.user.user_zonefile_data_pubkey(user_zonefile)
    if zonefile_key is not None:
        print 'still have zonefile key'
        print json.dumps(user_zonefile, indent=4, sort_keys=True)
        return False

    # have right data 
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )

    for i in xrange(0, len(datasets)):
        print "get hello_world_%s" % (i+1)
        dat = testlib.blockstack_cli_get_mutable( "foo.test", "hello_world_{}".format(i+1), public_key=wallets[4].pubkey_hex )
        if dat is None:
            print "No data '%s'" % ("hello_world_%s" % (i+1))
            return False

        if 'error' in dat:
            print json.dumps(dat, indent=4, sort_keys=True)
            return False

        if json.loads(dat['data']) != datasets[i]:
            print "Mismatch %s: %s != %s" % (i, dat, datasets[i])
            return False
    
    res = testlib.blockstack_cli_lookup("foo.test")
    if 'error' in res:
        print 'error looking up profile: {}'.format(res)
        return False

    assert 'profile' in res
    assert 'zonefile' in res

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

    global first_name_block

    # make a test namespace
    resp = testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                                 wallets[0].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

    testlib.next_block(**kw)  # end of 689

    resp = testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 2, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

    testlib.next_block(**kw)  # 690

    # make a zonefile and a profile
    resp = testlib.blockstack_import_user('foo.test', wallets[1].privkey,
                                          wallets[3].privkey, **kw)  # 691

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    first_name_block = testlib.get_current_block(**kw)

    resp = testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # end of 692

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print 'failed to whois foo.test'
        print json.dumps(whois, indent=4)
        return False

    # this should be the second-to-last block
    if whois['expire_block'] != testlib.get_current_block(**kw) + 2:
        print 'wrong expire block (expect 2 more)'
        print whois
        return False

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # end of 693; begin epoch 2
    # begin epoch 2

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # 694

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print 'failed to whois foo.test'
        print json.dumps(whois, indent=4)
        return False

    # this should be the last block
    if whois['expire_block'] != testlib.get_current_block(**kw) + 2:
        print 'wrong expire block (expect 2 more)'
        print whois
        return False

    if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 2:
        print 'wrong renewal block (expect 2 more)'
        print whois
        return False

    print whois

    testlib.next_block(**kw)  # 695 (epoch 3 begins)

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # end of 696

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print whois
        return False

    # this should be the expire block
    if whois['expire_block'] != testlib.get_current_block(**kw):
        print 'wrong expire block (now at {})'.format(
            testlib.get_current_block(**kw))
        print whois
        return False

    # should now be a grace period
    if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 5:
        print 'wrong renewal block (now at {})'.format(
            testlib.get_current_block(**kw))
        print whois
        return False

    last_transaction_height = whois['last_transaction_height']

    # begin epoch 3 (grace period)
    testlib.next_block(**kw)  # end of 697

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    testlib.next_block(**kw)  # 698

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    testlib.next_block(**kw)  # 699

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    testlib.next_block(**kw)  # 700

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    testlib.blockstack_renew_user('foo.test', wallets[3].privkey,
                                  wallets[0].privkey,
                                  **kw)  # end of 701 (end of grace period)

    # try lookup (should succeed again)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # 702 (name can be registered again)
def scenario(wallets, **kw):

    wallet = testlib.blockstack_client_initialize_wallet(
        "0123456789abcdef", wallets[2].privkey, wallets[3].privkey,
        wallets[4].privkey)

    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)

    # make zonefiles:
    # one with a data key
    # one without a data key
    # one with a nonstandard zonefile
    zf1 = blockstack_client.zonefile.make_empty_zonefile(
        'foo1.test', wallets[4].pubkey_hex)
    zf1_txt = blockstack_zones.make_zone_file(zf1)

    zf2 = blockstack_client.zonefile.make_empty_zonefile('foo2.test', None)
    zf2_txt = blockstack_zones.make_zone_file(zf2)

    zf3_txt = '\x00\x01\x02\x03\x04\x05'

    testlib.blockstack_name_register(
        "foo1.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=blockstack_client.get_zonefile_data_hash(zf1_txt))
    testlib.blockstack_name_register(
        "foo2.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=blockstack_client.get_zonefile_data_hash(zf2_txt))
    testlib.blockstack_name_register(
        "foo3.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=blockstack_client.get_zonefile_data_hash(zf3_txt))
    testlib.next_block(**kw)

    # replicate zonefiles
    proxy = testlib.make_proxy()
    res = blockstack_client.proxy.put_zonefiles("localhost:{}".format(
        blockstack.RPC_SERVER_PORT), [
            base64.b64encode(zf1_txt),
            base64.b64encode(zf2_txt),
            base64.b64encode(zf3_txt)
        ],
                                                proxy=proxy)
    if 'error' in res:
        print res
        return False

    for s in res['saved']:
        if s != 1:
            print res
            return False

    print 'waiting for zonefiles to be saved...'
    time.sleep(5)

    # store signed profile for each
    working_dir = kw['working_dir']

    for name in ['foo1.test', 'foo2.test', 'foo3.test']:
        profile = blockstack_client.user.make_empty_user_profile()
        profile['name'] = name

        profile_path = os.path.join(working_dir, '{}.profile'.format(name))
        with open(profile_path, 'w') as f:
            f.write(json.dumps(profile))

        print 'sign profile for {}'.format(name)

        jwt = testlib.blockstack_cli_sign_profile(name, profile_path)
        if 'error' in jwt:
            print jwt
            return False

        jwt_path = os.path.join(working_dir, '{}.profile.jwt'.format(name))
        with open(jwt_path, 'w') as f:
            f.write(jwt)

        print 'verify profile for {}'.format(name)

        res = testlib.blockstack_cli_verify_profile(name, jwt_path)
        if 'error' in res:
            print res
            return False

        print 'store profile for {}'.format(name)

        # store the jwt to the right place
        res = blockstack_client.storage.put_mutable_data(name,
                                                         jwt,
                                                         sign=False,
                                                         profile=True,
                                                         raw=True)
        if not res:
            print res
            return False

        print 'lookup profile for {}'.format(name)

        # lookup
        res = testlib.blockstack_cli_lookup(name)
        if name != 'foo3.test':
            if 'error' in res:
                print res
                return False

            if res['profile'] != profile:
                print 'profile mismatch:'
                print res
                print profile
                return False

        else:
            if 'error' not in res:
                print res
                return False
def scenario(wallets, **kw):

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

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

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

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

    # make zonefiles:
    # one normal one
    # one with a nonstandard zonefile
    zf1_txt = testlib.make_empty_zonefile('foo1.test', wallets[3].addr)
    zf2_txt = '\x00\x01\x02\x03\x04\x05'

    testlib.blockstack_name_register(
        "foo1.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash(zf1_txt))
    testlib.blockstack_name_register(
        "foo2.test",
        wallets[2].privkey,
        wallets[3].addr,
        zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash(zf2_txt))
    testlib.next_block(**kw)

    # replicate zonefiles
    for zf in [zf1_txt, zf2_txt]:
        res = testlib.blockstack_put_zonefile(zf)
        assert res

    print 'waiting for zonefiles to be saved...'
    time.sleep(5)

    # store signed profile for each
    working_dir = kw['working_dir']

    for name in ['foo1.test', 'foo2.test']:
        profile = {'name': name, 'type': '@Person', 'account': []}
        print 'sign profile for {}'.format(name)

        profile_path = os.path.join(working_dir, '{}.profile'.format(name))
        with open(profile_path, 'w') as f:
            f.write(json.dumps(profile))

        jwt = testlib.blockstack_cli_sign_profile(profile_path,
                                                  wallets[3].privkey)
        if 'error' in jwt:
            print jwt
            return False

        jwt_path = os.path.join(working_dir, '{}.profile.jwt'.format(name))
        with open(jwt_path, 'w') as f:
            f.write(json.dumps(jwt))

        print 'verify profile for {}'.format(name)

        res = testlib.blockstack_cli_verify_profile(jwt_path, wallets[3].addr)
        if 'error' in res:
            print res
            return False

        print 'store profile for {}'.format(name)

        # store the jwt to the right place
        res = testlib.blockstack_put_profile(name, json.dumps(jwt),
                                             wallets[3].privkey,
                                             'http://localhost:4000')
        assert res

        print 'lookup profile for {}'.format(name)

        # lookup
        res = testlib.blockstack_cli_lookup(name)
        if name != 'foo2.test':
            if 'error' in res:
                print res
                return False

            if res['profile'] != profile:
                print 'profile mismatch:'
                print res['profile']
                print profile
                return False

        else:
            if 'zonefile' not in res or 'error' not in res['zonefile']:
                print res
                return False
def scenario(wallets, **kw):

    global first_name_block
    test_proxy = testlib.make_proxy()

    # make a test namespace
    resp = testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                                 wallets[0].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

    testlib.next_block(**kw)  # end of 689

    resp = testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 2, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

    testlib.next_block(**kw)  # 690

    # make a zonefile and a profile
    driver_urls = blockstack_client.storage.make_mutable_data_urls(
        'foo.test', use_only=['dht', 'disk'])
    zonefile = blockstack_client.zonefile.make_empty_zonefile(
        'foo.test', wallets[4].pubkey_hex, urls=driver_urls)
    zonefile_txt = blockstack_zones.make_zone_file(zonefile,
                                                   origin='foo.test',
                                                   ttl=4200)

    # make a new keyfile as well
    user_profile = blockstack_client.user.make_empty_user_profile()
    '''
    res = blockstack_client.key_file.make_initial_key_file(user_profile, wallets[3].privkey)
    if 'error' in res:
        print res
        return res

    keyfile_txt = res['key_file']
    '''
    zonefile_hash = blockstack_client.get_zonefile_data_hash(zonefile_txt)

    resp = testlib.blockstack_name_import("foo.test", wallets[3].addr,
                                          zonefile_hash, wallets[1].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

    testlib.next_block(**kw)  # 691

    # broadcast zonefile
    res = testlib.blockstack_cli_sync_zonefile('foo.test',
                                               zonefile_string=zonefile_txt)
    if 'error' in res:
        print res
        return False
    '''
    # upload keyfile
    res = blockstack_client.key_file.key_file_put('foo.test', keyfile_txt)
    if 'error' in res:
        print res
        return False
    '''

    rc = blockstack_client.profile.put_profile(
        'foo.test',
        user_profile,
        blockchain_id='foo.test',
        user_data_privkey=wallets[4].privkey,
        user_zonefile=zonefile,
        proxy=test_proxy)
    if not rc:
        print 'failed to put profile'
        return False

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    first_name_block = testlib.get_current_block(**kw)

    resp = testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # end of 692

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print 'failed to whois foo.test'
        print json.dumps(whois, indent=4)
        return False

    # this should be the second-to-last block
    if whois['expire_block'] != testlib.get_current_block(**kw) + 2:
        print 'wrong expire block (expect 2 more)'
        print whois
        return False

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # end of 693; begin epoch 2
    # begin epoch 2

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # 694

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print 'failed to whois foo.test'
        print json.dumps(whois, indent=4)
        return False

    # this should be the last block
    if whois['expire_block'] != testlib.get_current_block(**kw) + 2:
        print 'wrong expire block (expect 2 more)'
        print whois
        return False

    if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 2:
        print 'wrong renewal block (expect 2 more)'
        print whois
        return False

    print whois

    testlib.next_block(**kw)  # 695 (epoch 3 begins)

    # try lookup
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # end of 696

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print whois
        return False

    # this should be the expire block
    if whois['expire_block'] != testlib.get_current_block(**kw):
        print 'wrong expire block (now at {})'.format(
            testlib.get_current_block(**kw))
        print whois
        return False

    # should now be a grace period
    if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 5:
        print 'wrong renewal block (now at {})'.format(
            testlib.get_current_block(**kw))
        print whois
        return False

    last_transaction_height = whois['last_transaction_height']

    # begin epoch 3 (grace period)
    testlib.next_block(**kw)  # end of 697

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    testlib.next_block(**kw)  # 698

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    testlib.next_block(**kw)  # 699

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    testlib.next_block(**kw)  # 700

    # try lookup (should fail)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in res:
        print res
        return False

    if 'expired' not in res['error']:
        print res
        return False

    # make a zonefile and a profile
    driver_urls = blockstack_client.storage.make_mutable_data_urls(
        'foo.test', use_only=['dht', 'disk'])
    new_zonefile = blockstack_client.zonefile.make_empty_zonefile(
        'foo.test', wallets[4].pubkey_hex, urls=driver_urls)
    new_zonefile_txt = blockstack_zones.make_zone_file(new_zonefile,
                                                       origin='foo.test',
                                                       ttl=4200)

    # make a new keyfile as well
    new_user_profile = blockstack_client.user.make_empty_user_profile()
    new_user_profile['new_user'] = True
    '''
    res = blockstack_client.key_file.make_initial_key_file(new_user_profile, wallets[0].privkey)
    if 'error' in res:
        print res
        return res

    new_keyfile_txt = res['key_file']
    '''
    new_zonefile_hash = blockstack_client.get_zonefile_data_hash(
        new_zonefile_txt)

    rc = blockstack_client.profile.put_profile(
        'foo.test',
        new_user_profile,
        blockchain_id='foo.test',
        user_data_privkey=wallets[4].privkey,
        user_zonefile=new_zonefile,
        proxy=test_proxy)
    if not rc:
        print 'failed to put profile'
        return False

    # renew/xfer/update
    resp = testlib.blockstack_name_renew('foo.test',
                                         wallets[3].privkey,
                                         zonefile_hash=new_zonefile_hash,
                                         recipient_addr=wallets[0].addr)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)  # end of 701 (end of grace period)

    # try lookup (should succeed again)
    res = testlib.blockstack_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    if res['zonefile'] != new_zonefile_txt:
        print 'wrong zonefile'
        print new_zonefile_txt
        print res
        return False

    testlib.next_block(**kw)  # 702 (name can be registered again)
Пример #9
0
def scenario(wallets, **kw):

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

    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)

    wallet = testlib.blockstack_client_initialize_wallet(
        "0123456789abcdef", wallets[2].privkey, wallets[3].privkey,
        wallets[4].privkey)

    balance_before = testlib.blockstack_cli_balance()
    deposit_info = testlib.blockstack_cli_deposit()
    price_info = testlib.blockstack_cli_price("foo.test",
                                              password="******")
    wallet_info = testlib.blockstack_cli_wallet("0123456789abcdef")

    resp = testlib.blockstack_cli_register("foo.test", "0123456789abcdef")
    if 'error' in resp:
        print >> sys.stderr, json.dumps(resp, indent=4, sort_keys=True)
        return False

    # wait for the preorder to get confirmed
    for i in xrange(0, 5):
        testlib.next_block(**kw)

    # queued?
    preorder_info = testlib.blockstack_cli_info()
    names_owned_before = testlib.blockstack_cli_get_names_owned_by_address(
        wallets[3].addr)

    for i in xrange(0, 7):
        testlib.next_block(**kw)

    # wait for the poller to pick it up
    print >> sys.stderr, "Waiting 10 seconds for the backend to submit the register"
    time.sleep(10)

    # wait for the register to get confirmed
    for i in xrange(0, 5):
        testlib.next_block(**kw)

    # registered?
    register_info = testlib.blockstack_cli_info()
    names_info = testlib.blockstack_cli_names()

    for i in xrange(0, 7):
        testlib.next_block(**kw)

    print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge registration"
    time.sleep(10)

    # wait for update to get confirmed
    for i in xrange(0, 5):
        testlib.next_block(**kw)

    update_info = testlib.blockstack_cli_info()
    names_owned_after = testlib.blockstack_cli_get_names_owned_by_address(
        wallets[3].addr)
    whois = testlib.blockstack_cli_whois("foo.test")

    for i in xrange(0, 7):
        testlib.next_block(**kw)

    print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge update"
    time.sleep(10)

    # put some immutable data
    put_immutable_info = testlib.blockstack_cli_put_immutable(
        "foo.test", "hello_world", '{"hello": "world"}')
    if 'error' in put_immutable_info:
        print "put_immutable failed"
        print json.dumps(put_immutable_info, indent=4, sort_keys=True)
        return False

    # wait for update to be confirmed
    for i in xrange(0, 12):
        testlib.next_block(**kw)

    print >> sys.stderr, "Waiting 10 seconds for backend to acknowledge put-immutable update"
    time.sleep(10)

    balance_after = testlib.blockstack_cli_balance()
    blockchain_history = testlib.blockstack_cli_get_name_blockchain_history(
        "foo.test")
    zonefile_info = testlib.blockstack_cli_get_name_zonefile("foo.test",
                                                             json=False)
    all_names_info = testlib.blockstack_cli_get_all_names(0)
    namespace_names_info = testlib.blockstack_cli_get_names_in_namespace(
        "test", 0)
    lookup_info = testlib.blockstack_cli_lookup("foo.test")
    update_history = testlib.blockstack_cli_list_update_history("foo.test")
    zonefile_history = testlib.blockstack_cli_list_zonefile_history("foo.test")
    blockchain_record = testlib.blockstack_cli_get_name_blockchain_record(
        "foo.test")
def scenario(wallets, **kw):

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

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

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

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

    working_dir = testlib.get_working_dir(**kw)

    sub_zf_template = '$ORIGIN {}\n$TTL 3600\n_http._tcp URI 10 1 "http://www.foo.com"\n{}'
    zf_template = '$ORIGIN {}\n$TTL 3600\n_http._tcp URI 10 1 "http://www.foo.com"\n_resolver URI 10 1 "http://resolver.foo"\n{}'
    zf_default_url = '_file URI 10 1 "file://' + working_dir + '/{}"'
    zf_default_url_2 = '_file URI 20 1 "file://' + working_dir + '/{}"'

    subdomain_zonefiles = {
        'bar.foo1.test':
        sub_zf_template.format('bar.foo1.test',
                               zf_default_url.format('bar.foo1.test')),
        'bar.foo2.test':
        sub_zf_template.format('bar.foo2.test',
                               zf_default_url.format('bar.foo2.test')),
        'bar.foo3.test':
        sub_zf_template.format('bar.foo3.test',
                               zf_default_url.format('bar.foo3.test')),
    }

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

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

    # sign and put profiles
    for subd in ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']:
        profile_data = {
            'type': 'Person',
            'name': subd,
        }
        profile_jwt = testlib.blockstack_make_profile(profile_data,
                                                      wallets[4].privkey)
        path = os.path.join(working_dir, subd)
        with open(path, 'w') as f:
            f.write(profile_jwt)

    # whois
    for i in xrange(1, 4):
        name = 'foo{}.test'.format(i)

        res = testlib.blockstack_cli_whois(name)
        if 'error' in res:
            print res
            return False

        if not res.has_key('zonefile_hash') or res[
                'zonefile_hash'] != storage.get_zonefile_data_hash(
                    zonefiles[name]):
            print res
            return False

        if res['owner_address'] != wallets[3].addr:
            print res
            return False

        # upload zonefile
        assert testlib.blockstack_put_zonefile(zonefiles[name])

    subdomain_zonefiles_2 = {
        'bar.foo1.test':
        zf_template.format('bar.foo1.test',
                           zf_default_url_2.format('bar.foo1.test')),
        'bar.foo2.test':
        zf_template.format('bar.foo2.test',
                           zf_default_url_2.format('bar.foo2.test')),
        'bar.foo3.test':
        zf_template.format('bar.foo3.test',
                           zf_default_url_2.format('bar.foo3.test')),
    }

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

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

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

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

    # start API daemon
    print 'starting API daemon'
    wallet_keys = testlib.blockstack_client_initialize_wallet(
        "0123456789abcdef", wallets[0].privkey, wallets[1].privkey,
        wallets[2].privkey)

    # authenticate
    pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex()
    res = testlib.blockstack_cli_app_signin("foo.test", pk, 'register.app', [
        'names', 'register', 'prices', 'zonefiles', 'blockchain', 'node_read',
        'user_read'
    ])
    if 'error' in res:
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    ses = res['token']

    # query each subdomain
    proxy = testlib.make_proxy()

    # test 301 redirects.
    res = testlib.blockstack_REST_call('GET',
                                       '/v1/names/baz.foo1.test',
                                       ses,
                                       allow_redirects=False)
    if 'error' in res:
        res['test'] = 'Failed to query non-registered name.'
        print json.dumps(res)
        return False
    if res['http_status'] != 301:
        res['test'] = 'Failed to get a redirect.'
        print json.dumps(res)
        return False

    for i in xrange(1, 4):
        fqn = 'bar.foo{}.test'.format(i)

        # test REST whois
        res = testlib.blockstack_REST_call('GET', '/v1/names/{}'.format(fqn),
                                           ses)
        if 'error' in res:
            res['test'] = 'Failed to query name'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on name lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        if res['response']['zonefile'] != subdomain_zonefiles[fqn]:
            print 'wrong zone file'
            print res
            print 'expected'
            print zonefiles['foo{}.test'.format(i)]
            return False

        if res['response']['status'] != 'registered_subdomain':
            print 'wrong status'
            print res
            return False

        # test CLI lookup
        res = testlib.blockstack_cli_lookup(fqn)
        if 'error' in res:
            print res
            return False

        print res
        if res['profile'] != {'type': 'Person', 'name': fqn}:
            print 'wrong profile'
            print res['profile']
            return False

        # test REST lookup
        res = testlib.blockstack_REST_call("GET", "/v1/users/{}".format(fqn),
                                           ses)
        if 'error' in res:
            res['test'] = 'Failed to query name profile'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on name profile lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        print res
        if res['response'] != {'type': 'Person', 'name': fqn}:
            print 'wrong profile on REST call'
            print res
            return False

        # test CLI lookup by address
        res = testlib.blockstack_cli_get_names_owned_by_address(
            wallets[4].addr)
        if 'error' in res:
            print 'failed to get subdomains owned by {}'.format(
                wallets[4].addr)
            print res
            return False

        if fqn not in res:
            print '{} not in list'.format(fqn)
            print res
            return False

        # test REST lookup by address
        res = testlib.blockstack_REST_call(
            'GET', '/v1/addresses/bitcoin/{}'.format(wallets[4].addr), ses)
        if 'error' in res:
            res['test'] = 'Failed to query names owned by address'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on address lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        if fqn not in res['response']['names']:
            print '{} not in REST list'.format(fqn)
            print res
            return False

        # test REST get name history
        res = testlib.blockstack_REST_call('GET',
                                           '/v1/names/{}/history'.format(fqn),
                                           ses)
        if 'error' in res:
            res['test'] = 'Failed to query subdomain history'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on subdomain history lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        blocks = res['response']
        if len(blocks.keys()) != 2:
            print 'expected two updates'
            print blocks
            return False

        # get each historic zone file
        for block_height in blocks:
            for prev_state in blocks[block_height]:
                value_hash = prev_state['value_hash']
                res = testlib.blockstack_REST_call(
                    'GET', '/v1/names/{}/zonefile/{}'.format(fqn, value_hash),
                    ses)
                if 'error' in res:
                    print 'failed to query zone file {} for {}'.format(
                        value_hash, fqn)
                    print json.dumps(res)
                    return False

    # reindex
    assert testlib.check_subdomain_db(**kw)
Пример #11
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)

    working_dir = testlib.get_working_dir(**kw)

    sub_zf_template = '$ORIGIN {}\n$TTL 3600\n{}'
    zf_template = '$ORIGIN {}\n$TTL 3600\n_http._tcp URI 10 1 "http://www.foo.com"\n_resolver URI 10 1 "http://resolver.foo"\n{}'
    zf_default_url = '_file URI 10 1 "http://localhost:4000/hub/{}/profile.json'
    zf_default_url_2 = '_file URI 20 1 "http://localhost:4000/hub/{}/profile.json'

    subdomain_zonefiles = {
        'bar.foo1.test':
        sub_zf_template.format(
            'bar.foo1.test',
            zf_default_url.format(
                virtualchain.address_reencode(wallets[0].addr,
                                              network='mainnet'))),
        'bar.foo2.test':
        sub_zf_template.format(
            'bar.foo2.test',
            zf_default_url.format(
                virtualchain.address_reencode(wallets[1].addr,
                                              network='mainnet'))),
        'bar.foo3.test':
        sub_zf_template.format(
            'bar.foo3.test',
            zf_default_url.format(
                virtualchain.address_reencode(wallets[2].addr,
                                              network='mainnet'))),
    }

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

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

    # sign and put profiles
    for i, subd in enumerate(
        ['bar.foo1.test', 'bar.foo2.test', 'bar.foo3.test']):
        profile_data = {
            'type': 'Person',
            'name': subd,
        }
        profile_jwt = testlib.blockstack_make_profile(profile_data,
                                                      wallets[i].privkey)
        testlib.blockstack_put_profile(None, profile_jwt, wallets[i].privkey,
                                       'http://localhost:4000')

    # whois
    for i in xrange(1, 4):
        name = 'foo{}.test'.format(i)

        res = testlib.blockstack_cli_whois(name)
        if 'error' in res:
            print res
            return False

        if not res.has_key('zonefile_hash') or res[
                'zonefile_hash'] != storage.get_zonefile_data_hash(
                    zonefiles[name]):
            print res
            return False

        if res['owner_address'] != wallets[3].addr:
            print res
            return False

        # upload zonefile
        assert testlib.blockstack_put_zonefile(zonefiles[name])

    subdomain_zonefiles_2 = {
        'bar.foo1.test':
        sub_zf_template.format(
            'bar.foo1.test',
            zf_default_url_2.format(
                virtualchain.address_reencode(wallets[0].addr,
                                              network='mainnet'))),
        'bar.foo2.test':
        sub_zf_template.format(
            'bar.foo2.test',
            zf_default_url_2.format(
                virtualchain.address_reencode(wallets[1].addr,
                                              network='mainnet'))),
        'bar.foo3.test':
        sub_zf_template.format(
            'bar.foo3.test',
            zf_default_url_2.format(
                virtualchain.address_reencode(wallets[2].addr,
                                              network='mainnet'))),
    }

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

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

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

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

    # query each subdomain
    # test 301 redirects.
    res = testlib.blockstack_REST_call('GET',
                                       '/v1/names/baz.foo1.test',
                                       allow_redirects=False)
    if 'error' in res:
        res['test'] = 'Failed to query non-registered name.'
        print json.dumps(res)
        return False

    if res['http_status'] != 301:
        res['test'] = 'Failed to get a redirect.'
        print json.dumps(res)
        return False

    for i in xrange(1, 4):
        fqn = 'bar.foo{}.test'.format(i)

        # test REST whois
        res = testlib.blockstack_REST_call('GET', '/v1/names/{}'.format(fqn))
        if 'error' in res:
            res['test'] = 'Failed to query name'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on name lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        if res['response']['zonefile'] != subdomain_zonefiles[fqn]:
            print 'wrong zone file'
            print res
            print 'expected'
            print zonefiles['foo{}.test'.format(i)]
            return False

        if res['response']['status'] != 'registered_subdomain':
            print 'wrong status'
            print res
            return False

        # test CLI lookup
        res = testlib.blockstack_cli_lookup(fqn)
        if 'error' in res:
            print res
            return False

        print res
        if res['profile'] != {'type': 'Person', 'name': fqn}:
            print 'wrong profile'
            print res['profile']
            return False

        # test REST lookup
        res = testlib.blockstack_REST_call("GET", "/v1/users/{}".format(fqn))
        if 'error' in res:
            res['test'] = 'Failed to query name profile'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on name profile lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        print res
        if res['response'] != {'type': 'Person', 'name': fqn}:
            print 'wrong profile on REST call'
            print res
            return False

        # test CLI lookup by address
        res = testlib.blockstack_cli_get_names_owned_by_address(
            wallets[i - 1].addr)
        if 'error' in res:
            print 'failed to get subdomains owned by {}'.format(
                wallets[i - 1].addr)
            print res
            return False

        if fqn not in res:
            print '{} not in list'.format(fqn)
            print res
            return False

        # test REST lookup by address
        res = testlib.blockstack_REST_call(
            'GET', '/v1/addresses/bitcoin/{}'.format(wallets[i - 1].addr))
        if 'error' in res:
            res['test'] = 'Failed to query names owned by address'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on address lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        if fqn not in res['response']['names']:
            print '{} not in REST list'.format(fqn)
            print res
            return False

        # test REST get name history
        res = testlib.blockstack_REST_call('GET',
                                           '/v1/names/{}/history'.format(fqn))
        if 'error' in res:
            res['test'] = 'Failed to query subdomain history'
            print json.dumps(res)
            return False

        if res['http_status'] != 200 and res['http_status'] != 404:
            res['test'] = 'HTTP status {}, response = {} on subdomain history lookup'.format(
                res['http_status'], res['response'])
            print json.dumps(res)
            return False

        blocks = res['response']
        if len(blocks.keys()) != 2:
            print 'expected two updates'
            print blocks
            return False

        # get each historic zone file
        for block_height in blocks:
            for prev_state in blocks[block_height]:
                value_hash = prev_state['value_hash']
                res = testlib.blockstack_REST_call(
                    'GET', '/v1/names/{}/zonefile/{}'.format(fqn, value_hash))
                if 'error' in res:
                    print 'failed to query zone file {} for {}'.format(
                        value_hash, fqn)
                    print json.dumps(res)
                    return False

    # reindex
    assert testlib.check_subdomain_db(**kw)
def check(state_engine):

    global wallet_keys, datasets, zonefile_hash

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

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

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

    # not preordered
    preorder = state_engine.get_name_preorder(
        "foo.test", pybitcoin.make_pay_to_address_script(wallets[2].addr),
        wallets[3].addr)
    if preorder is not None:
        print "still have preorder"
        return False

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

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

    # have right hash
    if name_rec['value_hash'] != zonefile_hash:
        print "Invalid zonefile hash"
        return False

    # zonefile is NOT legacy
    user_zonefile = blockstack_client.zonefile.load_name_zonefile(
        'foo.test', zonefile_hash)
    if 'error' in user_zonefile:
        print json.dumps(user_zonefile, indent=4, sort_keys=True)
        return False

    if blockstack_profiles.is_profile_in_legacy_format(user_zonefile):
        print "legacy still"
        print json.dumps(user_zonefile, indent=4, sort_keys=True)
        return False

    res = testlib.blockstack_cli_lookup("foo.test")
    if 'error' in res:
        print 'error looking up profile: {}'.format(res)
        return False

    assert 'profile' in res
    assert 'zonefile' in res

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

    global put_result, wallet_keys, legacy_profile, zonefile_hash, zonefile_hash_2, error


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

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

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

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = blockstack_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[8].privkey )

    # set up legacy profile hash
    legacy_txt = json.dumps(legacy_profile,sort_keys=True)
    legacy_hash = pybitcoin.hex_hash160( legacy_txt )

    result_1 = testlib.blockstack_name_update( "foo.test", legacy_hash, wallets[3].privkey )
    testlib.next_block( **kw )

    rc = blockstack_client.storage.put_immutable_data( None, result_1['transaction_hash'], data_hash=legacy_hash, data_text=legacy_txt )
    assert rc is not None

    testlib.next_block( **kw )

    # migrate profiles to standard zonefiles
    res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        res['test'] = 'Failed to initialize foo.test profile'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 

    testlib.next_block( **kw )

    # give foo.test a nonstandard zonefile (as something that serializes to JSON)
    nonstandard_zonefile_json = {'nonstandard': 'true', 'error': 'nonstandard'}
    nonstandard_zonefile_txt = json.dumps(nonstandard_zonefile_json, sort_keys=True)
    nonstandard_zonefile_raw = binascii.unhexlify( "".join(["%02x" % i for i in xrange(0, 256)]))

    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] )

    zf_data = [nonstandard_zonefile_txt, nonstandard_zonefile_raw]
    for zi in xrange(0, len(zf_data)):
        nonstandard_zonefile = zf_data[zi]

        resp = testlib.blockstack_cli_update( "foo.test", nonstandard_zonefile, "0123456789abcdef", nonstandard=True )
        if 'error' in resp:
            print "failed to put nonstandard zonefile '%s'" % nonstandard_zonefile
            print json.dumps(resp, indent=4, sort_keys=True)
            error = True
            return

        testlib.expect_atlas_zonefile(resp['value_hash'])

        # wait for it to take effect
        for i in xrange(0, 12):
            testlib.next_block( **kw )

        time.sleep(3)

        # getting zonefile should still work...
        resp = testlib.blockstack_cli_advanced_get_name_zonefile( "foo.test", json=True )
        if 'error' in resp:
            print "failed to get zonefile %s" % zi
            print json.dumps(resp, indent=4, sort_keys=True)
            error = True
            return 

        if 'warning' not in resp:
            print "no non-standard warning:\n%s" % json.dumps(resp, indent=4, sort_keys=True)
            error = True
            return

        if resp['zonefile'] != nonstandard_zonefile:
            print "failed to load nonstandard zonefile json"
            print "expected:\n%s\n\ngot:\n%s" % (nonstandard_zonefile, resp['zonefile'])
            error = True
            return 

        # the following should all fail
        dataplane_funcs = [
            ("lookup",        lambda: testlib.blockstack_cli_lookup( "foo.test" )),
            ("put_immutable", lambda: testlib.blockstack_cli_advanced_put_immutable( "foo.test", "fail", '{"Fail": "Yes"}' )),
            ("get_immutable", lambda: testlib.blockstack_cli_advanced_get_immutable( "foo.test", "fail" )),
            ("put_mutable",   lambda: testlib.blockstack_cli_advanced_put_mutable( "foo.test", "fail", '{"fail": "yes"}' )),
            ("get_mutable",   lambda: testlib.blockstack_cli_advanced_get_mutable( "foo.test", "fail" )),
            ("delete_immutable", lambda: testlib.blockstack_cli_advanced_delete_immutable( "foo.test", "00" * 32 )),
            ("delete_mutable", lambda: testlib.blockstack_cli_advanced_delete_mutable( "foo.test", "fail" ))
        ]

        for data_func_name, data_func in dataplane_funcs:
            resp = data_func()
            if 'error' not in resp:
                print "%s succeeded when it should not have:\n%s" % (data_func_name, json.dumps(resp, indent=4, sort_keys=True))
                error = True
                return
      
        # this should succeed
        zf_hist = testlib.blockstack_cli_advanced_list_zonefile_history( "foo.test" )
        if len(zf_hist) != 2*(zi+1)+1:
            print "missing zonefile history: %s (expected %s items, got %s)" % (zf_hist, zi+3, len(zf_hist))
            error = True
            return

        if zf_hist[-1] != nonstandard_zonefile:
            print "invalid zonefile: expected\n%s\ngot\n%s\n" % (nonstandard_zonefile, zf_hist[-1])
            error = True
            return

        # this should work, but with "non-standard zonefiles"
        hist = testlib.blockstack_cli_advanced_list_immutable_data_history("foo.test", "fail")
        if len(hist) != 2*(zi+1)+1:
            print "missing immutable data history: %s (expected %s items, got %s)" % (hist, zi+3, len(hist))
            error = True
            return 

        if hist[-1] != 'non-standard zonefile':
            print "not a non-standard zonefile: %s" % hist[-1]
            error = True
            return 

        # verify that we can migrate it back
        resp = testlib.blockstack_cli_migrate( "foo.test", "0123456789abcdef", force=True )
        if 'error' in resp:
            print "failed to migrate"
            print json.dumps(resp, indent=4, sort_keys=True)
            error = True
            return 

        zonefile_hash = resp['zonefile_hash']

        # wait for it to take effect
        for i in xrange(0, 12):
            testlib.next_block( **kw )

        time.sleep(3)

    # see that put_immutable works
    put_result = blockstack_client.put_immutable( "foo.test", "hello_world_immutable", {"hello": "world"}, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True )

    testlib.expect_atlas_zonefile(put_result['zonefile_hash'])

    # tell serialization-checker that value_hash can be ignored here
    print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
    sys.stdout.flush()
    
    # wait for confirmation
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "waiting for confirmation"
    time.sleep(3)

    # see that put_mutable works
    put_result = blockstack_client.put_mutable( "foo.test", "hello_world_mutable", {"hello": "world"}, proxy=test_proxy, wallet_keys=wallet_keys_2 )
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True )
    
    testlib.next_block( **kw )
def check( state_engine ):

    global wallet_keys, datasets, zonefile_hash

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

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

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

    # not preordered
    preorder = state_engine.get_name_preorder( "foo.test", pybitcoin.make_pay_to_address_script(wallets[2].addr), wallets[3].addr )
    if preorder is not None:
        print "still have preorder"
        return False
    
    # registered 
    name_rec = state_engine.get_name( "foo.test" )
    if name_rec is None:
        print "name does not exist"
        return False 

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

    # have right hash 
    if name_rec['value_hash'] != zonefile_hash:
        print "Invalid zonefile hash"
        return False 

    # zonefile is NOT legacy 
    user_zonefile = blockstack_client.zonefile.load_name_zonefile( 'foo.test', zonefile_hash )
    if 'error' in user_zonefile:
        print json.dumps(user_zonefile, indent=4, sort_keys=True)
        return False 

    if blockstack_profiles.is_profile_in_legacy_format( user_zonefile ):
        print "legacy still"
        print json.dumps(user_zonefile, indent=4, sort_keys=True)
        return False
    
    res = testlib.blockstack_cli_lookup("foo.test")
    if 'error' in res:
        print 'error looking up profile: {}'.format(res)
        return False

    assert 'profile' in res
    assert 'zonefile' in res

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

    global first_name_block

    # make a test namespace
    resp = testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        return False

    testlib.next_block( **kw ) # end of 689

    resp = testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 2, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        return False

    testlib.next_block( **kw ) # 690

    resp = testlib.blockstack_name_import( "foo.test", wallets[3].addr, "11" * 20, wallets[1].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        return False

    testlib.next_block( **kw ) # 691
    first_name_block = testlib.get_current_block( **kw )

    resp = testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        return False

    testlib.next_block( **kw ) # end of 692 (epoch 3 should be active)

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print 'failed to whois foo.test'
        print json.dumps(whois, indent=4)
        return False

    # epoch 3 should be active...
    if whois['expire_block'] != testlib.get_current_block(**kw) + 4:
        print 'wrong expire block (should be 4 away)'
        print whois
        return False

    resp = testlib.blockstack_name_renew( 'foo.test', wallets[3].privkey, zonefile_hash='22'*20, recipient_addr=wallets[2].addr)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw) # end of 693 (new epoch)

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print whois
        return False

    if whois['expire_block'] != testlib.get_current_block(**kw) + 4:
        print 'expire block: {}'.format(whois['expire_block'])
        print 'current block + 4: {}'.format(testlib.get_current_block(**kw) + 4)
        return False

    if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 9:
        print 'renewal deadline: {}'.format(whois['renewal_deadline'])
        print 'current block + 9: {}'.format(testlib.get_current_block(**kw) + 9)
        return False

    # expire it again (block 694-698)
    for i in xrange(0, 4):
        testlib.next_block(**kw)

    lookup = testlib.blockstack_cli_lookup('foo.test')
    if 'error' not in lookup:
        print lookup
        return False

    if 'name is expired' not in lookup['error'].lower():
        print lookup
        return False

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print whois
        return False

    if whois['expire_block'] != testlib.get_current_block(**kw):
        print 'expire block: {}'.format(whois['expire_block'])
        print 'current block: {}'.format(testlib.get_current_block(**kw))
        return False

    if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 5:
        print 'renewal deadline: {}'.format(whois['renewal_deadline'])
        print 'current block + 4: {}'.format(testlib.get_current_block(**kw) + 5)
        return False

    # renew
    resp = testlib.blockstack_name_renew( 'foo.test', wallets[2].privkey, zonefile_hash='33'*20, recipient_addr=wallets[4].addr)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw) # 699

    whois = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print whois
        return False

    if whois['expire_block'] != testlib.get_current_block(**kw) + 4:
        print 'expire block: {}'.format(whois['expire_block'])
        print 'current block + 4: {}'.format(testlib.get_current_block(**kw) + 4)
        return False

    if whois['renewal_deadline'] != testlib.get_current_block(**kw) + 9:
        print 'renewal deadline: {}'.format(whois['renewal_deadline'])
        print 'current block + 9: {}'.format(testlib.get_current_block(**kw) + 9)
        return False

    if whois['owner_address'] != wallets[4].addr:
        print 'wrong owner; expected {}'.format(wallets[4].addr)
        print whois
        return False
Пример #16
0
def scenario(wallets, **kw):

    global put_result, wallet_keys, legacy_profile, zonefile_hash, zonefile_hash_2, error

    wallet_keys = testlib.blockstack_client_initialize_wallet(
        "0123456789abcdef", wallets[8].privkey, wallets[3].privkey,
        wallets[4].privkey)

    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)

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

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

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

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

    testlib.blockstack_name_register("foo.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    # set up legacy profile hash
    legacy_txt = json.dumps(legacy_profile, sort_keys=True)
    legacy_hash = virtualchain.lib.hashing.hex_hash160(legacy_txt)

    result_1 = testlib.blockstack_cli_update("foo.test", legacy_txt,
                                             '0123456789abcdef')
    if 'error' in result_1:
        print json.dumps(result_1, indent=4, sort_keys=True)
        return False

    # wait for it to go through...
    for i in xrange(0, 12):
        testlib.next_block(**kw)

    print "wait 10 seconds for update to go through"
    time.sleep(10)

    rc = blockstack_client.storage.put_immutable_data(
        legacy_txt, result_1['transaction_hash'], data_hash=legacy_hash)
    assert rc is not None

    testlib.next_block(**kw)

    # migrate profiles to standard zonefiles
    res = testlib.migrate_profile("foo.test",
                                  proxy=test_proxy,
                                  wallet_keys=wallet_keys)
    if 'error' in res:
        res['test'] = 'Failed to initialize foo.test profile'
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    # give foo.test a nonstandard zonefile (as something that serializes to JSON)
    nonstandard_zonefile_json = {'nonstandard': 'true', 'error': 'nonstandard'}
    nonstandard_zonefile_txt = json.dumps(nonstandard_zonefile_json,
                                          sort_keys=True)
    nonstandard_zonefile_raw = binascii.unhexlify("".join(
        ["%02x" % i for i in xrange(0, 256)]))

    zf_data = [nonstandard_zonefile_txt, nonstandard_zonefile_raw]
    for zi in xrange(0, len(zf_data)):
        nonstandard_zonefile = zf_data[zi]

        resp = testlib.blockstack_cli_update("foo.test",
                                             nonstandard_zonefile,
                                             "0123456789abcdef",
                                             nonstandard=True)
        if 'error' in resp:
            print "failed to put nonstandard zonefile '%s'" % nonstandard_zonefile
            print json.dumps(resp, indent=4, sort_keys=True)
            return False

        testlib.expect_atlas_zonefile(resp['zonefile_hash'])

        # wait for it to take effect
        for i in xrange(0, 12):
            testlib.next_block(**kw)

        time.sleep(10)

        # getting zonefile should still work...
        resp = testlib.blockstack_cli_get_name_zonefile("foo.test",
                                                        json=True,
                                                        raw=False)
        if 'error' in resp:
            print "failed to get zonefile %s" % zi
            print json.dumps(resp, indent=4, sort_keys=True)
            return False

        if resp['zonefile'] != nonstandard_zonefile:
            print "failed to load nonstandard zonefile json"
            print "expected:\n%s\n\ngot:\n%s" % (nonstandard_zonefile,
                                                 resp['zonefile'])
            return False

        # the following should all fail
        dataplane_funcs = [
            ("lookup", lambda: testlib.blockstack_cli_lookup("foo.test")),
            ("put_immutable", lambda: testlib.blockstack_cli_put_immutable(
                "foo.test",
                "fail",
                '{"Fail": "Yes"}',
                password='******')),
            ("get_immutable",
             lambda: testlib.blockstack_cli_get_immutable("foo.test", "fail")),
            ("put_mutable", lambda: testlib.blockstack_cli_put_mutable(
                "foo.test",
                "fail",
                '{"fail": "yes"}',
                password='******')),
            ("get_mutable",
             lambda: testlib.blockstack_cli_get_mutable("foo.test", "fail")),
            ("delete_immutable",
             lambda: testlib.blockstack_cli_delete_immutable(
                 "foo.test", "00" * 32, password='******')),
            ("delete_mutable", lambda: testlib.blockstack_cli_delete_mutable(
                "foo.test", "fail", password='******'))
        ]

        for data_func_name, data_func in dataplane_funcs:
            resp = data_func()
            if 'error' not in resp:
                if data_func_name != 'lookup':
                    print "%s succeeded when it should not have:\n%s" % (
                        data_func_name,
                        json.dumps(resp, indent=4, sort_keys=True))
                    return False
                elif 'error' not in resp['profile']:
                    print "%s succeeded when it should not have:\n%s" % (
                        data_func_name,
                        json.dumps(resp, indent=4, sort_keys=True))
                    return False

        # this should succeed
        zf_hist = testlib.blockstack_cli_list_zonefile_history("foo.test")
        if len(zf_hist) != 2 * (zi + 1) + 1:
            print "missing zonefile history: %s (expected %s items, got %s)" % (
                zf_hist, zi + 3, len(zf_hist))
            return False

        update_hist = testlib.blockstack_cli_list_update_history("foo.test")
        if len(update_hist) != 2 * (zi + 1) + 1:
            print 'missing zonefile history: %s (expected %s items, got %s)' % (
                zf_hist, zi + 3, len(zf_hist))
            return False

        name_hist = testlib.blockstack_cli_get_name_blockchain_history(
            "foo.test")

        if zf_hist[-1] != nonstandard_zonefile:
            print "invalid zonefile: expected\n%s\ngot\n%s\n" % (
                nonstandard_zonefile, zf_hist[-1])
            return False

        # this should work, but with "non-standard zonefiles"
        hist = testlib.blockstack_cli_list_immutable_data_history(
            "foo.test", "fail")
        if len(hist) != 2 * (zi + 1) + 1:
            print "missing immutable data history: %s (expected %s items, got %s)" % (
                hist, zi + 3, len(hist))
            return False

        if hist[-1] != 'non-standard zonefile':
            print "not a non-standard zonefile: %s" % hist[-1]
            return False

        # verify that we can migrate it back
        resp = testlib.blockstack_cli_migrate("foo.test",
                                              "0123456789abcdef",
                                              force=True,
                                              interactive=False)
        if 'error' in resp:
            print "failed to migrate"
            print json.dumps(resp, indent=4, sort_keys=True)
            return False

        zonefile_hash = resp['zonefile_hash']

        # wait for it to take effect
        for i in xrange(0, 12):
            testlib.next_block(**kw)

        time.sleep(10)

    # see that put_immutable works
    put_result = testlib.blockstack_cli_put_immutable(
        "foo.test",
        "hello_world_immutable",
        json.dumps({'hello': 'world'}),
        password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)
        return False

    testlib.expect_atlas_zonefile(put_result['zonefile_hash'])

    # tell serialization-checker that value_hash can be ignored here
    print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
    sys.stdout.flush()

    # wait for confirmation
    for i in xrange(0, 12):
        testlib.next_block(**kw)

    print "waiting for confirmation"
    time.sleep(10)

    # see that put_mutable works
    put_result = testlib.blockstack_cli_put_mutable(
        "foo.test",
        "hello_world_mutable",
        json.dumps({'hello': 'world'}),
        password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    testlib.next_block(**kw)
def scenario( wallets, **kw ):

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

    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 )
    
    wallet = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey )

    balance_before = testlib.blockstack_cli_balance()
    deposit_info = testlib.blockstack_cli_deposit()
    price_info = testlib.blockstack_cli_price( "foo.test", password="******" )
    wallet_info = testlib.blockstack_cli_wallet( "0123456789abcdef" ) 

    resp = testlib.blockstack_cli_register( "foo.test", "0123456789abcdef" )
    if 'error' in resp:
        print >> sys.stderr, json.dumps(resp, indent=4, sort_keys=True)
        return False
   
    # wait for the preorder to get confirmed
    for i in xrange(0, 5):
        testlib.next_block( **kw )

    # queued?
    preorder_info = testlib.blockstack_cli_info()
    names_owned_before = testlib.blockstack_cli_get_names_owned_by_address( wallets[3].addr )

    for i in xrange(0, 7):
        testlib.next_block( **kw )

    # wait for the poller to pick it up
    print >> sys.stderr, "Waiting 10 seconds for the backend to submit the register"
    time.sleep(10)

    # wait for the register to get confirmed 
    for i in xrange(0, 5):
        testlib.next_block( **kw )

    # registered?
    register_info = testlib.blockstack_cli_info()
    names_info = testlib.blockstack_cli_names()

    for i in xrange(0, 7):
        testlib.next_block( **kw )

    print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge registration"
    time.sleep(10)

    # wait for update to get confirmed 
    for i in xrange(0, 5):
        testlib.next_block( **kw )

    update_info = testlib.blockstack_cli_info()
    names_owned_after = testlib.blockstack_cli_get_names_owned_by_address( wallets[3].addr )
    whois = testlib.blockstack_cli_whois( "foo.test" )

    for i in xrange(0, 7):
        testlib.next_block( **kw )

    print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge update"
    time.sleep(10)

    # put some immutable data 
    put_immutable_info = testlib.blockstack_cli_put_immutable( "foo.test", "hello_world", '{"hello": "world"}' )    
    if 'error' in put_immutable_info:
        print "put_immutable failed"
        print json.dumps(put_immutable_info, indent=4, sort_keys=True)
        return False

    # wait for update to be confirmed 
    for i in xrange(0, 12):
        testlib.next_block( **kw )

    print >> sys.stderr, "Waiting 10 seconds for backend to acknowledge put-immutable update"
    time.sleep(10)

    balance_after = testlib.blockstack_cli_balance()
    blockchain_history = testlib.blockstack_cli_get_name_blockchain_history( "foo.test" )
    zonefile_info = testlib.blockstack_cli_get_name_zonefile( "foo.test", json=False )
    all_names_info = testlib.blockstack_cli_get_all_names(0)
    namespace_names_info = testlib.blockstack_cli_get_names_in_namespace("test", 0)
    lookup_info = testlib.blockstack_cli_lookup( "foo.test" )
    update_history = testlib.blockstack_cli_list_update_history( "foo.test" )
    zonefile_history = testlib.blockstack_cli_list_zonefile_history( "foo.test" )
    blockchain_record = testlib.blockstack_cli_get_name_blockchain_record( "foo.test" )