def scenario(wallets, **kw): testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3]) testlib.next_block(**kw) # should fail, since multisig isn't enabled yet testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3]) testlib.next_block(**kw) testlib.expect_snv_fail_at("foo.test", testlib.get_current_block(**kw)) # foo.test should be preordered (in both 0.13 and 0.14) state_engine = testlib.get_state_engine() preorder = state_engine.get_name_preorder( "foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr) if preorder is None: print "foo.test not preordered" return False # epoch changes here testlib.blockstack_name_preorder("bar.test", wallets[3].privkey, wallets[4].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3]) testlib.next_block(**kw) testlib.blockstack_name_register("bar.test", wallets[3].privkey, wallets[4].addr) testlib.next_block(**kw)
def scenario(wallets, **kw): global pk 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 ): testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.blockstack_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3] ) testlib.next_block( **kw ) # should fail, since multisig isn't enabled yet testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3] ) testlib.next_block( **kw ) testlib.expect_snv_fail_at( "foo.test", testlib.get_current_block(**kw)) # foo.test should be preordered (in both 0.13 and 0.14) state_engine = testlib.get_state_engine() preorder = state_engine.get_name_preorder("foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr) if preorder is None: print "foo.test not preordered" return False # epoch changes here testlib.blockstack_name_preorder( "bar.test", wallets[3].privkey, wallets[4].addr ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3] ) testlib.next_block( **kw ) testlib.blockstack_name_register( "bar.test", wallets[3].privkey, wallets[4].addr ) testlib.next_block( **kw )
def scenario( wallets, **kw ): global pk, pk2 testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR) testlib.next_block( **kw ) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print 'price of {} in BTC is {}'.format('foo.test', btc_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", 8*stacks_price, wallets[0].privkey) testlib.blockstack_send_tokens(addr2, "STACKS", 8*stacks_price, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, 8*btc_price, addr) testlib.send_funds(wallets[0].privkey, 8*btc_price, addr2) testlib.next_block(**kw) def _tx_pay_btc(txhex, privk, burn_price, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS): tx = virtualchain.btc_tx_deserialize(txhex) # up the burn amount tx['outs'][3]['script'] = virtualchain.btc_make_payment_script(burn_addr) tx['outs'][3]['value'] = burn_price tx['outs'][4]['value'] -= burn_price # re-sign for i in tx['ins']: i['script'] = '' txhex = virtualchain.btc_tx_serialize(tx) _addr = virtualchain.address_reencode(virtualchain.get_privkey_address(privk)) txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(privk, testlib.get_utxos(_addr), txhex) # re-sign the last output with the payment key tx_signed = virtualchain.btc_tx_deserialize(txhex_signed) tx_signed['ins'][-1]['script'] = '' txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(testlib.get_default_payment_wallet().privkey, testlib.get_utxos(testlib.get_default_payment_wallet().addr), virtualchain.btc_tx_serialize(tx_signed)) print txhex_signed res = testlib.broadcast_transaction(txhex_signed) assert 'error' not in res return res # preorder/register using BTC testlib.blockstack_name_preorder( "foo.test", pk, addr2 ) testlib.blockstack_name_preorder( "bar.test", pk, addr2 ) testlib.blockstack_name_preorder( "baz.test", pk, addr2 ) testlib.blockstack_name_preorder( "goo.test", pk, addr2 ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", pk, addr2 ) testlib.blockstack_name_register( "bar.test", pk, addr2 ) testlib.blockstack_name_register( "baz.test", pk, addr2 ) testlib.blockstack_name_register( "goo.test", pk, addr2 ) testlib.next_block( **kw ) # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active) res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens) res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr) # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active). Also underpay BTC res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1) # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens). Also underpay BTC res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1, wallets[0].addr) testlib.next_block(**kw) # all should have failed assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0 # try to renew using Stacks (won't work, since we're still collecting fees in BTC and need to send to the namespace creator's address) res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr) # try to renew using Stacks (won't work, since we used the wrong burn address while pay-to-creator was active). Also underpay BTC res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1) # try to renew using Stacks (won't work, since we send tokens to the wrong burn address for tokens). Also underpay BTC res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1, wallets[0].addr) testlib.next_block(**kw) # all should have failed assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 0 # try to renew using Stacks, now that pay-to-creator has expired res = testlib.blockstack_name_renew('foo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, expect_success=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) # should fail--can't mix stacks and btc res = testlib.blockstack_name_renew('bar.test', pk2, price={'units': 'STACKS', 'amount': stacks_price-1}, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price) # should succeed--paid in stacks res = testlib.blockstack_name_renew('baz.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, expect_success=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price - 1) # should fail--wrong burn address res = testlib.blockstack_name_renew('goo.test', pk2, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True, tx_only=True) res = _tx_pay_btc(res['transaction'], pk2, btc_price, wallets[0].addr) testlib.next_block(**kw) # only two should have succeeded assert virtualchain.lib.indexer.StateEngine.get_block_statistics(testlib.get_current_block(**kw))['num_processed_ops'] == 2
def scenario(wallets, **kw): global debug resp = testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_namespace_ready("test", wallets[1].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_update("foo.test", "11" * 20, wallets[4].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = name_rec['consensus_hash'] resp = testlib.blockstack_name_renew("foo.test", wallets[4].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[3].addr, True, wallets[4].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False
def scenario(wallets, **kw): global pk testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) # all names below are the same price testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 1, 1, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks( 'foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name( 'foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", stacks_price * 5, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, btc_price * 10, addr) testlib.next_block(**kw) # preorder/register using Stacks (preorders should fail since we're using the wrong burn address for tokens) testlib.blockstack_name_preorder("foo.test", pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price }, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True) testlib.blockstack_name_preorder("bar.test", pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price - 1 }, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True) testlib.next_block(**kw) op_info = virtualchain.lib.indexer.StateEngine.get_block_statistics( testlib.get_current_block(**kw)) if op_info['num_processed_ops'] > 0: print 'handled ops this block' print op_info return False # preorder/register using Stacks (preorders should be accepted, but bar2 will fail to register) testlib.blockstack_name_preorder( "foo2.test", pk, wallets[2].addr, price={ 'units': 'STACKS', 'amount': stacks_price }, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False) testlib.blockstack_name_preorder( "bar2.test", pk, wallets[2].addr, price={ 'units': 'STACKS', 'amount': stacks_price - 1 }, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False) testlib.next_block(**kw) # preorder/register using Stacks (preorders should succeed now, but bar3.test will fail to register since we're not paying enough stacks) testlib.blockstack_name_register( "bar2.test", pk, wallets[2].addr ) # should fail at this point, since the preorder sent to the wrong burn address testlib.blockstack_name_register( "foo2.test", pk, wallets[2].addr ) # should fail at this point, since the preorder sent to the wrong burn address testlib.blockstack_name_preorder( "foo3.test", pk, wallets[2].addr, price={ 'units': 'STACKS', 'amount': stacks_price }, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False) testlib.blockstack_name_preorder( "bar3.test", pk, wallets[2].addr, price={ 'units': 'STACKS', 'amount': stacks_price - 1 }, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('bar2.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('foo2.test', testlib.get_current_block(**kw)) # tokens are not yet accepted if testlib.get_state_engine().get_name('bar2.test'): print 'registered bar2.test' return False if testlib.get_state_engine().get_name('foo2.test'): print 'registered foo2.test' return False # preorder/register using Stacks (should succeed without safety checks or overrides) testlib.blockstack_name_preorder("foo.test", pk, wallets[2].addr, price={ 'units': 'STACKS', 'amount': stacks_price }) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", pk, wallets[2].addr) # should succeed testlib.blockstack_name_register("bar2.test", pk, wallets[2].addr) # should fail testlib.blockstack_name_register("foo2.test", pk, wallets[2].addr) # should succeed testlib.blockstack_name_register("bar3.test", pk, wallets[2].addr) # should fail testlib.blockstack_name_register("foo3.test", pk, wallets[2].addr) # should succeed testlib.next_block(**kw) testlib.expect_snv_fail_at('bar2.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('bar3.test', testlib.get_current_block(**kw)) if testlib.get_state_engine().get_name('bar2.test'): print 'registered bar2.test' return False if testlib.get_state_engine().get_name('bar3.test'): print 'registered bar3.test' return False
def scenario(wallets, **kw): global import_block # make a test namespace resp = testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 10, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_name_import("foo.test", wallets[3].addr, "11" * 20, wallets[1].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) import_block = testlib.get_current_block(**kw) resp = testlib.blockstack_namespace_ready("test", wallets[1].privkey) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_update("foo.test", "22" * 20, wallets[4].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = name_rec['consensus_hash'] resp = testlib.blockstack_name_transfer("foo.test", wallets[3].addr, True, wallets[4].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False # wait for expiration (with multipler)... for i in xrange(0, 10 * NAMESPACE_LIFETIME_MULTIPLIER): testlib.next_block(**kw) # re-register testlib.blockstack_name_preorder("foo.test", wallets[7].privkey, wallets[8].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[7].privkey, wallets[8].addr) testlib.next_block(**kw) # consensus hash must be None db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] is not None: print 'wrong consensus hash: expected {}'.format(None) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[0].addr, True, wallets[8].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[8].addr, True, wallets[0].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_update("foo.test", "33" * 20, wallets[8].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False
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 debug resp = testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) resp = testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) resp = testlib.blockstack_name_import("foo.test", wallets[3].addr, "11" * 20, wallets[1].privkey) if 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) resp = testlib.blockstack_namespace_ready("test", wallets[1].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be None db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] is not None: print 'wrong consensus hash: expected None' print json.dumps(name_rec, indent=4, sort_keys=True) return False # ping-ping a bit... 3 --> 4 --> 5 --> 4 --> 5 --> 4 resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[3].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[5].addr, True, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[5].addr, True, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_TRANSFER db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False # update (4) resp = testlib.blockstack_name_update("foo.test", "11" * 20, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = name_rec['consensus_hash'] # ping-ping a bit... 4 --> 5 --> 4 --> 5 --> 4 --> 5 resp = testlib.blockstack_name_transfer("foo.test", wallets[5].addr, True, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[5].addr, True, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[5].addr, True, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False # now update (5) resp = testlib.blockstack_name_update("foo.test", "22" * 20, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1) resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_update("foo.test", "33" * 20, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1) resp = testlib.blockstack_name_update("foo.test", "44" * 20, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1) resp = testlib.blockstack_name_transfer("foo.test", wallets[5].addr, True, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_update("foo.test", "55" * 20, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1) resp = testlib.blockstack_name_update("foo.test", "66" * 20, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1) resp = testlib.blockstack_name_transfer("foo.test", wallets[5].addr, True, wallets[4].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False resp = testlib.blockstack_name_update("foo.test", "11" * 20, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'wrong consensus hash: expected {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1)) print json.dumps(name_rec, indent=4, sort_keys=True) return False update_ch = testlib.get_consensus_at(testlib.get_current_block(**kw) - 1) resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[5].privkey) if debug or 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) # consensus hash should be the one from the last NAME_UPDATE db = testlib.get_state_engine() name_rec = db.get_name('foo.test') if name_rec['consensus_hash'] != update_ch: print 'wrong consensus hash: expected {}'.format(update_ch) print json.dumps(name_rec, indent=4, sort_keys=True) return False
def scenario(wallets, **kw): global pk testlib.blockstack_namespace_preorder("test1", wallets[1].addr, wallets[0].privkey) testlib.blockstack_namespace_preorder("test2", wallets[1].addr, wallets[0].privkey) testlib.blockstack_namespace_preorder("test3", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test1", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=1) testlib.blockstack_namespace_reveal( "test2", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=2) testlib.blockstack_namespace_reveal( "test3", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=3) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test1", wallets[1].privkey) testlib.blockstack_namespace_ready("test2", wallets[1].privkey) testlib.blockstack_namespace_ready("test3", wallets[1].privkey) testlib.next_block(**kw) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test1') stacks_price = blockstack.lib.scripts.price_name_stacks( 'foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name( 'foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", 3 * stacks_price, wallets[0].privkey) testlib.send_funds( wallets[0].privkey, btc_price - 5500 - 1, addr) # deliberately insufficient funds for ordering the name in BTC testlib.next_block(**kw) wallet_before_burn = testlib.get_balance(wallets[0].addr) # preorder/register in all three namespaces testlib.blockstack_name_preorder("foo.test1", pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price }) testlib.blockstack_name_preorder("bar.test1", wallets[1].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo.test2", wallets[1].privkey, wallets[3].addr) testlib.blockstack_name_preorder("foo.test3", wallets[1].privkey, wallets[3].addr) testlib.next_block(**kw) wallet_after_burn = testlib.get_balance(wallets[0].addr) if wallet_after_burn - wallet_before_burn != btc_price: print 'foo.test2 did not pay {} to {} (but paid {})'.format( btc_price, wallets[0].addr, wallet_after_burn - wallet_before_burn) return False testlib.send_funds( wallets[0].privkey, btc_price - 5500 - 1, addr) # deliberately insufficient funds for ordering the name in BTC testlib.blockstack_name_register("foo.test1", pk, wallets[3].addr) # paid in Stacks testlib.blockstack_name_register("bar.test1", wallets[1].privkey, wallets[3].addr) # paid in BTC testlib.blockstack_name_register( "foo.test2", wallets[1].privkey, wallets[3].addr) # paid in BTC to wallets[0] testlib.blockstack_name_register("foo.test3", wallets[1].privkey, wallets[3].addr) # paid in Stacks testlib.next_block(**kw) testlib.send_funds( wallets[0].privkey, btc_price - 5500 - 1, addr) # deliberately insufficient funds for ordering the name in BTC wallet_before_burn = testlib.get_balance(wallets[0].addr) testlib.blockstack_name_renew("foo.test1", wallets[3].privkey, price={ 'units': 'STACKS', 'amount': stacks_price }) # paid in Stacks testlib.blockstack_name_renew("bar.test1", wallets[3].privkey) # paid in BTC testlib.blockstack_name_renew( "foo.test2", wallets[3].privkey) # paid in BTC to wallets[0] testlib.blockstack_name_renew("foo.test3", wallets[3].privkey) # paid in Stacks testlib.next_block(**kw) wallet_after_burn = testlib.get_balance(wallets[0].addr) if wallet_after_burn - wallet_before_burn != btc_price: print 'foo.test2 did not pay {} to {} (but paid {})'.format( btc_price, wallets[0].addr, wallet_after_burn - wallet_before_burn) return False # should all fail--wrong burn addresses testlib.blockstack_name_renew("foo.test1", pk, price={ 'units': 'STACKS', 'amount': stacks_price }, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True) testlib.blockstack_name_renew("bar.test1", wallets[3].privkey, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True) testlib.blockstack_name_renew("foo.test2", wallets[3].privkey, burn_addr=wallets[1].addr, safety_checks=False, expect_fail=True) testlib.blockstack_name_renew("foo.test3", wallets[3].privkey, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test1', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('bar.test1', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('foo.test2', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('foo.test3', testlib.get_current_block(**kw))
def scenario(wallets, **kw): global pk, pk2, pk3 testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode( virtualchain.get_privkey_address(pk2)) addr3 = virtualchain.address_reencode( virtualchain.get_privkey_address(pk3)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks( 'foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name( 'foo', namespace, testlib.get_current_block(**kw)) # try to preorder/register using not enough Bitcoin and not enough Bitcoin (should fail) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print 'price of {} in BTC is {}'.format('foo.test', btc_price) print '' testlib.send_funds(wallets[0].privkey, btc_price * 2, addr) # try to preorder/register using not enough bitcoin (preorder should succeed; register should fail) testlib.blockstack_name_preorder("foo.test", pk, wallets[3].addr, price={ 'units': 'BTC', 'amount': btc_price - 1 }, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) testlib.blockstack_name_register("foo.test", pk, wallets[3].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # pass tokens testlib.send_funds(wallets[0].privkey, btc_price * 2, addr2) testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price, wallets[0].privkey) testlib.next_block(**kw) # try to preorder/register using not enough Stacks (preorder should succeed; register should fail) testlib.blockstack_name_preorder("foo.test", pk2, wallets[4].addr, price={ 'units': 'STACKS', 'amount': stacks_price - 1 }, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) testlib.blockstack_name_register("foo.test", pk2, wallets[4].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # pass tokens testlib.send_funds(wallets[0].privkey, btc_price * 2, addr3) testlib.blockstack_send_tokens(addr3, "STACKS", stacks_price, wallets[0].privkey) testlib.next_block(**kw) # try to preorder/register using the right amount of stacks, but not paying in BTC (should succeed) testlib.blockstack_name_preorder("foo.test", pk3, wallets[1].addr, price={ 'units': 'STACKS', 'amount': stacks_price }) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", pk3, wallets[1].addr) testlib.next_block(**kw)
def scenario( wallets, **kw ): global pk, pk2 testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,6,6,6,6,6,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR) testlib.next_block( **kw ) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode(virtualchain.get_privkey_address(pk2)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks('foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name('foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", stacks_price * 8, wallets[0].privkey) testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price * 8, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, btc_price * 10, addr) # fund with enough bitcoin testlib.send_funds(wallets[0].privkey, btc_price * 10, addr2) # fund with enough bitcoin testlib.next_block(**kw) def _tx_pay_btc(txhex, privk, btc_paid, burn_addr): tx = virtualchain.btc_tx_deserialize(txhex) # up the burn amount btc_price = blockstack.lib.scripts.price_name('baz', namespace, testlib.get_current_block(**kw)) tx['outs'][2]['script'] = virtualchain.btc_make_payment_script(burn_addr) tx['outs'][2]['value'] = btc_paid tx['outs'][1]['value'] -= btc_paid # re-sign for i in tx['ins']: i['script'] = '' txhex = virtualchain.btc_tx_serialize(tx) _addr = virtualchain.address_reencode(virtualchain.get_privkey_address(privk)) txhex_signed = virtualchain.tx_sign_all_unsigned_inputs(privk, testlib.get_utxos(_addr), txhex) print txhex_signed res = testlib.broadcast_transaction(txhex_signed) assert 'error' not in res, res['error'] return res balance_before = testlib.get_addr_balances(addr)[addr]['STACKS'] # pay with Stacks and Bitcoin. Preorder should succeed only when we use the Blockstack burn address, but register should fail since we're paying Stacks. Pay enough bitcoin as well. res_fooa = testlib.blockstack_name_preorder('fooa.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_fooa = _tx_pay_btc(res_fooa['transaction'], pk, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_bara = testlib.blockstack_name_preorder('bara.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_bara = _tx_pay_btc(res_bara['transaction'], pk, btc_price, wallets[0].addr) res_baza = testlib.blockstack_name_preorder('baza.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_baza = _tx_pay_btc(res_baza['transaction'], pk, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_gooa = testlib.blockstack_name_preorder('gooa.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_gooa = _tx_pay_btc(res_gooa['transaction'], pk, btc_price, wallets[0].addr) res_foob = testlib.blockstack_name_preorder('foob.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_foob = _tx_pay_btc(res_foob['transaction'], pk, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_barb = testlib.blockstack_name_preorder('barb.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_barb = _tx_pay_btc(res_barb['transaction'], pk, btc_price - 1, wallets[0].addr) res_bazb = testlib.blockstack_name_preorder('bazb.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_bazb = _tx_pay_btc(res_bazb['transaction'], pk, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_goob = testlib.blockstack_name_preorder('goob.test', pk, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_goob = _tx_pay_btc(res_goob['transaction'], pk, btc_price - 1, wallets[0].addr) testlib.next_block(**kw) # should have paid in Stacks for each preorder balance_after = testlib.get_addr_balances(addr)[addr]['STACKS'] if balance_after != balance_before - (2 * stacks_price + 2 * stacks_price - 2): print 'names cost {}'.format(balance_before - balance_after) return False # should all fail since we tried to pay in stacks at this time testlib.blockstack_name_register('fooa.test', pk, wallets[3].addr) testlib.blockstack_name_register('bara.test', pk, wallets[3].addr) testlib.blockstack_name_register('baza.test', pk, wallets[3].addr) testlib.blockstack_name_register('gooa.test', pk, wallets[3].addr) testlib.blockstack_name_register('foob.test', pk, wallets[3].addr) testlib.blockstack_name_register('barb.test', pk, wallets[3].addr) testlib.blockstack_name_register('bazb.test', pk, wallets[3].addr) testlib.blockstack_name_register('goob.test', pk, wallets[3].addr) testlib.next_block(**kw) # pay-to-creator ends testlib.expect_snv_fail_at('fooa.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('bara.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('baza.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('gooa.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('foob.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('barb.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('bazb.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('goob.test', testlib.get_current_block(**kw)) balance_before = testlib.get_addr_balances(addr2)[addr2]['STACKS'] # pay with Stacks and Bitcoin, now that pay-to-creator has passed. Preorder should succeed when we pay to blockstack burn address, and register should succeed (when we fund enough), all because we paid in stacks. res_fooa = testlib.blockstack_name_preorder('fooa.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_fooa = _tx_pay_btc(res_fooa['transaction'], pk2, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_bara = testlib.blockstack_name_preorder('bara.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_bara = _tx_pay_btc(res_bara['transaction'], pk2, btc_price, wallets[0].addr) res_baza = testlib.blockstack_name_preorder('baza.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_baza = _tx_pay_btc(res_baza['transaction'], pk2, btc_price, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_gooa = testlib.blockstack_name_preorder('gooa.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_gooa = _tx_pay_btc(res_gooa['transaction'], pk2, btc_price, wallets[0].addr) res_foob = testlib.blockstack_name_preorder('foob.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_foob = _tx_pay_btc(res_foob['transaction'], pk2, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_barb = testlib.blockstack_name_preorder('barb.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_barb = _tx_pay_btc(res_barb['transaction'], pk2, btc_price - 1, wallets[0].addr) res_bazb = testlib.blockstack_name_preorder('bazb.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, tx_only=True, expect_success=True, safety_checks=False) res_bazb = _tx_pay_btc(res_bazb['transaction'], pk2, btc_price - 1, blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) res_goob = testlib.blockstack_name_preorder('goob.test', pk2, wallets[3].addr, price={'units': 'STACKS', 'amount': stacks_price - 1}, burn_addr=wallets[0].addr, tx_only=True, safety_checks=False) res_goob = _tx_pay_btc(res_goob['transaction'], pk2, btc_price - 1, wallets[0].addr) testlib.next_block(**kw) # should have paid in Stacks for each preorder balance_after = testlib.get_addr_balances(addr2)[addr2]['STACKS'] if balance_after != balance_before - (2 * stacks_price + 2 * stacks_price - 2): print 'baz.test cost {}'.format(balance_before - balance_after) return False # only foo*.test should succeed, since we both paid enough stacks and paid to the burn address testlib.blockstack_name_register('fooa.test', pk2, wallets[3].addr) testlib.blockstack_name_register('bara.test', pk2, wallets[3].addr) testlib.blockstack_name_register('baza.test', pk2, wallets[3].addr) testlib.blockstack_name_register('gooa.test', pk2, wallets[3].addr) testlib.blockstack_name_register('foob.test', pk2, wallets[3].addr) testlib.blockstack_name_register('barb.test', pk2, wallets[3].addr) testlib.blockstack_name_register('bazb.test', pk2, wallets[3].addr) testlib.blockstack_name_register('goob.test', pk2, wallets[3].addr) testlib.next_block(**kw) testlib.expect_snv_fail_at('bara.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('baza.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('gooa.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('barb.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('bazb.test', testlib.get_current_block(**kw)) testlib.expect_snv_fail_at('goob.test', testlib.get_current_block(**kw))
def scenario(wallets, **kw): global pk testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks( 'foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name( 'foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", stacks_price * 4, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, btc_price * 10, addr) # fund with enough bitcoin testlib.next_block(**kw) # preorder/register using Stacks---Stacks should still be used since that's what the transaction indicates testlib.blockstack_name_preorder("foo.test", pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price }) testlib.next_block(**kw) testlib.send_funds(wallets[0].privkey, btc_price * 10, addr) testlib.blockstack_name_register("foo.test", pk, wallets[3].addr) testlib.next_block(**kw) # preorder/register using Bitcoin--Stacks should NOT be used since that's what the transaction indicates testlib.blockstack_name_preorder("bar.test", pk, wallets[3].addr, price={ 'units': 'BTC', 'amount': btc_price }) testlib.next_block(**kw) testlib.blockstack_name_register('bar.test', pk, wallets[3].addr) testlib.next_block(**kw) balance_before = testlib.get_addr_balances(addr)[addr]['STACKS'] # pay with Stacks and Bitcoin. Preorder should succeed, and register should also succeed since we're paying enough stacks. Underpay bitcoin res = testlib.blockstack_name_preorder('baz.test', pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price }, tx_only=True, expect_success=True) txhex = res['transaction'] tx = virtualchain.btc_tx_deserialize(txhex) # up the burn amount btc_price = blockstack.lib.scripts.price_name( 'baz', namespace, testlib.get_current_block(**kw)) tx['outs'][2]['script'] = virtualchain.btc_make_payment_script( blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) tx['outs'][2]['value'] = btc_price - 1 tx['outs'][1]['value'] -= btc_price - 1 # re-sign for i in tx['ins']: i['script'] = '' txhex = virtualchain.btc_tx_serialize(tx) txhex_signed = virtualchain.tx_sign_all_unsigned_inputs( pk, testlib.get_utxos(addr), txhex) print txhex_signed res = testlib.broadcast_transaction(txhex_signed) if 'error' in res: print res return False testlib.next_block(**kw) # should have paid in Stacks balance_after = testlib.get_addr_balances(addr)[addr]['STACKS'] if balance_after != balance_before - stacks_price: print 'baz.test cost {}'.format(balance_before - balance_after) return False # should succeed, since we paid enough stacks (Bitcoin is not considered) testlib.blockstack_name_register('baz.test', pk, wallets[3].addr) testlib.next_block(**kw) balance_before = testlib.get_addr_balances(addr)[addr]['STACKS'] # register a name where we pay not enough stacks, but enough bitcoin. preorder should succeed, but register should fail since we tried to use stacks res = testlib.blockstack_name_preorder('goo.test', pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price - 1 }, tx_only=True, expect_success=True) txhex = res['transaction'] tx = virtualchain.btc_tx_deserialize(txhex) # up the burn amount to the name price btc_price = blockstack.lib.scripts.price_name( 'goo', namespace, testlib.get_current_block(**kw)) tx['outs'][2]['script'] = virtualchain.btc_make_payment_script( blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) tx['outs'][2]['value'] = btc_price tx['outs'][1]['value'] -= btc_price # re-sign for i in tx['ins']: i['script'] = '' txhex = virtualchain.btc_tx_serialize(tx) txhex_signed = virtualchain.tx_sign_all_unsigned_inputs( pk, testlib.get_utxos(addr), txhex) print txhex_signed res = testlib.broadcast_transaction(txhex_signed) if 'error' in res: print res return False testlib.next_block(**kw) # should have paid in Stacks balance_after = testlib.get_addr_balances(addr)[addr]['STACKS'] if balance_after != balance_before - stacks_price + 1: print 'goo.test paid {}'.format(balance_before - balance_after) return False # should fail, since we tried to pay in stacks and didn't pay enough testlib.blockstack_name_register('goo.test', pk, wallets[3].addr) testlib.next_block(**kw) testlib.expect_snv_fail_at('goo.test', testlib.get_current_block(**kw)) if testlib.get_state_engine().get_name('goo.test') is not None: print 'registered goo.test' return False balance_before = testlib.get_addr_balances(addr)[addr]['STACKS'] # underpay in both Stacks and Bitcoin. # both stacks and bitcoin will be burned. # preorder should succeed, but register should fail. res = testlib.blockstack_name_preorder('nop.test', pk, wallets[3].addr, price={ 'units': 'STACKS', 'amount': stacks_price - 1 }, safety_checks=False, tx_only=True, expect_success=True) txhex = res['transaction'] tx = virtualchain.btc_tx_deserialize(txhex) # up the burn amount to the name price, but just under btc_price = blockstack.lib.scripts.price_name( 'nop', namespace, testlib.get_current_block(**kw)) tx['outs'][2]['script'] = virtualchain.btc_make_payment_script( blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS) tx['outs'][2]['value'] = btc_price - 1 tx['outs'][1]['value'] -= btc_price - 1 # re-sign for i in tx['ins']: i['script'] = '' txhex = virtualchain.btc_tx_serialize(tx) txhex_signed = virtualchain.tx_sign_all_unsigned_inputs( pk, testlib.get_utxos(addr), txhex) print txhex_signed res = testlib.broadcast_transaction(txhex_signed) if 'error' in res: print res return False testlib.next_block(**kw) # should fail, since we didn't pay enough stacks and tried to pay in stacks res = testlib.blockstack_name_register('nop.test', pk, wallets[3].addr) testlib.next_block(**kw) testlib.expect_snv_fail_at('nop.test', testlib.get_current_block(**kw)) # preorder should still have debited balance_after = testlib.get_addr_balances(addr)[addr]['STACKS'] if balance_after != balance_before - stacks_price + 1: print 'paid {} for nop.test'.format(balance_before - balance_after) return False
def scenario(wallets, **kw): testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.lib.config.NAMESPACE_VERSION_PAY_TO_CREATOR) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # pay for a name in a v1 namespace with Stacks addr = virtualchain.address_reencode(virtualchain.get_privkey_address(pk)) addr2 = virtualchain.address_reencode( virtualchain.get_privkey_address(pk2)) # calculate the cost of doing so namespace = testlib.get_state_engine().get_namespace('test') stacks_price = blockstack.lib.scripts.price_name_stacks( 'foo', namespace, testlib.get_current_block(**kw)) btc_price = blockstack.lib.scripts.price_name( 'foo', namespace, testlib.get_current_block(**kw)) print '' print 'price of {} in Stacks is {}'.format('foo.test', stacks_price) print 'price of {} in BTC is {}'.format('foo.test', btc_price) print '' testlib.blockstack_send_tokens(addr, "STACKS", stacks_price, wallets[0].privkey) testlib.blockstack_send_tokens(addr2, "STACKS", stacks_price, wallets[0].privkey) testlib.send_funds(wallets[0].privkey, 2 * btc_price, addr) testlib.send_funds(wallets[0].privkey, 2 * btc_price, addr2) testlib.next_block(**kw) # preorder/register using BTC testlib.blockstack_name_preorder("foo.test", pk, addr2) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", pk, addr2) testlib.next_block(**kw) # try to renew using Stacks (won't work, since we send tokens the wrong burn address) testlib.blockstack_name_renew( 'foo.test', pk2, price={ 'units': 'STACKS', 'amount': stacks_price }, burn_addr=blockstack.lib.config.BLOCKSTACK_BURN_ADDRESS, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # try to renew using Stacks (won't work, since we're still collecting fees in BTC and need to send to the namespace creator's address) testlib.blockstack_name_renew('foo.test', pk2, price={ 'units': 'STACKS', 'amount': stacks_price }, burn_addr=wallets[0].addr, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # try to renew using Stacks, now that pay-to-creator has expired testlib.blockstack_name_renew('foo.test', pk2, price={ 'units': 'STACKS', 'amount': stacks_price }) testlib.next_block(**kw)
def scenario(wallets, **kw): global value_hashes testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # register 10 names for i in xrange(0, 10): res = testlib.blockstack_name_preorder("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # make some subdomains zf_template = "$ORIGIN {}\n$TTL 3600\n{}" zf_default_url = '_https._tcp URI 10 1 "https://raw.githubusercontent.com/nobody/content/profile.md"' zonefiles = { 'foo_0.test': zf_template.format( 'foo_0.test', subdomains.make_subdomain_txt( 'bar.foo_0.test', 'foo_0.test', wallets[4].addr, 0, zf_template.format('bar.foo_0.test', zf_default_url), wallets[4].privkey)), 'foo_1.test': zf_template.format( 'foo_1.test', subdomains.make_subdomain_txt( 'bar.foo_1.test', 'foo_1.test', wallets[4].addr, 0, zf_template.format('bar.foo_1.test', zf_default_url), wallets[4].privkey)), 'foo_2.test': zf_template.format( 'foo_2.test', subdomains.make_subdomain_txt( 'bar.foo_2.test', 'foo_2.test', wallets[4].addr, 0, zf_template.format('bar.foo_2.test', zf_default_url), wallets[4].privkey)), 'foo_3.test': zf_template.format( 'foo_3.test', subdomains.make_subdomain_txt( 'bar.foo_3.test', 'foo_3.test', wallets[4].addr, 0, zf_template.format('bar.foo_3.test', zf_default_url), wallets[4].privkey)), 'foo_4.test': zf_template.format( 'foo_4.test', subdomains.make_subdomain_txt( 'bar.foo_4.test', 'foo_4.test', wallets[4].addr, 0, zf_template.format('bar.foo_4.test', zf_default_url), wallets[4].privkey)), 'foo_5.test': zf_template.format( 'foo_5.test', subdomains.make_subdomain_txt( 'bar.foo_5.test', 'foo_5.test', wallets[4].addr, 0, zf_template.format('bar.foo_5.test', zf_default_url), wallets[4].privkey)), 'foo_6.test': zf_template.format( 'foo_6.test', subdomains.make_subdomain_txt( 'bar.foo_6.test', 'foo_6.test', wallets[4].addr, 0, zf_template.format('bar.foo_6.test', zf_default_url), wallets[4].privkey)), 'foo_7.test': zf_template.format( 'foo_7.test', subdomains.make_subdomain_txt( 'bar.foo_7.test', 'foo_7.test', wallets[4].addr, 0, zf_template.format('bar.foo_7.test', zf_default_url), wallets[4].privkey)), 'foo_8.test': zf_template.format( 'foo_8.test', subdomains.make_subdomain_txt( 'bar.foo_8.test', 'foo_8.test', wallets[4].addr, 0, zf_template.format('bar.foo_8.test', zf_default_url), wallets[4].privkey)), 'foo_9.test': zf_template.format( 'foo_9.test', subdomains.make_subdomain_txt( 'bar.foo_9.test', 'foo_9.test', wallets[4].addr, 0, zf_template.format('bar.foo_9.test', zf_default_url), wallets[4].privkey)), } for i in xrange(0, 10): res = testlib.blockstack_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr, zonefile_hash=blockstack.lib.storage.get_zonefile_data_hash( zonefiles['foo_{}.test'.format(i)])) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # propagate the first five subdomains for i in range(0, 5): name = 'foo_{}.test'.format(i) assert testlib.blockstack_put_zonefile(zonefiles[name]) # process the first five subdomains testlib.next_block(**kw) # propagate the last five subdomains, but don't process them for i in range(5, 10): name = 'foo_{}.test'.format(i) assert testlib.blockstack_put_zonefile(zonefiles[name]) print 'waiting for all zone files to replicate' time.sleep(10) working_dir = os.environ.get('BLOCKSTACK_WORKING_DIR') restore_dir = os.path.join(working_dir, "snapshot_dir") # make a backup db = testlib.get_state_engine() print 'begin make backups of state from {}'.format( testlib.get_current_block(**kw) - 1) for name in os.listdir(os.path.join(working_dir, 'backups')): if name.endswith('.{}'.format(testlib.get_current_block(**kw) - 1)): os.unlink(os.path.join(working_dir, 'backups', name)) db.make_backups(testlib.get_current_block(**kw)) print 'end make backups' def _backup_and_restore(): # snapshot the latest backup snapshot_path = os.path.join(working_dir, "snapshot.bsk") rc = blockstack.fast_sync_snapshot(working_dir, snapshot_path, wallets[3].privkey, None) if not rc: print "Failed to fast_sync_snapshot" return False if not os.path.exists(snapshot_path): print "Failed to create snapshot {}".format(snapshot_path) return False # sign with more keys for i in xrange(4, 6): rc = blockstack.fast_sync_sign_snapshot(snapshot_path, wallets[i].privkey) if not rc: print "Failed to sign with key {}".format(i) return False # restore! rc = restore(kw['working_dir'], snapshot_path, restore_dir, [ wallets[3].pubkey_hex, wallets[4].pubkey_hex, wallets[5].pubkey_hex ], 3) if not rc: print "1 failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], snapshot_path, restore_dir, [ wallets[5].pubkey_hex, wallets[4].pubkey_hex, wallets[3].pubkey_hex ], 3) if not rc: print "2 failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 2) if not rc: print "3 failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[3].pubkey_hex, wallets[5].pubkey_hex], 2) if not rc: print "4 failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[4].pubkey_hex, wallets[5].pubkey_hex], 2) if not rc: print "5 failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[3].pubkey_hex], 1) if not rc: print "6 failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[4].pubkey_hex, wallets[0].pubkey_hex], 1) if not rc: print "7 failed to restore snapshot {}".format(snapshot_path) return False rc = restore(kw['working_dir'], snapshot_path, restore_dir, [ wallets[0].pubkey_hex, wallets[1].pubkey_hex, wallets[5].pubkey_hex ], 1) if not rc: print "8 failed to restore snapshot {}".format(snapshot_path) return False shutil.move(restore_dir, restore_dir + '.bak') # should fail rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[3].pubkey_hex], 2) if rc: print "restored insufficient signatures snapshot {}".format( snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[3].pubkey_hex, wallets[4].pubkey_hex], 3) if rc: print "restored insufficient signatures snapshot {}".format( snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[0].pubkey_hex], 1) if rc: print "restored wrongly-signed snapshot {}".format(snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore(kw['working_dir'], snapshot_path, restore_dir, [wallets[0].pubkey_hex, wallets[3].pubkey_hex], 2) if rc: print "restored wrongly-signed snapshot {}".format(snapshot_path) return False shutil.rmtree(restore_dir) # should fail rc = restore(kw['working_dir'], snapshot_path, restore_dir, [ wallets[0].pubkey_hex, wallets[3].pubkey_hex, wallets[4].pubkey_hex ], 3) if rc: print "restored wrongly-signed snapshot {}".format(snapshot_path) return False shutil.rmtree(restore_dir) shutil.move(restore_dir + '.bak', restore_dir) return True # test backup and restore res = _backup_and_restore() if not res: return res # first five subdomains are all present in the subdomain DB subds = ['bar.foo_{}.test'.format(i) for i in range(0, 5)] subdomain_db = blockstack.lib.subdomains.SubdomainDB( os.path.join(restore_dir, 'subdomains.db'), os.path.join(restore_dir, 'zonefiles')) for subd in subds: rec = subdomain_db.get_subdomain_entry(subd) if not rec: print 'not found: {}'.format(subd) return False # last 5 subdomains are queued in the subdomain DB queue queued_zfinfos = blockstack.lib.queue.queuedb_findall( os.path.join(restore_dir, 'subdomains.db.queue'), 'zonefiles') if len(queued_zfinfos) != 5: print 'only {} zonefiles queued'.format(queued_zfinfos) print queued_zfinfos return False # process the last five subdomains testlib.next_block(**kw) shutil.rmtree(restore_dir) os.unlink(os.path.join(working_dir, "snapshot.bsk")) # test backup and restore res = _backup_and_restore() if not res: return res # all subdomains are all present in the subdomain DB subds = ['bar.foo_{}.test'.format(i) for i in range(0, 10)] subdomain_db = blockstack.lib.subdomains.SubdomainDB( os.path.join(restore_dir, 'subdomains.db'), os.path.join(restore_dir, 'zonefiles')) for subd in subds: rec = subdomain_db.get_subdomain_entry(subd) if not rec: print 'not found: {}'.format(subd) return False # nothing queued queued_zfinfos = blockstack.lib.queue.queuedb_findall( os.path.join(restore_dir, 'subdomains.db.queue'), 'zonefiles') if len(queued_zfinfos) != 0: print '{} zonefiles queued'.format(queued_zfinfos) print queued_zfinfos return False shutil.rmtree(restore_dir)
def scenario(wallets, **kw): coeff = 255 base = 32 bucket_exponents = [10, 10, 10, 9, 9, 9, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0] nonalpha_discount = 10 novowel_discount = 10 cost_unit = blockstack.config.NAME_COST_UNIT_STACKS testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, coeff, base, bucket_exponents, nonalpha_discount, novowel_discount, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # query a large amount of Stacks (exceeds 2**64) name_cost = testlib.blockstack_get_name_token_cost('foo.test') print name_cost assert name_cost['units'] == 'STACKS' assert name_cost['amount'] > 2**64 # send a large amount of Stacks (exceeds 2**64) -- should fail, since our transactions only allow 8 bytes to encode the STACKs count try: res = testlib.blockstack_send_tokens(wallets[2].addr, "STACKS", name_cost['amount'], wallets[0].privkey, expect_fail=True) assert 'error' not in res print res print 'Accidentally succeeded to send {} STACKS'.format( name_cost['amount']) return False except: pass # should fail, since we can't encode the price as a 64-bit number try: res = testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr, expect_fail=True) assert 'error' not in res print res print 'Accidentally succeeded to preorder foo.test for {} STACKs'.format( name_cost['amount']) return False except: pass ns = testlib.get_state_engine().get_namespace('test') # old price function should be wonky since it's a big float discount = 10.0 # for foo2.id, the non-alpha discount applies old_price_multiplier = 0.1 old_price_float = (float(coeff * (base**bucket_exponents[len('foo2') - 1])) / float(discount)) * cost_unit * old_price_multiplier new_price_int = blockstack.scripts.price_name( 'foo2', ns, testlib.get_current_block(**kw)) print 'old price: {}'.format(old_price_float) print 'new price: {}'.format(new_price_int) print 'diff: {}'.format(abs(int(old_price_float) - new_price_int)) # diff should be 1024, since we're dealing with floats bigger than 2**53 assert abs(int(old_price_float) - new_price_int) > 100, 'old price: {}, new price: {}'.format( old_price_float, new_price_int) testlib.blockstack_name_preorder("foo2.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo2.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw)
def scenario(wallets, **kw): global debug, consensus resp = testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) resp = testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) if 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) resp = testlib.blockstack_namespace_ready("test", wallets[1].privkey) if 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) resp = testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) resp = testlib.blockstack_name_preorder("bar.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) resp = testlib.blockstack_name_preorder("baz.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) testlib.next_block(**kw) resp = testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) return False resp = testlib.blockstack_name_register("bar.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) return False resp = testlib.blockstack_name_register("baz.test", wallets[2].privkey, wallets[3].addr) if 'error' in resp: print json.dumps(resp, indent=4) return False testlib.next_block(**kw) # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER. # baz.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER # in both cases, the consensus hash should be the one from the NAME_TRANSFER, # since there was no prior consensus hash. resp = testlib.blockstack_name_transfer("foo.test", wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print resp return False resp = testlib.blockstack_name_transfer("baz.test", wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) for name in ['foo.test', 'baz.test']: db = testlib.get_state_engine() name_rec = db.get_name(name, include_history=False) if name_rec['consensus_hash'] is None: print 'NAME_TRANSFER did not set the consensus hash: {}'.format( name_rec) return False if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_TRANSFER set wrong consensus hash (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_rec['consensus_hash']) return False # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE # the consensus hash should be the one from the NAME_UPDATE resp = testlib.blockstack_name_update('bar.test', '11' * 20, wallets[3].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) db = testlib.get_state_engine() name_rec = db.get_name('bar.test', include_history=False) bar_update_ch = name_rec['consensus_hash'] assert bar_update_ch, 'No consensus hash set on update' if bar_update_ch != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_UPDATE did not set consensus hash {} (got {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), bar_update_ch, name_rec) return False # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER # the consensus hash should still be the one from the NAME_UPDATE resp = testlib.blockstack_name_transfer('bar.test', wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) db = testlib.get_state_engine() name_rec = db.get_name('bar.test', include_history=False) if name_rec['consensus_hash'] != bar_update_ch: print 'update consensus hash not preserved (expected {}): {}'.format( bar_update_ch, name_rec) return False # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_UPDATE # the consensus hash should be from foo.test's NAME_UPDATE resp = testlib.blockstack_name_update('foo.test', '22' * 20, wallets[4].privkey) if 'error' in resp: print resp return False # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER, NAME_UPDATE # the consensus hash should be from bar.test's last NAME_UPDATE resp = testlib.blockstack_name_update('bar.test', '33' * 20, wallets[4].privkey) if 'error' in resp: print resp return False # baz.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_TRANSFER # the consensus hash should be from the last NAME_TRANSFER resp = testlib.blockstack_name_transfer('baz.test', wallets[3].addr, True, wallets[4].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) db = testlib.get_state_engine() name_rec = db.get_name('foo.test', include_history=False) name_history = db.get_name_at('foo.test', testlib.get_current_block(**kw)) foo_update_ch = name_rec['consensus_hash'] # foo.test: consensus hash should match that of the previously-sent update now. if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_UPDATE did not set consensus hash for foo.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_rec) return False # foo.test: name's history's consensus hash should match the update as well if name_history[0]['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_UPDATE did not match consensus hash in history for foo.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_history[0]) return False name_rec = db.get_name('bar.test', include_history=False) name_history = db.get_name_at('bar.test', testlib.get_current_block(**kw)) bar_update_ch = name_rec['consensus_hash'] # bar.test: consensus hash should match the update's consensus hash if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_UPDATE did not set consensus hash for bar.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_rec) return False # bar.test: name's history's consensus hash should match the update as well if name_history[0]['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_UPDATE did not match consensus hash in history for bar.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_history[0]) return False db = testlib.get_state_engine() name_rec = db.get_name('baz.test', include_history=False) name_history = db.get_name_at('baz.test', testlib.get_current_block(**kw)) # baz.test: consensus hash should match that of previously-sent NAME_TRANSFER if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_TRANSFER did not set consensus hash for baz.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_rec) return False # baz.test: name's history's consensus hash should have been set to the last NAME_TRANSFER consensus hash if name_history[0]['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_TRANSFER did not match consensus hash in history for baz.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_history[0]) return False # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER # foo.test's consensus hash should be that of its last NAME_UPDATE resp = testlib.blockstack_name_transfer('foo.test', wallets[3].addr, True, wallets[4].privkey) if 'error' in resp: print resp return False # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER # bar.test's consensus hash should be that of its last NAME_UPDATE resp = testlib.blockstack_name_transfer('bar.test', wallets[3].addr, True, wallets[4].privkey) if 'error' in resp: print resp return False # baz.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_TRANSFER, NAME_TRANSFER # baz.test's consensus hash should be that of the last NAME_TRANSFER still resp = testlib.blockstack_name_transfer('baz.test', wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) db = testlib.get_state_engine() name_rec = db.get_name('foo.test', include_history=False) name_history = db.get_name_at('foo.test', testlib.get_current_block(**kw)) # foo.test's last NAME_UPDATE set the consensus hash if name_rec['consensus_hash'] != foo_update_ch: print 'NAME_TRANSFER did not preserve previous consensus hash for foo.test (expected {}): {}'.format( foo_update_ch, name_rec) return False # foo.test's last-history-inserted consensus hash should be from the NAME_UPDATE if name_history[0]['consensus_hash'] != foo_update_ch: print 'NAME_UPDATE did not match consensus hash in history for foo.test (expected {}): {}'.format( foo_update_ch, name_history[0]) return False db = testlib.get_state_engine() name_rec = db.get_name('bar.test', include_history=False) name_history = db.get_name_at('bar.test', testlib.get_current_block(**kw)) # bar.test's last NAME_UPDATE set the consensus hash if name_rec['consensus_hash'] != bar_update_ch: print 'NAME_TRANSFER did not preserve previous consensus hash for bar.test (expected {}): {}'.format( bar_update_ch, name_rec) return False # bar.test's last-history-inserted consensus hash should be from the NAME_UPDATE if name_history[0]['consensus_hash'] != bar_update_ch: print 'NAME_UPDATE did not match consensus hash in history for bar.test (expected {}): {}'.format( bar_update_ch, name_history[0]) return False db = testlib.get_state_engine() name_rec = db.get_name('baz.test', include_history=False) name_history = db.get_name_at('baz.test', testlib.get_current_block(**kw)) # baz.test's last NAME_TRANSFER set the consensus hash if name_rec['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_TRANSFER did not preserve previous consensus hash for baz.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_rec) return False # baz.test's last-history-inserted consensus hash should be from the NAME_TRANSFER if name_history[0]['consensus_hash'] != testlib.get_consensus_at( testlib.get_current_block(**kw) - 1): print 'NAME_TRANSFER did not match consensus hash in history for baz.test (expected {}): {}'.format( testlib.get_consensus_at(testlib.get_current_block(**kw) - 1), name_history[0]) return False # foo.test: NAME_PREORDER, NAME_REGISTRATION, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER, NAME_TRANSFER # foo.test's consensus hash should be that of its last NAME_UPDATE resp = testlib.blockstack_name_transfer('foo.test', wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print resp return False # bar.test: NAME_PREORDER, NAME_REGISTRATION, NAME_UPDATE, NAME_TRANSFER, NAME_UPDATE, NAME_TRANSFER, NAME_TRANSFER # bar.test's consensus hash should be that of its last NAME_UPDATE resp = testlib.blockstack_name_transfer('bar.test', wallets[4].addr, True, wallets[3].privkey) if 'error' in resp: print resp return False testlib.next_block(**kw) db = testlib.get_state_engine() name_rec = db.get_name('foo.test', include_history=False) name_history = db.get_name_at('foo.test', testlib.get_current_block(**kw)) # foo.test's last NAME_UPDATE set the consensus hash if name_rec['consensus_hash'] != foo_update_ch: print 'NAME_TRANSFER did not preserve previous consensus hash (expected {}): {}'.format( foo_update_ch, name_rec) return False # foo.test's last-history-inserted consensus hash should be from NAME_UPDATE if name_history[0]['consensus_hash'] != foo_update_ch: print 'NAME_UPDATE did not match consensus hash in history (expected {}): {}'.format( foo_update_ch, name_history[0]) return False name_rec = db.get_name('bar.test', include_history=False) name_history = db.get_name_at('bar.test', testlib.get_current_block(**kw)) # bar.test's last NAME_UPDATE set the consensus hash if name_rec['consensus_hash'] != bar_update_ch: print 'NAME_TRANSFER did not preserve previous consensus hash (expected {}): {}'.format( bar_update_ch, name_rec) return False # bar.test's last-history-inserted consensus hash should be from the NAME_UPDATE if name_history[0]['consensus_hash'] != bar_update_ch: print 'NAME_UPDATE did not match consensus hash in history (expected {}): {}'.format( bar_update_ch, name_history[0]) return False