def announce_new_peer(self, peer_info_dumped, peer_target) -> None:
        try:
            peer_info = PeerInfo.load(peer_info_dumped)
        except Exception as e:
            traceback.print_exc()
            logging.error(
                f"Invalid peer info. peer_target={peer_target}, exception={e}")
            return

        logging.debug("Add New Peer: " + str(peer_info.peer_id))

        peer_manager = self._channel_service.peer_manager
        peer_manager.add_peer(peer_info)
        # broadcast the new peer to the others for adding an audience
        self._channel_service.broadcast_scheduler.schedule_job(
            BroadcastCommand.SUBSCRIBE, peer_target)

        logging.debug("Try save peer list...")
        # self._channel_service.save_peer_manager(peer_manager)
        self._channel_service.show_peers()

        if conf.CONSENSUS_ALGORITHM == conf.ConsensusAlgorithm.lft:
            quorum, complain_quorum = peer_manager.get_quorum()
            self._channel_service.consensus.set_quorum(
                quorum=quorum, complain_quorum=complain_quorum)
Example #2
0
    def leader_complain_to_rs(self,
                              group_id,
                              is_announce_new_peer=True) -> PeerInfo:
        """When fail to find a leader, Ask to RS.
        RS check leader and notify leader info or set new leader first peer who complained

        :param group_id:
        :param is_announce_new_peer:
        :return:
        """
        logging.debug(f"peer_manager:leader_complain_to_rs")

        if ObjectManager().peer_service.stub_to_radiostation is None:
            return None

        peer_self = self.get_peer(ObjectManager().peer_service.peer_id,
                                  ObjectManager().peer_service.group_id)
        peer_self_dumped = peer_self.dump()
        response = ObjectManager().peer_service.stub_to_radiostation.call(
            "Request",
            loopchain_pb2.Message(
                code=message_code.Request.peer_complain_leader,
                message=group_id,
                object=peer_self_dumped))

        if response is not None and response.code == message_code.Response.success:
            try:
                leader_peer = PeerInfo.load(response.object)
            except Exception as e:
                traceback.print_exc()
                logging.error(
                    f"Invalid peer info. Check your Radio Station. exception={e}"
                )
                return None
            self.set_leader_peer(leader_peer)
        else:
            leader_peer = None

        # logging.debug(str(leader_peer))
        # self.set_leader_peer(leader_peer)
        #
        # if is_announce_new_peer:
        #     self.announce_new_leader("", leader_peer.peer_id)

        return leader_peer
    async def get(self, request, request_type):
        # args = ServerComponents().parser.parse_args()
        args = request.raw_args
        channel = get_channel_name_from_args(args)
        logging.debug(f'channel name : {channel}')
        if request_type == self.__REQUEST_TYPE['PEER_LIST']:
            grpc_response = ServerComponents().get_peer_list(channel)

            peer_manager = PeerManager(channel)
            peer_list_data = PeerListData.load(grpc_response.peer_list)
            peer_manager.set_peer_list(peer_list_data)

            all_peer_list = []
            connected_peer_list = []

            if peer_manager.peer_list:
                leader_peer_id = ""

                # for set peer_type info to peer
                leader_peer = peer_manager.get_leader_peer(conf.ALL_GROUP_ID,
                                                           is_peer=False)
                if leader_peer is not None:
                    leader_peer_id = leader_peer.peer_id

                for peer_id in peer_manager.peer_list[conf.ALL_GROUP_ID]:
                    peer_each: PeerInfo = peer_manager.peer_list[
                        conf.ALL_GROUP_ID][peer_id]
                    peer_data = peer_each.serialize()

                    if peer_each.peer_id == leader_peer_id:
                        peer_data['peer_type'] = loopchain_pb2.BLOCK_GENERATOR
                    else:
                        peer_data['peer_type'] = loopchain_pb2.PEER

                    all_peer_list.append(peer_data)

                    if peer_each.status == PeerStatus.connected:
                        connected_peer_list.append(peer_data)

            json_data = {
                'registered_peer_count': len(all_peer_list),
                'connected_peer_count': len(connected_peer_list),
                'registered_peer_list': all_peer_list,
                'connected_peer_list': connected_peer_list
            }
            result = {
                'response_code': message_code.Response.success,
                'data': json_data
            }

        elif request_type == self.__REQUEST_TYPE['PEER_STATUS_LIST']:
            grpc_response = ServerComponents().get_peer_list(channel)

            peer_manager = PeerManager(channel)
            peer_list_data = PeerListData.load(grpc_response.peer_list)
            peer_manager.set_peer_list(peer_list_data)

            registered_peer_count = 0
            connected_peer_count = 0
            all_peer_list = []

            if peer_manager.peer_list:
                async_futures: List[grpc.Future] = []
                for peer_id in peer_manager.peer_list[conf.ALL_GROUP_ID]:
                    async_future = ServerComponents().get_peer_status_async(
                        peer_id, conf.ALL_GROUP_ID, channel)
                    async_futures.append(async_future)

                if async_futures:
                    futures.as_completed(async_futures)

                for async_future, peer_id in zip(
                        async_futures,
                        peer_manager.peer_list[conf.ALL_GROUP_ID]):
                    if async_future.exception():
                        logging.warning(
                            f'RequestType({request_type}), exception({async_future.exception()})'
                        )
                        continue

                    grpc_response = async_future.result()
                    if grpc_response is not None and grpc_response.status != "":
                        peer_each = peer_manager.peer_list[
                            conf.ALL_GROUP_ID][peer_id]
                        status_json = json.loads(grpc_response.status)
                        status_json["order"] = peer_each.order
                        all_peer_list.append(status_json)

                registered_peer_count = peer_manager.get_peer_count()
                connected_peer_count = peer_manager.get_connected_peer_count()

            json_data = {
                'registered_peer_count': registered_peer_count,
                'connected_peer_count': connected_peer_count,
                'peer_status_list': all_peer_list
            }
            result = {
                'response_code': message_code.Response.success,
                'data': json_data
            }

        elif request_type == self.__REQUEST_TYPE['LEADER_PEER']:
            grpc_response = ServerComponents().get_leader_peer(channel)

            result = dict()
            result['response_code'] = grpc_response.code

            if grpc_response.code == message_code.Response.success:
                peer_info = PeerInfo.load(grpc_response.object)
                result['data'] = peer_info.serialize()
            else:
                result['message'] = message_code.get_response_msg(
                    grpc_response.code)

        elif request_type == self.__REQUEST_TYPE['PEER_STATUS']:
            peer_id = args['peer_id']
            group_id = args['group_id']

            if peer_id is None or group_id is None:
                return self.__abort_if_arg_isnt_enough('peer_id, group_id')

            # logging.debug(f"try get_peer_status peer_id({peer_id}), group_id({group_id})")
            grpc_response = ServerComponents().get_peer_status(
                args['peer_id'], args['group_id'], channel)
            result = json.loads(grpc_response.status)

        else:
            return ServerComponents().abort_if_url_doesnt_exist(
                request_type, self.__REQUEST_TYPE)

        return response.json(result)