Ejemplo n.º 1
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))
Ejemplo n.º 2
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))
Ejemplo n.º 3
0
    def VoteUnconfirmedBlock(self, request, context):
        if self.peer_service.peer_type == loopchain_pb2.PEER:
            return loopchain_pb2.CommonReply(
                response_code=message_code.Response.fail_no_leader_peer,
                message=message_code.get_response_msg(message_code.Response.fail_no_leader_peer))
        else:
            logging.info("Peer vote to : " + request.block_hash + " " + str(request.vote_code))
            self.peer_service.block_manager.get_candidate_blocks().vote_to_block(
                request.block_hash, (False, True)[request.vote_code == message_code.Response.success_validate_block],
                request.peer_id, request.group_id)

            return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 4
0
    async def AnnounceUnconfirmedBlock(self, request, context):
        """Send the UnconfirmedBlock includes collected transactions to reps and request to verify it.

        :param request:
        :param context:
        :return:
        """
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        channel_stub = StubCollection().channel_stubs[channel_name]

        try:
            round_ = request.round_
        except AttributeError:
            round_ = 0

        utils.logger.info(
            f"peer_id({request.peer_id}), height({request.height}), "
            f"round({round_}), hash({request.hash}), from_recovery({request.from_recovery!r})"
        )

        from_recovery = request.from_recovery if request.from_recovery else False

        await channel_stub.async_task().announce_unconfirmed_block(
            request.block, round_, from_recovery)
        return loopchain_pb2.CommonReply(
            response_code=message_code.Response.success, message="success")
Ejemplo n.º 5
0
    def AnnounceUnconfirmedBlock(self, request, context):
        """수집된 tx 로 생성한 Block 을 각 peer 에 전송하여 검증을 요청한다.

        :param request:
        :param context:
        :return:
        """

        unconfirmed_block = pickle.loads(request.block)

        logging.debug(
            f"#block \n"
            f"peer_id({unconfirmed_block.peer_id})\n"
            f"made_block_count({unconfirmed_block.made_block_count})\n"
            f"is_voting_block({unconfirmed_block.is_voting_block})\n"
            f"is_divided_block({unconfirmed_block.is_divided_block})")

        self.peer_service.block_manager.add_unconfirmed_block(
            unconfirmed_block)

        if unconfirmed_block.made_block_count >= conf.LEADER_BLOCK_CREATION_LIMIT \
                and unconfirmed_block.is_voting_block is True \
                and unconfirmed_block.is_divided_block is False:
            self.peer_service.reset_leader(unconfirmed_block.next_leader_peer)

        return loopchain_pb2.CommonReply(
            response_code=message_code.Response.success, message="success")
Ejemplo n.º 6
0
    def Echo(self, request, context):
        """gRPC 기본 성능을 확인하기 위한 echo interface, loopchain 기능과는 무관하다.

        :return: request 를 message 되돌려 준다.
        """
        return loopchain_pb2.CommonReply(response_code=message_code.Response.success,
                                         message=request.request)
Ejemplo n.º 7
0
    def AnnounceUnconfirmedBlock(self, request, context):
        """수집된 tx 로 생성한 Block 을 각 peer 에 전송하여 검증을 요청한다.

        :param request:
        :param context:
        :return:
        """
        # self.__block_manager.add_unconfirmed_block(request.block)

        unconfirmed_block = pickle.loads(request.block)

        logging.warning("Black Peer makes Fail validate Message by intention!")
        vote_code, message = message_code.get_response(
            message_code.Response.fail_validate_block)
        self.peer_service.stub_to_blockgenerator.call(
            "VoteUnconfirmedBlock",
            loopchain_pb2.BlockVote(
                vote_code=vote_code,
                message=message,
                block_hash=unconfirmed_block.block_hash,
                peer_id=ObjectManager().peer_service.peer_id,
                group_id=ObjectManager().peer_service.group_id))

        return loopchain_pb2.CommonReply(
            response_code=message_code.Response.success, message="success")
Ejemplo n.º 8
0
    def AnnounceConfirmedBlock(self, request, context):
        """Block Generator 가 announce 하는 인증된 블록의 대한 hash 를 전달받는다.
        :param request: BlockAnnounce of loopchain.proto
        :param context: gRPC parameter
        :return: CommonReply of loopchain.proto
        """
        # Peer To BlockGenerator
        logging.debug("AnnounceConfirmedBlock block hash: " +
                      request.block_hash)
        response_code, response_msg = message_code.get_response(
            message_code.Response.fail_announce_block)

        confirmed_block = pickle.loads(request.block)

        logging.debug(f"block \n"
                      f"peer_id({confirmed_block.peer_id})\n"
                      f"made_block_count({confirmed_block.made_block_count})\n"
                      f"is_divided_block({confirmed_block.is_divided_block})")

        if len(request.block) > 0:
            logging.warning(
                "AnnounceConfirmedBlock without Consensus ===================="
            )
            # 아래의 return 값을 확인하지 않아도 예외인 경우 아래 except 에서 확인된다.
            self.peer_service.add_unconfirm_block(request.block)

        try:
            self.peer_service.block_manager.confirm_block(request.block_hash)
            response_code, response_msg = message_code.get_response(
                message_code.Response.success_announce_block)
        except (BlockchainError, BlockInValidError, BlockError) as e:
            logging.error("AnnounceConfirmedBlock: " + str(e))

        return loopchain_pb2.CommonReply(response_code=response_code,
                                         message=response_msg)
Ejemplo n.º 9
0
 def AnnounceDeletePeer(self, request, context):
     logging.debug(
         f"AnnounceDeletePeer peer_id({request.peer_id}) group_id({request.group_id})"
     )
     self.peer_service.peer_list.remove_peer(request.peer_id,
                                             request.group_id)
     return loopchain_pb2.CommonReply(response_code=0, message="success")
Ejemplo n.º 10
0
    def AnnounceNewPeer(self, request, context):
        """RadioStation에서 Broadcasting 으로 신규피어목록을 받아온다

        :param request: PeerRequest
        :param context:
        :return:
        """
        # RadioStation To Peer
        logging.info('Here Comes new peer: ' + str(request))
        if len(request.peer_object) > 0:
            peer = pickle.loads(request.peer_object)
            # 서버로부터 발급된 토큰 검증
            # Secure 인 경우 검증에 통과하여야만 peer_list에 추가함
            if self.peer_service.auth.is_secure\
                    and self.peer_service.auth.verify_new_peer(peer, loopchain_pb2.PEER) is False:
                # TODO AnnounceNewPeer 과정을 실패로 처리한다.
                logging.debug("New Peer Validation Fail")
            else:
                logging.debug("Add New Peer: " + str(peer.peer_id))
                self.peer_service.peer_list.add_peer_object(peer)
                logging.debug("Try save peer list...")
                self.peer_service.common_service.save_peer_list(
                    self.peer_service.peer_list)
        self.peer_service.show_peers()

        return loopchain_pb2.CommonReply(response_code=0, message="success")
Ejemplo n.º 11
0
    async def VoteUnconfirmedBlock(self, request, context):
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        utils.logger.info(f"vote({request.vote})")

        channel_stub = StubCollection().channel_stubs[channel_name]
        await channel_stub.async_task().vote_unconfirmed_block(request.vote)
        return loopchain_pb2.CommonReply(
            response_code=message_code.Response.success, message="success")
Ejemplo n.º 12
0
    def ComplainLeader(self, request, context):
        logging.debug("ComplainLeader: " + request.message)

        # TODO AnnounceComplained 메시지를 브로드 캐스트 하여 ComplainLeader 에 대한 투표를 받는다.
        # 수집후 AnnounceNewLeader 메시지에 ComplainLeader 투표 결과를 담아서 발송한다.
        # 현재 우선 AnnounceNewLeader 를 즉시 전송하게 구현한다. Leader Change 를 우선 확인하기 위한 임시 구현
        self.peer_service.peer_list.announce_new_leader(request.complained_leader_id, request.new_leader_id)

        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 13
0
    def UnSubscribe(self, request, context):
        """BlockGenerator 의 broadcast 채널에서 Peer 를 제외한다.

        :param request:
        :param context:
        :return:
        """
        self.peer_service.common_service.remove_audience(request.peer_id, request.peer_target)
        return loopchain_pb2.CommonReply(response_code=0, message="success")
Ejemplo n.º 14
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")
Ejemplo n.º 15
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")
Ejemplo n.º 16
0
    def Subscribe(self, request, context):
        """BlockGenerator 가 broadcast(unconfirmed or confirmed block) 하는 채널에
        Peer 를 등록한다.

        :param request:
        :param context:
        :return:
        """
        self.peer_service.common_service.add_audience(request)
        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))
Ejemplo n.º 17
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")
Ejemplo n.º 18
0
    def AddTxList(self, request: loopchain_pb2.TxSendList, context):
        """Add tx to Block Manager

        :param request:
        :param context:
        :return:
        """
        utils.logger.spam(f"peer_outer_service:AddTxList try validate_dumped_tx_message")
        channel_name = request.channel or conf.LOOPCHAIN_DEFAULT_CHANNEL
        StubCollection().channel_tx_receiver_stubs[channel_name].sync_task().add_tx_list(request)
        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 19
0
    def AnnounceUnconfirmedBlock(self, request, context):
        """수집된 tx 로 생성한 Block 을 각 peer 에 전송하여 검증을 요청한다.

        :param request:
        :param context:
        :return:
        """

        unconfirmed_block = pickle.loads(request.block)
        self.peer_service.block_manager.add_unconfirmed_block(unconfirmed_block)

        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 20
0
    def AddTx(self, request, context):
        """피어로부터 받은 tx 를 Block Manager 에 추가한다.
        이 기능은 Block Generator 에서만 동작해야 한다. 일반 Peer 는 이 기능을 사용할 권한을 가져서는 안된다.

        :param request:
        :param context:
        :return:
        """

        if self.peer_service.peer_type == loopchain_pb2.PEER:
            return loopchain_pb2.CommonReply(
                response_code=message_code.Response.fail_no_leader_peer,
                message=message_code.get_response_msg(message_code.Response.fail_no_leader_peer))
        else:  # Block Manager 에 tx 추가
            if self.peer_service.block_manager.consensus.block is None:
                return loopchain_pb2.CommonReply(
                    response_code=message_code.Response.fail_made_block_count_limited,
                    message="this leader can't make more block")

            self.peer_service.block_manager.add_tx_unloaded(request.tx)
            return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 21
0
    def AnnounceUnconfirmedBlock(self, request, context):
        """수집된 tx 로 생성한 Block 을 각 peer 에 전송하여 검증을 요청한다.

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

        channel_stub = StubCollection().channel_stubs[channel_name]
        channel_stub.sync_task().announce_unconfirmed_block(request.block)
        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 22
0
    def VoteUnconfirmedBlock(self, request, context):
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel

        util.logger.debug(f"VoteUnconfirmedBlock block_hash({request.block_hash})")

        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")
Ejemplo n.º 23
0
    async def ComplainLeader(self, request: ComplainLeaderRequest, context):
        channel = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        utils.logger.info(
            f"complain_vote: {request.complain_vote}, from_recovery({request.from_recovery!r})"
        )

        from_recovery = request.from_recovery if request.from_recovery else False

        channel_stub = StubCollection().channel_stubs[channel]
        await channel_stub.async_task().complain_leader(
            vote_dumped=request.complain_vote, from_recovery=from_recovery)

        return loopchain_pb2.CommonReply(
            response_code=message_code.Response.success, message="success")
Ejemplo n.º 24
0
    async def AddTxList(self, request: loopchain_pb2.TxSendList, context):
        """Add tx to Block Manager

        :param request:
        :param context:
        :return:
        """
        utils.logger.info(f"length of txlist: {len(request.tx_list)}")
        channel_name = request.channel or conf.LOOPCHAIN_DEFAULT_CHANNEL
        tx_receiver_stub = StubCollection(
        ).channel_tx_receiver_stubs[channel_name]
        await tx_receiver_stub.async_task().add_tx_list(request)
        return loopchain_pb2.CommonReply(
            response_code=message_code.Response.success, message="success")
Ejemplo n.º 25
0
    def AnnounceDeletePeer(self, request, context):
        """delete peer by radio station heartbeat, It delete peer info over whole channels.

        :param request:
        :param context:
        :return:
        """
        channel = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        logging.debug(f"AnnounceDeletePeer peer_id({request.peer_id}) group_id({request.group_id})")

        if self.peer_service.peer_id != request.peer_id:
            channel_stub = StubCollection().channel_stubs[channel]
            channel_stub.sync_task().delete_peer(request.peer_id, request.group_id)

        return loopchain_pb2.CommonReply(response_code=0, message="success")
Ejemplo n.º 26
0
    def ComplainLeader(self, request: ComplainLeaderRequest, context):
        channel = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        util.logger.notice(f"ComplainLeader "
                           f"height({request.block_height}) complained_peer({request.complained_leader_id})")

        channel_stub = StubCollection().channel_stubs[channel]
        channel_stub.sync_task().complain_leader(
            complained_leader_id=request.complained_leader_id,
            new_leader_id=request.new_leader_id,
            block_height=request.block_height,
            peer_id=request.peer_id,
            group_id=request.group_id
        )

        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 27
0
    def AnnounceNewPeer(self, request, context):
        """RadioStation에서 Broadcasting 으로 신규 피어정보를 받아온다

        :param request: PeerRequest
        :param context:
        :return:
        """
        # RadioStation To Peer
        # prevent to show certificate content
        # logging.info('Here Comes new peer: ' + str(request))
        channel = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        logging.debug(f"peer outer service::AnnounceNewPeer channel({channel})")

        if request.peer_object:
            channel_stub = StubCollection().channel_stubs[channel]
            channel_stub.sync_task().announce_new_peer(request.peer_object, request.peer_target)

        return loopchain_pb2.CommonReply(response_code=0, message="success")
Ejemplo n.º 28
0
    def AnnounceUnconfirmedBlock(self, request, context):
        """Send the UnconfirmedBlock includes collected transactions to reps and request to verify it.

        :param request:
        :param context:
        :return:
        """
        channel_name = conf.LOOPCHAIN_DEFAULT_CHANNEL if request.channel == '' else request.channel
        channel_stub = StubCollection().channel_stubs[channel_name]

        try:
            round_ = request.round_
        except AttributeError:
            round_ = 0

        asyncio.run_coroutine_threadsafe(
            channel_stub.async_task().announce_unconfirmed_block(request.block, round_),
            self.peer_service.inner_service.loop
        )
        return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 29
0
 def NotifyProcessError(self, request, context):
     """Peer Stop by Process Error
     """
     util.exit_and_msg(request.request)
     return loopchain_pb2.CommonReply(response_code=message_code.Response.success, message="success")
Ejemplo n.º 30
0
 def AnnounceNewLeader(self, request, context):
     logging.debug("AnnounceNewLeader: " + request.message)
     self.peer_service.reset_leader(request.new_leader_id)
     return loopchain_pb2.CommonReply(
         response_code=message_code.Response.success, message="success")