def check_wallet(payment_privkey, owner_privkey, data_privkey): config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] res = testlib.blockstack_REST_call('GET', '/v1/wallet/keys', None, api_pass=api_pass) if 'error' in res: print 'failed to get wallet' print res return False res = res['response'] if res['payment_privkey'] != payment_privkey: print 'wrong payment privkey' return False if res['owner_privkey'] != owner_privkey: print 'wrong owner privkey' return False if res['data_privkey'] != data_privkey: print 'wrong data privkey' return False return True
def get_blockstack_client_session( new_blockstack_client_session_opts=None ): """ Get or instantiate our storage API session. """ global blockstack_client_session global blockstack_client_session_opts # do we have storage? if blockstack_client is None: return None opts = None if new_blockstack_client_session_opts is not None: opts = new_blockstack_client_session_opts else: opts = blockstack_client.get_config() if opts is None: return None blockstack_client_session = blockstack_client.session( conf=opts ) if blockstack_client_session is not None: if new_blockstack_client_session_opts is not None: blockstack_client_session_opts = new_blockstack_client_session_opts return blockstack_client_session
def blockstack_app_session( blockchain_id, app_privkey, app_domain, config_path ): """ Make a session for the given application Returns {'error': ...} on error """ conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] api_port = int(conf['api_endpoint_port']) req = { 'version': 1, 'blockchain_id': blockchain_id, 'app_domain': app_domain, 'app_public_keys': [{'public_key': virtualchain.lib.ecdsalib.get_pubkey_hex(app_privkey), 'device_id': '0'}], 'methods': ['store_write'], 'app_private_key': app_privkey, 'device_id': '0', } signer = jsontokens.TokenSigner() token = signer.sign( req, app_privkey ) url = 'http://localhost:{}/v1/auth?authRequest={}'.format(api_port, token) resp = requests.get( url, headers={'Authorization': 'bearer {}'.format(api_pass), 'Origin': 'http://localhost:8888'} ) if resp.status_code != 200: print "GET {} status code {}".format(url, resp.status_code) return {'error': 'Failed to get session'} payload = resp.json() ses = payload['token'] return {'ses': ses}
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data empty_key = ECPrivateKey().to_hex() wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[1].privkey, wallets[2].privkey, wallets[0].privkey) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # let's do a withdraw of all res = testlib.blockstack_REST_call('POST', '/v1/wallet/balance', None, api_pass=api_pass, data= { 'address' : virtualchain.get_privkey_address(empty_key), }) if 'error' in res['response']: res['test'] = 'Failed to perform withdraw' print json.dumps(res) error = True return False for i in xrange (0, 1): testlib.next_block( **kw ) print 'Waiting for the withdraw to go through' res = testlib.blockstack_REST_call('GET', '/v1/wallet/balance/0', None, api_pass=api_pass) if 'error' in res['response']: res['test'] = 'Failed to get wallet balance' print json.dumps(res) error = True return False res = testlib.blockstack_REST_call('GET', '/v1/wallet/balance/0', None, api_pass=api_pass) if 'error' in res['response']: res['test'] = 'Failed to get wallet balance' print json.dumps(res) error = True return False
def get_config_dir(config_dir=None): """ Get the default configuration directory. """ if config_dir is None: config = get_config() config_dir = config['dir'] return config_dir
def get_config_dir( config_dir=None ): """ Get the default configuration directory. """ if config_dir is None: config = get_config() config_dir = config['dir'] return config_dir
def blockstack_client_queue_state(): """ Get queue information from the client backend """ config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) assert config_path is not None conf = blockstack_client.get_config(config_path) queue_info = blockstack_client.backend.queue.get_queue_state( path=conf['queue_path']) return queue_info
def check(state_engine): global error global names, owner_wallets, payment_wallets, recipients config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG") assert config_path config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] if error: print "Key operation failed." return False # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: print "namespace not ready" 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, recipient in zip(names, recipients): res = testlib.blockstack_REST_call("GET", "/v1/names/{}".format(name), None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name {}'.format(name) print json.dumps(res) return False if 'address' not in res['response']: print res return False cur_owner_address = res['response']['address'] if cur_owner_address != recipient: print "After transfer, unexpected owner. Expected {}, Actual {}".format( recipient, cur_owner_address) return False return True
def scenario( wallets, **kw ): # save the wallet wallet = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey ) if 'error' in wallet: print 'failed to set wallet: {}'.format(wallet) return False config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] if not check_wallet(wallets[2].privkey, wallets[3].privkey, wallets[4].privkey): return False res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/owner', None, api_pass=api_pass, data=wallets[0].privkey) if 'error' in res: print 'failed to set owner key' print res return False if not check_wallet(wallets[2].privkey, wallets[0].privkey, wallets[4].privkey): return False res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/payment', None, api_pass=api_pass, data=wallets[1].privkey) if 'error' in res: print 'failed to set payment key' print res return False if not check_wallet(wallets[1].privkey, wallets[0].privkey, wallets[4].privkey): return False res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/data', None, api_pass=api_pass, data=wallets[2].privkey) if 'error' in res: print 'failed to set payment key' print res return False if not check_wallet(wallets[1].privkey, wallets[0].privkey, wallets[2].privkey): return False
def make_proxy(): """ Create a blockstack client API proxy """ global utxo_opts client_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) assert client_path is not None client_config = blockstack_client.get_config(client_path) proxy = blockstack_client.session(conf=client_config) proxy.config_path = client_path # add in some UTXO goodness proxy.get_unspents = get_unspents proxy.broadcast_transaction = broadcast_transaction return proxy
def get_zonefile_from_atlas(blockchain_id, config_path, name_record=None): """ Get the zone file from the atlas network Return the raw zone file on success Raise on eror """ import blockstack_client import blockstack_client.proxy as proxy conf = blockstack_client.get_config(config_path) if not conf: raise Exception( "Failed to load config file from {}".format(config_path)) if 'server' not in conf or 'port' not in conf: raise Exception("Config file is missing 'server' and/or 'port") if name_record is not None: name_record = proxy.get_name_blockchain_record(blockchain_id) if 'error' in name_record: raise Exception( "Failed to load name record for {}".format(blockchain_id)) name_zonefile_hash = name_record['value_hash'] atlas_host = conf['server'] atlas_port = conf['port'] hostport = '{}:{}'.format(atlas_host, atlas_port) zonefile_txt = None expected_zonefile_hash = str(name_zonefile_hash) # load from atlas res = proxy.get_zonefiles(hostport, [expected_zonefile_hash]) if 'error' in res: raise Exception("Failed to load {} from Atlas network: {}".format( expected_zonefile_hash, res['error'])) zonefile_txt = res['zonefiles'][expected_zonefile_hash] return zonefile_txt
def __init__(self): global utxo_opts client_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) assert client_path is not None client_config = blockstack_client.get_config(client_path) self.client = blockstack_client.BlockstackRPCClient( client_config['server'], client_config['port']) self.config_path = client_path self.conf = { "start_block": blockstack.FIRST_BLOCK_MAINNET, "initial_utxos": utxo_opts, "storage_drivers": client_config['storage_drivers'], "metadata": client_config['metadata'], "path": client_path } self.spv_headers_path = utxo_opts['spv_headers_path'] if not os.path.exists(self.conf['metadata']): os.makedirs(self.conf['metadata'], 0700)
def get_zonefile_from_atlas(blockchain_id, config_path, name_record=None): """ Get the zone file from the atlas network Return the raw zone file on success Raise on eror """ import blockstack_client import blockstack_client.proxy as proxy conf = blockstack_client.get_config(config_path) if not conf: raise Exception("Failed to load config file from {}".format(config_path)) if 'server' not in conf or 'port' not in conf: raise Exception("Config file is missing 'server' and/or 'port") if name_record is not None: name_record = proxy.get_name_blockchain_record(blockchain_id) if 'error' in name_record: raise Exception("Failed to load name record for {}".format(blockchain_id)) name_zonefile_hash = name_record['value_hash'] atlas_host = conf['server'] atlas_port = conf['port'] hostport = '{}:{}'.format( atlas_host, atlas_port ) zonefile_txt = None expected_zonefile_hash = str(name_zonefile_hash) # load from atlas res = proxy.get_zonefiles( hostport, [expected_zonefile_hash] ) if 'error' in res: raise Exception("Failed to load {} from Atlas network: {}".format(expected_zonefile_hash, res['error'])) zonefile_txt = res['zonefiles'][expected_zonefile_hash] return zonefile_txt
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) # let's set the key to skip the transfer. config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/owner', None, api_pass=api_pass, data=new_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set owner key' print res return False # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls('bar.test', use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile('bar.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file( zonefile, origin='bar.test', ttl=3600 ) # leaving the call format of this one the same to make sure that our registrar correctly # detects that the requested TRANSFER is superfluous # register the name bar.test res = testlib.blockstack_REST_call( 'POST', '/v1/names', None, api_pass=api_pass, data={ 'name': 'bar.test', 'zonefile': zonefile_txt, 'owner_address': new_addr }) if 'error' in res: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False print res tx_hash = res['response']['transaction_hash'] # wait for preorder to get confirmed... for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(None, 'bar.test', 'preorder', tx_hash, api_pass = api_pass ) if not res: return False # wait for the preorder to get confirmed for i in xrange(0, 4): testlib.next_block( **kw ) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(None, 'bar.test', 'register', None, api_pass = api_pass ) if not res: return False for i in xrange(0, 4): testlib.next_block( **kw ) print 'Wait for update to be submitted' time.sleep(10) # wait for update to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(None, 'bar.test', 'update', None, api_pass = api_pass ) if not res: print res print "update error in first update" return False for i in xrange(0, 4): testlib.next_block( **kw ) print 'Wait for transfer to be submitted' time.sleep(10) # wait for transfer to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(None, 'bar.test', 'transfer', None, api_pass = api_pass ) if res: print "Wrongly issued a TRANSFER" return False res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False zonefile_hash = res['response']['zonefile_hash'] # should still be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False # do we have the history for the name? res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history", None, api_pass=api_pass ) if 'error' in res or res['http_status'] != 200: res['test'] = "Failed to get name history for foo.test" print json.dumps(res) return False # valid history? hist = res['response'] if len(hist.keys()) != 3: res['test'] = 'Failed to get update history' res['history'] = hist print json.dumps(res, indent=4, sort_keys=True) return False # get the zonefile res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), None, api_pass=api_pass ) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name zonefile' print json.dumps(res) return False # same zonefile we put? if res['response']['zonefile'] != zonefile_txt: res['test'] = 'mismatched zonefile, expected\n{}\n'.format(zonefile_txt) print json.dumps(res) return False # okay, now let's try to do a transfer. # FIRST, I want to change the key to a key that # doesn't own the name and a payment key that has no money res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/owner', None, api_pass=api_pass, data=insanity_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set owner key' print res return False res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/payment', None, api_pass=api_pass, data=insanity_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set owner key' print res return False payment_key = wallets[1].privkey # let's do this with the bad key res = testlib.blockstack_REST_call( 'PUT', '/v1/names/bar.test/owner', None, api_pass=api_pass, data={ 'owner': destination_owner, 'payment_key' : payment_key }) if 'error' in res or res['http_status'] != 202: res['test'] = '(Correctly) failed to transfer user' print json.dumps(res) # let's do this with the good one! res = testlib.blockstack_REST_call( 'PUT', '/v1/names/bar.test/owner', None, api_pass=api_pass, data={ 'owner': destination_owner, 'owner_key' : new_key, 'payment_key' : payment_key }) if 'error' in res or res['http_status'] != 202: res['test'] = '(Wrongly) failed to transfer user' print json.dumps(res) error = True return False else: print "Submitted transfer!" print res print 'Wait for transfer to be submitted' time.sleep(10) # wait to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(None, 'bar.test', 'transfer', None, api_pass = api_pass ) if not res: print "transfer error" print res return False for i in xrange(0, 4): testlib.next_block( **kw ) # wait for zonefile to propagate time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False cur_owner_address = res['response']['address'] if cur_owner_address != destination_owner: print "After transfer, unexpected owner. Expected {}, Actual {}".format( destination_owner, cur_owner_address) return False
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data empty_key = ECPrivateKey().to_hex() wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", empty_key, empty_key, empty_key) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy(test_proxy) 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) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] payment_key = wallets[1].privkey # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls( 'bar.test', use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile( 'bar.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file(zonefile, origin='bar.test', ttl=3600) no_key_postage = {'name': 'bar.test', 'zonefile': zonefile_txt} key_postage = dict(no_key_postage) key_postage['payment_key'] = payment_key key_postage['owner_key'] = new_key res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=no_key_postage) if 'error' not in res['response']: print "Successfully registered user with should-have-been-bad keys" print res return False # let's do a small withdraw res = testlib.blockstack_REST_call( 'POST', '/v1/wallet/balance', None, api_pass=api_pass, data={ 'address': virtualchain.get_privkey_address(empty_key), 'amount': int(1e4), 'payment_key': payment_key }) if 'error' in res['response']: res['test'] = 'Failed to perform withdraw' print json.dumps(res) error = True return False for i in xrange(0, 1): testlib.next_block(**kw) print 'Waiting for the withdraw to go through' res = testlib.blockstack_REST_call('GET', '/v1/wallet/balance/0', None, api_pass=api_pass) if 'error' in res['response']: res['test'] = 'Failed to get wallet balance' print json.dumps(res) error = True return False if int(res['response']['balance']['satoshis']) <= 0: res['test'] = 'Wallet balance did not increment!' print json.dumps(res) error = True return False res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=key_postage) if 'error' in res['response']: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False print "Registering bar.test" for i in xrange(0, 6): testlib.next_block(**kw) if not res: return False # wait for the preorder to get confirmed for i in xrange(0, 6): testlib.next_block(**kw) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.verify_in_queue(None, 'bar.test', 'register', None, api_pass=api_pass) if not res: return False for i in xrange(0, 6): testlib.next_block(**kw) print 'Wait for update to be submitted' time.sleep(10) # wait for update to get confirmed for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.verify_in_queue(None, 'bar.test', 'update', None, api_pass=api_pass) if not res: print res print "update error in first update" return False for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False zonefile_hash = res['response']['zonefile_hash'] # should still be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False # do we have the history for the name? res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = "Failed to get name history for foo.test" print json.dumps(res) return False # valid history? hist = res['response'] if len(hist.keys()) != 3: res['test'] = 'Failed to get update history' res['history'] = hist print json.dumps(res, indent=4, sort_keys=True) return False # get the zonefile res = testlib.blockstack_REST_call( "GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name zonefile' print json.dumps(res) return False # same zonefile we put? if res['response']['zonefile'] != zonefile_txt: res['test'] = 'mismatched zonefile, expected\n{}\n'.format( zonefile_txt) print json.dumps(res) return False # okay, now let's try to do an update. # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls( 'bar.test', use_only=['http', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile( 'bar.test', wallets[3].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file(zonefile, origin='bar.test', ttl=3600) # let's do this update. res = testlib.blockstack_REST_call('PUT', '/v1/names/bar.test/zonefile', None, api_pass=api_pass, data={ 'zonefile': zonefile_txt, 'owner_key': new_key, 'payment_key': payment_key }) if 'error' in res or res['http_status'] != 202: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False else: print "Submitted update!" print res print 'Wait for update to be submitted' time.sleep(10) # wait for update to get confirmed for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.verify_in_queue(None, 'bar.test', 'update', None, api_pass=api_pass) if not res: print "update error in second update" print res return False for i in xrange(0, 6): testlib.next_block(**kw) # wait for zonefile to propagate time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False zonefile_hash = res['response']['zonefile_hash'] # get the zonefile res = testlib.blockstack_REST_call( "GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name zonefile' print json.dumps(res) return False # same zonefile we put? if res['response']['zonefile'] != zonefile_txt: res['test'] = 'mismatched zonefile, expected\n{}\n'.format( zonefile_txt) print json.dumps(res) return False
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy(test_proxy) 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) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # migrate profiles res = testlib.migrate_profile("foo.test", proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] config_dir = os.path.dirname(config_path) # make sure we can do REST calls res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # make sure we can do REST calls with different app names and user names res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # register the name bar.test res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data={'name': 'bar.test'}) if 'error' in res: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False # wait for update to get confirmed for i in xrange(0, 48): if i % 12 == 0: print "waiting for RPC daemon to catch up" time.sleep(10) testlib.next_block(**kw) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res: res['test'] = 'Failed to query name' print json.dumps(res) error = True return False if res['http_status'] != 200: res['test'] = 'HTTP status {}, response = {}'.format( res['http_status'], res['response']) print json.dumps(res) error = True return False # should now be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data, wallet_balance wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[0].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr, wallet=wallets[3] ) testlib.next_block( **kw ) testlib.blockstack_client_set_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[0].privkey ) # migrate profiles res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # make sure we can do REST calls res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass ) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # make sure we can do REST calls with different app names and user names res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass ) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # what's the balance? res = testlib.blockstack_REST_call('GET', '/v1/wallet/balance', None, api_pass=api_pass ) if res['http_status'] != 200: res['test'] = 'failed to query wallet' print json.dumps(res) return False wallet_balance = res['response']['balance']['satoshis'] balance_before = testlib.get_balance(wallets[3].addr) # can we move the funds? res = testlib.blockstack_REST_call('POST', '/v1/wallet/balance', None, api_pass=api_pass, data={'address': wallets[3].addr} ) if res['http_status'] != 200: res['test'] = 'failed to transfer funds' print json.dumps(res) return False if not res['response'].has_key('transaction_hash'): res['test'] = 'missing tx hash' print json.dumps(res) return False # confirm it for i in xrange(0, 10): testlib.next_block(**kw) new_balance = testlib.get_balance(wallets[5].addr) balance_after = testlib.get_balance(wallets[3].addr) if new_balance != 0: print 'new balance of {} is {}'.format(wallets[5].addr, new_balance) return False if abs(balance_before + wallet_balance - balance_after) > 10000: print "{} + {} !~= {}".format(balance_before, wallet_balance, balance_after) return False
def delete_immutable_handler( key, txid, sig_key_txid, **kw ): return True def delete_mutable_handler( data_id, signature, **kw ): return True def get_classes(): return ['read_public', 'write_private'] if __name__ == "__main__": config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) assert config_path is not None, "You must set BLOCKSTACK_CLIENT_CONFIG" import blockstack_client config = blockstack_client.get_config(config_path) assert config is not None print json.dumps(config, indent=4, sort_keys=True) storage_init(config) assert len(sys.argv) > 1, "You must specify one or more names" for name in sys.argv[1:]: zonefile = get_data(name, zonefile=True) assert zonefile is not None and 'error' not in zonefile, "Bad zonefile: %s" % zonefile profile = get_data( name, zonefile=False ) assert profile is not None and 'error' not in profile, "Bad profile: %s" % profile print "zonefile:\n%s" % zonefile print "profile:\n%s" % json.dumps(profile, indent=4, sort_keys=True) print ""
def main(conf, function, args): """ Fetch and serve the application """ global appdir global client_port wallet_keys = None client_config_path = os.path.join(os.path.dirname(conf['path']), blockstack_client.CONFIG_FILENAME) if function in ["run", "publish", "setup"]: # need wallet wallet = blockstack_client.get_wallet(config_path=client_config_path) if wallet is None or 'error' in wallet: print >> sys.stderr, "Failed to get wallet" sys.exit(1) wallet_keys = wallet if function == "run": # run the app try: blockchain_id = args[0] appname = args[1] except: print >> sys.stderr, "Usage: %s-%s [opts] blockchain_id appname [tag [appdir]]" % ( sys.argv[0], function) sys.exit(1) # optional arguments tag = None appdir = None try: tag = int(args[2]) appdir = args[3] except: pass # load the app res = app_load(conf, blockchain_id, appname, wallet_keys=wallet_keys, tag=tag, appdir=appdir) if 'error' in res: print >> sys.stderr, "Failed to load app: %s" % res['error'] sys.exit(1) client_conf = blockstack_client.get_config(client_config_path) client_port = client_conf.get('api_endpoint_port', None) if client_port is None: print >> sys.stderr, "Could not determine client RPC port" sys.exit(1) if appdir is None: appdir = res['root'] httpd = SocketServer.TCPServer(("localhost", conf['port']), AppRequestHandler) httpd.serve_forever() return {'status': True} elif function == "publish": # publish an app try: appname = args[0] appdir = args[1] except: print >> sys.stderr, "Usage: %s-%s [opts] appname appdir [tag [key_passphrase]]" % ( sys.argv[0], function) sys.exit(1) # optional args tag = None key_passphrase = None try: tag = int(args[2]) key_passphrase = args[3] except: pass # TODO: mutable vs immutable res = app_publish(conf, appname, appdir, wallet_keys=wallet_keys, version=tag, key_passphrase=key_passphrase) if 'error' in res: print >> sys.stderr, "Failed to publish app: %s" % res['error'] sys.exit(1) return res elif function == 'setup': # set up app-publishing client_config_path = os.path.join(os.path.dirname(conf['path']), blockstack_client.CONFIG_FILENAME) res = blockstack_file.file_key_regenerate( conf['blockchain_id'], conf['hostname'], config_path=client_config_path, wallet_keys=wallet_keys) if 'error' in res: print >> sys.stderr, "Failed to publish app: %s" % res['error'] sys.exit(1) return res else: print >> sys.stderr, "Unrecognized directive '%s'" % function sys.exit(1)
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy(test_proxy) 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) testlib.next_block(**kw) testlib.blockstack_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # migrate profiles res = testlib.migrate_profile("foo.test", proxy=test_proxy, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # make sure we can do REST calls res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # make sure we can do REST calls with different app names and user names res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # can we even get to the wallet? res = testlib.blockstack_REST_call('POST', '/v1/wallet/balance', None, api_pass=api_pass, data={ 'address': wallets[4].addr, 'amount': 100000 }) if res['http_status'] != 200: res['test'] = 'failed to transfer funds' # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls( 'foo.test', use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile( 'foo.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file(zonefile, origin='foo.test', ttl=3600) # register the name bar.test, with min 3 confirmations on its UTXOs data = { 'name': 'bar.test', 'zonefile': zonefile_txt, 'owner_address': wallets[4].addr, 'min_confs': 3 } # should fail res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=data) if res['http_status'] == 200: res['test'] = 'succeeded in sending bar.test' print json.dumps(res) error = True return False # wait for confirmations for i in xrange(0, 3): testlib.next_block(**kw) # should succeed res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=data) if 'error' in res or 'error' in res['response']: res['test'] = 'failed to send bar.test' print json.dumps(res) error = True return False # wait for update to get confirmed for i in xrange(0, 48): if i % 12 == 0: print "waiting for RPC daemon to catch up" time.sleep(10) testlib.next_block(**kw) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res: res['test'] = 'Failed to query name' print json.dumps(res) error = True return False if res['http_status'] != 200: res['test'] = 'HTTP status {}, response = {}'.format( res['http_status'], res['response']) print json.dumps(res) error = True return False # should now be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # migrate profiles res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) # make a session datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.blockstack_cli_app_signin("foo.test", datastore_pk, 'register.app', ['names', 'register', 'prices', 'zonefiles', 'blockchain', 'node_read', 'wallet_write']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # for funsies, get the price of .test res = testlib.blockstack_REST_call('GET', '/v1/prices/namespaces/test', ses) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get price of .test' print json.dumps(res) return False test_price = res['response']['satoshis'] print '\n\n.test costed {} satoshis\n\n'.format(test_price) # get the price for bar.test res = testlib.blockstack_REST_call('GET', '/v1/prices/names/bar.test', ses) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get price of bar.test' print json.dumps(res) return False bar_price = res['response']['total_estimated_cost']['satoshis'] print "\n\nbar.test will cost {} satoshis\n\n".format(bar_price) # let's set the key to skip the transfer. config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/owner', None, api_pass=api_pass, data=new_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set owner key' print res return False # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls('bar.test', use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile('bar.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file( zonefile, origin='bar.test', ttl=3600 ) # leaving the call format of this one the same to make sure that our registrar correctly # detects that the requested TRANSFER is superfluous # register the name bar.test res = testlib.blockstack_REST_call('POST', '/v1/names', ses, data={'name': 'bar.test', 'zonefile': zonefile_txt, 'owner_address': new_addr }) if 'error' in res: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False print res tx_hash = res['response']['transaction_hash'] # wait for preorder to get confirmed... for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'preorder', tx_hash ) if not res: return False # wait for the preorder to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'register', None ) if not res: return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for update to be submitted' time.sleep(10) # wait for update to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'update', None ) if not res: return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for transfer to be submitted' time.sleep(10) # wait for transfer to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'transfer', None ) if res: print "Wrongly issued a TRANSFER" return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for transfer to be confirmed' time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", ses) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False zonefile_hash = res['response']['zonefile_hash'] # should still be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False # do we have the history for the name? res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history", ses ) if 'error' in res or res['http_status'] != 200: res['test'] = "Failed to get name history for foo.test" print json.dumps(res) return False # valid history? hist = res['response'] if len(hist.keys()) != 3: res['test'] = 'Failed to get update history' res['history'] = hist print json.dumps(res, indent=4, sort_keys=True) return False # get the zonefile res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), ses ) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name zonefile' print json.dumps(res) return False # same zonefile we put? if res['response']['zonefile'] != zonefile_txt: res['test'] = 'mismatched zonefile, expected\n{}\n'.format(zonefile_txt) print json.dumps(res) return False ### Now, we'll do it again, but this time, we're going to CHANGE THE KEY in the middle of registrations. ### to test the different paths, I'll start 3 registrations: # 1 has submitted preorder # 1 has submitted register # 1 has submitted update ### And then I'll issue a change-key # make zonefile for recipients zonefiles = [] for i in [1,2,3]: name = "tricky{}.test".format(i) driver_urls = blockstack_client.storage.make_mutable_data_urls(name, use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile(name, wallets[4].pubkey_hex, urls=driver_urls) zonefiles.append(blockstack_zones.make_zone_file( zonefile, origin=name, ttl=3600 )) # leaving the call format of this one the same to make sure that our registrar correctly # detects that the requested TRANSFER is superfluous res = testlib.blockstack_REST_call( 'POST', '/v1/names', ses, data={'name':'tricky1.test', 'zonefile':zonefiles[0], 'owner_address':new_addr}) if 'error' in res: res['test'] = 'Failed to register tricky1.test' print json.dumps(res) error = True return False tx_hash = res['response']['transaction_hash'] # wait for preorder to get confirmed... for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.blockstack_REST_call( 'POST', '/v1/names', ses, data={'name':'tricky2.test', 'zonefile':zonefiles[1], 'owner_address':new_addr}) if 'error' in res: res['test'] = 'Failed to register tricky2.test' print json.dumps(res) error = True return False # wait for the preorder to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.blockstack_REST_call( 'POST', '/v1/names', ses, data={'name':'tricky3.test', 'zonefile':zonefiles[2], 'owner_address':new_addr}) if 'error' in res: res['test'] = 'Failed to register tricky3.test' print json.dumps(res) error = True return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for update to be submitted' time.sleep(10) for i in xrange(0, 1): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'tricky1.test', 'update', None) res = testlib.verify_in_queue(ses, 'tricky2.test', 'register', None) res = testlib.verify_in_queue(ses, 'tricky3.test', 'preorder', None) # let's go crazy. res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/owner', None, api_pass=api_pass, data=insanity_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set owner key' print res return False # wait for preorder to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) # wake up registrar, submit register time.sleep(10) for i in xrange(0, 12): testlib.next_block( **kw ) # wake up registrar, submit update time.sleep(10) for i in xrange(0, 12): testlib.next_block( **kw ) # wake up registrar, propogate zonefile time.sleep(10)
def scenario(wallets, **kw): testlib.blockstack_namespace_preorder("id", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.blockstack_namespace_reveal( "id", 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("id", wallets[1].privkey) testlib.next_block(**kw) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] wallet = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey) resp = testlib.blockstack_cli_register("foo.id", "0123456789abcdef") if 'error' in resp: print >> sys.stderr, json.dumps(resp, indent=4, sort_keys=True) return False # wait for the preorder to get confirmed for i in xrange(0, 12): testlib.next_block(**kw) # wait for the poller to pick it up print >> sys.stderr, "Waiting 10 seconds for the backend to submit the register" time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 12): testlib.next_block(**kw) print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge registration" time.sleep(10) # wait for update to get confirmed for i in xrange(0, 12): testlib.next_block(**kw) print >> sys.stderr, "Waiting 10 seconds for the backend to acknowledge update" time.sleep(10) test_data = [{ 'hash': '34fdcde8b75440c5cb82480a14b4f3d731a67dc4', 'string': '$ORIGIN aaron.id\n$TTL 3600\n_http._tcp URI 10 1 "https://gaia.blockstack.org/hub/34bNQUVgyhSrA8XpM4HkerHUUdNmLpiyj7/0/profile.json"', 'decoded': None, 'b64': False }, { 'hash': 'd4fbae5d1f66f1ae0431e35bcd5a98782adc29ba', 'decoded': '$ORIGIN baron.id\n$TTL 3600\n_http._tcp URI 10 1 "https://gaia.blockstack.org/hub/34bNQUVgyhSrA8XpM4HkerHUUdNmLpiyj7/0/profile.json"', 'string': 'JE9SSUdJTiBiYXJvbi5pZAokVFRMIDM2MDAKX2h0dHAuX3RjcCBVUkkgMTAgMSAiaHR0cHM6Ly9nYWlhLmJsb2Nrc3RhY2sub3JnL2h1Yi8zNGJOUVVWZ3loU3JBOFhwTTRIa2VySFVVZE5tTHBpeWo3LzAvcHJvZmlsZS5qc29uIg==', 'b64': True }] for datum in test_data: post_data = {} if datum['b64']: key = 'zonefile_b64' else: key = 'zonefile' post_data[key] = datum['string'] zfhash = datum['hash'] res = testlib.blockstack_REST_call("PUT", "/v1/names/foo.id/zonefile", None, api_pass=api_pass, data={'zonefile_hash': zfhash}) if 'error' in res or res['http_status'] != 202: res['test'] = 'failed to update zonefile hash' print json.dumps(res) return False print >> sys.stderr, "Waiting 10 seconds for the backend to submit the register" time.sleep(10) # wait for update to get confirmed for i in xrange(0, 10): testlib.next_block(**kw) print 'Wait for second update to be confirmed' time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/foo.id", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name foo.id' print json.dumps(res) return False # update set? if res['response']['zonefile_hash'] != zfhash: res['test'] = 'failed to set zonefile hash' print json.dumps(res) return False res = testlib.blockstack_REST_call("POST", "/v1/zonefile/", None, api_pass=api_pass, data=post_data) if 'error' in res or res['http_status'] != 200: res['test'] = 'failed to announce zonefile' print json.dumps(res) return False print 'Broadcasted zonefile' time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/foo.id", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name foo.id' print json.dumps(res) return False if res['response']['zonefile'] != datum['string'] and \ res['response']['zonefile'] != datum['decoded']: res['test'] = 'failed to set zonefile string' print json.dumps(res) return False
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data, wallet_balance wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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[3].privkey, wallets[5].addr ) testlib.next_block( **kw ) register_resp = testlib.blockstack_name_register( "foo.test", wallets[3].privkey, wallets[5].addr ) testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # get utxos for the payer payer_utxos = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=1'.format(wallets[3].addr), None, api_pass=api_pass) if 'error' in payer_utxos: payer_utxos['test'] = 'failed to get utxos' print json.dumps(payer_utxos) return False # have both the test wallet output and the one the NAME_REGISTRATION sent if len(payer_utxos['response']) != 1: payer_utxos['test'] = 'wrong utxos' print json.dumps(payer_utxos) return False # last transaction should be the register, and it should have been paid with the owner address (since that's how we sent it above) if payer_utxos['response'][0]['transaction_hash'] != register_resp['transaction_hash'] or payer_utxos['response'][0]['confirmations'] != 1: payer_utxos['test'] = 'invalid utxos (tx_hash, confirmations)' print json.dumps(payer_utxos) return False # get utxos for the owner wallet owner_utxos = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=1'.format(wallets[5].addr), None, api_pass=api_pass) if 'error' in owner_utxos: owner_utxos['test'] = 'failed to get utxos' print json.dumps(owner_utxos) return False # two utxos: one for the initial wallet fill-up from the test framework, and one from the registration if len(owner_utxos['response']) != 2: owner_utxos['test'] = 'wrong utxos' print json.dumps(owner_utxos) return False # last transaction should be the register found = False for utxo in owner_utxos['response']: if utxo['transaction_hash'] == register_resp['transaction_hash'] and utxo['confirmations'] == 1: found = True if not found: owner_utxos['test'] = 'invalid utxos (tx_hash, confirmations)' print json.dumps(owner_utxos) return False # verify that min_confirmations=2 hides these transactions res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=2'.format(wallets[5].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False if len(res['response']) > 1: res['test'] = 'got more UTXOs than we expected' print json.dumps(res) return False # count UTXOs in wallets[1] res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=0'.format(wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False initial_utxos = res['response'] if len(initial_utxos) == 0: res['test'] = 'test bug: no UTXOs for wallet' print json.dumps(res) return False # send money from one wallet to another fund_tx = testlib.send_funds_tx(wallets[0].privkey, 10**8, wallets[1].addr) res = testlib.blockstack_REST_call('POST', '/v1/blockchains/bitcoin/txs', None, data={'tx': fund_tx}, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to send {}'.format(fund_tx) print json.dumps(res) return False if not res['response'].has_key('transaction_hash'): res['test'] = 'response is missing transaction hash' print json.dumps(res) return False # verify that it's in the UTXO set with min_confirmations=0 res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=0'.format(wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False if len(res['response']) != len(initial_utxos) + 1: res['test'] = 'missing UTXO' print json.dumps(res) return False current_utxos = res['response'] # verify that with min_confirmations=1, we have what we started with res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=1'.format(wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False if res['response'] != initial_utxos: res['test'] = 'initial utxos do not match current utxos' print json.dumps(res) print json.dumps(initial_utxos) return False # confirm everything for i in xrange(0, 10): testlib.next_block(**kw) # verify that we have what we started with res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/{}/unspent'.format(wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False current_utxos_no_confirmation = [dict([(k, v) for (k, v) in filter(lambda (x, y): x != 'confirmations', utxo.items())]) for utxo in current_utxos]
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) # make a session datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.blockstack_cli_app_signin("foo.test", datastore_pk, 'register.app', ['names', 'register', 'prices', 'zonefiles', 'blockchain', 'node_read', 'wallet_write']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # my own KEYS owner_key = new_key config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] payment_key = wallets[1].privkey payer = wallets[1].addr # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls('bar.test', use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile('bar.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file( zonefile, origin='bar.test', ttl=3600 ) postage = {'name': 'bar.test', 'zonefile': zonefile_txt, 'owner_address': new_addr, 'payment_key' : payment_key, 'owner_key' : owner_key} # leaving the call format of this one the same to make sure that our registrar correctly # detects that the requested TRANSFER is superfluous # register the name bar.test res = testlib.blockstack_REST_call('POST', '/v1/names', ses, data=postage) if 'error' in res: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False print res tx_hash = res['response']['transaction_hash'] # wait for preorder to get confirmed... for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'preorder', tx_hash ) if not res: return False # wait for the preorder to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'register', None ) if not res: return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for update to be submitted' time.sleep(10) # wait for update to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'update', None ) if not res: return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for transfer to be submitted' time.sleep(10) # wait for transfer to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'transfer', None ) if res: print "Wrongly issued a TRANSFER" return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for transfer to be confirmed' time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", ses) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False zonefile_hash = res['response']['zonefile_hash'] # should still be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False # do we have the history for the name? res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history", ses ) if 'error' in res or res['http_status'] != 200: res['test'] = "Failed to get name history for foo.test" print json.dumps(res) return False # valid history? hist = res['response'] if len(hist.keys()) != 3: res['test'] = 'Failed to get update history' res['history'] = hist print json.dumps(res, indent=4, sort_keys=True) return False # get the zonefile res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), ses ) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name zonefile' print json.dumps(res) return False # same zonefile we put? if res['response']['zonefile'] != zonefile_txt: res['test'] = 'mismatched zonefile, expected\n{}\n'.format(zonefile_txt) print json.dumps(res) return False ### Now, we'll do it again, but this time, we're going to CHANGE THE KEY in the middle of registrations. ### to test the different paths, I'll start 3 registrations: # 1 has submitted preorder # 1 has submitted register # 1 has submitted update ### And then I'll issue a change-key # make zonefile for recipients zonefiles = [] postages = [] for i in [1,2,3]: name = "tricky{}.test".format(i) driver_urls = blockstack_client.storage.make_mutable_data_urls(name, use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile(name, wallets[4].pubkey_hex, urls=driver_urls) zf_txt = blockstack_zones.make_zone_file( zonefile, origin=name, ttl=3600 ) zonefiles.append(zf_txt) postages.append( {'name': name, 'zonefile' : zf_txt, 'owner_address': new_addr, 'payment_key' : payment_key, 'owner_key' : owner_key}) res = testlib.blockstack_REST_call('POST', '/v1/names', ses, data=postages[0]) if 'error' in res: res['test'] = 'Failed to register tricky1.test' print json.dumps(res) error = True return False tx_hash = res['response']['transaction_hash'] # wait for preorder to get confirmed... for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.blockstack_REST_call('POST', '/v1/names', ses, data=postages[1]) if 'error' in res: res['test'] = 'Failed to register tricky2.test' print json.dumps(res) error = True return False # wait for the preorder to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.blockstack_REST_call('POST', '/v1/names', ses, data=postages[2]) if 'error' in res: res['test'] = 'Failed to register tricky3.test' print json.dumps(res) error = True return False for i in xrange(0, 6): testlib.next_block( **kw ) print 'Wait for update to be submitted' time.sleep(10) for i in xrange(0, 1): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'tricky1.test', 'update', None) res = testlib.verify_in_queue(ses, 'tricky2.test', 'register', None) res = testlib.verify_in_queue(ses, 'tricky3.test', 'preorder', None) # let's go crazy. res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/owner', None, api_pass=api_pass, data=insanity_key) res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/payment', None, api_pass=api_pass, data=insanity_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set owner key' print res return False # wait for preorder to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) # wake up registrar, submit register time.sleep(10) for i in xrange(0, 12): testlib.next_block( **kw ) # wake up registrar, submit update time.sleep(10) for i in xrange(0, 12): testlib.next_block( **kw ) # wake up registrar, propogate zonefile time.sleep(10)
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data, wallet_balance wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy(test_proxy) 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[3].privkey, wallets[5].addr) testlib.next_block(**kw) register_resp = testlib.blockstack_name_register("foo.test", wallets[3].privkey, wallets[5].addr) testlib.next_block(**kw) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # get utxos for the payer payer_utxos = testlib.blockstack_REST_call( 'GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=1'.format( wallets[3].addr), None, api_pass=api_pass) if 'error' in payer_utxos: payer_utxos['test'] = 'failed to get utxos' print json.dumps(payer_utxos) return False # have both the test wallet output and the one the NAME_REGISTRATION sent if len(payer_utxos['response']) != 1: payer_utxos['test'] = 'wrong utxos' print json.dumps(payer_utxos) return False # last transaction should be the register, and it should have been paid with the owner address (since that's how we sent it above) if payer_utxos['response'][0]['transaction_hash'] != register_resp[ 'transaction_hash'] or payer_utxos['response'][0][ 'confirmations'] != 1: payer_utxos['test'] = 'invalid utxos (tx_hash, confirmations)' print json.dumps(payer_utxos) return False # get utxos for the owner wallet owner_utxos = testlib.blockstack_REST_call( 'GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=1'.format( wallets[5].addr), None, api_pass=api_pass) if 'error' in owner_utxos: owner_utxos['test'] = 'failed to get utxos' print json.dumps(owner_utxos) return False # two utxos: one for the initial wallet fill-up from the test framework, and one from the registration if len(owner_utxos['response']) != 2: owner_utxos['test'] = 'wrong utxos' print json.dumps(owner_utxos) return False # last transaction should be the register found = False for utxo in owner_utxos['response']: if utxo['transaction_hash'] == register_resp[ 'transaction_hash'] and utxo['confirmations'] == 1: found = True if not found: owner_utxos['test'] = 'invalid utxos (tx_hash, confirmations)' print json.dumps(owner_utxos) return False # verify that min_confirmations=2 hides these transactions res = testlib.blockstack_REST_call( 'GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=2'.format( wallets[5].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False if len(res['response']) > 1: res['test'] = 'got more UTXOs than we expected' print json.dumps(res) return False # count UTXOs in wallets[1] res = testlib.blockstack_REST_call( 'GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=0'.format( wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False initial_utxos = res['response'] if len(initial_utxos) == 0: res['test'] = 'test bug: no UTXOs for wallet' print json.dumps(res) return False # send money from one wallet to another fund_tx = testlib.send_funds_tx(wallets[0].privkey, 10**8, wallets[1].addr) res = testlib.blockstack_REST_call('POST', '/v1/blockchains/bitcoin/txs', None, data={'tx': fund_tx}, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to send {}'.format(fund_tx) print json.dumps(res) return False if not res['response'].has_key('transaction_hash'): res['test'] = 'response is missing transaction hash' print json.dumps(res) return False # verify that it's in the UTXO set with min_confirmations=0 res = testlib.blockstack_REST_call( 'GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=0'.format( wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False if len(res['response']) != len(initial_utxos) + 1: res['test'] = 'missing UTXO' print json.dumps(res) return False current_utxos = res['response'] # verify that with min_confirmations=1, we have what we started with res = testlib.blockstack_REST_call( 'GET', '/v1/blockchains/bitcoin/{}/unspent?min_confirmations=1'.format( wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False if res['response'] != initial_utxos: res['test'] = 'initial utxos do not match current utxos' print json.dumps(res) print json.dumps(initial_utxos) return False # confirm everything for i in xrange(0, 10): testlib.next_block(**kw) # verify that we have what we started with res = testlib.blockstack_REST_call( 'GET', '/v1/blockchains/bitcoin/{}/unspent'.format(wallets[1].addr), None, api_pass=api_pass) if 'error' in res: res['test'] = 'failed to get utxos' print json.dumps(res) return False current_utxos_no_confirmation = [ dict([(k, v) for ( k, v) in filter(lambda (x, y): x != 'confirmations', utxo.items()) ]) for utxo in current_utxos ]
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # migrate profiles res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # make sure we can do REST calls res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass ) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # make sure we can do REST calls with different app names and user names res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass ) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # can we even get to the wallet? res = testlib.blockstack_REST_call('POST', '/v1/wallet/balance', None, api_pass=api_pass, data={'address': wallets[4].addr, 'amount': 100000} ) if res['http_status'] != 200: res['test'] = 'failed to transfer funds' # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls('foo.test', use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile('foo.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file( zonefile, origin='foo.test', ttl=3600 ) # register the name bar.test, with min 3 confirmations on its UTXOs data = { 'name': 'bar.test', 'zonefile': zonefile_txt, 'owner_address': wallets[4].addr, 'min_confs': 3 } # should fail res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=data) if res['http_status'] == 200: res['test'] = 'succeeded in sending bar.test' print json.dumps(res) error = True return False # wait for confirmations for i in xrange(0, 3): testlib.next_block( **kw ) # should succeed res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=data) if 'error' in res or 'error' in res['response']: res['test'] = 'failed to send bar.test' print json.dumps(res) error = True return False # wait for update to get confirmed for i in xrange(0, 48): if i % 12 == 0: print "waiting for RPC daemon to catch up" time.sleep(10) testlib.next_block( **kw ) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res: res['test'] = 'Failed to query name' print json.dumps(res) error = True return False if res['http_status'] != 200: res['test'] = 'HTTP status {}, response = {}'.format(res['http_status'], res['response']) print json.dumps(res) error = True return False # should now be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # migrate profiles res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) # make a session datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.blockstack_cli_app_signin("foo.test", datastore_pk, 'register.app', ['names', 'register', 'prices', 'zonefiles', 'blockchain', 'node_read', 'wallet_write']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # let's set the key to skip the transfer. config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] new_payment_key = { 'private_key' : wallets[1].privkey, 'persist_change' : True } res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/payment', None, api_pass=api_pass, data=new_payment_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set payment key' print res return False testlib.stop_api() testlib.start_api('0123456789abcdef') res = testlib.blockstack_REST_call('GET', '/v1/wallet/payment_address', None, api_pass = api_pass) if res['http_status'] != 200 or 'error' in res: res['test'] = 'Failed to get payment address' print res return False if res['response']['address'] != wallets[1].addr: res['test'] = 'Got wrong payer address, expected {}, got {}'.format( wallets[1].addr, res['response']['address']) print res return False res = testlib.blockstack_REST_call('PUT', '/v1/wallet/keys/owner', None, api_pass=api_pass, data=new_key) if res['http_status'] != 200 or 'error' in res: print 'failed to set owner key' print res return False # make zonefile for recipient driver_urls = blockstack_client.storage.make_mutable_data_urls('bar.test', use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile('bar.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file( zonefile, origin='bar.test', ttl=3600 ) # leaving the call format of this one the same to make sure that our registrar correctly # detects that the requested TRANSFER is superfluous # register the name bar.test res = testlib.blockstack_REST_call('POST', '/v1/names', ses, data={'name': 'bar.test', 'zonefile': zonefile_txt, 'owner_address': new_addr }) if 'error' in res: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False print res tx_hash = res['response']['transaction_hash'] # wait for preorder to get confirmed... for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'preorder', tx_hash ) if not res: return False # wait for the preorder to get confirmed for i in xrange(0, 4): testlib.next_block( **kw ) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'register', None ) if not res: return False for i in xrange(0, 4): testlib.next_block( **kw ) print 'Wait for update to be submitted' time.sleep(10) # wait for update to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'update', None ) if not res: return False for i in xrange(0, 4): testlib.next_block( **kw ) print 'Wait for transfer to be submitted' time.sleep(10) # wait for transfer to get confirmed for i in xrange(0, 6): testlib.next_block( **kw ) res = testlib.verify_in_queue(ses, 'bar.test', 'transfer', None ) if res: print res print "Wrongly issued a TRANSFER" return False for i in xrange(0, 4): testlib.next_block( **kw ) print 'Wait for transfer to be confirmed' time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", ses) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False zonefile_hash = res['response']['zonefile_hash'] # should still be registered if res['response']['status'] != 'registered': print "register not complete" print json.dumps(res) return False # do we have the history for the name? res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history", ses ) if 'error' in res or res['http_status'] != 200: res['test'] = "Failed to get name history for foo.test" print json.dumps(res) return False # valid history? hist = res['response'] if len(hist.keys()) != 3: res['test'] = 'Failed to get update history' res['history'] = hist print json.dumps(res, indent=4, sort_keys=True) return False # get the zonefile res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), ses ) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name zonefile' print json.dumps(res) return False # same zonefile we put? if res['response']['zonefile'] != zonefile_txt: res['test'] = 'mismatched zonefile, expected\n{}\n'.format(zonefile_txt) print json.dumps(res) return False
def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data, wallet_balance wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy( test_proxy ) 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 ) testlib.next_block( **kw ) testlib.blockstack_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # migrate profiles res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # make sure we can do REST calls res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass ) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # make sure we can do REST calls with different app names and user names res = testlib.blockstack_REST_call('GET', '/v1/blockchains/bitcoin/pending', None, api_pass=api_pass ) if 'error' in res: res['test'] = 'Failed to get queues' print json.dumps(res) return False # what's the balance? res = testlib.blockstack_REST_call('GET', '/v1/wallet/balance', None, api_pass=api_pass ) if res['http_status'] != 200: res['test'] = 'failed to query wallet' print json.dumps(res) return False wallet_balance = res['response']['balance']['satoshis'] balance_before = testlib.get_balance(wallets[8].addr) # can we move the funds? res = testlib.blockstack_REST_call('POST', '/v1/wallet/balance', None, api_pass=api_pass, data={'address': wallets[8].addr, 'amount': wallet_balance / 2, 'message': "hello world!"}) if res['http_status'] != 200: res['test'] = 'failed to transfer funds' print json.dumps(res) return False if not res['response'].has_key('transaction_hash'): res['test'] = 'missing tx hash' print json.dumps(res) return False print "\n\nTransaction: {}\n\n".format(res['response']['transaction_hash']) # confirm it for i in xrange(0, 12): testlib.next_block(**kw) new_balance = testlib.get_balance(wallets[5].addr) balance_after = testlib.get_balance(wallets[8].addr) print "wallet balance: {}".format(wallet_balance) print "new balance {}: {}".format(wallets[5].addr, new_balance) print "balance after {}: {}".format(wallets[8].addr, balance_after) print "balance before {}: {}".format(wallets[8].addr, balance_before) if new_balance > wallet_balance / 2: print 'new balance of {} is {}'.format(wallets[5].addr, new_balance) return False if abs(balance_after - balance_before) > abs(wallet_balance / 2) + 54500: print "{} - {} != {}".format(balance_after, balance_before, wallet_balance / 2) return False
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy(test_proxy) 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) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] # register the name bar.test. autogenerate the rest postage = { 'name': 'bar.test', 'owner_key': owner_key, 'payment_key': payment_key } res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=postage) if 'error' in res: res['test'] = 'Failed to register user' print json.dumps(res) error = True return False print res tx_hash = res['response']['transaction_hash'] # wait for preorder to get confirmed... for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.verify_in_queue(None, 'bar.test', 'preorder', tx_hash) if not res: return False # wait for the preorder to get confirmed for i in xrange(0, 6): testlib.next_block(**kw) # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.verify_in_queue(None, 'bar.test', 'register', None) if not res: return False for i in xrange(0, 6): testlib.next_block(**kw) print 'Wait for update to be submitted' time.sleep(10) # wait for update to get confirmed for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.verify_in_queue(None, 'bar.test', 'update', None) if not res: return False for i in xrange(0, 6): testlib.next_block(**kw) print 'Wait for update to be confirmed' time.sleep(10) res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False zonefile_hash = res['response']['zonefile_hash'] old_expire_block = res['response']['expire_block'] # renew it res = testlib.blockstack_REST_call('POST', '/v1/names', None, api_pass=api_pass, data=postage) if 'error' in res or res['http_status'] != 202: res['test'] = 'Failed to renew name' print json.dumps(res) return False # verify in renew queue for i in xrange(0, 6): testlib.next_block(**kw) res = testlib.verify_in_queue(None, 'bar.test', 'renew', None) if not res: return False for i in xrange(0, 6): testlib.next_block(**kw) # new expire block res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name bar.test' print json.dumps(res) return False new_expire_block = res['response']['expire_block'] # do we have the history for the name? res = testlib.blockstack_REST_call("GET", "/v1/names/bar.test/history", None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = "Failed to get name history for bar.test" print json.dumps(res) return False # valid history? hist = res['response'] if len(hist.keys()) != 4: res['test'] = 'Failed to get update history' res['history'] = hist print json.dumps(res, indent=4, sort_keys=True) return False # get the zonefile res = testlib.blockstack_REST_call( "GET", "/v1/names/bar.test/zonefile/{}".format(zonefile_hash), None, api_pass=api_pass) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to get name zonefile' print json.dumps(res) return False # verify pushed back if old_expire_block + 12 >= new_expire_block: # didn't go through print >> sys.stderr, "Renewal didn't work: %s --> %s" % ( old_expire_block, new_expire_block) return False
def scenario(wallets, **kw): global error global names, owner_wallets, payment_wallets, recipients wallet_keys = testlib.blockstack_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() blockstack_client.set_default_proxy(test_proxy) 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) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() processed_preorders = 0 while processed_preorders < len(owner_wallets): name, owner = names[processed_preorders], owner_wallets[ processed_preorders] payer_ix = processed_preorders % len(payment_wallets) payer = payment_wallets[payer_ix] testlib.blockstack_name_preorder(name, payer.privkey, owner.addr) processed_preorders += 1 if payer_ix == (len(payment_wallets) - 1): testlib.next_block(**kw) testlib.next_block(**kw) testlib.next_block(**kw) processed_registers = 0 while processed_registers < len(owner_wallets): name, owner = names[processed_registers], owner_wallets[ processed_registers] payer_ix = processed_registers % len(payment_wallets) payer = payment_wallets[payer_ix] testlib.blockstack_name_register(name, payer.privkey, owner.addr) processed_registers += 1 if payer_ix == (len(payment_wallets) - 1): testlib.next_block(**kw) testlib.next_block(**kw) # now let's go crazy with transfers config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) config_dir = os.path.dirname(config_path) conf = blockstack_client.get_config(config_path) assert conf api_pass = conf['api_password'] testlib.next_block(**kw) processed_transfers = 0 while processed_transfers < len(owner_wallets): name, owner_privkey, recipient = ( names[processed_transfers], owner_wallets[processed_transfers].privkey, recipients[processed_transfers]) payer_ix = processed_transfers % len(payment_wallets) payer = payment_wallets[payer_ix] driver_urls = blockstack_client.storage.make_mutable_data_urls( name, use_only=['dht', 'disk']) zonefile = blockstack_client.zonefile.make_empty_zonefile( name, None, urls=driver_urls) zonefile_txt = blockstack_zones.make_zone_file(zonefile, origin=name, ttl=3600) res = testlib.blockstack_REST_call('POST', '/v1/names/', None, api_pass=api_pass, data={ 'name': name, 'owner_address': recipient, 'owner_key': owner_privkey, 'payment_key': payer.privkey, 'zonefile': zonefile_txt, }) if 'error' in res or res['http_status'] != 202: res['test'] = '(Wrongly) failed to renew/transfer/update user' print json.dumps(res) error = True return False else: print "Submitted transfer!" processed_transfers += 1 if (payer_ix == (len(payment_wallets) - 1) or processed_transfers >= len(owner_wallets)): print 'Waiting to get more UTXOs and processing transfers' time.sleep(10) for i in range(11): testlib.next_block(**kw) return True