async def prepare_outgoing_message(
        self,
        receiver_node_id: NodeID,
        message: BaseMessage,
    ) -> OutgoingMessage:
        try:
            enr = await self.enr_db.get(receiver_node_id)
        except KeyError:
            raise ValueError(
                f"No ENR for peer {encode_hex(receiver_node_id)} known")

        try:
            ip_address = enr[IP_V4_ADDRESS_ENR_KEY]
        except KeyError:
            raise ValueError(
                f"ENR for peer {encode_hex(receiver_node_id)} does not contain an IP address"
            )

        try:
            udp_port = enr[UDP_PORT_ENR_KEY]
        except KeyError:
            raise ValueError(
                f"ENR for peer {encode_hex(receiver_node_id)} does not contain a UDP port"
            )

        outgoing_message = OutgoingMessage(
            message=message,
            receiver_endpoint=Endpoint(
                ip_address,
                udp_port,
            ),
            receiver_node_id=receiver_node_id,
        )
        return outgoing_message
Example #2
0
async def test_datagram_sender(socket_pair):
    sending_socket, receiving_socket = socket_pair
    receiver_endpoint = receiving_socket.getsockname()
    sender_endpoint = sending_socket.getsockname()

    send_channel, receive_channel = trio.open_memory_channel(1)
    async with background_trio_service(DatagramSender(receive_channel, sending_socket)):
        outgoing_datagram = OutgoingDatagram(
            b"some packet",
            Endpoint(inet_aton(receiver_endpoint[0]), receiver_endpoint[1]),
        )
        await send_channel.send(outgoing_datagram)

        with trio.fail_after(0.5):
            data, sender = await receiving_socket.recvfrom(1024)
        assert data == outgoing_datagram.datagram
        assert sender == sender_endpoint
Example #3
0
    async def ping(self, node_id: NodeID) -> None:
        local_enr = await self.get_local_enr()
        ping = PingMessage(
            request_id=self.message_dispatcher.get_free_request_id(node_id),
            enr_seq=local_enr.sequence_number,
        )

        try:
            with trio.fail_after(REQUEST_RESPONSE_TIMEOUT):
                incoming_message = await self.message_dispatcher.request(
                    node_id, ping)
        except ValueError as value_error:
            self.logger.warning(
                f"Failed to send ping to %s: %s",
                encode_hex(node_id),
                value_error,
            )
        except trio.TooSlowError:
            self.logger.warning(f"Ping to %s timed out", encode_hex(node_id))
        else:
            if not isinstance(incoming_message.message, PongMessage):
                self.logger.warning(
                    "Peer %s responded to Ping with %s instead of Pong",
                    encode_hex(node_id),
                    incoming_message.message.__class__.__name__,
                )
            else:
                self.logger.debug("Received Pong from %s", encode_hex(node_id))

                self.update_routing_table(node_id)

                pong = incoming_message.message
                local_endpoint = Endpoint(
                    ip_address=pong.packet_ip,
                    port=pong.packet_port,
                )
                endpoint_vote = EndpointVote(
                    endpoint=local_endpoint,
                    node_id=node_id,
                    timestamp=time.monotonic(),
                )
                await self.endpoint_vote_send_channel.send(endpoint_vote)

                await self.maybe_request_remote_enr(incoming_message)
    async def get_endpoint_from_node_db(self, receiver_node_id: NodeID) -> Endpoint:
        try:
            enr = self.node_db.get_enr(receiver_node_id)
        except KeyError:
            raise ValueError(f"No ENR for peer {encode_hex(receiver_node_id)} known")

        try:
            ip_address = enr[IP_V4_ADDRESS_ENR_KEY]
        except KeyError:
            raise ValueError(
                f"ENR for peer {encode_hex(receiver_node_id)} does not contain an IP address"
            )

        try:
            udp_port = enr[UDP_PORT_ENR_KEY]
        except KeyError:
            raise ValueError(
                f"ENR for peer {encode_hex(receiver_node_id)} does not contain a UDP port"
            )

        return Endpoint(ip_address, udp_port)