def scenario(wallets, **kw): # 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) # end of 689 assert virtualchain.lib.indexer.StateEngine.get_block_statistics( testlib.get_current_block(**kw))['num_processed_ops'] == 0 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 assert balances[wallets[2].addr][STACKS] == 0 # try to spend tokens with an empty consensus hash (note that this is epoch 5) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 600000, wallets[0].privkey, consensus_hash='00' * 16) testlib.next_block(**kw) assert virtualchain.lib.indexer.StateEngine.get_block_statistics( testlib.get_current_block(**kw))['num_processed_ops'] > 0 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 0 assert balances[wallets[1].addr][STACKS] == 600000 assert balances[wallets[2].addr][STACKS] == 0
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, 3) ] for i in range(0, 3 * len(new_keys)): 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, 800000, cur_addr) testlib.send_funds(wallets[0].privkey, 800000, new_addr) testlib.blockstack_send_tokens(new_addr, 'STACKS', 100, new_keys[i % len(new_keys)]) testlib.next_block(**kw) balance_info = json.loads(testlib.nodejs_cli('balance', new_addr)) assert int(balance_info['STACKS']) == 100 + int( initial_new_balance_info['STACKS']) if (i + 1) % len(new_keys) != 0: assert int(balance_info['STACKS']) == 100 balance_info = json.loads(testlib.nodejs_cli('balance', cur_addr)) assert int(balance_info['STACKS']) == int( initial_cur_balance_info['STACKS']) - 100 if i % len(new_keys) != 0: assert int(balance_info['STACKS']) == 0 # each *new* address has 6 history items -- three spends, three 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 3 debits for 100, and 3 credits for 100 assert int(history[0]['credit_value']) == 300, history assert int(history[0]['debit_value']) == 300, history assert len(history) == 6, history
def scenario(wallets, **kw): testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) balances = testlib.get_wallet_balances(wallets[2]) assert balances[wallets[2].addr][STACKS] == 0 # should fail--not enough stacks testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr, safety_checks=False, expect_fail=True) testlib.next_block(**kw) name_cost = testlib.blockstack_get_name_token_cost('foo.test') assert name_cost['units'] == STACKS assert name_cost['amount'] > 0 # send tokens and preorder multiple times in the block # should all succeed, BUT: force them to go in order through UTXO chaining for i in range(0, 5): name_recipient_privkey = wallets[-(i + 1)].privkey name_recipient_addr = virtualchain.address_reencode( virtualchain.get_privkey_address(name_recipient_privkey)) testlib.blockstack_send_tokens(name_recipient_addr, "STACKS", name_cost['amount'], wallets[0].privkey) testlib.send_funds(wallets[0].privkey, 1000000, name_recipient_addr) testlib.blockstack_name_preorder("foo_{}.test".format(i), name_recipient_privkey, wallets[3].addr, safety_checks=False) testlib.blockstack_name_register("foo_{}.test".format(i), name_recipient_privkey, wallets[3].addr, safety_checks=False) testlib.next_block(**kw)
def scenario(wallets, **kw): global pk testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks( 'foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name( 'foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", stacks_price, wallets[0].privkey) testlib.send_funds( wallets[0].privkey, btc_price - 5500 - 1, addr) # deliberately insufficient funds for ordering the name in BTC testlib.next_block(**kw) # preorder/register using Stacks testlib.blockstack_name_preorder("foo.test", pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price }) testlib.next_block(**kw) testlib.send_funds( wallets[0].privkey, btc_price - 5500 - 1, addr) # deliberately insufficient funds for ordering the name in BTC testlib.blockstack_name_register("foo.test", pk, wallets[3].addr) testlib.next_block(**kw)
def scenario( wallets, **kw ): global pk, pk2 testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR) testlib.next_block( **kw ) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print 'price of {} in BTC is {}'.format('foo.test', btc_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", stacks_price + 2, wallets[0].privkey) testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price + 1, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, 3*btc_price, addr) testlib.send_funds(wallets[0].privkey, 3*btc_price, addr2) testlib.next_block(**kw) # preorder/register using Stacks testlib.blockstack_name_preorder( "foo.test", pk, addr2) testlib.blockstack_name_preorder( "bar.test", pk2, addr) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", pk, addr2 ) testlib.blockstack_name_register( "bar.test", pk2, addr ) testlib.next_block( **kw ) testlib.next_block( **kw ) testlib.next_block( **kw ) testlib.next_block( **kw ) # end of pay to namespace creator # renew using more stacks than we have (should fail) # bar.test should succeed testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price + 2}, expect_fail=True, safety_checks=False) testlib.blockstack_name_renew('bar.test', pk, price={'units': 'STACKS', 'amount': stacks_price + 1}) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))
def scenario( wallets, **kw ): global pk, pk2 testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR) testlib.next_block( **kw ) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", stacks_price + 1, wallets[0].privkey) testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price + 1, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr) # deliberately insufficient funds for ordering the name in BTC testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr2) # deliberately insufficient funds for ordering the name in BTC testlib.next_block(**kw) testlib.next_block(**kw) testlib.next_block(**kw) testlib.next_block(**kw) # move beyond pay-to-creator requirement # preorder/register using Stacks, but overpay (foo.test fails, bar.test succeeds) testlib.blockstack_name_preorder( "foo.test", pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price + 2}, expect_fail=True, safety_checks=False) testlib.blockstack_name_preorder( "bar.test", pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price + 1}) testlib.next_block( **kw ) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr) # deliberately insufficient funds for ordering the name in BTC testlib.send_funds(wallets[0].privkey, btc_price - 5500 - 1, addr2) # deliberately insufficient funds for ordering the name in BTC testlib.blockstack_name_register( "foo.test", pk, wallets[3].addr ) # should fail testlib.blockstack_name_register( "bar.test", pk2, wallets[3].addr ) # should succeed testlib.next_block( **kw ) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw))
def scenario(wallets, **kw): blockstack.lib.config.set_genesis_block_patches(genesis_patches) 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.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'] == 1 # new balances should reflect patch balances = testlib.get_addr_balances([w.addr for w in wallets] + [new_addr_b58, new_grant_addr_b58]) print balances assert balances[wallets[0].addr][ STACKS] == 100 + 200 + 600000 + 600001 + 10000 + 10001 + 10002 + 10003 + 10004 + 10005 - 600000 # += 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) # TODO history of each address should be changed to reflect vesting # TODO try different lock heights -- can we retroactively grant tokens to an address that has received or spent tokens already? # TODO: make sure we re-lock an account if it received tokens prior to the patch, and is granted new tokens with a time-lock """ for addr in [wallets[0].addr, wallets[1].addr, wallets[2].addr, new_addr_b58, new_grant_addr_b58]: vesting = blockstack.lib.db.namedb.namedb_get_account_vesting( """ cur_vesting = namedb_get_account_vesting(con, address, 'STACKS')
def scenario( wallets, **kw ): global pk, pk2 testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR) testlib.next_block( **kw ) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print 'price of {} in BTC is {}'.format('foo.test', btc_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", 8*stacks_price, wallets[0].privkey) testlib.blockstack_send_tokens(addr2, "STACKS", 8*stacks_price, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, 8*btc_price, addr) testlib.send_funds(wallets[0].privkey, 8*btc_price, addr2) testlib.next_block(**kw) def _tx_pay_btc(txhex, privk, burn_price, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS): tx = virtualchain.btc_tx_deserialize(txhex) # up the burn amount tx['outs'][3]['script'] = virtualchain.btc_make_payment_script(burn_addr) tx['outs'][3]['value'] = burn_price tx['outs'][4]['value'] -= burn_price # re-sign for i in tx['ins']: i['script'] = '' txhex = virtualchain.btc_tx_serialize(tx) _addr = virtualchain.address_reencode(virtualchain.get_privkey_address(privk)) txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(privk, testlib.get_utxos(_addr), txhex) # re-sign the last output with the payment key tx_signed = virtualchain.btc_tx_deserialize(txhex_signed) tx_signed['ins'][-1]['script'] = '' txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(testlib.get_default_payment_wallet().privkey, testlib.get_utxos(testlib.get_default_payment_wallet().addr), virtualchain.btc_tx_serialize(tx_signed)) print txhex_signed res = testlib.broadcast_transaction(txhex_signed) assert 'error' not in res return res # preorder/register using BTC testlib.blockstack_name_preorder( "foo.test", pk, addr2 ) testlib.blockstack_name_preorder( "bar.test", pk, addr2 ) testlib.blockstack_name_preorder( "baz.test", pk, addr2 ) testlib.blockstack_name_preorder( "goo.test", pk, addr2 ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", pk, addr2 ) testlib.blockstack_name_register( "bar.test", pk, addr2 ) testlib.blockstack_name_register( "baz.test", pk, addr2 ) testlib.blockstack_name_register( "goo.test", pk, addr2 ) testlib.next_block( **kw ) # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active) res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens) res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr) # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active). Also underpay BTC res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1) # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens). Also underpay BTC res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1, wallets[0].addr) testlib.next_block(**kw) # all should have failed assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0 # try to renew using Stacks (won't work, since we're still collecting fees in BTC and need to send to the namespace creator's address) res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr) # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active). Also underpay BTC res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1) # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens). Also underpay BTC res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1, wallets[0].addr) testlib.next_block(**kw) # all should have failed assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0 # try to renew using Stacks, now that pay-to-creator has expired res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, expect_success=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) # should fail--can't mix stacks and btc res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) # should succeed--paid in stacks res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, expect_success=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1) # should fail--wrong burn address res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr) testlib.next_block(**kw) # only two should have succeeded assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 2
def scenario(wallets, **kw): # 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): testlib.disable_snv_checks() testlib.disable_did_checks() # make failed transactions resp = testlib.blockstack_namespace_preorder( "test2", wallets[1].addr, wallets[0].privkey, consensus_hash='00000000000000000000000000000000', safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAMESPACE_PREORDER') resp = 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=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAMESPACE_REVEAL') resp = testlib.blockstack_namespace_ready("test2", wallets[1].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAMESPACE_READY') # okay, go and actually create this namespace so we can preorder names 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.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # start failing again resp = testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr, consensus_hash='00000000000000000000000000000000', safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAME_PREORDER') resp = testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAME_REGISTRATION') resp = testlib.blockstack_name_update("foo.test", "11" * 20, wallets[3].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAME_UPDATE') resp = testlib.blockstack_name_transfer("foo.test", wallets[0].addr, True, wallets[3].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAME_TRANSFER') resp = testlib.blockstack_name_renew("foo.test", wallets[3].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAME_REGISTRATION') resp = testlib.blockstack_name_revoke("foo.test", wallets[3].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'NAME_REVOKE') resp = testlib.blockstack_send_tokens( wallets[0].addr, 'STACKS', 123, wallets[3].privkey, consensus_hash='11111111111111111111111111111111', safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'TOKEN_TRANSFER') resp = testlib.blockstack_announce("hello world", wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) test_failed_tx(resp['transaction_hash'], 'ANNOUNCE')
def scenario(wallets, **kw): # will be rejected, since locked testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 689 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 assert balances[wallets[2].addr][STACKS] == 0 # will succeed, since whitelisted testlib.blockstack_send_tokens( wallets[1].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False ) # need to disable safety checks since it's "currently" block 690 testlib.next_block(**kw) # end of 690 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # try to send back (will fail since its locked) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[1].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 691 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # try to send back (will fail since the address is not whitelisted) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[1].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 692 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # send to wallets[2] (should succeed) testlib.blockstack_send_tokens( wallets[2].addr, "STACKS", 50000, wallets[1].privkey, safety_checks=False ) # need to disable safety checks since it's "currently" block 692 testlib.next_block(**kw) # end of 693 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 50000 assert balances[wallets[2].addr][STACKS] == 50000 # send to wallets[1] (should fail since locked) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 50000, wallets[2].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 694 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 50000 assert balances[wallets[2].addr][STACKS] == 50000 # send to wallets[1] (should succeed now) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 50000, wallets[2].privkey, safety_checks=False) testlib.next_block(**kw) # end of 695 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # send to a new address new_addr = 'n17Wp3qk9WNGESLHHey18dcgQAn5aDDPuE' testlib.blockstack_send_tokens(new_addr, 'STACKS', 123456, wallets[0].privkey, safety_checks=False) testlib.next_block(**kw) # end of 696 balance_info = json.loads(testlib.nodejs_cli('balance', new_addr)) assert int(balance_info['STACKS']) == 123456 balance_info = json.loads(testlib.nodejs_cli('balance', wallets[0].addr)) assert int(balance_info['STACKS']) == 500000 - 123456
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)
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 ): # will be rejected, since locked testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 689 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 assert balances[wallets[2].addr][STACKS] == 0 # will succeed, since whitelisted testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False) # need to disable safety checks since it's "currently" block 690 testlib.next_block(**kw) # end of 690 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # try to send back (will fail since its locked) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[1].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 691 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # try to send back (will fail since the address is not whitelisted) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[1].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 692 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # send to wallets[2] (should succeed) testlib.blockstack_send_tokens(wallets[2].addr, "STACKS", 50000, wallets[1].privkey, safety_checks=False) # need to disable safety checks since it's "currently" block 692 testlib.next_block(**kw) # end of 693 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 50000 assert balances[wallets[2].addr][STACKS] == 50000 # send to wallets[1] (should fail since locked) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 50000, wallets[2].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 694 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 50000 assert balances[wallets[2].addr][STACKS] == 50000 # send to wallets[1] (should succeed now) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 50000, wallets[2].privkey, safety_checks=False) testlib.next_block(**kw) # end of 695 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0
def scenario(wallets, **kw): # should fail testlib.blockstack_namespace_preorder("test_fail", wallets[1].addr, wallets[0].privkey, safety_checks=False, price={ 'units': 'STACKS', 'amount': 0 }) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test_fail", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.expect_snv_fail_at('test_fail', testlib.get_current_block(**kw)) # should succeed testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[3].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[3].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # should fail (empty balance) testlib.blockstack_name_preorder('foo_fail.test', wallets[0].privkey, wallets[3].addr, safety_checks=False, expect_fail=True) testlib.next_block(**kw) testlib.blockstack_name_register('foo_fail.test', wallets[0].privkey, wallets[3].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo_fail.test', testlib.get_current_block(**kw)) # should succeed testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # deplete balance balance = json.loads(testlib.nodejs_cli('balance', wallets[2].addr)) testlib.blockstack_send_tokens(wallets[0].addr, 'STACKS', int(balance['STACKS']), wallets[2].privkey) balance = json.loads(testlib.nodejs_cli('balance', wallets[3].addr)) testlib.blockstack_send_tokens(wallets[0].addr, 'STACKS', int(balance['STACKS']), wallets[3].privkey) testlib.next_block(**kw) # should fail--not enough funds testlib.blockstack_name_renew("foo.test", wallets[3].privkey, expect_fail=True) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # should fail--not enough funds testlib.blockstack_name_preorder("baz.test", wallets[2].privkey, wallets[3].addr, expect_fail=True, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('baz.test', testlib.get_current_block(**kw)) testlib.blockstack_name_register("baz.test", wallets[2].privkey, wallets[3].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('baz.test', testlib.get_current_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
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 ): 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, pk2, pk3 testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode( virtualchain.get_privkey_address(pk2)) addr3 = virtualchain.address_reencode( virtualchain.get_privkey_address(pk3)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks( 'foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name( 'foo', namespace, testlib.get_current_block(**kw)) # try to preorder/register using not enough Bitcoin and not enough Bitcoin (should fail) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print 'price of {} in BTC is {}'.format('foo.test', btc_price) print '' testlib.send_funds(wallets[0].privkey, btc_price * 2, addr) # try to preorder/register using not enough bitcoin (preorder should succeed; register should fail) testlib.blockstack_name_preorder("foo.test", pk, wallets[3].addr, price={ 'units': 'BTC', 'amount': btc_price - 1 }, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) testlib.blockstack_name_register("foo.test", pk, wallets[3].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # pass tokens testlib.send_funds(wallets[0].privkey, btc_price * 2, addr2) testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price, wallets[0].privkey) testlib.next_block(**kw) # try to preorder/register using not enough Stacks (preorder should succeed; register should fail) testlib.blockstack_name_preorder("foo.test", pk2, wallets[4].addr, price={ 'units': 'STACKS', 'amount': stacks_price - 1 }, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) testlib.blockstack_name_register("foo.test", pk2, wallets[4].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # pass tokens testlib.send_funds(wallets[0].privkey, btc_price * 2, addr3) testlib.blockstack_send_tokens(addr3, "STACKS", stacks_price, wallets[0].privkey) testlib.next_block(**kw) # try to preorder/register using the right amount of stacks, but not paying in BTC (should succeed) testlib.blockstack_name_preorder("foo.test", pk3, wallets[1].addr, price={ 'units': 'STACKS', 'amount': stacks_price }) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", pk3, wallets[1].addr) testlib.next_block(**kw)
def scenario(wallets, **kw): coeff = 255 base = 32 bucket_exponents = [10, 10, 10, 9, 9, 9, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0] nonalpha_discount = 10 novowel_discount = 10 cost_unit = blockstack.config.NAME_COST_UNIT_STACKS testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, coeff, base, bucket_exponents, nonalpha_discount, novowel_discount, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # query a large amount of Stacks (exceeds 2**64) name_cost = testlib.blockstack_get_name_token_cost('foo.test') print name_cost assert name_cost['units'] == 'STACKS' assert name_cost['amount'] > 2**64 # send a large amount of Stacks (exceeds 2**64) -- should fail, since our transactions only allow 8 bytes to encode the STACKs count try: res = testlib.blockstack_send_tokens(wallets[2].addr, "STACKS", name_cost['amount'], wallets[0].privkey, expect_fail=True) assert 'error' not in res print res print 'Accidentally succeeded to send {} STACKS'.format( name_cost['amount']) return False except: pass # should fail, since we can't encode the price as a 64-bit number try: res = testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr, expect_fail=True) assert 'error' not in res print res print 'Accidentally succeeded to preorder foo.test for {} STACKs'.format( name_cost['amount']) return False except: pass ns = testlib.get_state_engine().get_namespace('test') # old price function should be wonky since it's a big float discount = 10.0 # for foo2.id, the non-alpha discount applies old_price_multiplier = 0.1 old_price_float = (float(coeff * (base**bucket_exponents[len('foo2') - 1])) / float(discount)) * cost_unit * old_price_multiplier new_price_int = blockstack.scripts.price_name( 'foo2', ns, testlib.get_current_block(**kw)) print 'old price: {}'.format(old_price_float) print 'new price: {}'.format(new_price_int) print 'diff: {}'.format(abs(int(old_price_float) - new_price_int)) # diff should be 1024, since we're dealing with floats bigger than 2**53 assert abs(int(old_price_float) - new_price_int) > 100, 'old price: {}, new price: {}'.format( old_price_float, new_price_int) testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo2.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw)
def scenario(wallets, **kw): global 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 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
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): # will be rejected, since locked testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 689 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 # will be rejected, since locked testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 200000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 690 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 300000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 691 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 400000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 692 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 500000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 693 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 # will succeed testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 600000, wallets[0].privkey, safety_checks=False) testlib.next_block(**kw) # end of 694 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 0 assert balances[wallets[1].addr][STACKS] == 600000
def scenario(wallets, **kw): testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) balances_before = get_wallet_balances(wallets) # ping-pong testlib.blockstack_send_tokens(wallets[3].addr, "STACKS", 100000, wallets[4].privkey) testlib.blockstack_send_tokens(wallets[3].addr, "STACKS", 100000, wallets[4].privkey) testlib.blockstack_send_tokens(wallets[4].addr, "STACKS", 100000, wallets[3].privkey) testlib.blockstack_send_tokens(wallets[4].addr, "STACKS", 100000, wallets[3].privkey) testlib.next_block(**kw) balances_after = get_wallet_balances(wallets) print 'balance before' print json.dumps(balances_before, indent=4, sort_keys=True) print 'balance after' print json.dumps(balances_after, indent=4, sort_keys=True) assert set(balances_after.keys()) == set(balances_before.keys()) for addr in balances_after: assert balances_before[addr][STACKS] == balances_after[addr][STACKS] balances_before = balances_after # cycle testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, wallets[0].privkey) testlib.blockstack_send_tokens(wallets[2].addr, "STACKS", 100000, wallets[1].privkey) testlib.blockstack_send_tokens(wallets[3].addr, "STACKS", 100000, wallets[2].privkey) testlib.blockstack_send_tokens(wallets[4].addr, "STACKS", 100000, wallets[3].privkey) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[4].privkey) testlib.next_block(**kw) balances_after = get_wallet_balances(wallets) print 'balance before' print json.dumps(balances_before, indent=4, sort_keys=True) print 'balance after' print json.dumps(balances_after, indent=4, sort_keys=True) assert set(balances_after.keys()) == set(balances_before.keys()) for addr in balances_after: assert balances_before[addr][STACKS] == balances_after[addr][STACKS] balances_before = balances_after # fan-in testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[1].privkey) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[2].privkey) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[3].privkey) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[4].privkey) testlib.next_block(**kw) balances_after = get_wallet_balances(wallets) print 'balance before' print json.dumps(balances_before, indent=4, sort_keys=True) print 'balance after' print json.dumps(balances_after, indent=4, sort_keys=True) assert set(balances_after.keys()) == set(balances_before.keys()) assert balances_after[wallets[0].addr][STACKS] == balances_before[ wallets[0].addr][STACKS] + 4 * 100000 for addr in [wallets[i].addr for i in range(1, 5)]: assert balances_before[addr][STACKS] - 100000 == balances_after[addr][ STACKS] balances_before = balances_after # fan out testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[4].privkey) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, wallets[4].privkey) testlib.blockstack_send_tokens(wallets[2].addr, "STACKS", 100000, wallets[4].privkey) testlib.blockstack_send_tokens(wallets[3].addr, "STACKS", 100000, wallets[4].privkey) testlib.next_block(**kw) balances_after = get_wallet_balances(wallets) print 'balance before' print json.dumps(balances_before, indent=4, sort_keys=True) print 'balance after' print json.dumps(balances_after, indent=4, sort_keys=True) assert set(balances_after.keys()) == set(balances_before.keys()) assert balances_after[wallets[4].addr][STACKS] == balances_before[ wallets[4].addr][STACKS] - 4 * 100000 for addr in [wallets[i].addr for i in range(0, 4)]: assert balances_before[addr][STACKS] + 100000 == balances_after[addr][ STACKS]