def scenario( wallets, **kw ):

    testlib.blockstore_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    testlib.next_block( **kw )
    
    testlib.blockstore_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 )
def scenario( wallets, **kw ):
    resp = testlib.blockstack_cli_namespace_preorder("test", wallets[0].privkey, wallets[1].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

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

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

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

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

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

    testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr)
    testlib.next_block(**kw)
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 )

    # will all be rejected trivially, since the first import must come from the importer's address
    testlib.blockstack_name_import( "foo.test", wallets[4].addr, "11" * 20, wallets[2].privkey )
    testlib.blockstack_name_import( "bar.test", wallets[2].addr, "22" * 20, wallets[3].privkey )
    testlib.blockstack_name_import( "baz.test", wallets[3].addr, "33" * 20, wallets[4].privkey )
    testlib.next_block( **kw )
   
    # will be accepted 
    testlib.blockstack_name_import( "goo.test", wallets[2].addr, "11" * 20, wallets[1].privkey )
    
    # will all be rejected because they weren't sent from a importer-derived key
    testlib.blockstack_name_import( "foo.test", wallets[4].addr, "11" * 20, wallets[2].privkey )
    testlib.blockstack_name_import( "bar.test", wallets[2].addr, "22" * 20, wallets[3].privkey )
    testlib.blockstack_name_import( "baz.test", wallets[3].addr, "33" * 20, wallets[4].privkey )
    testlib.next_block( **kw )
    
    testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )
def scenario( wallets, **kw ):

    # order 3 namespaces
    testlib.blockstore_namespace_preorder( "test1", wallets[1].addr, wallets[0].privkey )
    testlib.blockstore_namespace_preorder( "test2", wallets[3].addr, wallets[2].privkey )
    testlib.blockstore_namespace_preorder( "test3", wallets[5].addr, wallets[4].privkey )
    testlib.next_block( **kw )

    # reveal them all
    testlib.blockstore_namespace_reveal( "test1", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 11, wallets[0].privkey )
    testlib.blockstore_namespace_reveal( "test2", wallets[3].addr, 52596, 251, 5, [7,6,5,4,3,2,1,1,1,1,1,1,1,1,1,1], 11, 12, wallets[2].privkey )
    testlib.blockstore_namespace_reveal( "test3", wallets[5].addr, 52597, 252, 6, [8,7,6,5,4,3,2,2,2,2,2,2,2,2,2,2], 12, 13, wallets[4].privkey )
    testlib.next_block( **kw )
def scenario( wallets, **kw ):

    global reveal_block
    global preorder_block 

    testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    preorder_block = testlib.get_current_block( **kw ) + 1
    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 )
    reveal_block = testlib.get_current_block( **kw ) + 1

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

    global reveal_blocks, reveal_block

    for count in xrange(0, 3):
        resp = testlib.blockstack_namespace_preorder( "test", wallets[count+1].addr, wallets[count].privkey )
        if 'error' in resp:
            print json.dumps(resp, indent=4)

        testlib.next_block( **kw )

        # reveal it  
        buckets = [count] * 16
        testlib.blockstack_namespace_reveal( "test", wallets[count+1].addr, count + 1, count + 1, count + 1, buckets, count + 1, count + 1, wallets[count].privkey )
        testlib.next_block( **kw )

        reveal_blocks.append( testlib.get_current_block(**kw) )

        # expire it (2 blocks later)
        for i in xrange(0, 3): 
            testlib.next_block( **kw )

        # try to ready it (should fail)
        resp = testlib.blockstack_namespace_ready( "test", wallets[count+1].privkey )
        if 'error' in resp:
            print json.dumps(resp, indent=4)

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

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

    testlib.blockstore_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.blockstore_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    resp = testlib.blockstore_name_preorder_multi(
        ["foo.test", "bar.test", "baz.test"], wallets[2].privkey, [wallets[3].addr, wallets[4].addr, wallets[5].addr]
    )
    if "error" in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**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)
def scenario( wallets, **kw ):
    global preorder_block, reveal_block

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

    preorder_block = testlib.get_current_block( **kw ) + 1
    testlib.next_block(**kw)

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

    reveal_block = testlib.get_current_block( **kw ) + 1
    testlib.next_block(**kw)
def scenario( wallets, **kw ):

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

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

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

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
   
    # only wallets[3] should get it
    testlib.blockstack_name_register( "foo.test", wallets[4].privkey, wallets[3].addr, safety_checks=False )
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr, safety_checks=False )
    testlib.next_block( **kw )
def scenario( wallets, **kw ):

    global snv_consensus, snv_block_id 

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

    testlib.blockstore_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.blockstore_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

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

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

    snv_block_id = testlib.get_current_block()
    snv_consensus = testlib.get_consensus_at( snv_block_id )
def scenario(wallets, **kw):

    testlib.blockstore_namespace_preorder("test", wallets[1].addr, wallets[0].privkey)

    # wait 10 blocks between
    for i in xrange(0, 10):
        testlib.next_block(**kw)

    testlib.blockstore_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,
    )

    # wait 10 blocks between
    for i in xrange(0, 10):
        testlib.next_block(**kw)

    testlib.blockstore_namespace_ready("test", wallets[1].privkey)

    # wait 10 blocks between
    for i in xrange(0, 10):
        testlib.next_block(**kw)
def scenario( wallets, **kw ):

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

    testlib.blockstore_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.blockstore_name_import( "foo.test", wallets[2].addr, "11" * 20, wallets[1].privkey )
    testlib.blockstore_name_import( "bar.test", wallets[3].addr, "22" * 20, wallets[1].privkey )
    testlib.blockstore_name_import( "baz.test", wallets[4].addr, "33" * 20, wallets[1].privkey )
    testlib.next_block( **kw )
    
    testlib.blockstore_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )
def scenario( wallets, **kw ):

    global final_consensus

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

    testlib.blockstore_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.blockstore_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    resp = testlib.blockstore_name_preorder_multi( ["foo.test", "bar.test", "baz.test"], wallets[2].privkey, [wallets[3].addr, wallets[4].addr, wallets[5].addr] )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        sys.exit(1)
        
    testlib.next_block( **kw )
    preorder_consensus = testlib.get_consensus_at( testlib.get_current_block() )

    # these should all fail, since they're paired with the wrong addresses
    resp = testlib.blockstore_name_register( "foo.test", wallets[2].privkey, wallets[5].addr )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        sys.exit(1)
        
    resp = testlib.blockstore_name_register( "bar.test", wallets[2].privkey, wallets[3].addr )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        sys.exit(1)

    resp = testlib.blockstore_name_register( "baz.test", wallets[2].privkey, wallets[4].addr )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )
        sys.exit(1)

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

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

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

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

    testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr, safety_checks=False )
    testlib.blockstack_name_preorder( "foo.test", wallets[4].privkey, wallets[5].addr, safety_checks=False )
    testlib.blockstack_name_preorder( "foo.test", wallets[0].privkey, wallets[1].addr, safety_checks=False )
    testlib.blockstack_name_preorder( "foo.test", wallets[5].privkey, wallets[2].addr, safety_checks=False )
    testlib.next_block( **kw )

    # all of these should fail, since they're in the same block
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr, safety_checks=False )
    testlib.blockstack_name_register( "foo.test", wallets[4].privkey, wallets[5].addr, safety_checks=False )
    testlib.blockstack_name_register( "foo.test", wallets[0].privkey, wallets[1].addr, safety_checks=False )
    testlib.blockstack_name_register( "foo.test", wallets[5].privkey, wallets[2].addr, safety_checks=False )
    testlib.next_block( **kw )
def scenario( wallets, **kw ): 
    resp = testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block( **kw )

    # reveal it  
    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 )

    # expire it (1 day later)
    for i in xrange(0, 145): 
        testlib.next_block( **kw )

    # try to ready it (should fail)
    resp = testlib.blockstack_namespace_ready( "test", wallets[1].privkey )
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block( **kw )

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

    # save the wallet 
    wallet = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey, start_rpc=False )
    if 'error' in wallet:
        print 'failed to set wallet: {}'.format(wallet)
        return False

    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( "foo.id", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )

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

    # start api server 
    res = testlib.start_api("0123456789abcdef")
    if 'error' in res:
        print 'failed to start API server: {}'.format(res)
        return False

    # set up node environment 
    nodedir = testlib.nodejs_setup()

    # run 'core-test' test on blockstack (tests authentication from blockstack.js to Core API)
    testlib.nodejs_copy_package(nodedir, "blockstack")
    testlib.nodejs_copy_package(nodedir, "blockstack-storage")
    testlib.nodejs_run_test(nodedir, "integration-test-storage")
    testlib.nodejs_cleanup(nodedir)
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 )

    # can't import once ready
    resp = testlib.blockstack_name_import( "foo.test", wallets[1].addr, "11" * 20, wallets[0].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

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

    testlib.next_block( **kw )

    # expire it (1 day later)
    for i in xrange(0, 145): 
        testlib.next_block( **kw )

    # try to re-preorder it 
    resp = testlib.blockstack_namespace_preorder( "test", wallets[3].addr, wallets[2].privkey )
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block( **kw )
def scenario( wallets, **kw ):
    resp = testlib.blockstack_cli_namespace_preorder("test", wallets[0].privkey, wallets[1].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    resp = testlib.blockstack_cli_namespace_reveal('test', wallets[0].privkey, wallets[1].privkey, 52560, 4, 4, '6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0', 10, 10)
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)
def scenario( wallets, **kw ):
    # send a data-bearing transaction without 'id'
    tx = mktx(5500, 5500, wallets[1].addr, wallets[0].privkey, "eg")
    if 'error' in tx:
        print tx
        return False

    res = blockstack_client.tx.broadcast_tx(tx)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # send a data-bearing transaction with only 'id'
    tx = mktx(5500, 5500, wallets[1].addr, wallets[0].privkey, "id")
    if 'error' in tx:
        print tx
        return False

    res = blockstack_client.tx.broadcast_tx(tx)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # send a data-bearing transaction with an invalid opcode after 'id'
    tx = mktx(5500, 5500, wallets[1].addr, wallets[0].privkey, "id{")
    if 'error' in tx:
        print tx
        return False

    res = blockstack_client.tx.broadcast_tx(tx)
    if 'error' in res:
        print res
        return False

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

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

    testlib.next_block( **kw )
   
    resp = testlib.blockstack_namespace_preorder( "test", wallets[2].addr, wallets[3].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    resp = 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 )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_namespace_reveal( "test", wallets[2].addr, 11111, 222, 3, [4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,0], 11, 12, wallets[3].privkey )
    if 'error' in resp:
        print json.dumps( resp, indent=4 )

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

    global wallet_keys, wallet_keys_2, error, index_file_data, resource_data

    wallet_keys = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey )
    test_proxy = testlib.TestAPIProxy()
    ysi_client.set_default_proxy( test_proxy )

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

    testlib.ysi_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.ysi_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

    testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    testlib.next_block( **kw )
    
    # 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 

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

    config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None)

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

    ses = res['token']

    # for funsies, get the price of .test
    res = testlib.ysi_REST_call('GET', '/v1/prices/namespaces/test', ses )
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get price of .test'
        print json.dumps(res)
        return False

    test_price = res['response']['satoshis']
    print '\n\n.test costed {} satoshis\n\n'.format(test_price)

    # get the price for bar.test
    res = testlib.ysi_REST_call('GET', '/v1/prices/names/bar.test', ses )
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get price of bar.test'
        print json.dumps(res)
        return False

    bar_price = res['response']['total_estimated_cost']['satoshis']
    print "\n\nbar.test will cost {} satoshis\n\n".format(bar_price)

    # register the name bar.test. autogenerate the rest 
    res = testlib.ysi_REST_call('POST', '/v1/names', ses, data={'name': 'bar.test',
                                                                       'unsafe' : True})
    if 'error' in res:
        res['test'] = 'Failed to register user'
        print json.dumps(res)
        error = True
        return False

    print res
    tx_hash = res['response']['transaction_hash']

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

    res = testlib.verify_in_queue(ses, 'bar.test', 'preorder', tx_hash )
    testlib.next_block( **kw )

    if not res:
        return False

    # wait for register to go through 
    print 'Wait for register to be submitted'
    time.sleep(10)

    # wait for the register to get confirmed 
    res = testlib.verify_in_queue(ses, 'bar.test', 'register', None )
    testlib.next_block( **kw )

    if not res:
        return False

    '''
    print 'Wait for update to be submitted'
    time.sleep(10)
    time.sleep(10)

    # wait for update to get confirmed 
    res = testlib.verify_in_queue(ses, 'bar.test', 'update', None )
    testlib.next_block( **kw )

    if not res:
        return False

    print 'Wait for update to be confirmed'
    time.sleep(10)
    '''

    print 'Wait for zonefile to get picked up and confirmed?'
    time.sleep(10)
    time.sleep(10)
    testlib.next_block(**kw)

    res = testlib.ysi_REST_call("GET", "/v1/names/bar.test", ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name bar.test'
        print json.dumps(res)
        return False

    zonefile_hash = res['response']['zonefile_hash']

    # do we have the history for the name?
    res = testlib.ysi_REST_call("GET", "/v1/names/bar.test/history", ses )
    if 'error' in res or res['http_status'] != 200:
        res['test'] = "Failed to get name history for bar.test"
        print json.dumps(res)
        return False

    # valid history?
    hist = res['response']
    if len(hist.keys()) != 2:
        res['test'] = 'Failed to get update history'
        res['history'] = hist
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    # get the zonefile
    res = testlib.ysi_REST_call("GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), ses )
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name zonefile'
        print json.dumps(res)
        return False
def scenario(wallets, **kw):

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

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

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

    namespace_rec = testlib.ysi_cli_get_namespace_blockchain_record("test")
    if 'error' in namespace_rec:
        print namespace_rec
        return False

    namespace_balance = testlib.get_balance(namespace_rec['address'])
    burn_balance = testlib.get_balance(
        ysi_client.constants.BLOCKSTACK_BURN_ADDRESS)

    res = testlib.ysi_name_preorder("foo.test", wallets[2].privkey,
                                    wallets[3].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    res = testlib.ysi_name_register("foo.test", wallets[2].privkey,
                                    wallets[3].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)  # expired

    res = testlib.ysi_name_preorder("foo.test", wallets[3].privkey,
                                    wallets[4].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    res = testlib.ysi_name_register("foo.test", wallets[3].privkey,
                                    wallets[4].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)
    testlib.next_block(**kw)

    res = testlib.ysi_name_renew("foo.test", wallets[4].privkey)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)  # expired

    res = testlib.ysi_name_preorder("foo.test", wallets[2].privkey,
                                    wallets[3].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    res = testlib.ysi_name_register("foo.test", wallets[2].privkey,
                                    wallets[3].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    new_namespace_balance = testlib.get_balance(namespace_rec['address'])
    name_rec = testlib.get_name_blockchain_record('foo.test')
    name_cost = name_rec['op_fee']

    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)  # expired

    if new_namespace_balance - namespace_balance != 4 * name_cost:
        print 'address {} did not get credited'.format(
            namespace_rec['address'])
        print '{} != {} + 4*{}'.format(new_namespace_balance,
                                       namespace_balance, name_cost)
        return False

    # preorder should send to the null burn address now.
    res = testlib.ysi_name_preorder("foo2.test", wallets[4].privkey,
                                    wallets[0].addr)
    if 'error' in res:
        print res
        return False

    # try forcing it to the namespace burn address, to verify that it fails
    res = testlib.ysi_name_preorder("foo_fail.test",
                                    wallets[4].privkey,
                                    wallets[0].addr,
                                    burn_addr=namespace_rec['address'])
    if 'error' not in res:
        print res
        return False

    res = testlib.ysi_name_preorder("foo_fail.test",
                                    wallets[4].privkey,
                                    wallets[0].addr,
                                    burn_addr=namespace_rec['address'],
                                    safety_checks=False,
                                    tx_fee=10000 * 5)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should be accepted
    res = testlib.ysi_name_register("foo2.test", wallets[4].privkey,
                                    wallets[0].addr)
    if 'error' in res:
        print res
        return False

    # should be rejected
    res = testlib.ysi_name_register("foo_fail.test", wallets[4].privkey,
                                    wallets[0].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should have been rejected due to wrong burn address
    whois = testlib.ysi_cli_whois('foo_fail.test')
    if 'error' not in whois:
        print whois
        return False

    new_burn_balance = testlib.get_balance(
        ysi_client.constants.BLOCKSTACK_BURN_ADDRESS)
    new_namespace_balance = testlib.get_balance(namespace_rec['address'])
    name_rec_2 = testlib.get_name_blockchain_record('foo2.test')
    name_cost_2 = name_rec_2['op_fee']

    # namespace should NOT have gotten the fee for foo_fail.  It should only have gotten it for foo.test
    if new_namespace_balance - namespace_balance != 4 * name_cost + 3 * 5500:
        print 'address {} got credited after fee capture period'.format(
            namespace_rec['address'])
        print '{} != {} + 4*{}'.format(new_namespace_balance,
                                       namespace_balance, name_cost)
        return False

    # burn address should have received the fee for the second name
    if new_burn_balance - name_cost_2 != burn_balance:
        print 'null burn address did not get credited'
        print '{} != {} + {}'.format(new_burn_balance, burn_balance,
                                     name_cost_2)
        return False
def scenario(wallets, **kw):

    global wallet_keys, wallet_keys_2, error, index_file_data, resource_data

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

    # migrate profiles, but no data key in the zone file
    res = testlib.migrate_profile("foo.test",
                                  zonefile_has_data_key=False,
                                  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

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

    testlib.next_block(**kw)

    config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None)

    # make a session
    datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex()
    res = testlib.blockstack_cli_app_signin(
        "foo.test", datastore_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']

    # register the name bar.test. autogenerate the rest
    old_user_zonefile = blockstack_client.zonefile.make_empty_zonefile(
        'bar.test', None)
    old_user_zonefile_txt = blockstack_zones.make_zone_file(old_user_zonefile)

    res = testlib.blockstack_REST_call('POST',
                                       '/v1/names',
                                       ses,
                                       data={
                                           'name': 'bar.test',
                                           'zonefile': old_user_zonefile_txt,
                                           'make_profile': True
                                       })
    if 'error' in res:
        res['test'] = 'Failed to register user'
        print json.dumps(res)
        error = True
        return False

    print res
    tx_hash = res['response']['transaction_hash']

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

    res = testlib.verify_in_queue(ses, 'bar.test', 'preorder', tx_hash)
    if not res:
        return False

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

    # wait for register to go through
    print 'Wait for register to be submitted'
    time.sleep(10)

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

    res = testlib.verify_in_queue(ses, 'bar.test', 'register', None)
    if not res:
        return False

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

    # wait for register to go through
    print 'Wait for zonefile to replicate'
    time.sleep(10)

    res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name bar.test'
        print json.dumps(res)
        return False

    old_expire_block = res['response']['expire_block']

    # get the zonefile
    res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/zonefile",
                                       ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name zonefile'
        print json.dumps(res)
        return False

    # zonefile must not have a public key listed
    zonefile_txt = res['response']['zonefile']
    print zonefile_txt

    parsed_zonefile = blockstack_zones.parse_zone_file(zonefile_txt)
    if parsed_zonefile.has_key('txt'):
        print 'have txt records'
        print parsed_zonefile
        return False

    # renew it, but put the *current* owner key as the zonefile's *new* public key
    new_user_zonefile = blockstack_client.zonefile.make_empty_zonefile(
        'bar.test', wallets[3].pubkey_hex)
    new_user_zonefile_txt = blockstack_zones.make_zone_file(new_user_zonefile)

    res = testlib.blockstack_REST_call("POST",
                                       "/v1/names",
                                       ses,
                                       data={
                                           'name': 'bar.test',
                                           'zonefile': new_user_zonefile_txt
                                       })
    if 'error' in res or res['http_status'] != 202:
        res['test'] = 'Failed to renew name'
        print json.dumps(res)
        return False

    # verify in renew queue
    for i in xrange(0, 6):
        testlib.next_block(**kw)

    res = testlib.verify_in_queue(ses, 'bar.test', 'renew', None)
    if not res:
        return False

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

    # new expire block
    res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name bar.test'
        print json.dumps(res)
        return False

    new_expire_block = res['response']['expire_block']

    # do we have the history for the name?
    res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history",
                                       ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = "Failed to get name history for bar.test"
        print json.dumps(res)
        return False

    # valid history?
    hist = res['response']
    if len(hist.keys()) != 3:
        res['test'] = 'Failed to get update history'
        res['history'] = hist
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    # get the zonefile
    res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/zonefile",
                                       ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name zonefile'
        print json.dumps(res)
        return False

    # zonefile must have old owner key
    zonefile_txt = res['response']['zonefile']
    parsed_zonefile = blockstack_zones.parse_zone_file(zonefile_txt)
    if not parsed_zonefile.has_key('txt'):
        print 'missing txt'
        print parsed_zonefile
        return False

    found = False
    for txtrec in parsed_zonefile['txt']:
        if txtrec['name'] == 'pubkey' and txtrec[
                'txt'] == 'pubkey:data:{}'.format(wallets[3].pubkey_hex):
            found = True

    if not found:
        print 'missing public key {}'.format(wallets[3].pubkey_hex)
        return False

    # profile lookup must work
    res = testlib.blockstack_REST_call("GET", "/v1/users/bar.test", ses)
    if 'error' in res or res['http_status'] != 200:
        res['text'] = 'failed to get profile for bar.test'
        print json.dumps(res)
        return False

    print ''
    print json.dumps(res['response'], indent=4, sort_keys=True)
    print ''

    # verify pushed back
    if old_expire_block + 12 != new_expire_block:
        # didn't go through
        print >> sys.stderr, "Renewal didn't work: %s --> %s" % (
            old_expire_block, new_expire_block)
        return False
def scenario(wallets, **kw):

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

    testlib.next_block(**kw)

    resp = 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)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    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)

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

    # wait for a bit...
    for i in xrange(0, 10):
        testlib.next_block(**kw)

    resp = testlib.blockstack_name_renew("foo.test", wallets[3].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # update
    resp = testlib.blockstack_name_update("foo.test", "22" * 20,
                                          wallets[3].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

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

    global first_name_block

    # make a test namespace
    resp = testlib.ysi_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.ysi_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.ysi_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.ysi_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

    whois = testlib.ysi_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

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

    whois = testlib.ysi_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)
    testlib.next_block(**kw)  # end of 696

    whois = testlib.ysi_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']

    # should go through
    resp = testlib.ysi_name_preorder('foo.test',
                                     wallets[3].privkey,
                                     wallets[0].addr,
                                     safety_checks=False,
                                     tx_fee=500 * 5)
    if 'error' in resp:
        print resp
        return False

    # should go through
    resp = testlib.ysi_name_preorder('foo.test',
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     safety_checks=False,
                                     tx_fee=500 * 5)
    if 'error' in resp:
        print resp
        return False

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

    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20)
    if 'error' not in resp:
        print resp
        return False

    # should go through, but be rejected
    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20,
                                     safety_checks=False,
                                     tx_fee=500 * 5)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)  # 698
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should NOT have gone through
    whois = testlib.ysi_cli_whois('foo.test')
    if 'error' in whois:
        print whois
        return False

    if whois['last_transaction_height'] != last_transaction_height:
        print 'accidentally registered'
        return False

    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20)
    if 'error' not in resp:
        print resp
        return False

    # should go through, but be rejected
    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20,
                                     safety_checks=False,
                                     tx_fee=500 * 5)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)  # 699
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

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

    if whois['last_transaction_height'] != last_transaction_height:
        print 'accidentally registered'
        return False

    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20)
    if 'error' not in resp:
        print resp
        return False

    # should go through, but be rejected
    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20,
                                     safety_checks=False,
                                     tx_fee=500 * 5)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)  # 700
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

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

    if whois['last_transaction_height'] != last_transaction_height:
        print 'accidentally registered'
        return False

    # should go through, but be rejected (expired preorder)
    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20,
                                     safety_checks=False)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)  # end of 701 (end of grace period)
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

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

    # should go through, and be rejected (expired preorder)
    resp = testlib.ysi_name_register("foo.test",
                                     wallets[1].privkey,
                                     wallets[2].addr,
                                     zonefile_hash='44' * 20)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)  # 702 (name can be registered again)
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

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

    # should go through, but fail (expired preorder)
    resp = testlib.ysi_name_register("foo.test",
                                     wallets[3].privkey,
                                     wallets[0].addr,
                                     zonefile_hash='33' * 20)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)  # 703
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    whois = testlib.ysi_cli_whois('foo.test')
    if 'error' not in whois:
        print whois
        return False
def scenario(wallets, **kw):

    global put_result, wallet_keys, wallet_keys_2, datasets, zonefile_hash, dataset_change

    # set up a second client
    config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None)
    assert config_path

    config_dir_2 = os.path.dirname(config_path) + '.2'
    os.makedirs(config_dir_2)

    config_path_2 = os.path.join(config_dir_2, 'client.ini')

    res = testlib.peer_make_config(16300, config_dir_2)
    if 'error' in res:
        print "failed to set up {}".format(config_dir_2)
        return False

    wallet_keys_2 = testlib.ysi_client_initialize_wallet(
        "0123456789abcdef", wallets[5].privkey, wallets[6].privkey,
        wallets[7].privkey)
    wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef",
                                                       wallets[2].privkey,
                                                       wallets[3].privkey,
                                                       wallets[4].privkey)

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

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

    testlib.ysi_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.ysi_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

    resp = testlib.ysi_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, 12):
        testlib.next_block(**kw)

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

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

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

    # wait for initial update to get confirmed
    for i in xrange(0, 12):
        # tell serialization-checker that value_hash can be ignored here
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()

        testlib.next_block(**kw)

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

    # wait for zonefile/profile replication
    for i in xrange(0, 12):
        testlib.next_block(**kw)

    print >> sys.stderr, "Waiting for the backend to replicate zonefile and profile"
    time.sleep(10)

    # make a few accounts
    res = testlib.ysi_cli_put_account("foo.test",
                                      "serviceFoo",
                                      "serviceFooID",
                                      "foo://bar.com",
                                      "0123456789abcdef",
                                      extra_data='foofield=foo!',
                                      wallet_keys=wallet_keys)
    if 'error' in res:
        res['test'] = 'Failed to create foo.test serviceFoo account'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    time.sleep(2)

    res = testlib.ysi_cli_put_account("foo.test",
                                      "serviceBar",
                                      "serviceBarID",
                                      "bar://baz.com",
                                      "0123456789abcdef",
                                      extra_data='barfield=bar!',
                                      wallet_keys=wallet_keys)
    if 'error' in res:
        res['test'] = 'Failed to create foo.test serviceBar account'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    time.sleep(2)

    # put some data
    put_result = testlib.ysi_cli_put_mutable("foo.test",
                                             "hello_world_1",
                                             json.dumps(datasets[0]),
                                             password="******")
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)
        return False

    time.sleep(2)

    put_result = testlib.ysi_cli_put_mutable("foo.test",
                                             "hello_world_2",
                                             json.dumps(datasets[1]),
                                             password="******")
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)
        return False

    time.sleep(2)

    put_result = testlib.ysi_cli_put_mutable("foo.test",
                                             "hello_world_3",
                                             json.dumps(datasets[2]),
                                             password="******")
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)
        return False

    time.sleep(2)

    # increment data version too
    datasets[0]['buf'] = []
    for i in xrange(0, 5):
        datasets[0]["dataset_change"] = dataset_change
        datasets[0]['buf'].append(i)

        put_result = testlib.ysi_cli_put_mutable("foo.test",
                                                 "hello_world_1",
                                                 json.dumps(datasets[0]),
                                                 password="******")
        if 'error' in put_result:
            print json.dumps(put_result, indent=4, sort_keys=True)
            return False

        time.sleep(2)

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

    global debug

    resp = testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    resp = 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 )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

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

    testlib.next_block( **kw )

    resp = testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )
    
    resp = testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # ping-ping a bit... 3 --> 4 --> 5 --> 4 --> 5 --> 4
    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, False, wallets[3].privkey ) 
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, True, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, False, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, True, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, False, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # update (4)
    resp = testlib.blockstack_name_update( "foo.test", "11" * 20, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    # ping-ping a bit... 4 --> 5 --> 4 --> 5 --> 4 --> 5
    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, True, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, False, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, True, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, False, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )
    
    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, True, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    # now update (5)
    resp = testlib.blockstack_name_update( "foo.test", "22" * 20, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # transfer and update
    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, True, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_update( "foo.test", "33" * 20, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # update, transfer, transfer, update
    resp = testlib.blockstack_name_update( "foo.test", "44" * 20, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, False, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, True, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_update( "foo.test", "55" * 20, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # update, transfer, update
    resp = testlib.blockstack_name_update( "foo.test", "66" * 20, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, False, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_update( "foo.test", "11" * 20, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # transfer and update
    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, True, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_update( "foo.test", "33" * 20, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # update, transfer 
    resp = testlib.blockstack_name_update( "foo.test", "99" * 20, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[5].addr, False, wallets[4].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # transfer
    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, True, wallets[5].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

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

    global put_result, wallet_keys, legacy_profile, zonefile_hash, zonefile_hash_2


    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 )

    # 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 )
    result_2 = testlib.blockstack_name_update( "bar.test", legacy_hash, wallets[6].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

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

    testlib.next_block( **kw )

    # 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 

    zonefile_hash = res['zonefile_hash']

    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

    zonefile_hash_2 = res['zonefile_hash']

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

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

    # 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(10)

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

    # see that put_mutable works
    put_result = blockstack_client.put_mutable( "bar.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 scenario(wallets, **kw):
    segwit_addr_1 = get_segwit_address(wallets[1].privkey)
    segwit_addr_1_tb = get_segwit_address(wallets[1].privkey, hrp='tb')
    segwit_addr_0_tb = get_segwit_address(wallets[0].privkey, hrp='tb')

    print segwit_addr_0_tb
    print segwit_addr_1_tb

    pubk = virtualchain.lib.ecdsalib.ecdsa_private_key(
        wallets[1].privkey, compressed=True).public_key().to_hex()
    addrhash = virtualchain.lib.hashing.bin_hash160(
        pubk.decode('hex')).encode('hex')

    a = 'tb1pzjpqjwmz5d5e9qkey6vphmtkvh5rsn9225xsgg79'
    namespace_preorder_name_hash = blockstack.lib.hashing.hash_name(
        'test', virtualchain.make_payment_script(wallets[0].addr), a)
    print 'hash of {} + {} + {} = {}'.format(
        'test', virtualchain.make_payment_script(wallets[0].addr), a,
        namespace_preorder_name_hash)

    resp = testlib.blockstack_namespace_preorder("test",
                                                 wallets[1].addr,
                                                 wallets[0].privkey,
                                                 tx_only=True)
    tx = virtualchain.btc_tx_deserialize(resp['transaction'])

    new_tx = {
        'locktime': 0,
        'version': 1,
        'ins': tx['ins'],
        'outs': tx['outs'],
    }

    for inp in new_tx['ins']:
        inp['script'] = ''
        inp['witness_script'] = ''

    print 'script before: {}'.format(tx['outs'][0]['script'])

    patched_script = virtualchain.make_data_script(
        'id*'.encode('hex') + namespace_preorder_name_hash +
        tx['outs'][0]['script'].decode('hex')[25:].encode('hex'))

    print 'script after : {}'.format(patched_script)

    new_tx['outs'][0] = {'script': patched_script, 'value': 0}

    unsigned_txhex = virtualchain.btc_tx_serialize(new_tx)
    print 'unsigned: {}'.format(unsigned_txhex)

    addr = virtualchain.address_reencode(
        virtualchain.get_privkey_address(wallets[0].privkey))
    utxos = testlib.get_utxos(addr)
    prev_outputs = [{
        'out_script': inp['out_script'],
        'value': inp['value']
    } for inp in utxos]

    signed_txhex = virtualchain.tx_sign_all_unsigned_inputs(
        wallets[0].privkey, prev_outputs, unsigned_txhex)

    print 'signed: {}'.format(signed_txhex)

    res = testlib.broadcast_transaction(signed_txhex)
    assert 'error' not in res

    testlib.next_block(**kw)

    # should fail
    resp = 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,
        tx_only=True)
    resp = replace_output_with_bech32(resp['transaction'], 1,
                                      wallets[0].privkey, addrhash)

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

    global synchronized, value_hash

    import ysi_integration_tests.atlas_network as atlas_network

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

    testlib.ysi_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.ysi_namespace_ready( "test", wallets[1].privkey )
    testlib.next_block( **kw )

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

    # set up RPC daemon
    test_proxy = testlib.TestAPIProxy()
    ysi_client.set_default_proxy( test_proxy )
    wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey )
    testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] )

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.ysi_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    for i in xrange(0, 10):
        res = testlib.ysi_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr )
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block( **kw )
    
    # make 10 empty zonefiles and propagate them 
    for i in xrange(0, 10):
        data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex()
        empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] )
        empty_zonefile_str = ysi_zones.make_zone_file( empty_zonefile )
        value_hash = ysi_client.hash_zonefile( empty_zonefile )

        res = testlib.ysi_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey )
        if 'error' in res:
            print json.dumps(res)
            return False

        testlib.next_block( **kw )

        # propagate 
        res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str)
        if 'error' in res:
            print json.dumps(res)
            return False

    # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer
    # only the seed node will be publicly routable; the other 8 will be unable to directly talk to each other.
    atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007]
    atlas_topology = {}
    for node_port in atlas_nodes:
        atlas_topology[node_port] = [16264]

    def nat_drop(src_hostport, dest_hostport):
        if dest_hostport is None:
            return 0.0
        
        host, port = ysi_client.utils.url_to_host_port( dest_hostport )
        if port in atlas_nodes:
            # connections to the above nodes will always fail, since they're NAT'ed
            return 1.0

        else:
            # connections to the seed node always succeed
            return 0.0

    network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" ) )
    atlas_network.atlas_network_start( network_des, drop_probability=nat_drop )

    print "Waiting 60 seconds for the altas peers to catch up"
    time.sleep(60.0)

    # wait at most 60 seconds for atlas network to converge
    synchronized = False
    for i in xrange(0, 60):
        atlas_network.atlas_print_network_state( network_des )
        if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ):
            print "Synchronized!"
            synchronized = True
            break

        else:
            time.sleep(1.0)
    
    # shut down 
    atlas_network.atlas_network_stop( network_des )
    return synchronized
def scenario(wallets, **kw):

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

    # NOTE: names expire in 5 * NAMESPACE_LIFETIME_MULTIPLER blocks
    testlib.blockstack_namespace_reveal(
        "test", wallets[1].addr, 5, 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)

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

    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")
Example #36
0
def scenario(wallets, **kw):

    global put_result, wallet_keys, datasets, zonefile_hash, dataset_change

    wallet = testlib.blockstack_client_initialize_wallet(
        "0123456789abcdef", wallets[5].privkey, wallets[3].privkey,
        wallets[4].privkey)
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)
    wallet_keys = wallet

    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)

    # migrate profile
    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
    else:
        zonefile_hash = res['zonefile_hash']

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

    testlib.next_block(**kw)

    # sign some data
    for dataset in datasets:
        data_str = json.dumps(dataset, sort_keys=True)

        print "\nsign {} with {}, verify with {}\n".format(
            data_str, wallets[4].privkey, wallets[4].pubkey_hex)

        res = testlib.blockstack_cli_sign_data(data_str)
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        res = testlib.blockstack_cli_verify_data("foo.test", res)
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        print "\nsign {} with {}, verify with {}\n".format(
            data_str, wallets[0].privkey, wallets[0].pubkey_hex)

        # try with explicit keys
        res = testlib.blockstack_cli_sign_data(data_str,
                                               private_key=wallets[0].privkey)
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        res = testlib.blockstack_cli_verify_data(
            "foo.test", res, public_key=wallets[0].pubkey_hex)
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

    testlib.next_block(**kw)
Example #37
0
def scenario(wallets, **kw):

    global wallet_keys, wallet_keys_2, error, index_file_data, resource_data

    wallet_keys = testlib.blockstack_client_initialize_wallet(
        "0123456789abcdef", wallets[5].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)

    # 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

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

    testlib.next_block(**kw)

    config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None)

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

    ses = res['token']

    # let's set the key to skip the transfer.

    config_dir = os.path.dirname(config_path)
    conf = blockstack_client.get_config(config_path)
    assert conf

    api_pass = conf['api_password']

    new_payment_key = {
        'private_key': wallets[1].privkey,
        'persist_change': True
    }

    res = testlib.blockstack_REST_call('PUT',
                                       '/v1/wallet/keys/payment',
                                       None,
                                       api_pass=api_pass,
                                       data=new_payment_key)
    if res['http_status'] != 200 or 'error' in res:
        print 'failed to set payment key'
        print res
        return False

    testlib.stop_api()
    testlib.start_api('0123456789abcdef')

    res = testlib.blockstack_REST_call('GET',
                                       '/v1/wallet/payment_address',
                                       None,
                                       api_pass=api_pass)
    if res['http_status'] != 200 or 'error' in res:
        res['test'] = 'Failed to get payment address'
        print res
        return False
    if res['response']['address'] != wallets[1].addr:
        res['test'] = 'Got wrong payer address, expected {}, got {}'.format(
            wallets[1].addr, res['response']['address'])
        print res
        return False

    res = testlib.blockstack_REST_call('PUT',
                                       '/v1/wallet/keys/owner',
                                       None,
                                       api_pass=api_pass,
                                       data=new_key)
    if res['http_status'] != 200 or 'error' in res:
        print 'failed to set owner key'
        print res
        return False

    # make zonefile for recipient
    driver_urls = blockstack_client.storage.make_mutable_data_urls(
        'bar.test', use_only=['dht', 'disk'])
    zonefile = blockstack_client.zonefile.make_empty_zonefile(
        'bar.test', wallets[4].pubkey_hex, urls=driver_urls)
    zonefile_txt = blockstack_zones.make_zone_file(zonefile,
                                                   origin='bar.test',
                                                   ttl=3600)

    # leaving the call format of this one the same to make sure that our registrar correctly
    #   detects that the requested TRANSFER is superfluous
    # register the name bar.test
    res = testlib.blockstack_REST_call('POST',
                                       '/v1/names',
                                       ses,
                                       data={
                                           'name': 'bar.test',
                                           'zonefile': zonefile_txt,
                                           'owner_address': new_addr
                                       })
    if 'error' in res:
        res['test'] = 'Failed to register user'
        print json.dumps(res)
        error = True
        return False

    print res
    tx_hash = res['response']['transaction_hash']

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

    res = testlib.verify_in_queue(ses, 'bar.test', 'preorder', tx_hash)
    if not res:
        return False

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

    # wait for register to go through
    print 'Wait for register to be submitted'
    time.sleep(10)

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

    res = testlib.verify_in_queue(ses, 'bar.test', 'register', None)
    if not res:
        return False

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

    print 'Wait for update to be submitted'
    time.sleep(10)

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

    res = testlib.verify_in_queue(ses, 'bar.test', 'update', None)
    if not res:
        return False

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

    print 'Wait for transfer to be submitted'
    time.sleep(10)

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

    res = testlib.verify_in_queue(ses, 'bar.test', 'transfer', None)
    if res:
        print "Wrongly issued a TRANSFER"
        return False

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

    print 'Wait for transfer to be confirmed'
    time.sleep(10)

    res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name bar.test'
        print json.dumps(res)
        return False

    zonefile_hash = res['response']['zonefile_hash']

    # should still be registered
    if res['response']['status'] != 'registered':
        print "register not complete"
        print json.dumps(res)
        return False

    # do we have the history for the name?
    res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history",
                                       ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = "Failed to get name history for foo.test"
        print json.dumps(res)
        return False

    # valid history?
    hist = res['response']
    if len(hist.keys()) != 3:
        res['test'] = 'Failed to get update history'
        res['history'] = hist
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    # get the zonefile
    res = testlib.blockstack_REST_call(
        "GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), ses)
    if 'error' in res or res['http_status'] != 200:
        res['test'] = 'Failed to get name zonefile'
        print json.dumps(res)
        return False

    # same zonefile we put?
    if res['response']['zonefile'] != zonefile_txt:
        res['test'] = 'mismatched zonefile, expected\n{}\n'.format(
            zonefile_txt)
        print json.dumps(res)
        return False
Example #38
0
def scenario(wallets, **kw):

    global txids
    global consensuses

    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)

    testlib.next_block(**kw)
    # do a sequence of updates, every other block
    for i in xrange(0, 20):

        if (i % 2) != 0:
            update_hash = ("%02x" % (i)) * 20
            resp = testlib.blockstack_name_update("foo.test", update_hash,
                                                  wallets[3].privkey)

            txids[update_hash] = resp['transaction_hash']
            consensuses[update_hash] = testlib.get_consensus_at(
                testlib.get_current_block(**kw), **kw)

        testlib.next_block(**kw)

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

    global fail_blocks

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

    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)
    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)

    # wait for it to expire...
    for i in xrange(0, 2 * NAMESPACE_LIFETIME_MULTIPLIER + 1):
        testlib.next_block(**kw)

    # verify that operations fail
    resp = testlib.blockstack_name_update("foo.test",
                                          "11" * 20,
                                          wallets[3].privkey,
                                          safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should fail
    resp = testlib.blockstack_name_transfer("foo.test",
                                            wallets[4].addr,
                                            True,
                                            wallets[3].privkey,
                                            safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should fail
    resp = testlib.blockstack_name_renew("foo.test",
                                         wallets[3].privkey,
                                         safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should fail
    resp = testlib.blockstack_name_revoke("foo.test",
                                          wallets[3].privkey,
                                          safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))
Example #40
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 = pybitcoin.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(3)

        # getting zonefile should still work...
        resp = testlib.blockstack_cli_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)
            return False 

        if 'warning' not in resp:
            print "no non-standard warning:\n%s" % 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:
                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 )
        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(3)

    # 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(3)

    # 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 )
Example #41
0
def scenario(wallets, **kw):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    global first_name_block
    test_proxy = testlib.make_proxy()

    # make a test namespace
    resp = testlib.ysi_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.ysi_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 = ysi_client.storage.make_mutable_data_urls(
        'foo.test', use_only=['dht', 'disk'])
    zonefile = ysi_client.zonefile.make_empty_zonefile('foo.test',
                                                       wallets[4].pubkey_hex,
                                                       urls=driver_urls)
    zonefile_txt = ysi_zones.make_zone_file(zonefile,
                                            origin='foo.test',
                                            ttl=4200)

    # make a new keyfile as well
    user_profile = ysi_client.user.make_empty_user_profile()
    '''
    res = ysi_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 = ysi_client.get_zonefile_data_hash(zonefile_txt)

    resp = testlib.ysi_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.ysi_cli_sync_zonefile('foo.test',
                                        zonefile_string=zonefile_txt)
    if 'error' in res:
        print res
        return False
    '''
    # upload keyfile
    res = ysi_client.key_file.key_file_put('foo.test', keyfile_txt)
    if 'error' in res:
        print res
        return False
    '''

    rc = ysi_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.ysi_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    first_name_block = testlib.get_current_block(**kw)

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

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

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

    whois = testlib.ysi_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.ysi_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.ysi_cli_lookup('foo.test')
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)  # 694

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

    whois = testlib.ysi_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.ysi_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.ysi_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.ysi_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.ysi_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.ysi_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.ysi_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.ysi_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 = ysi_client.storage.make_mutable_data_urls(
        'foo.test', use_only=['dht', 'disk'])
    new_zonefile = ysi_client.zonefile.make_empty_zonefile(
        'foo.test', wallets[4].pubkey_hex, urls=driver_urls)
    new_zonefile_txt = ysi_zones.make_zone_file(new_zonefile,
                                                origin='foo.test',
                                                ttl=4200)

    # make a new keyfile as well
    new_user_profile = ysi_client.user.make_empty_user_profile()
    new_user_profile['new_user'] = True
    '''
    res = ysi_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 = ysi_client.get_zonefile_data_hash(new_zonefile_txt)

    rc = ysi_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.ysi_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.ysi_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)
Example #43
0
def scenario( wallets, **kw ):

    global import_block_1, import_block_2

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

    testlib.next_block( **kw )

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

    testlib.next_block( **kw )

    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 )

    testlib.next_block( **kw )

    import_block_1 = testlib.get_current_block( **kw )

    testlib.next_block( **kw )

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

    testlib.next_block( **kw )
    
    import_block_2 = testlib.get_current_block( **kw )

    testlib.next_block( **kw )

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

    testlib.next_block( **kw )

    # wait for expiration (with multipler)...
    for i in xrange(0, 10 * NAMESPACE_LIFETIME_MULTIPLIER):
        testlib.next_block( **kw )

    # re-register
    testlib.blockstack_name_preorder( "foo.test", wallets[7].privkey, wallets[8].addr )
    testlib.next_block( **kw )

    testlib.blockstack_name_register( "foo.test", wallets[7].privkey, wallets[8].addr )
    testlib.next_block( **kw )
def scenario(wallets, **kw):

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

    testlib.blockstore_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.blockstore_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

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

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

    resp = testlib.blockstore_name_revoke("foo.test", wallets[4].privkey)
    testlib.next_block(**kw)
def scenario( wallets, **kw ):

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

    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 ) # 690

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

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

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

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

    # should fail (safety checks stop it)
    resp = testlib.blockstack_name_renew( "foo.test", wallets[3].privkey, zonefile_hash='22' * 20, recipient_addr=wallets[0].addr )
    if 'error' not in resp:
        print resp
        return False

    # should succeed in being sent
    resp = testlib.blockstack_name_renew( "foo.test", wallets[3].privkey, zonefile_hash='22' * 20, recipient_addr=wallets[0].addr, safety_checks=False, tx_fee=10000 * 5 )
    if 'error' in resp:
        print resp
        return False

    # should fail to get accepted
    testlib.expect_snv_fail_at( "foo.test", testlib.get_current_block(**kw))
    testlib.next_block( **kw ) # 694

    # should NOT have been renewed 
    whois2 = testlib.blockstack_cli_whois('foo.test')
    if 'error' in whois:
        print whois
        return False

    if whois2['block_renewed_at'] != whois['block_renewed_at']:
        print 'accidentally renewed'
        print whois
        print whois2
        return False

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

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

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

    global debug

    resp = testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                                 wallets[0].privkey)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    resp = 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)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

    resp = testlib.blockstack_name_preorder("foo.test", wallets[2].privkey,
                                            wallets[3].addr)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    resp = testlib.blockstack_name_register("foo.test", wallets[2].privkey,
                                            wallets[3].addr)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True,
                                            wallets[3].privkey)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    resp = testlib.blockstack_name_transfer("foo.test", wallets[0].addr, True,
                                            wallets[4].privkey)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

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

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

    testlib.ysi_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,
        version_bits=2)
    testlib.next_block(**kw)

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

    namespace_rec = testlib.ysi_cli_get_namespace_blockchain_record("test")
    if 'error' in namespace_rec:
        print namespace_rec
        return False

    namespace_balance = testlib.get_balance(namespace_rec['address'])

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

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

    # renew/xfer/update
    res = testlib.ysi_name_renew("foo.test",
                                 wallets[3].privkey,
                                 zonefile_hash="22" * 20,
                                 recipient_addr=wallets[4].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # renew/update
    res = testlib.ysi_name_renew("foo.test",
                                 wallets[4].privkey,
                                 zonefile_hash="33" * 20)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # renew/xfer
    res = testlib.ysi_name_renew("foo.test",
                                 wallets[4].privkey,
                                 recipient_addr=wallets[1].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # renew
    res = testlib.ysi_name_renew("foo.test", wallets[1].privkey)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    new_namespace_balance = testlib.get_balance(namespace_rec['address'])
    name_rec = testlib.get_name_blockchain_record('foo.test')
    name_cost = name_rec['op_fee']

    if new_namespace_balance - namespace_balance != name_cost * 5:
        print 'address {} did not get credited'.format(
            namespace_rec['address'])
        print '{} != {} + {}'.format(new_namespace_balance, namespace_balance,
                                     name_cost * 5)
        return False
Example #48
0
def scenario(wallets, **kw):

    global fail_blocks

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

    testlib.ysi_namespace_reveal(
        "test", wallets[1].addr, 10, 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.ysi_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

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

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

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

    # can't do anything with the name for another 10 blocks
    resp = testlib.ysi_name_update("foo.test",
                                   "11" * 20,
                                   wallets[3].privkey,
                                   safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should fail
    resp = testlib.ysi_name_transfer("foo.test",
                                     wallets[4].addr,
                                     True,
                                     wallets[3].privkey,
                                     safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should fail
    resp = testlib.ysi_name_renew("foo.test",
                                  wallets[3].privkey,
                                  safety_checks=False,
                                  tx_fee=10000 * 5)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # wait for it to expire...
    for i in xrange(0, 8 * NAMESPACE_LIFETIME_MULTIPLIER):
        testlib.next_block(**kw)

    # verify that operations continue to fail (BUG IN 0.13: THIS SUCCEEDS WHEN IT SHOULD FAIL)
    resp = testlib.ysi_name_update("foo.test",
                                   "11" * 20,
                                   wallets[3].privkey,
                                   safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should fail
    resp = testlib.ysi_name_transfer("foo.test",
                                     wallets[4].addr,
                                     True,
                                     wallets[3].privkey,
                                     safety_checks=False)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # should fail
    resp = testlib.ysi_name_renew("foo.test",
                                  wallets[3].privkey,
                                  safety_checks=False,
                                  tx_fee=10000 * 5)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)
    fail_blocks.append(testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw))

    # re-preorder...
    resp = testlib.ysi_name_preorder("foo.test", wallets[4].privkey,
                                     wallets[0].addr)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # re-register
    resp = testlib.ysi_name_register("foo.test", wallets[4].privkey,
                                     wallets[0].addr)
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # warn the serialization checker that this changes behavior from 0.13
    print "BLOCKSTACK_SERIALIZATION_CHANGE_BEHAVIOR"
    sys.stdout.flush()
def scenario( wallets, **kw ):

    global datasets, zonefile_hashes, put_result, last_hash

    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 )

    # migrate profile
    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 )

    put_result = blockstack_client.put_immutable( "foo.test", "hello_world_1", datasets[0], proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    zonefile_hashes.append( put_result['immutable_data_hash'] )

    testlib.next_block( **kw )

    put_result = blockstack_client.put_immutable( "foo.test", "hello_world_2", datasets[1], proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    zonefile_hashes.append( put_result['immutable_data_hash'] )

    testlib.next_block( **kw )

    put_result = blockstack_client.put_immutable( "foo.test", "hello_world_3", datasets[2], proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    zonefile_hashes.append( put_result['immutable_data_hash'] )

    testlib.next_block( **kw )

    # should fail (name collision)
    datasets[0]['newdata'] = "asdf"
    put_result = blockstack_client.put_immutable( "foo.test", "hello_world_1", datasets[0], proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' not in put_result:
        zonefile_hashes[0] = put_result['immutable_data_hash']

    del datasets[0]['newdata']

    testlib.next_block( **kw )

    # delete everything
    for i in xrange(0, len(datasets)):
        print "delete %s" % zonefile_hashes[i]
        put_result = blockstack_client.delete_immutable( "foo.test", zonefile_hashes[i], wallet_keys=wallet_keys )
        if 'error' in put_result:
            print json.dumps(put_result, indent=4, sort_keys=True)

        testlib.next_block(**kw)

    last_hash = put_result['zonefile_hash']
def scenario(wallets, **kw):

    global datasets

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

    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)

    # migrate profile (but no data key)
    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

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

    testlib.next_block(**kw)

    # put immutable (with owner key)
    log.debug("put immutable 1 with owner key")
    testlib.blockstack_client_set_wallet("0123456789abcdef",
                                         wallet_keys['payment_privkey'],
                                         wallet_keys['owner_privkey'], None)

    res = testlib.start_api("0123456789abcdef")
    if 'error' in res:
        print 'failed to start API: {}'.format(res)
        return False

    put_result = testlib.blockstack_cli_put_immutable(
        "foo.test",
        "hello_world_1_immutable",
        json.dumps(datasets[0], sort_keys=True),
        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)

    # put immutable (with owner key)
    log.debug("put immutable 2 with owner key")
    testlib.blockstack_cli_put_immutable("foo.test",
                                         "hello_world_2_immutable",
                                         json.dumps(datasets[1],
                                                    sort_keys=True),
                                         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)

    # put mutable (with owner key)
    log.debug("put mutable 1 with owner key")
    put_result = testlib.blockstack_cli_put_mutable(
        "foo.test",
        "hello_world_1_mutable",
        json.dumps(datasets[0], sort_keys=True),
        password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)
        return False

    # put mutable (with owner key)
    log.debug("put mutable 2 with owner key")
    put_result = testlib.blockstack_cli_put_mutable(
        "foo.test",
        "hello_world_2_mutable",
        json.dumps(datasets[1], sort_keys=True),
        password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    # add data signing key
    res = blockstack_client.set_data_pubkey("foo.test",
                                            wallets[4].pubkey_hex,
                                            wallet_keys=wallet_keys,
                                            proxy=test_proxy)
    if 'error' in res:
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    testlib.expect_atlas_zonefile(res['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)

    # put immutable (with new key)
    log.debug("put immutable with new key")

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

    res = testlib.start_api("0123456789abcdef")
    if 'error' in res:
        print 'failed to start API: {}'.format(res)
        return False

    # put immutable
    put_result = testlib.blockstack_cli_put_immutable(
        "foo.test",
        "hello_world_3_immutable",
        json.dumps(datasets[2], sort_keys=True),
        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)

    # put mutable (with new key)
    log.debug("put mutable with new key")
    put_result = testlib.blockstack_cli_put_mutable(
        "foo.test",
        "hello_world_3_mutable",
        json.dumps(datasets[2], sort_keys=True),
        password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    # delete immutable (new key)
    log.debug("delete immutable with new key")
    result = testlib.blockstack_cli_delete_immutable(
        "foo.test", "hello_world_1_immutable", password='******')
    if 'error' in result:
        print json.dumps(result, indent=4, sort_keys=True)
        return False

    testlib.expect_atlas_zonefile(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)

    # delete mutable (new key)
    log.debug("delete mutable with new key")
    result = testlib.blockstack_cli_delete_mutable("foo.test",
                                                   "hello_world_1_mutable",
                                                   password='******')
    if 'error' in result:
        print json.dumps(result, indent=4, sort_keys=True)
        return False

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

    global zonefile_hash

    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[0].privkey )
    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, 12):
        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(15)

    # wait for the register to get confirmed 
    for i in xrange(0, 12):
        # warn the serialization checker that this changes behavior from 0.13
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()
        
        testlib.next_block( **kw )

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

    # wait for update to get confirmed 
    for i in xrange(0, 12):
        # warn the serialization checker that this changes behavior from 0.13
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()
        
        testlib.next_block( **kw )

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

    # transfer to a new address 
    resp = testlib.blockstack_cli_transfer( "foo.test", wallets[4].addr, "0123456789abcdef" )

    if 'error' in resp:
        print >> sys.stderr, "transfer error: %s" % resp['error']
        return False

    # wait for it to go through 
    for i in xrange(0, 12):
        # warn the serialization checker that this changes behavior from 0.13
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()

        testlib.next_block( **kw )

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

    testlib.next_block(**kw)
Example #52
0
def scenario(wallets, **kw):

    zonefile_batches = []

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

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

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

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

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

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

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

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

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

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

    # send all zonefiles at once, but go in reverse order.
    # kick off the indexer at each batch
    for zfbatch in reversed(zonefile_batches):
        for name in zfbatch:
            assert testlib.blockstack_put_zonefile(zfbatch[name])

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

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

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

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

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

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

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

    testlib.ysi_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.ysi_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)

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

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

    testlib.ysi_name_update("foo.test", "11" * 20, wallets[3].privkey)
    testlib.next_block(**kw)

    testlib.ysi_name_renew("foo.test", wallets[3].privkey)
    testlib.next_block(**kw)
def scenario( wallets, **kw ):

    global wallet_keys, wallet_keys_2, key_names, 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, payment_privkey=wallets[5].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 

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

    testlib.next_block( **kw )

    data_pk = wallets[4].privkey
    data_pub = wallets[4].pubkey_hex

    res = blockstack_client.create_app_account("foo.test", "serviceFoo", "serviceFooID", "foo://bar.com", ["disk"], data_pub, proxy=test_proxy, wallet_keys=wallet_keys )
    if 'error' in res:
        res['test'] = 'Failed to create foo.test account'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    
    # put some data into the account
    res = blockstack_client.put_app_data( "foo.test", "serviceFoo", "serviceFooID", "foo_data", "foo_payload", data_pk, proxy=test_proxy )
    if 'error' in res:
        res['test'] = 'Failed to put app data'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return
    
    # put some data to delete into the account
    res = blockstack_client.put_app_data( "foo.test", "serviceFoo", "serviceFooID", "foo_data_delete", "foo_payload_delete", data_pk, proxy=test_proxy )
    if 'error' in res:
        res['test'] = 'Failed to put app data'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

    res = blockstack_client.delete_app_data( "foo.test", "serviceFoo", "serviceFooID", "foo_data_delete", data_pk, proxy=test_proxy )
    if 'error' in res:
        res['test'] = 'Failed to put app data'
        print json.dumps(res, indent=4, sort_keys=True)
        error = True
        return

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

    global datasets, put_result, legacy_profile, data_history_1, data_history_2, data_history_3

    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)

    # empty data
    testlib.blockstack_name_update("foo.test", "00" * 20, wallets[3].privkey)
    data_history_1.append("missing zonefile")
    data_history_2.append("missing zonefile")
    data_history_3.append("missing zonefile")

    testlib.next_block(**kw)

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

    result = testlib.blockstack_name_update("foo.test", legacy_hash,
                                            wallets[3].privkey)
    data_history_1.append("missing zonefile")
    data_history_2.append("missing zonefile")
    data_history_3.append("missing zonefile")
    testlib.next_block(**kw)

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

    # put immutable data
    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)

    # migrate profile
    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)
    data_history_1.append("data not defined")
    data_history_2.append("data not defined")
    data_history_3.append("data not defined")

    put_result = blockstack_client.put_immutable("foo.test",
                                                 "hello_world_1",
                                                 datasets[0],
                                                 proxy=test_proxy,
                                                 wallet_keys=wallet_keys)
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    data_history_1.append(put_result['immutable_data_hash'])
    data_history_2.append("data not defined")
    data_history_3.append("data not defined")

    testlib.next_block(**kw)

    put_result = blockstack_client.put_immutable("foo.test",
                                                 "hello_world_2",
                                                 datasets[1],
                                                 proxy=test_proxy,
                                                 wallet_keys=wallet_keys)
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    data_history_1.append(data_history_1[-1])
    data_history_2.append(put_result['immutable_data_hash'])
    data_history_3.append("data not defined")

    testlib.next_block(**kw)

    put_result = blockstack_client.put_immutable("foo.test",
                                                 "hello_world_3",
                                                 datasets[2],
                                                 proxy=test_proxy,
                                                 wallet_keys=wallet_keys)
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    data_history_1.append(data_history_1[-1])
    data_history_2.append(data_history_2[-1])
    data_history_3.append(put_result['immutable_data_hash'])
    testlib.next_block(**kw)

    # overwrite
    datasets[0]['newdata'] = "asdf"
    put_result = blockstack_client.put_immutable("foo.test",
                                                 "hello_world_3",
                                                 datasets[0],
                                                 proxy=test_proxy,
                                                 wallet_keys=wallet_keys)
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    data_history_1.append(data_history_1[-1])
    data_history_2.append(data_history_2[-1])
    data_history_3.append(put_result['immutable_data_hash'])

    del datasets[0]['newdata']

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

    global zonefile_hash

    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 )
    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, 12):
        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, 12):
        # warn the serialization checker that this changes behavior from 0.13
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()
        
        testlib.next_block( **kw )

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

    # wait for initial update to get confirmed 
    for i in xrange(0, 12):
        # warn the serialization checker that this changes behavior from 0.13
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()
        
        testlib.next_block( **kw )

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

    # what's the name's renewal block?
    proxy = testlib.make_proxy()
    res = blockstack_client.get_name_blockchain_record( "foo.test", proxy=proxy )
    if 'error' in res:
        print >> sys.stderr, json.dumps(res, indent=4, sort_keys=True)
        return False
    
    old_expire_block = res['expire_block']

    # send an update, changing the zonefile
    data_pubkey = wallet['data_pubkey']
    zonefile = blockstack_client.zonefile.make_empty_zonefile( "foo.test", data_pubkey )
    blockstack_client.user.put_immutable_data_zonefile( zonefile, "testdata", blockstack_client.get_data_hash("testdata"), data_url="file:///testdata")
    zonefile_json = json.dumps(zonefile)

    resp = testlib.blockstack_cli_update( "foo.test", zonefile_json, "0123456789abcdef" )
    
    if 'error' in resp:
        print >> sys.stderr, "update error: %s" % resp['error']
        return False

    zonefile_hash = resp['zonefile_hash']
    
    # wait for it to go through 
    for i in xrange(0, 12):
        # warn the serialization checker that this changes behavior from 0.13
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()
        
        testlib.next_block( **kw )

    print >> sys.stderr, "Waiting 10 seconds for the backend to acknowedge the update"
    time.sleep(10)
    # wait for it to go through 
    for i in xrange(0, 12):
        # warn the serialization checker that this changes behavior from 0.13
        print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
        sys.stdout.flush()
        
        testlib.next_block( **kw )

    # revoke it 
    resp = testlib.blockstack_cli_revoke( "foo.test", "0123456789abcdef" )
    if 'error' in resp:
        print >> sys.stderr, "Revoke request failed:\n%s" % json.dumps(resp, indent=4, sort_keys=True)
        return False

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

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

    global datasets, immutable_data_hashes, put_result, last_hash

    wallet = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, None )
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy( test_proxy )
    wallet_keys = wallet

    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 )

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

    # tell serialization-checker that value_hash can be ignored here
    print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash"
    sys.stdout.flush()
    
    testlib.next_block( **kw )
    
    put_result = testlib.blockstack_cli_put_immutable("foo.test", "hello_world_1", json.dumps(datasets[0], sort_keys=True), password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    testlib.expect_atlas_zonefile(put_result['zonefile_hash'])
    immutable_data_hashes.append( put_result['immutable_data_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)

    put_result = testlib.blockstack_cli_put_immutable("foo.test", "hello_world_2", json.dumps(datasets[1], sort_keys=True), password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    testlib.expect_atlas_zonefile(put_result['zonefile_hash'])
    immutable_data_hashes.append( put_result['immutable_data_hash'] )

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

    put_result = testlib.blockstack_cli_put_immutable("foo.test", "hello_world_3", json.dumps(datasets[2], sort_keys=True), password='******')
    if 'error' in put_result:
        print json.dumps(put_result, indent=4, sort_keys=True)

    testlib.expect_atlas_zonefile(put_result['zonefile_hash'])
    immutable_data_hashes.append( put_result['immutable_data_hash'] )
    last_hash = put_result['zonefile_hash']

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

    # should succeed (name collision)
    datasets[0][u'newdata'] = u"asdf"
    put_result = testlib.blockstack_cli_put_immutable("foo.test", "hello_world_1", json.dumps(datasets[0], sort_keys=True), password='******')
    if 'error' not in put_result:
        immutable_data_hashes[0] = put_result['immutable_data_hash']
    else:
        print json.dumps(put_result, indent=4, sort_keys=True )

    testlib.expect_atlas_zonefile(put_result['zonefile_hash'])
    last_hash = put_result['zonefile_hash']

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

    global debug

    resp = testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    resp = 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 )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

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

    testlib.next_block( **kw )

    resp = testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )
    
    resp = testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr )
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    resp = testlib.blockstack_name_transfer( "foo.test", wallets[4].addr, True, wallets[3].privkey ) 
    if debug or 'error' in resp:
        print json.dumps( resp, indent=4 )

    testlib.next_block( **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,
        version_bits=2)
    testlib.next_block(**kw)

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

    namespace_rec = testlib.blockstack_cli_get_namespace_blockchain_record(
        "test")
    if 'error' in namespace_rec:
        print namespace_rec
        return False

    namespace_balance = testlib.get_balance(namespace_rec['address'])
    burn_balance = testlib.get_balance(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)

    res = testlib.blockstack_name_preorder("foo.test", wallets[2].privkey,
                                           wallets[3].addr)  # +name_cost
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    res = testlib.blockstack_name_register("foo.test", wallets[2].privkey,
                                           wallets[3].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    new_namespace_balance = testlib.get_balance(namespace_rec['address'])
    name_rec = testlib.get_name_blockchain_record('foo.test')
    name_cost = name_rec['op_fee']

    if new_namespace_balance - namespace_balance != name_cost:
        print 'address {} did not get credited'.format(
            namespace_rec['address'])
        print '{} != {} + {}'.format(new_namespace_balance, namespace_balance,
                                     name_cost)
        return False

    # should send to null burn address
    res = testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey,
                                           wallets[3].addr)
    if 'error' in res:
        print res
        return False

    # preorder should send to the null burn address now.
    # try forcing it to the namespace burn address, to verify that it fails
    res = testlib.blockstack_name_preorder("foo_fail.test",
                                           wallets[2].privkey,
                                           wallets[3].addr,
                                           burn_addr=namespace_rec['address'],
                                           expect_fail=True)
    if 'error' not in res:
        print res
        return False

    res = testlib.blockstack_name_preorder("foo_fail.test",
                                           wallets[2].privkey,
                                           wallets[3].addr,
                                           burn_addr=namespace_rec['address'],
                                           price={
                                               'units': 'BTC',
                                               'amount': name_cost
                                           },
                                           safety_checks=False,
                                           tx_fee=10000 * 5)  # +name_cost
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should be rejected
    res = testlib.blockstack_name_register("foo_fail.test",
                                           wallets[2].privkey,
                                           wallets[3].addr,
                                           safety_checks=False)
    if 'error' in res:
        print res
        return False

    # should be accepted
    res = testlib.blockstack_name_register("foo2.test", wallets[2].privkey,
                                           wallets[3].addr)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo_fail.test',
                               testlib.get_current_block(**kw))

    # should have been rejected due to wrong burn address
    whois = testlib.blockstack_cli_whois('foo_fail.test')
    if 'error' not in whois:
        print whois
        return False

    new_burn_balance = testlib.get_balance(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    new_namespace_balance = testlib.get_balance(namespace_rec['address'])
    name_rec_2 = testlib.get_name_blockchain_record('foo2.test')
    name_cost_2 = name_rec_2['op_fee']

    # namespace should NOT have gotten the fee for foo_fail.  It should only have gotten it for foo.test
    if new_namespace_balance - namespace_balance < 2 * name_cost or new_namespace_balance - namespace_balance >= 3 * name_cost:
        print 'address {} got credited after fee capture period'.format(
            namespace_rec['address'])
        print '{} != {} + 2*{}'.format(new_namespace_balance,
                                       namespace_balance, name_cost)
        return False

    # burn address should have received the fee for the second name
    if new_burn_balance - name_cost_2 != burn_balance:
        print 'null burn address did not get credited'
        print '{} != {} + {}'.format(new_burn_balance, burn_balance,
                                     name_cost_2)
        return False