Exemplo n.º 1
0
def menu4_1(params=None):
    admin_manager = AdminManager("demotool")

    print("\nInput Peer Target [IP]:[port] (default '' -> 127.0.0.1:7100, [port] -> 127.0.0.1:[port])")
    choice = input(" >>  ")
    if choice == "":
        choice = "127.0.0.1:7100"
    elif choice.find(':') == -1:
        choice = "127.0.0.1:" + choice

    select_channel_index = 0
    select_channel_string = ""
    for channel in admin_manager.get_channel_list():
        if select_channel_index != 0:
            select_channel_string += ", "
        select_channel_string += f"{select_channel_index}: {admin_manager.get_channel_list()[select_channel_index]}"
        select_channel_index += 1

    print(f"Select Channel ({select_channel_string})")
    channel_choice = input(" >>  ")
    try:
        test_globals["channel_name"] = admin_manager.get_channel_list()[int(channel_choice)]
    except Exception as e:
        print(f"wrong channel number! Now use default channel({admin_manager.get_channel_list()[0]})\n")
        test_globals["channel_name"] = admin_manager.get_channel_list()[0]

    print("your input: " + choice)
    channel = grpc.insecure_channel(choice)
    peer_stub = loopchain_pb2_grpc.PeerServiceStub(channel)
    response = peer_stub.GetStatus(loopchain_pb2.StatusRequest(request="hello"), conf.GRPC_TIMEOUT)
    print("Peer Status: " + str(response))
    menu4(peer_stub)
Exemplo n.º 2
0
    def __get_peer_stub_list(self):
        """It updates peer list for block manager refer to peer list on the loopchain network.
        This peer list is not same to the peer list of the loopchain network.

        :return max_height: a height of current blockchain
        :return peer_stubs: current peer list on the loopchain network
        """
        max_height = -1  # current max height
        unconfirmed_block_height = -1
        peer_stubs = []  # peer stub list for block height synchronization

        if not ObjectManager().channel_service.is_support_node_function(
                conf.NodeFunction.Vote):
            rest_stub = ObjectManager().channel_service.radio_station_stub
            peer_stubs.append(rest_stub)
            last_block = rest_stub.call("GetLastBlock")
            max_height = self.__blockchain.block_versioner.get_height(
                last_block)

            return max_height, unconfirmed_block_height, peer_stubs

        # Make Peer Stub List [peer_stub, ...] and get max_height of network
        peer_target = ChannelProperty().peer_target
        peer_manager = ObjectManager().channel_service.peer_manager
        target_dict = peer_manager.get_IP_of_peers_dict()
        target_list = [
            peer_target for peer_id, peer_target in target_dict.items()
            if peer_id != ChannelProperty().peer_id
        ]

        for target in target_list:
            if target != peer_target:
                logging.debug(f"try to target({target})")
                channel = GRPCHelper().create_client_channel(target)
                stub = loopchain_pb2_grpc.PeerServiceStub(channel)
                try:
                    response = stub.GetStatus(
                        loopchain_pb2.StatusRequest(
                            request="",
                            channel=self.__channel_name,
                        ), conf.GRPC_TIMEOUT_SHORT)

                    response.block_height = max(
                        response.block_height,
                        response.unconfirmed_block_height)

                    if response.block_height > max_height:
                        # Add peer as higher than this
                        max_height = response.block_height
                        unconfirmed_block_height = response.unconfirmed_block_height
                        peer_stubs.append(stub)

                except Exception as e:
                    logging.warning(
                        f"This peer has already been removed from the block height target node. {e}"
                    )

        return max_height, unconfirmed_block_height, peer_stubs
Exemplo n.º 3
0
    def __get_peer_stub_list(self, target_peer_stub=None):
        """It updates peer list for block manager refer to peer list on the loopchain network.
        This peer list is not same to the peer list of the loopchain network.

        :return max_height: a height of current blockchain
        :return peer_stubs: current peer list on the loopchain network
        """
        peer_target = ChannelProperty().peer_target
        peer_manager = ObjectManager().channel_service.peer_manager

        # Make Peer Stub List [peer_stub, ...] and get max_height of network
        max_height = -1  # current max height
        peer_stubs = []  # peer stub list for block height synchronization

        if ObjectManager().channel_service.is_support_node_function(
                conf.NodeFunction.Vote):
            target_dict = peer_manager.get_IP_of_peers_dict()
            target_list = [
                peer_target for peer_id, peer_target in target_dict.items()
                if peer_id != ChannelProperty().peer_id
            ]
        else:
            target_list = [f"{target_peer_stub.target}"]

        for target in target_list:
            if target != peer_target:
                logging.debug(f"try to target({target})")
                channel = GRPCHelper().create_client_channel(target)
                stub = loopchain_pb2_grpc.PeerServiceStub(channel)
                try:
                    if ObjectManager(
                    ).channel_service.is_support_node_function(
                            conf.NodeFunction.Vote):
                        response = stub.GetStatus(
                            loopchain_pb2.StatusRequest(
                                request="",
                                channel=self.__channel_name,
                            ), conf.GRPC_TIMEOUT_SHORT)
                    else:
                        response = target_peer_stub.call("Status")
                        util.logger.spam('{/api/v1/status/peer} response: ' +
                                         response.text)
                        response.block_height = int(
                            json.loads(response.text)["block_height"])
                        stub.target = target

                    if response.block_height > max_height:
                        # Add peer as higher than this
                        max_height = response.block_height
                        peer_stubs.append(stub)

                except Exception as e:
                    logging.warning(
                        f"This peer has already been removed from the block height target node. {e}"
                    )

        return max_height, peer_stubs
Exemplo n.º 4
0
def run_black_peer_server_as_process_and_stub(port,
                                              radiostation_port=conf.
                                              PORT_RADIOSTATION,
                                              group_id=None):
    process = run_black_peer_server_as_process(port, radiostation_port,
                                               group_id)
    channel = grpc.insecure_channel('localhost:' + str(port))
    stub = loopchain_pb2_grpc.PeerServiceStub(channel)
    return process, stub
Exemplo n.º 5
0
 def __handler_connect(self, request, context):
     """make stub to peer service
     
     :param request: message=target of peer_service
     :param context: 
     :return: 
     """
     logging.debug("__handler_connect %s", request.message)
     self.__stub_to_peer_service = loopchain_pb2_grpc.PeerServiceStub(grpc.insecure_channel(request.message))
     return_code = (message_code.Response.success, message_code.Response.fail)[self.__stub_to_peer_service is None]
     return loopchain_pb2.Message(code=return_code)
Exemplo n.º 6
0
def run_peer_server_as_process_and_stub(
        port,
        radiostation_port=conf.PORT_RADIOSTATION,
        group_id=None,
        score=None):
    process = run_peer_server_as_process(port, radiostation_port, group_id,
                                         score)
    channel = grpc.insecure_channel('localhost:' + str(port))
    stub = loopchain_pb2_grpc.PeerServiceStub(channel)
    util.request_server_in_time(stub.GetStatus,
                                loopchain_pb2.StatusRequest(request=""))
    return process, stub
Exemplo n.º 7
0
def menu4_1(params=None):
    print(
        "Input Peer Target [IP]:[port] (default '' -> 127.0.0.1:7100, [port] -> 127.0.0.1:[port])"
    )
    choice = input(" >>  ")
    if choice == "":
        choice = "127.0.0.1:7100"
    elif choice.find(':') == -1:
        choice = "127.0.0.1:" + choice

    print("your input: " + choice)
    channel = grpc.insecure_channel(choice)
    peer_stub = loopchain_pb2_grpc.PeerServiceStub(channel)
    response = peer_stub.GetStatus(
        loopchain_pb2.StatusRequest(request="hello"), conf.GRPC_TIMEOUT)
    print("Peer Status: " + str(response))
    menu4(peer_stub)
Exemplo n.º 8
0
    def _get_peer_stub_list(self) -> Tuple[int, int, List[Tuple[str, Any]]]:
        """It updates peer list for block manager refer to peer list on the loopchain network.
        This peer list is not same to the peer list of the loopchain network.

        :return max_height: a height of current blockchain
        :return unconfirmed_block_height: unconfirmed_block_height on the network
        :return peer_stubs: current peer list on the network (target, peer_stub)
        """
        max_height = -1  # current max height
        unconfirmed_block_height = -1
        peer_stubs = []  # peer stub list for block height synchronization

        rs_client: RestClient = self._channel_service.rs_client

        if not self._channel_service.is_support_node_function(
                conf.NodeFunction.Vote):
            status_response = rs_client.call(RestMethod.Status)
            max_height = status_response['block_height']
            peer_stubs.append((rs_client.target, rs_client))
            return max_height, unconfirmed_block_height, peer_stubs

        # Make Peer Stub List [peer_stub, ...] and get max_height of network
        self._block_height_sync_bad_targets = {
            k: v
            for k, v in self._block_height_sync_bad_targets.items()
            if v > self._blockchain.block_height
        }
        utils.logger.info(
            f"Bad Block Sync Peer : {self._block_height_sync_bad_targets}")
        peer_target = ChannelProperty().peer_target
        my_height = self._blockchain.block_height

        port_pattern = re.compile(r":([0-9]{2,5})$")

        def _converter(target) -> str:
            port = int(port_pattern.search(target).group(1))
            new_port = f":{port + conf.PORT_DIFF_REST_SERVICE_CONTAINER}"
            return port_pattern.sub(new_port, target)

        endpoints = {
            target: _converter(target)
            for target in self._block_manager.get_target_list()
        }

        for grpc_endpoint, rest_endpoint in endpoints.items():
            if grpc_endpoint == peer_target:
                continue
            if grpc_endpoint in self._block_height_sync_bad_targets:
                continue
            utils.logger.debug(
                f"try to grpc_endpoint({grpc_endpoint}), rest_endpoint({rest_endpoint})"
            )
            channel = GRPCHelper().create_client_channel(grpc_endpoint)
            stub = loopchain_pb2_grpc.PeerServiceStub(channel)
            try:
                client = RestClient(self._block_manager.channel_name,
                                    rest_endpoint)
                response: dict = client.call(RestMethod.Status,
                                             timeout=conf.REST_TIMEOUT)
                target_block_height = max(response["block_height"],
                                          response["unconfirmed_block_height"])

                recovery = response.get("recovery", {})
                # only recovery_mode node should be included in block sync when running by recovery_mode
                if conf.RECOVERY_MODE and not recovery.get("mode", False):
                    continue

                if target_block_height > my_height:
                    peer_stubs.append((grpc_endpoint, stub))
                    max_height = max(max_height, target_block_height)
                    unconfirmed_block_height = max(
                        unconfirmed_block_height,
                        response["unconfirmed_block_height"])

            except Exception as e:
                utils.logger.warning(
                    f"This peer has already been removed from the block height target node. {e!r}"
                )

        return max_height, unconfirmed_block_height, peer_stubs
Exemplo n.º 9
0
 def set_stub_port(self, port):
     self.__stub_to_peer_service = loopchain_pb2_grpc.PeerServiceStub(
         grpc.insecure_channel(conf.IP_LOCAL + ':' + str(port)))
Exemplo n.º 10
0
    def block_height_sync(self, target_peer_stub=None):
        """block height sync with other peers
        """

        if self.__block_height_sync_lock is True:
            # ***** 이 보정 프로세스는 AnnounceConfirmBlock 메시지를 받았을때 블럭 Height 차이로 Peer 가 처리하지 못한 경우에도 진행한다.
            # 따라서 이미 sync 가 진행 중일때의 요청은 무시한다.
            logging.warning("block height sync is already running...")
            return

        peer_target = ObjectManager().peer_service.peer_target
        peer_manager = ObjectManager(
        ).peer_service.channel_manager.get_peer_manager(self.__channel_name)
        block_manager = ObjectManager(
        ).peer_service.channel_manager.get_block_manager(self.__channel_name)

        self.__block_height_sync_lock = True
        if target_peer_stub is None:
            target_peer_stub = peer_manager.get_leader_stub_manager()

        ### Block Height 보정 작업, Peer의 데이타 동기화 Process ###
        ### Love&Hate Algorithm ###
        logging.info("try block height sync...with love&hate")

        # Make Peer Stub List [peer_stub, ...] and get max_height of network
        max_height = 0
        peer_stubs = []
        target_list = list(peer_manager.get_IP_of_peers_in_group())
        for peer_target_each in target_list:
            target = ":".join(peer_target_each.split(":")[1:])
            if target != peer_target:
                logging.debug(f"try to target({target})")
                channel = grpc.insecure_channel(target)
                stub = loopchain_pb2_grpc.PeerServiceStub(channel)
                try:
                    response = stub.GetStatus(
                        loopchain_pb2.StatusRequest(
                            request="", channel=self.__channel_name))
                    if response.block_height > max_height:
                        # Add peer as higher than this
                        max_height = response.block_height
                        peer_stubs.append(stub)
                except Exception as e:
                    logging.warning("Already bad.... I don't love you" +
                                    str(e))

        if len(peer_stubs) == 0:
            util.logger.warning(
                f"peer_service:block_height_sync there is no other peer to height sync!"
            )
            self.__block_height_sync_lock = False
            return

        my_height = block_manager.get_blockchain().block_height

        if max_height > my_height:  # 자기가 가장 높은 블럭일때 처리 필요 TODO
            logging.info(
                f"You need block height sync to: {max_height} yours: {my_height}"
            )
            # 자기(현재 Peer)와 다르면 Peer 목록을 순회하며 마지막 block 에서 자기 Height Block 까지 역순으로 요청한다.
            # (blockchain 의 block 탐색 로직 때문에 height 순으로 조회는 비효율적이다.)

            preload_blocks = {}  # height : block dictionary

            # Target Peer 의 마지막 block hash 부터 시작한다.
            response = target_peer_stub.call(
                "GetLastBlockHash",
                loopchain_pb2.StatusRequest(request="",
                                            channel=self.__channel_name))
            logging.debug(response)
            request_hash = response.block_hash

            max_try = max_height - my_height
            while block_manager.get_blockchain().last_block.block_hash \
                    != request_hash and max_try > 0:

                for peer_stub in peer_stubs:
                    response = None
                    try:
                        # 이때 요청 받은 Peer 는 해당 Block 과 함께 자신의 현재 Height 를 같이 보내준다.
                        # TODO target peer 의 마지막 block 보다 높은 Peer 가 있으면 현재 target height 까지 완료 후
                        # TODO Height Sync 를 다시 한다.
                        response = peer_stub.BlockSync(
                            loopchain_pb2.BlockSyncRequest(
                                block_hash=request_hash,
                                channel=self.__channel_name),
                            conf.GRPC_TIMEOUT)
                    except Exception as e:
                        logging.warning("There is a bad peer, I hate you: " +
                                        str(e))

                    if response is not None and response.response_code == message_code.Response.success:
                        util.logger.spam(
                            f"response block_height({response.block_height})")
                        dump = response.block
                        block = pickle.loads(dump)

                        # 마지막 블럭에서 역순으로 블럭을 구한다.
                        request_hash = block.prev_block_hash

                        # add block to preload_blocks
                        logging.debug("Add preload_blocks Height: " +
                                      str(block.height))
                        preload_blocks[block.height] = block

                        if response.max_block_height > max_height:
                            max_height = response.max_block_height

                        if (my_height + 1) == block.height:
                            max_try = 0  # 더이상 요청을 진행하지 않는다.
                            logging.info("Block Height Sync Complete.")
                            break
                        max_try -= 1
                    else:
                        # 이 반복 요청중 응답 하지 않은 Peer 는 반복중에 다시 요청하지 않는다.
                        # (TODO: 향후 Bad에 대한 리포트 전략은 별도로 작업한다.)
                        peer_stubs.remove(peer_stub)
                        logging.warning(
                            "Make this peer to bad (error above or no response): "
                            + str(peer_stub))

            if preload_blocks.__len__() > 0:
                while my_height < max_height:
                    add_height = my_height + 1
                    logging.debug("try add block height: " + str(add_height))
                    try:
                        block_manager.add_block(preload_blocks[add_height])
                        my_height = add_height
                    except KeyError as e:
                        logging.error("fail block height sync: " + str(e))
                        break
                    except exception.BlockError as e:
                        logging.error(
                            "Block Error Clear all block and restart peer.")
                        block_manager.clear_all_blocks()
                        util.exit_and_msg(
                            "Block Error Clear all block and restart peer.")

            if my_height < max_height:
                # block height sync 가 완료되지 않았으면 다시 시도한다.
                logging.warning(
                    "fail block height sync in one time... try again...")
                self.__block_height_sync_lock = False
                self.block_height_sync(target_peer_stub)

        self.__block_height_sync_lock = False
Exemplo n.º 11
0
    def __get_peer_stub_list(self) -> Tuple[int, int, List[Tuple]]:
        """It updates peer list for block manager refer to peer list on the loopchain network.
        This peer list is not same to the peer list of the loopchain network.

        :return max_height: a height of current blockchain
        :return unconfirmed_block_height: unconfirmed_block_height on the network
        :return peer_stubs: current peer list on the network (target, peer_stub)
        """
        max_height = -1  # current max height
        unconfirmed_block_height = -1
        peer_stubs = []  # peer stub list for block height synchronization

        if not ObjectManager().channel_service.is_support_node_function(
                conf.NodeFunction.Vote):
            rs_client = ObjectManager().channel_service.rs_client
            status_response = rs_client.call(RestMethod.Status)
            max_height = status_response['block_height']
            peer_stubs.append((rs_client.target, rs_client))
            return max_height, unconfirmed_block_height, peer_stubs

        # Make Peer Stub List [peer_stub, ...] and get max_height of network
        self.__block_height_sync_bad_targets = {
            k: v
            for k, v in self.__block_height_sync_bad_targets.items()
            if v > self.blockchain.block_height
        }
        util.logger.info(
            f"Bad Block Sync Peer : {self.__block_height_sync_bad_targets}")
        peer_target = ChannelProperty().peer_target
        my_height = self.blockchain.block_height

        if self.blockchain.last_block:
            reps_hash = self.blockchain.get_reps_hash_by_header(
                self.blockchain.last_block.header)
        else:
            reps_hash = ChannelProperty().crep_root_hash
        rep_targets = self.blockchain.find_preps_targets_by_roothash(reps_hash)
        target_list = list(rep_targets.values())
        for target in target_list:
            if target == peer_target:
                continue
            if target in self.__block_height_sync_bad_targets:
                continue
            util.logger.debug(f"try to target({target})")
            channel = GRPCHelper().create_client_channel(target)
            stub = loopchain_pb2_grpc.PeerServiceStub(channel)
            try:
                response = stub.GetStatus(
                    loopchain_pb2.StatusRequest(
                        request='block_sync',
                        channel=self.__channel_name,
                    ), conf.GRPC_TIMEOUT_SHORT)
                target_block_height = max(response.block_height,
                                          response.unconfirmed_block_height)

                if target_block_height > my_height:
                    peer_stubs.append((target, stub))
                    max_height = max(max_height, target_block_height)
                    unconfirmed_block_height = max(
                        unconfirmed_block_height,
                        response.unconfirmed_block_height)

            except Exception as e:
                util.logger.warning(
                    f"This peer has already been removed from the block height target node. {e}"
                )

        return max_height, unconfirmed_block_height, peer_stubs
Exemplo n.º 12
0
 def set_stub_port(self, port, IP_address):
     self.__stub_to_peer_service = loopchain_pb2_grpc.PeerServiceStub(
         grpc.insecure_channel(IP_address + ':' + str(port)))