예제 #1
0
    def __handler_status(self, request, context):
        util.logger.debug(f"peer_outer_service:handler_status ({request.message})")

        if request.message == "get_stub_manager_to_server":
            # this case is check only gRPC available
            return loopchain_pb2.Message(code=message_code.Response.success)

        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        channel_stub = StubCollection().channel_stubs[channel_name]

        # FIXME : is need?
        if conf.ENABLE_REP_RADIO_STATION and request.message == "check peer status by rs":
            channel_stub.sync_task().reset_timer(TimerService.TIMER_KEY_CONNECT_PEER)

        callback = partial(self.__status_update, request.channel)
        future = asyncio.run_coroutine_threadsafe(
            channel_stub.async_task().get_status(),
            self.peer_service.inner_service.loop
        )
        future.add_done_callback(callback)

        status = self.__get_status_peer_type_data(request.channel)
        if status is None:
            return loopchain_pb2.Message(code=message_code.Response.fail)

        meta = json.loads(request.meta) if request.meta else {}
        if meta.get("highest_block_height", None) and meta["highest_block_height"] > status["block_height"]:
            util.logger.spam(f"(peer_outer_service.py:__handler_status) there is difference of height !")

        status_json = json.dumps(status)

        return loopchain_pb2.Message(code=message_code.Response.success, meta=status_json)
예제 #2
0
    def ready(self, amqp_target, amqp_key):
        StubCollection().amqp_target = amqp_target
        StubCollection().amqp_key = amqp_key

        async def ready_tasks():
            from loopchain import loggers
            loggers.get_preset().update_logger()
            loggers.update_other_loggers()

            logging.debug('rest_server:initialize')
            await StubCollection().create_peer_stub()

            channels_info = await StubCollection().peer_stub.async_task(
            ).get_channel_infos()
            channel_name = None
            for channel_name, channel_info in channels_info.items():
                await StubCollection().create_channel_stub(channel_name)
                await StubCollection().create_icon_score_stub(channel_name)

            results = await StubCollection().peer_stub.async_task(
            ).get_channel_info_detail(channel_name)

            RestProperty().node_type = conf.NodeType(results[6])
            RestProperty().rs_target = results[3]

            logging.debug(
                f'rest_server:initialize complete. '
                f'node_type({RestProperty().node_type}), rs_target({RestProperty().rs_target})'
            )

        self.__app.add_task(ready_tasks())
예제 #3
0
    def UnSubscribe(self, request, context):
        """BlockGenerator 의 broadcast 채널에서 Peer 를 제외한다.

        :param request:
        :param context:
        :return:
        """
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        channel_stub = StubCollection().channel_stubs[channel_name]
        peer_list = [target['peer_target'] for target in self.peer_service.channel_infos[channel_name]["peers"]]

        if (request.peer_target in peer_list and conf.ENABLE_CHANNEL_AUTH) or \
                (request.node_type == loopchain_pb2.CommunityNode and not conf.ENABLE_CHANNEL_AUTH):
            asyncio.run_coroutine_threadsafe(
                channel_stub.async_task().remove_audience(peer_target=request.peer_target),
                self.peer_service.inner_service.loop
            )
            util.logger.spam(f"peer_outer_service::Unsubscribe remove_audience target({request.peer_target}) "
                             f"in channel({request.channel})")
        else:
            logging.error(f"This target({request.peer_target}), {request.node_type} failed to unsubscribe.")
            return loopchain_pb2.CommonReply(response_code=message_code.get_response_code(message_code.Response.fail),
                                             message=message_code.get_response_msg("Unknown type peer"))

        return loopchain_pb2.CommonReply(response_code=message_code.get_response_code(message_code.Response.success),
                                         message=message_code.get_response_msg(message_code.Response.success))
예제 #4
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
예제 #5
0
    def __init__(self, channel, score_package, amqp_target, amqp_key):
        """Score service init
        """
        loggers.get_preset().channel_name = channel
        loggers.get_preset().score_package = score_package
        loggers.get_preset().update_logger()
        loggers.update_other_loggers()

        self.score: PeerScore = None
        self.score_plugin = Plugins().load_score_plugin(channel)
        self.iiss_plugin = Plugins().load_iiss_plugin(channel)

        self.__peer_id: str = None
        self.__channel_name: str = channel

        StubCollection().amqp_key = amqp_key
        StubCollection().amqp_target = amqp_target

        score_queue_name = conf.SCORE_QUEUE_NAME_FORMAT.format(
            score_package_name=score_package,
            channel_name=channel,
            amqp_key=amqp_key)
        self.__inner_service = ScoreInnerService(amqp_target,
                                                 score_queue_name,
                                                 conf.AMQP_USERNAME,
                                                 conf.AMQP_PASSWORD,
                                                 score_service=self)

        setproctitle.setproctitle(f"{setproctitle.getproctitle()} {channel}")
예제 #6
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"]
예제 #7
0
    def score_change_block_hash(self, block_height, old_block_hash, new_block_hash):
        change_hash_info = json.dumps({"block_height": block_height, "old_block_hash": old_block_hash,
                                       "new_block_hash": new_block_hash})

        if not util.channel_use_icx(ChannelProperty().name):
            stub = StubCollection().score_stubs[ChannelProperty().name]
            stub.sync_task().change_block_hash(change_hash_info)
예제 #8
0
    def GetBlock(self, request, context):
        """Block 정보를 조회한다.

        :param request: loopchain.proto 의 GetBlockRequest 참고
         request.block_hash: 조회할 block 의 hash 값, "" 로 조회하면 마지막 block 의 hash 값을 리턴한다.
         request.block_data_filter: block 정보 중 조회하고 싶은 key 값 목록 "key1, key2, key3" 형식의 string
         request.tx_data_filter: block 에 포함된 transaction(tx) 중 조회하고 싶은 key 값 목록
        "key1, key2, key3" 형식의 string
        :param context:
        :return: loopchain.proto 의 GetBlockReply 참고,
        block_hash, block 정보 json, block 에 포함된 tx 정보의 json 리스트를 받는다.
        포함되는 정보는 param 의 filter 에 따른다.
        """

        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        channel_stub = StubCollection().channel_stubs[channel_name]
        response_code, block_hash, confirm_info, block_data_json, tx_data_json_list = \
            channel_stub.sync_task().get_block(
                block_height=request.block_height,
                block_hash=request.block_hash,
                block_data_filter=request.block_data_filter,
                tx_data_filter=request.tx_data_filter)

        return loopchain_pb2.GetBlockReply(response_code=response_code,
                                           block_hash=block_hash,
                                           block_data_json=block_data_json,
                                           confirm_info=confirm_info,
                                           tx_data_json=tx_data_json_list)
예제 #9
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}")
예제 #10
0
    def Subscribe(self, request, context):
        """BlockGenerator 가 broadcast(unconfirmed or confirmed block) 하는 채널에
        Peer 를 등록한다.

        :param request:
        :param context:
        :return:
        """
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        if not request.peer_id or not request.peer_target:
            return loopchain_pb2.CommonReply(
                response_code=message_code.get_response_code(message_code.Response.fail_wrong_subscribe_info),
                message=message_code.get_response_msg(message_code.Response.fail_wrong_subscribe_info)
            )

        channel_stub = StubCollection().channel_stubs[channel_name]
        peer_list = [target['peer_target'] for target in self.peer_service.channel_infos[channel_name]["peers"]]

        if (request.peer_target in peer_list and conf.ENABLE_CHANNEL_AUTH) or \
                (request.node_type == loopchain_pb2.CommunityNode and not conf.ENABLE_CHANNEL_AUTH):
            channel_stub.sync_task().add_audience(peer_target=request.peer_target)
            util.logger.debug(f"peer_outer_service::Subscribe add_audience "
                              f"target({request.peer_target}) in channel({request.channel}), "
                              f"order({request.peer_order})")
        else:
            logging.error(f"This target({request.peer_target}, {request.node_type}) failed to subscribe.")
            return loopchain_pb2.CommonReply(response_code=message_code.get_response_code(message_code.Response.fail),
                                             message=message_code.get_response_msg("Unknown type peer"))

        return loopchain_pb2.CommonReply(response_code=message_code.get_response_code(message_code.Response.success),
                                         message=message_code.get_response_msg(message_code.Response.success))
예제 #11
0
    def GetTx(self, request, context):
        """get transaction

        :param request: tx_hash
        :param context:channel_loopchain_default
        :return:
        """
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        channel_stub = StubCollection().channel_stubs[channel_name]
        tx = channel_stub.sync_task().get_tx(request.tx_hash)

        response_code, response_msg = message_code.get_response(
            message_code.Response.fail)
        response_meta = ""
        response_data = ""
        response_sign = b''
        response_public_key = b''

        if tx is not None:
            response_code, response_msg = message_code.get_response(
                message_code.Response.success)
            response_meta = json.dumps(tx.meta)
            response_data = tx.get_data().decode(conf.PEER_DATA_ENCODING)
            response_sign = tx.signature
            response_public_key = tx.public_key

        return loopchain_pb2.GetTxReply(response_code=response_code,
                                        meta=response_meta,
                                        data=response_data,
                                        signature=response_sign,
                                        public_key=response_public_key,
                                        more_info=response_msg)
예제 #12
0
        async def _run():
            route_key = conf.PEER_QUEUE_NAME_FORMAT.format(
                amqp_key=conf.AMQP_KEY)
            peer_inner_service = PeerInnerService(conf.AMQP_TARGET,
                                                  route_key,
                                                  peer_service=None)
            peer_inner_service._callback_connection_lost_callback = lambda conn: None
            await peer_inner_service.connect()

            route_key = conf.CHANNEL_QUEUE_NAME_FORMAT.format(
                channel_name=conf.LOOPCHAIN_DEFAULT_CHANNEL,
                amqp_key=conf.AMQP_KEY)
            channel_inner_service = ChannelInnerService(conf.AMQP_TARGET,
                                                        route_key,
                                                        channel_service=None)
            channel_inner_service._callback_connection_lost_callback = lambda conn: None
            await channel_inner_service.connect()

            StubCollection().amqp_target = conf.AMQP_TARGET
            StubCollection().amqp_key = conf.AMQP_KEY

            await StubCollection().create_peer_stub()
            result = await StubCollection().peer_stub.async_task().hello()
            self.assertEqual(result, 'peer_hello')

            await StubCollection().create_channel_stub(
                conf.LOOPCHAIN_DEFAULT_CHANNEL)
            result = await StubCollection().channel_stubs[
                conf.LOOPCHAIN_DEFAULT_CHANNEL].async_task().hello()
            self.assertEqual(result, 'channel_hello')

            await peer_inner_service._connection.close()
            await channel_inner_service._connection.close()
예제 #13
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)
예제 #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()}"
        )

        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
예제 #15
0
    def __handler_get_tx_by_address(self, request, context):
        """Get Transaction by address

        :param request:
        :param context:
        :return:
        """
        params = json.loads(request.meta)
        address = params.pop('address', None)
        index = params.pop('index', None)

        if address is None or index is None:  # or params:
            return loopchain_pb2.Message(
                code=message_code.Response.fail_illegal_params)

        channel_stub = StubCollection().channel_stubs[request.channel]
        future = asyncio.run_coroutine_threadsafe(
            channel_stub.async_task().get_tx_by_address(address, index),
            self.peer_service.inner_service.loop)
        tx_list, next_index = future.result()
        tx_list_dumped = json.dumps(tx_list).encode(
            encoding=conf.PEER_DATA_ENCODING)

        return loopchain_pb2.Message(code=message_code.Response.success,
                                     meta=str(next_index),
                                     object=tx_list_dumped)
예제 #16
0
    def AnnounceNewBlockForVote(self, request, context):
        """수집된 tx 로 생성한 Block 을 각 peer 에 전송하여 검증을 요청한다.

        :param request:
        :param context:
        :return:
        """
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        logging.debug(
            f"peer_outer_service::AnnounceNewBlockForVote channel({channel_name})"
        )

        block: Block = pickle.loads(request.block)
        epoch = pickle.loads(request.epoch)

        logging.debug(f"#block \n"
                      f"epoch({epoch.block_height})\n"
                      f"prev_epoch({epoch.prev_epoch})\n"
                      f"block_type({block.block_type})\n"
                      f"block_hash({block.block_hash})\n"
                      f"peer_id({block.peer_id})\n"
                      f"made_block_count({block.made_block_count})\n"
                      f"block_type({block.block_type})\n")

        channel_stub = StubCollection().channel_stubs[channel_name]
        channel_stub.sync_task().announce_new_block_for_vote(block, epoch)

        return loopchain_pb2.CommonReply(
            response_code=message_code.Response.success, message="success")
예제 #17
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"]
예제 #18
0
    async def icx_sendTransaction(**kwargs):
        if RestProperty().node_type == conf.NodeType.CitizenNode:
            return await redirect_request_to_rs(kwargs,
                                                RestProperty().rs_target,
                                                conf.ApiVersion.v2.name)

        request = make_request("icx_sendTransaction", kwargs,
                               ParamType.send_tx)
        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_inner_tasks = StubCollection().channel_stubs[
            conf.LOOPCHAIN_DEFAULT_CHANNEL]
        code, tx_hash = await channel_inner_tasks.async_task().create_icx_tx(
            kwargs)

        response_data = {'response_code': code}

        if code != message_code.Response.success:
            response_data['message'] = message_code.responseCodeMap[code][1]
        else:
            response_data['tx_hash'] = tx_hash

        util.logger.spam(f"response_data: ({response_data})")

        return response_data
예제 #19
0
    def __init__(self, tx_versioner: TransactionVersioner, add_tx_list_callback, loop, crash_callback_in_join_thread):
        super().__init__()

        self.__is_running = True
        self.__tx_queue = self.Queue()
        self.__tx_queue.cancel_join_thread()

        async def _add_tx_list(tx_list):
            add_tx_list_callback(tx_list)

        def _receive_tx_list(tx_queue):
            while True:
                tx_list = tx_queue.get()
                if not self.__is_running or tx_list is None:
                    break
                asyncio.run_coroutine_threadsafe(_add_tx_list(tx_list), loop)

            while not tx_queue.empty():
                tx_queue.get()

        self.__receive_thread = threading.Thread(target=_receive_tx_list, args=(self.__tx_queue,))
        self.__receive_thread.start()

        args = (ChannelProperty().name,
                StubCollection().amqp_target,
                StubCollection().amqp_key,
                tx_versioner,
                self.__tx_queue)
        super().start(target=ChannelTxReceiverInnerService.main,
                      args=args,
                      crash_callback_in_join_thread=crash_callback_in_join_thread)
예제 #20
0
    def __init__(self, channel_name, amqp_target, amqp_key):
        self.__block_manager: BlockManager = None
        self.__score_container: CommonSubprocess = None
        self.__score_info: dict = None
        self.__peer_auth: PeerAuthorization = None
        self.__peer_manager: PeerManager = None
        self.__broadcast_scheduler: BroadcastScheduler = None
        self.__radio_station_stub = None
        self.__consensus: Consensus = None
        self.__proposer: Proposer = None
        self.__acceptor: Acceptor = None
        self.__timer_service = TimerService()

        loggers.get_preset().channel_name = channel_name
        loggers.get_preset().update_logger()

        channel_queue_name = conf.CHANNEL_QUEUE_NAME_FORMAT.format(channel_name=channel_name, amqp_key=amqp_key)
        self.__inner_service = ChannelInnerService(
            amqp_target, channel_queue_name, conf.AMQP_USERNAME, conf.AMQP_PASSWORD, channel_service=self)

        logging.info(f"ChannelService : {channel_name}, Queue : {channel_queue_name}")

        ChannelProperty().name = channel_name
        ChannelProperty().amqp_target = amqp_target

        StubCollection().amqp_key = amqp_key
        StubCollection().amqp_target = amqp_target

        command_arguments.add_raw_command(command_arguments.Type.Channel, channel_name)
        command_arguments.add_raw_command(command_arguments.Type.AMQPTarget, amqp_target)
        command_arguments.add_raw_command(command_arguments.Type.AMQPKey, amqp_key)

        ObjectManager().channel_service = self
예제 #21
0
    def __prevent_next_block_mismatch(self, next_block: Block) -> bool:
        logging.debug(f"prevent_block_mismatch...")
        score_stub = StubCollection().icon_score_stubs[self.__channel_name]
        request = {
            "method": "ise_getStatus",
            "params": {
                "filter": ["lastBlock"]
            }
        }

        response = score_stub.sync_task().query(request)
        score_last_block_height = int(response['lastBlock']['blockHeight'], 16)

        if score_last_block_height == next_block.header.height:
            logging.debug(f"already invoked block in score...")
            return False

        if score_last_block_height < next_block.header.height:
            for invoke_block_height in range(score_last_block_height + 1,
                                             next_block.header.height):
                logging.debug(
                    f"mismatch invoke_block_height({invoke_block_height}) "
                    f"score_last_block_height({score_last_block_height}) "
                    f"next_block_height({next_block.header.height})")

                invoke_block = self.find_block_by_height(invoke_block_height)
                if invoke_block is None:
                    raise RuntimeError(
                        "Error raised during prevent mismatch block, "
                        f"Cannot find block({invoke_block_height}")

                invoke_block, invoke_block_result = ObjectManager(
                ).channel_service.score_invoke(invoke_block)

                self.__add_tx_to_block_db(invoke_block, invoke_block_result)
                ObjectManager().channel_service.score_write_precommit_state(
                    invoke_block)

            return True

        if score_last_block_height == next_block.header.height + 1:
            try:
                invoke_result_block_height_bytes = \
                    self.__confirmed_block_db.Get(BlockChain.INVOKE_RESULT_BLOCK_HEIGHT_KEY)
                invoke_result_block_height = int.from_bytes(
                    invoke_result_block_height_bytes, byteorder='big')

                if invoke_result_block_height == next_block.header.height:
                    logging.debug(f"already saved invoke result...")
                    return False
            except KeyError:
                logging.debug(f"There is no invoke result height in db.")
        else:
            util.exit_and_msg(
                "Too many different(over 2) of block height between the loopchain and score. "
                "Peer will be down. : "
                f"loopchain({next_block.header.height})/score({score_last_block_height})"
            )
            return True
예제 #22
0
    def Query(self, request, context):
        """Score 의 invoke 로 생성된 data 에 대한 query 를 수행한다."""
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        score_stub = StubCollection().score_stubs[channel_name]
        response_code, response = score_stub.sync_task().query(request.params)

        return loopchain_pb2.QueryReply(response_code=response_code, response=response)
예제 #23
0
 def score_remove_precommit_state(self, block: Block):
     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
예제 #24
0
    async def _wait():
        StubCollection().amqp_target = conf.AMQP_TARGET
        StubCollection().amqp_key = f"{util.get_private_ip()}:{port}"

        logging.debug(f'{StubCollection().amqp_key} peer hello')

        await StubCollection().create_peer_stub()
        await StubCollection().peer_stub.async_task().hello()

        logging.debug(f'{StubCollection().amqp_key} peer hello complete')
예제 #25
0
    def AnnounceNewLeader(self, request, context):
        if not request.channel:
            raise Exception("peer_outer_service:AnnounceNewLeader : Channel is not defined.")

        logging.debug(f"AnnounceNewLeader({request.channel}): " + request.message)

        channel_stub = StubCollection().channel_stubs[request.channel]
        channel_stub.sync_task().reset_leader(request.new_leader_id)

        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
예제 #26
0
    def VoteUnconfirmedBlock(self, request, context):
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        channel_stub = StubCollection().channel_stubs[channel_name]
        channel_stub.sync_task().vote_unconfirmed_block(
            peer_id=request.peer_id,
            group_id=request.group_id,
            block_hash=request.block_hash,
            vote_code=request.vote_code)

        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
예제 #27
0
    def VoteUnconfirmedBlock(self, request, context):
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        utils.logger.debug(f"VoteUnconfirmedBlock vote({request.vote})")

        channel_stub = StubCollection().channel_stubs[channel_name]
        asyncio.run_coroutine_threadsafe(
            channel_stub.async_task().vote_unconfirmed_block(request.vote),
            self.peer_service.inner_service.loop
        )
        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
예제 #28
0
    def ComplainLeader(self, request: ComplainLeaderRequest, context):
        channel = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        utils.logger.info(f"ComplainLeader {request.complain_vote}")

        channel_stub = StubCollection().channel_stubs[channel]
        asyncio.run_coroutine_threadsafe(
            channel_stub.async_task().complain_leader(vote_dumped=request.complain_vote),
            self.peer_service.inner_service.loop
        )

        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
예제 #29
0
    def score_change_block_hash(self, block_height, old_block_hash,
                                new_block_hash):
        change_hash_info = json.dumps({
            "block_height": block_height,
            "old_block_hash": old_block_hash,
            "new_block_hash": new_block_hash
        })

        if not conf.USE_EXTERNAL_SCORE:
            stub = StubCollection().score_stubs[ChannelProperty().name]
            stub.sync_task().change_block_hash(change_hash_info)
예제 #30
0
    def __handler_peer_list(self, request, context):
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        channel_stub = StubCollection().channel_stubs[channel_name]
        all_group_peer_list_str, peer_list_str = channel_stub.sync_task().get_peer_list()

        message = "All Group Peers count: " + all_group_peer_list_str

        return loopchain_pb2.Message(
            code=message_code.Response.success,
            message=message,
            meta=peer_list_str)