コード例 #1
0
    def add_tx(self, request) -> None:
        tx_json = request.tx_json

        tx_versioner = self._blockchain.tx_versioner
        tx_version, tx_type = tx_versioner.get_version(tx_json)

        ts = TransactionSerializer.new(tx_version, tx_type, tx_versioner)
        tx = ts.from_(tx_json)

        tv = TransactionVerifier.new(tx_version, tx_type, tx_versioner)
        tv.verify(tx)

        if tx is not None:
            self._block_manager.add_tx_obj(tx)
            util.apm_event(
                ChannelProperty().peer_id, {
                    'event_type': 'AddTx',
                    'peer_id': ChannelProperty().peer_id,
                    'peer_name': conf.PEER_NAME,
                    'channel_name': ChannelProperty().name,
                    'data': {
                        'tx_hash': tx.tx_hash
                    }
                })

        if not conf.ALLOW_MAKE_EMPTY_BLOCK:
            self._channel_service.start_leader_complain_timer_if_tx_exists()
コード例 #2
0
    async def relay_all_txs(self):
        rs_client = ObjectManager().channel_service.rs_client
        if not rs_client:
            return

        items = list(self.__tx_queue.d.values())
        self.__tx_queue.d.clear()

        for item in items:
            tx = item.value
            if not util.is_in_time_boundary(tx.timestamp,
                                            conf.TIMESTAMP_BOUNDARY_SECOND,
                                            util.get_now_time_stamp()):
                continue

            ts = TransactionSerializer.new(tx.version, tx.type(),
                                           self.blockchain.tx_versioner)
            if tx.version == v2.version:
                rest_method = RestMethod.SendTransaction2
            elif tx.version == v3.version:
                rest_method = RestMethod.SendTransaction3
            else:
                continue

            raw_data = ts.to_raw_data(tx)
            raw_data["from_"] = raw_data.pop("from")
            for i in range(conf.RELAY_RETRY_TIMES):
                try:
                    await rs_client.call_async(
                        rest_method, rest_method.value.params(**raw_data))
                except Exception as e:
                    util.logger.warning(f"Relay failed. Tx({tx}), {e}")
                else:
                    break
コード例 #3
0
    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))
コード例 #4
0
ファイル: block_serializer.py プロジェクト: yakkle/loopchain
    def _deserialize_body_data(self, json_data: dict):
        transactions = OrderedDict()
        for tx_data in json_data['transactions']:
            tx_version, tx_type = self._tx_versioner.get_version(tx_data)
            ts = TransactionSerializer.new(tx_version, tx_type,
                                           self._tx_versioner)
            tx = ts.from_(tx_data)
            transactions[tx.hash] = tx

        vote_class = BlockVotes
        leader_vote_class = LeaderVotes
        if json_data["prevVotes"]:
            any_vote = next(vote for vote in json_data["prevVotes"] if vote)
            if any_vote.get("round") is None:
                vote_class = v0_1a.BlockVotes
                leader_vote_class = v0_1a.LeaderVotes

        leader_votes = leader_vote_class.deserialize_votes(
            json_data["leaderVotes"])
        prev_votes = vote_class.deserialize_votes(json_data["prevVotes"])

        return {
            "transactions": transactions,
            "leader_votes": leader_votes,
            "prev_votes": prev_votes
        }
コード例 #5
0
    def _serialize(self, block: 'Block'):
        header: BlockHeader = block.header
        body: BlockBody = block.body

        transactions = []
        for tx in body.transactions.values():
            ts = TransactionSerializer.new(tx.version, tx.type(), self._tx_versioner)
            tx_serialized = ts.to_full_data(tx)
            transactions.append(tx_serialized)

        return {
            "version": header.version,
            "prevHash": header.prev_hash.hex_0x(),
            "transactionsHash": header.transactions_hash.hex_0x(),
            "stateHash": header.state_hash.hex_0x(),
            "receiptsHash": header.receipts_hash.hex_0x(),
            "repsHash": header.reps_hash.hex_0x(),
            "nextRepsHash": header.next_reps_hash.hex_0x(),
            "leaderVotesHash": header.leader_votes_hash.hex_0x(),
            "prevVotesHash": header.prev_votes_hash.hex_0x(),
            "logsBloom": header.logs_bloom.hex_0x(),
            "timestamp": hex(header.timestamp),
            "transactions": transactions,
            "leaderVotes": LeaderVotes.serialize_votes(body.leader_votes),
            "prevVotes": BlockVotes.serialize_votes(body.prev_votes),
            "hash": header.hash.hex_0x(),
            "height": hex(header.height),
            "leader": header.peer_id.hex_hx(),
            "signature": header.signature.to_base64str(),
            "nextLeader": header.next_leader.hex_xx(),
        }
コード例 #6
0
    async def add_tx_list(self, request) -> tuple:
        if self.__nid is None:
            response_code = message_code.Response.fail
            message = "Node initialization is not completed."
            return response_code, message

        tx_list = []
        for tx_item in request.tx_list:
            tx_json = json.loads(tx_item.tx_json)

            tx_version, tx_type = self.__tx_versioner.get_version(tx_json)

            ts = TransactionSerializer.new(tx_version, tx_type, self.__tx_versioner)
            tx = ts.from_(tx_json)

            tv = TransactionVerifier.new(tx_version, tx_type, self.__tx_versioner)
            tv.pre_verify(tx, nid=self.__nid)

            tx.size(self.__tx_versioner)

            tx_list.append(tx)

        tx_len = len(tx_list)
        if tx_len == 0:
            response_code = message_code.Response.fail
            message = "fail tx validate while AddTxList"
        else:
            self.__tx_queue.put(tx_list)
            response_code = message_code.Response.success
            message = f"success ({len(tx_list)})/({len(request.tx_list)})"

        return response_code, message
コード例 #7
0
    def test_serializer_version_check(self, tx_factory: 'TxFactory'):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version,
                                       type_=self.type_,
                                       versioner=tx_versioner)

        assert isinstance(ts, v3_issue.TransactionSerializer)
コード例 #8
0
ファイル: test_crypto.py プロジェクト: icon-project/loopchain
    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)
コード例 #9
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)
コード例 #10
0
    def test_get_hash(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)

        full_data = ts.to_full_data(tx)
        tx_hash = ts.get_hash(full_data)

        assert tx.hash == Hash32(tx_hash)
コード例 #11
0
    def test_to_full_data_equals_tx_raw_data(self, tx_factory: 'TxFactory'):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version,
                                       type_=tx.type(),
                                       versioner=tx_versioner)

        full_data = ts.to_full_data(tx)
        assert full_data == tx.raw_data
コード例 #12
0
    def test_get_hash(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=self.type_, versioner=tx_versioner)

        full_data = ts.to_full_data(tx)
        tx_hash = ts.get_hash(full_data)

        assert tx.hash == Hash32.fromhex(tx_hash, ignore_prefix=True)
コード例 #13
0
    def test_to_origin_data_has_valid_form(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=self.type_, versioner=tx_versioner)

        origin_data = ts.to_origin_data(tx)
        expected_keys = ["version", "from", "to", "stepLimit", "timestamp", "nid", "value", "nonce", "signature"]

        assert set(origin_data) == set(expected_keys)
コード例 #14
0
    def test_to_db_data_equals_dict_raw_data(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=self.type_, versioner=tx_versioner)

        db_data = ts.to_db_data(tx)

        assert db_data == tx.raw_data
        assert tx.raw_data == dict(tx.raw_data)
コード例 #15
0
    def test_to_db_data_equals_full_data(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)

        db_data = ts.to_db_data(tx)
        full_data = ts.to_full_data(tx)

        assert db_data == full_data
コード例 #16
0
    def test_orig_tx_equals_deserialized_tx(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)

        full_data = ts.to_full_data(tx)
        tx_restored = ts.from_(full_data)

        assert tx == tx_restored
コード例 #17
0
    async def create_icx_tx(self, kwargs: dict):
        tx_hash = None
        relay_target = None
        if self.__qos_controller.limit():
            util.logger.debug(f"Out of TPS limit. tx={kwargs}")
            return message_code.Response.fail_out_of_tps_limit, tx_hash, relay_target

        node_type = self.__properties.get('node_type', None)
        if node_type is None:
            util.logger.warning("Node type has not been set yet.")
            return NodeInitializationError.message_code, tx_hash, relay_target
        elif node_type != conf.NodeType.CommunityNode.value:
            relay_target = self.__properties.get('relay_target', None)
            return message_code.Response.fail_no_permission, tx_hash, relay_target

        result_code = None
        exception = None
        tx = None

        try:
            tx_version, tx_type = self.__tx_versioner.get_version(kwargs)

            ts = TransactionSerializer.new(tx_version, tx_type,
                                           self.__tx_versioner)
            tx = ts.from_(kwargs)

            nid = self.__properties.get('nid', None)
            if nid is None:
                util.logger.warning(f"NID has not been set yet.")
                raise NodeInitializationError(tx.hash.hex())

            tv = TransactionVerifier.new(tx_version, tx_type,
                                         self.__tx_versioner)
            tv.pre_verify(tx, nid=nid)

            self.__pre_validate(tx)

            logging.debug(f"create icx input : {kwargs}")

            self.__broadcast_scheduler.schedule_job(BroadcastCommand.CREATE_TX,
                                                    (tx, self.__tx_versioner))
            return message_code.Response.success, tx.hash.hex(), relay_target

        except MessageCodeError as e:
            result_code = e.message_code
            exception = e
            traceback.print_exc()
        except BaseException as e:
            result_code = TransactionInvalidError.message_code
            exception = e
            traceback.print_exc()
        finally:
            if exception:
                logging.warning(f"create_icx_tx: tx restore fail.\n\n"
                                f"kwargs({kwargs})\n\n"
                                f"tx({tx})\n\n"
                                f"exception({exception})")
                return result_code, tx_hash, relay_target
コード例 #18
0
    def test_to_full_data_equals_to_db_data_with_tx_hash(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=self.type_, versioner=tx_versioner)

        full_data = ts.to_full_data(tx)
        db_data = ts.to_db_data(tx)
        db_data["txHash"] = tx.hash.hex()

        assert db_data == full_data
コード例 #19
0
    def test_to_full_data_equals_raw_data_with_method(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)

        full_data = ts.to_full_data(tx)
        raw_data = ts.to_raw_data(tx)
        raw_data["method"] = tx.method

        assert full_data == raw_data
コード例 #20
0
    def test_to_origin_data_has_valid_form(self, tx_factory: 'TxFactory',
                                           tx_version, expected_keys):
        tx: Transaction = tx_factory(tx_version)
        ts = TransactionSerializer.new(version=tx.version,
                                       type_=tx.type(),
                                       versioner=tx_versioner)

        origin_data = ts.to_origin_data(tx)
        assert set(origin_data) == set(expected_keys)
コード例 #21
0
    def test_orig_tx_equals_deserialized_tx(self, tx_builder_factory: TxBuilderFactory):
        with freeze_time():
            # TODO: origin data contains signature, so it affects tx_hash of deserialized tx.
            tx: genesis.Transaction = tx_builder_factory(self.tx_version)\
                .build(is_signing=False)
            ts: genesis.TransactionSerializer = TransactionSerializer.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)

        tx_restored = ts.from_(tx.raw_data)

        assert tx == tx_restored
コード例 #22
0
    def test_orig_tx_equals_deserialized_tx(self, tx_factory: TxFactory):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)

        tx_restored = ts.from_(tx.raw_data)

        object.__setattr__(tx, "to_address", "")
        object.__setattr__(tx_restored, "to_address", "")

        assert tx == tx_restored
コード例 #23
0
    def test_get_hash(self, tx_factory: 'TxFactory'):
        tx: Transaction = tx_factory(self.tx_version)
        ts = TransactionSerializer.new(version=tx.version,
                                       type_=tx.type(),
                                       versioner=tx_versioner)

        tx_hash = ts.get_hash(tx.raw_data)
        assert tx.hash == Hash32.fromhex(tx_hash,
                                         ignore_prefix=True,
                                         allow_malformed=False)
コード例 #24
0
ファイル: transaction.py プロジェクト: yakkle/loopchain
    def size(self, versioner: 'TransactionVersioner'):
        if not hasattr(self, _size_attr_name_):
            from loopchain.blockchain.transactions import TransactionSerializer
            ts = TransactionSerializer.new(self.version, self.type(),
                                           versioner)
            tx_serialized = ts.to_full_data(self)
            tx_serialized = json.dumps(tx_serialized)
            tx_serialized = tx_serialized.encode('utf-8')
            object.__setattr__(self, _size_attr_name_, len(tx_serialized))

        return getattr(self, _size_attr_name_)
コード例 #25
0
    def test_serializer_version_check(self, tx_factory: TxFactory, tx_version):
        tx: Transaction = tx_factory(tx_version)
        ts = TransactionSerializer.new(version=tx.version, type_=tx.type(), versioner=tx_versioner)

        if tx_version == genesis.version:
            assert isinstance(ts, genesis.TransactionSerializer)
        elif tx_version == v2.version:
            assert isinstance(ts, v2.TransactionSerializer)
        elif tx_version == v3.version:
            assert isinstance(ts, v3.TransactionSerializer)
        else:
            assert False
コード例 #26
0
ファイル: block_serializer.py プロジェクト: yakkle/loopchain
    def _deserialize_body_data(self, json_data: dict):
        confirm_prev_block = json_data.get("confirm_prev_block")

        transactions = OrderedDict()
        for tx_data in json_data['confirmed_transaction_list']:
            tx_version, tx_type = self._tx_versioner.get_version(tx_data)
            ts = TransactionSerializer.new(tx_version, tx_type, self._tx_versioner)
            tx = ts.from_(tx_data)
            transactions[tx.hash] = tx

        return {
            "confirm_prev_block": confirm_prev_block,
            "transactions": transactions
        }
コード例 #27
0
    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)
コード例 #28
0
    def _deserialize_body_data(self, json_data: dict):
        transactions = OrderedDict()
        for tx_data in json_data['transactions']:
            tx_version, tx_type = self._tx_versioner.get_version(tx_data)
            ts = TransactionSerializer.new(tx_version, tx_type, self._tx_versioner)
            tx = ts.from_(tx_data)
            transactions[tx.hash] = tx

        leader_votes = LeaderVotes.deserialize_votes(json_data["leaderVotes"])
        prev_votes = BlockVotes.deserialize_votes(json_data["prevVotes"])

        return {
            "transactions": transactions,
            "leader_votes": leader_votes,
            "prev_votes": prev_votes
        }
コード例 #29
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)
コード例 #30
0
    async def get_block_v2(self, block_height,
                           block_hash) -> Tuple[int, str, str]:
        # This is a temporary function for v2 support of exchanges.
        block, block_hash, _, fail_response_code = await self.__get_block(
            block_hash, block_height)
        if fail_response_code:
            return fail_response_code, block_hash, json.dumps({})

        tx_versioner = self._blockchain.tx_versioner
        bs = BlockSerializer.new(block.header.version, tx_versioner)
        block_data_dict = bs.serialize(block)

        if block.header.height == 0:
            return message_code.Response.success, block_hash, json.dumps(
                block_data_dict)

        confirmed_tx_list_without_fail = []
        for tx in block.body.transactions.values():
            invoke_result = self._block_manager.get_invoke_result(tx.hash)

            if 'failure' in invoke_result:
                continue

            ts = TransactionSerializer.new(tx.version, tx.type(), tx_versioner)
            full_data = ts.to_full_data(tx)
            if tx.version == "0x3":
                step_used, step_price = int(invoke_result["stepUsed"],
                                            16), int(
                                                invoke_result["stepPrice"], 16)
                full_data["fee"] = hex(step_used * step_price)

            confirmed_tx_list_without_fail.append(full_data)

        # Replace the existing confirmed_transactions with v2 ver.
        if block.header.version == "0.1a":
            block_data_dict[
                "confirmed_transaction_list"] = confirmed_tx_list_without_fail
        else:
            block_data_dict["transactions"] = confirmed_tx_list_without_fail
        block_data_json = json.dumps(block_data_dict)

        if fail_response_code:
            return fail_response_code, block_hash, json.dumps({})

        return message_code.Response.success, block_hash, block_data_json