示例#1
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("foo.test",
                                     wallets[2].privkey,
                                     wallets[3].addr,
                                     wallet=wallets[3])
    testlib.next_block(**kw)

    # should fail, since multisig isn't enabled yet
    testlib.blockstack_name_register("foo.test",
                                     wallets[2].privkey,
                                     wallets[3].addr,
                                     wallet=wallets[3])
    testlib.next_block(**kw)

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

    # foo.test should be preordered (in both 0.13 and 0.14)
    state_engine = testlib.get_state_engine()
    preorder = state_engine.get_name_preorder(
        "foo.test", virtualchain.make_payment_script(wallets[2].addr),
        wallets[3].addr)
    if preorder is None:
        print "foo.test not preordered"
        return False

    # epoch changes here

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

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

    testlib.blockstack_name_register("bar.test", wallets[3].privkey,
                                     wallets[4].addr)
    testlib.next_block(**kw)
示例#2
0
def scenario(wallets, **kw):
    global pk

    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)

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks(
        'foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name(
        'foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price,
                                   wallets[0].privkey)
    testlib.send_funds(
        wallets[0].privkey, btc_price - 5500 - 1,
        addr)  # deliberately insufficient funds for ordering the name in BTC
    testlib.next_block(**kw)

    # preorder/register using Stacks
    testlib.blockstack_name_preorder("foo.test",
                                     pk,
                                     wallets[3].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.next_block(**kw)

    testlib.send_funds(
        wallets[0].privkey, btc_price - 5500 - 1,
        addr)  # deliberately insufficient funds for ordering the name in BTC
    testlib.blockstack_name_register("foo.test", pk, wallets[3].addr)
    testlib.next_block(**kw)
示例#3
0
def scenario( wallets, **kw ):
    global pk, pk2

    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=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR)
    testlib.next_block( **kw )

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print 'price of {} in BTC is {}'.format('foo.test', btc_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price + 2, wallets[0].privkey)
    testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price + 1, wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, 3*btc_price, addr)
    testlib.send_funds(wallets[0].privkey, 3*btc_price, addr2)
    testlib.next_block(**kw)

    # preorder/register using Stacks
    testlib.blockstack_name_preorder( "foo.test", pk, addr2)
    testlib.blockstack_name_preorder( "bar.test", pk2, addr)
    testlib.next_block( **kw )

    testlib.blockstack_name_register( "foo.test", pk, addr2 )
    testlib.blockstack_name_register( "bar.test", pk2, addr )
    testlib.next_block( **kw )
    testlib.next_block( **kw )
    testlib.next_block( **kw )
    testlib.next_block( **kw ) # end of pay to namespace creator

    # renew using more stacks than we have (should fail)
    # bar.test should succeed
    testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price + 2}, expect_fail=True, safety_checks=False)
    testlib.blockstack_name_renew('bar.test', pk, price={'units': 'STACKS', 'amount': stacks_price + 1})
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))
def scenario( wallets, **kw ):
    global pk, pk2

    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=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR)
    testlib.next_block( **kw )

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price + 1, wallets[0].privkey)
    testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price + 1, wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr)  # deliberately insufficient funds for ordering the name in BTC
    testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr2)  # deliberately insufficient funds for ordering the name in BTC
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)
    testlib.next_block(**kw)    # move beyond pay-to-creator requirement

    # preorder/register using Stacks, but overpay (foo.test fails, bar.test succeeds)
    testlib.blockstack_name_preorder( "foo.test", pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price + 2}, expect_fail=True, safety_checks=False)
    testlib.blockstack_name_preorder( "bar.test", pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price + 1})
    testlib.next_block( **kw )
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))

    testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr)  # deliberately insufficient funds for ordering the name in BTC
    testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr2)  # deliberately insufficient funds for ordering the name in BTC
    testlib.blockstack_name_register( "foo.test", pk, wallets[3].addr ) # should fail
    testlib.blockstack_name_register( "bar.test", pk2, wallets[3].addr ) # should succeed
    testlib.next_block( **kw )
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_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, wallet=wallets[3] )
    testlib.next_block( **kw )

    # should fail, since multisig isn't enabled yet
    testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3] )
    testlib.next_block( **kw )
    
    testlib.expect_snv_fail_at( "foo.test", testlib.get_current_block(**kw))

    # foo.test should be preordered (in both 0.13 and 0.14)
    state_engine = testlib.get_state_engine()
    preorder = state_engine.get_name_preorder("foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr)
    if preorder is None:
        print "foo.test not preordered"
        return False

    # epoch changes here

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

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

    testlib.blockstack_name_register( "bar.test", wallets[3].privkey, wallets[4].addr )
    testlib.next_block( **kw )
def scenario( wallets, **kw ):
    global pk, pk2

    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,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR)
    testlib.next_block( **kw )

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print 'price of {} in BTC is {}'.format('foo.test', btc_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", 8*stacks_price, wallets[0].privkey)
    testlib.blockstack_send_tokens(addr2, "STACKS", 8*stacks_price, wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, 8*btc_price, addr)
    testlib.send_funds(wallets[0].privkey, 8*btc_price, addr2)
    testlib.next_block(**kw)

    def _tx_pay_btc(txhex, privk, burn_price, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS):
        tx = virtualchain.btc_tx_deserialize(txhex)

        # up the burn amount 
        tx['outs'][3]['script'] = virtualchain.btc_make_payment_script(burn_addr)
        tx['outs'][3]['value'] = burn_price

        tx['outs'][4]['value'] -= burn_price

        # re-sign 
        for i in tx['ins']:
            i['script'] = ''

        txhex = virtualchain.btc_tx_serialize(tx)
        _addr = virtualchain.address_reencode(virtualchain.get_privkey_address(privk))
        txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(privk, testlib.get_utxos(_addr), txhex)

        # re-sign the last output with the payment key
        tx_signed = virtualchain.btc_tx_deserialize(txhex_signed)
        tx_signed['ins'][-1]['script'] = ''
        txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(testlib.get_default_payment_wallet().privkey, testlib.get_utxos(testlib.get_default_payment_wallet().addr), virtualchain.btc_tx_serialize(tx_signed))
        
        print txhex_signed

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

    # preorder/register using BTC
    testlib.blockstack_name_preorder( "foo.test", pk, addr2 )
    testlib.blockstack_name_preorder( "bar.test", pk, addr2 )
    testlib.blockstack_name_preorder( "baz.test", pk, addr2 )
    testlib.blockstack_name_preorder( "goo.test", pk, addr2 )
    testlib.next_block( **kw )

    testlib.blockstack_name_register( "foo.test", pk, addr2 )
    testlib.blockstack_name_register( "bar.test", pk, addr2 )
    testlib.blockstack_name_register( "baz.test", pk, addr2 )
    testlib.blockstack_name_register( "goo.test", pk, addr2 )
    testlib.next_block( **kw )

    # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active)
    res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price)

    # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens)
    res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr)

    # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active).  Also underpay BTC
    res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1)

    # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens).  Also underpay BTC
    res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1, wallets[0].addr)
    testlib.next_block(**kw)

    # all should have failed
    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0

    # try to renew using Stacks (won't work, since we're still collecting fees in BTC and need to send to the namespace creator's address)
    res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price)
    
    res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr)

    # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active).  Also underpay BTC
    res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1)

    # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens).  Also underpay BTC
    res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1, wallets[0].addr)
    testlib.next_block(**kw)

    # all should have failed
    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0

    # try to renew using Stacks, now that pay-to-creator has expired
    res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, expect_success=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price)

    # should fail--can't mix stacks and btc
    res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price)

    # should succeed--paid in stacks
    res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, expect_success=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1)

    # should fail--wrong burn address
    res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True)
    res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr)
    testlib.next_block(**kw)

    # only two should have succeeded
    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 2
def scenario(wallets, **kw):

    global debug

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = name_rec['consensus_hash']

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False
def scenario(wallets, **kw):
    global pk

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

    # all names below are the same price
    testlib.blockstack_namespace_reveal(
        "test",
        wallets[1].addr,
        52595,
        250,
        4, [6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        1,
        1,
        wallets[0].privkey,
        version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR)
    testlib.next_block(**kw)

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks(
        'foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name(
        'foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price * 5,
                                   wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, btc_price * 10, addr)
    testlib.next_block(**kw)

    # preorder/register using Stacks (preorders should fail since we're using the wrong burn address for tokens)
    testlib.blockstack_name_preorder("foo.test",
                                     pk,
                                     wallets[3].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     },
                                     burn_addr=wallets[0].addr,
                                     safety_checks=False,
                                     expect_fail=True)
    testlib.blockstack_name_preorder("bar.test",
                                     pk,
                                     wallets[3].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price - 1
                                     },
                                     burn_addr=wallets[0].addr,
                                     safety_checks=False,
                                     expect_fail=True)
    testlib.next_block(**kw)

    op_info = virtualchain.lib.indexer.StateEngine.get_block_statistics(
        testlib.get_current_block(**kw))
    if op_info['num_processed_ops'] > 0:
        print 'handled ops this block'
        print op_info
        return False

    # preorder/register using Stacks (preorders should be accepted, but bar2 will fail to register)
    testlib.blockstack_name_preorder(
        "foo2.test",
        pk,
        wallets[2].addr,
        price={
            'units': 'STACKS',
            'amount': stacks_price
        },
        burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS,
        safety_checks=False)
    testlib.blockstack_name_preorder(
        "bar2.test",
        pk,
        wallets[2].addr,
        price={
            'units': 'STACKS',
            'amount': stacks_price - 1
        },
        burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS,
        safety_checks=False)
    testlib.next_block(**kw)

    # preorder/register using Stacks (preorders should succeed now, but bar3.test will fail to register since we're not paying enough stacks)
    testlib.blockstack_name_register(
        "bar2.test", pk, wallets[2].addr
    )  # should fail at this point, since the preorder sent to the wrong burn address
    testlib.blockstack_name_register(
        "foo2.test", pk, wallets[2].addr
    )  # should fail at this point, since the preorder sent to the wrong burn address

    testlib.blockstack_name_preorder(
        "foo3.test",
        pk,
        wallets[2].addr,
        price={
            'units': 'STACKS',
            'amount': stacks_price
        },
        burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS,
        safety_checks=False)
    testlib.blockstack_name_preorder(
        "bar3.test",
        pk,
        wallets[2].addr,
        price={
            'units': 'STACKS',
            'amount': stacks_price - 1
        },
        burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS,
        safety_checks=False)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('bar2.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('foo2.test', testlib.get_current_block(**kw))

    # tokens are not yet accepted
    if testlib.get_state_engine().get_name('bar2.test'):
        print 'registered bar2.test'
        return False

    if testlib.get_state_engine().get_name('foo2.test'):
        print 'registered foo2.test'
        return False

    # preorder/register using Stacks (should succeed without safety checks or overrides)
    testlib.blockstack_name_preorder("foo.test",
                                     pk,
                                     wallets[2].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.next_block(**kw)

    testlib.blockstack_name_register("foo.test", pk,
                                     wallets[2].addr)  # should succeed
    testlib.blockstack_name_register("bar2.test", pk,
                                     wallets[2].addr)  # should fail
    testlib.blockstack_name_register("foo2.test", pk,
                                     wallets[2].addr)  # should succeed
    testlib.blockstack_name_register("bar3.test", pk,
                                     wallets[2].addr)  # should fail
    testlib.blockstack_name_register("foo3.test", pk,
                                     wallets[2].addr)  # should succeed
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('bar2.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('bar3.test', testlib.get_current_block(**kw))

    if testlib.get_state_engine().get_name('bar2.test'):
        print 'registered bar2.test'
        return False

    if testlib.get_state_engine().get_name('bar3.test'):
        print 'registered bar3.test'
        return False
示例#9
0
def scenario(wallets, **kw):

    global import_block

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

    testlib.next_block(**kw)

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

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

    testlib.next_block(**kw)

    import_block = testlib.get_current_block(**kw)

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_name_update("foo.test", "22" * 20,
                                          wallets[4].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = name_rec['consensus_hash']

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

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

    # consensus hash must be None
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] is not None:
        print 'wrong consensus hash: expected {}'.format(None)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_name_transfer("foo.test", wallets[0].addr, True,
                                            wallets[8].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_name_transfer("foo.test", wallets[8].addr, True,
                                            wallets[0].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_name_update("foo.test", "33" * 20,
                                          wallets[8].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False
示例#10
0
def scenario(wallets, **kw):
    global pk, pk2

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    addr2 = virtualchain.address_reencode(
        virtualchain.get_privkey_address(pk2))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks(
        'baz', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name(
        'baz', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('baz.test', stacks_price)
    print 'price of {} in BTC is {}'.format('baz.test', btc_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price,
                                   wallets[0].privkey)
    testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price * 2,
                                   wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, 10 * btc_price, addr)
    testlib.send_funds(wallets[0].privkey, 10 * btc_price, addr2)
    testlib.next_block(**kw)

    # preorder/register using Stacks
    testlib.blockstack_name_preorder("baz.test",
                                     wallets[2].privkey,
                                     addr2,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.blockstack_name_preorder("goo.test",
                                     wallets[2].privkey,
                                     addr2,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.blockstack_name_preorder("nop.test",
                                     wallets[2].privkey,
                                     addr2,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.next_block(**kw)

    testlib.blockstack_name_register("baz.test", wallets[2].privkey, addr2)
    testlib.blockstack_name_register("goo.test", wallets[2].privkey, addr2)
    testlib.blockstack_name_register("nop.test", wallets[2].privkey, addr2)
    testlib.next_block(**kw)

    balance_before = testlib.get_addr_balances(addr2)[addr2]['STACKS']

    # pay with both Stacks and Bitcoin
    # should favor Stacks payment over Bitcoin payment if we pay enough stacks.
    # Stacks should have been burned, as well as BTC.
    res = testlib.blockstack_name_renew('baz.test',
                                        pk2,
                                        price={
                                            'units': 'STACKS',
                                            'amount': stacks_price
                                        },
                                        tx_only=True,
                                        expect_success=True)
    txhex = res['transaction']
    tx = virtualchain.btc_tx_deserialize(txhex)

    # up the burn amount
    btc_price = blockstack.lib.scripts.price_name(
        'baz', namespace, testlib.get_current_block(**kw))
    tx['outs'][3]['script'] = virtualchain.btc_make_payment_script(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    tx['outs'][3]['value'] = btc_price

    tx['outs'][4]['value'] -= btc_price

    # re-sign
    for i in tx['ins']:
        i['script'] = ''

    txhex = virtualchain.btc_tx_serialize(tx)
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        pk2, testlib.get_utxos(addr2), txhex)

    # re-sign the last output with the payment key
    tx_signed = virtualchain.btc_tx_deserialize(txhex_signed)
    tx_signed['ins'][-1]['script'] = ''
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        testlib.get_default_payment_wallet().privkey,
        testlib.get_utxos(testlib.get_default_payment_wallet().addr),
        virtualchain.btc_tx_serialize(tx_signed))

    print txhex_signed

    res = testlib.broadcast_transaction(txhex_signed)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should have paid in Stacks
    balance_after = testlib.get_addr_balances(addr2)[addr2]['STACKS']
    if balance_after != balance_before - stacks_price:
        print 'baz.test cost {}'.format(balance_before - balance_after)
        return False

    balance_before = testlib.get_addr_balances(addr2)[addr2]['STACKS']

    # try to renew a name where we pay not enough stacks, but enough bitcoin.
    # should be rejected.
    res = testlib.blockstack_name_renew('goo.test',
                                        pk2,
                                        price={
                                            'units': 'STACKS',
                                            'amount': stacks_price - 1
                                        },
                                        tx_only=True)
    txhex = res['transaction']
    tx = virtualchain.btc_tx_deserialize(txhex)

    # up the burn amount to the name price
    btc_price = blockstack.lib.scripts.price_name(
        'goo', namespace, testlib.get_current_block(**kw))
    tx['outs'][3]['script'] = virtualchain.btc_make_payment_script(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    tx['outs'][3]['value'] = btc_price

    tx['outs'][4]['value'] -= btc_price

    # re-sign
    for i in tx['ins']:
        i['script'] = ''

    txhex = virtualchain.btc_tx_serialize(tx)
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        pk2, testlib.get_utxos(addr2), txhex)

    # re-sign the last output with the payment key
    tx_signed = virtualchain.btc_tx_deserialize(txhex_signed)
    tx_signed['ins'][-1]['script'] = ''
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        testlib.get_default_payment_wallet().privkey,
        testlib.get_utxos(testlib.get_default_payment_wallet().addr),
        virtualchain.btc_tx_serialize(tx_signed))

    print txhex_signed

    res = testlib.broadcast_transaction(txhex_signed)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should NOT have paid in Stacks
    balance_after = testlib.get_addr_balances(addr2)[addr2]['STACKS']
    if balance_after != balance_before:
        print 'goo.test paid {}'.format(balance_before - balance_after)
        return False

    balance_before = testlib.get_addr_balances(addr2)[addr2]['STACKS']

    # underpay in both Stacks and Bitcoin.
    # only bitcoin will be burned; transaction will not be processed
    res = testlib.blockstack_name_renew('nop.test',
                                        pk2,
                                        price={
                                            'units': 'STACKS',
                                            'amount': stacks_price - 1
                                        },
                                        tx_only=True)
    txhex = res['transaction']
    tx = virtualchain.btc_tx_deserialize(txhex)

    # up the burn amount to the name price
    btc_price = blockstack.lib.scripts.price_name(
        'goo', namespace, testlib.get_current_block(**kw))
    tx['outs'][3]['script'] = virtualchain.btc_make_payment_script(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    tx['outs'][3]['value'] = btc_price - 1

    tx['outs'][4]['value'] -= btc_price + 1

    # re-sign
    for i in tx['ins']:
        i['script'] = ''

    txhex = virtualchain.btc_tx_serialize(tx)
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        pk2, testlib.get_utxos(addr2), txhex)

    # re-sign the last output with the payment key
    tx_signed = virtualchain.btc_tx_deserialize(txhex_signed)
    tx_signed['ins'][-1]['script'] = ''
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        testlib.get_default_payment_wallet().privkey,
        testlib.get_utxos(testlib.get_default_payment_wallet().addr),
        virtualchain.btc_tx_serialize(tx_signed))

    print txhex_signed

    res = testlib.broadcast_transaction(txhex_signed)
    if 'error' in res:
        print res
        return False

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

    balance_after = testlib.get_addr_balances(addr2)[addr2]['STACKS']
    if balance_after != balance_before:
        print 'paid {} for nop.test'.format(balance_before - balance_after)
        return False
示例#11
0
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_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)

    # consensus hash should be None
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] is not None:
        print 'wrong consensus hash: expected None'
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    # ping-ping a bit... 3 --> 4 --> 5 --> 4 --> 5 --> 4
    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)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_TRANSFER
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = name_rec['consensus_hash']

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

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

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)

    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)

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)

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

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)

    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)

    testlib.next_block(**kw)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'wrong consensus hash: expected {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1))
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False

    update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)

    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)

    # consensus hash should be the one from the last NAME_UPDATE
    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test')
    if name_rec['consensus_hash'] != update_ch:
        print 'wrong consensus hash: expected {}'.format(update_ch)
        print json.dumps(name_rec, indent=4, sort_keys=True)
        return False
示例#12
0
def scenario(wallets, **kw):
    global pk

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

    testlib.blockstack_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,
        10,
        wallets[0].privkey,
        version_bits=1)
    testlib.blockstack_namespace_reveal(
        "test2",
        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.blockstack_namespace_reveal(
        "test3",
        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=3)
    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test1", wallets[1].privkey)
    testlib.blockstack_namespace_ready("test2", wallets[1].privkey)
    testlib.blockstack_namespace_ready("test3", wallets[1].privkey)
    testlib.next_block(**kw)

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test1')
    stacks_price = blockstack.lib.scripts.price_name_stacks(
        'foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name(
        'foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", 3 * stacks_price,
                                   wallets[0].privkey)
    testlib.send_funds(
        wallets[0].privkey, btc_price - 5500 - 1,
        addr)  # deliberately insufficient funds for ordering the name in BTC
    testlib.next_block(**kw)

    wallet_before_burn = testlib.get_balance(wallets[0].addr)

    # preorder/register in all three namespaces
    testlib.blockstack_name_preorder("foo.test1",
                                     pk,
                                     wallets[3].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.blockstack_name_preorder("bar.test1", wallets[1].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo.test2", wallets[1].privkey,
                                     wallets[3].addr)
    testlib.blockstack_name_preorder("foo.test3", wallets[1].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)

    wallet_after_burn = testlib.get_balance(wallets[0].addr)
    if wallet_after_burn - wallet_before_burn != btc_price:
        print 'foo.test2 did not pay {} to {} (but paid {})'.format(
            btc_price, wallets[0].addr, wallet_after_burn - wallet_before_burn)
        return False

    testlib.send_funds(
        wallets[0].privkey, btc_price - 5500 - 1,
        addr)  # deliberately insufficient funds for ordering the name in BTC
    testlib.blockstack_name_register("foo.test1", pk,
                                     wallets[3].addr)  # paid in Stacks
    testlib.blockstack_name_register("bar.test1", wallets[1].privkey,
                                     wallets[3].addr)  # paid in BTC
    testlib.blockstack_name_register(
        "foo.test2", wallets[1].privkey,
        wallets[3].addr)  # paid in BTC to wallets[0]
    testlib.blockstack_name_register("foo.test3", wallets[1].privkey,
                                     wallets[3].addr)  # paid in Stacks
    testlib.next_block(**kw)

    testlib.send_funds(
        wallets[0].privkey, btc_price - 5500 - 1,
        addr)  # deliberately insufficient funds for ordering the name in BTC

    wallet_before_burn = testlib.get_balance(wallets[0].addr)
    testlib.blockstack_name_renew("foo.test1",
                                  wallets[3].privkey,
                                  price={
                                      'units': 'STACKS',
                                      'amount': stacks_price
                                  })  # paid in Stacks
    testlib.blockstack_name_renew("bar.test1",
                                  wallets[3].privkey)  # paid in BTC
    testlib.blockstack_name_renew(
        "foo.test2", wallets[3].privkey)  # paid in BTC to wallets[0]
    testlib.blockstack_name_renew("foo.test3",
                                  wallets[3].privkey)  # paid in Stacks
    testlib.next_block(**kw)

    wallet_after_burn = testlib.get_balance(wallets[0].addr)
    if wallet_after_burn - wallet_before_burn != btc_price:
        print 'foo.test2 did not pay {} to {} (but paid {})'.format(
            btc_price, wallets[0].addr, wallet_after_burn - wallet_before_burn)
        return False

    # should all fail--wrong burn addresses
    testlib.blockstack_name_renew("foo.test1",
                                  pk,
                                  price={
                                      'units': 'STACKS',
                                      'amount': stacks_price
                                  },
                                  burn_addr=wallets[0].addr,
                                  safety_checks=False,
                                  expect_fail=True)
    testlib.blockstack_name_renew("bar.test1",
                                  wallets[3].privkey,
                                  burn_addr=wallets[0].addr,
                                  safety_checks=False,
                                  expect_fail=True)
    testlib.blockstack_name_renew("foo.test2",
                                  wallets[3].privkey,
                                  burn_addr=wallets[1].addr,
                                  safety_checks=False,
                                  expect_fail=True)
    testlib.blockstack_name_renew("foo.test3",
                                  wallets[3].privkey,
                                  burn_addr=wallets[0].addr,
                                  safety_checks=False,
                                  expect_fail=True)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo.test1', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('bar.test1', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('foo.test2', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('foo.test3', testlib.get_current_block(**kw))
def scenario(wallets, **kw):
    global pk, pk2, pk3

    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)

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    addr2 = virtualchain.address_reencode(
        virtualchain.get_privkey_address(pk2))
    addr3 = virtualchain.address_reencode(
        virtualchain.get_privkey_address(pk3))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks(
        'foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name(
        'foo', namespace, testlib.get_current_block(**kw))

    # try to preorder/register using not enough Bitcoin and not enough Bitcoin (should fail)
    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print 'price of {} in BTC is {}'.format('foo.test', btc_price)
    print ''

    testlib.send_funds(wallets[0].privkey, btc_price * 2, addr)

    # try to preorder/register using not enough bitcoin (preorder should succeed; register should fail)
    testlib.blockstack_name_preorder("foo.test",
                                     pk,
                                     wallets[3].addr,
                                     price={
                                         'units': 'BTC',
                                         'amount': btc_price - 1
                                     },
                                     safety_checks=False)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))

    testlib.blockstack_name_register("foo.test",
                                     pk,
                                     wallets[3].addr,
                                     safety_checks=False)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))

    # pass tokens
    testlib.send_funds(wallets[0].privkey, btc_price * 2, addr2)
    testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price,
                                   wallets[0].privkey)
    testlib.next_block(**kw)

    # try to preorder/register using not enough Stacks (preorder should succeed; register should fail)
    testlib.blockstack_name_preorder("foo.test",
                                     pk2,
                                     wallets[4].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price - 1
                                     },
                                     safety_checks=False)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))

    testlib.blockstack_name_register("foo.test",
                                     pk2,
                                     wallets[4].addr,
                                     safety_checks=False)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))

    # pass tokens
    testlib.send_funds(wallets[0].privkey, btc_price * 2, addr3)
    testlib.blockstack_send_tokens(addr3, "STACKS", stacks_price,
                                   wallets[0].privkey)
    testlib.next_block(**kw)

    # try to preorder/register using the right amount of stacks, but not paying in BTC (should succeed)
    testlib.blockstack_name_preorder("foo.test",
                                     pk3,
                                     wallets[1].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.next_block(**kw)

    testlib.blockstack_name_register("foo.test", pk3, wallets[1].addr)
    testlib.next_block(**kw)
def scenario( wallets, **kw ):
    global pk, pk2

    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,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR)
    testlib.next_block( **kw )

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price * 8, wallets[0].privkey)
    testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price * 8, wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, btc_price * 10, addr)    # fund with enough bitcoin
    testlib.send_funds(wallets[0].privkey, btc_price * 10, addr2)    # fund with enough bitcoin
    testlib.next_block(**kw)

    def _tx_pay_btc(txhex, privk, btc_paid, burn_addr):
        tx = virtualchain.btc_tx_deserialize(txhex)

        # up the burn amount 
        btc_price = blockstack.lib.scripts.price_name('baz', namespace, testlib.get_current_block(**kw))
        tx['outs'][2]['script'] = virtualchain.btc_make_payment_script(burn_addr)
        tx['outs'][2]['value'] = btc_paid

        tx['outs'][1]['value'] -= btc_paid

        # re-sign 
        for i in tx['ins']:
            i['script'] = ''

        txhex = virtualchain.btc_tx_serialize(tx)
        _addr = virtualchain.address_reencode(virtualchain.get_privkey_address(privk))
        txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(privk, testlib.get_utxos(_addr), txhex)
        
        print txhex_signed
        res = testlib.broadcast_transaction(txhex_signed)
        assert 'error' not in res, res['error']
        return res

    balance_before = testlib.get_addr_balances(addr)[addr]['STACKS']

    # pay with Stacks and Bitcoin.  Preorder should succeed only when we use the Blockstack burn address, but register should fail since we're paying Stacks.  Pay enough bitcoin as well.
    res_fooa = testlib.blockstack_name_preorder('fooa.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_fooa = _tx_pay_btc(res_fooa['transaction'], pk, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)

    res_bara = testlib.blockstack_name_preorder('bara.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_bara = _tx_pay_btc(res_bara['transaction'], pk, btc_price, wallets[0].addr)

    res_baza = testlib.blockstack_name_preorder('baza.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_baza = _tx_pay_btc(res_baza['transaction'], pk, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)

    res_gooa = testlib.blockstack_name_preorder('gooa.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_gooa = _tx_pay_btc(res_gooa['transaction'], pk, btc_price, wallets[0].addr)

    res_foob = testlib.blockstack_name_preorder('foob.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_foob = _tx_pay_btc(res_foob['transaction'], pk, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    
    res_barb = testlib.blockstack_name_preorder('barb.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_barb = _tx_pay_btc(res_barb['transaction'], pk, btc_price - 1, wallets[0].addr)
    
    res_bazb = testlib.blockstack_name_preorder('bazb.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_bazb = _tx_pay_btc(res_bazb['transaction'], pk, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    
    res_goob = testlib.blockstack_name_preorder('goob.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_goob = _tx_pay_btc(res_goob['transaction'], pk, btc_price - 1, wallets[0].addr)

    testlib.next_block(**kw)

    # should have paid in Stacks for each preorder
    balance_after = testlib.get_addr_balances(addr)[addr]['STACKS']
    if balance_after != balance_before - (2 * stacks_price + 2 * stacks_price - 2):
        print 'names cost {}'.format(balance_before - balance_after)
        return False

    # should all fail since we tried to pay in stacks at this time
    testlib.blockstack_name_register('fooa.test', pk, wallets[3].addr)
    testlib.blockstack_name_register('bara.test', pk, wallets[3].addr)
    testlib.blockstack_name_register('baza.test', pk, wallets[3].addr)
    testlib.blockstack_name_register('gooa.test', pk, wallets[3].addr)

    testlib.blockstack_name_register('foob.test', pk, wallets[3].addr)
    testlib.blockstack_name_register('barb.test', pk, wallets[3].addr)
    testlib.blockstack_name_register('bazb.test', pk, wallets[3].addr)
    testlib.blockstack_name_register('goob.test', pk, wallets[3].addr)

    testlib.next_block(**kw)    # pay-to-creator ends
    testlib.expect_snv_fail_at('fooa.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('bara.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('baza.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('gooa.test', testlib.get_current_block(**kw))

    testlib.expect_snv_fail_at('foob.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('barb.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('bazb.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('goob.test', testlib.get_current_block(**kw))

    balance_before = testlib.get_addr_balances(addr2)[addr2]['STACKS']

    # pay with Stacks and Bitcoin, now that pay-to-creator has passed.  Preorder should succeed when we pay to blockstack burn address, and register should succeed (when we fund enough), all because we paid in stacks.
    res_fooa = testlib.blockstack_name_preorder('fooa.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_fooa = _tx_pay_btc(res_fooa['transaction'], pk2, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)

    res_bara = testlib.blockstack_name_preorder('bara.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_bara = _tx_pay_btc(res_bara['transaction'], pk2, btc_price, wallets[0].addr)

    res_baza = testlib.blockstack_name_preorder('baza.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_baza = _tx_pay_btc(res_baza['transaction'], pk2, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)

    res_gooa = testlib.blockstack_name_preorder('gooa.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_gooa = _tx_pay_btc(res_gooa['transaction'], pk2, btc_price, wallets[0].addr)

    res_foob = testlib.blockstack_name_preorder('foob.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_foob = _tx_pay_btc(res_foob['transaction'], pk2, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)

    res_barb = testlib.blockstack_name_preorder('barb.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_barb = _tx_pay_btc(res_barb['transaction'], pk2, btc_price - 1, wallets[0].addr)

    res_bazb = testlib.blockstack_name_preorder('bazb.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False)
    res_bazb = _tx_pay_btc(res_bazb['transaction'], pk2, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)

    res_goob = testlib.blockstack_name_preorder('goob.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False)
    res_goob = _tx_pay_btc(res_goob['transaction'], pk2, btc_price - 1, wallets[0].addr)

    testlib.next_block(**kw)

    # should have paid in Stacks for each preorder
    balance_after = testlib.get_addr_balances(addr2)[addr2]['STACKS']
    if balance_after != balance_before - (2 * stacks_price + 2 * stacks_price - 2):
        print 'baz.test cost {}'.format(balance_before - balance_after)
        return False

    # only foo*.test should succeed, since we both paid enough stacks and paid to the burn address
    testlib.blockstack_name_register('fooa.test', pk2, wallets[3].addr)
    testlib.blockstack_name_register('bara.test', pk2, wallets[3].addr)
    testlib.blockstack_name_register('baza.test', pk2, wallets[3].addr)
    testlib.blockstack_name_register('gooa.test', pk2, wallets[3].addr)

    testlib.blockstack_name_register('foob.test', pk2, wallets[3].addr)
    testlib.blockstack_name_register('barb.test', pk2, wallets[3].addr)
    testlib.blockstack_name_register('bazb.test', pk2, wallets[3].addr)
    testlib.blockstack_name_register('goob.test', pk2, wallets[3].addr)

    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('bara.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('baza.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('gooa.test', testlib.get_current_block(**kw))

    testlib.expect_snv_fail_at('barb.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('bazb.test', testlib.get_current_block(**kw))
    testlib.expect_snv_fail_at('goob.test', testlib.get_current_block(**kw))
def scenario(wallets, **kw):
    global pk

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks(
        'foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name(
        'foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price * 4,
                                   wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, btc_price * 10,
                       addr)  # fund with enough bitcoin
    testlib.next_block(**kw)

    # preorder/register using Stacks---Stacks should still be used since that's what the transaction indicates
    testlib.blockstack_name_preorder("foo.test",
                                     pk,
                                     wallets[3].addr,
                                     price={
                                         'units': 'STACKS',
                                         'amount': stacks_price
                                     })
    testlib.next_block(**kw)

    testlib.send_funds(wallets[0].privkey, btc_price * 10, addr)
    testlib.blockstack_name_register("foo.test", pk, wallets[3].addr)
    testlib.next_block(**kw)

    # preorder/register using Bitcoin--Stacks should NOT be used since that's what the transaction indicates
    testlib.blockstack_name_preorder("bar.test",
                                     pk,
                                     wallets[3].addr,
                                     price={
                                         'units': 'BTC',
                                         'amount': btc_price
                                     })
    testlib.next_block(**kw)

    testlib.blockstack_name_register('bar.test', pk, wallets[3].addr)
    testlib.next_block(**kw)

    balance_before = testlib.get_addr_balances(addr)[addr]['STACKS']

    # pay with Stacks and Bitcoin.  Preorder should succeed, and register should also succeed since we're paying enough stacks.  Underpay bitcoin
    res = testlib.blockstack_name_preorder('baz.test',
                                           pk,
                                           wallets[3].addr,
                                           price={
                                               'units': 'STACKS',
                                               'amount': stacks_price
                                           },
                                           tx_only=True,
                                           expect_success=True)
    txhex = res['transaction']
    tx = virtualchain.btc_tx_deserialize(txhex)

    # up the burn amount
    btc_price = blockstack.lib.scripts.price_name(
        'baz', namespace, testlib.get_current_block(**kw))
    tx['outs'][2]['script'] = virtualchain.btc_make_payment_script(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    tx['outs'][2]['value'] = btc_price - 1

    tx['outs'][1]['value'] -= btc_price - 1

    # re-sign
    for i in tx['ins']:
        i['script'] = ''

    txhex = virtualchain.btc_tx_serialize(tx)
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        pk, testlib.get_utxos(addr), txhex)

    print txhex_signed

    res = testlib.broadcast_transaction(txhex_signed)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should have paid in Stacks
    balance_after = testlib.get_addr_balances(addr)[addr]['STACKS']
    if balance_after != balance_before - stacks_price:
        print 'baz.test cost {}'.format(balance_before - balance_after)
        return False

    # should succeed, since we paid enough stacks (Bitcoin is not considered)
    testlib.blockstack_name_register('baz.test', pk, wallets[3].addr)
    testlib.next_block(**kw)

    balance_before = testlib.get_addr_balances(addr)[addr]['STACKS']

    # register a name where we pay not enough stacks, but enough bitcoin.  preorder should succeed, but register should fail since we tried to use stacks
    res = testlib.blockstack_name_preorder('goo.test',
                                           pk,
                                           wallets[3].addr,
                                           price={
                                               'units': 'STACKS',
                                               'amount': stacks_price - 1
                                           },
                                           tx_only=True,
                                           expect_success=True)
    txhex = res['transaction']
    tx = virtualchain.btc_tx_deserialize(txhex)

    # up the burn amount to the name price
    btc_price = blockstack.lib.scripts.price_name(
        'goo', namespace, testlib.get_current_block(**kw))
    tx['outs'][2]['script'] = virtualchain.btc_make_payment_script(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    tx['outs'][2]['value'] = btc_price

    tx['outs'][1]['value'] -= btc_price

    # re-sign
    for i in tx['ins']:
        i['script'] = ''

    txhex = virtualchain.btc_tx_serialize(tx)
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        pk, testlib.get_utxos(addr), txhex)

    print txhex_signed

    res = testlib.broadcast_transaction(txhex_signed)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should have paid in Stacks
    balance_after = testlib.get_addr_balances(addr)[addr]['STACKS']
    if balance_after != balance_before - stacks_price + 1:
        print 'goo.test paid {}'.format(balance_before - balance_after)
        return False

    # should fail, since we tried to pay in stacks and didn't pay enough
    testlib.blockstack_name_register('goo.test', pk, wallets[3].addr)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('goo.test', testlib.get_current_block(**kw))

    if testlib.get_state_engine().get_name('goo.test') is not None:
        print 'registered goo.test'
        return False

    balance_before = testlib.get_addr_balances(addr)[addr]['STACKS']

    # underpay in both Stacks and Bitcoin.
    # both stacks and bitcoin will be burned.
    # preorder should succeed, but register should fail.
    res = testlib.blockstack_name_preorder('nop.test',
                                           pk,
                                           wallets[3].addr,
                                           price={
                                               'units': 'STACKS',
                                               'amount': stacks_price - 1
                                           },
                                           safety_checks=False,
                                           tx_only=True,
                                           expect_success=True)
    txhex = res['transaction']
    tx = virtualchain.btc_tx_deserialize(txhex)

    # up the burn amount to the name price, but just under
    btc_price = blockstack.lib.scripts.price_name(
        'nop', namespace, testlib.get_current_block(**kw))
    tx['outs'][2]['script'] = virtualchain.btc_make_payment_script(
        blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS)
    tx['outs'][2]['value'] = btc_price - 1

    tx['outs'][1]['value'] -= btc_price - 1

    # re-sign
    for i in tx['ins']:
        i['script'] = ''

    txhex = virtualchain.btc_tx_serialize(tx)
    txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        pk, testlib.get_utxos(addr), txhex)

    print txhex_signed

    res = testlib.broadcast_transaction(txhex_signed)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

    # should fail, since we didn't pay enough stacks and tried to pay in stacks
    res = testlib.blockstack_name_register('nop.test', pk, wallets[3].addr)
    testlib.next_block(**kw)
    testlib.expect_snv_fail_at('nop.test', testlib.get_current_block(**kw))

    # preorder should still have debited
    balance_after = testlib.get_addr_balances(addr)[addr]['STACKS']
    if balance_after != balance_before - stacks_price + 1:
        print 'paid {} for nop.test'.format(balance_before - balance_after)
        return False
def scenario(wallets, **kw):

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

    testlib.blockstack_namespace_reveal(
        "test",
        wallets[1].addr,
        52595,
        250,
        4, [6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        10,
        10,
        wallets[0].privkey,
        version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR)
    testlib.next_block(**kw)

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

    # pay for a name in a v1 namespace with Stacks
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    addr2 = virtualchain.address_reencode(
        virtualchain.get_privkey_address(pk2))

    # calculate the cost of doing so
    namespace = testlib.get_state_engine().get_namespace('test')
    stacks_price = blockstack.lib.scripts.price_name_stacks(
        'foo', namespace, testlib.get_current_block(**kw))
    btc_price = blockstack.lib.scripts.price_name(
        'foo', namespace, testlib.get_current_block(**kw))

    print ''
    print 'price of {} in Stacks is {}'.format('foo.test', stacks_price)
    print 'price of {} in BTC is {}'.format('foo.test', btc_price)
    print ''

    testlib.blockstack_send_tokens(addr, "STACKS", stacks_price,
                                   wallets[0].privkey)
    testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price,
                                   wallets[0].privkey)
    testlib.send_funds(wallets[0].privkey, 2 * btc_price, addr)
    testlib.send_funds(wallets[0].privkey, 2 * btc_price, addr2)
    testlib.next_block(**kw)

    # preorder/register using BTC
    testlib.blockstack_name_preorder("foo.test", pk, addr2)
    testlib.next_block(**kw)

    testlib.blockstack_name_register("foo.test", pk, addr2)
    testlib.next_block(**kw)

    # try to renew using Stacks (won't work, since we send tokens the wrong burn address)
    testlib.blockstack_name_renew(
        'foo.test',
        pk2,
        price={
            'units': 'STACKS',
            'amount': stacks_price
        },
        burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS,
        safety_checks=False,
        expect_fail=True)
    testlib.next_block(**kw)

    # try to renew using Stacks (won't work, since we're still collecting fees in BTC and need to send to the namespace creator's address)
    testlib.blockstack_name_renew('foo.test',
                                  pk2,
                                  price={
                                      'units': 'STACKS',
                                      'amount': stacks_price
                                  },
                                  burn_addr=wallets[0].addr,
                                  safety_checks=False,
                                  expect_fail=True)
    testlib.next_block(**kw)

    # try to renew using Stacks, now that pay-to-creator has expired
    testlib.blockstack_name_renew('foo.test',
                                  pk2,
                                  price={
                                      'units': 'STACKS',
                                      'amount': stacks_price
                                  })
    testlib.next_block(**kw)
示例#17
0
def scenario(wallets, **kw):

    global value_hashes

    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)

    # register 10 names
    for i in xrange(0, 10):
        res = testlib.blockstack_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)

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

    zonefiles = {
        'foo_0.test':
        zf_template.format(
            'foo_0.test',
            subdomains.make_subdomain_txt(
                'bar.foo_0.test', 'foo_0.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_0.test', zf_default_url),
                wallets[4].privkey)),
        'foo_1.test':
        zf_template.format(
            'foo_1.test',
            subdomains.make_subdomain_txt(
                'bar.foo_1.test', 'foo_1.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_1.test', zf_default_url),
                wallets[4].privkey)),
        'foo_2.test':
        zf_template.format(
            'foo_2.test',
            subdomains.make_subdomain_txt(
                'bar.foo_2.test', 'foo_2.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_2.test', zf_default_url),
                wallets[4].privkey)),
        'foo_3.test':
        zf_template.format(
            'foo_3.test',
            subdomains.make_subdomain_txt(
                'bar.foo_3.test', 'foo_3.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_3.test', zf_default_url),
                wallets[4].privkey)),
        'foo_4.test':
        zf_template.format(
            'foo_4.test',
            subdomains.make_subdomain_txt(
                'bar.foo_4.test', 'foo_4.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_4.test', zf_default_url),
                wallets[4].privkey)),
        'foo_5.test':
        zf_template.format(
            'foo_5.test',
            subdomains.make_subdomain_txt(
                'bar.foo_5.test', 'foo_5.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_5.test', zf_default_url),
                wallets[4].privkey)),
        'foo_6.test':
        zf_template.format(
            'foo_6.test',
            subdomains.make_subdomain_txt(
                'bar.foo_6.test', 'foo_6.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_6.test', zf_default_url),
                wallets[4].privkey)),
        'foo_7.test':
        zf_template.format(
            'foo_7.test',
            subdomains.make_subdomain_txt(
                'bar.foo_7.test', 'foo_7.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_7.test', zf_default_url),
                wallets[4].privkey)),
        'foo_8.test':
        zf_template.format(
            'foo_8.test',
            subdomains.make_subdomain_txt(
                'bar.foo_8.test', 'foo_8.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_8.test', zf_default_url),
                wallets[4].privkey)),
        'foo_9.test':
        zf_template.format(
            'foo_9.test',
            subdomains.make_subdomain_txt(
                'bar.foo_9.test', 'foo_9.test', wallets[4].addr, 0,
                zf_template.format('bar.foo_9.test', zf_default_url),
                wallets[4].privkey)),
    }

    for i in xrange(0, 10):
        res = testlib.blockstack_name_register(
            "foo_{}.test".format(i),
            wallets[2].privkey,
            wallets[3].addr,
            zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash(
                zonefiles['foo_{}.test'.format(i)]))
        if 'error' in res:
            print json.dumps(res)
            return False

    testlib.next_block(**kw)

    # propagate the first five subdomains
    for i in range(0, 5):
        name = 'foo_{}.test'.format(i)
        assert testlib.blockstack_put_zonefile(zonefiles[name])

    # process the first five subdomains
    testlib.next_block(**kw)

    # propagate the last five subdomains, but don't process them
    for i in range(5, 10):
        name = 'foo_{}.test'.format(i)
        assert testlib.blockstack_put_zonefile(zonefiles[name])

    print 'waiting for all zone files to replicate'
    time.sleep(10)

    working_dir = os.environ.get('BLOCKSTACK_WORKING_DIR')
    restore_dir = os.path.join(working_dir, "snapshot_dir")

    # make a backup
    db = testlib.get_state_engine()

    print 'begin make backups of state from {}'.format(
        testlib.get_current_block(**kw) - 1)
    for name in os.listdir(os.path.join(working_dir, 'backups')):
        if name.endswith('.{}'.format(testlib.get_current_block(**kw) - 1)):
            os.unlink(os.path.join(working_dir, 'backups', name))

    db.make_backups(testlib.get_current_block(**kw))
    print 'end make backups'

    def _backup_and_restore():
        # snapshot the latest backup
        snapshot_path = os.path.join(working_dir, "snapshot.bsk")
        rc = blockstack.fast_sync_snapshot(working_dir, snapshot_path,
                                           wallets[3].privkey, None)
        if not rc:
            print "Failed to fast_sync_snapshot"
            return False

        if not os.path.exists(snapshot_path):
            print "Failed to create snapshot {}".format(snapshot_path)
            return False

        # sign with more keys
        for i in xrange(4, 6):
            rc = blockstack.fast_sync_sign_snapshot(snapshot_path,
                                                    wallets[i].privkey)
            if not rc:
                print "Failed to sign with key {}".format(i)
                return False

        # restore!
        rc = restore(kw['working_dir'], snapshot_path, restore_dir, [
            wallets[3].pubkey_hex, wallets[4].pubkey_hex, wallets[5].pubkey_hex
        ], 3)
        if not rc:
            print "1 failed to restore snapshot {}".format(snapshot_path)
            return False

        rc = restore(kw['working_dir'], snapshot_path, restore_dir, [
            wallets[5].pubkey_hex, wallets[4].pubkey_hex, wallets[3].pubkey_hex
        ], 3)
        if not rc:
            print "2 failed to restore snapshot {}".format(snapshot_path)
            return False

        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 2)
        if not rc:
            print "3 failed to restore snapshot {}".format(snapshot_path)
            return False

        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[3].pubkey_hex, wallets[5].pubkey_hex], 2)
        if not rc:
            print "4 failed to restore snapshot {}".format(snapshot_path)
            return False

        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[4].pubkey_hex, wallets[5].pubkey_hex], 2)
        if not rc:
            print "5 failed to restore snapshot {}".format(snapshot_path)
            return False

        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[3].pubkey_hex], 1)
        if not rc:
            print "6 failed to restore snapshot {}".format(snapshot_path)
            return False

        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[4].pubkey_hex, wallets[0].pubkey_hex], 1)
        if not rc:
            print "7 failed to restore snapshot {}".format(snapshot_path)
            return False

        rc = restore(kw['working_dir'], snapshot_path, restore_dir, [
            wallets[0].pubkey_hex, wallets[1].pubkey_hex, wallets[5].pubkey_hex
        ], 1)
        if not rc:
            print "8 failed to restore snapshot {}".format(snapshot_path)
            return False

        shutil.move(restore_dir, restore_dir + '.bak')

        # should fail
        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[3].pubkey_hex], 2)
        if rc:
            print "restored insufficient signatures snapshot {}".format(
                snapshot_path)
            return False

        shutil.rmtree(restore_dir)

        # should fail
        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 3)
        if rc:
            print "restored insufficient signatures snapshot {}".format(
                snapshot_path)
            return False

        shutil.rmtree(restore_dir)

        # should fail
        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[0].pubkey_hex], 1)
        if rc:
            print "restored wrongly-signed snapshot {}".format(snapshot_path)
            return False

        shutil.rmtree(restore_dir)

        # should fail
        rc = restore(kw['working_dir'], snapshot_path, restore_dir,
                     [wallets[0].pubkey_hex, wallets[3].pubkey_hex], 2)
        if rc:
            print "restored wrongly-signed snapshot {}".format(snapshot_path)
            return False

        shutil.rmtree(restore_dir)

        # should fail
        rc = restore(kw['working_dir'], snapshot_path, restore_dir, [
            wallets[0].pubkey_hex, wallets[3].pubkey_hex, wallets[4].pubkey_hex
        ], 3)
        if rc:
            print "restored wrongly-signed snapshot {}".format(snapshot_path)
            return False

        shutil.rmtree(restore_dir)
        shutil.move(restore_dir + '.bak', restore_dir)
        return True

    # test backup and restore
    res = _backup_and_restore()
    if not res:
        return res

    # first five subdomains are all present in the subdomain DB
    subds = ['bar.foo_{}.test'.format(i) for i in range(0, 5)]
    subdomain_db = blockstack.lib.subdomains.SubdomainDB(
        os.path.join(restore_dir, 'subdomains.db'),
        os.path.join(restore_dir, 'zonefiles'))
    for subd in subds:
        rec = subdomain_db.get_subdomain_entry(subd)
        if not rec:
            print 'not found: {}'.format(subd)
            return False

    # last 5 subdomains are queued in the subdomain DB queue
    queued_zfinfos = blockstack.lib.queue.queuedb_findall(
        os.path.join(restore_dir, 'subdomains.db.queue'), 'zonefiles')
    if len(queued_zfinfos) != 5:
        print 'only {} zonefiles queued'.format(queued_zfinfos)
        print queued_zfinfos
        return False

    # process the last five subdomains
    testlib.next_block(**kw)

    shutil.rmtree(restore_dir)
    os.unlink(os.path.join(working_dir, "snapshot.bsk"))

    # test backup and restore
    res = _backup_and_restore()
    if not res:
        return res

    # all subdomains are all present in the subdomain DB
    subds = ['bar.foo_{}.test'.format(i) for i in range(0, 10)]
    subdomain_db = blockstack.lib.subdomains.SubdomainDB(
        os.path.join(restore_dir, 'subdomains.db'),
        os.path.join(restore_dir, 'zonefiles'))
    for subd in subds:
        rec = subdomain_db.get_subdomain_entry(subd)
        if not rec:
            print 'not found: {}'.format(subd)
            return False

    # nothing queued
    queued_zfinfos = blockstack.lib.queue.queuedb_findall(
        os.path.join(restore_dir, 'subdomains.db.queue'), 'zonefiles')
    if len(queued_zfinfos) != 0:
        print '{} zonefiles queued'.format(queued_zfinfos)
        print queued_zfinfos
        return False

    shutil.rmtree(restore_dir)
def scenario(wallets, **kw):

    coeff = 255
    base = 32
    bucket_exponents = [10, 10, 10, 9, 9, 9, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0]
    nonalpha_discount = 10
    novowel_discount = 10
    cost_unit = blockstack.config.NAME_COST_UNIT_STACKS

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

    testlib.blockstack_namespace_reveal(
        "test",
        wallets[1].addr,
        52595,
        coeff,
        base,
        bucket_exponents,
        nonalpha_discount,
        novowel_discount,
        wallets[0].privkey,
        version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS)
    testlib.next_block(**kw)

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

    # query a large amount of Stacks (exceeds 2**64)
    name_cost = testlib.blockstack_get_name_token_cost('foo.test')
    print name_cost

    assert name_cost['units'] == 'STACKS'
    assert name_cost['amount'] > 2**64

    # send a large amount of Stacks (exceeds 2**64) -- should fail, since our transactions only allow 8 bytes to encode the STACKs count
    try:
        res = testlib.blockstack_send_tokens(wallets[2].addr,
                                             "STACKS",
                                             name_cost['amount'],
                                             wallets[0].privkey,
                                             expect_fail=True)
        assert 'error' not in res
        print res
        print 'Accidentally succeeded to send {} STACKS'.format(
            name_cost['amount'])
        return False
    except:
        pass

    # should fail, since we can't encode the price as a 64-bit number
    try:
        res = testlib.blockstack_name_preorder("foo.test",
                                               wallets[2].privkey,
                                               wallets[3].addr,
                                               expect_fail=True)
        assert 'error' not in res
        print res
        print 'Accidentally succeeded to preorder foo.test for {} STACKs'.format(
            name_cost['amount'])
        return False
    except:
        pass

    ns = testlib.get_state_engine().get_namespace('test')

    # old price function should be wonky since it's a big float
    discount = 10.0  # for foo2.id, the non-alpha discount applies
    old_price_multiplier = 0.1
    old_price_float = (float(coeff *
                             (base**bucket_exponents[len('foo2') - 1])) /
                       float(discount)) * cost_unit * old_price_multiplier

    new_price_int = blockstack.scripts.price_name(
        'foo2', ns, testlib.get_current_block(**kw))

    print 'old price: {}'.format(old_price_float)
    print 'new price: {}'.format(new_price_int)
    print 'diff: {}'.format(abs(int(old_price_float) - new_price_int))

    # diff should be 1024, since we're dealing with floats bigger than 2**53
    assert abs(int(old_price_float) -
               new_price_int) > 100, 'old price: {}, new price: {}'.format(
                   old_price_float, new_price_int)

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

    testlib.blockstack_name_register("foo2.test", wallets[2].privkey,
                                     wallets[3].addr)
    testlib.next_block(**kw)
def scenario(wallets, **kw):

    global debug, consensus

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

    testlib.next_block(**kw)

    resp = testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    if '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 'error' in resp:
        print json.dumps(resp, indent=4)

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

    resp = testlib.blockstack_name_preorder("baz.test", wallets[2].privkey,
                                            wallets[3].addr)
    if '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 'error' in resp:
        print json.dumps(resp, indent=4)
        return False

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

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

    testlib.next_block(**kw)

    # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER.
    # baz.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER
    # in both cases, the consensus hash should be the one from the NAME_TRANSFER,
    # since there was no prior consensus hash.
    resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True,
                                            wallets[3].privkey)
    if 'error' in resp:
        print resp
        return False

    resp = testlib.blockstack_name_transfer("baz.test", wallets[4].addr, True,
                                            wallets[3].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    for name in ['foo.test', 'baz.test']:
        db = testlib.get_state_engine()
        name_rec = db.get_name(name, include_history=False)

        if name_rec['consensus_hash'] is None:
            print 'NAME_TRANSFER did not set the consensus hash: {}'.format(
                name_rec)
            return False

        if name_rec['consensus_hash'] != testlib.get_consensus_at(
                testlib.get_current_block(**kw) - 1):
            print 'NAME_TRANSFER set wrong consensus hash (expected {}): {}'.format(
                testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
                name_rec['consensus_hash'])
            return False

    # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE
    # the consensus hash should be the one from the NAME_UPDATE
    resp = testlib.blockstack_name_update('bar.test', '11' * 20,
                                          wallets[3].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    db = testlib.get_state_engine()
    name_rec = db.get_name('bar.test', include_history=False)
    bar_update_ch = name_rec['consensus_hash']
    assert bar_update_ch, 'No consensus hash set on update'

    if bar_update_ch != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_UPDATE did not set consensus hash {} (got {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            bar_update_ch, name_rec)
        return False

    # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER
    # the consensus hash should still be the one from the NAME_UPDATE
    resp = testlib.blockstack_name_transfer('bar.test', wallets[4].addr, True,
                                            wallets[3].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    db = testlib.get_state_engine()
    name_rec = db.get_name('bar.test', include_history=False)
    if name_rec['consensus_hash'] != bar_update_ch:
        print 'update consensus hash not preserved (expected {}): {}'.format(
            bar_update_ch, name_rec)
        return False

    # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_UPDATE
    # the consensus hash should be from foo.test's NAME_UPDATE
    resp = testlib.blockstack_name_update('foo.test', '22' * 20,
                                          wallets[4].privkey)
    if 'error' in resp:
        print resp
        return False

    # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER, NAME_UPDATE
    # the consensus hash should be from bar.test's last NAME_UPDATE
    resp = testlib.blockstack_name_update('bar.test', '33' * 20,
                                          wallets[4].privkey)
    if 'error' in resp:
        print resp
        return False

    # baz.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_TRANSFER
    # the consensus hash should be from the last NAME_TRANSFER
    resp = testlib.blockstack_name_transfer('baz.test', wallets[3].addr, True,
                                            wallets[4].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test', include_history=False)
    name_history = db.get_name_at('foo.test', testlib.get_current_block(**kw))
    foo_update_ch = name_rec['consensus_hash']

    # foo.test: consensus hash should match that of the previously-sent update now.
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_UPDATE did not set consensus hash for foo.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_rec)
        return False

    # foo.test: name's history's consensus hash should match the update as well
    if name_history[0]['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_UPDATE did not match consensus hash in history for foo.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_history[0])
        return False

    name_rec = db.get_name('bar.test', include_history=False)
    name_history = db.get_name_at('bar.test', testlib.get_current_block(**kw))
    bar_update_ch = name_rec['consensus_hash']

    # bar.test: consensus hash should match the update's consensus hash
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_UPDATE did not set consensus hash for bar.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_rec)
        return False

    # bar.test: name's history's consensus hash should match the update as well
    if name_history[0]['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_UPDATE did not match consensus hash in history for bar.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_history[0])
        return False

    db = testlib.get_state_engine()
    name_rec = db.get_name('baz.test', include_history=False)
    name_history = db.get_name_at('baz.test', testlib.get_current_block(**kw))

    # baz.test: consensus hash should match that of previously-sent NAME_TRANSFER
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_TRANSFER did not set consensus hash for baz.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_rec)
        return False

    # baz.test: name's history's consensus hash should have been set to the last NAME_TRANSFER consensus hash
    if name_history[0]['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_TRANSFER did not match consensus hash in history for baz.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_history[0])
        return False

    # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER
    # foo.test's consensus hash should be that of its last NAME_UPDATE
    resp = testlib.blockstack_name_transfer('foo.test', wallets[3].addr, True,
                                            wallets[4].privkey)
    if 'error' in resp:
        print resp
        return False

    # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER
    # bar.test's consensus hash should be that of its last NAME_UPDATE
    resp = testlib.blockstack_name_transfer('bar.test', wallets[3].addr, True,
                                            wallets[4].privkey)
    if 'error' in resp:
        print resp
        return False

    # baz.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_TRANSFER, NAME_TRANSFER
    # baz.test's consensus hash should be that of the last NAME_TRANSFER still
    resp = testlib.blockstack_name_transfer('baz.test', wallets[4].addr, True,
                                            wallets[3].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test', include_history=False)
    name_history = db.get_name_at('foo.test', testlib.get_current_block(**kw))

    # foo.test's last NAME_UPDATE set the consensus hash
    if name_rec['consensus_hash'] != foo_update_ch:
        print 'NAME_TRANSFER did not preserve previous consensus hash for foo.test (expected {}): {}'.format(
            foo_update_ch, name_rec)
        return False

    # foo.test's last-history-inserted consensus hash should be from the NAME_UPDATE
    if name_history[0]['consensus_hash'] != foo_update_ch:
        print 'NAME_UPDATE did not match consensus hash in history for foo.test (expected {}): {}'.format(
            foo_update_ch, name_history[0])
        return False

    db = testlib.get_state_engine()
    name_rec = db.get_name('bar.test', include_history=False)
    name_history = db.get_name_at('bar.test', testlib.get_current_block(**kw))

    # bar.test's last NAME_UPDATE set the consensus hash
    if name_rec['consensus_hash'] != bar_update_ch:
        print 'NAME_TRANSFER did not preserve previous consensus hash for bar.test (expected {}): {}'.format(
            bar_update_ch, name_rec)
        return False

    # bar.test's last-history-inserted consensus hash should be from the NAME_UPDATE
    if name_history[0]['consensus_hash'] != bar_update_ch:
        print 'NAME_UPDATE did not match consensus hash in history for bar.test (expected {}): {}'.format(
            bar_update_ch, name_history[0])
        return False

    db = testlib.get_state_engine()
    name_rec = db.get_name('baz.test', include_history=False)
    name_history = db.get_name_at('baz.test', testlib.get_current_block(**kw))

    # baz.test's last NAME_TRANSFER set the consensus hash
    if name_rec['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_TRANSFER did not preserve previous consensus hash for baz.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_rec)
        return False

    # baz.test's last-history-inserted consensus hash should be from the NAME_TRANSFER
    if name_history[0]['consensus_hash'] != testlib.get_consensus_at(
            testlib.get_current_block(**kw) - 1):
        print 'NAME_TRANSFER did not match consensus hash in history for baz.test (expected {}): {}'.format(
            testlib.get_consensus_at(testlib.get_current_block(**kw) - 1),
            name_history[0])
        return False

    # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER, NAME_TRANSFER
    # foo.test's consensus hash should be that of its last NAME_UPDATE
    resp = testlib.blockstack_name_transfer('foo.test', wallets[4].addr, True,
                                            wallets[3].privkey)
    if 'error' in resp:
        print resp
        return False

    # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER, NAME_TRANSFER
    # bar.test's consensus hash should be that of its last NAME_UPDATE
    resp = testlib.blockstack_name_transfer('bar.test', wallets[4].addr, True,
                                            wallets[3].privkey)
    if 'error' in resp:
        print resp
        return False

    testlib.next_block(**kw)

    db = testlib.get_state_engine()
    name_rec = db.get_name('foo.test', include_history=False)
    name_history = db.get_name_at('foo.test', testlib.get_current_block(**kw))

    # foo.test's last NAME_UPDATE set the consensus hash
    if name_rec['consensus_hash'] != foo_update_ch:
        print 'NAME_TRANSFER did not preserve previous consensus hash (expected {}): {}'.format(
            foo_update_ch, name_rec)
        return False

    # foo.test's last-history-inserted consensus hash should be from NAME_UPDATE
    if name_history[0]['consensus_hash'] != foo_update_ch:
        print 'NAME_UPDATE did not match consensus hash in history (expected {}): {}'.format(
            foo_update_ch, name_history[0])
        return False

    name_rec = db.get_name('bar.test', include_history=False)
    name_history = db.get_name_at('bar.test', testlib.get_current_block(**kw))

    # bar.test's last NAME_UPDATE set the consensus hash
    if name_rec['consensus_hash'] != bar_update_ch:
        print 'NAME_TRANSFER did not preserve previous consensus hash (expected {}): {}'.format(
            bar_update_ch, name_rec)
        return False

    # bar.test's last-history-inserted consensus hash should be from the NAME_UPDATE
    if name_history[0]['consensus_hash'] != bar_update_ch:
        print 'NAME_UPDATE did not match consensus hash in history (expected {}): {}'.format(
            bar_update_ch, name_history[0])
        return False