def scenario( wallets, **kw ): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data empty_key = ECPrivateKey().to_hex() wallet_keys = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[1].privkey, wallets[2].privkey, wallets[0].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # 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 = ysi_client.get_config(config_path) assert conf api_pass = conf['api_password'] # let's do a withdraw of all res = testlib.ysi_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.ysi_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.ysi_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 check(state_engine): global wallet_keys, datasets, zonefile_hash # 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 # not preordered preorder = state_engine.get_name_preorder( "foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr) if preorder is not None: print "still have preorder" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "name does not exist" return False # owned if name_rec['address'] != wallets[3].addr or name_rec[ 'sender'] != virtualchain.make_payment_script(wallets[3].addr): print "name has wrong owner" return False # have right hash if name_rec['value_hash'] != zonefile_hash: print "Invalid zonefile hash" return False # have right data test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) res = testlib.ysi_cli_lookup("foo.test") if 'error' in res: print 'error looking up profile: {}'.format(res) return False assert 'profile' in res assert 'zonefile' in res return True
def check(state_engine): global snv_block_id, last_consensus # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: return False ns = state_engine.get_namespace("test") if ns is None: return False if ns['namespace_id'] != 'test': return False # not preordered preorder = state_engine.get_name_preorder( "foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr) if preorder is not None: print "preorder exists" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "no such name" return False # owned by if name_rec['address'] != wallets[3].addr or name_rec[ 'sender'] != virtualchain.make_payment_script(wallets[3].addr): print "wrong owner" return False # revoked if not name_rec['revoked']: return False # snv lookup works test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) snv_rec = ysi_client.snv_lookup("foo.test", snv_block_id, last_consensus, proxy=test_proxy) if 'error' in snv_rec: print json.dumps(snv_rec, indent=4) return False print snv_rec return True
def check(state_engine): global wallet_keys, data_history_1, data_history_2, data_history_3 # 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 # not preordered preorder = state_engine.get_name_preorder( "foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr) if preorder is not None: print "still have preorder" return False # registered name_rec = state_engine.get_name("foo.test") if name_rec is None: print "name does not exist" return False # owned if name_rec['address'] != wallets[3].addr or name_rec[ 'sender'] != virtualchain.make_payment_script(wallets[3].addr): print "name has wrong owner" return False # have right data history test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) hist = [data_history_1, data_history_2, data_history_3] for i in xrange(0, len(hist)): test_hist = ysi_client.list_immutable_data_history( "foo.test", "hello_world_%s" % (i + 1)) if test_hist != hist[i]: print "hello_world_%s expected: %s" % (i + 1, ",".join(hist[i])) print "hello_world_%s got: %s" % (i + 1, ",".join(test_hist)) return False return True
def check( state_engine ): global last_consensus, snv_block_id # not revealed, but ready ns = state_engine.get_namespace_reveal( "test" ) if ns is not None: return False ns = state_engine.get_namespace( "test" ) if ns is None: return False if ns['namespace_id'] != 'test': return False # not preordered for i in xrange(0, len(wallets)): preorder = state_engine.get_name_preorder( "foo.test", virtualchain.make_payment_script(wallets[i].addr), wallets[(i+1)%5].addr ) if preorder is not None: print "preordered" return False # registered name_rec = state_engine.get_name( "foo.test" ) if name_rec is None: print "no name" return False # updated, and data preserved if name_rec['value_hash'] != "22" * 20: print "wrong value hash" return False # transferred if name_rec['address'] != wallets[4].addr or name_rec['sender'] != virtualchain.make_payment_script( wallets[4].addr ): print "wrong owner" return False # snv lookup works test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) spv_headers_path = test_proxy.spv_headers_path snv_rec = ysi_client.snv_lookup( "foo.test", snv_block_id, last_consensus, proxy=test_proxy ) if 'error' in snv_rec: print json.dumps(snv_rec, indent=4 ) return False print snv_rec return True
def check(state_engine): global update_hashes # 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 name = "foo.test" preorder = state_engine.get_name_preorder( name, virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr) if preorder is not None: print "still have preorder" return False # registered name_rec = state_engine.get_name(name) if name_rec is None: print "name does not exist" return False # owned if name_rec['address'] != wallets[4].addr or name_rec[ 'sender'] != virtualchain.make_payment_script(wallets[4].addr): print "name has wrong owner" return False test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) update_history = ysi_client.list_update_history(name) if update_history != update_hashes: print "update history: %s" % ",".join(update_history) print "update hashes: %s" % ",".join(update_hashes) return False return True
def check(state_engine): global snv_block_id, last_consensus # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: return False ns = state_engine.get_namespace("test") if ns is None: return False if ns['namespace_id'] != 'test': return False # not preordered preorder = state_engine.get_name_preorder( "foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr) if preorder is not None: return False # not registered name_rec = state_engine.get_name("foo.test") if name_rec is not None: print "Not expired:" print json.dumps(name_rec, indent=4) return False # snv lookup works test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) snv_rec = ysi_client.snv_lookup("foo.test", snv_block_id, last_consensus, proxy=test_proxy) if 'error' in snv_rec: print json.dumps(snv_rec, indent=4) print "Expected (%s, %s) from (%s, %s)" % (snv_block_id, snv_consensus, lastblock, lastconsensus) return False print snv_rec return True
def scenario(wallets, **kw): global wallet_keys, error, foo_output, bar_output, baz_output, config_paths, put_benchmark_data, get_benchmark_data, aws_key, aws_secret print "patch '%s'" % os.environ.get("BLOCKSTACK_CLIENT_CONFIG") with open(os.environ.get('BLOCKSTACK_CLIENT_CONFIG'), "a+") as f: f.write(s3_config) f.flush() testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.ysi_name_preorder("bar.test", wallets[5].privkey, wallets[6].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.ysi_name_register("bar.test", wallets[5].privkey, wallets[6].addr) testlib.next_block(**kw) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys['foo.test'] = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[8].privkey) wallet_keys['bar.test'] = ysi_client.make_wallet_keys( owner_privkey=wallets[6].privkey, data_privkey=wallets[7].privkey, payment_privkey=wallets[9].privkey) # migrate profiles for name in ['foo.test', 'bar.test']: res = testlib.migrate_profile(name, proxy=test_proxy, wallet_keys=wallet_keys[name]) if 'error' in res: res['test'] = 'Failed to initialize %s profile' % name print json.dumps(res, indent=4, sort_keys=True) error = True return testlib.next_block(**kw) # set up config file config_path = os.environ['BLOCKSTACK_FILE_CONFIG'] with open(config_path, "w") as f: f.write(TEST_CONFIG_FILE) config_paths = {} # set up config file and upload file for each principal for name in ['foo.test', 'bar.test']: config_dir = os.path.dirname(config_path) + "." + name os.makedirs(config_dir) name_config_path = os.path.join(config_dir, os.path.basename(config_path)) config_paths[name] = name_config_path # config path with open(config_paths[name], "w") as f: f.write(TEST_CONFIG_FILE) # upload paths for sz in file_sizes: upload_path = make_local_upload_path(config_path, name, sz) with open(upload_path, "w") as f: with open("/dev/urandom", "r") as r: # generate file file_data = r.read(sz) f.write(file_data) f.flush() foo_output = os.path.join(os.path.dirname(config_path), 'foo.test-out.txt') foo_fail_output = os.path.join(os.path.dirname(config_path), 'foo.test-out-fail.txt') bar_output = os.path.join(os.path.dirname(config_path), 'bar.test-out.txt') bar_fail_output = os.path.join(os.path.dirname(config_path), 'bar.test-out-fail.txt') # initialize file app res = ysi_file.file_key_regenerate("foo.test", "localhost", config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return res = ysi_file.file_key_regenerate("bar.test", "localhost", config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return # send a file from foo.test to bar.test # do so many times for sz in file_sizes: put_benchmark_data[sz] = [] for i in xrange(0, samples): upload_name = make_upload_name('foo.test', i, sz) local_path = make_local_upload_path(config_path, 'foo.test', sz) begin = time.time() res = ysi_file.file_put('foo.test', 'localhost', ['bar.test'], upload_name, local_path, config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) end = time.time() if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return put_benchmark_data[sz].append(end - begin) # get a file from foo.test, as bar.test # do so many times for sz in file_sizes: get_benchmark_data[sz] = [] for i in xrange(0, samples): upload_name = make_upload_name('foo.test', i, sz) src_local_path = make_local_upload_path(config_path, 'foo.test', sz) local_path = make_local_upload_path(config_path, 'bar.test', sz) begin = time.time() res = ysi_file.file_get('bar.test', 'localhost', 'foo.test', upload_name, local_path, config_path=config_paths['bar.test'], wallet_keys=wallet_keys['bar.test']) end = time.time() if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return rc = os.system("cmp \"%s\" \"%s\"" % (src_local_path, local_path)) if rc != 0: raise Exception("Not equal: \"%s\" and \"%s\"" % (src_local_path, local_path)) try: os.unlink(output_path) except: pass get_benchmark_data[sz].append(end - begin) # delete for sz in file_sizes: for i in xrange(0, samples): upload_name = make_upload_name('foo.test', i, sz) res = ysi_file.file_delete('foo.test', upload_name, config_path=config_paths['foo.test'], wallet_keys=wallet_keys['foo.test']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return
def scenario( wallets, **kw ): global put_result, wallet_keys, wallet_keys_2, legacy_profile, zonefile_hash, zonefile_hash_2 wallet_keys = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[8].privkey, wallets[3].privkey, None ) wallet_keys_2 = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[9].privkey, wallets[6].privkey, None ) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.ysi_name_preorder( "bar.test", wallets[5].privkey, wallets[6].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.ysi_name_register( "bar.test", wallets[5].privkey, wallets[6].addr ) testlib.next_block( **kw ) # set up legacy profile hash legacy_txt = json.dumps(legacy_profile,sort_keys=True) legacy_hash = virtualchain.lib.hashing.hex_hash160( legacy_txt ) result_1 = testlib.ysi_name_update( "foo.test", legacy_hash, wallets[3].privkey ) result_2 = testlib.ysi_name_update( "bar.test", legacy_hash, wallets[6].privkey ) testlib.next_block( **kw ) rc = ysi_client.storage.put_immutable_data( legacy_txt, result_1['transaction_hash'], data_hash=legacy_hash ) assert rc is not None rc = ysi_client.storage.put_immutable_data( legacy_txt, result_2['transaction_hash'], data_hash=legacy_hash ) assert rc is not None testlib.next_block( **kw ) # migrate profiles, but no zone file keys res = testlib.migrate_profile( "foo.test", proxy=test_proxy, wallet_keys=wallet_keys, zonefile_has_data_key=False ) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return zonefile_hash = res['zonefile_hash'] res = testlib.migrate_profile( "bar.test", proxy=test_proxy, wallet_keys=wallet_keys_2, zonefile_has_data_key=False ) if 'error' in res: res['test'] = 'Failed to initialize bar.test profile' print json.dumps(res, indent=4, sort_keys=True) error = True return zonefile_hash_2 = res['zonefile_hash'] # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API: {}'.format(res) return False # see that put_immutable works put_result = testlib.ysi_cli_put_immutable( 'foo.test', 'hello_world_immutable', json.dumps({'hello': 'world_immutable'}, sort_keys=True), password='******') if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True ) testlib.expect_atlas_zonefile(put_result['zonefile_hash']) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block( **kw ) print "waiting for confirmation" time.sleep(10) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys_2['payment_privkey'], wallet_keys_2['owner_privkey'], wallet_keys_2['data_privkey'] ) res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API: {}'.format(res) return False # put_mutable should fail on its own, since we have no privat ekey put_result = testlib.ysi_cli_put_mutable( "bar.test", "hello_world_mutable", json.dumps({'hello': 'world'}, sort_keys=True), password='******') if 'error' not in put_result: print json.dumps(put_result, indent=4, sort_keys=True) print "accidentally succeeded to put_mutable with no public key in zone file" return False # see that put_mutable works, if we give a private key put_result = testlib.ysi_cli_put_mutable( "bar.test", "hello_world_mutable", json.dumps({'hello': 'world'}, sort_keys=True), password='******', private_key=wallet_keys_2['data_privkey']) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True ) return False testlib.next_block( **kw )
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_client_set_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].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) # make a session datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.ysi_cli_app_signin(datastore_pk, 'register.app', [ 'names', 'register', 'prices', 'zonefiles', 'blockchain', 'node_read', 'store_admin', 'store_read', 'store_write' ]) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # make a datastore res = testlib.ysi_REST_call('POST', '/v1/stores', ses) if 'error' in res or res['http_status'] != 200: print 'failed to create datastore' print json.dumps(res, indent=4, sort_keys=True) return False # get the data store id res = testlib.ysi_REST_call('GET', '/v1/stores/register.app', ses) if 'error' in res or res['http_status'] != 200: print 'failed to get store' print json.dumps(res, indent=4, sort_keys=True) return False if 'error' in res['response']: print 'failed to get datastore' print json.dumps(res, indent=4, sort_keys=True) return False datastore_info = res['response'] datastore_name = datastore_info['datastore_id'] # get the data store name res = testlib.ysi_REST_call('GET', '/v1/stores/register.app', ses) if 'error' in res or res['http_status'] != 200: print 'failed to get datastore' print json.dumps(res, indent=4, sort_keys=True) return False if 'error' in res['response']: print 'failed to get datastore' print json.dumps(res, indent=4, sort_keys=True) return False datastore_info = res['response'] datastore_name = datastore_info['datastore_id'] # make directories for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {}'.format(dpath) res = testlib.ysi_REST_call( 'POST', '/v1/stores/{}/directories'.format(datastore_name), ses, path=dpath) if 'error' in res or res['http_status'] != 200: print 'failed to mkdir {}: {}'.format(dpath, res['http_status']) return False # stat directories for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'stat {}'.format(dpath) res = testlib.ysi_REST_call( 'GET', '/v1/stores/{}/inodes'.format(datastore_name), ses, path=dpath) if 'error' in res or res['http_status'] != 200: print 'failed to stat {}: {}'.format(dpath, res['http_status']) return False inode_info = res['response'] if inode_info['type'] != ysi_client.schemas.MUTABLE_DATUM_DIR_TYPE: print 'not a directory: {}, {}'.format(dpath, res) return False # list directories for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_REST_call( 'GET', '/v1/stores/{}/directories'.format(datastore_name), ses, path=dpath) if 'error' in res or res['http_status'] != 200: print 'failed to listdir {}: {}'.format(dpath, res['http_status']) return False dirinfo = res['response'] if len(dirinfo.keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format( expected, dirinfo) return False for child in expected: if not dirinfo.has_key(child): print 'invalid directory: missing {} in {}'.format( child, dirinfo) print json.dumps(res, indent=4, sort_keys=True) return False # put files for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'putfile {}'.format(dpath) data = 'hello {}'.format(os.path.basename(dpath)) res = testlib.ysi_REST_call( 'POST', '/v1/stores/{}/files'.format(datastore_name), ses, raw_data=data, path=dpath) if 'error' in res or res['http_status'] != 200: print 'failed to putfile {}: {}'.format(dpath, res['http_status']) return False # stat files for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'stat {}'.format(dpath) res = testlib.ysi_REST_call( 'GET', '/v1/stores/{}/inodes'.format(datastore_name), ses, path=dpath) if 'error' in res or res['http_status'] != 200: print 'failed to stat {}: {}'.format(dpath, res['http_status']) return False inode_data = res['response'] if inode_data['type'] != ysi_client.schemas.MUTABLE_DATUM_FILE_TYPE: print 'not a file: {}, {}'.format(dpath, res) return False # list directories again for dpath, expected in [('/', ['dir1', 'dir2', 'file1', 'file2']), ('/dir1', ['dir3', 'file3']), ('/dir1/dir3', ['dir4', 'file4']), ('/dir1/dir3/dir4', ['file5'])]: print 'listdir {}'.format(dpath) res = testlib.ysi_REST_call( 'GET', '/v1/stores/{}/directories'.format(datastore_name), ses, path=dpath) if 'error' in res or res['http_status'] != 200: print 'failed to listdir {}: {}'.format(dpath, res['http_status']) return False dirinfo = res['response'] if len(dirinfo.keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format( expected, dirinfo) return False for child in expected: if not dirinfo.has_key(child): print 'invalid directory: missing {} in {}'.format( child, dirinfo) return False # get files for dpath in [ '/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5' ]: print 'getfile {}'.format(dpath) res = testlib.ysi_REST_call( 'GET', '/v1/stores/{}/files'.format(datastore_name), ses, path=dpath) if 'error' in res or res['http_status'] != 200: print 'failed to getfile {}: {}'.format(dpath, res['http_status']) return False filedata = res['raw'] if filedata != 'hello {}'.format(os.path.basename(dpath)): print 'failed to read {}: got "{}"'.format(dpath, filedata) return False # delete datastore res = testlib.ysi_REST_call("DELETE", "/v1/stores", ses) if res['http_status'] != 200: print 'failed to delete datastore' print json.dumps(res) return False # nothing should be here res = testlib.ysi_REST_call( 'GET', '/v1/stores/{}/directories'.format(datastore_name), ses, path='/') if res['http_status'] != 404: print 'got HTTP {} on getting deleted store'.format(res['http_status']) print json.dumps(res) return False
def check( state_engine ): global wallet_keys, datasets, zonefile_hash # 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 # not preordered preorder = state_engine.get_name_preorder( "foo.test", virtualchain.make_payment_script(wallets[2].addr), wallets[3].addr ) if preorder is not None: print "still have preorder" return False # registered name_rec = state_engine.get_name( "foo.test" ) if name_rec is None: print "name does not exist" return False # owned if name_rec['address'] != wallets[3].addr or name_rec['sender'] != virtualchain.make_payment_script(wallets[3].addr): print "name has wrong owner" return False # have right hash if name_rec['value_hash'] != zonefile_hash: print "Invalid zonefile hash" return False # have right data test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) for i in xrange(0, len(datasets)): print "get hello_world_%s" % (i+1) dat = testlib.ysi_cli_get_mutable( "foo.test", "hello_world_{}".format(i+1), public_key=wallets[4].pubkey_hex ) if dat is None: print "No data '%s'" % ("hello_world_%s" % (i+1)) return False if 'error' in dat: print json.dumps(dat, indent=4, sort_keys=True) return False if json.loads(dat['data']) != datasets[i]: print "Mismatch %s: %s != %s" % (i, dat, datasets[i]) return False res = testlib.ysi_cli_lookup("foo.test") if 'error' in res: print 'error looking up profile: {}'.format(res) return False assert 'profile' in res assert 'zonefile' in res return True
def scenario( wallets, **kw ): global wallet_keys, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.ysi_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 ) data_pk = wallets[-1].privkey data_pub = wallets[-1].pubkey_hex config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) # make an index file index_file_path = "/tmp/name_preorder_register_update_app_publish.foo.test.index.html" with open(index_file_path, "w") as f: f.write(index_file_data) # register an application under foo.test res = testlib.ysi_cli_app_publish("foo.test", "ping.app", "node_read", index_file_path, password="******" ) if 'error' in res: res['test'] = 'Failed to register foo.test/bar app' print json.dumps(res, indent=4, sort_keys=True) return False # put mutable data, to be accessed as a resource resource_file_path = "/tmp/name_preorder_register_update_app_publish.foo.test.resource" with open(resource_file_path, "w") as f: f.write(resource_data) res = testlib.ysi_cli_app_put_resource("foo.test", "ping.app", "hello_world", resource_file_path, password="******" ) if 'error' in res: res['test'] = 'Failed to store app resource' print json.dumps(res, indent=4, sort_keys=True) return False testlib.next_block( **kw )
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, key_names, error testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].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 in this block print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) # make an account res = testlib.ysi_cli_put_account("foo.test", "serviceFoo", "serviceFooID", "foo://bar.com", None, extra_data='foofield=foo!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test account' print json.dumps(res, indent=4, sort_keys=True) error = True return res = testlib.ysi_cli_put_account("foo.test", "deletedService", "deletedServiceID", "foo://deleted", None, extra_data='barfield=bar!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test deletedService account' print json.dumps(res, indent=4, sort_keys=True) error = True return # delete an account res = testlib.ysi_cli_delete_account("foo.test", "deletedService", "deletedServiceID", None, wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to delete foo.test deletedService' print json.dumps(res, indent=4, sort_keys=True) error = True return testlib.next_block(**kw)
def scenario(wallets, **kw): global put_result, wallet_keys, wallet_keys_2, datasets, zonefile_hash, dataset_change # make a storage gateway (will be port 16300) res = testlib.peer_setup(0) if 'error' in res: return res storage_gateway_working_dir = res['working_dir'] storage_gateway_config_path = res['config_path'] # make sure the storage gateway saves to disk # ysi_client.config. res = peer_start(storage_gateway_wd, args=['--foreground', '--no-indexer']) # start storage gateway # res = testlib.peer_start( # set up client wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[2].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) resp = testlib.ysi_cli_register("foo.test", "0123456789abcdef") if 'error' in resp: print >> sys.stderr, json.dumps(resp, indent=4, sort_keys=True) return False # wait for the preorder to get confirmed for i in xrange(0, 12): testlib.next_block(**kw) # wait for the poller to pick it up print >> sys.stderr, "Waiting 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 for the backend to acknowledge registration" time.sleep(10) # wait for initial update to get confirmed for i in xrange(0, 12): # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw) print >> sys.stderr, "Waiting for the backend to acknowledge update" time.sleep(10) # wait for zonefile/profile replication for i in xrange(0, 12): testlib.next_block(**kw) print >> sys.stderr, "Waiting for the backend to replicate zonefile and profile" time.sleep(10) # make a few accounts res = testlib.ysi_cli_put_account("foo.test", "serviceFoo", "serviceFooID", "foo://bar.com", "0123456789abcdef", extra_data='foofield=foo!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test serviceFoo account' print json.dumps(res, indent=4, sort_keys=True) error = True return time.sleep(2) res = testlib.ysi_cli_put_account("foo.test", "serviceBar", "serviceBarID", "bar://baz.com", "0123456789abcdef", extra_data='barfield=bar!', wallet_keys=wallet_keys) if 'error' in res: res['test'] = 'Failed to create foo.test serviceBar account' print json.dumps(res, indent=4, sort_keys=True) error = True return time.sleep(2) # put some data put_result = testlib.ysi_cli_put_mutable("foo.test", "hello_world_1", json.dumps(datasets[0]), password="******") if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False time.sleep(2) put_result = testlib.ysi_cli_put_mutable("foo.test", "hello_world_2", json.dumps(datasets[1]), password="******") if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False time.sleep(2) put_result = testlib.ysi_cli_put_mutable("foo.test", "hello_world_3", json.dumps(datasets[2]), password="******") if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False time.sleep(2) # increment data version too datasets[0]['buf'] = [] for i in xrange(0, 5): datasets[0]["dataset_change"] = dataset_change datasets[0]['buf'].append(i) put_result = testlib.ysi_cli_put_mutable("foo.test", "hello_world_1", json.dumps(datasets[0]), password="******") if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) return False time.sleep(2) testlib.next_block(**kw)
assert 'profile' in profile_resp, "missing profile:\n%s" % json.dumps( profile_resp, indent=4, sort_keys=True) # profile will be in 'raw' form raw_profile = profile_resp['profile'] profile = ysi_client.storage.parse_mutable_data( raw_profile, user_pubkey) except Exception, e: traceback.print_exc() print "Invalid profile" return False # have right data test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) for i in xrange(0, len(datasets)): print "get hello_world_%s" % (i + 1) dat = ysi_client.get_mutable("hello_world_%s" % (i + 1), blockchain_id="foo.test") if dat is None: print "No data '%s'" % ("hello_world_%s" % (i + 1)) return False if 'error' in dat: print json.dumps(dat, indent=4, sort_keys=True) return False if json.loads(dat['data']) != datasets[i]: print "Mismatch %s: %s %s != %s %s" % (
def scenario(wallets, **kw): global put_result, wallet_keys, datasets, zonefile_hash, dataset_change wallet = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, None) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = wallet testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_name_register("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) # migrate profile res = testlib.migrate_profile("foo.test", proxy=test_proxy, wallet_keys=wallet_keys, zonefile_has_data_key=False) if 'error' in res: res['test'] = 'Failed to initialize foo.test profile' print json.dumps(res, indent=4, sort_keys=True) return False else: zonefile_hash = res['zonefile_hash'] print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" testlib.next_block(**kw) # should fail with no public key res = testlib.ysi_cli_get_public_key("foo.test") if 'error' not in res: print 'accidentally succeeded to get public key for zone file without one' print res return False # verify this also fails for the RESTful API res = testlib.ysi_REST_call('GET', '/v1/names/foo.test/public_key', None) if res['http_status'] == 200: print 'accidentally succeeded to get public key for zone file without one' print res return False if res['http_status'] != 404: print 'wrong status code: expected 404' print res return False wallet = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) wallet_keys = wallet # migrate profile; add data key 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) return False else: zonefile_hash = res['zonefile_hash'] print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" testlib.next_block(**kw) # should have a public key now res = testlib.ysi_cli_get_public_key("foo.test") if 'error' in res: print 'no public key from zone file for foo.test' print res return False if res['public_key'] != keylib.key_formatting.decompress( keylib.ECPrivateKey(wallets[4].privkey).public_key().to_hex()): print 'wrong public key' print res return False # verify this also succeeds for the RESTful API res = testlib.ysi_REST_call('GET', '/v1/names/foo.test/public_key', None) if res['http_status'] != 200: print 'failed to get public key from RESTful API' print res return False if res['response']['public_key'] != keylib.key_formatting.decompress( keylib.ECPrivateKey(wallets[4].privkey).public_key().to_hex()): print 'wrong public key' print res return False # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block(**kw)
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_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.ysi_cli_app_signin("foo.test", datastore_pk, 'register.app', [ 'names', 'register', 'prices', 'zonefiles', 'blockchain', 'node_read' ]) 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.ysi_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.ysi_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) # register the name bar.test. autogenerate the rest res = testlib.ysi_REST_call('POST', '/v1/names', ses, data={ 'name': 'bar.test', 'unsafe': True }) 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, 3): testlib.next_block(**kw) res = testlib.verify_in_queue(ses, 'bar.test', 'preorder', tx_hash) testlib.next_block(**kw) if not res: return False # wait for register to go through print 'Wait for register to be submitted' time.sleep(10) # wait for the register to get confirmed res = testlib.verify_in_queue(ses, 'bar.test', 'register', None) testlib.next_block(**kw) if not res: return False print 'Wait for update to be submitted' time.sleep(10) time.sleep(10) # wait for update to get confirmed res = testlib.verify_in_queue(ses, 'bar.test', 'update', None) testlib.next_block(**kw) if not res: return False print 'Wait for update to be confirmed' time.sleep(10) res = testlib.ysi_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'] # do we have the history for the name? res = testlib.ysi_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 bar.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.ysi_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
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_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 = ysi_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.ysi_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.ysi_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.ysi_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.ysi_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 synchronized import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) for i in xrange(0, 10): res = testlib.ysi_name_register( "foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # start up a simple Atlas test network with two nodes: the main one doing the test, and a subordinate one that treats it as a seed peer. network_des = atlas_network.atlas_network_build( [17000], {17000: [16264]}, {}, os.path.join( testlib.working_dir(**kw), "atlas_network" )) atlas_network.atlas_network_start( network_des ) time.sleep(5.0) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey(wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)] ) empty_zonefile_str = ysi_zones.make_zone_file( empty_zonefile ) value_hash = ysi_client.hash_zonefile( empty_zonefile ) res = testlib.ysi_name_update( "foo_{}.test".format(i), value_hash, wallets[3].privkey ) if 'error' in res: print json.dumps(res) return False testlib.next_block( **kw ) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # wait at most 10 seconds for atlas network to converge synchronized = False for i in xrange(0, 10): atlas_network.atlas_print_network_state( network_des ) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block( **kw ) - 1, 1 ): print "Synchronized!" synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop( network_des ) return synchronized
def check(state_engine): global last_consensus, snv_block_id # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: return False ns = state_engine.get_namespace("test") if ns is None: return False if ns['namespace_id'] != 'test': return False names = ['foo.test', 'bar.test', 'baz.test'] name_preorder_wallets = [wallets[2], wallets[3], wallets[4]] name_register_wallets = [wallets[5], wallets[6], wallets[7]] name_transfer_wallets = [wallets[6], wallets[7], wallets[5]] test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) for i in xrange(0, len(names)): name = names[i] name_preorder_wallet = name_preorder_wallets[i] name_register_wallet = name_register_wallets[i] name_transfer_wallet = name_transfer_wallets[i] # not preordered preorder = state_engine.get_name_preorder( name, pybitcoin.make_pay_to_address_script(name_preorder_wallet.addr), name_register_wallet.addr) if preorder is not None: return False # registered name_rec = state_engine.get_name(name) if name_rec is None: return False # data is gone if name_rec['value_hash'] is not None: return False # owned by the right transfer wallet if name_rec['address'] != name_transfer_wallet.addr or name_rec[ 'sender'] != pybitcoin.make_pay_to_address_script( name_transfer_wallet.addr): return False # renewed if name_rec['last_renewed'] == name_rec['first_registered']: return False # revoked if not name_rec['revoked']: return False # snv lookup works snv_rec = ysi_client.snv_lookup(name, snv_block_id, last_consensus, proxy=test_proxy) if 'error' in snv_rec: print json.dumps(snv_rec, indent=4) return False return True
def scenario( wallets, **kw ): global put_result, wallet_keys, datasets, zonefile_hash, dataset_change wallet = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = wallet testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # migrate profile 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 else: zonefile_hash = res['zonefile_hash'] # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_1", json.dumps(datasets[0]), password='******' ) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) testlib.next_block( **kw ) put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_2", json.dumps(datasets[1]), password='******' ) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_3", json.dumps(datasets[2]), password='******' ) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True) # increment version too datasets[0]['buf'] = [] for i in xrange(0, 5): datasets[0]["dataset_change"] = dataset_change datasets[0]['buf'].append(i) put_result = testlib.ysi_cli_put_mutable( "foo.test", "hello_world_1", json.dumps(datasets[0]), password='******' ) if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True ) testlib.next_block( **kw )
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_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 = ysi_client.get_config(config_path) assert conf api_pass = conf['api_password'] # make sure we can do REST calls res = testlib.ysi_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.ysi_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.ysi_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 = ysi_client.storage.make_mutable_data_urls( 'foo.test', use_only=['dht', 'disk']) zonefile = ysi_client.zonefile.make_empty_zonefile('foo.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = ysi_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.ysi_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.ysi_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.ysi_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 empty_key = ECPrivateKey().to_hex() wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", empty_key, empty_key, empty_key) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # 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 = ysi_client.get_config(config_path) assert conf api_pass = conf['api_password'] payment_key = wallets[1].privkey # make zonefile for recipient driver_urls = ysi_client.storage.make_mutable_data_urls( 'bar.test', use_only=['dht', 'disk']) zonefile = ysi_client.zonefile.make_empty_zonefile('bar.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = ysi_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.ysi_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.ysi_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.ysi_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.ysi_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, 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 zonefile to be sent' time.sleep(10) res = testlib.ysi_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 print res['response'] 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.ysi_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.ysi_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 = ysi_client.storage.make_mutable_data_urls( 'bar.test', use_only=['http', 'disk']) zonefile = ysi_client.zonefile.make_empty_zonefile('bar.test', wallets[3].pubkey_hex, urls=driver_urls) zonefile_txt = ysi_zones.make_zone_file(zonefile, origin='bar.test', ttl=3600) # let's do this update. res = testlib.ysi_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, 4): testlib.next_block(**kw) # wait for zonefile to propagate time.sleep(10) res = testlib.ysi_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.ysi_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, error, index_file_data, resource_data test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey ) testlib.ysi_client_set_wallet( "0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey'] ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.ysi_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 res = testlib.start_api("0123456789abcdef") if 'error' in res: print 'failed to start API: {}'.format(res) return False # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() testlib.next_block( **kw ) # sign in and make a token datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.ysi_cli_app_signin("foo.test", datastore_pk, 'http://localhost:8888', ['store_read', 'store_write', 'store_admin']) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # export to environment ysi_client.set_secret("BLOCKSTACK_API_SESSION", ses) datastore_id_res = testlib.ysi_cli_datastore_get_id( datastore_pk ) datastore_id = datastore_id_res['datastore_id'] # use random data for file file_data = None with open('/dev/urandom', 'r') as f: file_data = f.read(16384) # make datastore res = testlib.ysi_cli_create_datastore( "foo.test", datastore_pk, ['disk'], ses ) if 'error' in res: print "failed to create datastore: {}".format(res['error']) return False # make directories for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {}'.format(dpath) res = testlib.ysi_cli_datastore_mkdir( "foo.test", datastore_pk, dpath, ses ) if 'error' in res: print 'failed to mkdir {}: {}'.format(dpath, res['error']) return False # make directories again (should fail with EEXIST) for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'mkdir {} (should fail)'.format(dpath) res = testlib.ysi_cli_datastore_mkdir( "foo.test", datastore_pk, dpath, ses ) if 'error' not in res: print 'accidentally succeeded to mkdir {}: {}'.format(dpath, res) return False if not res.has_key('errno'): print 'no errno in error {}'.format(res) return False if res['errno'] != errno.EEXIST: print 'wrong errno in error {}'.format(res) return False # stat directories for dpath in ['/dir1', '/dir2', '/dir1/dir3', '/dir1/dir3/dir4']: print 'stat {}'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to stat {}: {}'.format(dpath, res['error']) return False if res['type'] != ysi_client.schemas.MUTABLE_DATUM_DIR_TYPE: print 'not a directory: {}, {}'.format(dpath, res) return False # list directories for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False print res if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format(expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # put files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'putfile {}'.format(dpath) data = '{} hello {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile( "foo.test", datastore_pk, dpath, data, ses ) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False # stat files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'stat {}'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to stat {}: {}'.format(dpath, res['error']) return False if res['type'] != ysi_client.schemas.MUTABLE_DATUM_FILE_TYPE: print 'not a file: {}, {}'.format(dpath, res) return False # list directories again for dpath, expected in [('/', ['dir1', 'dir2', 'file1', 'file2']), ('/dir1', ['dir3', 'file3']), ('/dir1/dir3', ['dir4', 'file4']), ('/dir1/dir3/dir4', ['file5'])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format(expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # get files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # put files again! for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'putfile {}'.format(dpath) data = '{} hello 2 {}'.format(file_data, dpath) res = testlib.ysi_cli_datastore_putfile( "foo.test", datastore_pk, dpath, data, ses ) if 'error' in res: print 'failed to putfile {}: {}'.format(dpath, res['error']) return False # get files again! for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'getfile {}'.format(dpath) res = testlib.ysi_cli_datastore_getfile( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to getfile {}: {}'.format(dpath, res['error']) return False if res != '{} hello 2 {}'.format(file_data, dpath): print 'failed to read {}'.format(dpath) return False # remove files for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'deletefile {}'.format(dpath) res = testlib.ysi_cli_datastore_deletefile( "foo.test", datastore_pk, dpath, ses ) if 'error' in res: print 'failed to deletefile {}: {}'.format(dpath, res['error']) return False # stat files (should all fail) for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # get files (should all fail) for dpath in ['/file1', '/file2', '/dir1/file3', '/dir1/dir3/file4', '/dir1/dir3/dir4/file5']: print 'getfile {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_getfile( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to get {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories, 3rd time for dpath, expected in [('/', ['dir1', 'dir2']), ('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {}'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' in res: print 'failed to listdir {}: {}'.format(dpath, res['error']) return False if len(res['children'].keys()) != len(expected): print 'invalid directory: expected:\n{}\ngot:\n{}\n'.format(expected, res) return False for child in expected: if not res['children'].has_key(child): print 'invalid directory: missing {} in {}'.format(child, res) return False # remove directories for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'rmdir {}'.format(dpath) res = testlib.ysi_cli_datastore_rmdir( "foo.test", datastore_pk, dpath, ses ) if 'error' in res: print 'failed to rmdir {}: {}'.format(dpath, res['error']) return False # stat directories (should all fail) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'stat {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_stat( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to stat {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # list directories (should all fail) for dpath, expected in [('/dir1', ['dir3']), ('/dir1/dir3', ['dir4']), ('/dir1/dir3/dir4', [])]: print 'listdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, dpath, ses ) if 'error' not in res or 'errno' not in res: print 'accidentally succeeded to list {}: {}'.format(dpath, res) return False if res['errno'] != errno.ENOENT: print 'wrong errno: {}'.format(res) return False # remove directories again (should fail) for dpath in ['/dir1/dir3/dir4', '/dir1/dir3', '/dir2', '/dir1']: print 'rmdir {} (expect failure)'.format(dpath) res = testlib.ysi_cli_datastore_rmdir( "foo.test", datastore_pk, dpath, ses ) if 'error' not in res: print 'accidentally succeeded to rmdir twice: {}'.format(res) return False if res.get('errno') != errno.ENOENT: print 'wrong errno on rmdir: {}'.format(res) return False # root should be empty print 'listdir {}'.format('/') res = testlib.ysi_cli_datastore_listdir( "foo.test", datastore_id, '/', ses ) if 'error' in res: print 'failed to listdir /: {}'.format(res['error']) return False if len(res['children'].keys()) > 0: print 'root still has children: {}'.format(res['children'].keys()) return False # delete datastore print 'delete datastore' res = testlib.ysi_cli_delete_datastore( "foo.test", datastore_pk, ses ) if 'error' in res: print 'failed to delete foo-app.com datastore' print json.dumps(res) return False # no more data in disk driver names = os.listdir("/tmp/ysi-disk/mutable") if names != ['foo.test']: print 'improper cleanup' return False testlib.next_block( **kw )
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_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) data_pk = wallets[-1].privkey data_pub = wallets[-1].pubkey_hex config_path = os.environ.get("BLOCKSTACK_CLIENT_CONFIG", None) # make a session datastore_pk = keylib.ECPrivateKey(wallets[-1].privkey).to_hex() res = testlib.ysi_cli_app_signin( "foo.test", datastore_pk, 'register.app', [ 'names', 'register', 'transfer', 'prices', 'zonefiles', 'blockchain', 'node_read' ]) if 'error' in res: print json.dumps(res, indent=4, sort_keys=True) error = True return ses = res['token'] # register the name bar.test res = testlib.ysi_REST_call('POST', '/v1/names', ses, data={'name': 'bar.test'}) 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 update to be confirmed' time.sleep(10) res = testlib.ysi_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'] # transfer it res = testlib.ysi_REST_call("PUT", "/v1/names/bar.test/owner", ses, data={'owner': wallets[7].addr}) if 'error' in res or res['http_status'] != 202: res['test'] = 'Failed to transfer name' print json.dumps(res) return False # 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 not res: return False for i in xrange(0, 4): testlib.next_block(**kw) print 'waiting for transfer to get confirmed' time.sleep(10) # poll res = testlib.ysi_REST_call("GET", "/v1/names/bar.test", ses) if 'error' in res or res['http_status'] != 200: res['test'] = 'Failed to query name' print json.dumps(res) error = True return False # new owner? if not res['response'].has_key('address'): res['test'] = 'No address given' print json.dumps(res) return False address_testnet = virtualchain.address_reencode(str( res['response']['address']), network='testnet') if address_testnet != wallets[7].addr: res['test'] = 'Failed to transfer name to new address {}'.format( wallets[7].addr) res['owner_address_testnet'] = address_testnet print json.dumps(res) return False # do we have the history for the name? res = testlib.ysi_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()) != 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.ysi_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
def check(state_engine): global snv_block_id_foo, snv_txid_bar, last_consensus # not revealed, but ready ns = state_engine.get_namespace_reveal("test") if ns is not None: return False ns = state_engine.get_namespace("test") if ns is None: return False if ns['namespace_id'] != 'test': return False # not preordered for i in xrange(0, len(wallets)): for name in ["foo.test", "bar.test", "baz.test"]: preorder = state_engine.get_name_preorder( name, virtualchain.make_payment_script(wallets[i].addr), wallets[(i + 1) % 5].addr) if preorder is not None: print "preordered" return False # but still registered for name in ["foo.test", "bar.test", "baz.test"]: name_rec = state_engine.get_name(name) if name_rec is None: print "no name" return False # updated, and data preserved name_rec = state_engine.get_name("baz.test") if name_rec['value_hash'] != "22" * 20: print "wrong value hash" return False # transferred name_rec = state_engine.get_name("bar.test") if name_rec['address'] != wallets[4].addr or name_rec[ 'sender'] != virtualchain.make_payment_script(wallets[4].addr): print "wrong owner" return False # snv lookup works # NOTE: cannot use serial numbers here, since a NAME_IMPORT does not contain a consensus hash. test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) bitcoind = testlib.get_bitcoind() snv_rec = ysi_client.snv_lookup("foo.test", snv_block_id_foo, last_consensus, proxy=test_proxy) if 'error' in snv_rec: print json.dumps(snv_rec, indent=4) print "failed to look up foo.test from consensus hash %s" % last_consensus return False # can use bar.test's NAME_TRANSFER txid to verify foo.test, since it has a consensus hash snv_rec_bar_tx = ysi_client.snv_lookup("foo.test", snv_block_id_foo, snv_txid_bar, proxy=test_proxy) if 'error' in snv_rec_bar_tx: print json.dumps(snv_rec_bar_tx, indent=4) print "failed to look up foo.test from transaction %s" % snv_txid_bar return False if snv_rec != snv_rec_bar_tx: print "--------" print json.dumps(snv_rec, indent=4) print "" print json.dumps(snv_rec_bar_tx, indent=4) print "" print "Not equal" return False print snv_rec return True
def scenario( wallets, **kw ): global put_result, wallet_keys, legacy_profile, zonefile_hash, zonefile_hash_2, error wallet_keys = testlib.ysi_client_initialize_wallet( "0123456789abcdef", wallets[8].privkey, wallets[3].privkey, wallets[4].privkey ) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy( test_proxy ) testlib.ysi_namespace_preorder( "test", wallets[1].addr, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0], 10, 10, wallets[0].privkey ) testlib.next_block( **kw ) testlib.ysi_namespace_ready( "test", wallets[1].privkey ) testlib.next_block( **kw ) testlib.ysi_name_preorder( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) testlib.ysi_name_register( "foo.test", wallets[2].privkey, wallets[3].addr ) testlib.next_block( **kw ) # set up legacy profile hash legacy_txt = json.dumps(legacy_profile,sort_keys=True) legacy_hash = virtualchain.lib.hashing.hex_hash160( legacy_txt ) result_1 = testlib.ysi_cli_update("foo.test", legacy_txt, '0123456789abcdef') if 'error' in result_1: print json.dumps(result_1, indent=4, sort_keys=True) return False # wait for it to go through... for i in xrange(0, 12): testlib.next_block(**kw) print "wait 10 seconds for update to go through" time.sleep(10) rc = ysi_client.storage.put_immutable_data( legacy_txt, result_1['transaction_hash'], data_hash=legacy_hash ) assert rc is not None testlib.next_block( **kw ) # migrate profiles to standard zonefiles 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) return False testlib.next_block( **kw ) # give foo.test a nonstandard zonefile (as something that serializes to JSON) nonstandard_zonefile_json = {'nonstandard': 'true', 'error': 'nonstandard'} nonstandard_zonefile_txt = json.dumps(nonstandard_zonefile_json, sort_keys=True) nonstandard_zonefile_raw = binascii.unhexlify( "".join(["%02x" % i for i in xrange(0, 256)])) zf_data = [nonstandard_zonefile_txt, nonstandard_zonefile_raw] for zi in xrange(0, len(zf_data)): nonstandard_zonefile = zf_data[zi] resp = testlib.ysi_cli_update( "foo.test", nonstandard_zonefile, "0123456789abcdef", nonstandard=True ) if 'error' in resp: print "failed to put nonstandard zonefile '%s'" % nonstandard_zonefile print json.dumps(resp, indent=4, sort_keys=True) return False testlib.expect_atlas_zonefile(resp['zonefile_hash']) # wait for it to take effect for i in xrange(0, 12): testlib.next_block( **kw ) time.sleep(10) # getting zonefile should still work... resp = testlib.ysi_cli_get_name_zonefile( "foo.test", json=True, raw=False) if 'error' in resp: print "failed to get zonefile %s" % zi print json.dumps(resp, indent=4, sort_keys=True) return False if resp['zonefile'] != nonstandard_zonefile: print "failed to load nonstandard zonefile json" print "expected:\n%s\n\ngot:\n%s" % (nonstandard_zonefile, resp['zonefile']) return False # the following should all fail dataplane_funcs = [ ("lookup", lambda: testlib.ysi_cli_lookup( "foo.test" )), ("put_immutable", lambda: testlib.ysi_cli_put_immutable( "foo.test", "fail", '{"Fail": "Yes"}', password='******' )), ("get_immutable", lambda: testlib.ysi_cli_get_immutable( "foo.test", "fail" )), ("put_mutable", lambda: testlib.ysi_cli_put_mutable( "foo.test", "fail", '{"fail": "yes"}', password='******' )), ("get_mutable", lambda: testlib.ysi_cli_get_mutable( "foo.test", "fail" )), ("delete_immutable", lambda: testlib.ysi_cli_delete_immutable( "foo.test", "00" * 32, password='******' )), ("delete_mutable", lambda: testlib.ysi_cli_delete_mutable( "foo.test", "fail", password='******' )) ] for data_func_name, data_func in dataplane_funcs: resp = data_func() if 'error' not in resp: if data_func_name != 'lookup': print "%s succeeded when it should not have:\n%s" % (data_func_name, json.dumps(resp, indent=4, sort_keys=True)) return False elif 'error' not in resp['profile']: print "%s succeeded when it should not have:\n%s" % (data_func_name, json.dumps(resp, indent=4, sort_keys=True)) return False # this should succeed zf_hist = testlib.ysi_cli_list_zonefile_history( "foo.test" ) if len(zf_hist) != 2*(zi+1)+1: print "missing zonefile history: %s (expected %s items, got %s)" % (zf_hist, zi+3, len(zf_hist)) return False update_hist = testlib.ysi_cli_list_update_history( "foo.test" ) if len(update_hist) != 2*(zi+1)+1: print 'missing zonefile history: %s (expected %s items, got %s)' % (zf_hist, zi+3, len(zf_hist)) return False name_hist = testlib.ysi_cli_get_name_blockchain_history("foo.test") if zf_hist[-1] != nonstandard_zonefile: print "invalid zonefile: expected\n%s\ngot\n%s\n" % (nonstandard_zonefile, zf_hist[-1]) return False # this should work, but with "non-standard zonefiles" hist = testlib.ysi_cli_list_immutable_data_history("foo.test", "fail") if len(hist) != 2*(zi+1)+1: print "missing immutable data history: %s (expected %s items, got %s)" % (hist, zi+3, len(hist)) return False if hist[-1] != 'non-standard zonefile': print "not a non-standard zonefile: %s" % hist[-1] return False # verify that we can migrate it back resp = testlib.ysi_cli_migrate( "foo.test", "0123456789abcdef", force=True, interactive=False ) if 'error' in resp: print "failed to migrate" print json.dumps(resp, indent=4, sort_keys=True) return False zonefile_hash = resp['zonefile_hash'] # wait for it to take effect for i in xrange(0, 12): testlib.next_block( **kw ) time.sleep(10) # see that put_immutable works put_result = testlib.ysi_cli_put_immutable("foo.test", "hello_world_immutable", json.dumps({'hello': 'world'}), password='******') if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True ) return False testlib.expect_atlas_zonefile(put_result['zonefile_hash']) # tell serialization-checker that value_hash can be ignored here print "BLOCKSTACK_SERIALIZATION_CHECK_IGNORE value_hash" sys.stdout.flush() # wait for confirmation for i in xrange(0, 12): testlib.next_block( **kw ) print "waiting for confirmation" time.sleep(10) # see that put_mutable works put_result = testlib.ysi_cli_put_mutable("foo.test", "hello_world_mutable", json.dumps({'hello': 'world'}), password='******') if 'error' in put_result: print json.dumps(put_result, indent=4, sort_keys=True ) testlib.next_block( **kw )
def scenario(wallets, **kw): global synchronized, value_hash import ysi_integration_tests.atlas_network as atlas_network testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # set up RPC daemon test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) wallet_keys = ysi_client.make_wallet_keys( owner_privkey=wallets[3].privkey, data_privkey=wallets[4].privkey, payment_privkey=wallets[5].privkey) testlib.ysi_client_set_wallet("0123456789abcdef", wallet_keys['payment_privkey'], wallet_keys['owner_privkey'], wallet_keys['data_privkey']) # register 10 names for i in xrange(0, 10): res = testlib.ysi_name_preorder("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) for i in xrange(0, 10): res = testlib.ysi_name_register("foo_{}.test".format(i), wallets[2].privkey, wallets[3].addr) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # start up an Atlas test network with 9 nodes: the main one doing the test, and 8 subordinate ones that treat it as a seed peer # organize nodes into a linear chain: node n is neighbor to n-1 and n+1, with the seed at one end. # nodes cannot talk to anyone else. atlas_nodes = [17000, 17001, 17002, 17003, 17004, 17005, 17006, 17007] atlas_topology = {} atlas_topology[17000] = [16264, 17001] atlas_topology[17007] = [17006] for i in xrange(1, len(atlas_nodes) - 1): atlas_topology[atlas_nodes[i]] = [ atlas_nodes[i - 1], atlas_nodes[i + 1] ] def chain_drop(src_hostport, dest_hostport): if src_hostport is None: return 0.0 src_host, src_port = ysi_client.utils.url_to_host_port(src_hostport) dest_host, dest_port = ysi_client.utils.url_to_host_port(dest_hostport) if (src_port == 16264 and dest_port == 17000) or (src_port == 17000 and dest_port == 16264): # seed end of the chain return 0.0 if abs(src_port - dest_port) <= 1: # chain link return 0.0 # drop otherwise return 1.0 network_des = atlas_network.atlas_network_build( atlas_nodes, atlas_topology, {}, os.path.join(testlib.working_dir(**kw), "atlas_network")) atlas_network.atlas_network_start(network_des, drop_probability=chain_drop) print "Waiting 25 seconds for the altas peers to catch up" time.sleep(25.0) # make 10 empty zonefiles and propagate them for i in xrange(0, 10): data_pubkey = virtualchain.BitcoinPrivateKey( wallet_keys['data_privkey']).public_key().to_hex() empty_zonefile = ysi_client.zonefile.make_empty_zonefile( "foo_{}.test".format(i), data_pubkey, urls=["file:///tmp/foo_{}.test".format(i)]) empty_zonefile_str = ysi_zones.make_zone_file(empty_zonefile) value_hash = ysi_client.hash_zonefile(empty_zonefile) res = testlib.ysi_name_update("foo_{}.test".format(i), value_hash, wallets[3].privkey) if 'error' in res: print json.dumps(res) return False testlib.next_block(**kw) # propagate res = testlib.ysi_cli_sync_zonefile('foo_{}.test'.format(i), zonefile_string=empty_zonefile_str) if 'error' in res: print json.dumps(res) return False # wait at most 60 seconds for atlas network to converge synchronized = False for i in xrange(0, 60): atlas_network.atlas_print_network_state(network_des) if atlas_network.atlas_network_is_synchronized( network_des, testlib.last_block(**kw) - 1, 1): print "Synchronized!" sys.stdout.flush() synchronized = True break else: time.sleep(1.0) # shut down atlas_network.atlas_network_stop(network_des) if not synchronized: print "Not synchronized" sys.stdout.flush() return synchronized
def scenario(wallets, **kw): global wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) # 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 = ysi_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.ysi_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, 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) 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) if not res: return False for i in xrange(0, 4): testlib.next_block(**kw) print 'Wait for update to be confirmed' time.sleep(10) res = testlib.ysi_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.ysi_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, 4): testlib.next_block(**kw) # new expire block res = testlib.ysi_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.ysi_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.ysi_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 wallet_keys, wallet_keys_2, error, index_file_data, resource_data wallet_keys = testlib.ysi_client_initialize_wallet("0123456789abcdef", wallets[5].privkey, wallets[3].privkey, wallets[4].privkey) test_proxy = testlib.TestAPIProxy() ysi_client.set_default_proxy(test_proxy) testlib.ysi_namespace_preorder("test", wallets[1].addr, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_reveal( "test", wallets[1].addr, 52595, 250, 4, [6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 10, 10, wallets[0].privkey) testlib.next_block(**kw) testlib.ysi_namespace_ready("test", wallets[1].privkey) testlib.next_block(**kw) testlib.ysi_name_preorder("foo.test", wallets[2].privkey, wallets[3].addr) testlib.next_block(**kw) testlib.ysi_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.ysi_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 = ysi_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.ysi_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.ysi_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.ysi_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 = ysi_client.storage.make_mutable_data_urls( 'bar.test', use_only=['dht', 'disk']) zonefile = ysi_client.zonefile.make_empty_zonefile('bar.test', wallets[4].pubkey_hex, urls=driver_urls) zonefile_txt = ysi_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.ysi_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 "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.ysi_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.ysi_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.ysi_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