def test_hash_origin_case_v2(self): request = r'''{ "jsonrpc": "2.0", "method": "icx_sendTransaction", "id": 1234, "params": { "from": "hxbe258ceb872e08851f1f59694dac2558708ece11", "to": "hx5bfdb090f43a808005ffc27c25b213145e80b7cd", "value": "0xde0b6b3a7640000", "fee": "0x1000000", "timestamp": "1000000000000", "nonce": "0x1", "tx_hash": "a247a97a23398daccb66e2d61d63788b3c2edb91e1fdbb4f34d86d485eb72915", "signature": "VAia7YZ2Ji6igKWzjR2YsGa2m53nKPrfK7uXYW78QLE+ATehAVZPC40szvAiA6NEU5gCYB4c4qaQzqDh2ugcHgA=" } }''' logging.info(f"request : {request}") request = json.loads(request) logging.info(f"request loaded : {request}") question = request["params"] answer = "icx_sendTransaction.fee.0x1000000.from.hxbe258ceb872e08851f1f59694dac2558708ece11.nonce.0x1." \ "timestamp.1000000000000.to.hx5bfdb090f43a808005ffc27c25b213145e80b7cd." \ "value.0xde0b6b3a7640000" tv = TransactionVersioner() version, type_ = tv.get_version(question) ts = TransactionSerializer.new(version, type_, tv) tx = ts.from_(question) result = self.hash_generator.generate_salted_origin(ts.to_origin_data(tx)) self.assertEqual(result, answer)
def test_hash_case_v3_null(self): request = r'''{ "jsonrpc": "2.0", "method": "icx_sendTransaction", "id": 1234, "params": { "version": "0x3", "from": "hxbe258ceb872e08851f1f59694dac2558708ece11", "to": "cxb0776ee37f5b45bfaea8cff1d8232fbb6122ec32", "stepLimit": "0x12345", "timestamp": "0x563a6cf330136", "nid": "0x1", "nonce": "0x1", "signature": "VAia7YZ2Ji6igKWzjR2YsGa2m53nKPrfK7uXYW78QLE+ATehAVZPC40szvAiA6NEU5gCYB4c4qaQzqDh2ugcHgA=", "dataType": "call", "data": { "method": "transfer", "params": { "to": "hxab2d8215eab14bc6bdd8bfb2c8151257032ecd8b", "value": "0x1", "array0": [ null, null ], "array1": [ { "hash": null, "value": null }, { "hash": null, "value": "0x78" } ] } } } }''' logging.info(f"request : {request}") request = json.loads(request) logging.info(f"request loaded : {request}") question = request["params"] answer = r"icx_sendTransaction.data.{method.transfer.params." \ r"{array0.[\0.\0].array1.[{hash.\0.value.\0}.{hash.\0.value.0x78}]." \ r"to.hxab2d8215eab14bc6bdd8bfb2c8151257032ecd8b.value.0x1}}." \ r"dataType.call.from.hxbe258ceb872e08851f1f59694dac2558708ece11.nid.0x1.nonce.0x1.stepLimit.0x12345." \ r"timestamp.0x563a6cf330136.to.cxb0776ee37f5b45bfaea8cff1d8232fbb6122ec32.version.0x3" tv = TransactionVersioner() version, type_ = tv.get_version(question) ts = TransactionSerializer.new(version, type_, tv) tx = ts.from_(question) result = self.hash_generator.generate_salted_origin(ts.to_origin_data(tx)) logging.info(f"result : {result}") self.assertEqual(result, answer)
def tx_versioner(): hash_versions = { "genesis": 0, "0x2": 1, "0x3": 1 } tx_versioner = TransactionVersioner() for tx_version, tx_hash_version in hash_versions.items(): tx_versioner.hash_generator_versions[tx_version] = tx_hash_version return tx_versioner
def __get_test_block(): block_builder = BlockBuilder.new("0.1a", TransactionVersioner()) block_builder.height = 0 block_builder.prev_hash = None block = block_builder.build( ) # It does not have commit state. It will be rebuilt. return block
def test_valid_timestamp(self): """Test for timestamp buffer in block verifier""" def block_maker(timestamp: int, height: int = 0, prev_hash=None): """Make dummy block""" tx_versioner = TransactionVersioner() dummy_receipts = {} block_builder = BlockBuilder.new("0.1a", tx_versioner) for i in range(1000): tx_builder = TransactionBuilder.new("0x3", None, tx_versioner) tx_builder.signer = test_signer tx_builder.to_address = ExternalAddress.new() tx_builder.step_limit = random.randint(0, 10000) tx_builder.value = random.randint(0, 10000) tx_builder.nid = 2 tx = tx_builder.build() tx_serializer = TransactionSerializer.new(tx.version, tx.type(), tx_versioner) block_builder.transactions[tx.hash] = tx dummy_receipts[tx.hash.hex()] = { "dummy_receipt": "dummy", "tx_dumped": tx_serializer.to_full_data(tx) } block_builder.signer = test_signer block_builder.prev_hash = prev_hash block_builder.height = height block_builder.state_hash = Hash32(bytes(Hash32.size)) block_builder.receipts = dummy_receipts block_builder.reps = [ExternalAddress.fromhex_address(test_signer.address)] block_builder.peer_id = ExternalAddress.fromhex(test_signer.address) block_builder.next_leader = ExternalAddress.fromhex(test_signer.address) block_builder.fixed_timestamp = timestamp b = block_builder.build() assert b.header.timestamp == timestamp return b test_signer = Signer.from_prikey(os.urandom(32)) first_block = block_maker(height=0, timestamp=utils.get_time_stamp()) second_block = block_maker(height=1, timestamp=utils.get_time_stamp() + 5, prev_hash=first_block.header.hash) third_block_from_far_future = block_maker(height=2, prev_hash=second_block.header.hash, timestamp=utils.get_time_stamp() + conf.TIMESTAMP_BUFFER_IN_VERIFIER + 5_000_000) block_verifier = BlockVerifier.new("0.1a", TransactionVersioner()) leader = first_block.header.peer_id reps = [ExternalAddress.fromhex_address(test_signer.address)] print("*---Normal time range") block_verifier.verify(block=second_block, prev_block=first_block, blockchain=None, generator=leader, reps=reps) print("*---Abnormal time range") with self.assertRaises(Exception): block_verifier.verify(block=third_block_from_far_future, prev_block=second_block, blockchain=None, generator=leader, reps=reps)
def test_size_attribute_has_set_correctly(self, tx_factory: 'TxFactory', tx_version: str): from loopchain.blockchain.transactions.transaction import _size_attr_name_ print("tx_fac:", tx_factory) tx = tx_factory(tx_version) assert not hasattr(tx, _size_attr_name_) tx.size(versioner=TransactionVersioner()) assert getattr(tx, _size_attr_name_)
def create_basic_tx(peer_auth: Signer) -> Transaction: """ :param peer_auth: :return: transaction """ tx_builder = TransactionBuilder.new("0x3", TransactionVersioner()) tx_builder.private_key = peer_auth._private_key tx_builder.to_address = Address( "hx3f376559204079671b6a8df481c976e7d51b3c7c") tx_builder.value = 1 tx_builder.step_limit = 100000000 tx_builder.nid = 3 return tx_builder.build()
def tx_items(request, tx_item) -> List[Tuple[Transaction, TransactionVersioner]]: tx_versioner = TransactionVersioner() tx_params = [] tx_count = request.param Logger.info(f"tx_count : {request.param}") for i in range(tx_count): tx: Transaction = tx_item(tx_versioner) # Logger.info(f"tx : {tx.raw_data}") tx_params.append((tx, tx_versioner)) return tx_params
def test_tx_message_queue_thread_safe_maxsize(self, tx_items: List[Tuple[Transaction, TransactionVersioner]], tx_item: Callable[[TransactionVersioner], Transaction]): # given maxsize 2 assert_count = {'produce_count': 150, 'consume_count': 0} queue = TxMessagesQueue(maxsize=2, max_tx_size=10 * 1024, max_tx_count=21) tx_versioner = TransactionVersioner() init_tx_count = len(tx_items) for tx_param in tx_items: init_tx_item = TxItem.create_tx_item(tx_param, 'icon_dex') queue.append(init_tx_item) # when produce new tx_item and consume tx_messages from queue def producer(): for _ in range(assert_count.get('produce_count') - init_tx_count): tx = tx_item(tx_versioner) p_tx_item = TxItem.create_tx_item((tx, tx_versioner), 'icon_dex') queue.append(p_tx_item) Logger.info(f"producer() : queue = {queue}") def consumer(): while True: tx_messages = queue.pop() assert_count['consume_count'] += len(tx_messages) Logger.info(f"consumer() : queue = {queue}, tx_messages({id(tx_messages)})") Logger.info(f"consume_count : {assert_count['consume_count']}") if queue.empty() and not thread_producer.is_alive(): break time.sleep(0.03) thread_producer = threading.Thread(target=producer) thread_consumer = threading.Thread(target=consumer, args=()) thread_producer.start() thread_consumer.start() thread_producer.join() thread_consumer.join() # then assert assert_count.get('consume_count') == assert_count.get('produce_count')
def block_maker(timestamp: int, height: int = 0, prev_hash=None): """Make dummy block""" tx_versioner = TransactionVersioner() dummy_receipts = {} block_builder = BlockBuilder.new("0.1a", tx_versioner) for i in range(1000): tx_builder = TransactionBuilder.new("0x3", None, tx_versioner) tx_builder.signer = test_signer tx_builder.to_address = ExternalAddress.new() tx_builder.step_limit = random.randint(0, 10000) tx_builder.value = random.randint(0, 10000) tx_builder.nid = 2 tx = tx_builder.build() tx_serializer = TransactionSerializer.new( tx.version, tx.type(), tx_versioner) block_builder.transactions[tx.hash] = tx dummy_receipts[tx.hash.hex()] = { "dummy_receipt": "dummy", "tx_dumped": tx_serializer.to_full_data(tx) } block_builder.signer = test_signer block_builder.prev_hash = prev_hash block_builder.height = height block_builder.state_hash = Hash32(bytes(Hash32.size)) block_builder.receipts = dummy_receipts block_builder.reps = [ ExternalAddress.fromhex_address(test_signer.address) ] block_builder.peer_id = ExternalAddress.fromhex( test_signer.address) block_builder.next_leader = ExternalAddress.fromhex( test_signer.address) block_builder.fixed_timestamp = timestamp b = block_builder.build() assert b.header.timestamp == timestamp return b
def test_block_v0_4(self): block_version = "0.4" test_signer = Signer.from_prikey(os.urandom(32)) tx_versioner = TransactionVersioner() dummy_receipts = {} block_builder = BlockBuilder.new(block_version, tx_versioner) for i in range(5): tx_builder = TransactionBuilder.new("0x3", None, tx_versioner) tx_builder.signer = test_signer tx_builder.to_address = ExternalAddress.new() tx_builder.step_limit = random.randint(0, 10000) tx_builder.value = random.randint(0, 10000) tx_builder.nid = 2 tx = tx_builder.build() tx_serializer = TransactionSerializer.new(tx.version, tx.type(), tx_versioner) block_builder.transactions[tx.hash] = tx dummy_receipts[tx.hash.hex()] = { "dummy_receipt": "dummy", "tx_dumped": tx_serializer.to_full_data(tx) } next_leader = ExternalAddress.fromhex( "hx00112233445566778899aabbccddeeff00112233") block_builder.signer = test_signer block_builder.height = 0 block_builder.prev_hash = Hash32(bytes(Hash32.size)) block_builder.state_hash = Hash32(bytes(Hash32.size)) block_builder.receipts = dummy_receipts block_builder.reps = [ ExternalAddress.fromhex_address(test_signer.address) ] block_builder.next_leader = next_leader block_builder.next_reps = [] vote = BlockVote.new(test_signer, utils.get_time_stamp(), block_builder.height - 1, 0, block_builder.prev_hash) votes = BlockVotes(block_builder.reps, conf.VOTING_RATIO, block_builder.height - 1, 0, block_builder.prev_hash) votes.add_vote(vote) block_builder.prev_votes = votes.votes block = block_builder.build() block_verifier = BlockVerifier.new(block_version, tx_versioner) block_verifier.invoke_func = lambda b, prev_b: (block, dummy_receipts) reps_getter = lambda _: block_builder.reps generator = ExternalAddress.fromhex_address(test_signer.address) block_verifier.verify(block, None, None, generator=generator, reps_getter=reps_getter) block_serializer = BlockSerializer.new(block_version, tx_versioner) block_serialized = block_serializer.serialize(block) logging.info(json.dumps(block_serialized, indent=4)) block_deserialized = block_serializer.deserialize(block_serialized) logging.info( json.dumps(block_serializer.serialize(block_deserialized), indent=4)) assert block.header == block_deserialized.header assert block.body == block_deserialized.body tx_hashes = list(block.body.transactions) tx_index = random.randrange(0, len(tx_hashes)) block_prover = BlockProver.new(block.header.version, tx_hashes, BlockProverType.Transaction) tx_proof = block_prover.get_proof(tx_index) assert block_prover.prove(tx_hashes[tx_index], block.header.transactions_hash, tx_proof) block_prover = BlockProver.new(block.header.version, block_builder.receipts, BlockProverType.Receipt) receipt_proof = block_prover.get_proof(tx_index) receipts_hash = block_prover.to_hash32( block_builder.receipts[tx_index]) assert block_prover.prove(receipts_hash, block.header.receipts_hash, receipt_proof)
def test_hash_case_v2_v3_compatibility(self): # These methods are obsolete. # But this one and new one must have same results for v2 request. def create_origin_for_hash(json_data: dict): def gen_origin_str(json_data: dict): ordered_keys = list(json_data) ordered_keys.sort() for key in ordered_keys: yield key if isinstance(json_data[key], str): yield json_data[key] elif isinstance(json_data[key], dict): yield from gen_origin_str(json_data[key]) elif isinstance(json_data[key], int): yield str(json_data[key]) else: raise TypeError(f"{key} must be one of them(dict, str, int).") origin = ".".join(gen_origin_str(json_data)) return origin def generate_icx_hash(icx_origin_data, tx_hash_key): copy_tx = copy.deepcopy(icx_origin_data) if 'method' in copy_tx: del copy_tx['method'] if 'signature' in copy_tx: del copy_tx['signature'] if tx_hash_key in copy_tx: del copy_tx[tx_hash_key] origin = create_origin_for_hash(copy_tx) origin = f"icx_sendTransaction.{origin}" # gen hash return hashlib.sha3_256(origin.encode()).digest() request = r'''{ "jsonrpc": "2.0", "method": "icx_sendTransaction", "id": 1234, "params": { "version": "0x3", "from": "hxbe258ceb872e08851f1f59694dac2558708ece11", "to": "hx5bfdb090f43a808005ffc27c25b213145e80b7cd", "value": "0xde0b6b3a7640000", "timestamp": "0x563a6cf330136", "nonce": "0x1", "stepLimit": "0x100000", "nid": "0x2", "signature": "VAia7YZ2Ji6igKWzjR2YsGa2m53nKPrfK7uXYW78QLE+ATehAVZPC40szvAiA6NEU5gCYB4c4qaQzqDh2ugcHgA=" } }''' logging.info(f"request : {request}") request = json.loads(request) logging.info(f"request loaded : {request}") question = request["params"] tv = TransactionVersioner() version, type_ = tv.get_version(question) ts = TransactionSerializer.new(version, type_, tv) tx = ts.from_(question) result_new_hash = self.hash_generator.generate_hash(ts.to_origin_data(tx)) result_old_hash = generate_icx_hash(question, "tx_hash") self.assertEqual(result_new_hash, result_old_hash) v0_hash_generator = build_hash_generator(0, "icx_sendTransaction") result_old_hash = v0_hash_generator.generate_hash(ts.to_origin_data(tx)) self.assertEquals(result_new_hash, result_old_hash)
def tx_versioner(self) -> TransactionVersioner: return TransactionVersioner()
return client @pytest.mark.parametrize("rest_method", RestMethod) def test_url(self, rest_client: RestClient, rest_method: RestMethod): url = rest_client.create_url(rest_client._target, rest_method) assert url == request_urls[rest_method] @pytest.mark.parametrize("rest_method", RestMethod) def test_params(self, rest_client: RestClient, rest_method: RestMethod): params = rest_client.create_params(rest_method, request_params[rest_method]) params.pop('id', None) assert params == request_params_results[rest_method] tv = TransactionVersioner() tb = TransactionBuilder.new(version="0x2", type_=None, versioner=tv) tb.signer = Signer.new() tb.to_address = ExternalAddress(os.urandom(20)) tb.fee = 10 tb.value = 1000 tb.nonce = 123 request_tx2 = tb.build() request_tx2_param = TransactionSerializer.new("0x2", None, tv).to_raw_data(request_tx2) request_tx2_param["from_"] = request_tx2_param.pop("from") tb = TransactionBuilder.new(version="0x3", type_=None, versioner=tv) tb.step_limit = 1000000 tb.value = 100000 tb.signer = Signer.new()
def setUp(self): test_util.print_testname(self._testMethodName) self.signer = Signer.from_prikey(os.urandom(32)) self.tx_versioner = TransactionVersioner() self.tx_versioner.hash_generator_versions["0x2"] = 0
class TestTransaction(unittest.TestCase): def setUp(self): test_util.print_testname(self._testMethodName) self.signer = Signer.from_prikey(os.urandom(32)) self.tx_versioner = TransactionVersioner() self.tx_versioner.hash_generator_versions["0x2"] = 0 def test_transaction_genesis(self): tb = TransactionBuilder.new("genesis", None, self.tx_versioner) tb.accounts = [{ "name": "test0", "address": ExternalAddress(os.urandom(20)).hex_hx(), "balance": "0x12221231" }] tb.message = "Icon Loop" tx = tb.build(False) tv = TransactionVerifier.new("genesis", tx.type(), self.tx_versioner) tv.verify(tx) ts = TransactionSerializer.new("genesis", tx.type(), self.tx_versioner) tx_raw_data = ts.to_raw_data(tx) self.assertEqual(ts.from_(tx_raw_data), tx) def test_transaction_v2(self): tb = TransactionBuilder.new("0x2", None, self.tx_versioner) tb.fee = 1000000 tb.value = 100000 tb.signer = self.signer tb.to_address = ExternalAddress(os.urandom(20)) tb.nonce = random.randint(0, 100000) tx = tb.build() tv = TransactionVerifier.new("0x2", tx.type(), self.tx_versioner) tv.verify(tx) ts = TransactionSerializer.new("0x2", tx.type(), self.tx_versioner) tx_raw_data = ts.to_raw_data(tx) self.assertEqual(ts.from_(tx_raw_data), tx) def test_transaction_v3(self): tb = TransactionBuilder.new("0x3", None, self.tx_versioner) tb.step_limit = 1000000 tb.value = 100000 tb.signer = self.signer tb.to_address = ExternalAddress(os.urandom(20)) tb.nid = 3 tb.nonce = random.randint(0, 100000) tb.data = "test" tb.data_type = "message" tx = tb.build() tv = TransactionVerifier.new("0x3", tx.type(), self.tx_versioner) tv.verify(tx) ts = TransactionSerializer.new("0x3", tx.type(), self.tx_versioner) tx_raw_data = ts.to_raw_data(tx) self.assertEqual(ts.from_(tx_raw_data), tx) def test_transaction_v2_unsigned(self): signer = Signer.new() tb = TransactionBuilder.new("0x2", None, self.tx_versioner) tb.fee = 1000000 tb.value = 100000 tb.from_address = ExternalAddress.fromhex_address(signer.address) tb.to_address = ExternalAddress(os.urandom(20)) tb.nonce = random.randint(0, 100000) tx = tb.build(is_signing=False) tv = TransactionVerifier.new("0x2", tx.type(), self.tx_versioner) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.verify(tx)) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.pre_verify(tx)) tb.signer = signer signed_tx = tb.sign_transaction(tx) tv.verify(signed_tx) tv.pre_verify(signed_tx) def test_transaction_v3_unsigned(self): signer = Signer.new() tb = TransactionBuilder.new("0x3", None, self.tx_versioner) tb.step_limit = 1000000 tb.value = 100000 tb.from_address = ExternalAddress.fromhex_address(signer.address) tb.to_address = ExternalAddress(os.urandom(20)) tb.nid = 3 tb.nonce = random.randint(0, 100000) tb.data = "test" tb.data_type = "message" tx = tb.build(False) tv = TransactionVerifier.new("0x3", tx.type(), self.tx_versioner) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.verify(tx)) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.pre_verify(tx, nid=3)) tb.signer = signer signed_tx = tb.sign_transaction(tx) tv.verify(signed_tx) tv.pre_verify(signed_tx, nid=3) def test_transaction_v2_invalid_hash0(self): # noinspection PyDictCreation tx_dumped = { 'from': 'hx48cd6eb32339d5c719dcc0af21e9bc3b67d733e6', 'to': 'hx22f72e44141bedd50d1e536455682863d3d8a484', 'value': '0x186a0', 'fee': '0xf4240', 'timestamp': '1558679280067963', 'nonce': '1', 'tx_hash': '34477b3bc76fa73aad0258ba9fd36f28a3c4b26956c1e5eb92ddda7d98df4e32', # valid hash 'signature': 'W/hW/PAo+ExeSsreD//yJVgNqmnkWKs+m0VUqE11O7Ek82yEINuczLRXtj1k515q8Ep4OLsRPPiPNjDM9vuhsgE=' } tx_dumped['tx_hash'] = os.urandom(32).hex() # invalid hash tx_version, tx_type = self.tx_versioner.get_version(tx_dumped) ts = TransactionSerializer.new(tx_version, tx_type, self.tx_versioner) tx = ts.from_(tx_dumped) tv = TransactionVerifier.new(tx_version, tx_type, self.tx_versioner) self.assertRaises(TransactionInvalidHashError, lambda: tv.verify(tx)) self.assertRaises(TransactionInvalidHashError, lambda: tv.pre_verify(tx)) def test_transaction_v2_invalid_hash1(self): # noinspection PyDictCreation tx_dumped = { 'from': 'hx48cd6eb32339d5c719dcc0af21e9bc3b67d733e6', 'to': 'hx22f72e44141bedd50d1e536455682863d3d8a484', 'value': '0x186a0', 'fee': '0xf4240', 'timestamp': '1558679280067963', 'nonce': '1', 'tx_hash': '34477b3bc76fa73aad0258ba9fd36f28a3c4b26956c1e5eb92ddda7d98df4e32', 'signature': 'W/hW/PAo+ExeSsreD//yJVgNqmnkWKs+m0VUqE11O7Ek82yEINuczLRXtj1k515q8Ep4OLsRPPiPNjDM9vuhsgE=' } tx_dumped['value'] = hex(int(random.randrange(1, 100))) # invalid value tx_version, tx_type = self.tx_versioner.get_version(tx_dumped) ts = TransactionSerializer.new(tx_version, tx_type, self.tx_versioner) tx = ts.from_(tx_dumped) tv = TransactionVerifier.new(tx_version, tx_type, self.tx_versioner) self.assertRaises(TransactionInvalidHashError, lambda: tv.verify(tx)) self.assertRaises(TransactionInvalidHashError, lambda: tv.pre_verify(tx)) def test_transaction_v2_invalid_signature(self): # noinspection PyDictCreation tx_dumped = { 'from': 'hx48cd6eb32339d5c719dcc0af21e9bc3b67d733e6', 'to': 'hx22f72e44141bedd50d1e536455682863d3d8a484', 'value': '0x186a0', 'fee': '0xf4240', 'timestamp': '1558679280067963', 'nonce': '1', 'tx_hash': '34477b3bc76fa73aad0258ba9fd36f28a3c4b26956c1e5eb92ddda7d98df4e32', # valid hash 'signature': 'W/hW/PAo+ExeSsreD//yJVgNqmnkWKs+m0VUqE11O7Ek82yEINuczLRXtj1k515q8Ep4OLsRPPiPNjDM9vuhsgE=' } tx_dumped['signature'] = Signature(os.urandom( Signature.size)).to_base64str() # invalid signature tx_version, tx_type = self.tx_versioner.get_version(tx_dumped) ts = TransactionSerializer.new(tx_version, tx_type, self.tx_versioner) tx = ts.from_(tx_dumped) tv = TransactionVerifier.new(tx_version, tx_type, self.tx_versioner) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.verify(tx)) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.pre_verify(tx)) def test_transaction_v3_invalid_signature(self): # noinspection PyDictCreation tx_dumped = { 'version': '0x3', 'from': 'hx48cd6eb32339d5c719dcc0af21e9bc3b67d733e6', 'to': 'hxe0a231fa5c80e45f51d7df5f7d127954320df829', 'stepLimit': '0xf4240', 'timestamp': '0x5899c717f92f8', 'nid': '0x3', 'value': '0x186a0', 'nonce': '0x64', 'data': 'test', 'dataType': 'message', 'signature': 'J84KdBtQR4w1bcBdBGF8g6aNoCXjsY/5T6vGV4RXeMwEvafj9xVRDVjzF+vN1JVYvXrAzjlYPCiiBXBQe6+tRAE=' } tx_dumped['signature'] = Signature(os.urandom( Signature.size)).to_base64str() # invalid signature tx_version, tx_type = self.tx_versioner.get_version(tx_dumped) ts = TransactionSerializer.new(tx_version, tx_type, self.tx_versioner) tx = ts.from_(tx_dumped) tv = TransactionVerifier.new(tx_version, tx_type, self.tx_versioner) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.verify(tx)) self.assertRaises(TransactionInvalidSignatureError, lambda: tv.pre_verify(tx, nid=3)) def test_transaction_v3_invalid_nid(self): MockBlockchain = namedtuple("MockBlockchain", "find_nid find_tx_by_key") nids = list(range(0, 1000)) random.shuffle(nids) tb = TransactionBuilder.new("0x3", None, self.tx_versioner) tb.step_limit = 1000000 tb.value = 100000 tb.signer = self.signer tb.to_address = ExternalAddress(os.urandom(20)) tb.nid = nids[0] tb.nonce = random.randint(0, 100000) tb.data = "test" tb.data_type = "message" tx = tb.build() expected_nid = nids[1] mock_blockchain = MockBlockchain(find_nid=lambda: hex(expected_nid), find_tx_by_key=lambda _: False) tv = TransactionVerifier.new(tx.version, tx.type(), self.tx_versioner) self.assertRaises(TransactionInvalidNidError, lambda: tv.verify(tx, mock_blockchain)) self.assertRaises(TransactionInvalidNidError, lambda: tv.pre_verify(tx, nid=expected_nid)) def test_transaction_v2_duplicate_hash(self): MockBlockchain = namedtuple("MockBlockchain", "find_nid find_tx_by_key") tb = TransactionBuilder.new("0x2", None, self.tx_versioner) tb.fee = 1000000 tb.value = 100000 tb.signer = self.signer tb.to_address = ExternalAddress(os.urandom(20)) tb.nonce = random.randint(0, 100000) tx = tb.build() mock_blockchain = MockBlockchain(find_nid=lambda: hex(3), find_tx_by_key=lambda _: True) tv = TransactionVerifier.new(tx.version, tx.type(), self.tx_versioner) self.assertRaises(TransactionDuplicatedHashError, lambda: tv.verify(tx, mock_blockchain)) def test_transaction_v3_duplicate_hash(self): MockBlockchain = namedtuple("MockBlockchain", "find_nid find_tx_by_key") tb = TransactionBuilder.new("0x3", None, self.tx_versioner) tb.step_limit = 1000000 tb.value = 100000 tb.signer = self.signer tb.to_address = ExternalAddress(os.urandom(20)) tb.nid = 3 tb.nonce = random.randint(0, 100000) tb.data = "test" tb.data_type = "message" tx = tb.build() mock_blockchain = MockBlockchain(find_nid=lambda: hex(3), find_tx_by_key=lambda _: True) tv = TransactionVerifier.new(tx.version, tx.type(), self.tx_versioner) self.assertRaises(TransactionDuplicatedHashError, lambda: tv.verify(tx, mock_blockchain))
def _tx_builder_factory(tx_version: str, type_=None) -> TransactionBuilder: tx_builder = TransactionBuilder.new(version=tx_version, type_=type_, versioner=TransactionVersioner()) # Attributes that must be assigned tx_builder.signer = Signer.new() if tx_version == genesis.version: tx_builder = add_attrs_to_genesis_builder(tx_builder) elif tx_version == v2.version: tx_builder = add_attrs_to_v2_builder(tx_builder) elif tx_version == v3.version: tx_builder = add_attrs_to_v3_builder(tx_builder) return tx_builder
import os from typing import TYPE_CHECKING import pytest from loopchain.blockchain.blockchain import BlockChain from loopchain.blockchain.exception import TransactionDuplicatedHashError, TransactionInvalidHashError from loopchain.blockchain.transactions import Transaction, TransactionVerifier, TransactionVersioner, TransactionBuilder from loopchain.blockchain.transactions import genesis, v2, v3 from loopchain.blockchain.types import Hash32 if TYPE_CHECKING: from tests.unit.blockchain.conftest import TxFactory, TxBuilderFactory tx_versioner = TransactionVersioner() @pytest.mark.parametrize("tx_version", [genesis.version, v2.version, v3.version]) class TestTransactionVerifierBase: @pytest.fixture(autouse=True) def auto_fixture_for_test_abc_verifier(self, mocker): mocker.patch.object(TransactionVerifier, "__abstractmethods__", new_callable=set) def test_verifier_version_check(self, tx_version, tx_factory: 'TxFactory'): tx: Transaction = tx_factory(tx_version) tv = TransactionVerifier.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)