예제 #1
0
def scenario( wallets, **kw ):

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

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

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

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

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

    resp = testlib.blockstack_announce( "hello world!", wallets[3].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    resp = testlib.blockstack_announce( "This should not appear", wallets[4].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # save...
    working_dir = testlib.get_working_dir( **kw )
def scenario( wallets, **kw ):

    global working_dir 
    testlib.blockstore_namespace_preorder( "id", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

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

    testlib.blockstore_namespace_ready( "id", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.blockstore_name_preorder( "judecn.id", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    testlib.blockstore_name_register( "judecn.id", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

    resp = testlib.blockstore_announce( "hello world!", wallets[3].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    resp = testlib.blockstore_announce( "This should not appear", wallets[4].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # save...
    working_dir = testlib.get_working_dir( **kw )
예제 #3
0
def scenario(wallets, **kw):

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

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

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

    testlib.blockstack_name_preorder("judecn.id", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("faker.id", wallets[2].privkey,
                                     wallets[4].addr)
    testlib.next_block(**kw)

    message = 'hello world!'
    message_hash = blockstack.lib.storage.get_zonefile_data_hash(message)

    fake_message = 'This should not appear'
    fake_message_hash = blockstack.lib.storage.get_zonefile_data_hash(
        fake_message)

    testlib.blockstack_name_register("judecn.id",
                                     wallets[2].privkey,
                                     wallets[3].addr,
                                     zonefile_hash=message_hash)
    testlib.blockstack_name_register("faker.id",
                                     wallets[2].privkey,
                                     wallets[4].addr,
                                     zonefile_hash=fake_message_hash)
    testlib.next_block(**kw)

    assert testlib.blockstack_put_zonefile(message)
    assert testlib.blockstack_put_zonefile(fake_message)

    resp = testlib.blockstack_announce(message, wallets[3].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    resp = testlib.blockstack_announce(fake_message, wallets[4].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # save...
    working_dir = testlib.get_working_dir(**kw)
def scenario( wallets, **kw ): 
    resp = testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    if 'error' in resp:
        print json.dumps(resp, indent=4)

    # make the test abort at the next block 
    wd = testlib.get_working_dir( **kw )
    os.chmod( wd, 0555 )

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

    if 'error' in resp:
        print json.dumps(resp, indent=4)
예제 #5
0
def scenario( wallets, **kw ): 
    resp = testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )

    if 'error' in resp:
        print json.dumps(resp, indent=4)

    # make the test abort at the next block 
    wd = testlib.get_working_dir( **kw )
    os.chmod( wd, 0555 )

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

    if 'error' in resp:
        print json.dumps(resp, indent=4)
def scenario( wallets, **kw ):

    global wallet_keys, wallet_keys_2, key_names, error, gpghome


    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.blockstack_name_preorder( "bar.test", wallets[5].privkey, wallets[6].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_register( "bar.test", wallets[5].privkey, wallets[6].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 )
    wallet_keys_2 = blockstack_client.make_wallet_keys( owner_privkey=wallets[6].privkey, data_privkey=wallets[7].privkey )

    # migrate profiles 
    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 

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

    testlib.next_block( **kw )

    # add account keys 
    res = blockstack_gpg.gpg_profile_create_key( "foo.test", "foo_test_account_key", immutable=False,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 

    else:
        key_names['foo.test'].append( res )

    res = blockstack_gpg.gpg_profile_create_key( "bar.test", "bar_test_account_key", immutable=False,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 

    else:
        key_names['bar.test'].append( res )

    testlib.next_block( **kw )

    # add immutable app keys 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "secure_messaging", "foo_test_immutable_secmsg_key", immutable=True,
                                              proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 
    else:
        key_names['foo.test'].append( res )

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "secure_messaging", "bar_test_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )

    testlib.next_block( **kw )

    # add mutable app keys 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "less-secure_messaging", "foo_test_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "less-secure_messaging", "bar_test_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )

    testlib.next_block( **kw )

    # add profile keys that we'll delete
    res = blockstack_gpg.gpg_profile_create_key( "foo.test", "foo_test_deleted_account_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False)

    foo_profile_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_profile_delete_key_id = res['key_id']

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_profile_create_key( "bar.test", "bar_test_deleted_account_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False)

    bar_profile_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_profile_delete_key_id = res['key_id']

    testlib.next_block( **kw )

    # add immutable app keys, which we can delete
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    foo_immutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_immutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )
    
    bar_immutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_immutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )

    # add mutable app keys which we can delete
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    foo_mutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable mutable foo.test app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_mutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    bar_mutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable mutable bar.test app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_mutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )

    # delete profile keys
    res = blockstack_gpg.gpg_profile_delete_key( "foo.test", foo_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        res['test'] = 'Failed to create deletable account foo.test profile key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_profile_delete_key( "bar.test", bar_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys_2 )
    if 'error' in res:
        res['test'] = 'Failed to create deletable account bar.test profile key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

    # delete immutable app keys 
    res = blockstack_gpg.gpg_app_delete_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", 
                                            immutable=True, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_app_delete_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key",
                                            immutable=True, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

    testlib.next_block( **kw )

    # delete mutable app keys
    res = blockstack_gpg.gpg_app_delete_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key",
                                            proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True 
        return 

    testlib.next_block( **kw )
    res = blockstack_gpg.gpg_app_delete_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key",
                                            proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True 
        return 

    testlib.next_block( **kw )
 
    gpghome = testlib.gpg_key_dir(**kw)
예제 #7
0
def scenario( wallets, **kw ):

    global wallet_keys, wallet_keys_2, key_names, error, gpghome


    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.blockstack_name_preorder( "bar.test", wallets[5].privkey, wallets[6].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_register( "bar.test", wallets[5].privkey, wallets[6].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 )
    wallet_keys_2 = blockstack_client.make_wallet_keys( owner_privkey=wallets[6].privkey, data_privkey=wallets[7].privkey, payment_privkey=wallets[9].privkey )

    # migrate profiles 
    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 

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

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

    # add account keys 
    res = blockstack_gpg.gpg_profile_create_key( "foo.test", "foo_test_account_key", immutable=False,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 

    else:
        key_names['foo.test'].append( res )

    res = blockstack_gpg.gpg_profile_create_key( "bar.test", "bar_test_account_key", immutable=False,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 

    else:
        key_names['bar.test'].append( res )

    testlib.next_block( **kw )

    # add immutable app keys
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "secure_messaging", "foo_test_immutable_secmsg_key", immutable=True,
                                              proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 
    else:
        key_names['foo.test'].append( res )

    # tell serialization-checker that value_hash can be ignored here
    print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
    sys.stdout.flush()
    
    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)
    
    # set new wallet keys
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "secure_messaging", "bar_test_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )

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

    # add mutable app keys 
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "less-secure_messaging", "foo_test_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )

    testlib.next_block( **kw )
    
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "less-secure_messaging", "bar_test_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )

    testlib.next_block( **kw )

    # add profile keys that we'll delete
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_profile_create_key( "foo.test", "foo_test_deleted_account_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False)

    foo_profile_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_profile_delete_key_id = res['key_id']

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

    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_profile_create_key( "bar.test", "bar_test_deleted_account_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False)

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

    bar_profile_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_profile_delete_key_id = res['key_id']

    # add immutable app keys, which we can delete
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    foo_immutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_immutable_delete_key_id = res['key_id']

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

    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )
    
    bar_immutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_immutable_delete_key_id = res['key_id']

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

    # add mutable app keys which we can delete
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    foo_mutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable mutable foo.test app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_mutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )
    
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    bar_mutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable mutable bar.test app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_mutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )

    # delete profile keys
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_profile_delete_key( "foo.test", foo_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        res['test'] = 'Failed to create deletable account foo.test profile key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_profile_delete_key( "bar.test", bar_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys_2 )
    if 'error' in res:
        res['test'] = 'Failed to create deletable account bar.test profile key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

    # delete immutable app keys 
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_delete_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", 
                                            immutable=True, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

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

    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_delete_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key",
                                            immutable=True, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

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

    # delete mutable app keys
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_delete_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key",
                                            proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True 
        return 

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) 
    res = blockstack_gpg.gpg_app_delete_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key",
                                            proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True 
        return 

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

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

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

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

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

    working_dir = testlib.get_working_dir(**kw)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    ses = res['token']

    # query each subdomain
    proxy = testlib.make_proxy()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # reindex
    assert testlib.check_subdomain_db(**kw)
예제 #9
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 scenario( wallets, **kw ):

    global wallet_keys, wallet_keys_2, key_names, error, gpghome


    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.blockstack_name_preorder( "bar.test", wallets[5].privkey, wallets[6].addr )
    testlib.next_block( **kw )
    
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.blockstack_name_register( "bar.test", wallets[5].privkey, wallets[6].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, payment_privkey=wallets[8].privkey )
    wallet_keys_2 = blockstack_client.make_wallet_keys( owner_privkey=wallets[6].privkey, payment_privkey=wallets[9].privkey )

    # migrate profiles 
    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 

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

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

    # add account keys 
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_profile_create_key( "foo.test", "foo_test_account_key", immutable=False,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 

    else:
        key_names['foo.test'].append( res )

    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_profile_create_key( "bar.test", "bar_test_account_key", immutable=False,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 

    else:
        key_names['bar.test'].append( res )

    testlib.next_block( **kw )

    # add immutable app keys 
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "secure_messaging", "foo_test_immutable_secmsg_key", immutable=True,
                                              proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return 
    else:
        key_names['foo.test'].append( res )

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "secure_messaging", "bar_test_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)

    testlib.next_block( **kw )

    # add mutable app keys 
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "less-secure_messaging", "foo_test_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create foo.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "less-secure_messaging", "bar_test_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    if 'error' in res:
        res['test'] = 'Failed to create bar.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )

    testlib.next_block( **kw )

    # add profile keys that we'll delete
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_profile_create_key( "foo.test", "foo_test_deleted_account_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False)

    foo_profile_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_profile_delete_key_id = res['key_id']

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_profile_create_key( "bar.test", "bar_test_deleted_account_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw),
                                                gpghome=testlib.gpg_key_dir(**kw), use_key_server=False)

    bar_profile_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test account key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_profile_delete_key_id = res['key_id']

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)

    testlib.next_block( **kw )

    # add immutable app keys, which we can delete
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    foo_immutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_immutable_delete_key_id = res['key_id']

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)


    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key", immutable=True,
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )
    
    bar_immutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_immutable_delete_key_id = res['key_id']

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)

    testlib.next_block( **kw )

    # add mutable app keys which we can delete
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw) )

    foo_mutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable mutable foo.test app key'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    else:
        key_names['foo.test'].append( res )
        foo_mutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_create_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key",
                                                proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw) )

    bar_mutable_delete_key_id = None
    if 'error' in res:
        res['test'] = 'Failed to create deletable mutable bar.test app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return
    else:
        key_names['bar.test'].append( res )
        bar_mutable_delete_key_id = res['key_id']

    testlib.next_block( **kw )

    # delete profile keys
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_profile_delete_key( "foo.test", foo_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        res['test'] = 'Failed to create deletable account foo.test profile key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_profile_delete_key( "bar.test", bar_profile_delete_key_id, proxy=test_proxy, wallet_keys=wallet_keys_2 )
    if 'error' in res:
        res['test'] = 'Failed to create deletable account bar.test profile key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

    # delete immutable app keys 
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_delete_key( "foo.test", "immutable_delete", "foo_test_deleted_immutable_secmsg_key", 
                                            immutable=True, proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_delete_key( "bar.test", "immutable_delete", "bar_test_deleted_immutable_secmsg_key",
                                            immutable=True, proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test immutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True
        return 

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

    # wait for it to go through
    for i in xrange(0, 12):
        testlib.next_block( **kw )
    print "wait for confirmation"
    time.sleep(10)

    testlib.next_block( **kw )

    # delete mutable app keys
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_delete_key( "foo.test", "mutable_delete", "foo_test_deleted_mutable_secmsg_key",
                                            proxy=test_proxy, wallet_keys=wallet_keys, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable foo.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True 
        return 

    testlib.next_block( **kw )
    testlib.blockstack_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], None ) 
    res = blockstack_gpg.gpg_app_delete_key( "bar.test", "mutable_delete", "bar_test_deleted_mutable_secmsg_key",
                                            proxy=test_proxy, wallet_keys=wallet_keys_2, config_dir=testlib.get_working_dir(**kw))

    if 'error' in res:
        res['test'] = 'Failed to create deletable bar.test mutable app key'
        print json.dumps(res, indent=4, sort_keys=True )
        error = True 
        return 

    testlib.next_block( **kw )
 
    gpghome = testlib.gpg_key_dir(**kw)