예제 #1
0
    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)
예제 #2
0
    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
예제 #4
0
 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
예제 #5
0
    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)
예제 #6
0
    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_)
예제 #7
0
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()
예제 #8
0
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
예제 #9
0
    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')
예제 #10
0
        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
예제 #11
0
    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)
예제 #12
0
    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()
예제 #14
0
        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()
예제 #15
0
 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
예제 #16
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))
예제 #17
0
    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
예제 #18
0
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)