def scenario(wallets, **kw): # pass 100 stacks around in a circle. new_keys = [wallets[0].privkey] + [ virtualchain.lib.ecdsalib.ecdsa_private_key().to_hex() for i in range(0, 3) ] for i in range(0, 3 * len(new_keys)): new_addr = virtualchain.get_privkey_address(new_keys[(i + 1) % len(new_keys)]) cur_addr = virtualchain.get_privkey_address(new_keys[i % len(new_keys)]) initial_new_balance_info = json.loads( testlib.nodejs_cli('balance', new_addr)) initial_cur_balance_info = json.loads( testlib.nodejs_cli('balance', cur_addr)) print '\n initial new balance info: {} \n'.format( initial_new_balance_info) if 'STACKS' not in initial_new_balance_info: initial_new_balance_info['STACKS'] = 0 if i > 0: testlib.send_funds(wallets[0].privkey, 800000, cur_addr) testlib.send_funds(wallets[0].privkey, 800000, new_addr) testlib.blockstack_send_tokens(new_addr, 'STACKS', 100, new_keys[i % len(new_keys)]) testlib.next_block(**kw) balance_info = json.loads(testlib.nodejs_cli('balance', new_addr)) assert int(balance_info['STACKS']) == 100 + int( initial_new_balance_info['STACKS']) if (i + 1) % len(new_keys) != 0: assert int(balance_info['STACKS']) == 100 balance_info = json.loads(testlib.nodejs_cli('balance', cur_addr)) assert int(balance_info['STACKS']) == int( initial_cur_balance_info['STACKS']) - 100 if i % len(new_keys) != 0: assert int(balance_info['STACKS']) == 0 # each *new* address has 6 history items -- three spends, three receives for new_key in new_keys[1:]: new_addr = virtualchain.get_privkey_address(new_key) history = requests.get( 'http://localhost:16268/v1/accounts/{}/history?page=0'.format( new_addr)).json() # should have gotten 3 debits for 100, and 3 credits for 100 assert int(history[0]['credit_value']) == 300, history assert int(history[0]['debit_value']) == 300, history assert len(history) == 6, history
def check(state_engine): # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: print "namespace reveal exists" return False ns = state_engine.get_namespace("test") if ns is None: print "no namespace" return False if ns['namespace_id'] != 'test': print "wrong namespace" return False for name in [ 'hello_imports.test', 'hello.test', 'hello2.test', 'hello.subdomains.test' ]: name_info = testlib.nodejs_cli('whois', name) name_info = json.loads(name_info) if 'error' in name_info: print name_info return False if name_info['address'] != wallets[3].addr: print 'wrong address; expected {}'.format(wallets[3].addr) print name_info return False if 'http://localhost:4000' not in name_info['zonefile']: print 'wrong zone file; expected http://localhost:4000' print name_info return False profile = testlib.nodejs_cli('lookup', name) profile = json.loads(profile) if 'error' in profile: print profile return False if not profile['zonefile']: print 'no zonefile' print profile return False if not profile['profile']: print 'no profile' print profile return False return True
def get_wallet_balances(wallets): balances = {} for w in wallets: balance_info = json.loads(testlib.nodejs_cli('balance', w.addr)) for token_type in balance_info: balance_info[token_type] = int(balance_info[token_type]) balances[w.addr] = balance_info return balances
def scenario(wallets, **kw): # should fail testlib.blockstack_namespace_preorder("test_fail", wallets[1].addr, wallets[0].privkey, safety_checks=False, price={ 'units': 'STACKS', 'amount': 0 }) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test_fail", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.expect_snv_fail_at('test_fail', testlib.get_current_block(**kw)) # should succeed testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[3].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[3].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # should fail (empty balance) testlib.blockstack_name_preorder('foo_fail.test', wallets[0].privkey, wallets[3].addr, safety_checks=False, expect_fail=True) testlib.next_block(**kw) testlib.blockstack_name_register('foo_fail.test', wallets[0].privkey, wallets[3].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo_fail.test', testlib.get_current_block(**kw)) # should succeed testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # deplete balance balance = json.loads(testlib.nodejs_cli('balance', wallets[2].addr)) testlib.blockstack_send_tokens(wallets[0].addr, 'STACKS', int(balance['STACKS']), wallets[2].privkey) balance = json.loads(testlib.nodejs_cli('balance', wallets[3].addr)) testlib.blockstack_send_tokens(wallets[0].addr, 'STACKS', int(balance['STACKS']), wallets[3].privkey) testlib.next_block(**kw) # should fail--not enough funds testlib.blockstack_name_renew("foo.test", wallets[3].privkey, expect_fail=True) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # should fail--not enough funds testlib.blockstack_name_preorder("baz.test", wallets[2].privkey, wallets[3].addr, expect_fail=True, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('baz.test', testlib.get_current_block(**kw)) testlib.blockstack_name_register("baz.test", wallets[2].privkey, wallets[3].addr, safety_checks=False) testlib.next_block(**kw) testlib.expect_snv_fail_at('baz.test', testlib.get_current_block(**kw))
def scenario(wallets, **kw): # check initial balances initial_balances = get_wallet_balances(wallets) testlib.blockstack_namespace_preorder("test", wallets[5].addr, wallets[0].privkey) testlib.next_block(**kw) # end 689 # balance should have decreased by namespace cost. No other wallets should be affected namespace_price_info = json.loads( testlib.nodejs_cli('price_namespace', 'test')) assert namespace_price_info['units'] == STACKS namespace_cost = int(namespace_price_info['amount']) testlib.blockstack_namespace_reveal( "test", wallets[5].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) # end 690 (vested!) testlib.blockstack_namespace_ready("test", wallets[5].privkey) testlib.next_block(**kw) # end 691 testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # end 692 (vested!) # balance should have decreased by stacks token amount name_price_info = json.loads(testlib.nodejs_cli('price', 'foo.test')) assert namespace_price_info['units'] == STACKS name_cost = int(name_price_info['amount']) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) # vesting should happen testlib.next_block(**kw) # end 693 testlib.next_block(**kw) # end 694 (vested!) for i in range(0, 2): balances = get_wallet_balances(wallets) expected_balances = { wallets[0].addr: { STACKS: initial_balances[wallets[0].addr][STACKS] - namespace_cost + (VESTING_AMOUNT + 1) * (3 + i) }, wallets[1].addr: { STACKS: initial_balances[wallets[1].addr][STACKS] + (VESTING_AMOUNT * 2) * (3 + i) }, wallets[2].addr: { STACKS: initial_balances[wallets[2].addr][STACKS] - name_cost + (VESTING_AMOUNT * 3) * (3 + i) }, wallets[3].addr: { STACKS: initial_balances[wallets[3].addr][STACKS] + (VESTING_AMOUNT * 4) * (3 + i) }, wallets[4].addr: { STACKS: initial_balances[wallets[4].addr][STACKS] + (VESTING_AMOUNT * 5) * (3 + i) }, wallets[5].addr: { STACKS: initial_balances[wallets[5].addr][STACKS] }, } for j in range(0, len(wallets)): w = wallets[j] assert expected_balances[w.addr][STACKS] == balances[w.addr][ STACKS], 'Balance mismatch on wallet {} {}\'s {}: expected:\n{}, got:\n{}'.format( j, w.addr, STACKS, json.dumps(expected_balances[w.addr][STACKS], indent=4, sort_keys=True), json.dumps(balances[w.addr][STACKS], indent=4, sort_keys=True)) testlib.next_block(**kw) testlib.next_block(**kw) #vested!
def scenario(wallets, **kw): # pass 100 stacks around in a circle. new_keys = [wallets[0].privkey] + [ virtualchain.lib.ecdsalib.ecdsa_private_key().to_hex() for i in range(0, 4) ] for k in range(0, 4): for j in range(0, len(new_keys)): i = j new_addr = virtualchain.get_privkey_address( new_keys[(i + 1) % len(new_keys)]) cur_addr = virtualchain.get_privkey_address( new_keys[i % len(new_keys)]) initial_new_balance_info = json.loads( testlib.nodejs_cli('balance', new_addr)) initial_cur_balance_info = json.loads( testlib.nodejs_cli('balance', cur_addr)) print '\n initial new balance info: {} \n'.format( initial_new_balance_info) if 'STACKS' not in initial_new_balance_info: initial_new_balance_info['STACKS'] = 0 if i > 0: testlib.send_funds(wallets[0].privkey, 500000, cur_addr) testlib.send_funds(wallets[0].privkey, 500000, new_addr) testlib.blockstack_send_tokens(new_addr, 'STACKS', 100, new_keys[i % len(new_keys)], safety_checks=False) # consolidate utxos = testlib.get_utxos(wallets[0].addr) if len(utxos) > 1: balance = testlib.get_balance(wallets[0].addr) testlib.send_funds(wallets[0].privkey, balance - 5500, wallets[0].addr, change=False) utxos = testlib.get_utxos(new_addr) if len(utxos) > 1: balance = testlib.get_balance(new_addr) testlib.send_funds(new_keys[(i + 1) % len(new_keys)], balance - 5500, new_addr, change=False) testlib.next_block(**kw) for j in range(0, len(new_keys)): i = j new_addr = virtualchain.get_privkey_address( new_keys[(i + 1) % len(new_keys)]) cur_addr = virtualchain.get_privkey_address( new_keys[i % len(new_keys)]) if j == len(new_keys) - 1: if (i + 1) % len(new_keys) != 0: # last address should have 100 stacks, unless new_addr is wallets[0] balance_info = json.loads( testlib.nodejs_cli('balance', new_addr)) assert int(balance_info['STACKS']) == 100 else: if i % len(new_keys) != 0: # every other address, except wallets[0], should have 0 balance balance_info = json.loads( testlib.nodejs_cli('balance', cur_addr)) assert int(balance_info['STACKS']) == 0 # consolidate for j in range(0, len(new_keys)): cur_addr = virtualchain.get_privkey_address( new_keys[i % len(new_keys)]) utxos = testlib.get_utxos(cur_addr) if len(utxos) > 1: balance = testlib.get_balance(cur_addr) testlib.send_funds(new_keys[i % len(new_keys)], balance - 5500, cur_addr, change=False) testlib.next_block(**kw) # each *new* address has 4 history items -- four spends, four receives for new_key in new_keys[1:]: new_addr = virtualchain.get_privkey_address(new_key) history = requests.get( 'http://localhost:16268/v1/accounts/{}/history?page=0'.format( new_addr)).json() # should have gotten 4 debits for 100, and 4 credits for 100 assert int(history[0]['credit_value']) == 400, history assert int(history[0]['debit_value']) == 400, history assert len(history) == 8, history
def scenario(wallets, **kw): # will be rejected, since locked testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 689 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 600000 assert balances[wallets[1].addr][STACKS] == 0 assert balances[wallets[2].addr][STACKS] == 0 # will succeed, since whitelisted testlib.blockstack_send_tokens( wallets[1].addr, "STACKS", 100000, wallets[0].privkey, safety_checks=False ) # need to disable safety checks since it's "currently" block 690 testlib.next_block(**kw) # end of 690 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # try to send back (will fail since its locked) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[1].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 691 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # try to send back (will fail since the address is not whitelisted) testlib.blockstack_send_tokens(wallets[0].addr, "STACKS", 100000, wallets[1].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 692 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # send to wallets[2] (should succeed) testlib.blockstack_send_tokens( wallets[2].addr, "STACKS", 50000, wallets[1].privkey, safety_checks=False ) # need to disable safety checks since it's "currently" block 692 testlib.next_block(**kw) # end of 693 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 50000 assert balances[wallets[2].addr][STACKS] == 50000 # send to wallets[1] (should fail since locked) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 50000, wallets[2].privkey, safety_checks=False, expect_fail=True) testlib.next_block(**kw) # end of 694 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 50000 assert balances[wallets[2].addr][STACKS] == 50000 # send to wallets[1] (should succeed now) testlib.blockstack_send_tokens(wallets[1].addr, "STACKS", 50000, wallets[2].privkey, safety_checks=False) testlib.next_block(**kw) # end of 695 balances = testlib.get_wallet_balances(wallets) assert balances[wallets[0].addr][STACKS] == 500000 assert balances[wallets[1].addr][STACKS] == 100000 assert balances[wallets[2].addr][STACKS] == 0 # send to a new address new_addr = 'n17Wp3qk9WNGESLHHey18dcgQAn5aDDPuE' testlib.blockstack_send_tokens(new_addr, 'STACKS', 123456, wallets[0].privkey, safety_checks=False) testlib.next_block(**kw) # end of 696 balance_info = json.loads(testlib.nodejs_cli('balance', new_addr)) assert int(balance_info['STACKS']) == 123456 balance_info = json.loads(testlib.nodejs_cli('balance', wallets[0].addr)) assert int(balance_info['STACKS']) == 500000 - 123456
def scenario(wallets, **kw): global GAIA_READ_URL global GAIA_READ_PORT global GAIA_WRITE_PORT global GAIA_WRITE_URL # get gaia hub info with open(os.path.join(os.environ['BLOCKSTACK_WORKING_DIR'], 'gaia.conf'), 'r') as f: GAIA_CONF = json.loads(f.read().strip()) try: GAIA_READ_PORT = urlparse.urlparse( GAIA_CONF['readURL']).netloc.split(':')[-1] GAIA_READ_PORT = int(GAIA_READ_PORT) except: GAIA_READ_PORT = 80 if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT'): GAIA_READ_PORT = int( os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT']) read_urlinfo = urlparse.urlparse(GAIA_CONF['readURL']) GAIA_READ_URL = 'http://{}:{}'.format( read_urlinfo.netloc.split(':')[0], GAIA_READ_PORT) GAIA_WRITE_PORT = GAIA_CONF['port'] if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT'): GAIA_WRITE_PORT = int( os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT']) GAIA_WRITE_URL = 'http://{}:{}'.format(GAIA_CONF['servername'], GAIA_WRITE_PORT) # fill in URL tb_conf_path = os.path.join(os.environ['BLOCKSTACK_WORKING_DIR'], 'transaction-broadcaster.conf') with open(tb_conf_path, 'r') as f: tb_conf = json.loads(f.read().strip()) testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, -1, 250, 4, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=3) testlib.next_block(**kw) # import a name with the CLI res = testlib.nodejs_cli('name_import', 'hello_imports.test', 'ID-{}'.format(wallets[3].addr), 'http://*****:*****@Person', 'account': [] }, wallets[3].privkey) testlib.blockstack_put_profile('hello_imports.test', profile_data, wallets[3].privkey, 'http://*****:*****@Person', 'account': [] }, wallets[3].privkey) testlib.blockstack_put_profile('hello2.test', profile_data, wallets[3].privkey, 'http://localhost:4001') stop_subdomain_registrar()
def scenario( wallets, **kw ): global GAIA_READ_URL global GAIA_READ_PORT global GAIA_WRITE_PORT global GAIA_WRITE_URL global owner_privkey global owner_address # get gaia hub info with open(os.path.join(os.environ['BLOCKSTACK_WORKING_DIR'], 'gaia.conf'), 'r') as f: GAIA_CONF = json.loads(f.read().strip()) try: GAIA_READ_PORT = urlparse.urlparse(GAIA_CONF['readURL']).netloc.split(':')[-1] GAIA_READ_PORT = int(GAIA_READ_PORT) except: GAIA_READ_PORT = 80 if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT'): GAIA_READ_PORT = int(os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT']) read_urlinfo = urlparse.urlparse(GAIA_CONF['readURL']) GAIA_READ_URL = 'http://{}:{}'.format(read_urlinfo.netloc.split(':')[0], GAIA_READ_PORT) GAIA_WRITE_PORT = GAIA_CONF['port'] if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT'): GAIA_WRITE_PORT = int(os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT']) GAIA_WRITE_URL = 'http://{}:{}'.format(GAIA_CONF['servername'], GAIA_WRITE_PORT) testlib.blockstack_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, -1, 250, 4, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey, version_bits=1) testlib.next_block( **kw ) testlib.blockstack_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # register this user under a keychain res = testlib.nodejs_cli('make_keychain') res = json.loads(res) mnemonic = res['mnemonic'] owner_privkey = res['ownerKeyInfo']['privateKey'] owner_address = res['ownerKeyInfo']['idAddress'][3:] profile = { 'type': '@Person', 'account': [], 'name': 'Testy McTestface', } testlib.blockstack_register_user('foo.test', wallets[3].privkey, owner_privkey, profile=profile, profile_name='0/profile.json', **kw) # verify that we can look up this profile res = testlib.blockstack_get_profile('foo.test') if res['profile'] != profile: print 'wrong profile' print profile print res['profile'] return False # patch the profile to insert an app URL res = testlib.nodejs_cli('gaia_sethub', 'foo.test', GAIA_WRITE_URL, 'http://www.testapp.com', GAIA_WRITE_URL, mnemonic) res = testlib.blockstack_get_profile('foo.test') updated_profile = {} updated_profile.update(res['profile']) apps = updated_profile['apps'] del updated_profile['apps'] if updated_profile != profile: print 'wrong profile after sethub' print expected_profile print res['profile'] return False if not apps['http://www.testapp.com'].startswith(GAIA_READ_URL): print 'wrong app entry for testapp.com' print apps print GAIA_WRITE_URL return False print "" print "mnemnic: {}".format(mnemonic) print "hub url: {}".format(GAIA_WRITE_URL) print ""
def scenario(wallets, **kw): # force paying in bitcoin. It should fail testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey, price={ 'units': 'BTC', 'amount': 40000000 }, expect_fail=True) testlib.next_block(**kw) testlib.expect_snv_fail_at('test', testlib.get_current_block(**kw)) # should fail, since not preordered testlib.blockstack_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.expect_snv_fail_at('test', testlib.get_current_block(**kw)) # try again, but underpay namespace_price_info = json.loads( testlib.nodejs_cli('price_namespace', 'test')) assert namespace_price_info['units'] == STACKS namespace_cost = int(namespace_price_info['amount']) # should succeed testlib.blockstack_namespace_preorder("test", wallets[2].addr, wallets[0].privkey, price={ 'units': STACKS, 'amount': namespace_cost - 1 }) testlib.next_block(**kw) # should fail, since we underpaid by 1 microstack testlib.blockstack_namespace_reveal( "test", wallets[2].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.expect_snv_fail_at('test', testlib.get_current_block(**kw)) # try again, but overpay (should succeed) testlib.blockstack_namespace_preorder("test", wallets[3].addr, wallets[0].privkey, price={ 'units': STACKS, 'amount': namespace_cost + 1 }) testlib.next_block(**kw) # should succeed testlib.blockstack_namespace_reveal( "test", wallets[3].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=blockstack.NAMESPACE_VERSION_PAY_WITH_STACKS) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[3].privkey) testlib.next_block(**kw) # force paying in Bitcoin. It should succeed, but the register should fail testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[0].addr, price={ 'units': 'BTC', 'amount': 640000 }) testlib.next_block(**kw) # should fail, since the preorder didn't pay the right type of currency testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[0].addr) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) name_price_info = json.loads(testlib.nodejs_cli('price', 'foo.test')) assert namespace_price_info['units'] == STACKS name_cost = int(name_price_info['amount']) # try underpaying in STACKs. It should succeed, but the register should fail testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[1].addr, price={ 'units': STACKS, 'amount': name_cost - 1 }) testlib.next_block(**kw) # should fail, since the preorder didn't pay enough money testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[1].addr) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # try overpaying in STACKs. It should succeed testlib.blockstack_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr, price={ 'units': STACKS, 'amount': name_cost + 1 }) testlib.next_block(**kw) # should succeed this time testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr, zonefile_hash='11' * 20) testlib.next_block(**kw) # try renewing with BTC (should fail) testlib.blockstack_name_renew('foo.test', wallets[3].privkey, price={ 'units': 'BTC', 'amount': 640000 }, expect_fail=True) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # try renewing with STACKs, but underpaying (should fail) testlib.blockstack_name_renew('foo.test', wallets[3].privkey, price={ 'units': STACKS, 'amount': name_cost - 1 }, expect_fail=True) testlib.next_block(**kw) testlib.expect_snv_fail_at('foo.test', testlib.get_current_block(**kw)) # try renewing with STACKs but overpay (should succeed) testlib.blockstack_name_renew('foo.test', wallets[3].privkey, recipient_addr=wallets[4].addr, zonefile_hash='44' * 20, price={ 'units': STACKS, 'amount': name_cost + 1 }) testlib.next_block(**kw)
def scenario(wallets, **kw): global GAIA_READ_URL global GAIA_READ_PORT global GAIA_WRITE_PORT global GAIA_WRITE_URL global owner_privkey global owner_address # get gaia hub info with open(os.path.join(os.environ['BLOCKSTACK_WORKING_DIR'], 'gaia.conf'), 'r') as f: GAIA_CONF = json.loads(f.read().strip()) try: GAIA_READ_PORT = urlparse.urlparse( GAIA_CONF['readURL']).netloc.split(':')[-1] GAIA_READ_PORT = int(GAIA_READ_PORT) except: GAIA_READ_PORT = 80 if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT'): GAIA_READ_PORT = int( os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT']) read_urlinfo = urlparse.urlparse(GAIA_CONF['readURL']) GAIA_READ_URL = 'http://{}:{}'.format( read_urlinfo.netloc.split(':')[0], GAIA_READ_PORT) GAIA_WRITE_PORT = GAIA_CONF['port'] if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT'): GAIA_WRITE_PORT = int( os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT']) GAIA_WRITE_URL = 'http://{}:{}'.format(GAIA_CONF['servername'], GAIA_WRITE_PORT) testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, -1, 250, 4, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey, version_bits=1) testlib.next_block(**kw) testlib.blockstack_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # register this user under a keychain res = testlib.nodejs_cli('make_keychain') res = json.loads(res) mnemonic = res['mnemonic'] owner_privkey = res['ownerKeyInfo']['privateKey'] owner_address = res['ownerKeyInfo']['idAddress'][3:] profile = { 'type': '@Person', 'account': [], 'name': 'Testy McTestface', } testlib.blockstack_register_user('foo.test', wallets[3].privkey, owner_privkey, profile=profile, **kw) print "" print "mnemnic: {}".format(mnemonic) print "hub url: {}".format(GAIA_WRITE_URL) print ""
def scenario(wallets, **kw): global GAIA_READ_URL global GAIA_READ_PORT global GAIA_WRITE_PORT global GAIA_WRITE_URL global owner_privkey global owner_address # get gaia hub info with open(os.path.join(os.environ['BLOCKSTACK_WORKING_DIR'], 'gaia.conf'), 'r') as f: GAIA_CONF = json.loads(f.read().strip()) try: GAIA_READ_PORT = urlparse.urlparse( GAIA_CONF['readURL']).netloc.split(':')[-1] GAIA_READ_PORT = int(GAIA_READ_PORT) except: GAIA_READ_PORT = 80 if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT'): GAIA_READ_PORT = int( os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_READ_PORT']) read_urlinfo = urlparse.urlparse(GAIA_CONF['readURL']) GAIA_READ_URL = 'http://{}:{}'.format( read_urlinfo.netloc.split(':')[0], GAIA_READ_PORT) GAIA_WRITE_PORT = GAIA_CONF['port'] if os.environ.get('BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT'): GAIA_WRITE_PORT = int( os.environ['BLOCKSTACK_PUBLIC_TESTNET_GAIA_WRITE_PORT']) GAIA_WRITE_URL = 'http://{}:{}'.format(GAIA_CONF['servername'], GAIA_WRITE_PORT) GAIA_DISK_PATH = GAIA_CONF['diskSettings']['storageRootDirectory'] testlib.blockstack_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "test", wallets[1].addr, -1, 250, 4, [0, 0, 0, 0, 0, 0, 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("test", wallets[1].privkey) testlib.next_block(**kw) # register this user under a keychain res = testlib.nodejs_cli('make_keychain') res = json.loads(res) mnemonic = res['mnemonic'] owner_privkey = res['ownerKeyInfo']['privateKey'] owner_address = res['ownerKeyInfo']['idAddress'][3:] testlib.blockstack_register_user('foo.test', wallets[3].privkey, owner_privkey, **kw) # get app keys res = testlib.nodejs_cli('get_app_keys', mnemonic, 'ID-{}'.format(owner_address), 'http://www.testapp.com') res = json.loads(res) app_privkey = res['keyInfo']['privateKey'] if res['keyInfo'][ 'privateKey'] != 'TODO' else res['legacyKeyInfo']['privateKey'] # patch the profile to insert an app URL res = testlib.nodejs_cli('gaia_sethub', 'foo.test', GAIA_WRITE_URL, 'http://www.testapp.com', GAIA_WRITE_URL, mnemonic) # store a bunch of data to Gaia tmpdir = os.path.join(os.environ['BLOCKSTACK_WORKING_DIR'], 'gaia_inputs') os.makedirs(tmpdir) count = 3 random_noise = os.urandom(32) for i in range(0, count): path = os.path.join(tmpdir, 'gaia-{}.txt'.format(i)) with open(path, 'w') as f: f.write('gaia data {}'.format(i)) f.write(random_noise) encrypted_path = os.path.join(tmpdir, 'gaia-{}-encrypted.txt'.format(i)) with open(encrypted_path, 'w') as f: f.write('gaia encrypted data {}'.format(i)) f.write(random_noise) print '\n\nputfile {}\n\n'.format(path) testlib.blockstack_gaia_putfile(app_privkey, path, '/foo/gaia-{}.txt'.format(i), GAIA_WRITE_URL, encrypt=False, sign=False) testlib.blockstack_gaia_putfile(app_privkey, encrypted_path, '/foo/gaia-{}-encrypted.txt'.format(i), GAIA_WRITE_URL, encrypt=True) testlib.blockstack_gaia_putfile(app_privkey, path, '/foo/gaia-{}-signed.txt'.format(i), GAIA_WRITE_URL, encrypt=False, sign=True) testlib.blockstack_gaia_putfile( app_privkey, encrypted_path, '/foo/gaia-{}-encrypted-signed.txt'.format(i), GAIA_WRITE_URL, encrypt=True, sign=True) # make sure they're all there res = testlib.blockstack_gaia_listfiles(app_privkey, GAIA_WRITE_URL) if len(res) != 5 * count: print json.dumps(res, indent=4, sort_keys=True) print 'wrong number of files: {}'.format(len(res)) return False for i in range(0, count): for filename in [ 'foo/gaia-{}.txt'.format(i), 'foo/gaia-{}-encrypted.txt'.format(i), 'foo/gaia-{}-signed.txt'.format(i), 'foo/gaia-{}-signed.txt.sig'.format(i), 'foo/gaia-{}-encrypted-signed.txt'.format(i) ]: if filename not in res: print json.dumps(res, indent=4, sort_keys=True) print 'missing {}'.format(filename) return False def check_reads(): # make sure we can get them all for i in range(0, count): for filename in [ 'foo/gaia-{}.txt'.format(i), 'foo/gaia-{}-encrypted.txt'.format(i), 'foo/gaia-{}-signed.txt'.format(i), 'foo/gaia-{}-encrypted-signed.txt'.format(i) ]: verify = 'signed' in filename decrypt = 'encrypted' in filename privkey = app_privkey if verify or decrypt else None expected_data = 'gaia encrypted data {}{}'.format( i, random_noise) if decrypt else 'gaia data {}{}'.format( i, random_noise) res = testlib.blockstack_gaia_getfile('foo.test', 'http://www.testapp.com', filename, privkey=privkey, verify=verify, decrypt=decrypt) if res != expected_data: print 'expected\n{}'.format(expected_data) print 'got\n{}'.format(res) import time time.sleep(1000000) return False return True res = check_reads() if not res: return False # dump the gaia hub and make sure they're all there dump_dir = os.path.join(os.environ['BLOCKSTACK_WORKING_DIR'], 'gaia-dump') res = testlib.blockstack_gaia_dump_bucket('foo.test', 'http://www.testapp.com', GAIA_WRITE_URL, mnemonic, dump_dir) if 'error' in res: print res return False app_storage_path = os.path.join( GAIA_DISK_PATH, virtualchain.address_reencode( virtualchain.get_privkey_address(app_privkey + '01'), network='mainnet')) def compare_directories(): for filename in os.listdir(dump_dir): app_storage_filename = os.path.join(app_storage_path, filename.replace('\\x2f', '/')) deserialized_filename = os.path.join(dump_dir, filename) d1 = open(deserialized_filename).read() d2 = open(app_storage_filename).read() if d1 != d2: print "{} and {} differ".format(app_storage_filename, deserialized_filename) return False for filename in os.listdir(os.path.join(app_storage_path, 'foo')): serialized_filename = os.path.join(dump_dir, 'foo\\x2f{}'.format(filename)) app_storage_filename = os.path.join(app_storage_path, 'foo', filename) d1 = open(serialized_filename).read() d2 = open(app_storage_filename).read() if d1 != d2: print "{} and {} differ".format(app_storage_filename, app_storage_filename) return False return True res = compare_directories() if not res: return False shutil.move(app_storage_path, '{}.bak'.format(app_storage_path)) os.makedirs(app_storage_path) # restore the gaia dump res = testlib.blockstack_gaia_restore_bucket('foo.test', 'http://www.testapp.com', GAIA_WRITE_URL, mnemonic, dump_dir) if 'error' in res: print res return False res = compare_directories() if not res: return False res = check_reads() if not res: return False
def do_POST(self): content_type = self.headers.getheader('content-type') postvars = {} txid = None if content_type is not None: ctype, pdict = cgi.parse_header(content_type) if ctype == 'multipart/form-data': postvars = cgi.parse_multipart(self.rfile, pdict) elif ctype == 'application/x-www-form-urlencoded': length = int(self.headers.getheader('content-length')) postvars = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1) if self.path == '/sendBTC': # fund an address with bitcoin addr = postvars.get('addr', [None]) value = postvars.get('value', [None]) if addr[0] is None or value[0] is None: log.error("Missing addr or value") self.error_page(400, "Invalid request: missing addr or value") return # addr can be either base58check or c32check if re.match('^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+$', addr[0]): # c32check try: res = testlib.nodejs_cli('convert_address', addr[0]) res = json.loads(res) addr = [res['BTC']] except: self.error_page(500, 'Failed to convert {} to a Stacks address'.format(addr[0])) self.end_headers() return try: value = int(value[0]) addr = virtualchain.address_reencode(addr[0]) except: log.error("Failed to read addr and/or value") log.error("postvars = {}".format(postvars)) self.error_page(400, "Invalid addr or value") return # don't take too much if value > 10000000: log.error('{} requested too much ({})'.format(addr, value)) self.error_page(400, 'Requested too much BTC (at most {} is allowed)'.format(10000000)) return # send funds res = testlib.send_funds(testlib.get_default_payment_wallet().privkey, value, addr) if 'error' in res: log.error("Failed to send {} BTC from {} to {}: {}".format( value, testlib.get_default_payment_wallet().privkey, addr, res )) self.error_page(400, "Failed to send value") return txid = res['txid'] self.send_response(302) location = '/' if txid: location = '/?bitcoinTxid={}'.format(txid) self.send_header('location', location) self.end_headers() return elif self.path == '/sendStacks': # fund an address with bitcoin addr = postvars.get('addr', [None]) value = postvars.get('value', [None]) if addr[0] is None or value[0] is None: log.error("Missing addr or value") log.error("Got {}".format(postvars)) self.error_page(400, "Invalid request: missing addr or value") self.end_headers() return # addr can be either base58check or c32check if re.match('^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]+$', addr[0]): # c32check try: res = testlib.nodejs_cli('convert_address', addr[0]) res = json.loads(res) addr = [res['BTC']] except: self.error_page(500, 'Failed to convert {} to a Stacks address'.format(addr[0])) self.end_headers() return try: value = int(value[0]) addr = virtualchain.address_reencode(str(addr[0])) except: log.error("Failed to read addr and/or value") log.error('addr = {}, value = {}'.format(addr[0], value[0])) self.error_page(400, "Invalid addr or value") self.end_headers() return # don't take too much if value > 1000000000: log.error('{} requested too much ({})'.format(addr, value)) self.error_page(400, 'Requested too much STACKS (at most {} is allowed)'.format(1000000000)) self.end_headers() return # send funds res = None try: res = testlib.blockstack_send_tokens(addr, 'STACKS', value, wallets[3].privkey) txid = res['transaction_hash'] except Exception as e: log.exception(e) self.error_page(500, 'Failed to send tokens to {}\n{}'.format(addr, ''.join(traceback.format_exc()))) self.end_headers() return if 'error' in res: log.error("Failed to send {} Stacks from {} to {}: {}".format( value, testlib.get_default_payment_wallet().privkey, addr, res )) self.error_page(400, "Failed to send value") self.end_headers() return # also send some BTC res = testlib.send_funds(testlib.get_default_payment_wallet().privkey, 5000000, addr) if 'error' in res: log.error("Failed to send {} BTC from {} to {}: {}".format( value, testlib.get_default_payment_wallet().privkey, addr, res )) self.error_page(400, "Failed to send value") return self.send_response(302) location = '/' if txid: location = '/?stacksTxid={}'.format(txid) self.send_header('location', location) self.end_headers() return else: log.error("Unsupported path {}".format(self.path)) self.error_page(400, "Only support /sendfunds at this time") self.end_headers() return