From 4f3b2338ba9e35ce7d743ad13c75b829d6ed4a4f Mon Sep 17 00:00:00 2001 From: Darius Date: Fri, 30 Dec 2022 14:39:24 -0500 Subject: [PATCH 01/25] feat/networkbehaviour: Added ListenOn and RemoveListener --- swarm-derive/src/lib.rs | 6 ++++++ swarm/src/behaviour.rs | 39 ++++++++++++++++++++++++++++++++++++++- swarm/src/lib.rs | 6 ++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index b142ea77c67..fc5cb99c3b3 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -585,6 +585,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { std::task::Poll::Ready(#network_behaviour_action::Dial { opts, handler: provided_handler }) => { return std::task::Poll::Ready(#network_behaviour_action::Dial { opts, handler: #provided_handler_and_new_handlers }); } + std::task::Poll::Ready(#network_behaviour_action::ListenOn { address }) => { + return std::task::Poll::Ready(#network_behaviour_action::ListenOn { address }); + } + std::task::Poll::Ready(#network_behaviour_action::RemoveListener { id }) => { + return std::task::Poll::Ready(#network_behaviour_action::RemoveListener { id }); + } std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { peer_id, handler, event }) => { return std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { peer_id, diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 141d6c3efbd..cfed6318ed2 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -630,7 +630,20 @@ pub enum NetworkBehaviourAction< /// # #[derive(Debug, PartialEq, Eq)] /// # struct PreciousMessage(String); /// ``` - Dial { opts: DialOpts, handler: THandler }, + Dial { + opts: DialOpts, + handler: THandler, + }, + + /// Instructs the `Swarm` to listen on the provided address + ListenOn { + address: Multiaddr, + }, + + /// Instructs the `Swarm` to remove the listener + RemoveListener { + id: ListenerId, + }, /// Instructs the `Swarm` to send an event to the handler dedicated to a /// connection with a peer. @@ -703,6 +716,12 @@ impl NetworkBehaviourAction::Dial { opts, handler } => { NetworkBehaviourAction::Dial { opts, handler } } + NetworkBehaviourAction::ListenOn { address } => { + NetworkBehaviourAction::ListenOn { address } + } + NetworkBehaviourAction::RemoveListener { id } => { + NetworkBehaviourAction::RemoveListener { id } + } NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -734,6 +753,12 @@ impl NetworkBehaviourAction { NetworkBehaviourAction::Dial { opts, handler } } + NetworkBehaviourAction::ListenOn { address } => { + NetworkBehaviourAction::ListenOn { address } + } + NetworkBehaviourAction::RemoveListener { id } => { + NetworkBehaviourAction::RemoveListener { id } + } NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -777,6 +802,12 @@ where opts, handler: f(handler), }, + NetworkBehaviourAction::ListenOn { address } => { + NetworkBehaviourAction::ListenOn { address } + } + NetworkBehaviourAction::RemoveListener { id } => { + NetworkBehaviourAction::RemoveListener { id } + } NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -821,6 +852,12 @@ where opts, handler: f_handler(handler), }, + NetworkBehaviourAction::ListenOn { address } => { + NetworkBehaviourAction::ListenOn { address } + } + NetworkBehaviourAction::RemoveListener { id } => { + NetworkBehaviourAction::RemoveListener { id } + } NetworkBehaviourAction::NotifyHandler { peer_id, handler, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index c4fd2de563e..438aa09edf9 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1026,6 +1026,12 @@ where } } } + NetworkBehaviourAction::ListenOn { address } => { + self.listen_on(address).ok()?; + } + NetworkBehaviourAction::RemoveListener { id } => { + self.remove_listener(id); + } NetworkBehaviourAction::NotifyHandler { peer_id, handler, From ee4cf3033d38e545f50c731a610cc93ee4741011 Mon Sep 17 00:00:00 2001 From: Darius Date: Sun, 14 May 2023 06:17:53 -0400 Subject: [PATCH 02/25] chore: Use ListenerId in `ToSwarm::ListenOn` --- swarm-derive/src/lib.rs | 4 ++-- swarm/src/behaviour.rs | 6 +++--- swarm/src/lib.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 291bf25df58..0d9c854e4c2 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -706,8 +706,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { std::task::Poll::Ready(#network_behaviour_action::Dial { opts }) => { return std::task::Poll::Ready(#network_behaviour_action::Dial { opts }); } - std::task::Poll::Ready(#network_behaviour_action::ListenOn { address }) => { - return std::task::Poll::Ready(#network_behaviour_action::ListenOn { address }); + std::task::Poll::Ready(#network_behaviour_action::ListenOn { id, address }) => { + return std::task::Poll::Ready(#network_behaviour_action::ListenOn { id, address }); } std::task::Poll::Ready(#network_behaviour_action::RemoveListener { id }) => { return std::task::Poll::Ready(#network_behaviour_action::RemoveListener { id }); diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 9bf73178a75..1a4531e80f4 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -279,7 +279,7 @@ pub enum ToSwarm { Dial { opts: DialOpts }, /// Instructs the `Swarm` to listen on the provided address - ListenOn { address: Multiaddr }, + ListenOn { id: ListenerId, address: Multiaddr }, /// Instructs the `Swarm` to remove the listener RemoveListener { id: ListenerId }, @@ -351,7 +351,7 @@ impl ToSwarm { match self { ToSwarm::GenerateEvent(e) => ToSwarm::GenerateEvent(e), ToSwarm::Dial { opts } => ToSwarm::Dial { opts }, - ToSwarm::ListenOn { address } => ToSwarm::ListenOn { address }, + ToSwarm::ListenOn { id, address } => ToSwarm::ListenOn { id, address }, ToSwarm::RemoveListener { id } => ToSwarm::RemoveListener { id }, ToSwarm::NotifyHandler { peer_id, @@ -382,7 +382,7 @@ impl ToSwarm { match self { ToSwarm::GenerateEvent(e) => ToSwarm::GenerateEvent(f(e)), ToSwarm::Dial { opts } => ToSwarm::Dial { opts }, - ToSwarm::ListenOn { address } => ToSwarm::ListenOn { address }, + ToSwarm::ListenOn { id, address } => ToSwarm::ListenOn { id, address }, ToSwarm::RemoveListener { id } => ToSwarm::RemoveListener { id }, ToSwarm::NotifyHandler { peer_id, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 14c82bcd8ee..05c12660698 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1121,8 +1121,8 @@ where } } } - ToSwarm::ListenOn { address } => { - self.listen_on(address).ok()?; + ToSwarm::ListenOn { id, address } => { + self.transport.listen_on(id, address).ok()?; } ToSwarm::RemoveListener { id } => { self.remove_listener(id); From a5331cb43f979bb305e5a13c1b5893584467cb60 Mon Sep 17 00:00:00 2001 From: Darius Clark Date: Sun, 14 May 2023 08:48:43 -0400 Subject: [PATCH 03/25] Update swarm-derive/src/lib.rs Co-authored-by: Thomas Eizinger --- swarm-derive/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 0d9c854e4c2..4070383cfb7 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -699,7 +699,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } }; - quote!{ match #trait_to_impl::poll(&mut self.#field, cx, poll_params) { #generate_event_match_arm From ced5bb0f5c8d7c4eab3baad8eea7fed703553dbc Mon Sep 17 00:00:00 2001 From: Darius Clark Date: Sun, 14 May 2023 08:48:50 -0400 Subject: [PATCH 04/25] Update swarm/src/behaviour.rs Co-authored-by: Thomas Eizinger --- swarm/src/behaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 1a4531e80f4..aa009b6f77f 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -278,7 +278,7 @@ pub enum ToSwarm { /// This allows a [`NetworkBehaviour`] to identify a connection that resulted out of its own dial request. Dial { opts: DialOpts }, - /// Instructs the `Swarm` to listen on the provided address + /// Instructs the [`Swarm`] to listen on the provided address ListenOn { id: ListenerId, address: Multiaddr }, /// Instructs the `Swarm` to remove the listener From 9d2db406f419c656f3a3e7974ce2d02e5ad8d45f Mon Sep 17 00:00:00 2001 From: Darius Clark Date: Sun, 14 May 2023 08:49:10 -0400 Subject: [PATCH 05/25] Update swarm/src/behaviour.rs Co-authored-by: Thomas Eizinger --- swarm/src/behaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index aa009b6f77f..b3c8e72eb5b 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -281,7 +281,7 @@ pub enum ToSwarm { /// Instructs the [`Swarm`] to listen on the provided address ListenOn { id: ListenerId, address: Multiaddr }, - /// Instructs the `Swarm` to remove the listener + /// Instructs the [`Swarm`] to remove the listener RemoveListener { id: ListenerId }, /// Instructs the `Swarm` to send an event to the handler dedicated to a From ad8856e275007b9641d3ac13515dfd3d0037d57a Mon Sep 17 00:00:00 2001 From: Darius Date: Sun, 14 May 2023 22:46:04 -0400 Subject: [PATCH 06/25] chore: Send ListenerError to behaviour --- swarm/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index f0b854d5d04..77a448d3113 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1118,7 +1118,14 @@ where } } ToSwarm::ListenOn { id, address } => { - self.transport.listen_on(id, address).ok()?; + if let Err(e) = self.transport.listen_on(id, address) { + self.behaviour.on_swarm_event(FromSwarm::ListenerError( + behaviour::ListenerError { + listener_id: id, + err: &e, + }, + )); + } } ToSwarm::RemoveListener { id } => { self.remove_listener(id); From ec128ac200451b0f243b3438c483eccc7a318309 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 21:36:09 +1000 Subject: [PATCH 07/25] Update swarm/src/behaviour.rs --- swarm/src/behaviour.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 3113e615646..2bbb7e2e488 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -275,10 +275,10 @@ pub enum ToSwarm { /// This allows a [`NetworkBehaviour`] to identify a connection that resulted out of its own dial request. Dial { opts: DialOpts }, - /// Instructs the [`Swarm`] to listen on the provided address + /// Instructs the [`Swarm`] to listen on the provided address. ListenOn { id: ListenerId, address: Multiaddr }, - /// Instructs the [`Swarm`] to remove the listener + /// Instructs the [`Swarm`] to remove the listener. RemoveListener { id: ListenerId }, /// Instructs the `Swarm` to send an event to the handler dedicated to a From 97be0c611d1055de5f6cf81ebb46763f99e3ab09 Mon Sep 17 00:00:00 2001 From: Darius Date: Mon, 15 May 2023 07:39:25 -0400 Subject: [PATCH 08/25] chore: Update CHANGELOG.md --- swarm/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 159c61af9b6..e0cc7396888 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,5 +1,8 @@ ## 0.43.0 - unreleased +- Allow `NetworkBehaviours` to create and remove listeners. + See [PR 3292]. + - Raise MSRV to 1.65. See [PR 3715]. @@ -50,6 +53,7 @@ - Remove deprecated `NetworkBehaviourAction` type. See [PR 3919]. +[PR 3292]: https://github.com/libp2p/rust-libp2p/pull/3292 [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 [PR 3651]: https://github.com/libp2p/rust-libp2p/pull/3651 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 From 8cbf3861f0e32df4748090e99490f9192e2871a2 Mon Sep 17 00:00:00 2001 From: Darius Date: Mon, 15 May 2023 07:53:12 -0400 Subject: [PATCH 09/25] chore: Update comments --- swarm/src/behaviour.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 2bbb7e2e488..90b20d16576 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -275,10 +275,10 @@ pub enum ToSwarm { /// This allows a [`NetworkBehaviour`] to identify a connection that resulted out of its own dial request. Dial { opts: DialOpts }, - /// Instructs the [`Swarm`] to listen on the provided address. + /// Instructs the [`Swarm`](crate::Swarm) to listen on the provided address. ListenOn { id: ListenerId, address: Multiaddr }, - /// Instructs the [`Swarm`] to remove the listener. + /// Instructs the [`Swarm`](crate::Swarm) to remove the listener. RemoveListener { id: ListenerId }, /// Instructs the `Swarm` to send an event to the handler dedicated to a From 97ec46d4ad1c70b48f4fb70091065e8c46a0f38a Mon Sep 17 00:00:00 2001 From: Darius Date: Thu, 25 May 2023 00:36:58 -0400 Subject: [PATCH 10/25] chore: Return listener error to behaviour --- swarm/src/lib.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 0d7ff8174a5..15195a9f2e7 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -372,7 +372,16 @@ where /// Depending on the underlying transport, one listener may have multiple listening addresses. pub fn listen_on(&mut self, addr: Multiaddr) -> Result> { let id = ListenerId::next(); - self.transport.listen_on(id, addr)?; + + if let Err(e) = self.transport.listen_on(id, addr) { + self.behaviour + .on_swarm_event(FromSwarm::ListenerError(behaviour::ListenerError { + listener_id: id, + err: &e, + })); + return Err(e); + } + self.behaviour .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { listener_id: id, From fa64bcadefb89257f4ff6e90a7d80087088fc521 Mon Sep 17 00:00:00 2001 From: Darius Date: Thu, 25 May 2023 08:25:21 -0400 Subject: [PATCH 11/25] chore: emit event when calling ToSwarm::ListenOn --- swarm/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 15195a9f2e7..019337e791d 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1034,6 +1034,11 @@ where }, )); } + + self.behaviour + .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { + listener_id: id, + })); } ToSwarm::RemoveListener { id } => { self.remove_listener(id); From 124a1502266d88acbc102bd89a0d00539d2fb1e8 Mon Sep 17 00:00:00 2001 From: Darius Date: Fri, 26 May 2023 11:37:22 -0400 Subject: [PATCH 12/25] chore: Add Swarm::add_listener --- swarm/src/lib.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 019337e791d..703010c1f16 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -382,10 +382,7 @@ where return Err(e); } - self.behaviour - .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { - listener_id: id, - })); + self.add_listener(id); Ok(id) } @@ -553,6 +550,14 @@ where self.confirmed_external_addr.iter() } + /// TBD + fn add_listener(&mut self, listener_id: ListenerId) { + self.behaviour + .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { + listener_id, + })); + } + /// Add a **confirmed** external address for the local node. /// /// This function should only be called with addresses that are guaranteed to be reachable. @@ -1035,10 +1040,7 @@ where )); } - self.behaviour - .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { - listener_id: id, - })); + self.add_listener(id); } ToSwarm::RemoveListener { id } => { self.remove_listener(id); From 1f6a7989bfcfc686b349b849a683a344487157af Mon Sep 17 00:00:00 2001 From: Darius Date: Sat, 27 May 2023 00:32:21 -0400 Subject: [PATCH 13/25] chore: Add test --- swarm/tests/listener.rs | 142 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 swarm/tests/listener.rs diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs new file mode 100644 index 00000000000..369cd7f722d --- /dev/null +++ b/swarm/tests/listener.rs @@ -0,0 +1,142 @@ +use std::{ + collections::{HashSet, VecDeque}, + task::{Context, Poll}, +}; + +use libp2p_core::{multiaddr::Protocol, transport::ListenerId, Endpoint, Multiaddr}; +use libp2p_identity::PeerId; +use libp2p_swarm::{ + derive_prelude::NewListener, dummy, ConnectionDenied, ConnectionId, FromSwarm, ListenerClosed, + ListenerError, NetworkBehaviour, NewListenAddr, PollParameters, Swarm, SwarmEvent, THandler, + THandlerInEvent, THandlerOutEvent, ToSwarm, +}; + +use libp2p_swarm_test::SwarmExt; + +#[derive(Default)] +struct Behaviour { + events: VecDeque::ToSwarm, THandlerInEvent>>, + listeners: HashSet, +} + +impl Behaviour { + pub fn listen(&mut self, addr: Multiaddr) -> ListenerId { + let listener_id = ListenerId::next(); + assert!(!self.listeners.contains(&listener_id)); + self.events.push_back(ToSwarm::ListenOn { + id: listener_id, + address: addr, + }); + + self.listeners.insert(listener_id); + + listener_id + } + + pub fn stop_listening(&mut self, id: ListenerId) { + self.events.push_back(ToSwarm::RemoveListener { id }); + } +} + +impl NetworkBehaviour for Behaviour { + type ConnectionHandler = dummy::ConnectionHandler; + type ToSwarm = void::Void; + + fn handle_established_inbound_connection( + &mut self, + _: ConnectionId, + _: PeerId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, ConnectionDenied> { + Ok(dummy::ConnectionHandler) + } + + fn handle_established_outbound_connection( + &mut self, + _: ConnectionId, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + ) -> Result, ConnectionDenied> { + Ok(dummy::ConnectionHandler) + } + + fn on_connection_handler_event( + &mut self, + _: PeerId, + _: ConnectionId, + _: THandlerOutEvent, + ) { + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::NewListener(NewListener { listener_id }) => { + assert!(self.listeners.contains(&listener_id)); + } + FromSwarm::NewListenAddr(NewListenAddr { listener_id, .. }) => { + assert!(self.listeners.contains(&listener_id)); + } + FromSwarm::ListenerError(ListenerError { listener_id, err }) => { + panic!("Error for listener {listener_id:?}: {err}"); + } + FromSwarm::ListenerClosed(ListenerClosed { + listener_id, + reason, + }) => { + assert!(self.listeners.contains(&listener_id)); + assert!(reason.is_ok()); + self.listeners.remove(&listener_id); + assert!(!self.listeners.contains(&listener_id)); + } + _ => {} + } + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> { + if let Some(event) = self.events.pop_front() { + return Poll::Ready(event); + } + + Poll::Pending + } +} + +#[async_std::test] +async fn listener() { + let mut swarm: Swarm = Swarm::new_ephemeral(|_| Behaviour::default()); + let addr: Multiaddr = Protocol::Memory(0).into(); + let id = swarm.behaviour_mut().listen(addr.clone()); + + let address = swarm + .wait(|e| match e { + SwarmEvent::NewListenAddr { + listener_id, + address, + } => { + assert_eq!(listener_id, id); + Some(address) + } + _ => None, + }) + .await; + + swarm.behaviour_mut().stop_listening(id); + + swarm + .wait(|e| match e { + SwarmEvent::ListenerClosed { listener_id, addresses, reason } => { + assert_eq!(listener_id, id); + assert!(addresses.contains(&address)); + assert!(reason.is_ok()); + Some(()) + } + _ => None, + }) + .await; +} From 15fd6e43bb25db9a82b8ca552e2ea92ea89cf061 Mon Sep 17 00:00:00 2001 From: Darius Date: Sat, 27 May 2023 03:01:26 -0400 Subject: [PATCH 14/25] chore: Rename test function --- swarm/tests/listener.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index 369cd7f722d..4d38282005c 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -108,8 +108,8 @@ impl NetworkBehaviour for Behaviour { } #[async_std::test] -async fn listener() { - let mut swarm: Swarm = Swarm::new_ephemeral(|_| Behaviour::default()); +async fn behaviour_listener() { + let mut swarm = Swarm::new_ephemeral(|_| Behaviour::default()); let addr: Multiaddr = Protocol::Memory(0).into(); let id = swarm.behaviour_mut().listen(addr.clone()); @@ -139,4 +139,4 @@ async fn listener() { _ => None, }) .await; -} +} \ No newline at end of file From c8968e0af50acc9fb4c5bcee7c3c439712677ff6 Mon Sep 17 00:00:00 2001 From: Darius Date: Sat, 27 May 2023 03:03:23 -0400 Subject: [PATCH 15/25] chore: Formatted code --- swarm/tests/listener.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index 4d38282005c..111eb65c694 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -130,7 +130,11 @@ async fn behaviour_listener() { swarm .wait(|e| match e { - SwarmEvent::ListenerClosed { listener_id, addresses, reason } => { + SwarmEvent::ListenerClosed { + listener_id, + addresses, + reason, + } => { assert_eq!(listener_id, id); assert!(addresses.contains(&address)); assert!(reason.is_ok()); @@ -139,4 +143,4 @@ async fn behaviour_listener() { _ => None, }) .await; -} \ No newline at end of file +} From 1e4099254f61ca148d15ac85bd5454aef707dab8 Mon Sep 17 00:00:00 2001 From: Darius Date: Sat, 27 May 2023 03:06:53 -0400 Subject: [PATCH 16/25] chore: Updated test --- swarm/tests/listener.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index 111eb65c694..f1469313b18 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -20,7 +20,7 @@ struct Behaviour { } impl Behaviour { - pub fn listen(&mut self, addr: Multiaddr) -> ListenerId { + pub(crate) fn listen(&mut self, addr: Multiaddr) -> ListenerId { let listener_id = ListenerId::next(); assert!(!self.listeners.contains(&listener_id)); self.events.push_back(ToSwarm::ListenOn { @@ -33,7 +33,7 @@ impl Behaviour { listener_id } - pub fn stop_listening(&mut self, id: ListenerId) { + pub(crate) fn stop_listening(&mut self, id: ListenerId) { self.events.push_back(ToSwarm::RemoveListener { id }); } } From 95e61abf9b5179e4cc7c4d119ba2611633274493 Mon Sep 17 00:00:00 2001 From: Darius Date: Tue, 6 Jun 2023 15:04:10 -0400 Subject: [PATCH 17/25] chore: Update test --- swarm/tests/listener.rs | 76 ++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index f1469313b18..c2fdd9d03db 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -13,6 +13,44 @@ use libp2p_swarm::{ use libp2p_swarm_test::SwarmExt; +#[async_std::test] +async fn behaviour_listener() { + let mut swarm = Swarm::new_ephemeral(|_| Behaviour::default()); + let addr: Multiaddr = Protocol::Memory(0).into(); + let id = swarm.behaviour_mut().listen(addr.clone()); + + let address = swarm + .wait(|e| match e { + SwarmEvent::NewListenAddr { + listener_id, + address, + } => { + assert_eq!(listener_id, id); + Some(address) + } + _ => None, + }) + .await; + + swarm.behaviour_mut().stop_listening(id); + + swarm + .wait(|e| match e { + SwarmEvent::ListenerClosed { + listener_id, + addresses, + reason, + } => { + assert_eq!(listener_id, id); + assert!(addresses.contains(&address)); + assert!(reason.is_ok()); + Some(()) + } + _ => None, + }) + .await; +} + #[derive(Default)] struct Behaviour { events: VecDeque::ToSwarm, THandlerInEvent>>, @@ -106,41 +144,3 @@ impl NetworkBehaviour for Behaviour { Poll::Pending } } - -#[async_std::test] -async fn behaviour_listener() { - let mut swarm = Swarm::new_ephemeral(|_| Behaviour::default()); - let addr: Multiaddr = Protocol::Memory(0).into(); - let id = swarm.behaviour_mut().listen(addr.clone()); - - let address = swarm - .wait(|e| match e { - SwarmEvent::NewListenAddr { - listener_id, - address, - } => { - assert_eq!(listener_id, id); - Some(address) - } - _ => None, - }) - .await; - - swarm.behaviour_mut().stop_listening(id); - - swarm - .wait(|e| match e { - SwarmEvent::ListenerClosed { - listener_id, - addresses, - reason, - } => { - assert_eq!(listener_id, id); - assert!(addresses.contains(&address)); - assert!(reason.is_ok()); - Some(()) - } - _ => None, - }) - .await; -} From f880ba2400eb82b97db2dce5faa8de8f79655f7d Mon Sep 17 00:00:00 2001 From: Darius Date: Tue, 6 Jun 2023 15:07:05 -0400 Subject: [PATCH 18/25] chore: Move code into add_listener --- swarm/src/lib.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index a57f5a316e2..a3adf3bed11 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -550,8 +550,15 @@ where self.confirmed_external_addr.iter() } - /// TBD - fn add_listener(&mut self, listener_id: ListenerId) { + fn add_listener(&mut self, listener_id: ListenerId, addr: Multiaddr) { + if let Err(e) = self.transport.listen_on(listener_id, addr) { + self.behaviour + .on_swarm_event(FromSwarm::ListenerError(behaviour::ListenerError { + listener_id, + err: &e, + })); + } + self.behaviour .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { listener_id, @@ -1031,16 +1038,7 @@ where } } ToSwarm::ListenOn { id, address } => { - if let Err(e) = self.transport.listen_on(id, address) { - self.behaviour.on_swarm_event(FromSwarm::ListenerError( - behaviour::ListenerError { - listener_id: id, - err: &e, - }, - )); - } - - self.add_listener(id); + self.add_listener(id, address); } ToSwarm::RemoveListener { id } => { self.remove_listener(id); From 7068f1274d784ff4edf0729821c35ca72ce5e754 Mon Sep 17 00:00:00 2001 From: Darius Date: Tue, 6 Jun 2023 15:15:53 -0400 Subject: [PATCH 19/25] fix: Move listen on into add_listener --- swarm/src/lib.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index a3adf3bed11..5d20a1d76f6 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -372,17 +372,7 @@ where /// Depending on the underlying transport, one listener may have multiple listening addresses. pub fn listen_on(&mut self, addr: Multiaddr) -> Result> { let id = ListenerId::next(); - - if let Err(e) = self.transport.listen_on(id, addr) { - self.behaviour - .on_swarm_event(FromSwarm::ListenerError(behaviour::ListenerError { - listener_id: id, - err: &e, - })); - return Err(e); - } - - self.add_listener(id); + self.add_listener(id, addr); Ok(id) } From 0bd41ab506ddd80bf9347d022ffc716d7d30b9a7 Mon Sep 17 00:00:00 2001 From: Darius Date: Tue, 6 Jun 2023 22:28:46 -0400 Subject: [PATCH 20/25] chore: Added ListenOpts --- swarm-derive/src/lib.rs | 4 ++-- swarm/src/behaviour.rs | 7 ++++--- swarm/src/lib.rs | 16 +++++++++++----- swarm/src/listen_opts.rs | 34 ++++++++++++++++++++++++++++++++++ swarm/tests/listener.rs | 11 ++++------- 5 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 swarm/src/listen_opts.rs diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 7177d528e86..e54cd058daf 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -732,8 +732,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> syn::Result { return std::task::Poll::Ready(#network_behaviour_action::Dial { opts }); } - std::task::Poll::Ready(#network_behaviour_action::ListenOn { id, address }) => { - return std::task::Poll::Ready(#network_behaviour_action::ListenOn { id, address }); + std::task::Poll::Ready(#network_behaviour_action::ListenOn { opts }) => { + return std::task::Poll::Ready(#network_behaviour_action::ListenOn { opts }); } std::task::Poll::Ready(#network_behaviour_action::RemoveListener { id }) => { return std::task::Poll::Ready(#network_behaviour_action::RemoveListener { id }); diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 29eea8ba55b..0615457291a 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -28,6 +28,7 @@ pub use listen_addresses::ListenAddresses; use crate::connection::ConnectionId; use crate::dial_opts::DialOpts; +use crate::listen_opts::ListenOpts; use crate::{ ConnectionDenied, ConnectionHandler, DialError, ListenError, THandler, THandlerInEvent, THandlerOutEvent, @@ -251,7 +252,7 @@ pub enum ToSwarm { Dial { opts: DialOpts }, /// Instructs the [`Swarm`](crate::Swarm) to listen on the provided address. - ListenOn { id: ListenerId, address: Multiaddr }, + ListenOn { opts: ListenOpts }, /// Instructs the [`Swarm`](crate::Swarm) to remove the listener. RemoveListener { id: ListenerId }, @@ -330,7 +331,7 @@ impl ToSwarm { match self { ToSwarm::GenerateEvent(e) => ToSwarm::GenerateEvent(e), ToSwarm::Dial { opts } => ToSwarm::Dial { opts }, - ToSwarm::ListenOn { id, address } => ToSwarm::ListenOn { id, address }, + ToSwarm::ListenOn { opts } => ToSwarm::ListenOn { opts }, ToSwarm::RemoveListener { id } => ToSwarm::RemoveListener { id }, ToSwarm::NotifyHandler { peer_id, @@ -361,7 +362,7 @@ impl ToSwarm { match self { ToSwarm::GenerateEvent(e) => ToSwarm::GenerateEvent(f(e)), ToSwarm::Dial { opts } => ToSwarm::Dial { opts }, - ToSwarm::ListenOn { id, address } => ToSwarm::ListenOn { id, address }, + ToSwarm::ListenOn { opts } => ToSwarm::ListenOn { opts }, ToSwarm::RemoveListener { id } => ToSwarm::RemoveListener { id }, ToSwarm::NotifyHandler { peer_id, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 5d20a1d76f6..a5501fa64f7 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -65,6 +65,7 @@ mod upgrade; pub mod behaviour; pub mod dial_opts; +pub mod listen_opts; pub mod dummy; pub mod handler; pub mod keep_alive; @@ -121,6 +122,7 @@ pub use handler::{ }; #[cfg(feature = "macros")] pub use libp2p_swarm_derive::NetworkBehaviour; +use listen_opts::ListenOpts; pub use stream::Stream; pub use stream_protocol::{InvalidProtocol, StreamProtocol}; @@ -371,8 +373,9 @@ where /// Listeners report their new listening addresses as [`SwarmEvent::NewListenAddr`]. /// Depending on the underlying transport, one listener may have multiple listening addresses. pub fn listen_on(&mut self, addr: Multiaddr) -> Result> { - let id = ListenerId::next(); - self.add_listener(id, addr); + let opts = ListenOpts::new(addr); + let id = opts.listener_id(); + self.add_listener(opts); Ok(id) } @@ -540,7 +543,10 @@ where self.confirmed_external_addr.iter() } - fn add_listener(&mut self, listener_id: ListenerId, addr: Multiaddr) { + fn add_listener(&mut self, opts: ListenOpts) { + let addr = opts.address(); + let listener_id = opts.listener_id(); + if let Err(e) = self.transport.listen_on(listener_id, addr) { self.behaviour .on_swarm_event(FromSwarm::ListenerError(behaviour::ListenerError { @@ -1027,8 +1033,8 @@ where }); } } - ToSwarm::ListenOn { id, address } => { - self.add_listener(id, address); + ToSwarm::ListenOn { opts } => { + self.add_listener(opts); } ToSwarm::RemoveListener { id } => { self.remove_listener(id); diff --git a/swarm/src/listen_opts.rs b/swarm/src/listen_opts.rs new file mode 100644 index 00000000000..0acb90a766f --- /dev/null +++ b/swarm/src/listen_opts.rs @@ -0,0 +1,34 @@ +use crate::ListenerId; +use libp2p_core::Multiaddr; + + +#[derive(Debug)] +pub struct ListenOpts { + id: ListenerId, + address: Multiaddr, +} + +impl ListenOpts { + pub fn new(address: Multiaddr) -> ListenOpts { + ListenOpts { + id: ListenerId::next(), + address, + } + } + + /// Get the [`ListenerId`] of this listen attempt + pub fn listener_id(&self) -> ListenerId { + self.id + } + + /// Get the [`Multiaddr`] that is being listened on + pub fn address(&self) -> Multiaddr { + self.address.clone() + } +} + +impl From for ListenOpts { + fn from(addr: Multiaddr) -> Self { + ListenOpts::new(addr) + } +} \ No newline at end of file diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index c2fdd9d03db..ebe20506382 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -8,7 +8,7 @@ use libp2p_identity::PeerId; use libp2p_swarm::{ derive_prelude::NewListener, dummy, ConnectionDenied, ConnectionId, FromSwarm, ListenerClosed, ListenerError, NetworkBehaviour, NewListenAddr, PollParameters, Swarm, SwarmEvent, THandler, - THandlerInEvent, THandlerOutEvent, ToSwarm, + THandlerInEvent, THandlerOutEvent, ToSwarm, listen_opts::ListenOpts, }; use libp2p_swarm_test::SwarmExt; @@ -59,13 +59,10 @@ struct Behaviour { impl Behaviour { pub(crate) fn listen(&mut self, addr: Multiaddr) -> ListenerId { - let listener_id = ListenerId::next(); + let opts = ListenOpts::new(addr); + let listener_id = opts.listener_id(); assert!(!self.listeners.contains(&listener_id)); - self.events.push_back(ToSwarm::ListenOn { - id: listener_id, - address: addr, - }); - + self.events.push_back(ToSwarm::ListenOn { opts }); self.listeners.insert(listener_id); listener_id From f4c196f8964f4ec1b6e75d77d5b09b88d9f3805e Mon Sep 17 00:00:00 2001 From: Darius Date: Tue, 6 Jun 2023 22:52:01 -0400 Subject: [PATCH 21/25] chore: Formatted code --- swarm/src/lib.rs | 2 +- swarm/src/listen_opts.rs | 3 +-- swarm/tests/listener.rs | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index a5501fa64f7..fdebc7b5e0a 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -65,10 +65,10 @@ mod upgrade; pub mod behaviour; pub mod dial_opts; -pub mod listen_opts; pub mod dummy; pub mod handler; pub mod keep_alive; +pub mod listen_opts; /// Bundles all symbols required for the [`libp2p_swarm_derive::NetworkBehaviour`] macro. #[doc(hidden)] diff --git a/swarm/src/listen_opts.rs b/swarm/src/listen_opts.rs index 0acb90a766f..9c7a2f7b1b5 100644 --- a/swarm/src/listen_opts.rs +++ b/swarm/src/listen_opts.rs @@ -1,7 +1,6 @@ use crate::ListenerId; use libp2p_core::Multiaddr; - #[derive(Debug)] pub struct ListenOpts { id: ListenerId, @@ -31,4 +30,4 @@ impl From for ListenOpts { fn from(addr: Multiaddr) -> Self { ListenOpts::new(addr) } -} \ No newline at end of file +} diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index ebe20506382..76ac346a9db 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -6,9 +6,9 @@ use std::{ use libp2p_core::{multiaddr::Protocol, transport::ListenerId, Endpoint, Multiaddr}; use libp2p_identity::PeerId; use libp2p_swarm::{ - derive_prelude::NewListener, dummy, ConnectionDenied, ConnectionId, FromSwarm, ListenerClosed, - ListenerError, NetworkBehaviour, NewListenAddr, PollParameters, Swarm, SwarmEvent, THandler, - THandlerInEvent, THandlerOutEvent, ToSwarm, listen_opts::ListenOpts, + derive_prelude::NewListener, dummy, listen_opts::ListenOpts, ConnectionDenied, ConnectionId, + FromSwarm, ListenerClosed, ListenerError, NetworkBehaviour, NewListenAddr, PollParameters, + Swarm, SwarmEvent, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, }; use libp2p_swarm_test::SwarmExt; From bc789b2842a3364a7b85754ab2cb7725a6e14ab8 Mon Sep 17 00:00:00 2001 From: Darius Date: Wed, 7 Jun 2023 00:28:25 -0400 Subject: [PATCH 22/25] chore: re-export ListenOpts --- swarm/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index fdebc7b5e0a..1d750caab67 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -68,7 +68,7 @@ pub mod dial_opts; pub mod dummy; pub mod handler; pub mod keep_alive; -pub mod listen_opts; +mod listen_opts; /// Bundles all symbols required for the [`libp2p_swarm_derive::NetworkBehaviour`] macro. #[doc(hidden)] @@ -122,7 +122,7 @@ pub use handler::{ }; #[cfg(feature = "macros")] pub use libp2p_swarm_derive::NetworkBehaviour; -use listen_opts::ListenOpts; +pub use listen_opts::ListenOpts; pub use stream::Stream; pub use stream_protocol::{InvalidProtocol, StreamProtocol}; From 5ea58d153e5a23025a2dddbaf2504d82cf4f6b82 Mon Sep 17 00:00:00 2001 From: Darius Date: Wed, 7 Jun 2023 00:34:11 -0400 Subject: [PATCH 23/25] chore: Updated code --- swarm/src/lib.rs | 12 ++++++++---- swarm/src/listen_opts.rs | 4 ++-- swarm/tests/listener.rs | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 1d750caab67..5b52309335b 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -375,7 +375,7 @@ where pub fn listen_on(&mut self, addr: Multiaddr) -> Result> { let opts = ListenOpts::new(addr); let id = opts.listener_id(); - self.add_listener(opts); + self.add_listener(opts)?; Ok(id) } @@ -543,22 +543,26 @@ where self.confirmed_external_addr.iter() } - fn add_listener(&mut self, opts: ListenOpts) { + fn add_listener(&mut self, opts: ListenOpts) -> Result<(), TransportError> { let addr = opts.address(); let listener_id = opts.listener_id(); - if let Err(e) = self.transport.listen_on(listener_id, addr) { + if let Err(e) = self.transport.listen_on(listener_id, addr.clone()) { self.behaviour .on_swarm_event(FromSwarm::ListenerError(behaviour::ListenerError { listener_id, err: &e, })); + + return Err(e); } self.behaviour .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { listener_id, })); + + Ok(()) } /// Add a **confirmed** external address for the local node. @@ -1034,7 +1038,7 @@ where } } ToSwarm::ListenOn { opts } => { - self.add_listener(opts); + let _ = self.add_listener(opts); } ToSwarm::RemoveListener { id } => { self.remove_listener(id); diff --git a/swarm/src/listen_opts.rs b/swarm/src/listen_opts.rs index 9c7a2f7b1b5..9c4d69a6fa0 100644 --- a/swarm/src/listen_opts.rs +++ b/swarm/src/listen_opts.rs @@ -21,8 +21,8 @@ impl ListenOpts { } /// Get the [`Multiaddr`] that is being listened on - pub fn address(&self) -> Multiaddr { - self.address.clone() + pub fn address(&self) -> &Multiaddr { + &self.address } } diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index 76ac346a9db..8c732fe45af 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -6,7 +6,7 @@ use std::{ use libp2p_core::{multiaddr::Protocol, transport::ListenerId, Endpoint, Multiaddr}; use libp2p_identity::PeerId; use libp2p_swarm::{ - derive_prelude::NewListener, dummy, listen_opts::ListenOpts, ConnectionDenied, ConnectionId, + derive_prelude::NewListener, dummy, ListenOpts, ConnectionDenied, ConnectionId, FromSwarm, ListenerClosed, ListenerError, NetworkBehaviour, NewListenAddr, PollParameters, Swarm, SwarmEvent, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, }; From 603933cc74e35d76fc759a792280d597d2d1f73e Mon Sep 17 00:00:00 2001 From: Darius Date: Wed, 7 Jun 2023 00:34:41 -0400 Subject: [PATCH 24/25] chore: Added comment --- swarm/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 5b52309335b..18e8f60d158 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1038,6 +1038,7 @@ where } } ToSwarm::ListenOn { opts } => { + // Error is dispatched internally, safe to ignore. let _ = self.add_listener(opts); } ToSwarm::RemoveListener { id } => { From 08d76599c64f6fa9571c4a69e9e9e3b98c4b100d Mon Sep 17 00:00:00 2001 From: Darius Date: Wed, 7 Jun 2023 00:34:55 -0400 Subject: [PATCH 25/25] chore: Formatted code --- swarm/tests/listener.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swarm/tests/listener.rs b/swarm/tests/listener.rs index 8c732fe45af..71d92cb0e1f 100644 --- a/swarm/tests/listener.rs +++ b/swarm/tests/listener.rs @@ -6,9 +6,9 @@ use std::{ use libp2p_core::{multiaddr::Protocol, transport::ListenerId, Endpoint, Multiaddr}; use libp2p_identity::PeerId; use libp2p_swarm::{ - derive_prelude::NewListener, dummy, ListenOpts, ConnectionDenied, ConnectionId, - FromSwarm, ListenerClosed, ListenerError, NetworkBehaviour, NewListenAddr, PollParameters, - Swarm, SwarmEvent, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, + derive_prelude::NewListener, dummy, ConnectionDenied, ConnectionId, FromSwarm, ListenOpts, + ListenerClosed, ListenerError, NetworkBehaviour, NewListenAddr, PollParameters, Swarm, + SwarmEvent, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, }; use libp2p_swarm_test::SwarmExt;