From 43524e7bf04c27ace76d128fa48407a61eb690d2 Mon Sep 17 00:00:00 2001
From: Nathaniel Cook <nvcook42@gmail.com>
Date: Thu, 13 Jun 2024 04:37:03 -0600
Subject: [PATCH] feat(swarm): add `peer_id` to `ListenFailure`

It's possible in certain failure modes to know the peer_id of a failed incoming connection. For example when an inbound connection has been negotiated/upgraded but then rejected locally for a connection limit or similar reason. In these cases it makes sense to communicate the peer_id to behaviours in case they have created any internal state about the peer.

Related https://github.com/libp2p/rust-libp2p/pull/4777

Pull-Request: #4818.
---
 Cargo.lock             | 2 +-
 Cargo.toml             | 2 +-
 swarm/CHANGELOG.md     | 5 ++++-
 swarm/Cargo.toml       | 2 +-
 swarm/src/behaviour.rs | 9 ++++++++-
 swarm/src/lib.rs       | 3 +++
 6 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index d680af5ea42..367d37b0ec2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3292,7 +3292,7 @@ dependencies = [
 
 [[package]]
 name = "libp2p-swarm"
-version = "0.44.3"
+version = "0.45.0"
 dependencies = [
  "async-std",
  "either",
diff --git a/Cargo.toml b/Cargo.toml
index 822c1692960..bf57480bbbe 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -102,7 +102,7 @@ libp2p-rendezvous = { version = "0.14.1", path = "protocols/rendezvous" }
 libp2p-request-response = { version = "0.26.4", path = "protocols/request-response" }
 libp2p-server = { version = "0.12.7", path = "misc/server" }
 libp2p-stream = { version = "0.1.0-alpha.1", path = "protocols/stream" }
-libp2p-swarm = { version = "0.44.3", path = "swarm" }
+libp2p-swarm = { version = "0.45.0", path = "swarm" }
 libp2p-swarm-derive = { version = "=0.34.2", path = "swarm-derive" } # `libp2p-swarm-derive` may not be compatible with different `libp2p-swarm` non-breaking releases. E.g. `libp2p-swarm` might introduce a new enum variant `FromSwarm` (which is `#[non-exhaustive]`) in a non-breaking release. Older versions of `libp2p-swarm-derive` would not forward this enum variant within the `NetworkBehaviour` hierarchy. Thus the version pinning is required.
 libp2p-swarm-test = { version = "0.3.0", path = "swarm-test" }
 libp2p-tcp = { version = "0.41.1", path = "transports/tcp" }
diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md
index 8cded416628..1b53ee9b937 100644
--- a/swarm/CHANGELOG.md
+++ b/swarm/CHANGELOG.md
@@ -1,4 +1,7 @@
-## 0.44.3
+## 0.45.0
+
+- Add peer_id to `FromSwarm::ListenFailure`.
+  See [PR 4818](https://github.com/libp2p/rust-libp2p/pull/4818).
 
 - Use `web-time` instead of `instant`.
   See [PR 5347](https://github.com/libp2p/rust-libp2p/pull/5347).
diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml
index 338cbf91641..60cf58cb495 100644
--- a/swarm/Cargo.toml
+++ b/swarm/Cargo.toml
@@ -3,7 +3,7 @@ name = "libp2p-swarm"
 edition = "2021"
 rust-version = { workspace = true }
 description = "The libp2p swarm"
-version = "0.44.3"
+version = "0.45.0"
 authors = ["Parity Technologies <admin@parity.io>"]
 license = "MIT"
 repository = "https://github.com/libp2p/rust-libp2p"
diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs
index 5070871a4c1..fc9045dfc3f 100644
--- a/swarm/src/behaviour.rs
+++ b/swarm/src/behaviour.rs
@@ -148,6 +148,9 @@ pub trait NetworkBehaviour: 'static {
     /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial.
     /// In order to actually use this connection, this function must return a [`ConnectionHandler`].
     /// Returning an error will immediately close the connection.
+    ///
+    /// Note when any composed behaviour returns an error the connection will be closed and a
+    /// [`FromSwarm::ListenFailure`] event will be emitted.
     fn handle_established_inbound_connection(
         &mut self,
         _connection_id: ConnectionId,
@@ -184,6 +187,9 @@ pub trait NetworkBehaviour: 'static {
     /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial.
     /// In order to actually use this connection, this function must return a [`ConnectionHandler`].
     /// Returning an error will immediately close the connection.
+    ///
+    /// Note when any composed behaviour returns an error the connection will be closed and a
+    /// [`FromSwarm::DialFailure`] event will be emitted.
     fn handle_established_outbound_connection(
         &mut self,
         _connection_id: ConnectionId,
@@ -269,7 +275,7 @@ pub enum ToSwarm<TOutEvent, TInEvent> {
     /// The emphasis on a **new** candidate is important.
     /// Protocols MUST take care to only emit a candidate once per "source".
     /// For example, the observed address of a TCP connection does not change throughout its lifetime.
-    /// Thus, only one candidate should be emitted per connection.    
+    /// Thus, only one candidate should be emitted per connection.
     ///
     /// This makes the report frequency of an address a meaningful data-point for consumers of this event.
     /// This address will be shared with all [`NetworkBehaviour`]s via [`FromSwarm::NewExternalAddrCandidate`].
@@ -508,6 +514,7 @@ pub struct ListenFailure<'a> {
     pub send_back_addr: &'a Multiaddr,
     pub error: &'a ListenError,
     pub connection_id: ConnectionId,
+    pub peer_id: Option<PeerId>,
 }
 
 /// [`FromSwarm`] variant that informs the behaviour that a new listener was created.
diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs
index cf2961cef6d..ec5b7a109cc 100644
--- a/swarm/src/lib.rs
+++ b/swarm/src/lib.rs
@@ -754,6 +754,7 @@ where
                                         send_back_addr: &send_back_addr,
                                         error: &listen_error,
                                         connection_id: id,
+                                        peer_id: Some(peer_id),
                                     },
                                 ));
 
@@ -867,6 +868,7 @@ where
                         send_back_addr: &send_back_addr,
                         error: &error,
                         connection_id: id,
+                        peer_id: None,
                     }));
                 self.pending_swarm_events
                     .push_back(SwarmEvent::IncomingConnectionError {
@@ -970,6 +972,7 @@ where
                                 send_back_addr: &send_back_addr,
                                 error: &listen_error,
                                 connection_id,
+                                peer_id: None,
                             }));
 
                         self.pending_swarm_events