Exemple #1
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))
Exemple #2
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)

    # derive importer keys and do imports
    # NOTE: breaks consensus trace from 0.14.0
    private_keychain = keychain.PrivateKeychain.from_private_key(
        wallets[1].privkey)
    private_keys = [
        wallets[1].privkey
    ]  # NOTE: always start with the reveal key, then use children
    for i in xrange(0, 3):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds(
            wallets[1].privkey, 100000000,
            virtualchain.BitcoinPrivateKey(import_key).public_key().address())
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)

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

    testlib.next_block(**kw)

    resp = testlib.blockstack_name_import(
        "foo.test", addr_reencode("1ARVjrtKnUVWt2GNrpuFLnNCL2WGUhKdkW"),
        "33" * 20, private_keys[2])  # derived child 2
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    resp = testlib.blockstack_name_import(
        "foo.test", addr_reencode("1PYu4vKB3g2QLDFdurxqYSJ9aJSed7tne1"),
        "22" * 20, private_keys[1])  # derived child 1
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    testlib.blockstack_namespace_ready("test", wallets[1].privkey)
    testlib.next_block(**kw)
    def do_POST(self):
        content_type = self.headers.getheader('content-type')
        postvars = {}

        if content_type is not None:
            ctype, pdict = cgi.parse_header(content_type)
            if ctype == 'multipart/form-data':
                postvars = cgi.parse_multipart(self.rfile, pdict)
            elif ctype == 'application/x-www-form-urlencoded':
                length = int(self.headers.getheader('content-length'))
                postvars = cgi.parse_qs(self.rfile.read(length),
                                        keep_blank_values=1)

        if self.path == '/sendfunds':
            # fund an address
            addr = postvars.get('addr', [None])
            value = postvars.get('value', [None])

            if addr[0] is None or value[0] is None:
                log.error("Missing addr or value")
                self.send_response(400,
                                   "Invalid request: missing addr or value")
                self.end_headers()
                return

            try:
                value = int(value[0])
                addr = virtualchain.address_reencode(addr[0])
            except:
                log.error("Failed to read addr and/or value")
                log.error("postvars = {}".format(postvars))
                self.send_response(400, "Invalid addr or value")
                self.end_headers()
                return

            # can't take more than 0.1 BTC per address

            # send funds
            res = testlib.send_funds(
                testlib.get_default_payment_wallet().privkey, value, addr)
            if 'error' in res:
                log.error("Failed to send {} from {} to {}: {}".format(
                    value,
                    testlib.get_default_payment_wallet().privkey, addr, res))
                self.send_response(400, "Failed to send value")
                self.end_headers()
                return

            self.send_response(302)
            self.send_header('location', '/')
            self.end_headers()
            return

        else:
            log.error("Unsupported path {}".format(self.path))
            self.send_response(400, "Only support /sendfunds at this time")
            self.end_headers()
            return
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 )
    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 + 1, wallets[0].privkey)
    testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price + 1, 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 Stacks
    testlib.blockstack_name_preorder( "foo.test", pk, addr2, price={'units': 'STACKS', 'amount': stacks_price + 1})
    testlib.next_block( **kw )

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

    # renew using Stacks
    testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price + 1})
    testlib.next_block(**kw)
def scenario( wallets, **kw ):

    # try to spend tokens to ourselves
    testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False, expect_fail=True)
    testlib.next_block(**kw) # end of 689

    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0

    # try to spend more tokens than we have 
    testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 600001, wallets[0].privkey, safety_checks=False, expect_fail=True)
    testlib.next_block(**kw)

    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0

    # try to spend tokens that don't exist
    testlib.blockstack_send_tokens(wallets[1].addr, "noop", 600000, wallets[0].privkey, safety_checks=False, expect_fail=True)
    testlib.next_block(**kw)

    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0
   
    # try to spend tokens with an invalid consensus hash (note that this is epoch 4)
    testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 600000, wallets[0].privkey, consensus_hash='00' * 16, safety_checks=False, expect_fail=True)
    testlib.next_block(**kw)
    
    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0

    # try to spend tokens from an account that doesn't exist
    pk = virtualchain.lib.ecdsalib.ecdsa_private_key().to_hex()
    addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk))
    testlib.send_funds(wallets[0].privkey, 10240000, addr)

    testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, pk, safety_checks=False, expect_fail=True)
    testlib.next_block(**kw)

    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0

    # try to send 0 tokens
    testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 0, wallets[0].privkey, safety_checks=False, expect_fail=True)
    testlib.next_block(**kw)

    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0
Exemple #6
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 + 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.next_block(**kw)

    # preorder/register using Stacks, but overpay
    testlib.blockstack_name_preorder( "foo.test", pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price + 2}, expect_fail=True, safety_checks=False)
    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.blockstack_name_register( "foo.test", pk, wallets[3].addr ) # should fail
    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 )

    # derive importer keys and do imports
    # NOTE: breaks consensus trace from 0.14.0
    private_keychain = keychain.PrivateKeychain.from_private_key( wallets[1].privkey )
    private_keys = [wallets[1].privkey]     # NOTE: always start with the reveal key, then use children
    for i in xrange(0, 3):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds( wallets[1].privkey, 100000000, virtualchain.BitcoinPrivateKey(import_key).public_key().address() )
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)

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

    testlib.next_block( **kw )

    resp = testlib.blockstack_name_import( "foo.test", addr_reencode("1ARVjrtKnUVWt2GNrpuFLnNCL2WGUhKdkW"), "33" * 20, private_keys[2] )    # derived child 2
    if 'error' in resp:
        print json.dumps(resp, indent=4 )

    testlib.next_block( **kw )

    resp = testlib.blockstack_name_import( "foo.test", addr_reencode("1PYu4vKB3g2QLDFdurxqYSJ9aJSed7tne1"), "22" * 20, private_keys[1] )    # derived child 1
    if 'error' in resp:
        print json.dumps(resp, indent=4 )

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

    # pass 100 stacks around in a circle.
    new_keys = [wallets[0].privkey] + [
        virtualchain.lib.ecdsalib.ecdsa_private_key().to_hex()
        for i in range(0, 4)
    ]
    for k in range(0, 4):
        for j in range(0, len(new_keys)):
            i = j

            new_addr = virtualchain.get_privkey_address(
                new_keys[(i + 1) % len(new_keys)])
            cur_addr = virtualchain.get_privkey_address(
                new_keys[i % len(new_keys)])

            initial_new_balance_info = json.loads(
                testlib.nodejs_cli('balance', new_addr))
            initial_cur_balance_info = json.loads(
                testlib.nodejs_cli('balance', cur_addr))

            print '\n initial new balance info: {} \n'.format(
                initial_new_balance_info)

            if 'STACKS' not in initial_new_balance_info:
                initial_new_balance_info['STACKS'] = 0

            if i > 0:
                testlib.send_funds(wallets[0].privkey, 500000, cur_addr)

            testlib.send_funds(wallets[0].privkey, 500000, new_addr)

            testlib.blockstack_send_tokens(new_addr,
                                           'STACKS',
                                           100,
                                           new_keys[i % len(new_keys)],
                                           safety_checks=False)

            # consolidate
            utxos = testlib.get_utxos(wallets[0].addr)
            if len(utxos) > 1:
                balance = testlib.get_balance(wallets[0].addr)
                testlib.send_funds(wallets[0].privkey,
                                   balance - 5500,
                                   wallets[0].addr,
                                   change=False)

            utxos = testlib.get_utxos(new_addr)
            if len(utxos) > 1:
                balance = testlib.get_balance(new_addr)
                testlib.send_funds(new_keys[(i + 1) % len(new_keys)],
                                   balance - 5500,
                                   new_addr,
                                   change=False)

        testlib.next_block(**kw)

        for j in range(0, len(new_keys)):
            i = j

            new_addr = virtualchain.get_privkey_address(
                new_keys[(i + 1) % len(new_keys)])
            cur_addr = virtualchain.get_privkey_address(
                new_keys[i % len(new_keys)])

            if j == len(new_keys) - 1:
                if (i + 1) % len(new_keys) != 0:
                    # last address should have 100 stacks, unless new_addr is wallets[0]
                    balance_info = json.loads(
                        testlib.nodejs_cli('balance', new_addr))
                    assert int(balance_info['STACKS']) == 100

            else:
                if i % len(new_keys) != 0:
                    # every other address, except wallets[0], should have 0 balance
                    balance_info = json.loads(
                        testlib.nodejs_cli('balance', cur_addr))
                    assert int(balance_info['STACKS']) == 0

        # consolidate
        for j in range(0, len(new_keys)):
            cur_addr = virtualchain.get_privkey_address(
                new_keys[i % len(new_keys)])
            utxos = testlib.get_utxos(cur_addr)
            if len(utxos) > 1:
                balance = testlib.get_balance(cur_addr)
                testlib.send_funds(new_keys[i % len(new_keys)],
                                   balance - 5500,
                                   cur_addr,
                                   change=False)

        testlib.next_block(**kw)

    # each *new* address has 4 history items -- four spends, four receives
    for new_key in new_keys[1:]:
        new_addr = virtualchain.get_privkey_address(new_key)
        history = requests.get(
            'http://localhost:16268/v1/accounts/{}/history?page=0'.format(
                new_addr)).json()

        # should have gotten 4 debits for 100, and 4 credits for 100
        assert int(history[0]['credit_value']) == 400, history
        assert int(history[0]['debit_value']) == 400, history

        assert len(history) == 8, history
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
Exemple #10
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):

    print '\nactivating segwit\n'

    virtualchain.set_features("segwit", True)

    print '\nsegwit state: {}\n'.format(virtualchain.get_features('segwit'))

    testlib.blockstack_namespace_preorder("test", wallets[1].addr,
                                          wallets[5].privkey)
    testlib.blockstack_namespace_preorder("mult", wallets[2].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[5].privkey)
    testlib.blockstack_namespace_reveal(
        "mult",
        wallets[2].addr,
        52595,
        250,
        4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        10,
        10,
        wallets[0].privkey,
        version_bits=2)
    testlib.next_block(**kw)

    private_keychain = keychain.PrivateKeychain.from_private_key(
        wallets[2].privkey)
    private_keys = [
        wallets[2].privkey
    ]  # NOTE: always start with the reveal key, then use children
    for i in xrange(0, 4):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds(
            wallets[1].privkey, 100000000,
            virtualchain.BitcoinPrivateKey(import_key).public_key().address())
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)

    # should succeed
    resp = testlib.blockstack_name_import("foo.mult", wallets[2].addr,
                                          '00' * 20, private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    # should succeed
    resp = testlib.blockstack_name_import("bar.mult", wallets[3].addr,
                                          "11" * 20, private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    # should succeed
    resp = testlib.blockstack_name_import("baz.mult", wallets[4].addr,
                                          "22" * 20, private_keys[2])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    # should succeed
    resp = testlib.blockstack_name_import("goo.mult", wallets[5].addr,
                                          "33" * 20, private_keys[3])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

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

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

    # get prices
    hello_cost = testlib.blockstack_get_name_cost('hello.mult')
    world_cost = testlib.blockstack_get_name_cost('world.mult')
    foo_cost = testlib.blockstack_get_name_cost('foo.mult')

    # register/renew
    res = testlib.blockstack_name_preorder("hello.mult", wallets[1].privkey,
                                           wallets[2].addr)
    if 'error' in res:
        print res
        return False

    res = testlib.blockstack_name_preorder('world.mult',
                                           wallets[6].privkey,
                                           wallets[7].addr,
                                           wallet=wallets[7])
    if 'error' in res:
        print res
        return False

    res = testlib.blockstack_name_renew('foo.mult', wallets[2].privkey)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)

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

    if new_namespace_balance != namespace_balance + hello_cost + world_cost + foo_cost:
        print 'wrong balance'
        print new_namespace_balance
        print namespace_balance
        print hello_cost
        print foo_cost
        return False

    res = testlib.blockstack_name_register("hello.mult", wallets[1].privkey,
                                           wallets[2].addr)
    if 'error' in res:
        print res
        return False

    res = testlib.blockstack_name_register('world.mult',
                                           wallets[6].privkey,
                                           wallets[7].addr,
                                           wallet=wallets[7],
                                           zonefile_hash='44' * 20)
    if 'error' in res:
        print res
        return False

    testlib.next_block(**kw)
Exemple #12
0
def scenario(wallets, **kw):

    global owner_address

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

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

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

    # pre-0.13 wallet
    legacy_wallet = testlib.make_legacy_014_wallet(wallets[2].privkey,
                                                   wallets[4].privkey,
                                                   wallets[0].privkey,
                                                   "0123456789abcdef")
    testlib.store_wallet(legacy_wallet)

    res = testlib.ysi_cli_setup_wallet("0123456789abcdef")
    if 'error' in res:
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    if not res.has_key('backup_wallet'):
        print "no backup_wallet"
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    if not os.path.exists(res['backup_wallet']):
        print "backup wallet doesn't exist"
        print json.dumps(res, indent=4, sort_keys=True)
        return False

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

    payment_address = str(res['payment_address'])
    owner_address = str(res['owner_address'])

    # fill wallet with 5 BTC
    res = testlib.send_funds(wallets[3].privkey, 5 * 10**8, payment_address)
    if 'error' in res:
        print "failed to fill wallet"
        print json.dumps(res)
        return False

    testlib.next_block(**kw)

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

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

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

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

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

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

    print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge update"
    time.sleep(10)
def scenario(wallets, **kw):

    # has the side-effect of starting the API server
    resp = testlib.blockstack_client_initialize_wallet("0123456789abcdef",
                                                       wallets[2].privkey,
                                                       wallets[3].privkey,
                                                       wallets[4].privkey)
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

    private_keychain = keychain.PrivateKeychain.from_private_key(
        wallets[1].privkey)
    private_keys = [
        wallets[1].privkey
    ]  # NOTE: always start with the reveal key, then use children
    for i in xrange(0, 4):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds(
            wallets[1].privkey, 100000000,
            virtualchain.BitcoinPrivateKey(import_key).public_key().address())
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)

    # should fail (first key must be revealer)
    resp = testlib.blockstack_cli_name_import("fail.test", wallets[2].addr,
                                              "Hello fail.test!",
                                              private_keys[1])
    if 'error' not in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    # should succeed
    resp = testlib.blockstack_cli_name_import("foo.test", wallets[2].addr,
                                              "Hello foo.test!",
                                              private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    # 3 in one block (zero-conf)
    resp = testlib.blockstack_cli_name_import("bar.test", wallets[3].addr,
                                              "Hello bar.test!",
                                              private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_cli_name_import("baz.test", wallets[4].addr,
                                              "Hello baz.test!",
                                              private_keys[2])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_cli_name_import("goo.test", wallets[5].addr,
                                              "Hello goo.test!",
                                              private_keys[3])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    # should fail (wrong key)
    resp = testlib.blockstack_cli_name_import("fail.test", wallets[5].addr,
                                              "Hello fail.test!",
                                              wallets[2].privkey)
    if 'error' not in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

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

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

    print "Waiting 10 seconds for registrar to replicate zone files"
    time.sleep(10)
def scenario( wallets, **kw ):
    patch_file_contents = '\n'.join(patch_file_addrs)
    
    h = hashlib.new('sha256')
    h.update(patch_file_contents)
    patch_file_hash = h.hexdigest()

    with open(patch_addrs_path, 'w') as f:
        f.write(patch_file_contents)

    for k in genesis_patches_files:
        genesis_patches_files[k]['sha256'] = patch_file_hash

    blockstack.lib.config.set_genesis_block_patches(genesis_patches)
    blockstack.lib.config.set_genesis_block_patches_files(genesis_patches_files)
    testlib.set_account_audits(False)

    # in block 689, so the patch hasn't taken place yet
    balances = testlib.get_wallet_balances(wallets)
    assert balances[wallets[0].addr][STACKS] == 100 + 600000
    assert balances[wallets[1].addr][STACKS] == 123 + 1000
    assert balances[wallets[2].addr][STACKS] == 0

    # send some tokens to a brand-new address
    testlib.blockstack_send_tokens(new_addr, "STACKS", 600000, wallets[0].privkey)
    testlib.blockstack_send_tokens(new_unlocked_addr, "STACKS", 100, wallets[0].privkey)
    testlib.next_block(**kw) # end of 689, triggers vesting of block 690
    
    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 2

    # new balances should reflect patch
    balances = testlib.get_addr_balances([w.addr for w in wallets] + [new_addr_b58, new_grant_addr_b58, new_unlocked_addr_b58])
    print balances

    assert balances[wallets[0].addr][STACKS] == 100 + 200 + 600000 + 600001 + 10000 + 10001 + 10002 + 10003 + 10004 + 10005 - 600000 - 100         # += new value + retroactive vesting
    assert balances[wallets[1].addr][STACKS] == 123 + 1000 + (10000000 * 10)
    assert balances[wallets[2].addr][STACKS] == 123456
    assert balances[new_addr_b58][STACKS] == 600000 + 222222 + 66
    assert balances[new_grant_addr_b58][STACKS] == 567 + (10000000 * 10)
    assert balances[new_unlocked_addr_b58][STACKS] == 100 + 123456 + 22000 + 22001 + 22002 + 22003 + 22004 + 22005

    # send some tokens to a brand-new address
    # should be transfer-locked
    testlib.blockstack_send_tokens(new_addr_b58, "STACKS", 600000, wallets[0].privkey, safety_checks=False, expect_fail=True)
    testlib.blockstack_send_tokens(new_grant_addr_b58, "STACKS", 1, new_wallet, safety_checks=False, expect_fail=True)
    testlib.blockstack_send_tokens(new_grant_addr_b58, "STACKS", 10000000, wallets[1].privkey, safety_checks=False)
    testlib.blockstack_send_tokens(new_addr_b58, "STACKS", 10000000, wallets[1].privkey, safety_checks=False)
    testlib.blockstack_send_tokens(new_grant_addr_b58, "STACKS", 3, new_unlocked_wallet, safety_checks=False)
    testlib.next_block(**kw)  # 690

    assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 3
    
    balances = testlib.get_addr_balances([w.addr for w in wallets] + [new_addr_b58, new_grant_addr_b58, new_unlocked_addr_b58])
    print balances

    assert balances[wallets[0].addr][STACKS] == 100 + 200 + 600000 + 600001 + 600010 + 10000 + 10001 + 10002 + 10003 + 10004 + 10005 + 10006 - 600000 - 100         # += new value + retroactive vesting
    assert balances[wallets[1].addr][STACKS] == 123 + 1000 + (10000000 * 10) - 10000000 - 10000000
    assert balances[wallets[2].addr][STACKS] == 123456
    assert balances[new_addr_b58][STACKS] == 600000 + 222222 + 66 + 10000000
    assert balances[new_grant_addr_b58][STACKS] == 567 + (10000000 * 10) + 10000000 + 3
    assert balances[new_unlocked_addr_b58][STACKS] == 100 + 123456 + 22000 + 22001 + 22002 + 22003 + 22004 + 22005 + 22006 - 3

    # apply patches from files
    balances = testlib.get_addr_balances(patch_file_addrs[0:5])
    print balances

    for addr in patch_file_addrs[0:5]:
        assert balances[addr].get(STACKS, 0) == 0

    testlib.next_block(**kw)    # make the balances real (end of 691)

    balances = testlib.get_addr_balances(patch_file_addrs[0:5])
    for addr in patch_file_addrs[0:5]:
        assert balances[addr][STACKS] == 12345
    
    # apply patches from files
    balances_before_patch = testlib.get_addr_balances(patch_file_addrs[5:8])
    print balances_before_patch

    assert balances_before_patch[new_addr_b58][STACKS] == 600000 + 222222 + 66 + 10000000
    assert balances_before_patch[new_grant_addr_b58][STACKS] == 567 + (10000000 * 10) + 10000000 + 3
    assert balances_before_patch[new_unlocked_addr_b58][STACKS] == 100 + 123456 + 22000 + 22001 + 22002 + 22003 + 22004 + 22005 + 22006 + 22007 - 3

    testlib.next_block(**kw)    # make the balances real (end of 692)

    balances_after_patch = testlib.get_addr_balances(patch_file_addrs[5:8])

    assert balances_after_patch[new_addr_b58][STACKS] == 600000 + 222222 + 66 + 10000000 + 23456
    assert balances_after_patch[new_grant_addr_b58][STACKS] == 567 + (10000000 * 10) + 10000000 + 3 + 23456
    assert balances_after_patch[new_unlocked_addr_b58][STACKS] == 100 + 123456 + 22000 + 22001 + 22002 + 22003 + 22004 + 22005 + 22006 + 22007 + 22008 - 3 + 23456

    # drain-transfer from newly-granted
    for (addr, privkey) in zip(patch_file_addrs[0:5], patch_file_privkeys):
        testlib.send_funds(wallets[0].privkey, 388500, virtualchain.address_reencode(addr))
        testlib.blockstack_send_tokens(new_addr_b58, "STACKS", 12345, privkey)

    testlib.next_block(**kw)
    
    balances_after_xfer = testlib.get_addr_balances(patch_file_addrs)
    print balances_after_xfer

    for addr in patch_file_addrs[0:5]:
        assert balances_after_xfer[addr].get(STACKS, 0) == 0

    assert balances_after_xfer[new_addr_b58][STACKS] == 600000 + 222222 + 66 + 10000000 + 23456 + 12345*5
    assert balances_after_xfer[new_grant_addr_b58][STACKS] == 567 + (10000000 * 10) + 10000000 + 3 + 23456
    assert balances_after_xfer[new_unlocked_addr_b58][STACKS] == 100 + 123456 + 22000 + 22001 + 22002 + 22003 + 22004 + 22005 + 22006 + 22007 + 22008 + 22009 - 3 + 23456
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):
    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)
Exemple #17
0
def scenario(wallets, **kw):

    # make a test namespace
    resp = testlib.ysi_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.ysi_namespace_reveal(
        "test", wallets[1].addr, 52595, 250, 4,
        [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10,
        wallets[0].privkey)
    if debug or 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # derive importer keys and do imports
    # NOTE: breaks consensus trace from 0.14.0
    private_keychain = keychain.PrivateKeychain.from_private_key(
        wallets[1].privkey)
    private_keys = [
        wallets[1].privkey
    ]  # NOTE: always start with the reveal key, then use children
    for i in xrange(0, 3):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds(
            wallets[1].privkey, 100000000,
            virtualchain.BitcoinPrivateKey(import_key).public_key().address())
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)

    resp = testlib.ysi_name_import("foo.test", wallets[3].addr, "11" * 20,
                                   private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # import twice
    resp = testlib.ysi_name_import("bar.test", wallets[4].addr, "22" * 20,
                                   private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    resp = testlib.ysi_name_import("bar.test", wallets[4].addr, "33" * 20,
                                   private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # import thrice in the same block
    resp = testlib.ysi_name_import("baz.test", wallets[5].addr, "44" * 20,
                                   private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("baz.test", wallets[5].addr, "55" * 20,
                                   private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("baz.test", wallets[5].addr, "66" * 20,
                                   private_keys[2])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # import all three in the same block
    resp = testlib.ysi_name_import("foo.test", wallets[5].addr, "66" * 20,
                                   private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("bar.test", wallets[3].addr, "77" * 20,
                                   private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("baz.test", wallets[4].addr, "88" * 20,
                                   private_keys[2])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # import thrice in the same block, again
    resp = testlib.ysi_name_import("baz.test", wallets[5].addr, "44" * 20,
                                   private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("baz.test", wallets[5].addr, "55" * 20,
                                   private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("baz.test", wallets[5].addr, "66" * 20,
                                   private_keys[2])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

    # import all three in the same block, again
    resp = testlib.ysi_name_import("foo.test", wallets[5].addr, "66" * 20,
                                   private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("bar.test", wallets[3].addr, "77" * 20,
                                   private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    resp = testlib.ysi_name_import("baz.test", wallets[4].addr, "88" * 20,
                                   private_keys[2])
    if 'error' in resp:
        print json.dumps(resp, indent=4)

    testlib.next_block(**kw)

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

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

    testlib.next_block( **kw )

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

    testlib.next_block( **kw )
    
    # import 3 names in the same block: foo.test, bar.test, baz.test
    names = ['foo.test', 'bar.test', 'baz.test']
    name_preorder_wallets = [wallets[2], wallets[3], wallets[4]]
    name_register_wallets = [wallets[5], wallets[6], wallets[7]]
    name_transfer_wallets = [wallets[6], wallets[7], wallets[5]]

    # derive importer keys and do imports
    # NOTE: breaks consensus trace from 0.14.0
    private_keychain = keychain.PrivateKeychain.from_private_key( wallets[1].privkey )
    private_keys = [wallets[1].privkey]     # NOTE: always start with the reveal key, then use children
    for i in xrange(0, len(names)-1):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds( wallets[1].privkey, 100000000, virtualchain.BitcoinPrivateKey(import_key).public_key().address() )
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)


    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]
        import_key = private_keys[i]

        resp = testlib.blockstack_name_import( name, register_wallet.addr, str(9 - i) * 40, import_key, safety_checks=False )
        if debug or  'error' in resp:
            print json.dumps( resp, indent=4 )

   
    testlib.next_block( **kw )

    # namespace ready...
    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 )

    # update 3 names in the same block
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]

        resp = testlib.blockstack_name_update( name, str(i + 2) * 40, register_wallet.privkey )
        if debug or  'error' in resp:
            print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # update 3 names in the same block, again
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]

        resp = testlib.blockstack_name_update( name, str(i + 1) * 40, register_wallet.privkey )
        if debug or  'error' in resp:
            print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # transfer 3 names in the same block 
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]
        transfer_wallet = name_transfer_wallets[i]

        resp = testlib.blockstack_name_transfer( name, transfer_wallet.addr, True, register_wallet.privkey ) 
        if debug or  'error' in resp:
            print json.dumps( resp, indent=4 )

    testlib.next_block( **kw )

    # exchange after transfer...
    tmp = name_register_wallets
    name_register_wallets = name_transfer_wallets
    name_transfer_wallets = tmp

    # revoke 3 names in the same block 
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]

        resp = testlib.blockstack_name_revoke( name, register_wallet.privkey )
        if debug or 'error' in resp:
            print json.dumps( resp, indent=4 )

    # iterate the blocks a few times 
    for i in xrange(0, 5):
        testlib.next_block( **kw )
def scenario(wallets, **kw):

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

    testlib.blockstack_namespace_reveal(
        "test",
        wallets[1].addr,
        52595,
        250,
        4, [6, 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)
Exemple #20
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 ):

    global owner_address

    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 )

    # pre-0.13 wallet
    legacy_wallet = testlib.make_legacy_013_wallet( wallets[2].privkey, wallets[4].privkey, "0123456789abcdef" )
    testlib.store_wallet( legacy_wallet )

    res = testlib.blockstack_cli_setup_wallet("0123456789abcdef")
    if 'error' in res:
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    if not res.has_key('backup_wallet'):
        print "no backup_wallet"
        print json.dumps(res, indent=4, sort_keys=True)
        return False

    if not os.path.exists(res['backup_wallet']):
        print "backup wallet doesn't exist"
        print json.dumps(res, indent=4, sort_keys=True)
        return False

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

    payment_address = str(res['payment_address'])
    owner_address = str(res['owner_address'])

    # fill wallet with 5 BTC
    res = testlib.send_funds( wallets[3].privkey, 5 * 10**8, payment_address )
    if 'error' in res:
        print "failed to fill wallet"
        print json.dumps(res)
        return False
   
    testlib.next_block( **kw )

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

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

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

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

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

    print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge update"
    time.sleep(10)
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)

    # 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
Exemple #24
0
    def do_POST(self):
        content_type = self.headers.getheader('content-type')
        postvars = {}
        txid = None

        if content_type is not None:
            ctype, pdict = cgi.parse_header(content_type)
            if ctype == 'multipart/form-data':
                postvars = cgi.parse_multipart(self.rfile, pdict)
            elif ctype == 'application/x-www-form-urlencoded':
                length = int(self.headers.getheader('content-length'))
                postvars = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1)

        if self.path == '/sendBTC':
            # fund an address with bitcoin
            addr = postvars.get('addr', [None])
            value = postvars.get('value', [None])

            if addr[0] is None or value[0] is None:
                log.error("Missing addr or value")
                self.error_page(400, "Invalid request: missing addr or value")
                return

            # addr can be either base58check or c32check
            if re.match('^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+$', addr[0]):
                # c32check 
                try:
                    res = testlib.nodejs_cli('convert_address', addr[0])
                    res = json.loads(res)
                    addr = [res['BTC']]
                except:
                    self.error_page(500, 'Failed to convert {} to a Stacks address'.format(addr[0]))
                    self.end_headers()
                    return

            try:
                value = int(value[0])
                addr = virtualchain.address_reencode(addr[0])
            except:
                log.error("Failed to read addr and/or value")
                log.error("postvars = {}".format(postvars))
                self.error_page(400, "Invalid addr or value")
                return

            # don't take too much
            if value > 10000000:
                log.error('{} requested too much ({})'.format(addr, value))
                self.error_page(400, 'Requested too much BTC (at most {} is allowed)'.format(10000000))
                return 

            # send funds
            res = testlib.send_funds(testlib.get_default_payment_wallet().privkey, value, addr)
            if 'error' in res:
                log.error("Failed to send {} BTC from {} to {}: {}".format(
                    value, testlib.get_default_payment_wallet().privkey, addr, res
                ))
                self.error_page(400, "Failed to send value")
                return

            txid = res['txid']

            self.send_response(302)
            location = '/'
            if txid:
                location = '/?bitcoinTxid={}'.format(txid)

            self.send_header('location', location)
            self.end_headers()
            return

        elif self.path == '/sendStacks':
            # fund an address with bitcoin
            addr = postvars.get('addr', [None])
            value = postvars.get('value', [None])

            if addr[0] is None or value[0] is None:
                log.error("Missing addr or value")
                log.error("Got {}".format(postvars))
                self.error_page(400, "Invalid request: missing addr or value")
                self.end_headers()
                return

            # addr can be either base58check or c32check
            if re.match('^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+$', addr[0]):
                # c32check 
                try:
                    res = testlib.nodejs_cli('convert_address', addr[0])
                    res = json.loads(res)
                    addr = [res['BTC']]
                except:
                    self.error_page(500, 'Failed to convert {} to a Stacks address'.format(addr[0]))
                    self.end_headers()
                    return

            try:
                value = int(value[0])
                addr = virtualchain.address_reencode(str(addr[0]))
            except:
                log.error("Failed to read addr and/or value")
                log.error('addr = {}, value = {}'.format(addr[0], value[0]))
                self.error_page(400, "Invalid addr or value")
                self.end_headers()
                return

            # don't take too much
            if value > 1000000000:
                log.error('{} requested too much ({})'.format(addr, value))
                self.error_page(400, 'Requested too much STACKS (at most {} is allowed)'.format(1000000000))
                self.end_headers()
                return 

            # send funds
            res = None
            try:
                res = testlib.blockstack_send_tokens(addr, 'STACKS', value, wallets[3].privkey)
                txid = res['transaction_hash']
            except Exception as e:
                log.exception(e)
                self.error_page(500, 'Failed to send tokens to {}\n{}'.format(addr, ''.join(traceback.format_exc())))
                self.end_headers()
                return
                
            if 'error' in res:
                log.error("Failed to send {} Stacks from {} to {}: {}".format(
                    value, testlib.get_default_payment_wallet().privkey, addr, res
                ))
                self.error_page(400, "Failed to send value")
                self.end_headers()
                return

            # also send some BTC
            res = testlib.send_funds(testlib.get_default_payment_wallet().privkey, 5000000, addr)
            if 'error' in res:
                log.error("Failed to send {} BTC from {} to {}: {}".format(
                    value, testlib.get_default_payment_wallet().privkey, addr, res
                ))
                self.error_page(400, "Failed to send value")
                return

            self.send_response(302)
            location = '/'
            if txid:
                location = '/?stacksTxid={}'.format(txid)

            self.send_header('location', location)
            self.end_headers()
            return

        else:
            log.error("Unsupported path {}".format(self.path))
            self.error_page(400, "Only support /sendfunds at this time")
            self.end_headers()
            return
def scenario( wallets, **kw ):

    # has the side-effect of starting the API server
    resp = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey )
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

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

    testlib.next_block(**kw)

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

    testlib.next_block(**kw)

    private_keychain = keychain.PrivateKeychain.from_private_key( wallets[1].privkey )
    private_keys = [wallets[1].privkey]     # NOTE: always start with the reveal key, then use children
    for i in xrange(0, 4):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds( wallets[1].privkey, 100000000, virtualchain.BitcoinPrivateKey(import_key).public_key().address() )
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)

    # should fail (first key must be revealer)
    resp = testlib.blockstack_cli_name_import("fail.test", wallets[2].addr, "Hello fail.test!", private_keys[1])
    if 'error' not in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    # should succeed
    resp = testlib.blockstack_cli_name_import("foo.test", wallets[2].addr, "Hello foo.test!", private_keys[0])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)
   
    # 3 in one block (zero-conf)
    resp = testlib.blockstack_cli_name_import("bar.test", wallets[3].addr, "Hello bar.test!", private_keys[1])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_cli_name_import("baz.test", wallets[4].addr, "Hello baz.test!", private_keys[2])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    resp = testlib.blockstack_cli_name_import("goo.test", wallets[5].addr, "Hello goo.test!", private_keys[3])
    if 'error' in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

    testlib.next_block(**kw)

    # should fail (wrong key)
    resp = testlib.blockstack_cli_name_import("fail.test", wallets[5].addr, "Hello fail.test!", wallets[2].privkey)
    if 'error' not in resp:
        print json.dumps(resp, indent=4, sort_keys=True)
        return False

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

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

    print "Waiting 10 seconds for registrar to replicate zone files"
    time.sleep(10)
Exemple #26
0
def scenario(wallets, **kw):

    global debug, consensus, small_unspents

    res = check_utxo_consumption(
        "test", wallets[0], wallets[1], wallets[2],
        ['namespace_preorder', 'namespace_reveal', 'namespace_ready'],
        wallets[1].addr, **kw)
    if 'error' in res:
        return False

    expected_utxo_count = res['expected_utxo_count']

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

    testlib.next_block(**kw)

    # verify that all the small UTXOs are NOT consumed
    bitcoind = testlib.connect_bitcoind()
    bitcoind.ping()

    txdata = bitcoind.getrawtransaction(resp['transaction_hash'], 1)
    if len(txdata['vin']) != 1:
        print simplejson.dumps(txdata, indent=4)
        print "wrong number of inputs: {} != 1".format(len(txdata['vin']))
        return False

    if spent_small_transaction(resp['transaction_hash']):
        return False

    # finish ordering the namespace
    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 simplejson.dumps(resp, indent=4)

    if spent_small_transaction(resp['transaction_hash']):
        return False

    testlib.next_block(**kw)

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

    if spent_small_transaction(resp['transaction_hash']):
        return False

    testlib.next_block(**kw)

    res = check_utxo_consumption(
        "foo.test", wallets[2], wallets[3], wallets[4],
        ['preorder', 'register', 'update', 'transfer'], wallets[4].addr, **kw)
    if 'error' in res:
        return False

    expected_utxo_count = res['expected_utxo_count']

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

    if spent_small_transaction(resp['transaction_hash']):
        return False

    testlib.next_block(**kw)

    # verify that all the small UTXOs are NOT consumed
    bitcoind = testlib.connect_bitcoind()
    bitcoind.ping()

    txdata = bitcoind.getrawtransaction(resp['transaction_hash'], 1)
    if len(txdata['vin']) != 1:
        print simplejson.dumps(txdata, indent=4)
        print "wrong number of inputs: {} != {}".format(
            len(txdata['vin']), expected_utxo_count)
        return False

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

    if spent_small_transaction(resp['transaction_hash']):
        return False

    testlib.next_block(**kw)

    # verify that all the UTXOs are consumed
    bitcoind = testlib.connect_bitcoind()
    bitcoind.ping()

    txdata = bitcoind.getrawtransaction(resp['transaction_hash'], 1)
    if len(txdata['vin']) != 1:
        print simplejson.dumps(txdata, indent=4)
        print "wrong number of inputs: {} != {}".format(
            len(txdata['vin']), expected_utxo_count)
        return False

    # make a few small UTXOs for the preorder payment addr
    for i in xrange(0, 3):
        res = testlib.send_funds(wallets[1].privkey, 10000,
                                 testlib.get_default_payment_wallet().addr)
        if 'error' in res:
            print simplejson.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        small_unspents.append(res['transaction_hash'])

    utxos = testlib.get_utxos(testlib.get_default_payment_wallet().addr)
    assert len(utxos) > 3

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

    if spent_small_transaction(resp['transaction_hash']):
        return False

    consensus = testlib.get_consensus_at(testlib.get_current_block(**kw), **kw)
    testlib.next_block(**kw)

    # inspect the transaction: only 3 UTXOs should have been consumed (2 owner UTXOs and 1 payment UTXO)
    txdata = testlib.connect_bitcoind().getrawtransaction(
        resp['transaction_hash'], 1)
    if len(txdata['vin']) != 3:
        print simplejson.dumps(txdata, indent=4)
        print "too many inputs"
        return False

    # make a few more small UTXOs for the preorder payment addr
    for i in xrange(0, 3):
        res = testlib.send_funds(wallets[1].privkey, 10000,
                                 testlib.get_default_payment_wallet().addr)
        if 'error' in res:
            print simplejson.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        small_unspents.append(res['transaction_hash'])

    utxos = testlib.get_utxos(testlib.get_default_payment_wallet().addr)
    assert len(utxos) > 3

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

    # inspect the transaction: only 2 UTXOs should have been consumed (1 owner UTXO and 1 payment UTXO)
    txdata = testlib.connect_bitcoind().getrawtransaction(
        resp['transaction_hash'], 1)
    if len(txdata['vin']) != 2:
        print simplejson.dumps(txdata, indent=4)
        print "too many inputs"
        return False

    if spent_small_transaction(resp['transaction_hash']):
        return False

    testlib.next_block(**kw)

    # make a few more small UTXOs for the preorder payment addr
    for i in xrange(0, 3):
        res = testlib.send_funds(wallets[1].privkey, 10000,
                                 testlib.get_default_payment_wallet().addr)
        if 'error' in res:
            print simplejson.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        small_unspents.append(res['transaction_hash'])

    utxos = testlib.get_utxos(testlib.get_default_payment_wallet().addr)
    assert len(utxos) > 3

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

    # inspect the transaction: only 3 UTXOs should have been consumed (2 owner UTXO and 1 payment UTXO)
    # NOTE: produces two UTXOs: an "owner" utxo and the change for the owner address
    txdata = testlib.connect_bitcoind().getrawtransaction(
        resp['transaction_hash'], 1)
    if len(txdata['vin']) != 3:
        print simplejson.dumps(txdata, indent=4)
        print "too many inputs"
        return False

    if spent_small_transaction(resp['transaction_hash']):
        return False

    testlib.next_block(**kw)

    # make a few more small UTXOs for the preorder payment addr
    for i in xrange(0, 3):
        res = testlib.send_funds(wallets[1].privkey, 10000,
                                 testlib.get_default_payment_wallet().addr)
        if 'error' in res:
            print simplejson.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        small_unspents.append(res['transaction_hash'])

    utxos = testlib.get_utxos(testlib.get_default_payment_wallet().addr)
    assert len(utxos) > 3

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

    # inspect the transaction: only 3 UTXOs should have been consumed (2 owner UTXO and 1 payment UTXO)
    txdata = testlib.connect_bitcoind().getrawtransaction(
        resp['transaction_hash'], 1)
    if len(txdata['vin']) != 3:
        print simplejson.dumps(txdata, indent=4)
        print "too many inputs"
        return False

    if spent_small_transaction(resp['transaction_hash']):
        return False

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

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

    # import 3 names in the same block: foo.test, bar.test, baz.test
    names = ['foo.test', 'bar.test', 'baz.test']
    name_preorder_wallets = [wallets[2], wallets[3], wallets[4]]
    name_register_wallets = [wallets[5], wallets[6], wallets[7]]
    name_transfer_wallets = [wallets[6], wallets[7], wallets[5]]

    # derive importer keys and do imports
    # NOTE: breaks consensus trace from 0.14.0
    private_keychain = keychain.PrivateKeychain.from_private_key(
        wallets[1].privkey)
    private_keys = [
        wallets[1].privkey
    ]  # NOTE: always start with the reveal key, then use children
    for i in xrange(0, len(names) - 1):
        import_key = private_keychain.child(i).private_key()

        print "fund {} (child {})".format(import_key, i)
        res = testlib.send_funds(
            wallets[1].privkey, 100000000,
            virtualchain.BitcoinPrivateKey(import_key).public_key().address())
        if 'error' in res:
            print json.dumps(res, indent=4, sort_keys=True)
            return False

        testlib.next_block(**kw)
        private_keys.append(import_key)

    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]
        import_key = private_keys[i]

        resp = testlib.blockstack_name_import(name, register_wallet.addr,
                                              str(9 - i) * 40, import_key)
        if 'error' in resp:
            print json.dumps(resp, indent=4)
            return False

    testlib.next_block(**kw)

    # namespace ready...
    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)

    # update 3 names in the same block
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]

        resp = testlib.blockstack_name_update(name,
                                              str(i + 2) * 40,
                                              register_wallet.privkey)
        if 'error' in resp:
            print json.dumps(resp, indent=4)
            return False

    testlib.next_block(**kw)

    # update 3 names in the same block, again
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]

        resp = testlib.blockstack_name_update(name,
                                              str(i + 1) * 40,
                                              register_wallet.privkey)
        if 'error' in resp:
            print json.dumps(resp, indent=4)
            return False

    testlib.next_block(**kw)

    # transfer 3 names in the same block
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]
        transfer_wallet = name_transfer_wallets[i]

        resp = testlib.blockstack_name_transfer(name, transfer_wallet.addr,
                                                True, register_wallet.privkey)
        if 'error' in resp:
            print json.dumps(resp, indent=4)
            return False

    testlib.next_block(**kw)

    # exchange after transfer...
    tmp = name_register_wallets
    name_register_wallets = name_transfer_wallets
    name_transfer_wallets = tmp

    # revoke 3 names in the same block
    for i in xrange(0, len(names)):

        name = names[i]
        register_wallet = name_register_wallets[i]

        resp = testlib.blockstack_name_revoke(name, register_wallet.privkey)
        if 'error' in resp:
            print json.dumps(resp, indent=4)
            return False

    # iterate the blocks a few times
    for i in xrange(0, 5):
        testlib.next_block(**kw)
Exemple #28
0
def check_utxo_consumption(name_or_ns, payment_wallet, owner_wallet,
                           data_wallet, operations, recipient_address, **kw):

    global small_unspents

    wallet = testlib.blockstack_client_initialize_wallet(
        "0123456789abcdef", payment_wallet.privkey, owner_wallet.privkey,
        data_wallet.privkey)
    test_proxy = testlib.TestAPIProxy()
    blockstack_client.set_default_proxy(test_proxy)

    # estimate the fee for the operation sequence
    fees = testlib.blockstack_cli_price(name_or_ns,
                                        "0123456789abcdef",
                                        recipient_address=recipient_address,
                                        operations=operations)
    if 'error' in fees:
        return fees

    print "without UTXOs:"
    print simplejson.dumps(fees, indent=4, sort_keys=True)

    # make a few small UTXOs for the payment address
    # count up the number of UTXOs that exist for this payment address
    payment_utxos = testlib.get_utxos(payment_wallet.addr)
    expected_utxo_count = len(payment_utxos)
    for i in xrange(0, 1):
        senders = wallets
        for sender in senders:
            if sender.privkey == payment_wallet.privkey:
                continue

            res = testlib.send_funds(sender.privkey, 10000,
                                     payment_wallet.addr)
            if 'error' in res:
                print simplejson.dumps(res, indent=4, sort_keys=True)
                return res

            expected_utxo_count += 1
            small_unspents.append(res['transaction_hash'])

        testlib.next_block(**kw)

    # estimate the fee with all the UTXOs
    fees_utxos = testlib.blockstack_cli_price(
        name_or_ns,
        "0123456789abcdef",
        recipient_address=recipient_address,
        operations=operations)
    if 'error' in fees_utxos:
        return fees_utxos

    print "with UTXOs:"
    print simplejson.dumps(fees_utxos, indent=4, sort_keys=True)

    # all our operations should have similar fees, regardless of the UTXO set
    for tx_fee_key in ['{}_tx_fee'.format(op) for op in operations]:
        fee_diff = abs(fees[tx_fee_key]['satoshis'] -
                       fees_utxos[tx_fee_key]['satoshis'])
        if fee_diff > 5500:
            print 'tx fees for {} disagree by {}'.format(tx_fee_key, fee_diff)
            return {'error': 'No appreciable fee change'}

    return {'status': True, 'expected_utxo_count': expected_utxo_count}