Beispiel #1
0
def test_uri():
    """Test URI class"""
    Uri(uri="localhost:9000")
    uri = Uri(host="localhost", port=9000)
    assert str(uri) == "localhost:9000"
    assert uri.host == "localhost"
    assert uri.port == 9000
    Uri()
    def __init__(self, **kwargs: Any) -> None:
        """Initialize a p2p libp2p connection."""
        super().__init__(**kwargs)
        ledger_id = self.configuration.config.get("ledger_id", DEFAULT_LEDGER)
        if ledger_id not in SUPPORTED_LEDGER_IDS:
            raise ValueError(  # pragma: nocover
                "Ledger id '{}' is not supported. Supported ids: '{}'".format(
                    ledger_id, SUPPORTED_LEDGER_IDS))
        libp2p_local_uri: Optional[str] = self.configuration.config.get(
            "local_uri")
        libp2p_public_uri: Optional[str] = self.configuration.config.get(
            "public_uri")
        libp2p_delegate_uri: Optional[str] = self.configuration.config.get(
            "delegate_uri")
        libp2p_monitoring_uri: Optional[str] = self.configuration.config.get(
            "monitoring_uri")
        libp2p_entry_peers = self.configuration.config.get("entry_peers")
        if libp2p_entry_peers is None:
            libp2p_entry_peers = []
        libp2p_entry_peers = list(cast(List, libp2p_entry_peers))
        log_file: Optional[str] = self.configuration.config.get("log_file")
        env_file: Optional[str] = self.configuration.config.get("env_file")
        peer_registration_delay: Optional[str] = self.configuration.config.get(
            "peer_registration_delay")
        records_storage_path: Optional[str] = self.configuration.config.get(
            "storage_path")
        node_connection_timeout: Optional[
            float] = self.configuration.config.get("node_connection_timeout")
        if (self.has_crypto_store and self.crypto_store.crypto_objects.get(
                ledger_id, None) is not None):  # pragma: no cover
            key = self.crypto_store.crypto_objects[ledger_id]
        else:
            raise ValueError(
                f"Couldn't find connection key for {str(ledger_id)} in connections keys. "
                "Please ensure agent private key is added with `aea add-key`.")

        uri = None
        if libp2p_local_uri is not None:
            uri = Uri(libp2p_local_uri)

        public_uri = None
        if libp2p_public_uri is not None:
            public_uri = Uri(libp2p_public_uri)

        delegate_uri = None
        if libp2p_delegate_uri is not None:
            delegate_uri = Uri(libp2p_delegate_uri)

        monitoring_uri = None
        if libp2p_monitoring_uri is not None:
            monitoring_uri = Uri(libp2p_monitoring_uri)  # pragma: nocover

        entry_peers = [
            MultiAddr.from_string(str(maddr)) for maddr in libp2p_entry_peers
        ]

        delay = None
        if peer_registration_delay is not None:
            try:
                delay = float(peer_registration_delay)
            except ValueError:
                raise ValueError(
                    f"peer_registration_delay {peer_registration_delay} must be a float number in seconds"
                )

        if public_uri is None:
            # node will be run as a ClientDHT
            # requires entry peers to use as relay
            if entry_peers is None or len(entry_peers) == 0:
                raise ValueError(  # pragma: no cover
                    "At least one Entry Peer should be provided when node is run in relayed mode"
                )
            if delegate_uri is not None:  # pragma: no cover
                self.logger.warning(
                    "Ignoring Delegate Uri configuration as node is run in relayed mode"
                )
        else:
            # node will be run as a full NodeDHT
            if uri is None:
                raise ValueError(  # pragma: no cover
                    "Local Uri must be set when Public Uri is provided. "
                    "Hint: they are the same for local host/network deployment"
                )
            # check if node's public host and entry peers hosts are either
            #  both private or both public
            if not _ip_all_private_or_all_public(
                [public_uri.host] + [maddr.host for maddr in entry_peers]):
                raise ValueError(  # pragma: nocover
                    "Node's public ip and entry peers ip addresses are not in the same ip address space (private/public)"
                )

        cert_requests = self.configuration.cert_requests
        if cert_requests is None or len(cert_requests) != 1:
            raise ValueError(  # pragma: no cover
                "cert_requests field must be set and contain exactly one entry!"
            )
        cert_request = cert_requests[0]

        agent_record = AgentRecord.from_cert_request(cert_request,
                                                     self.address,
                                                     key.public_key,
                                                     Path(self.data_dir))

        # libp2p local node
        self.logger.debug("Public key used by libp2p node: {}".format(
            key.public_key))

        module_dir = self._check_node_built()
        self.node = Libp2pNode(
            agent_record,
            key,
            module_dir,
            self.data_dir,
            LIBP2P_NODE_CLARGS,
            uri,
            public_uri,
            delegate_uri,
            monitoring_uri,
            entry_peers,
            log_file,
            env_file,
            self.logger,
            delay,
            records_storage_path,
            node_connection_timeout,
            max_restarts=self.configuration.config.get(
                "max_node_restarts", self.DEFAULT_MAX_RESTARTS),
        )

        self._in_queue = None  # type: Optional[asyncio.Queue]
        self._receive_from_node_task = None  # type: Optional[asyncio.Future]
    def __init__(
        self,
        agent_record: AgentRecord,
        key: Crypto,
        module_path: str,
        data_dir: str,
        clargs: Optional[List[str]] = None,
        uri: Optional[Uri] = None,
        public_uri: Optional[Uri] = None,
        delegate_uri: Optional[Uri] = None,
        monitoring_uri: Optional[Uri] = None,
        entry_peers: Optional[Sequence[MultiAddr]] = None,
        log_file: Optional[str] = None,
        env_file: Optional[str] = None,
        logger: logging.Logger = _default_logger,
        peer_registration_delay: Optional[float] = None,
        records_storage_path: Optional[str] = None,
        connection_timeout: Optional[float] = None,
        max_restarts: int = 5,
    ):
        """
        Initialize a p2p libp2p node.

        :param agent_record: the agent proof-of-representation for peer.
        :param key: secp256k1 curve private key.
        :param module_path: the module path.
        :param clargs: the command line arguments for the libp2p node
        :param uri: libp2p node ip address and port number in format ipaddress:port.
        :param public_uri: libp2p node public ip address and port number in format ipaddress:port.
        :param delegate_uri: libp2p node delegate service ip address and port number in format ipaddress:port.
        :param monitoring_uri: libp2 node monitoring ip address and port in fromat ipaddress:port
        :param entry_peers: libp2p entry peers multiaddresses.
        :param log_file: the logfile path for the libp2p node
        :param env_file: the env file path for the exchange of environment variables
        :param logger: the logger.
        :param peer_registration_delay: add artificial delay to agent registration in seconds
        :param connection_timeout: the connection timeout of the node
        :param max_restarts: amount of node restarts during operation
        """

        self.record = agent_record
        self.address = self.record.address

        # node id in the p2p network
        self.key = key.private_key
        self.pub = key.public_key

        # node uri
        self.uri = uri if uri is not None else Uri()

        # node public uri, optional
        self.public_uri = public_uri

        # node delegate uri, optional
        self.delegate_uri = delegate_uri

        # node monitoring uri, optional
        self.monitoring_uri = monitoring_uri

        # entry peer
        self.entry_peers = entry_peers if entry_peers is not None else []

        # peer configuration
        self.peer_registration_delay = peer_registration_delay
        self.records_storage_path = records_storage_path
        if (self.records_storage_path is not None
                and not Path(self.records_storage_path).is_absolute()):
            self.records_storage_path = os.path.join(  # pragma: nocover
                data_dir, self.records_storage_path)

        # node startup
        self.source = os.path.abspath(module_path)
        self.clargs = clargs if clargs is not None else []

        # node libp2p multiaddrs
        self.multiaddrs = []  # type: Sequence[MultiAddr]

        # log file
        self.log_file = log_file if log_file is not None else LIBP2P_NODE_LOG_FILE
        if not Path(self.log_file).is_absolute():
            self.log_file = os.path.join(data_dir,
                                         self.log_file)  # pragma: nocover
        # env file
        self.env_file = env_file if env_file is not None else LIBP2P_NODE_ENV_FILE
        if not Path(self.env_file).is_absolute():
            self.env_file = os.path.join(data_dir, self.env_file)

        # named pipes (fifos)
        self.pipe = None  # type: Optional[IPCChannel]

        self._loop = None  # type: Optional[AbstractEventLoop]
        self.proc = None  # type: Optional[subprocess.Popen]
        self._log_file_desc = None  # type: Optional[IO[str]]

        self._config = ""
        self.logger = logger
        self._connection_timeout = (connection_timeout if connection_timeout
                                    is not None else PIPE_CONN_TIMEOUT)
        self._max_restarts = max_restarts
        self._restart_counter: int = 0
Beispiel #4
0
    def __init__(self, **kwargs: Any) -> None:
        """Initialize a libp2p client connection."""
        super().__init__(**kwargs)

        self.connect_retries = self.configuration.config.get(
            "connect_retries", self.DEFAULT_CONNECT_RETRIES)
        ledger_id = self.configuration.config.get("ledger_id", DEFAULT_LEDGER)
        if ledger_id not in SUPPORTED_LEDGER_IDS:
            raise ValueError(  # pragma: nocover
                "Ledger id '{}' is not supported. Supported ids: '{}'".format(
                    ledger_id, SUPPORTED_LEDGER_IDS))

        key_file = self.configuration.config.get(
            "client_key_file")  # Optional[str]
        nodes = self.configuration.config.get("nodes")

        if nodes is None:
            raise ValueError("At least one node should be provided")
        nodes = list(cast(List, nodes))

        nodes_uris = [node.get("uri", None) for node in nodes]
        enforce(
            len(nodes_uris) == len(nodes) and None not in nodes_uris,
            "Delegate 'uri' should be provided for each node",
        )

        nodes_public_keys = [node.get("public_key", None) for node in nodes]
        enforce(
            len(nodes_public_keys) == len(nodes)
            and None not in nodes_public_keys,
            "Delegate 'public_key' should be provided for each node",
        )

        cert_requests = self.configuration.cert_requests
        if cert_requests is None or len(cert_requests) != len(nodes):
            raise ValueError(  # pragma: nocover
                "cert_requests field must be set and contain exactly as many entries as 'nodes'!"
            )
        for cert_request in cert_requests:
            save_path = cert_request.get_absolute_save_path(Path(
                self.data_dir))
            if not save_path.is_file():
                raise Exception(  # pragma: nocover
                    "cert_request 'save_path' field is not a file. "
                    "Please ensure that 'issue-certificates' command is called beforehand"
                )

        # TOFIX(): we cannot use store as the key will be used for TLS tcp connection
        #   also, as of now all the connections share the same key
        if key_file is not None:
            key = make_crypto(ledger_id, private_key_path=key_file)
        else:
            key = make_crypto(ledger_id)

        # client connection id
        self.key = key
        self.logger.debug("Public key used by libp2p client: {}".format(
            key.public_key))

        # delegate uris
        self.delegate_uris = [Uri(node_uri) for node_uri in nodes_uris]

        # delegates PoRs
        self.delegate_pors: List[AgentRecord] = []
        for i, cert_request in enumerate(cert_requests):
            agent_record = AgentRecord.from_cert_request(
                cert_request, self.address, nodes_public_keys[i],
                self.data_dir)
            self.delegate_pors.append(agent_record)

        # select a delegate
        index = random.randint(0, len(self.delegate_uris) - 1)  # nosec
        self.node_uri = self.delegate_uris[index]
        self.node_por = self.delegate_pors[index]
        self.logger.debug("Node to use as delegate: {}".format(self.node_uri))

        # tcp connection
        self._reader = None  # type: Optional[asyncio.StreamReader]
        self._writer = None  # type: Optional[asyncio.StreamWriter]

        self._in_queue = None  # type: Optional[asyncio.Queue]
        self._process_messages_task = None  # type: Union[asyncio.Future, None]