diff --git a/libp2p/identity/identify/protocol.py b/libp2p/identity/identify/protocol.py index 98e6effe..e157a85c 100644 --- a/libp2p/identity/identify/protocol.py +++ b/libp2p/identity/identify/protocol.py @@ -39,6 +39,24 @@ def _multiaddr_to_bytes(maddr: Multiaddr) -> bytes: return maddr.to_bytes() +def _remote_address_to_multiaddr( + remote_address: Optional[tuple[str, int]] +) -> Optional[Multiaddr]: + """Convert a (host, port) tuple to a Multiaddr.""" + if remote_address is None: + return None + + host, port = remote_address + + # Check if the address is IPv6 (contains ':') + if ":" in host: + # IPv6 address + return Multiaddr(f"/ip6/{host}/tcp/{port}") + else: + # IPv4 address + return Multiaddr(f"/ip4/{host}/tcp/{port}") + + def _mk_identify_protobuf( host: IHost, observed_multiaddr: Optional[Multiaddr] ) -> Identify: @@ -60,23 +78,28 @@ def _mk_identify_protobuf( def identify_handler_for(host: IHost) -> StreamHandlerFn: async def handle_identify(stream: INetStream) -> None: # get observed address from ``stream`` - # class Swarm(Service, INetworkService): - # TODO: Connection and `peer_id` are 1-1 mapping in our implementation, - # whereas in Go one `peer_id` may point to multiple connections. - # connections: dict[ID, INetConn] - # Luca: So I'm assuming that the connection is 1-1 mapping for now - peer_id = stream.muxed_conn.peer_id # remote peer_id - peer_store = host.get_peerstore() # get the peer store from the host - remote_peer_multiaddrs = peer_store.addrs( - peer_id - ) # get the Multiaddrs for the remote peer_id - logger.debug("multiaddrs of remote peer is %s", remote_peer_multiaddrs) - logger.debug("received a request for %s from %s", ID, peer_id) + peer_id = ( + stream.muxed_conn.peer_id + ) # remote peer_id is in class Mplex (mplex.py ) + + # Get the remote address + try: + remote_address = stream.get_remote_address() + # Convert to multiaddr + if remote_address: + observed_multiaddr = _remote_address_to_multiaddr(remote_address) + else: + observed_multiaddr = None + logger.debug( + "Connection from remote peer %s, address: %s, multiaddr: %s", + peer_id, + remote_address, + observed_multiaddr, + ) + except Exception as e: + logger.error("Error getting remote address: %s", e) + remote_address = None - # Select the first address if available, else None - observed_multiaddr = ( - remote_peer_multiaddrs[0] if remote_peer_multiaddrs else None - ) protobuf = _mk_identify_protobuf(host, observed_multiaddr) response = protobuf.SerializeToString() diff --git a/tests/core/identity/identify/test_protocol.py b/tests/core/identity/identify/test_protocol.py index e532da3d..e3777531 100644 --- a/tests/core/identity/identify/test_protocol.py +++ b/tests/core/identity/identify/test_protocol.py @@ -28,6 +28,9 @@ async def test_identify_protocol(security_protocol): host_a, host_b, ): + # Here, host_b is the requester and host_a is the responder. + # observed_addr represent host_b’s address as observed by host_a + # (i.e., the address from which host_b’s request was received). stream = await host_b.new_stream(host_a.get_id(), (ID,)) response = await stream.read() await stream.close() @@ -53,6 +56,8 @@ async def test_identify_protocol(security_protocol): ) # Check observed address + # TODO: use decapsulateCode(protocols('p2p').code) + # when the Multiaddr class will implement it host_b_addr = host_b.get_addrs()[0] cleaned_addr = Multiaddr.join( *(