class BaseProfilerTest(_BaseResourceTest._ResourceTest): __test__ = False def setUp(self): super().setUp() self.web = StubSite(ProfilerResource(self.manager)) @pytest.mark.skipif(sys.platform == 'win32', reason='shutil.rmtree fails on Windows') @inlineCallbacks def test_post(self): # Options yield self.web.options("profiler") tmpdir = tempfile.mkdtemp() tmpfile = tempfile.NamedTemporaryFile(dir=tmpdir, suffix='.prof', delete=False) filename = os.path.basename(tmpfile.name) full_path = os.path.join(tmpdir, filename) # Start profiler response_start = yield self.web.post("profiler", {'start': True}) data_start = response_start.json_value() self.assertTrue(data_start['success']) with open(full_path, 'r') as f: # In the start the file must be empty self.assertEqual(len(f.read()), 0) # Stop profiler response_stop = yield self.web.post("profiler", { 'stop': True, 'filepath': full_path }) data_stop = response_stop.json_value() self.assertTrue(data_stop['success']) with open(full_path, 'rb') as f: # After stop profiler file must have something self.assertGreater(len(f.read()), 0) # Success false response_error = yield self.web.post("profiler") data_error = response_error.json_value() self.assertFalse(data_error['success']) # Removing tmpdir shutil.rmtree(tmpdir) def test_dump_file(self): resource = ProfilerResource(self.manager) filename = resource.gen_dump_filename() filename_arr = filename.split('/') self.assertEqual(filename_arr[0], 'profiles') self.assertTrue(re.search(r'^profile\d{3}\.prof$', filename_arr[1]))
class BaseLockTest(_BaseResourceTest._ResourceTest): __test__ = False def setUp(self): super().setUp() self.web = StubSite(LockWalletResource(self.manager)) self.web_unlock = StubSite(UnlockWalletResource(self.manager)) self.web_state = StubSite(StateWalletResource(self.manager)) @inlineCallbacks def test_locking(self): # Wallet is locked response = yield self.web_state.get('wallet/state') data = response.json_value() self.assertTrue(data['is_locked']) # Unlock it response_success = yield self.web_unlock.post('wallet/unlock', {'password': '******'}) data_success = response_success.json_value() self.assertTrue(data_success['success']) # Wallet is unlocked response_unlocked = yield self.web_state.get('wallet/state') data_unlocked = response_unlocked.json_value() self.assertFalse(data_unlocked['is_locked']) # Test locking the wallet with resource # Options yield self.web.options("wallet/lock") response_test = yield self.web.post('wallet/lock') data_test = response_test.json_value() self.assertTrue(data_test['success']) # Validate wallet is locked response_locked = yield self.web_state.get('wallet/state') data_locked = response_locked.json_value() self.assertTrue(data_locked['is_locked'])
class BaseUnlockTest(_BaseResourceTest._ResourceTest): __test__ = False def setUp(self): super().setUp() self.web = StubSite(UnlockWalletResource(self.manager)) self.web_lock = StubSite(LockWalletResource(self.manager)) self.web_state = StubSite(StateWalletResource(self.manager)) @inlineCallbacks def test_unlocking(self): # Wallet is locked response = yield self.web_state.get("wallet/state") data = response.json_value() self.assertTrue(data['is_locked']) # Try to unlock with wrong password # Options yield self.web.options("wallet/unlock") response_error = yield self.web.post("wallet/unlock", {'password': '******'}) data_error = response_error.json_value() self.assertFalse(data_error['success']) # Try to unlock with correct password response_success = yield self.web.post("wallet/unlock", {'password': '******'}) data_success = response_success.json_value() self.assertTrue(data_success['success']) # Wallet is unlocked response_unlocked = yield self.web_state.get("wallet/state") data_unlocked = response_unlocked.json_value() self.assertFalse(data_unlocked['is_locked']) @inlineCallbacks def test_unlocking_hd_wallet(self): self.manager.wallet = HDWallet() self.manager.wallet._manually_initialize() self.manager.wallet.unlock(tx_storage=self.manager.tx_storage) # Wallet is not locked response = yield self.web_state.get("wallet/state") data = response.json_value() self.assertFalse(data['is_locked']) # Lock the wallet response_lock = yield self.web_lock.post("wallet/lock") data_lock = response_lock.json_value() self.assertTrue(data_lock['success']) # Wallet is locked response_locked = yield self.web_state.get("wallet/state") data_locked = response_locked.json_value() self.assertTrue(data_locked['is_locked']) # Unlock wallet invalid words response_invalid = yield self.web.post("wallet/unlock", {'words': 'abc def', 'passphrase': ''}) data_invalid = response_invalid.json_value() self.assertFalse(data_invalid['success']) # Unlock wallet response_success = yield self.web.post("wallet/unlock", {'passphrase': ''}) data_success = response_success.json_value() self.assertTrue(data_success['success']) # Wallet is unlocked response_unlocked = yield self.web_state.get("wallet/state") data_unlocked = response_unlocked.json_value() self.assertFalse(data_unlocked['is_locked']) # Lock the wallet and unlock with same words self.manager.wallet.lock() response_words = yield self.web.post("wallet/unlock", {'words': data_success['words'], 'passphrase': ''}) data_words = response_words.json_value() self.assertTrue(data_words['success'])
def test_match_values(self): decode_resource = StubSite(NanoContractDecodeResource(self.manager)) execute_resource = StubSite(NanoContractExecuteResource(self.manager)) match_value_resource = StubSite( NanoContractMatchValueResource(self.manager)) pushtx_resource = StubSite( PushTxResource(self.manager, allow_non_standard_script=True)) signtx_resource = StubSite(SignTxResource(self.manager)) decodetx_resource = StubSite(DecodeTxResource(self.manager)) add_new_blocks(self.manager, 3) add_blocks_unlock_reward(self.manager) self.reactor.advance(3) # Options yield match_value_resource.options( "wallet/nano_contracts/match_values") total_value = self.manager.get_tokens_issued_per_block(1) address1 = self.get_address(0) data_post = { 'oracle_data_id': 'some_id', 'total_value': total_value, 'input_value': total_value, 'min_timestamp': 1, 'fallback_address': self.get_address(1), 'values': [{ 'address': address1, 'value': 300 }] } # Error missing parameter response_error = yield match_value_resource.post( "wallet/nano_contracts/match_value", data_post) data_error = response_error.json_value() self.assertFalse(data_error['success']) self.assertEqual(data_error['message'], 'Missing parameter: oracle_pubkey_hash') # create nano contract data_post['oracle_pubkey_hash'] = '6o6ul2c+sqAariBVW+CwNaSJb9w=' response = yield match_value_resource.post( "wallet/nano_contracts/match_value", data_post) data = response.json_value() self.assertTrue(data['success']) self.assertIsNotNone(data['hex_tx']) nano_contract_hex = data['hex_tx'] # Error missing parameter response_error = yield decode_resource.get( "wallet/nano_contracts/decode", {}) data_error = response_error.json_value() self.assertFalse(data_error['success']) self.assertEqual(data_error['message'], 'Missing parameter: hex_tx') # Error invalid hex response_error2 = yield decode_resource.get( "wallet/nano_contracts/decode", {b'hex_tx': b'123'}) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success']) # Error valid hex but invalid tx struct response_error3 = yield decode_resource.get( "wallet/nano_contracts/decode", {b'hex_tx': b'1334'}) data_error3 = response_error3.json_value() self.assertFalse(data_error3['success']) # decode genesis_output = [ tx for tx in self.manager.tx_storage.get_all_genesis() if tx.is_block ][0].outputs[0] partial_tx = Transaction.create_from_struct( bytes.fromhex(nano_contract_hex)) partial_tx.outputs.append(genesis_output) response_decode = yield decode_resource.get( "wallet/nano_contracts/decode", {b'hex_tx': bytes(partial_tx.get_struct().hex(), 'utf-8')}) data = response_decode.json_value() self.assertTrue(data['success']) nano_contract = data['nano_contract'] self.assertIsNotNone(nano_contract) self.assertEqual(nano_contract['type'], 'NanoContractMatchValues') self.assertEqual(len(data['other_inputs']), 0) self.assertEqual(len(data['my_inputs']), 1) self.assertEqual(len(data['outputs']), 1) self.assertEqual(data['outputs'][0], genesis_output.to_human_readable()) address2 = self.get_address(2) data_put = { 'new_values': [{ 'address': address2, 'value': 500 }], 'input_value': total_value } # Error missing parameter response_error = yield match_value_resource.put( "wallet/nano_contracts/match_value", data_put) data_error = response_error.json_value() self.assertFalse(data_error['success']) self.assertEqual(data_error['message'], 'Missing parameter: hex_tx') # update data_put['hex_tx'] = partial_tx.get_struct().hex() response = yield match_value_resource.put( "wallet/nano_contracts/match_value", data_put) data = response.json_value() self.assertTrue(data['success']) self.assertIsNotNone(data['hex_tx']) # Error nano contract not found new_tx = Transaction.create_from_struct(partial_tx.get_struct()) new_tx.outputs = [] data_put['hex_tx'] = new_tx.get_struct().hex() response = yield match_value_resource.put( "wallet/nano_contracts/match_value", data_put) data = response.json_value() self.assertFalse(data['success']) # Error missing parameter response_error = yield signtx_resource.get("wallet/sign_tx", {}) data_error = response_error.json_value() self.assertFalse(data_error['success']) self.assertEqual(data_error['message'], 'Missing parameter: hex_tx') # Error wrong parameter value response_error2 = yield signtx_resource.get("wallet/sign_tx", { b'hex_tx': b'123', b'prepare_to_send': b'true' }) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success']) # Error valid hex but wrong tx struct value response_error3 = yield signtx_resource.get("wallet/sign_tx", { b'hex_tx': b'1334', b'prepare_to_send': b'true' }) data_error3 = response_error3.json_value() self.assertFalse(data_error3['success']) # sign tx response = yield signtx_resource.get( "wallet/sign_tx", { b'hex_tx': bytes(nano_contract_hex, 'utf-8'), b'prepare_to_send': b'true' }) data = response.json_value() self.assertTrue(data['success']) nano_contract_hex = data['hex_tx'] # sign tx without preparing response2 = yield signtx_resource.get( "wallet/sign_tx", {b'hex_tx': bytes(nano_contract_hex, 'utf-8')}) data2 = response2.json_value() self.assertTrue(data2['success']) self.assertIsNotNone(data2['hex_tx']) # propagate tx response = yield pushtx_resource.get( "push_tx", {b'hex_tx': bytes(nano_contract_hex, 'utf-8')}) data = response.json_value() self.assertTrue(data['success']) self.reactor.advance(3) # get tx hash response = yield decodetx_resource.get( "decode_tx", {b'hex_tx': bytes(nano_contract_hex, 'utf-8')}) data = response.json_value() self.assertTrue(data['success']) hash_hex = data['tx']['hash'] # Options yield execute_resource.options("wallet/nano_contracts/execute") # Error no data response_error = yield execute_resource.post( "wallet/nano_contracts/execute") data_error = response_error.json_value() self.assertFalse(data_error['success']) # Error missing parameter data = { 'spent_tx_index': 0, 'oracle_data': 'B3NvbWVfaWQEW/xjGQIBLA==', 'oracle_signature': 'MEUCIGeqbmLRI6lrgXMy4sQEgK94F5m14oVL5Z7oLLVII7BUAiEApKTMuWlwvws574' '+jtqKW5/AuH+ICD0u+HyMyHe0aric=', 'oracle_pubkey': 'Awmloohhey8WhajdDURgvbk1z3JHX2vxDSBjz9uG9wEp', 'address': address1, 'value': total_value, } response_error2 = yield execute_resource.post( "wallet/nano_contracts/execute", data) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success']) self.assertEqual(data_error2['message'], 'Missing parameter: spent_tx_id') # execute nano contract data['spent_tx_id'] = hash_hex response = yield execute_resource.post("wallet/nano_contracts/execute", data) data = response.json_value() self.assertTrue(data['success'])
class SendTokensTest(_BaseResourceTest._ResourceTest): def setUp(self): super().setUp() self.web = StubSite(SendTokensResource(self.manager)) self.web_mining = StubSite(MiningResource(self.manager)) self.web_balance = StubSite(BalanceResource(self.manager)) self.web_history = StubSite(HistoryResource(self.manager)) @inlineCallbacks def test_post(self): # Mining new block response_mining = yield self.web_mining.get("mining") data_mining = response_mining.json_value() block_bytes = resolve_block_bytes( block_bytes=data_mining['block_bytes']) yield self.web_mining.post( "mining", {'block_bytes': base64.b64encode(block_bytes).decode('utf-8')}) add_blocks_unlock_reward(self.manager) self.reactor.advance(10) # Unlocking wallet self.manager.wallet.unlock(b"MYPASS") # Sending token to random address without input # Options yield self.web.options("wallet/send_tokens") data_json = { "outputs": [{ "address": self.get_address(0), "value": 505 }], "inputs": [] } response = yield self.web.post("wallet/send_tokens", {'data': data_json}) data = response.json_value() self.assertTrue(data['success']) self.reactor.advance(10) # Asserting new balance response_balance = yield self.web_balance.get("wallet/balance") data_balance = response_balance.json_value() tokens_per_block = self.manager.get_tokens_issued_per_block(1) self.assertEqual(data_balance['balance'], { 'available': tokens_per_block - 505, 'locked': 0 }) # Getting history, so we can get the input response_history = yield self.web_history.get("wallet/history", { b'page': 1, b'count': 10 }) data_history = response_history.json_value() input_hash = data_history['history'][0]['tx_id'] # Sending token to random address with input wrong amount data_json = { "outputs": [{ "address": self.get_address(0), "value": 500 }], "inputs": [{ "tx_id": input_hash, "index": 0 }] } response2 = yield self.web.post("wallet/send_tokens", {'data': data_json}) data2 = response2.json_value() self.assertFalse(data2['success']) self.reactor.advance(10) # Sending duplicate input data_json_duplicate = { "outputs": [{ "address": self.get_address(0), "value": 19000 }], "inputs": [{ "tx_id": input_hash, "index": 0 }, { "tx_id": input_hash, "index": 0 }] } response_duplicate = yield self.web.post("wallet/send_tokens", {'data': data_json_duplicate}) data_duplicate = response_duplicate.json_value() self.assertFalse(data_duplicate['success']) # Sending token to random address with input right amount data_json2 = { "outputs": [{ "address": self.get_address(0), "value": self.manager.get_tokens_issued_per_block(1) - 505 }], "inputs": [{ "tx_id": input_hash, "index": 0 }] } response3 = yield self.web.post("wallet/send_tokens", {'data': data_json2}) data3 = response3.json_value() self.assertTrue(data3['success']) # Sending token to invalid addresses data_json3 = { "outputs": [{ "address": self.get_address(1), "value": 500 }], "inputs": [] } response_error1 = yield self.web.post("wallet/send_tokens", {'data': data_json3}) data_error1 = response_error1.json_value() self.assertFalse(data_error1['success']) data_json4 = { "outputs": [{ "address": "1234", "value": 500 }], "inputs": [] } response_error2 = yield self.web.post("wallet/send_tokens", {'data': data_json4}) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success']) # Error insuficient funds data_json5 = { "outputs": [{ "address": self.get_address(0), "value": 5000000 }], "inputs": [] } response_error3 = yield self.web.post("wallet/send_tokens", {'data': data_json5}) data_error3 = response_error3.json_value() self.assertFalse(data_error3['success']) add_new_blocks(self.manager, 1, advance_clock=1) add_blocks_unlock_reward(self.manager) # Sending token with timelock data_timelock = { "outputs": [{ "address": self.get_address(0), "value": 505, "timelock": 1542995660 }], "inputs": [] } response_timelock = yield self.web.post("wallet/send_tokens", {'data': data_timelock}) data_response_timelock = response_timelock.json_value() self.assertTrue(data_response_timelock['success']) self.reactor.advance(5) # Sending token with timestamp data_timestamp = { "outputs": [{ "address": self.get_address(0), "value": 5 }], "inputs": [], "timestamp": int(self.reactor.seconds()) } response_timestamp = yield self.web.post("wallet/send_tokens", {'data': data_timestamp}) data_response_timestamp = response_timestamp.json_value() self.assertTrue(data_response_timestamp['success']) self.reactor.advance(5) # Sending token with timestamp=0 data_timestamp = { "outputs": [{ "address": self.get_address(0), "value": 5 }], "inputs": [], "timestamp": 0 } response_timestamp = yield self.web.post("wallet/send_tokens", {'data': data_timestamp}) data_response_timestamp = response_timestamp.json_value() self.assertTrue(data_response_timestamp['success']) @inlineCallbacks def test_tx_weight(self): add_new_blocks(self.manager, 3, advance_clock=1) add_blocks_unlock_reward(self.manager) self.reactor.advance(3) # Unlocking wallet self.manager.wallet.unlock(b"MYPASS") self.manager.test_mode = TestMode.DISABLED data_json = { "outputs": [{ "address": self.get_address(0), "value": 505 }], "inputs": [], "weight": 1 } response = yield self.web.post("wallet/send_tokens", {'data': data_json}) data = response.json_value() self.assertFalse(data['success']) def test_error_request(self): resource = SendTokensResource(self.manager) request = TestDummyRequest('POST', 'wallet/send_tokens', {}) self.assertIsNotNone(request._finishedDeferreds) resource._err_tx_resolve('Error', request) self.assertIsNone(request._finishedDeferreds)
class SendTokensTest(_BaseResourceTest._ResourceTest): def setUp(self): super().setUp() self.network = 'testnet' self.manager = self.create_peer(self.network, unlock_wallet=True, wallet_index=True) sendtokens_resource = SendTokensResource(self.manager) sendtokens_resource.sleep_seconds = 0.1 self.web = StubSite(sendtokens_resource) self.web_address_history = StubSite( AddressHistoryResource(self.manager)) @inlineCallbacks def test_post(self): # Unlocking wallet self.manager.wallet.unlock(b'MYPASS') blocks = add_new_blocks(self.manager, 3, advance_clock=1) add_blocks_unlock_reward(self.manager) blocks_tokens = [ sum(txout.value for txout in blk.outputs) for blk in blocks ] self.assertEqual( self.manager.wallet.balance[settings.HATHOR_TOKEN_UID].available, sum(blocks_tokens)) # Options yield self.web.options('thin_wallet/send_tokens') tx_id = blocks[0].hash output = blocks[0].outputs[0] script_type_out = parse_address_script(output.script) address = script_type_out.address private_key = self.manager.wallet.get_private_key(address) output_address = decode_address(self.get_address(0)) value = blocks_tokens[0] o = TxOutput(value, create_output_script(output_address, None)) o_invalid_amount = TxOutput(value - 1, create_output_script(output_address, None)) i = TxInput(tx_id, 0, b'') # wrong weight tx = Transaction(inputs=[i], outputs=[o]) data_to_sign = tx.get_sighash_all() public_key_bytes, signature_bytes = self.manager.wallet.get_input_aux_data( data_to_sign, private_key) i.data = P2PKH.create_input_data(public_key_bytes, signature_bytes) tx.inputs = [i] tx.timestamp = int(self.clock.seconds()) tx.weight = 0 response = yield self.web.post('thin_wallet/send_tokens', {'tx_hex': tx.get_struct().hex()}) data = response.json_value() self.assertFalse(data['success']) # Error wrong amount tx2 = Transaction(inputs=[i], outputs=[o_invalid_amount]) data_to_sign = tx2.get_sighash_all() public_key_bytes, signature_bytes = self.manager.wallet.get_input_aux_data( data_to_sign, private_key) i.data = P2PKH.create_input_data(public_key_bytes, signature_bytes) tx2.inputs = [i] tx2.timestamp = int(self.clock.seconds()) tx2.weight = self.manager.minimum_tx_weight(tx2) response_wrong_amount = yield self.web.post( 'thin_wallet/send_tokens', {'tx_hex': tx2.get_struct().hex()}) data_wrong_amount = response_wrong_amount.json_value() self.assertFalse(data_wrong_amount['success']) # successful tx tx3 = Transaction(inputs=[i], outputs=[o]) data_to_sign = tx3.get_sighash_all() public_key_bytes, signature_bytes = self.manager.wallet.get_input_aux_data( data_to_sign, private_key) i.data = P2PKH.create_input_data(public_key_bytes, signature_bytes) tx3.inputs = [i] tx3.timestamp = int(self.clock.seconds()) tx3.weight = self.manager.minimum_tx_weight(tx3) # Then send tokens response = yield self.web.post('thin_wallet/send_tokens', {'tx_hex': tx3.get_struct().hex()}) data = response.json_value() self.assertTrue(data['success']) # Trying to send a double spending will not have success self.clock.advance(5) tx3.timestamp = int(self.clock.seconds()) response = yield self.web.post('thin_wallet/send_tokens', {'tx_hex': tx3.get_struct().hex()}) data_error = response.json_value() self.assertFalse(data_error['success']) self.clock.advance(5) # Check if tokens were really sent self.assertEqual( self.manager.wallet.balance[settings.HATHOR_TOKEN_UID].available, sum(blocks_tokens[:-1])) response_history = yield self.web_address_history.get( 'thin_wallet/address_history', { b'addresses[]': address.encode(), }) response_data = response_history.json_value()['history'] self.assertIn(data['tx']['hash'], [x['tx_id'] for x in response_data]) # Create token tx tx4 = create_tokens(self.manager, address, mint_amount=100, propagate=False) tx4.nonce = 0 tx4.timestamp = int(self.clock.seconds()) response = yield self.web.post('thin_wallet/send_tokens', {'tx_hex': tx4.get_struct().hex()}) data = response.json_value() self.assertTrue(data['success']) # # TODO these tests were causing timeouts in CI server [yan - 01.04.2019] # TODO add to top imports # from twisted.internet.defer import CancelledError, inlineCallbacks # from twisted.python.failure import Failure # def get_new_tx_struct(weight=0): # tx = Transaction(inputs=[i], outputs=[o]) # tx.inputs = tx3.inputs # self.clock.advance(5) # tx.timestamp = int(self.clock.seconds()) # if weight == 0: # weight = self.manager.minimum_tx_weight(tx) # tx.weight = weight # return tx.get_struct().hex() # # # Making pow threads full # deferreds = [] # for x in range(settings.MAX_POW_THREADS): # d = self.web.post('thin_wallet/send_tokens', {'tx_hex': get_new_tx_struct(50)}) # d.addErrback(lambda err: None) # deferreds.append(d) # # # All threads are in use # response = yield self.web.post('thin_wallet/send_tokens', {'tx_hex': get_new_tx_struct(1)}) # data = response.json_value() # self.assertFalse(data['success']) # # # Releasing one thread # d = deferreds.pop() # d.request.processingFailed(Failure(CancelledError())) # # # Waiting for thread to finish # yield d.request.thread_deferred # # # Now you can send # response = yield self.web.post('thin_wallet/send_tokens', {'tx_hex': get_new_tx_struct(1)}) # data = response.json_value() # self.assertTrue(data['success']) # # # Releasing all other threads # for d in deferreds: # d.request.processingFailed(Failure(CancelledError())) # # # Waiting for all threads to finish # for d in deferreds: # yield d.request.thread_deferred def test_error_request(self): resource = SendTokensResource(self.manager) request = TestDummyRequest('POST', 'thin_wallet/send_tokens', {}) self.assertIsNotNone(request._finishedDeferreds) resource._err_tx_resolve('Error', request) self.assertIsNone(request._finishedDeferreds) @inlineCallbacks def test_token(self): self.manager.wallet.unlock(b'MYPASS') resource = StubSite(TokenResource(self.manager)) # test list of tokens empty response_list1 = yield resource.get('thin_wallet/token') data_list1 = response_list1.json_value() self.assertTrue(data_list1['success']) self.assertEqual(len(data_list1['tokens']), 0) # test invalid token id response = yield resource.get('thin_wallet/token', {b'id': 'vvvv'.encode()}) data = response.json_value() self.assertFalse(data['success']) # test unknown token id unknown_uid = '00000000228ed1dd74a2e1b920c1d64bf81dc63875dce4fac486001073b45a27'.encode( ) response = yield resource.get('thin_wallet/token', {b'id': unknown_uid}) data = response.json_value() self.assertFalse(data['success']) # test success case add_new_blocks(self.manager, 1, advance_clock=1) add_blocks_unlock_reward(self.manager) token_name = 'MyTestToken' token_symbol = 'MTT' amount = 150 tx = create_tokens(self.manager, mint_amount=amount, token_name=token_name, token_symbol=token_symbol, use_genesis=False) token_uid = tx.tokens[0] response = yield resource.get('thin_wallet/token', {b'id': token_uid.hex().encode()}) data = response.json_value() self.assertTrue(data['success']) self.assertEqual(len(data['mint']), 1) self.assertEqual(len(data['melt']), 1) self.assertEqual(data['mint'][0]['tx_id'], tx.hash_hex) self.assertEqual(data['melt'][0]['tx_id'], tx.hash_hex) self.assertEqual(data['mint'][0]['index'], 1) self.assertEqual(data['melt'][0]['index'], 2) self.assertEqual(data['total'], amount) self.assertEqual(data['name'], token_name) self.assertEqual(data['symbol'], token_symbol) # test list of tokens with one token response_list2 = yield resource.get('thin_wallet/token') data_list2 = response_list2.json_value() self.assertTrue(data_list2['success']) self.assertEqual(len(data_list2['tokens']), 1) self.assertEqual(data_list2['tokens'][0]['name'], token_name) self.assertEqual(data_list2['tokens'][0]['symbol'], token_symbol) self.assertEqual(data_list2['tokens'][0]['uid'], tx.hash.hex()) token_name2 = 'New Token' token_symbol2 = 'NTK' tx2 = create_tokens(self.manager, mint_amount=amount, token_name=token_name2, token_symbol=token_symbol2, use_genesis=False) token_name3 = 'Wat Coin' token_symbol3 = 'WTC' tx3 = create_tokens(self.manager, mint_amount=amount, token_name=token_name3, token_symbol=token_symbol3, use_genesis=False) # test list of tokens with 3 tokens response_list3 = yield resource.get('thin_wallet/token') data_list3 = response_list3.json_value() self.assertTrue(data_list3['success']) self.assertEqual(len(data_list3['tokens']), 3) token1 = { 'uid': tx.hash.hex(), 'name': token_name, 'symbol': token_symbol } token2 = { 'uid': tx2.hash.hex(), 'name': token_name2, 'symbol': token_symbol2 } token3 = { 'uid': tx3.hash.hex(), 'name': token_name3, 'symbol': token_symbol3 } self.assertIn(token1, data_list3['tokens']) self.assertIn(token2, data_list3['tokens']) self.assertIn(token3, data_list3['tokens']) # test no wallet index manager2 = self.create_peer(self.network, unlock_wallet=True) resource2 = StubSite(TokenResource(manager2)) response2 = yield resource2.get('thin_wallet/token') data2 = response2.json_value() self.assertEqual(response2.responseCode, 503) self.assertFalse(data2['success']) @inlineCallbacks def test_token_history(self): self.manager.wallet.unlock(b'MYPASS') resource = StubSite(TokenHistoryResource(self.manager)) add_new_blocks(self.manager, 1, advance_clock=1) add_blocks_unlock_reward(self.manager) tx = create_tokens(self.manager, mint_amount=100, token_name='Teste', token_symbol='TST') token_uid = tx.tokens[0] response = yield resource.get('thin_wallet/token_history', { b'id': token_uid.hex().encode(), b'count': 3 }) data = response.json_value() # Success returning the token creation tx self.assertTrue(data['success']) self.assertFalse(data['has_more']) self.assertEqual(1, len(data['transactions'])) self.assertEqual(tx.hash.hex(), data['transactions'][0]['tx_id']) response = yield resource.get('thin_wallet/token_history', { b'id': b'123', b'count': 3 }) data = response.json_value() # Fail because token is unknown self.assertFalse(data['success']) # Create a tx with this token, so we can have more tx in the history output = tx.outputs[0] script_type_out = parse_address_script(output.script) address = script_type_out.address private_key = self.manager.wallet.get_private_key(address) output_address = decode_address(self.get_address(0)) o = TxOutput(100, create_output_script(output_address, None), 1) i = TxInput(tx.hash, 0, b'') tx2 = Transaction(inputs=[i], outputs=[o], tokens=[token_uid]) data_to_sign = tx2.get_sighash_all() public_key_bytes, signature_bytes = self.manager.wallet.get_input_aux_data( data_to_sign, private_key) i.data = P2PKH.create_input_data(public_key_bytes, signature_bytes) tx2.inputs = [i] tx2.timestamp = int(self.clock.seconds()) tx2.weight = self.manager.minimum_tx_weight(tx2) tx2.parents = self.manager.get_new_tx_parents() tx2.resolve() self.manager.propagate_tx(tx2) # Now we have 2 txs with this token response = yield resource.get('thin_wallet/token_history', { b'id': token_uid.hex().encode(), b'count': 3 }) data = response.json_value() # Success returning the token creation tx and newly created tx self.assertTrue(data['success']) self.assertFalse(data['has_more']) self.assertEqual(2, len(data['transactions'])) self.assertEqual(tx2.hash.hex(), data['transactions'][0]['tx_id']) self.assertEqual(tx.hash.hex(), data['transactions'][1]['tx_id']) response = yield resource.get('thin_wallet/token_history', { b'id': token_uid.hex().encode(), b'count': 1 }) data = response.json_value() # Testing has_more self.assertTrue(data['success']) self.assertTrue(data['has_more']) self.assertEqual(1, len(data['transactions'])) response = yield resource.get( 'thin_wallet/token_history', { b'id': token_uid.hex().encode(), b'count': 10, b'page': b'next', b'hash': tx2.hash.hex().encode(), b'timestamp': str(tx2.timestamp).encode(), }) data = response.json_value() # Testing next self.assertTrue(data['success']) self.assertFalse(data['has_more']) self.assertEqual(1, len(data['transactions'])) self.assertEqual(tx.hash.hex(), data['transactions'][0]['tx_id']) response = yield resource.get( 'thin_wallet/token_history', { b'id': token_uid.hex().encode(), b'count': 10, b'page': b'previous', b'hash': tx.hash.hex().encode(), b'timestamp': str(tx.timestamp).encode(), }) data = response.json_value() # Testing previous self.assertTrue(data['success']) self.assertFalse(data['has_more']) self.assertEqual(1, len(data['transactions'])) self.assertEqual(tx2.hash.hex(), data['transactions'][0]['tx_id']) response = yield resource.get( 'thin_wallet/token_history', { b'id': token_uid.hex().encode(), b'count': 10, b'page': b'previous', b'hash': tx2.hash.hex().encode(), b'timestamp': str(tx2.timestamp).encode(), }) data = response.json_value() # Testing previous from first self.assertTrue(data['success']) self.assertFalse(data['has_more']) self.assertEqual(0, len(data['transactions']))