示例#1
0
    def test_send_tx_response(self):
        question = "234234"
        answer = "0x234234"
        result = convert_params(question, ParamType.send_tx_response)
        logging.info(f"result : {json.dumps(result, indent=4)}")
        self.assertEqual(result, answer)

        question = "0x234234"
        answer = "0x234234"
        result = convert_params(question, ParamType.send_tx_response)
        logging.info(f"result : {json.dumps(result, indent=4)}")
        self.assertEqual(result, answer)

        question = 234234
        answer = "0x392fa"
        result = convert_params(question, ParamType.send_tx_response)
        logging.info(f"result : {json.dumps(result, indent=4)}")
        self.assertEqual(result, answer)

        question = "qsaad"
        answer = ValueError
        try:
            convert_params(question, ParamType.send_tx_response)
        except BaseException as e:
            self.assertEqual(answer, type(e))
示例#2
0
    async def icx_getTransactionResult(**kwargs):
        request = convert_params(kwargs, ParamType.get_tx_request)

        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL
        channel_stub = StubCollection().channel_stubs[channel_name]
        verify_result = dict()

        tx_hash = request["txHash"]
        response_code, result = await channel_stub.async_task().get_invoke_result(tx_hash)

        if response_code == message_code.Response.fail_tx_not_invoked:
            raise GenericJsonRpcServerError(
                code=JsonError.INVALID_PARAMS,
                message=message_code.responseCodeMap[response_code][1],
                http_status=status.HTTP_BAD_REQUEST
            )
        elif response_code == message_code.Response.fail_invalid_key_error or \
            response_code == message_code.Response.fail:
            raise GenericJsonRpcServerError(
                code=JsonError.INVALID_PARAMS,
                message='Invalid params txHash',
                http_status=status.HTTP_BAD_REQUEST
            )

        if result:
            try:
                result_dict = json.loads(result)
                verify_result = result_dict
            except json.JSONDecodeError as e:
                logging.warning(f"your result is not json, result({result}), {e}")

        response = convert_params(verify_result, ParamType.get_tx_result_response)
        return response
示例#3
0
    def score_write_precommit_state(self, block: Block):
        logging.debug(
            f"call score commit {ChannelProperty().name} {block.height} {block.block_hash}"
        )

        if conf.USE_EXTERNAL_SCORE:
            request = {
                "blockHeight": block.height,
                "blockHash": block.block_hash,
            }
            request = convert_params(request, ParamType.write_precommit_state)

            stub = StubCollection().icon_score_stubs[ChannelProperty().name]
            stub.sync_task().write_precommit_state(request)
            return True
        else:
            block_commit_info = json.dumps({
                "block_height": block.height,
                "block_hash": block.block_hash
            })
            stub = StubCollection().score_stubs[ChannelProperty().name]
            response = stub.sync_task().write_precommit_state(
                block_commit_info)

            if response.code == message_code.Response.success:
                return True
            else:
                logging.error(f"score db commit fail cause {response.message}")
                return False
示例#4
0
    def score_invoke(self, _block: Block) -> dict or None:
        if conf.USE_EXTERNAL_SCORE:
            method = "icx_sendTransaction"
            transactions = []
            for tx in _block.confirmed_transaction_list:
                data = tx.icx_origin_data
                transaction = {"method": method, "params": data}
                transactions.append(transaction)

            request = {
                'block': {
                    'blockHeight': _block.height,
                    'blockHash': _block.block_hash,
                    'prevBlockHash': _block.prev_block_hash,
                    'timestamp': _block.time_stamp
                },
                'transactions': transactions
            }
            request = convert_params(request, ParamType.invoke)
            stub = StubCollection().icon_score_stubs[ChannelProperty().name]
            response = stub.sync_task().invoke(request)
            response_to_json_query(response)
            _block.commit_state[
                ChannelProperty().name] = response['stateRootHash']
            return response["txResults"]
        else:
            stub = StubCollection().score_stubs[ChannelProperty().name]
            response = stub.sync_task().score_invoke(_block)

            if response.code == message_code.Response.success:
                commit_state = pickle.loads(response.object)
                _block.commit_state = commit_state
                return json.loads(response.meta)

        return None
示例#5
0
    def score_write_precommit_state(self, block: Block):
        logging.debug(
            f"call score commit {ChannelProperty().name} {block.header.height} {block.header.hash.hex()}"
        )

        new_block_hash = block.header.hash
        try:
            old_block_hash = self.__block_manager.get_old_block_hash(
                block.header.height, new_block_hash)
        except KeyError:
            old_block_hash = new_block_hash

        logging.debug(f"Block Hash : {old_block_hash} -> {new_block_hash}")
        request = {
            "blockHeight": block.header.height,
            "oldBlockHash": old_block_hash.hex(),
            "newBlockHash": new_block_hash.hex()
        }
        request = convert_params(request, ParamType.write_precommit_state)

        stub = StubCollection().icon_score_stubs[ChannelProperty().name]
        precommit_result: dict = stub.sync_task().write_precommit_state(
            request)
        if "error" in precommit_result:
            raise WritePrecommitStateError(precommit_result['error'])

        self.__block_manager.pop_old_block_hashes(block.header.height)
        return True
示例#6
0
    def genesis_invoke(self, block: Block) -> ('Block', dict):
        method = "icx_sendTransaction"
        transactions = []
        for tx in block.body.transactions.values():
            hash_version = conf.CHANNEL_OPTION[
                ChannelProperty().name]["genesis_tx_hash_version"]
            tx_serializer = TransactionSerializer.new(tx.version, hash_version)
            transaction = {
                "method": method,
                "params": {
                    "txHash": tx.hash.hex()
                },
                "genesisData": tx_serializer.to_full_data(tx)
            }
            transactions.append(transaction)

        request = {
            'block': {
                'blockHeight': block.header.height,
                'blockHash': block.header.hash.hex(),
                'timestamp': block.header.timestamp
            },
            'transactions': transactions
        }
        request = convert_params(request, ParamType.invoke)
        stub = StubCollection().icon_score_stubs[ChannelProperty().name]
        response = stub.sync_task().invoke(request)
        response_to_json_query(response)

        block_builder = BlockBuilder.from_new(block)
        block_builder.commit_state = {
            ChannelProperty().name: response['stateRootHash']
        }
        new_block = block_builder.build()
        return new_block, response["txResults"]
示例#7
0
    def __request_roll_back(self):
        target_block = self.blockchain.find_block_by_hash32(
            self.blockchain.last_block.header.prev_hash)
        if not self.blockchain.check_rollback_possible(target_block):
            util.logger.warning(
                f"The request cannot be rolled back to the target block({target_block})."
            )
            return

        request_origin = {
            'blockHeight': target_block.header.height,
            'blockHash': target_block.header.hash.hex_0x()
        }

        request = convert_params(request_origin, ParamType.roll_back)
        stub = StubCollection().icon_score_stubs[ChannelProperty().name]

        util.logger.debug(f"Rollback request({request})")
        response: dict = cast(dict, stub.sync_task().rollback(request))
        response_to_json_query(response)

        result_height = response.get("blockHeight")
        if hex(target_block.header.height) == result_height:
            util.logger.info(f"Rollback Success")
            self.blockchain.roll_back(target_block)
            self.rebuild_block()
        else:
            util.logger.warning(f"{response}")
示例#8
0
    def request_rollback(self) -> bool:
        """Request block data rollback behind to 1 block

        :return: if rollback success return True, else return False
        """
        target_block = self.blockchain.find_block_by_hash32(self.blockchain.last_block.header.prev_hash)
        if not self.blockchain.check_rollback_possible(target_block):
            util.logger.warning(f"The request cannot be rollback to the target block({target_block}).")
            return False

        request_origin = {
            'blockHeight': target_block.header.height,
            'blockHash': target_block.header.hash.hex_0x()
        }

        request = convert_params(request_origin, ParamType.roll_back)
        stub = StubCollection().icon_score_stubs[ChannelProperty().name]

        util.logger.debug(f"Rollback request({request})")
        response: dict = cast(dict, stub.sync_task().rollback(request))
        try:
            response_to_json_query(response)
        except GenericJsonRpcServerError as e:
            util.logger.warning(f"response error = {e}")
        else:
            result_height = response.get("blockHeight")
            if hex(target_block.header.height) == result_height:
                util.logger.info(f"Rollback Success. result height = {result_height}")
                self.blockchain.rollback(target_block)
                self.rebuild_block()
                return True

        util.logger.warning(f"Rollback Fail. response = {response}")
        return False
示例#9
0
    async def icx_getLastBlock(**kwargs):
        block_hash, result = await get_block_by_params(block_height=-1)
        util.logger.spam(f"JSONRPC_v3:icx_getLastBlock::block_hash({block_hash})")

        response = convert_params(result['block'], ParamType.get_block_response)

        return response
示例#10
0
    def score_invoke(self, _block: Block) -> dict or None:
        method = "icx_sendTransaction"
        transactions = []
        for tx in _block.body.transactions.values():
            tx_serializer = TransactionSerializer.new(tx.version, self.block_manager.get_blockchain().tx_versioner)

            transaction = {
                "method": method,
                "params": tx_serializer.to_full_data(tx)
            }
            transactions.append(transaction)

        request = {
            'block': {
                'blockHeight': _block.header.height,
                'blockHash': _block.header.hash.hex(),
                'prevBlockHash': _block.header.prev_hash.hex() if _block.header.prev_hash else '',
                'timestamp': _block.header.timestamp
            },
            'transactions': transactions
        }
        request = convert_params(request, ParamType.invoke)
        stub = StubCollection().icon_score_stubs[ChannelProperty().name]
        response = stub.sync_task().invoke(request)
        response_to_json_query(response)

        block_builder = BlockBuilder.from_new(_block, self.__block_manager.get_blockchain().tx_versioner)
        block_builder.commit_state = {
            ChannelProperty().name: response['stateRootHash']
        }
        new_block = block_builder.build()

        return new_block, response["txResults"]
示例#11
0
    async def icx_sendTransaction(**kwargs):
        if RestProperty().node_type == conf.NodeType.CitizenNode:
            return await redirect_request_to_rs(
                kwargs, RestProperty().rs_target)

        request = make_request("icx_sendTransaction", kwargs)
        icon_stub = StubCollection().icon_score_stubs[conf.LOOPCHAIN_DEFAULT_CHANNEL]
        response = await icon_stub.async_task().validate_transaction(request)
        response_to_json_query(response)

        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL
        channel_stub = StubCollection().channel_stubs[channel_name]
        response_code, tx_hash = \
            await channel_stub.async_task().create_icx_tx(kwargs)

        if response_code != message_code.Response.success:
            raise GenericJsonRpcServerError(
                code=JsonError.INVALID_REQUEST,
                message=message_code.responseCodeMap[response_code][1],
                http_status=status.HTTP_BAD_REQUEST
            )

        if tx_hash is None:
            raise GenericJsonRpcServerError(
                code=JsonError.INVALID_REQUEST,
                message='txHash is None',
                http_status=status.HTTP_BAD_REQUEST
            )
        return convert_params(tx_hash, ParamType.send_tx_response)
示例#12
0
    async def icx_getBlockByHeight(**kwargs):
        request = convert_params(kwargs, ParamType.get_block_by_height_request)

        block_hash, result = await get_block_by_params(block_height=request['height'])
        util.logger.spam(f"JSONRPC_v3:icx_getBlockByHeight::block_hash({block_hash})")

        response_code = result['response_code']
        if response_code != message_code.Response.success:
            raise GenericJsonRpcServerError(
                code=JsonError.INVALID_PARAMS,
                message=message_code.responseCodeMap[response_code][1],
                http_status=status.HTTP_BAD_REQUEST
            )

        response = convert_params(result['block'], ParamType.get_block_response)
        return response
示例#13
0
    async def icx_getTransactionByHash(**kwargs):
        request = convert_params(kwargs, ParamType.get_tx_request)

        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL
        channel_stub = StubCollection().channel_stubs[channel_name]

        response_code, tx_info = await channel_stub.async_task().get_tx_info(request["txHash"])
        if response_code == message_code.Response.fail_invalid_key_error:
            raise GenericJsonRpcServerError(
                code=JsonError.INVALID_PARAMS,
                message='Invalid params txHash',
                http_status=status.HTTP_BAD_REQUEST
            )

        result = tx_info["transaction"]
        result["txIndex"] = tx_info["tx_index"]
        result["blockHeight"] = tx_info["block_height"]
        result["blockHash"] = tx_info["block_hash"]

        response = convert_params(result, ParamType.get_tx_by_hash_response)
        return response
示例#14
0
    def score_write_precommit_state(self, block: Block):
        logging.debug(f"call score commit {ChannelProperty().name} {block.header.height} {block.header.hash.hex()}")

        request = {
            "blockHeight": block.header.height,
            "blockHash": block.header.hash.hex(),
        }
        request = convert_params(request, ParamType.write_precommit_state)

        stub = StubCollection().icon_score_stubs[ChannelProperty().name]
        stub.sync_task().write_precommit_state(request)
        return True
示例#15
0
    def test_get_tx_by_hash_response(self):
        question = {
            "txHash": "00abcdef1234567890",
            "blockHeight": "1234",
            "blockHash": "00abcdef0981"
        }

        answer = {
            "txHash": "0x00abcdef1234567890",
            "blockHeight": "0x4d2",
            "blockHash": "0x00abcdef0981"
        }

        result = convert_params(question, ParamType.get_tx_by_hash_response)
        logging.info(f"result : {json.dumps(result, indent=4)}")
        self.assertEqual(result, answer)
示例#16
0
    def genesis_invoke(self, block: Block) -> ('Block', dict):
        method = "icx_sendTransaction"
        transactions = []
        for tx in block.body.transactions.values():
            tx_serializer = TransactionSerializer.new(
                tx.version,
                self.block_manager.get_blockchain().tx_versioner)
            transaction = {
                "method": method,
                "params": {
                    "txHash": tx.hash.hex()
                },
                "genesisData": tx_serializer.to_full_data(tx)
            }
            transactions.append(transaction)

        request = {
            'block': {
                'blockHeight': block.header.height,
                'blockHash': block.header.hash.hex(),
                'timestamp': block.header.timestamp
            },
            'transactions': transactions
        }
        request = convert_params(request, ParamType.invoke)
        stub = StubCollection().icon_score_stubs[ChannelProperty().name]
        response = stub.sync_task().invoke(request)
        response_to_json_query(response)

        tx_receipts = response["txResults"]
        block_builder = BlockBuilder.from_new(
            block,
            self.block_manager.get_blockchain().tx_versioner)
        block_builder.reset_cache()
        block_builder.peer_id = block.header.peer_id
        block_builder.signature = block.header.signature

        block_builder.commit_state = {
            ChannelProperty().name: response['stateRootHash']
        }
        block_builder.state_hash = Hash32(
            bytes.fromhex(response['stateRootHash']))
        block_builder.receipts = tx_receipts
        block_builder.reps = self.get_rep_ids()
        new_block = block_builder.build()
        return new_block, tx_receipts
示例#17
0
    def score_remove_precommit_state(self, block: Block):
        if not util.channel_use_icx(ChannelProperty().name):
            request = {
                "blockHeight": block.height,
                "blockHash": block.block_hash,
            }
            request = convert_params(request, ParamType.remove_precommit_state)

            stub = StubCollection().icon_score_stubs[ChannelProperty().name]
            stub.sync_task().remove_precommit_state(request)

            return True
        else:
            invoke_fail_info = json.dumps({"block_height": block.height, "block_hash": block.block_hash})
            stub = StubCollection().score_stubs[ChannelProperty().name]
            stub.sync_task().remove_precommit_state(invoke_fail_info)
            return True
示例#18
0
    def genesis_invoke(self, block: Block) -> dict or None:
        if util.channel_use_icx(ChannelProperty().name):
            method = "icx_sendTransaction"
            transactions = []
            for tx in block.confirmed_transaction_list:
                transaction = {
                    "method": method,
                    "params": {
                        "txHash": tx.tx_hash
                    },
                    "genesisData": tx.genesis_origin_data
                }
                transactions.append(transaction)

            request = {
                'block': {
                    'blockHeight': block.height,
                    'blockHash': block.block_hash,
                    'timestamp': block.time_stamp
                },
                'transactions': transactions
            }
            request = convert_params(request, ParamType.invoke)
            stub = StubCollection().icon_score_stubs[ChannelProperty().name]
            response = stub.sync_task().invoke(request)
            response_to_json_query(response)
            block.commit_state[ChannelProperty().name] = response['stateRootHash']
            return response["txResults"]
        else:
            block_object = pickle.dumps(block)
            stub = StubCollection().score_stubs[ChannelProperty().name]
            response = stub.sync_task().genesis_invoke(block_object)
            if response.code == message_code.Response.success:
                return json.loads(response.meta)

        return None
示例#19
0
    def test_invoke(self):
        question = {
            "block": {
                "block_height": 1000,
                "block_hash": "0xa7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a",
                "time_stamp": "1234567890",
                "prevBlockHash": "0xb7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a",
            },
            "transactions": [{
                "method": "icx_sendTransaction",
                "params": {
                    "version": "0x3",
                    "from": "hxbe258ceb872e08851f1f59694dac2558708ece11",
                    "to": "hxb0776ee37f5b45bfaea8cff1d8232fbb6122ec32",
                    "value": "100",
                    "stepLimit": "12345",
                    "timestamp": "5500598",
                    "nonce": "7362",
                    "signature": "VAia7YZ2Ji6igKWzjR2YsGa2m53nKPrfK7uXYW78QLE+ATehAVZPC40szvAiA6NEU5gCYB4c4qaQzqDh2ugcHgA=",
                    "dataType": "call",
                    "data": {
                        "method": "transfer",
                        "params": {
                            "from": "hxbe258ceb872e08851f1f59694dac2558708ece11",
                            "to": "hxf5aac6e693ec2cb5973d3f314334670b3f85ad14",
                            "value": "56bc75e2d63100000"
                        }
                    }
                }
            }]
        }

        answer = {
            "block": {
                "blockHeight": "0x3e8",
                "blockHash": "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a",
                "timestamp": "0x499602d2",
                "prevBlockHash": "b7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a",
            },
            "transactions": [{
                "method": "icx_sendTransaction",
                "params": {
                    "version": "0x3",
                    "from": "hxbe258ceb872e08851f1f59694dac2558708ece11",
                    "to": "hxb0776ee37f5b45bfaea8cff1d8232fbb6122ec32",
                    "value": "0x100",
                    "stepLimit": "0x3039",
                    "timestamp": "0x53eeb6",
                    "nonce": "0x1cc2",
                    "signature": "VAia7YZ2Ji6igKWzjR2YsGa2m53nKPrfK7uXYW78QLE+ATehAVZPC40szvAiA6NEU5gCYB4c4qaQzqDh2ugcHgA=",
                    "dataType": "call",
                    "data": {
                        "method": "transfer",
                        "params": {
                            "from": "hxbe258ceb872e08851f1f59694dac2558708ece11",
                            "to": "hxf5aac6e693ec2cb5973d3f314334670b3f85ad14",
                            "value": "56bc75e2d63100000"
                        }
                    }
                }
            }]
        }

        result = convert_params(question, ParamType.invoke)
        logging.info(f"result : {json.dumps(result, indent=4)}")
        self.assertEqual(result, answer)
示例#20
0
    def test_get_block_response(self):
        question = {
            "prev_block_hash": "0x012332abcde",
            "merkle_tree_root_hash": "0x01234abc96",
            "time_stamp": "0x1cc3169d2c",
            "block_hash": "0x01282384583bb",
            "height": 124,
            "confirmed_transaction_list": [
                {
                    "from": "hx120983102983",
                    "to": "hx109238019238",
                    "txHash": "0123213b1a"
                },
                {
                    "from": "hx12098310293",
                    "to": "hx10923801928",
                    "txHash": "0123213b1a"
                },
                {
                    "from": "hx12093102983",
                    "to": "hx10923809238",
                    "txHash": "0123213b1a"
                },
                {
                    "from": "hx1209831029823",
                    "to": "hx1092380192382",
                    "txHash": "0123213b1a"
                }
            ]
        }

        answer = {
            "prev_block_hash": "0x012332abcde",
            "merkle_tree_root_hash": "0x01234abc96",
            "time_stamp": "0x1cc3169d2c",
            "block_hash": "0x01282384583bb",
            "height": 124,
            "confirmed_transaction_list": [
                {
                    "from": "hx120983102983",
                    "to": "hx109238019238",
                    "txHash": "0x0123213b1a"
                },
                {
                    "from": "hx12098310293",
                    "to": "hx10923801928",
                    "txHash": "0x0123213b1a"
                },
                {
                    "from": "hx12093102983",
                    "to": "hx10923809238",
                    "txHash": "0x0123213b1a"
                },
                {
                    "from": "hx1209831029823",
                    "to": "hx1092380192382",
                    "txHash": "0x0123213b1a"
                }
            ]
        }

        result = convert_params(question, ParamType.get_block_response)
        logging.info(f"result : {json.dumps(result, indent=4)}")
        self.assertEqual(result, answer)
示例#21
0
 async def node_GetBlockByHeight(**kwargs):
     request = convert_params(kwargs, ParamType.get_block_by_height_request)
     block_hash, response = await get_block_by_params(
         block_height=request['height'], with_commit_state=True)
     return response