def setUp(self): super().setUp() self.genesis_blocks = [tx for tx in get_genesis_transactions(None) if tx.is_block] self.genesis_txs = [tx for tx in get_genesis_transactions(None) if not tx.is_block] # read genesis keys self.genesis_private_key = get_genesis_key() self.genesis_public_key = self.genesis_private_key.public_key()
def test_new_tx(self): self.factory.connections.add(self.protocol) self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN self.manager.pubsub.publish(HathorEvents.NETWORK_NEW_TX_ACCEPTED, tx=get_genesis_transactions( self.manager.tx_storage)[1]) self.run_to_completion() value = self._decode_value(self.transport.value()) self.assertEqual(value['tx_id'], get_genesis_transactions(None)[1].hash.hex()) self.assertEqual(value['type'], 'network:new_tx_accepted')
def test_input_spent_received(self): self.factory.connections.add(self.protocol) self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN gen_tx = get_genesis_transactions(None)[0] gen_tx2 = get_genesis_transactions(None)[1] spent = SpentTx(gen_tx2.hash, gen_tx.hash, 0, 10, gen_tx.timestamp + 1) self.manager.pubsub.publish(HathorEvents.WALLET_INPUT_SPENT, output_spent=spent) self.run_to_completion() value = self._decode_value(self.transport.value()) self.assertEqual(value['type'], 'wallet:output_spent') self.assertEqual(value['output_spent']['tx_id'], gen_tx2.hash.hex()) self.assertEqual(value['output_spent']['from_tx_id'], gen_tx.hash.hex())
def test_blocks_are_blocked(self): genesis_tx = get_genesis_transactions(self.manager.tx_storage)[0] response_success = yield self.web.get( "transaction_acc_weight", {b'id': bytes(genesis_tx.hash.hex(), 'utf-8')}) data_success = response_success.json_value() self.assertFalse(data_success['success'])
def _create_genesis_cache(self) -> None: from hathor.transaction.genesis import get_genesis_transactions self._genesis_cache = {} assert self._genesis_cache is not None for genesis in get_genesis_transactions(self): assert genesis.hash is not None self._genesis_cache[genesis.hash] = genesis
def test_get_tips(self): genesis_txs = [tx for tx in get_genesis_transactions(self.manager.tx_storage) if not tx.is_block] # Tips are only the genesis response1 = yield self.web.get("tips") data1 = response1.json_value() self.assertEqual(len(data1), len(genesis_txs)) self.manager.wallet.unlock(b'MYPASS') # Add blocks to have funds add_new_blocks(self.manager, 2, advance_clock=1) add_blocks_unlock_reward(self.manager) # Add one tx, now you have only one tip tx = add_new_transactions(self.manager, 1)[0] response2 = yield self.web.get("tips") data2 = response2.json_value() self.assertEqual(len(data2), 1) # Getting tips sending timestamp as parameter response3 = yield self.web.get("tips", {b'timestamp': tx.timestamp - 1}) data3 = response3.json_value() self.assertEqual(len(data3), 2)
def test_genesis_weight(self): genesis_blocks = [tx for tx in get_genesis_transactions(None) if tx.is_block] genesis_block = genesis_blocks[0] genesis_txs = [tx for tx in get_genesis_transactions(None) if not tx.is_block] genesis_tx = genesis_txs[0] network = 'testnet' manager = self.create_peer(network, unlock_wallet=True) # Validate the block and tx weight # in test mode weight is always 1 self.assertEqual(manager.calculate_block_difficulty(genesis_block), 1) self.assertEqual(manager.minimum_tx_weight(genesis_tx), 1) manager.test_mode = TestMode.DISABLED self.assertEqual(manager.calculate_block_difficulty(genesis_block), genesis_block.weight) self.assertEqual(manager.minimum_tx_weight(genesis_tx), genesis_tx.weight)
def test_output(self): # Test if block output is valid genesis = get_genesis_transactions(None) for g in genesis: if g.is_block: for output in g.outputs: self.assertEqual(output.script.hex(), get_genesis_output())
def test_get(self): genesis_tx = get_genesis_transactions(self.manager.tx_storage)[1] response_success = yield self.web.get( "decode_tx", {b'hex_tx': bytes(genesis_tx.get_struct().hex(), 'utf-8')}) data_success = response_success.json_value() self.assertTrue(data_success['success']) data_genesis = genesis_tx.to_json(decode_script=True) data_genesis['raw'] = genesis_tx.get_struct().hex() data_genesis['nonce'] = str(data_genesis['nonce']) self.assertEqual(data_success['tx'], data_genesis) self.assertTrue('meta' in data_success) self.assertTrue('spent_outputs' in data_success) # Invalid hex response_error1 = yield self.web.get("decode_tx", {b'hex_tx': b'XXXX'}) data_error1 = response_error1.json_value() self.assertFalse(data_error1['success']) # Invalid tx hex response_error2 = yield self.web.get("decode_tx", {b'hex_tx': b'a12c'}) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success']) # Token creation tx script_type_out = parse_address_script( get_genesis_transactions( self.manager.tx_storage)[0].outputs[0].script) address = script_type_out.address add_blocks_unlock_reward(self.manager) tx2 = create_tokens(self.manager, address, mint_amount=100, propagate=True) response = yield self.web.get( 'decode_tx', {b'hex_tx': bytes(tx2.get_struct().hex(), 'utf-8')}) data = response.json_value() self.assertTrue(data['success'])
def setUp(self): super().setUp() self.block = get_genesis_transactions(None)[0] self.transport = StringTransportWithDisconnection() self.protocol = StratumClient() self.protocol.makeConnection(self.transport) self.job_request_params = { 'data': self.block.get_header_without_nonce().hex(), 'job_id': 'a734d03fe4b64739be2894742f3de20f', 'nonce_size': Block.SERIALIZATION_NONCE_SIZE, 'weight': self.block.weight, }
def test_output_received(self): self.factory.connections.add(self.protocol) self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN gen_tx = get_genesis_transactions(None)[0] output = UnspentTx(gen_tx.hash, 0, 10, gen_tx.timestamp, '', gen_tx.outputs[0].token_data) self.manager.pubsub.publish(HathorEvents.WALLET_OUTPUT_RECEIVED, total=10, output=output) self.run_to_completion() value = self._decode_value(self.transport.value()) self.assertEqual(value['total'], 10) self.assertEqual(value['type'], 'wallet:output_received') self.assertEqual(value['output']['tx_id'], gen_tx.hash.hex())
def test_separate_inputs(self): block = add_new_block(self.manager, advance_clock=5) my_input = TxInput(block.hash, 0, b'') genesis_blocks = [ tx for tx in get_genesis_transactions(None) if tx.is_block ] genesis_block = genesis_blocks[0] other_input = TxInput(genesis_block.hash, 0, b'') my_inputs, other_inputs = self.manager.wallet.separate_inputs( [my_input, other_input], self.manager.tx_storage) self.assertEqual(len(my_inputs), 1) self.assertEqual(my_inputs[0], my_input) self.assertEqual(len(other_inputs), 1) self.assertEqual(other_inputs[0], other_input)
def setUp(self): super().setUp() # import sys # from twisted.python import log # log.startLogging(sys.stdout) # self.set_random_seed(0) first_timestamp = min(tx.timestamp for tx in get_genesis_transactions(None)) self.clock.advance(first_timestamp + random.randint(3600, 120 * 24 * 3600)) self.network = 'testnet'
def test_get_one(self): genesis_tx = get_genesis_transactions(self.manager.tx_storage)[0] response_success = yield self.web.get( "transaction", {b'id': bytes(genesis_tx.hash.hex(), 'utf-8')}) data_success = response_success.json_value() self.assertTrue(data_success['success']) dict_test = genesis_tx.to_json(decode_script=True) dict_test['raw'] = genesis_tx.get_struct().hex() dict_test['nonce'] = str(dict_test['nonce']) if genesis_tx.is_block: dict_test['height'] = genesis_tx.calculate_height() self.assertEqual(data_success['tx'], dict_test) # Test sending hash that does not exist response_error1 = yield self.web.get( "transaction", { b'id': b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a5533848' }) data_error1 = response_error1.json_value() self.assertFalse(data_error1['success']) # Test sending invalid hash response_error2 = yield self.web.get( "transaction", { b'id': b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a553384' }) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success']) # Adding blocks to have funds add_new_blocks(self.manager, 2, advance_clock=1) add_blocks_unlock_reward(self.manager) tx = add_new_transactions(self.manager, 1)[0] tx2 = Transaction.create_from_struct(tx.get_struct()) tx2.parents = [tx.parents[1], tx.parents[0]] tx2.resolve() self.manager.propagate_tx(tx2) # Now we get a tx with conflict, voided_by and twin response_conflict = yield self.web.get( "transaction", {b'id': bytes(tx2.hash.hex(), 'utf-8')}) data_conflict = response_conflict.json_value() self.assertTrue(data_conflict['success'])
def _reset_cache(self) -> None: """Reset all caches. This function should not be called unless you know what you are doing.""" if not self.with_index: raise NotImplementedError self._cache_block_count = 0 self._cache_tx_count = 0 self.block_index = IndexesManager() self.tx_index = IndexesManager() self.all_index = IndexesManager() self.wallet_index = None self.tokens_index = None self._latest_timestamp = 0 from hathor.transaction.genesis import get_genesis_transactions self._first_timestamp = min(x.timestamp for x in get_genesis_transactions(self))
def is_genesis(self) -> bool: """ Check whether this transaction is a genesis transaction :rtype: bool """ if self.hash is None: return False if self.storage: genesis = self.storage.get_genesis(self.hash) if genesis: return True else: return False else: from hathor.transaction.genesis import get_genesis_transactions for genesis in get_genesis_transactions(self.storage): if self == genesis: return True return False
def test_subscribe_address(self): self.assertEqual(len(self.factory.address_connections), 0) self.protocol.state = HathorAdminWebsocketProtocol.STATE_OPEN # Subscribe to address address = '1Q4qyTjhpUXUZXzwKs6Yvh2RNnF5J1XN9a' payload = json.dumps({ 'type': 'subscribe_address', 'address': address }).encode('utf-8') self.protocol.onMessage(payload, True) self.assertEqual(len(self.factory.address_connections), 1) block_genesis = [ tx for tx in get_genesis_transactions(self.manager.tx_storage) if tx.is_block ][0] # Test publish address history # First clean the transport to make sure the value comes from this execution self.transport.clear() element = block_genesis.to_json_extended() self.manager.pubsub.publish(HathorEvents.WALLET_ADDRESS_HISTORY, address=address, history=element) self.run_to_completion() value = self._decode_value(self.transport.value()) self.assertEqual(value['type'], 'wallet:address_history') self.assertEqual(value['address'], address) self.assertEqual(value['history']['tx_id'], block_genesis.hash_hex) self.assertEqual(value['history']['timestamp'], block_genesis.timestamp) # Publishing with address that was not subscribed must not generate any value in the ws # First clean the transport to make sure the value comes from this execution self.transport.clear() wrong_address = '1Q4qyTjhpUXUZXzwKs6Yvh2RNnF5J1XN9b' self.manager.pubsub.publish(HathorEvents.WALLET_ADDRESS_HISTORY, address=wrong_address, history=element) self.run_to_completion() value = self._decode_value(self.transport.value()) self.assertIsNone(value)
def setUp(self): super().setUp() self.clock = HeapClock() self.set_random_seed(self.seed_config) print('-' * 30) print('Simulation seed config:', self.random_seed) print('-' * 30) def verify_pow(self) -> None: assert self.hash is not None self.old_verify_pow = BaseTransaction.verify_pow BaseTransaction.verify_pow = verify_pow self.network = 'testnet' first_timestamp = min(tx.timestamp for tx in get_genesis_transactions(None)) self.clock.advance(first_timestamp + random.randint(3600, 120 * 24 * 3600))
def test_get_data(self): genesis_tx = get_genesis_transactions(self.manager.tx_storage)[1] response_success = yield self.web.get( "transaction_acc_weight", {b'id': bytes(genesis_tx.hash.hex(), 'utf-8')}) data_success = response_success.json_value() self.assertTrue(data_success['success']) self.assertEqual(data_success['accumulated_weight'], genesis_tx.weight) self.assertEqual(data_success['confirmation_level'], 0) # Adding blocks to have funds add_new_blocks(self.manager, 2, advance_clock=1) add_blocks_unlock_reward(self.manager) tx = add_new_transactions(self.manager, 5)[0] add_new_blocks(self.manager, 2, advance_clock=1) add_blocks_unlock_reward(self.manager) response_success2 = yield self.web.get( "transaction_acc_weight", {b'id': bytes(tx.hash.hex(), 'utf-8')}) data_success2 = response_success2.json_value() self.assertGreater(data_success2['accumulated_weight'], tx.weight) self.assertEqual(data_success2['confirmation_level'], 1) # Test sending hash that does not exist response_error1 = yield self.web.get( "transaction_acc_weight", { b'id': b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a5533848' }) data_error1 = response_error1.json_value() self.assertFalse(data_error1['success']) # Test sending invalid hash response_error2 = yield self.web.get( "transaction_acc_weight", { b'id': b'000000831cff82fa730cbdf8640fae6c130aab1681336e2f8574e314a553384' }) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success'])
def test_checkmultisig(self): with self.assertRaises(MissingStackItems): op_checkmultisig([], log=[], extras=None) block = [x for x in get_genesis_transactions(None) if x.is_block][0] from hathor.transaction import Transaction, TxInput, TxOutput txin = TxInput(tx_id=block.hash, index=0, data=b'') txout = TxOutput(value=block.outputs[0].value, script=b'') tx = Transaction(inputs=[txin], outputs=[txout]) data_to_sign = tx.get_sighash_all() extras = ScriptExtras(tx=tx, txin=None, spent_tx=None) wallet = HDWallet() wallet._manually_initialize() wallet.words = wallet.mnemonic.generate() wallet._manually_initialize() keys_count = 3 keys = [] for i in range(keys_count): privkey = list(wallet.keys.values())[i] keys.append({ 'privkey': privkey, 'pubkey': privkey.sec(), 'signature': wallet.get_input_aux_data(data_to_sign, privkey)[1] }) wrong_privkey = list(wallet.keys.values())[3] wrong_key = { 'privkey': wrong_privkey, 'pubkey': wrong_privkey.sec(), 'signature': wallet.get_input_aux_data(data_to_sign, wrong_privkey)[1] } # All signatures match stack = [ keys[0]['signature'], keys[2]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3 ] op_checkmultisig(stack, log=[], extras=extras) self.assertEqual(1, stack.pop()) # New set of valid signatures stack = [ keys[0]['signature'], keys[1]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3 ] op_checkmultisig(stack, log=[], extras=extras) self.assertEqual(1, stack.pop()) # Changing the signatures but they match stack = [ keys[1]['signature'], keys[2]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3 ] op_checkmultisig(stack, log=[], extras=extras) self.assertEqual(1, stack.pop()) # Signatures are valid but in wrong order stack = [ keys[1]['signature'], keys[0]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3 ] op_checkmultisig(stack, log=[], extras=extras) self.assertEqual(0, stack.pop()) # Adding wrong signature, so we get error stack = [ keys[0]['signature'], wrong_key['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3 ] op_checkmultisig(stack, log=[], extras=extras) self.assertEqual(0, stack.pop()) # Adding same signature twice, so we get error stack = [ keys[0]['signature'], keys[0]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3 ] op_checkmultisig(stack, log=[], extras=extras) self.assertEqual(0, stack.pop()) # Adding less signatures than required, so we get error stack = [keys[0]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3] with self.assertRaises(MissingStackItems): op_checkmultisig(stack, log=[], extras=extras) # Quantity of signatures is more than it should stack = [ keys[0]['signature'], keys[1]['signature'], 3, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3 ] with self.assertRaises(MissingStackItems): op_checkmultisig(stack, log=[], extras=extras) # Quantity of pubkeys is more than it should stack = [ keys[0]['signature'], keys[1]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 4 ] with self.assertRaises(InvalidStackData): op_checkmultisig(stack, log=[], extras=extras) # Exception pubkey_count should be integer stack = [ keys[0]['signature'], keys[1]['signature'], 2, keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], '3' ] with self.assertRaises(InvalidStackData): op_checkmultisig(stack, log=[], extras=extras) # Exception not enough pub keys stack = [keys[0]['pubkey'], keys[1]['pubkey'], 3] with self.assertRaises(MissingStackItems): op_checkmultisig(stack, log=[], extras=extras) # Exception stack empty after pubkeys stack = [keys[0]['pubkey'], keys[1]['pubkey'], keys[2]['pubkey'], 3] with self.assertRaises(MissingStackItems): op_checkmultisig(stack, log=[], extras=extras)
def test_wallet_create_transaction(self): genesis_private_key_bytes = get_private_key_bytes( self.genesis_private_key, encryption_algorithm=serialization.BestAvailableEncryption( PASSWORD)) genesis_address = get_address_b58_from_public_key( self.genesis_public_key) # create wallet with genesis block key key_pair = KeyPair(private_key_bytes=genesis_private_key_bytes, address=genesis_address, used=True) keys = {} keys[key_pair.address] = key_pair w = Wallet(keys=keys, directory=self.directory) w.unlock(PASSWORD) genesis_blocks = [ tx for tx in get_genesis_transactions(None) if tx.is_block ] genesis_block = genesis_blocks[0] genesis_value = sum([output.value for output in genesis_block.outputs]) # wallet will receive genesis block and store in unspent_tx w.on_new_tx(genesis_block) for index in range(len(genesis_block.outputs)): utxo = w.unspent_txs[settings.HATHOR_TOKEN_UID].get( (genesis_block.hash, index)) self.assertIsNotNone(utxo) self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, genesis_value)) # create transaction spending this value, but sending to same wallet new_address = w.get_unused_address() out = WalletOutputInfo(decode_address(new_address), 100, timelock=None) tx1 = w.prepare_transaction_compute_inputs(Transaction, outputs=[out]) tx1.storage = self.storage tx1.update_hash() self.storage.save_transaction(tx1) w.on_new_tx(tx1) self.assertEqual(len(w.spent_txs), 1) self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, genesis_value)) # pass inputs and outputs to prepare_transaction, but not the input keys # spend output last transaction input_info = WalletInputInfo(tx1.hash, 1, None) new_address = w.get_unused_address() key2 = w.keys[new_address] out = WalletOutputInfo(decode_address(key2.address), 100, timelock=None) tx2 = w.prepare_transaction_incomplete_inputs(Transaction, inputs=[input_info], outputs=[out], tx_storage=self.storage) tx2.storage = self.storage tx2.update_hash() self.storage.save_transaction(tx2) w.on_new_tx(tx2) self.assertEqual(len(w.spent_txs), 2) self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, genesis_value)) # test keypair exception with self.assertRaises(WalletLocked): key_pair.get_private_key(None)
def test_pow(self): genesis = get_genesis_transactions(None) for g in genesis: self.assertEqual(g.calculate_hash(), g.hash) self.assertIsNone(g.verify_pow())
def test_verify(self): genesis = get_genesis_transactions(None) for g in genesis: g.verify_without_storage()
def test_genesis_tokens(self): genesis_blocks = [tx for tx in get_genesis_transactions(None) if tx.is_block] genesis_block = genesis_blocks[0] self.assertEqual(settings.GENESIS_TOKENS, sum([output.value for output in genesis_block.outputs]))
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)) 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 get_genesis_transactions(None) 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'])
def test_get(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')}) # Unlocking wallet self.manager.wallet.unlock(b'MYPASS') # Creating a valid transaction to be pushed to the network blocks = add_new_blocks(self.manager, 3, advance_clock=2) add_blocks_unlock_reward(self.manager) 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 = self.manager.get_tokens_issued_per_block(1) o = TxOutput(value, create_output_script(output_address, None)) i = TxInput(tx_id, 0, b'') 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 = self.manager.minimum_tx_weight(tx) tx.parents = self.manager.get_new_tx_parents(tx.timestamp) tx.resolve() response = yield self.web.get( 'push_tx', {b'hex_tx': bytes(tx.get_struct().hex(), 'utf-8')}) data = response.json_value() self.assertTrue(data['success']) # Sending token to random address without input data_json = { 'outputs': [{ 'address': self.get_address(0), 'value': 5 }], 'inputs': [] } yield self.web_tokens.post('wallet/send_tokens', {'data': data_json}) # modify tx so it will be a double spending, then rejected tx.weight += 0.1 tx.resolve() response_success = yield self.web.get( 'push_tx', {b'hex_tx': bytes(tx.get_struct().hex(), 'utf-8')}) data_success = response_success.json_value() self.assertFalse(data_success['success']) # Invalid tx (don't have inputs) genesis_tx = get_genesis_transactions(self.manager.tx_storage)[1] response_genesis = yield self.web.get( 'push_tx', {b'hex_tx': bytes(genesis_tx.get_struct().hex(), 'utf-8')}) data_genesis = response_genesis.json_value() self.assertFalse(data_genesis['success']) # Invalid hex response_error1 = yield self.web.get('push_tx', {b'hex_tx': b'XXXX'}) data_error1 = response_error1.json_value() self.assertFalse(data_error1['success']) # Invalid tx hex response_error2 = yield self.web.get('push_tx', {b'hex_tx': b'a12c'}) data_error2 = response_error2.json_value() self.assertFalse(data_error2['success']) # Token creation tx tx2 = create_tokens(self.manager, address, mint_amount=100, propagate=False) response = yield self.web.get( 'push_tx', {b'hex_tx': bytes(tx2.get_struct().hex(), 'utf-8')}) data = response.json_value() self.assertTrue(data['success'])