Exemple #1
0
    def __init__(
        self,
        local_private_key: keys.PrivateKey,
        local_node_id: NodeID,
        enr_db: ENRDatabaseAPI,
        outbound_envelope_send_channel: trio.abc.SendChannel[OutboundEnvelope],
        inbound_message_send_channel: trio.abc.SendChannel[AnyInboundMessage],
        session_cache_size: int,
        message_type_registry: MessageTypeRegistry = v51_registry,
        events: EventsAPI = None,
    ) -> None:
        self.local_private_key = local_private_key
        self.local_node_id = local_node_id

        self._enr_db = enr_db
        self._message_type_registry = message_type_registry

        if events is None:
            events = Events()
        self._events = events

        self._sessions = LRU(session_cache_size, callback=self._evict_session)
        self._sessions_by_endpoint = collections.defaultdict(set)

        self._outbound_packet_send_channel = outbound_envelope_send_channel
        self._inbound_message_send_channel = inbound_message_send_channel
Exemple #2
0
    def __init__(
        self,
        inbound_envelope_receive_channel: trio.abc.ReceiveChannel[InboundEnvelope],
        inbound_message_receive_channel: trio.abc.ReceiveChannel[AnyInboundMessage],
        pool: PoolAPI,
        enr_db: ENRDatabaseAPI,
        events: EventsAPI = None,
    ) -> None:
        self.logger = get_extended_debug_logger("ddht.Dispatcher")

        self._pool = pool
        self._enr_db = enr_db

        if events is None:
            events = Events()
        self._events = events

        self._inbound_envelope_receive_channel = inbound_envelope_receive_channel
        self._inbound_message_receive_channel = inbound_message_receive_channel

        (
            self._outbound_message_send_channel,
            self._outbound_message_receive_channel,
        ) = trio.open_memory_channel[AnyOutboundMessage](256)

        self.subscription_manager = SubscriptionManager()

        self._reserved_request_ids = set()
        self._active_request_ids = set()
Exemple #3
0
    def __init__(
        self,
        inbound_envelope_receive_channel: trio.abc.
        ReceiveChannel[InboundEnvelope],
        inbound_message_receive_channel: trio.abc.
        ReceiveChannel[AnyInboundMessage],
        pool: PoolAPI,
        enr_db: ENRDatabaseAPI,
        message_registry: MessageTypeRegistry = v51_registry,
        events: EventsAPI = None,
    ) -> None:
        self._registry = message_registry

        self._pool = pool
        self._enr_db = enr_db

        if events is None:
            events = Events()
        self._events = events

        self._inbound_envelope_receive_channel = inbound_envelope_receive_channel
        self._inbound_message_receive_channel = inbound_message_receive_channel

        (
            self._outbound_message_send_channel,
            self._outbound_message_receive_channel,
        ) = trio.open_memory_channel[AnyOutboundMessage](256)

        self._subscriptions = collections.defaultdict(set)

        self._reserved_request_ids = set()
        self._active_request_ids = set()
Exemple #4
0
 def __init__(
     self,
     private_key: keys.PrivateKey,
     endpoint: Endpoint,
     enr_db: ENRDatabaseAPI,
     events: Optional[EventsAPI] = None,
 ) -> None:
     self.private_key = private_key
     self.enr_db = enr_db
     self.enr = ENRFactory(
         private_key=private_key.to_bytes(),
         address__ip=endpoint.ip_address,
         address__udp_port=endpoint.port,
     )
     self.enr_db.set_enr(self.enr)
     if events is None:
         events = Events()
     self.events = events
Exemple #5
0
    def __init__(
        self,
        local_private_key: bytes,
        local_node_id: NodeID,
        remote_endpoint: Endpoint,
        enr_db: ENRDatabaseAPI,
        inbound_message_send_channel: trio.abc.SendChannel[AnyInboundMessage],
        outbound_envelope_send_channel: trio.abc.SendChannel[OutboundEnvelope],
        message_type_registry: MessageTypeRegistry = v51_registry,
        events: Optional[EventsAPI] = None,
    ) -> None:
        self.logger = get_extended_debug_logger("ddht.Session")

        self.id = uuid.uuid4()

        self.created_at = trio.current_time()
        self._handshake_complete = trio.Event()

        if events is None:
            events = Events()

        self._events = events
        self._nonce_counter = itertools.count()

        self._local_private_key = local_private_key
        self._local_node_id = local_node_id
        self.remote_endpoint = remote_endpoint
        self._enr_db = enr_db

        self._message_type_registry = message_type_registry

        self._status = SessionStatus.BEFORE

        (
            self._outbound_message_buffer_send_channel,
            self._outbound_message_buffer_receive_channel,
        ) = trio.open_memory_channel[AnyOutboundMessage](256)

        self._inbound_message_send_channel = inbound_message_send_channel
        self._outbound_envelope_send_channel = outbound_envelope_send_channel
Exemple #6
0
    async def run(self) -> None:
        self.manager.run_daemon_child_service(Canary())

        identity_scheme_registry = default_identity_scheme_registry

        message_type_registry = v51_registry

        enr_database_file = self._boot_info.base_dir / ENR_DATABASE_FILENAME
        enr_db: QueryableENRDatabaseAPI = QueryableENRDB(
            sqlite3.connect(enr_database_file), identity_scheme_registry)

        local_private_key = get_local_private_key(self._boot_info)

        enr_manager = ENRManager(
            enr_db=enr_db,
            private_key=local_private_key,
        )

        port = self._boot_info.port
        events = Events()

        if b"udp" not in enr_manager.enr:
            enr_manager.update((b"udp", port))
        elif enr_manager.enr[b"udp"] != port:
            enr_manager.update((b"udp", port))

        listen_on_ip_address: AnyIPAddress
        if self._boot_info.listen_on is None:
            listen_on_ip_address = DEFAULT_LISTEN
        else:
            listen_on_ip_address = self._boot_info.listen_on
            # Update the ENR if an explicit listening address was provided
            enr_manager.update(
                (IP_V4_ADDRESS_ENR_KEY, listen_on_ip_address.packed))

        listen_on = Endpoint(listen_on_ip_address.packed, self._boot_info.port)

        if self._boot_info.is_upnp_enabled:
            upnp_service = UPnPService(port)
            self.manager.run_daemon_child_service(upnp_service)
            self.manager.run_daemon_task(self._update_enr_ip_from_upnp,
                                         enr_manager, upnp_service)

        bootnodes = self._boot_info.bootnodes

        self.client = Client(
            local_private_key=local_private_key,
            listen_on=listen_on,
            enr_db=enr_db,
            session_cache_size=self._args.session_cache_size,
            events=events,
            message_type_registry=message_type_registry,
        )
        self.network = Network(
            client=self.client,
            bootnodes=bootnodes,
        )

        if self._boot_info.is_rpc_enabled:
            handlers = merge(
                get_core_rpc_handlers(enr_manager, self.network.routing_table),
                get_v51_rpc_handlers(self.network),
            )
            self.rpc_server = RPCServer(self._boot_info.ipc_path, handlers)
            self.manager.run_daemon_child_service(self.rpc_server)

        self.logger.info("Starting DDHT...")
        self.logger.info("Protocol-Version: %s",
                         self._boot_info.protocol_version.value)
        self.logger.info("DDHT base dir   : %s", self._boot_info.base_dir)
        self.logger.info("Listening on    : %s", listen_on)
        self.logger.info("Local Node ID   : %s",
                         encode_hex(enr_manager.enr.node_id))
        self.logger.info(
            "Local ENR       : seq=%d enr=%s",
            enr_manager.enr.sequence_number,
            enr_manager.enr,
        )

        self.manager.run_daemon_child_service(self.network)

        self._ready.set()

        await self.manager.wait_finished()
Exemple #7
0
    def __init__(
        self,
        local_private_key: keys.PrivateKey,
        listen_on: Endpoint,
        enr_db: ENRDatabaseAPI,
        events: EventsAPI = None,
        message_type_registry: MessageTypeRegistry = v51_registry,
    ) -> None:
        self._local_private_key = local_private_key

        self.listen_on = listen_on
        self._listening = trio.Event()

        self.enr_manager = ENRManager(
            private_key=local_private_key,
            enr_db=enr_db,
        )
        self.enr_db = enr_db
        self._registry = message_type_registry

        # Datagrams
        (
            self._outbound_datagram_send_channel,
            self._outbound_datagram_receive_channel,
        ) = trio.open_memory_channel[OutboundDatagram](256)
        (
            self._inbound_datagram_send_channel,
            self._inbound_datagram_receive_channel,
        ) = trio.open_memory_channel[InboundDatagram](256)

        # EnvelopePair
        (
            self._outbound_envelope_send_channel,
            self._outbound_envelope_receive_channel,
        ) = trio.open_memory_channel[OutboundEnvelope](256)
        (
            self._inbound_envelope_send_channel,
            self._inbound_envelope_receive_channel,
        ) = trio.open_memory_channel[InboundEnvelope](256)

        # Messages
        (
            self._outbound_message_send_channel,
            self._outbound_message_receive_channel,
        ) = trio.open_memory_channel[AnyOutboundMessage](256)
        (
            self._inbound_message_send_channel,
            self._inbound_message_receive_channel,
        ) = trio.open_memory_channel[AnyInboundMessage](256)

        if events is None:
            events = Events()
        self.events = events

        self.pool = Pool(
            local_private_key=self._local_private_key,
            local_node_id=self.enr_manager.enr.node_id,
            enr_db=self.enr_db,
            outbound_envelope_send_channel=self.
            _outbound_envelope_send_channel,
            inbound_message_send_channel=self._inbound_message_send_channel,
            message_type_registry=self._registry,
            events=self.events,
        )

        self.dispatcher = Dispatcher(
            self._inbound_envelope_receive_channel,
            self._inbound_message_receive_channel,
            self.pool,
            self.enr_db,
            self._registry,
            self.events,
        )
        self.envelope_decoder = EnvelopeEncoder(
            self._outbound_envelope_receive_channel,
            self._outbound_datagram_send_channel,
        )
        self.envelope_encoder = EnvelopeDecoder(
            self._inbound_datagram_receive_channel,
            self._inbound_envelope_send_channel,
            self.enr_manager.enr.node_id,
        )

        self._ready = trio.Event()
Exemple #8
0
def events():
    return Events()
Exemple #9
0
    async def run(self) -> None:
        identity_scheme_registry = default_identity_scheme_registry

        message_type_registry = v51_registry

        enr_database_dir = self._boot_info.base_dir / ENR_DATABASE_DIR_NAME
        enr_database_dir.mkdir(exist_ok=True)
        enr_db = ENRDB(LevelDB(enr_database_dir), identity_scheme_registry)

        local_private_key = get_local_private_key(self._boot_info)

        enr_manager = ENRManager(
            enr_db=enr_db,
            private_key=local_private_key,
        )

        port = self._boot_info.port
        events = Events()

        if b"udp" not in enr_manager.enr:
            enr_manager.update((b"udp", port))

        listen_on_ip_address: AnyIPAddress
        if self._boot_info.listen_on is None:
            listen_on_ip_address = DEFAULT_LISTEN
        else:
            listen_on_ip_address = self._boot_info.listen_on
            # Update the ENR if an explicit listening address was provided
            enr_manager.update(
                (IP_V4_ADDRESS_ENR_KEY, listen_on_ip_address.packed))

        listen_on = Endpoint(listen_on_ip_address.packed, self._boot_info.port)

        if self._boot_info.is_upnp_enabled:
            upnp_service = UPnPService(port)
            self.manager.run_daemon_child_service(upnp_service)
            self.manager.run_daemon_task(self._update_enr_ip_from_upnp,
                                         enr_manager, upnp_service)

        bootnodes = self._boot_info.bootnodes

        client = Client(
            local_private_key=local_private_key,
            listen_on=listen_on,
            enr_db=enr_db,
            events=events,
            message_type_registry=message_type_registry,
        )
        network = Network(
            client=client,
            bootnodes=bootnodes,
        )

        logger.info("Protocol-Version: %s",
                    self._boot_info.protocol_version.value)
        logger.info("DDHT base dir: %s", self._boot_info.base_dir)
        logger.info("Starting discovery service...")
        logger.info("Listening on %s:%d", listen_on, port)
        logger.info("Local Node ID: %s", encode_hex(enr_manager.enr.node_id))
        logger.info("Local ENR: seq=%d enr=%s",
                    enr_manager.enr.sequence_number, enr_manager.enr)

        await run_trio_service(network)