Exemplo n.º 1
0
def send_subsidized( client_privkey, resp, **kw ):

    unsigned_tx = resp['subsidized_tx']

    if client_privkey is not None:
        # sign all unsigned inputs 
        tx = testlib.tx_sign_all_unsigned_inputs( unsigned_tx, client_privkey )
    else:
        # already subsidized
        tx = unsigned_tx

    testlib.broadcast_transaction( tx )
Exemplo n.º 2
0
def send_subsidized( client_privkey, resp, **kw ):

    unsigned_tx = resp['subsidized_tx']

    if client_privkey is not None:
        # sign all unsigned inputs 
        tx = testlib.tx_sign_all_unsigned_inputs( unsigned_tx, client_privkey )
    else:
        # already subsidized
        tx = unsigned_tx

    testlib.broadcast_transaction( tx )
Exemplo n.º 3
0
def convert_funds_to_segwit(payment_key, tx_fee):
    # convert payment key to bech32
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(payment_key))
    pubk = virtualchain.lib.ecdsalib.ecdsa_private_key(payment_key, compressed=True).public_key().to_hex()
    addrhash = virtualchain.lib.hashing.bin_hash160(pubk.decode('hex')).encode('hex')
    segwit_addr = virtualchain.segwit_addr_encode(addrhash.decode('hex'), hrp='bcrt')
    
    # fund the segwit address, and then use the same payment key to send the transaction 
    fund_inputs = testlib.get_utxos(addr)
    fund_outputs = [
        {"script": '0014' + addrhash,
         "value": sum(inp['value'] for inp in fund_inputs) - tx_fee},
    ]
    fund_prev_outputs = [{'out_script': inp['out_script'], 'value': inp['value']} for inp in fund_inputs]
    fund_serialized_tx = testlib.serialize_tx(fund_inputs, fund_outputs)
    fund_signed_tx = virtualchain.tx_sign_all_unsigned_inputs(payment_key, fund_prev_outputs, fund_serialized_tx)

    print fund_signed_tx

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

    res.update({
        'utxos': fund_outputs
    })
    return res
    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
Exemplo n.º 5
0
def send_as_segwit_bech32(txhex, payment_key):
    print 'txhex: {}'.format(txhex)

    # get op-return data
    tx = virtualchain.btc_tx_deserialize(txhex)
    payload = tx['outs'][0]['script']
    
    print json.dumps(tx, indent=4, sort_keys=True)

    # convert payment key to bech32
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(payment_key))
    pubk = virtualchain.lib.ecdsalib.ecdsa_private_key(payment_key, compressed=True).public_key().to_hex()
    addrhash = virtualchain.lib.hashing.bin_hash160(pubk.decode('hex')).encode('hex')
    segwit_addr = virtualchain.segwit_addr_encode(addrhash.decode('hex'), hrp='bcrt')
    
    print 'privk = {}'.format(payment_key)
    print 'pubk = {}'.format(pubk)
    print 'addr = {}'.format(addr)
    print 'segwit addr = {}'.format(segwit_addr)
    print 'script = 00{}'.format(addrhash)

    tx_fee = 5500
    res = convert_funds_to_segwit(payment_key, tx_fee)
    fund_outputs = res['utxos']
    fund_txid = res['tx_hash']

    new_tx = {
        'locktime': 0,
        'version': 2,
        'ins': [
            {'outpoint': {'hash': fund_txid, 'index': 0},
             'script': '',
             'witness_script': '',
             'sequence': 4294967295},
        ],
        'outs': [
            {'script': tx['outs'][0]['script'],
             'value': tx['outs'][0]['value']},
            {'script': '0014' + addrhash,
             'value': fund_outputs[0]['value'] - tx_fee * 2},
            {'script': tx['outs'][2]['script'],
             'value': tx['outs'][2]['value']}
        ]
    }

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

    pk_segwit = virtualchain.make_segwit_info(payment_key)
    print json.dumps(pk_segwit, indent=4, sort_keys=True)

    signed_txhex = virtualchain.tx_sign_input(unsigned_txhex, 0, fund_outputs[0]['script'], fund_outputs[0]['value'], pk_segwit, segwit=True, scriptsig_type='p2wpkh')
    print 'signed: {}'.format(signed_txhex)

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

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

    global reveal_block
    global preorder_block

    res = testlib.blockstack_namespace_preorder("test",
                                                wallets[1].addr,
                                                wallets[0].privkey,
                                                tx_only=True,
                                                expect_fail=True)
    ns_preorder_txhex = res['transaction']

    # change the burn address
    ns_preorder_tx = virtualchain.btc_tx_deserialize(ns_preorder_txhex)
    ns_preorder_tx['outs'][2]['script'] = virtualchain.btc_make_payment_script(
        wallets[2].addr)

    for i in ns_preorder_tx['ins']:
        i['script'] = ''

    utxos = testlib.get_utxos(wallets[0].addr)
    ns_preorder_txhex = virtualchain.btc_tx_serialize(ns_preorder_tx)
    ns_preorder_txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(
        wallets[0].privkey, utxos, ns_preorder_txhex)

    print ns_preorder_txhex_signed

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

    print res

    testlib.next_block(**kw)

    num_ops = virtualchain.lib.indexer.StateEngine.get_block_statistics(
        testlib.get_current_block(**kw))
    if num_ops['num_parsed_ops'] != 1:
        print 'processed ops: {}'.format(num_ops)
        return False

    # try again, but use the right burn address
    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    preorder_block = testlib.get_current_block(**kw) + 1
    testlib.next_block(**kw)

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

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

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

    testlib.next_block(**kw)

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

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

    testlib.next_block(**kw)

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

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

    testlib.next_block(**kw)
Exemplo n.º 8
0
def replace_output_with_bech32(txhex, output_index, payment_key, addrhash):
    print 'txhex: {}'.format(txhex)
    tx = virtualchain.btc_tx_deserialize(txhex)

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

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

    new_tx['outs'][output_index] = {
        'script': '0014' + addrhash,
        'value': tx['outs'][output_index]['value']
    }

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

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

    signed_txhex = virtualchain.tx_sign_all_unsigned_inputs(
        payment_key, prev_outputs, unsigned_txhex)

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

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

    return res
    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
Exemplo n.º 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
def scenario(wallets, **kw):
    segwit_addr_1 = get_segwit_address(wallets[1].privkey)
    segwit_addr_1_tb = get_segwit_address(wallets[1].privkey, hrp='tb')
    segwit_addr_0_tb = get_segwit_address(wallets[0].privkey, hrp='tb')

    print segwit_addr_0_tb
    print segwit_addr_1_tb

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    testlib.next_block(**kw)

    # should fail
    resp = testlib.blockstack_namespace_reveal(
        "test",
        wallets[1].addr,
        52595,
        250,
        4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        10,
        10,
        wallets[0].privkey,
        tx_only=True)
    resp = replace_output_with_bech32(resp['transaction'], 1,
                                      wallets[0].privkey, addrhash)

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

    # send a data-bearing transaction without 'id'.  we shouldn't pick it up.
    tx = mktx(5500, 5500, wallets[1].addr, wallets[0].privkey, "eg")
    if 'error' in tx:
        print tx
        return False

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

    testlib.next_block(**kw)

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

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

    testlib.next_block(**kw)

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

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

    testlib.next_block(**kw)

    all_tests = {}

    # lifted from nameop_parsing_stacks, minus the "valid" tests

    # namespace preorder wire format
    # 0     2   3                                      23               39                         47
    # |-----|---|--------------------------------------|----------------|--------------------------|
    # magic op  hash(ns_id,script_pubkey,reveal_addr)   consensus hash    token fee (little-endian)

    namespace_preorders = {
        "too_short": "%s%s%s" % ("11" * 20, "33" * 15, '00' * 7),
        "too_long": "%s%s%s" % ("11" * 20, "22" * 16, '00' * 9),
        "no_stacks": "%s%s" % ("11" * 20, "22" * 16)
    }

    all_tests["*"] = compile_test("*", namespace_preorders)

    # namespace reveal wire format
    # 0     2   3        7     8     9    10   11   12   13   14    15    16    17       18        20                        39
    # |-----|---|--------|-----|-----|----|----|----|----|----|-----|-----|-----|--------|----------|-------------------------|
    # magic  op  life    coeff. base 1-2  3-4  5-6  7-8  9-10 11-12 13-14 15-16  nonalpha  version   namespace ID
    #                                                   bucket exponents         no-vowel
    #                                                                            discounts

    namespace_reveals = {
        "non-b38":
        "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" %
        ("11111111", "02", "03", "40", "41", "42", "43", "44", "45", "46",
         "47", "15", "0001", binascii.hexlify("Hello")),
        "period2":
        "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" %
        ("11111111", "02", "03", "40", "41", "42", "43", "44", "45", "46",
         "47", "15", "0001", binascii.hexlify("He.l.lo")),
        "period":
        "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" %
        ("11111111", "02", "03", "40", "41", "42", "43", "44", "45", "46",
         "47", "15", "0001", binascii.hexlify(".")),
        "no-plus":
        "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" %
        ("11111111", "02", "03", "40", "41", "42", "43", "44", "45", "46",
         "47", "15", "0001", binascii.hexlify("hel+lo")),
        "null_name":
        "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" %
        ("11111111", "02", "03", "40", "41", "42", "43", "44", "45", "46",
         "47", "15", "0001", binascii.hexlify("")),
        "too_long":
        "%s%s%s%s%s%s%s%s%s%s%s%s%s%s" %
        ("11111111", "02", "03", "40", "41", "42", "43", "44", "45", "46",
         "47", "15", "0001", binascii.hexlify("hellohellohellohello"))
    }

    all_tests["&"] = compile_test("&", namespace_reveals)

    # namespace ready wire format
    # 0     2  3  4           23
    # |-----|--|--|------------|
    # magic op  .  ns_id

    namespace_readys = {
        "non-b38": binascii.hexlify(".Hello"),
        "period": binascii.hexlify("."),
        "period2": binascii.hexlify(".hel.lo"),
        "no-plus": binascii.hexlify(".hel+lo"),
        "null_name": binascii.hexlify(""),
        "no-period": binascii.hexlify("hello"),
        "too_long": binascii.hexlify(".hellohellohellohello")
    }

    all_tests["!"] = compile_test("!", namespace_readys)

    # name preorder wire format
    # 0     2  3                                     23             39          47            66
    # |-----|--|--------------------------------------|--------------|-----------|-------------|
    # magic op  hash160(fqn,scriptPubkey,registerAddr) consensus hash token burn  token type
    #                                                                 (optional)   (optional)

    name_preorders = {
        "too_short":
        "%s%s" % ("11" * 20, "33" * 15),
        "stacks_incomplete_short":
        "%s%s00" % ("11" * 20, "22" * 16),
        "stacks_incomplete_long":
        "%s%s%s" % ("11" * 20, "22" * 16, '00' * 7),
        "stacks_no_token_type":
        "%s%s%s" % ("11" * 20, "22" * 16, '00' * 8),
        "stacks_incomplete_token_type_short":
        "%s%s%s%s" % ("11" * 20, "22" * 16, '00' * 8, binascii.hexlify('a')),
        "stacks_incomplete_token_type_long":
        "%s%s%s%s" % ("11" * 20, "22" * 16, '00' * 8,
                      binascii.hexlify('abcdefghijklmnopqr')),
        "stacks_too_long":
        "%s%s%s%s" % ("11" * 20, "22" * 16, '00' * 8,
                      binascii.hexlify('abcdefghijklmnopqrst')),
    }

    all_tests["?"] = compile_test("?", name_preorders)

    # name register/renew wire format (pre F-day 2017)
    # 0    2  3                             39
    # |----|--|-----------------------------|
    # magic op   name.ns_id (37 bytes)

    # name register/renew wire format (post F-day 2017)
    # 0    2  3                                  39                  59
    # |----|--|----------------------------------|-------------------|
    # magic op   name.ns_id (37 bytes, 0-padded)       value hash

    # With renewal payment in a token:
    # 0    2  3                                  39                  59                            67
    # |----|--|----------------------------------|-------------------|------------------------------|
    # magic op   name.ns_id (37 bytes, 0-padded)     zone file hash    tokens burned (little-endian)

    name_registrations = {
        "null_name":
        binascii.hexlify(""),
        "non-b38":
        binascii.hexlify("Hello.test"),
        "no-namespace":
        binascii.hexlify("hello"),
        "null-namespace":
        binascii.hexlify("hello."),
        "2period":
        binascii.hexlify("hello.tes.t"),
        "no-plus":
        binascii.hexlify("hel+lo.test"),
        "too-long":
        binascii.hexlify("hellohellohellohellohellohellohel.test"),
        "null_name_2":
        binascii.hexlify("\x00" * 37 + "\x11" * 20),
        "non-b38_2":
        binascii.hexlify("Hello.test" + "\x00" * 27 + "\x11" * 20),
        "no-namespace_2":
        binascii.hexlify("hello" + "\x00" * 32 + "\x11" * 20),
        "null-namespace_2":
        binascii.hexlify("hello." + "\x00" * 31 + "\x11" * 20),
        "2period_2":
        binascii.hexlify("hello.tes.t" + "\x00" * 26 + "\x11" * 20),
        "no-plus_2":
        binascii.hexlify("hel+lo.test" + "\x00" * 26 + "\x11" * 20),
        "too-long_2":
        binascii.hexlify("hellohellohellohellohellohellohel.test" +
                         "\x11" * 20),
        "no_hash":
        binascii.hexlify("hello.test" + "\x00" * 27),
        "hash_too_long":
        binascii.hexlify("hello.test" + "\x00" * 27 + "\x11" * 21),
        "padding_too_short":
        binascii.hexlify("hello.test" + "\x00" * 26 + "\x11" * 21),
        "op_too_short":
        binascii.hexlify("hello.test" + "\x00" * 26 + "\x11" * 20),
        "stacks_too_short_1":
        binascii.hexlify("hello.test" + '\00' * 27 + '\x11' * 20 + '\x00'),
        "stacks_too_short_7":
        binascii.hexlify("hello.test" + '\00' * 27 + '\x11' * 20 + '\x00' * 7),
        "stacks_too_long":
        binascii.hexlify("hello.test" + '\00' * 27 + '\x11' * 20 + '\x00' * 9),
    }

    all_tests[":"] = compile_test(":", name_registrations)

    # name update wire format
    #  0     2  3                                   19                      39
    # |-----|--|-----------------------------------|-----------------------|
    # magic op  hash128(name.ns_id,consensus hash) hash160(data)

    name_updates = {
        "too_short": "%s%s" % ("11" * 16, "33" * 19),
        "too_long": "%s%s00" % ("11" * 16, "22" * 20),
    }

    all_tests["+"] = compile_test("+", name_updates)

    # name transfer wire format
    # 0     2  3    4                   20              36
    # |-----|--|----|-------------------|---------------|
    # magic op keep  hash128(name.ns_id) consensus hash
    #          data?

    name_transfers = {
        "too_short": "%s%s%s" % (binascii.hexlify(">"), "11" * 16, "33" * 15),
        "too_long": "%s%s%s00" % (binascii.hexlify(">"), "11" * 16, "22" * 16),
        "too_short2": "%s%s%s" % (binascii.hexlify("~"), "11" * 16, "33" * 15),
        "too_long2":
        "%s%s%s00" % (binascii.hexlify("~"), "11" * 16, "22" * 16),
        "invalid-opcode":
        "%s%s%s" % (binascii.hexlify("!"), "11" * 16, "22" * 16)
    }

    all_tests[">"] = compile_test(">", name_transfers)

    # name revoke wire format
    # 0    2  3                             39
    # |----|--|-----------------------------|
    # magic op   name.ns_id (37 bytes)

    name_revokes = {
        "null_name": binascii.hexlify(""),
        "non-b38": binascii.hexlify("Hello.test"),
        "no-namespace": binascii.hexlify("hello"),
        "null-namespace": binascii.hexlify("hello."),
        "2period": binascii.hexlify("hello.tes.t"),
        "no-plus": binascii.hexlify("hel+lo.test"),
        "too-long": binascii.hexlify("hellohellohellohellohellohellohel.test")
    }

    all_tests["~"] = compile_test("~", name_revokes)

    # name import wire format
    # 0    2  3                             39
    # |----|--|-----------------------------|
    # magic op   name.ns_id (37 bytes)

    name_imports = {
        "null_name": binascii.hexlify(""),
        "non-b38": binascii.hexlify("Hello.test"),
        "no-namespace": binascii.hexlify("hello"),
        "null-namespace": binascii.hexlify("hello."),
        "2period": binascii.hexlify("hello.tes.t"),
        "no-plus": binascii.hexlify("hel+lo.test"),
        "too-long": binascii.hexlify("hellohellohellohellohellohellohel.test")
    }

    all_tests[";"] = compile_test(";", name_imports)

    # announce wire format
    # 0    2  3                             23
    # |----|--|-----------------------------|
    # magic op   message hash (160-bit)

    announces = {"too-short": "11" * 19, "too-long": "11" * 21}

    all_tests["#"] = compile_test("#", announces)

    for opcode in all_tests.keys():
        print '\n\n'
        print 'Running tests for {}'.format(opcode)
        print '\n\n'

        # queue tests
        for test_name in all_tests[opcode].keys():
            payload = all_tests[opcode][test_name]
            print '\ntest {}: {}\n'.format(test_name, payload)

            tx = mktx(5500, 5500, wallets[1].addr, wallets[0].privkey,
                      payload.decode('hex'))

            if 'error' in tx:
                print tx
                return False

            print 'tx: {}'.format(tx)
            res = testlib.broadcast_transaction(tx)
            if 'error' in res:
                print res
                return False

        # feed through virtualchain.  they should all be rejected by the parser
        testlib.next_block(**kw)

    last_block = testlib.get_current_block(**kw)
def scenario(wallets, **kw):

    namespace_price_old_btc_2 = {
        'units': 'BTC',
        'amount':
        blockstack.lib.scripts.price_namespace('old_btc_2', 694, 'BTC')
    }
    namespace_price_stacks_too_early_1_btc = {
        'units':
        'BTC',
        'amount':
        blockstack.lib.scripts.price_namespace('stacks_too_early_1', 690,
                                               'BTC')
    }
    namespace_price_stacks_too_early_2_stacks = {
        'units':
        'STACKS',
        'amount':
        blockstack.lib.scripts.price_namespace('stacks_too_early_1', 694,
                                               'STACKS')
    }

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[0].privkey)
    testlib.blockstack_namespace_preorder(
        "stacks_too_early_1",
        wallets[1].addr,
        wallets[0].privkey,
        safety_checks=False,
        price=namespace_price_stacks_too_early_1_btc,
        tx_fee=50000)
    testlib.blockstack_namespace_preorder("old_btc_1", wallets[1].addr,
                                          wallets[0].privkey)
    btc_too_late_tx = testlib.blockstack_namespace_preorder('btc_too_late',
                                                            wallets[1].addr,
                                                            wallets[2].privkey,
                                                            tx_only=True)

    print ''
    print btc_too_late_tx
    print ''

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

    # should be accepted
    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)

    # the stacks_too_early namespace cannot be revealed (i.e. its preorder got rejected)
    testlib.blockstack_namespace_reveal(
        "stacks_too_early_1",
        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.NAMESPACE_VERSION_PAY_WITH_STACKS,
        safety_checks=False,
        tx_fee=50000)
    testlib.next_block(**kw)  # end of 690
    testlib.expect_snv_fail_at('stacks_too_early_1',
                               testlib.get_current_block(**kw))

    res = testlib.blockstack_cli_get_namespace_blockchain_record('test')
    if 'error' in res:
        print 'test was not revealed'
        print res
        return False

    res = testlib.blockstack_cli_get_namespace_blockchain_record(
        'stacks_too_early_1')
    if 'error' not in res:
        print 'stacks too early 1 was revealed'
        print res
        return False

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

    # should succeed---last block we can pay in BTC
    testlib.blockstack_namespace_preorder("old_btc_2",
                                          wallets[1].addr,
                                          wallets[0].privkey,
                                          price=namespace_price_old_btc_2)

    # should be rejected---this is one block early
    testlib.blockstack_namespace_preorder(
        "stacks_too_early_2",
        wallets[1].addr,
        wallets[0].privkey,
        safety_checks=False,
        price=namespace_price_stacks_too_early_2_stacks,
        tx_fee=50000,
        expect_reject=True)
    testlib.next_block(**kw)  # end of 693
    testlib.expect_snv_fail_at('stacks_too_early_2',
                               testlib.get_current_block(**kw))

    # should succeed even though preordered with BTC
    testlib.blockstack_namespace_reveal(
        "old_btc_1",
        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.NAMESPACE_VERSION_PAY_WITH_STACKS)

    # should fail -- no preorder
    testlib.blockstack_namespace_reveal(
        "stacks_too_early_2",
        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.NAMESPACE_VERSION_PAY_WITH_STACKS,
        safety_checks=False,
        tx_fee=50000)

    # should be rejected---it's a block too late
    testlib.broadcast_transaction(btc_too_late_tx['transaction'])

    testlib.next_block(**kw)  # end of 694
    testlib.expect_snv_fail_at('stacks_too_early_2',
                               testlib.get_current_block(**kw))

    res = testlib.blockstack_cli_get_namespace_blockchain_record(
        'stacks_too_early_2')
    if 'error' not in res:
        print 'stacks too early 2 was revealed'
        print res
        return False

    res = testlib.blockstack_cli_get_namespace_blockchain_record('old_btc_1')
    if 'error' in res:
        print 'old_btc_1 not revealed'
        print res
        return False

    # should succeed, even though we're in the STACKS epoch
    testlib.blockstack_namespace_reveal(
        "old_btc_2",
        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.NAMESPACE_VERSION_PAY_WITH_STACKS)

    # should fail, since the preorer for btc_too_late was sent too late
    testlib.blockstack_namespace_reveal(
        "btc_too_late",
        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[2].privkey,
        version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS)
    testlib.next_block(**kw)  # end of 695
    testlib.expect_snv_fail_at('btc_too_late', testlib.get_current_block(**kw))

    res = testlib.blockstack_cli_get_namespace_blockchain_record('old_btc_2')
    if 'error' in res:
        print 'failed to reveal btc 2'
        print res
        return False

    res = testlib.blockstack_cli_get_namespace_blockchain_record(
        'btc_too_late')
    if 'error' not in res:
        print 'revealed btc_too_late'
        print res
        return False
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)
    res = testlib.blockstack_namespace_preorder("teststacks",
                                                wallets[1].addr,
                                                wallets[3].privkey,
                                                safety_checks=False,
                                                price={
                                                    'units': 'STACKS',
                                                    'amount': 64000000
                                                },
                                                tx_only=True)
    ns_preorder_tx_stacks = res['transaction']

    res = testlib.blockstack_namespace_preorder('test2',
                                                wallets[1].addr,
                                                wallets[2].privkey,
                                                tx_only=True)
    ns_preorder_tx = res['transaction']

    testlib.broadcast_transaction(ns_preorder_tx_stacks)

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

    # should have only accepted one operation
    block_stats = virtualchain.lib.indexer.StateEngine.get_block_statistics(
        testlib.get_current_block(**kw))
    if block_stats['num_parsed_ops'] != 1:
        print 'invalid number of parsed ops: {}'.format(
            block_stats['num_parsed_ops'])
        return False

    # try to register a Stacks transaction (should fail)
    testlib.blockstack_namespace_reveal(
        "teststacks", 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[3].privkey)

    testlib.next_block(**kw)  # end of 690, begin Stacks
    testlib.expect_snv_fail_at('teststacks', testlib.get_current_block(**kw))

    # should not be accepted, since no stacks are paid
    testlib.broadcast_transaction(ns_preorder_tx)

    # should succeed, even though preordered after the Stacks token activation
    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)  # end of 690

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

    # should fail
    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[2].privkey)
    testlib.next_block(**kw)