From d5010194109321c4596787f39fdb14227e5acb49 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 9 Nov 2022 11:39:10 +1100 Subject: [PATCH 01/21] Introduce `NetworkBehaviour::DialPayload` --- swarm/src/behaviour.rs | 164 +++++++++++----------------------- swarm/src/behaviour/either.rs | 47 +++++----- swarm/src/behaviour/toggle.rs | 31 +++---- swarm/src/connection/pool.rs | 66 +++++++------- swarm/src/dummy.rs | 11 ++- swarm/src/keep_alive.rs | 11 ++- swarm/src/lib.rs | 67 +++++++++----- 7 files changed, 185 insertions(+), 212 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 385b7eaf0a3..f6c02822baa 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -124,6 +124,8 @@ pub trait NetworkBehaviour: 'static { /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; + type DialPayload: Send + 'static; + /// Creates a new [`ConnectionHandler`] for a connection with a peer. /// /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] @@ -140,8 +142,26 @@ pub trait NetworkBehaviour: 'static { /// /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and /// connection closing. + // TODO: Mark as deprecated. fn new_handler(&mut self) -> Self::ConnectionHandler; + fn new_inbound_handler(&mut self) -> Self::ConnectionHandler { + self.new_handler() + } + + fn new_outbound_handler( + &mut self, + dial_payload: Option, + ) -> Self::ConnectionHandler { + if dial_payload.is_some() { + log::warn!( + "Discarding dial_payload. Please stop using the deprecated `new_handler` function." + ) + } + + self.new_handler() + } + /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. /// @@ -203,7 +223,7 @@ pub trait NetworkBehaviour: 'static { fn inject_dial_failure( &mut self, _peer_id: Option, - _handler: Self::ConnectionHandler, + _dial_payload: Option, _error: &DialError, ) { } @@ -213,13 +233,7 @@ pub trait NetworkBehaviour: 'static { /// /// This can include, for example, an error during the handshake of the encryption layer, or the /// connection unexpectedly closed. - fn inject_listen_failure( - &mut self, - _local_addr: &Multiaddr, - _send_back_addr: &Multiaddr, - _handler: Self::ConnectionHandler, - ) { - } + fn inject_listen_failure(&mut self, _local_addr: &Multiaddr, _send_back_addr: &Multiaddr) {} /// Indicates to the behaviour that a new listener was created. fn inject_new_listener(&mut self, _id: ListenerId) {} @@ -252,7 +266,13 @@ pub trait NetworkBehaviour: 'static { &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll>; + ) -> Poll< + NetworkBehaviourAction< + Self::OutEvent, + THandlerInEvent, + Self::DialPayload, + >, + >; } /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. @@ -291,11 +311,7 @@ pub trait PollParameters { // [`NetworkBehaviourAction::map_in`], mapping the handler `InEvent` leaving the // handler itself untouched. #[derive(Debug)] -pub enum NetworkBehaviourAction< - TOutEvent, - THandler: IntoConnectionHandler, - TInEvent = THandlerInEvent, -> { +pub enum NetworkBehaviourAction { /// Instructs the `Swarm` to return an event when it is being polled. GenerateEvent(TOutEvent), @@ -484,7 +500,10 @@ pub enum NetworkBehaviourAction< /// # #[derive(Debug, PartialEq, Eq)] /// # struct PreciousMessage(String); /// ``` - Dial { opts: DialOpts, handler: THandler }, + Dial { + opts: DialOpts, + dial_payload: TDialPayload, + }, /// Instructs the `Swarm` to send an event to the handler dedicated to a /// connection with a peer. @@ -544,18 +563,16 @@ pub enum NetworkBehaviourAction< }, } -impl - NetworkBehaviourAction -{ +impl NetworkBehaviourAction { /// Map the handler event. - pub fn map_in( + pub fn map_in( self, - f: impl FnOnce(TInEventOld) -> TInEventNew, - ) -> NetworkBehaviourAction { + f: impl FnOnce(TInEvent) -> E, + ) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => { - NetworkBehaviourAction::Dial { opts, handler } + NetworkBehaviourAction::Dial { opts, dial_payload } => { + NetworkBehaviourAction::Dial { opts, dial_payload } } NetworkBehaviourAction::NotifyHandler { peer_id, @@ -578,58 +595,20 @@ impl }, } } -} -impl NetworkBehaviourAction { /// Map the event the swarm will return. - pub fn map_out(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction { - match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), - NetworkBehaviourAction::Dial { opts, handler } => { - NetworkBehaviourAction::Dial { opts, handler } - } - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - } => NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - }, - NetworkBehaviourAction::ReportObservedAddr { address, score } => { - NetworkBehaviourAction::ReportObservedAddr { address, score } - } - NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - } => NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - }, - } - } -} - -impl NetworkBehaviourAction -where - THandlerOld: IntoConnectionHandler, - ::Handler: ConnectionHandler, -{ - /// Map the handler. - pub fn map_handler( + pub fn map_out( self, - f: impl FnOnce(THandlerOld) -> THandlerNew, - ) -> NetworkBehaviourAction - where - THandlerNew: IntoConnectionHandler, - ::Handler: ConnectionHandler, - { + f: impl FnOnce(TOutEvent) -> E, + ) -> NetworkBehaviourAction { match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial { + NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), + NetworkBehaviourAction::Dial { + opts, + dial_payload: initial_in_event, + } => NetworkBehaviourAction::Dial { opts, - handler: f(handler), + dial_payload: initial_in_event, }, NetworkBehaviourAction::NotifyHandler { peer_id, @@ -652,49 +631,12 @@ where }, } } -} -impl NetworkBehaviourAction -where - THandlerOld: IntoConnectionHandler, - ::Handler: ConnectionHandler, -{ - /// Map the handler and handler event. - pub fn map_handler_and_in( + pub fn map_dial_payload( self, - f_handler: impl FnOnce(THandlerOld) -> THandlerNew, - f_in_event: impl FnOnce(TInEventOld) -> TInEventNew, - ) -> NetworkBehaviourAction - where - THandlerNew: IntoConnectionHandler, - ::Handler: ConnectionHandler, - { - match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial { - opts, - handler: f_handler(handler), - }, - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - } => NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event: f_in_event(event), - }, - NetworkBehaviourAction::ReportObservedAddr { address, score } => { - NetworkBehaviourAction::ReportObservedAddr { address, score } - } - NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - } => NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - }, - } + f: impl FnOnce(TDialPayload) -> E, + ) -> NetworkBehaviourAction { + todo!() } } diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 6bb1d95a519..4fcf8aa2523 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -18,6 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::THandlerInEvent; use crate::handler::{either::IntoEitherHandler, ConnectionHandler, IntoConnectionHandler}; use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use either::Either; @@ -34,6 +35,7 @@ where { type ConnectionHandler = IntoEitherHandler; type OutEvent = Either; + type DialPayload = Either; fn new_handler(&mut self) -> Self::ConnectionHandler { match self { @@ -136,34 +138,25 @@ where fn inject_dial_failure( &mut self, peer_id: Option, - handler: Self::ConnectionHandler, + dial_payload: Option>, error: &DialError, ) { - match (self, handler) { - (Either::Left(behaviour), IntoEitherHandler::Left(handler)) => { - behaviour.inject_dial_failure(peer_id, handler, error) + match (self, dial_payload) { + (Either::Left(behaviour), Some(Either::Left(payload))) => { + behaviour.inject_dial_failure(peer_id, Some(payload), error) } - (Either::Right(behaviour), IntoEitherHandler::Right(handler)) => { - behaviour.inject_dial_failure(peer_id, handler, error) + (Either::Left(behaviour), None) => behaviour.inject_dial_failure(peer_id, None, error), + (Either::Right(behaviour), Some(Either::Right(payload))) => { + behaviour.inject_dial_failure(peer_id, Some(payload), error) } _ => unreachable!(), } } - fn inject_listen_failure( - &mut self, - local_addr: &Multiaddr, - send_back_addr: &Multiaddr, - handler: Self::ConnectionHandler, - ) { - match (self, handler) { - (Either::Left(behaviour), IntoEitherHandler::Left(handler)) => { - behaviour.inject_listen_failure(local_addr, send_back_addr, handler) - } - (Either::Right(behaviour), IntoEitherHandler::Right(handler)) => { - behaviour.inject_listen_failure(local_addr, send_back_addr, handler) - } - _ => unreachable!(), + fn inject_listen_failure(&mut self, local_addr: &Multiaddr, send_back_addr: &Multiaddr) { + match self { + Either::Left(behaviour) => behaviour.inject_listen_failure(local_addr, send_back_addr), + Either::Right(behaviour) => behaviour.inject_listen_failure(local_addr, send_back_addr), } } @@ -220,14 +213,22 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll< + NetworkBehaviourAction< + Self::OutEvent, + Either, THandlerInEvent>, + Either, + >, + > { let event = match self { Either::Left(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Left) - .map_handler_and_in(IntoEitherHandler::Left, Either::Left), + .map_in(Either::Left) + .map_dial_payload(Either::Left), Either::Right(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Right) - .map_handler_and_in(IntoEitherHandler::Right, Either::Right), + .map_in(Either::Right) + .map_dial_payload(Either::Right), }; Poll::Ready(event) diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 8f91c236148..5f246b89029 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -18,6 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::THandlerInEvent; use crate::handler::{ ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, KeepAlive, SubstreamProtocol, @@ -70,6 +71,7 @@ where { type ConnectionHandler = ToggleIntoConnectionHandler; type OutEvent = TBehaviour::OutEvent; + type DialPayload = TBehaviour::DialPayload; fn new_handler(&mut self) -> Self::ConnectionHandler { ToggleIntoConnectionHandler { @@ -150,26 +152,17 @@ where fn inject_dial_failure( &mut self, peer_id: Option, - handler: Self::ConnectionHandler, + dial_payload: Option, error: &DialError, ) { if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_dial_failure(peer_id, handler, error) - } + inner.inject_dial_failure(peer_id, dial_payload, error) } } - fn inject_listen_failure( - &mut self, - local_addr: &Multiaddr, - send_back_addr: &Multiaddr, - handler: Self::ConnectionHandler, - ) { + fn inject_listen_failure(&mut self, local_addr: &Multiaddr, send_back_addr: &Multiaddr) { if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_listen_failure(local_addr, send_back_addr, handler) - } + inner.inject_listen_failure(local_addr, send_back_addr) } } @@ -219,11 +212,15 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll< + NetworkBehaviourAction< + Self::OutEvent, + THandlerInEvent, + Self::DialPayload, + >, + > { if let Some(inner) = self.inner.as_mut() { - inner.poll(cx, params).map(|action| { - action.map_handler(|h| ToggleIntoConnectionHandler { inner: Some(h) }) - }) + inner.poll(cx, params) } else { Poll::Pending } diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index cc6a9bbd816..5b354a1a725 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -27,7 +27,8 @@ use crate::{ PendingInboundConnectionError, PendingOutboundConnectionError, }, transport::{Transport, TransportError}, - ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, PeerId, + ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, + NetworkBehaviour, PeerId, TBehaviourOutEvent, }; use concurrent_dial::ConcurrentDial; use fnv::FnvHashMap; @@ -55,7 +56,7 @@ mod concurrent_dial; mod task; /// A connection `Pool` manages a set of connections for each peer. -pub struct Pool +pub struct Pool where TTrans: Transport, { @@ -74,7 +75,7 @@ where >, /// The pending connections that are currently being negotiated. - pending: HashMap>, + pending: HashMap>, /// Next available identifier for a new connection / task. next_connection_id: ConnectionId, @@ -168,17 +169,16 @@ impl EstablishedConnection { } } -struct PendingConnection { +struct PendingConnection { /// [`PeerId`] of the remote peer. peer_id: Option, - /// Handler to handle connection once no longer pending but established. - handler: THandler, + dial_payload: Option, endpoint: PendingPoint, /// When dropped, notifies the task which then knows to terminate. abort_notifier: Option>, } -impl PendingConnection { +impl PendingConnection { fn is_for_same_remote_as(&self, other: PeerId) -> bool { self.peer_id.map_or(false, |peer| peer == other) } @@ -191,7 +191,9 @@ impl PendingConnection { } } -impl fmt::Debug for Pool { +impl fmt::Debug + for Pool +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.debug_struct("Pool") .field("counters", &self.counters) @@ -201,7 +203,7 @@ impl fmt::Debug for Pool +pub enum PoolEvent where TTrans: Transport, { @@ -249,8 +251,8 @@ where id: ConnectionId, /// The error that occurred. error: PendingOutboundConnectionError, - /// The handler that was supposed to handle the connection. - handler: THandler, + /// TODO + dial_payload: Option, /// The (expected) peer of the failed connection. peer: Option, }, @@ -265,8 +267,6 @@ where local_addr: Multiaddr, /// The error that occurred. error: PendingInboundConnectionError, - /// The handler that was supposed to handle the connection. - handler: THandler, }, /// A node has produced an event. @@ -288,7 +288,7 @@ where }, } -impl Pool +impl Pool where THandler: IntoConnectionHandler, TTrans: Transport, @@ -407,7 +407,7 @@ where } } -impl Pool +impl Pool where THandler: IntoConnectionHandler, TTrans: Transport + 'static, @@ -434,16 +434,16 @@ where >, >, peer: Option, - handler: THandler, + dial_payload: Option, role_override: Endpoint, dial_concurrency_factor_override: Option, - ) -> Result + ) -> Result)> where TTrans: Send, TTrans::Dial: Send + 'static, { if let Err(limit) = self.counters.check_max_pending_outgoing() { - return Err((limit, handler)); + return Err((limit, dial_payload)); }; let dial = ConcurrentDial::new( @@ -472,7 +472,7 @@ where connection_id, PendingConnection { peer_id: peer, - handler, + dial_payload, endpoint, abort_notifier: Some(abort_notifier), }, @@ -488,17 +488,14 @@ where pub fn add_incoming( &mut self, future: TFut, - handler: THandler, info: IncomingInfo<'_>, - ) -> Result + ) -> Result where TFut: Future> + Send + 'static, { let endpoint = info.create_connected_point(); - if let Err(limit) = self.counters.check_max_pending_incoming() { - return Err((limit, handler)); - } + self.counters.check_max_pending_incoming()?; let connection_id = self.next_connection_id(); @@ -519,7 +516,7 @@ where connection_id, PendingConnection { peer_id: None, - handler, + dial_payload: None, endpoint: endpoint.into(), abort_notifier: Some(abort_notifier), }, @@ -528,7 +525,11 @@ where } /// Polls the connection pool for events. - pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> + pub fn poll( + &mut self, + mut new_handler_fn: impl FnMut(&ConnectedPoint, Option) -> THandler, + cx: &mut Context<'_>, + ) -> Poll> where TTrans: Transport, THandler: IntoConnectionHandler + 'static, @@ -613,7 +614,7 @@ where } => { let PendingConnection { peer_id: expected_peer_id, - handler, + dial_payload, endpoint, abort_notifier: _, } = self @@ -715,7 +716,7 @@ where id, error: error .map(|t| vec![(endpoint.get_remote_address().clone(), t)]), - handler, + dial_payload, peer: expected_peer_id.or(Some(obtained_peer_id)), }) } @@ -726,7 +727,6 @@ where return Poll::Ready(PoolEvent::PendingInboundConnectionError { id, error, - handler, send_back_addr, local_addr, }) @@ -751,7 +751,8 @@ where let connection = Connection::new( muxer, - handler.into_handler(&obtained_peer_id, &endpoint), + new_handler_fn(&endpoint, dial_payload) + .into_handler(&obtained_peer_id, &endpoint), self.substream_upgrade_protocol_override, self.max_negotiating_inbound_streams, ); @@ -777,7 +778,7 @@ where task::PendingConnectionEvent::PendingFailed { id, error } => { if let Some(PendingConnection { peer_id, - handler, + dial_payload: initial_event, endpoint, abort_notifier: _, }) = self.pending.remove(&id) @@ -789,7 +790,7 @@ where return Poll::Ready(PoolEvent::PendingOutboundConnectionError { id, error, - handler, + dial_payload: initial_event, peer: peer_id, }); } @@ -803,7 +804,6 @@ where return Poll::Ready(PoolEvent::PendingInboundConnectionError { id, error, - handler, send_back_addr, local_addr, }); diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 61f055915b3..c0bb16dfb13 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,4 +1,4 @@ -use crate::behaviour::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::behaviour::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent}; use crate::handler::{InboundUpgradeSend, OutboundUpgradeSend}; use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol}; use libp2p_core::connection::ConnectionId; @@ -14,6 +14,7 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; + type DialPayload = Void; fn new_handler(&mut self) -> Self::ConnectionHandler { ConnectionHandler @@ -27,7 +28,13 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll< + NetworkBehaviourAction< + Self::OutEvent, + THandlerInEvent, + Self::DialPayload, + >, + > { Poll::Pending } } diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index ea5d5ee6399..7c2fdee70f6 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -1,4 +1,4 @@ -use crate::behaviour::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::behaviour::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent}; use crate::handler::{ ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, }; @@ -24,6 +24,7 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; + type DialPayload = Void; fn new_handler(&mut self) -> Self::ConnectionHandler { ConnectionHandler @@ -37,7 +38,13 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll< + NetworkBehaviourAction< + Self::OutEvent, + THandlerInEvent, + Self::DialPayload, + >, + > { Poll::Pending } } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 6fbff5db6b4..562ed1be1b7 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -266,7 +266,11 @@ where transport: transport::Boxed<(PeerId, StreamMuxerBox)>, /// The nodes currently active. - pool: Pool, transport::Boxed<(PeerId, StreamMuxerBox)>>, + pool: Pool< + THandler, + transport::Boxed<(PeerId, StreamMuxerBox)>, + TBehaviour::DialPayload, + >, /// The local peer ID. local_peer_id: PeerId, @@ -368,14 +372,13 @@ where /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); /// ``` pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { - let handler = self.behaviour.new_handler(); - self.dial_with_handler(opts.into(), handler) + self.dial_with_payload(opts.into(), None) } - fn dial_with_handler( + fn dial_with_payload( &mut self, swarm_dial_opts: DialOpts, - handler: ::ConnectionHandler, + payload: Option, ) -> Result<(), DialError> { let (peer_id, addresses, dial_concurrency_factor_override, role_override) = match swarm_dial_opts.0 { @@ -402,7 +405,7 @@ where if !condition_matched { self.behaviour.inject_dial_failure( Some(peer_id), - handler, + payload, &DialError::DialPeerConditionFalse(condition), ); @@ -413,7 +416,7 @@ where if self.banned_peers.contains(&peer_id) { let error = DialError::Banned; self.behaviour - .inject_dial_failure(Some(peer_id), handler, &error); + .inject_dial_failure(Some(peer_id), payload, &error); return Err(error); } @@ -450,7 +453,7 @@ where if addresses.is_empty() { let error = DialError::NoAddresses; self.behaviour - .inject_dial_failure(Some(peer_id), handler, &error); + .inject_dial_failure(Some(peer_id), payload, &error); return Err(error); }; @@ -525,14 +528,14 @@ where match self.pool.add_outgoing( dials, peer_id, - handler, + payload, role_override, dial_concurrency_factor_override, ) { Ok(_connection_id) => Ok(()), - Err((connection_limit, handler)) => { + Err((connection_limit, event)) => { let error = DialError::ConnectionLimit(connection_limit); - self.behaviour.inject_dial_failure(peer_id, handler, &error); + self.behaviour.inject_dial_failure(peer_id, event, &error); Err(error) } } @@ -662,7 +665,11 @@ where fn handle_pool_event( &mut self, - event: PoolEvent, transport::Boxed<(PeerId, StreamMuxerBox)>>, + event: PoolEvent< + THandler, + transport::Boxed<(PeerId, StreamMuxerBox)>, + TBehaviour::DialPayload, + >, ) -> Option>> { match event { PoolEvent::ConnectionEstablished { @@ -716,7 +723,7 @@ where PoolEvent::PendingOutboundConnectionError { id: _, error, - handler, + dial_payload: handler, peer, } => { let error = error.into(); @@ -739,11 +746,10 @@ where send_back_addr, local_addr, error, - handler, } => { log::debug!("Incoming connection failed: {:?}", error); self.behaviour - .inject_listen_failure(&local_addr, &send_back_addr, handler); + .inject_listen_failure(&local_addr, &send_back_addr); return Some(SwarmEvent::IncomingConnectionError { local_addr, send_back_addr, @@ -838,10 +844,8 @@ where local_addr, send_back_addr, } => { - let handler = self.behaviour.new_handler(); match self.pool.add_incoming( upgrade, - handler, IncomingInfo { local_addr: &local_addr, send_back_addr: &send_back_addr, @@ -853,9 +857,9 @@ where send_back_addr, }); } - Err((connection_limit, handler)) => { + Err(connection_limit) => { self.behaviour - .inject_listen_failure(&local_addr, &send_back_addr, handler); + .inject_listen_failure(&local_addr, &send_back_addr); log::warn!("Incoming connection rejected: {:?}", connection_limit); } }; @@ -927,15 +931,19 @@ where fn handle_behaviour_event( &mut self, - event: NetworkBehaviourAction, + event: NetworkBehaviourAction< + TBehaviour::OutEvent, + THandlerInEvent, + TBehaviour::DialPayload, + >, ) -> Option>> { match event { NetworkBehaviourAction::GenerateEvent(event) => { return Some(SwarmEvent::Behaviour(event)) } - NetworkBehaviourAction::Dial { opts, handler } => { + NetworkBehaviourAction::Dial { opts, dial_payload } => { let peer_id = opts.get_peer_id(); - if let Ok(()) = self.dial_with_handler(opts, handler) { + if let Ok(()) = self.dial_with_payload(opts, Some(dial_payload)) { if let Some(peer_id) = peer_id { return Some(SwarmEvent::Dialing(peer_id)); } @@ -1081,7 +1089,18 @@ where } // Poll the known peers. - match this.pool.poll(cx) { + match this.pool.poll( + |endpoint, payload| match (endpoint, payload) { + (ConnectedPoint::Dialer { .. }, payload) => { + this.behaviour.new_outbound_handler(payload) + } + (ConnectedPoint::Listener { .. }, None) => this.behaviour.new_inbound_handler(), + (ConnectedPoint::Listener { .. }, Some(_)) => { + panic!("Not sure what to do with dial payload as a listener") + } + }, + cx, + ) { Poll::Pending => {} Poll::Ready(pool_event) => { if let Some(swarm_event) = this.handle_pool_event(pool_event) { @@ -1156,7 +1175,7 @@ fn notify_one( /// was successfully sent to a handler, in either case the event is consumed. fn notify_any( ids: SmallVec<[ConnectionId; 10]>, - pool: &mut Pool, + pool: &mut Pool, event: THandlerInEvent, cx: &mut Context<'_>, ) -> Option<(THandlerInEvent, SmallVec<[ConnectionId; 10]>)> From 77c85f6e5d3569521f652c18db3a8c134e507a4e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 9 Nov 2022 13:00:59 +1100 Subject: [PATCH 02/21] WIP Migrate production code --- protocols/autonat/src/behaviour.rs | 18 +++---- protocols/autonat/src/behaviour/as_server.rs | 4 +- protocols/dcutr/src/behaviour.rs | 51 ++++++++++++++---- protocols/floodsub/src/layer.rs | 18 +++---- protocols/gossipsub/src/behaviour.rs | 12 ++--- protocols/gossipsub/src/behaviour/tests.rs | 22 +++++--- protocols/identify/src/behaviour.rs | 13 +++-- protocols/kad/src/behaviour.rs | 18 +++---- protocols/mdns/src/behaviour.rs | 30 ++++++----- protocols/ping/src/lib.rs | 12 ++++- protocols/relay/src/v2/client.rs | 56 +++++++++----------- protocols/relay/src/v2/relay.rs | 13 +++-- protocols/rendezvous/src/client.rs | 22 +++----- protocols/rendezvous/src/server.rs | 13 ++--- protocols/request-response/src/lib.rs | 13 +++-- swarm-derive/tests/test.rs | 3 +- swarm/src/behaviour.rs | 6 +-- swarm/src/test.rs | 10 ++-- 18 files changed, 190 insertions(+), 144 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index b39a7b141b4..c144d377304 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -36,6 +36,7 @@ use libp2p_request_response::{ handler::RequestResponseHandlerEvent, ProtocolSupport, RequestId, RequestResponse, RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -303,6 +304,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = as NetworkBehaviour>::ConnectionHandler; type OutEvent = Event; + type DialPayload = (); fn inject_connection_established( &mut self, @@ -372,10 +374,10 @@ impl NetworkBehaviour for Behaviour { fn inject_dial_failure( &mut self, peer: Option, - handler: Self::ConnectionHandler, + initial_event: Option, error: &DialError, ) { - self.inner.inject_dial_failure(peer, handler, error); + self.inner.inject_dial_failure(peer, initial_event, error); if let Some(event) = self.as_server().on_outbound_dial_error(peer, error) { self.pending_out_events .push_back(Event::InboundProbe(event)); @@ -487,14 +489,8 @@ impl NetworkBehaviour for Behaviour { self.inner.inject_event(peer_id, conn, event) } - fn inject_listen_failure( - &mut self, - local_addr: &Multiaddr, - send_back_addr: &Multiaddr, - handler: Self::ConnectionHandler, - ) { - self.inner - .inject_listen_failure(local_addr, send_back_addr, handler) + fn inject_listen_failure(&mut self, local_addr: &Multiaddr, send_back_addr: &Multiaddr) { + self.inner.inject_listen_failure(local_addr, send_back_addr) } fn inject_new_listener(&mut self, id: ListenerId) { @@ -512,7 +508,7 @@ impl NetworkBehaviour for Behaviour { type Action = NetworkBehaviourAction< ::OutEvent, - ::ConnectionHandler, + THandlerInEvent<::ConnectionHandler>, >; // Trait implemented for `AsClient` as `AsServer` to handle events from the inner [`RequestResponse`] Protocol. diff --git a/protocols/autonat/src/behaviour/as_server.rs b/protocols/autonat/src/behaviour/as_server.rs index 681076b92cb..48cb88b47c4 100644 --- a/protocols/autonat/src/behaviour/as_server.rs +++ b/protocols/autonat/src/behaviour/as_server.rs @@ -30,7 +30,7 @@ use libp2p_request_response::{ }; use libp2p_swarm::{ dial_opts::{DialOpts, PeerCondition}, - DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + DialError, NetworkBehaviourAction, PollParameters, }; use std::{ collections::{HashMap, HashSet, VecDeque}, @@ -137,7 +137,7 @@ impl<'a> HandleInnerEvent for AsServer<'a> { .override_dial_concurrency_factor(NonZeroU8::new(1).expect("1 > 0")) .addresses(addrs) .build(), - handler: self.inner.new_handler(), + dial_payload: (), }); } Err((status_text, error)) => { diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 5d93d90b339..acbef9e5980 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -26,6 +26,7 @@ use either::Either; use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; use libp2p_core::{Multiaddr, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ ConnectionHandler, ConnectionHandlerUpgrErr, DialError, IntoConnectionHandler, @@ -86,11 +87,26 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = handler::Prototype; type OutEvent = Event; + type DialPayload = handler::Prototype; fn new_handler(&mut self) -> Self::ConnectionHandler { handler::Prototype::UnknownConnection } + fn new_inbound_handler(&mut self) -> Self::ConnectionHandler { + handler::Prototype::UnknownConnection + } + + fn new_outbound_handler( + &mut self, + dial_payload: Option, + ) -> Self::ConnectionHandler { + match dial_payload { + Some(prototype) => prototype, + None => handler::Prototype::UnknownConnection, + } + } + fn addresses_of_peer(&mut self, _peer_id: &PeerId) -> Vec { vec![] } @@ -143,13 +159,13 @@ impl NetworkBehaviour for Behaviour { fn inject_dial_failure( &mut self, peer_id: Option, - handler: Self::ConnectionHandler, + dial_payload: Option, _error: &DialError, ) { - if let handler::Prototype::DirectConnection { + if let Some(handler::Prototype::DirectConnection { relayed_connection_id, role: handler::Role::Initiator { attempt }, - } = handler + }) = dial_payload { let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { @@ -243,7 +259,7 @@ impl NetworkBehaviour for Behaviour { .addresses(remote_addrs) .condition(dial_opts::PeerCondition::Always) .build(), - handler: handler::Prototype::DirectConnection { + dial_payload: handler::Prototype::DirectConnection { relayed_connection_id: connection, role: handler::Role::Listener, }, @@ -271,7 +287,7 @@ impl NetworkBehaviour for Behaviour { .addresses(remote_addrs) .override_role() .build(), - handler: handler::Prototype::DirectConnection { + dial_payload: handler::Prototype::DirectConnection { relayed_connection_id: connection, role: handler::Role::Initiator { attempt }, }, @@ -309,7 +325,13 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, poll_parameters: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll< + NetworkBehaviourAction< + Self::OutEvent, + THandlerInEvent, + handler::Prototype, + >, + > { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action.build(poll_parameters)); } @@ -321,7 +343,7 @@ impl NetworkBehaviour for Behaviour { /// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`] /// before being returned in [`Behaviour::poll`]. enum ActionBuilder { - Done(NetworkBehaviourAction), + Done(NetworkBehaviourAction, handler::Prototype>), Connect { attempt: u8, handler: NotifyHandler, @@ -334,8 +356,16 @@ enum ActionBuilder { }, } -impl From> for ActionBuilder { - fn from(action: NetworkBehaviourAction) -> Self { +impl From, handler::Prototype>> + for ActionBuilder +{ + fn from( + action: NetworkBehaviourAction< + Event, + THandlerInEvent, + handler::Prototype, + >, + ) -> Self { Self::Done(action) } } @@ -344,7 +374,8 @@ impl ActionBuilder { fn build( self, poll_parameters: &mut impl PollParameters, - ) -> NetworkBehaviourAction { + ) -> NetworkBehaviourAction, handler::Prototype> + { let obs_addrs = || { poll_parameters .external_addresses() diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 4256e39b7dc..08eb1946bcb 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -28,6 +28,7 @@ use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; use libp2p_core::{connection::ConnectionId, PeerId}; use libp2p_core::{ConnectedPoint, Multiaddr}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, PollParameters, @@ -41,12 +42,7 @@ use std::{collections::VecDeque, iter}; /// Network behaviour that handles the floodsub protocol. pub struct Floodsub { /// Events that need to be yielded to the outside when polling. - events: VecDeque< - NetworkBehaviourAction< - FloodsubEvent, - OneShotHandler, - >, - >, + events: VecDeque>, config: FloodsubConfig, @@ -107,10 +103,9 @@ impl Floodsub { } if self.target_peers.insert(peer_id) { - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + dial_payload: (), }); } } @@ -281,6 +276,7 @@ impl Floodsub { impl NetworkBehaviour for Floodsub { type ConnectionHandler = OneShotHandler; type OutEvent = FloodsubEvent; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { Default::default() @@ -339,10 +335,9 @@ impl NetworkBehaviour for Floodsub { // We can be disconnected by the remote in case of inactivity for example, so we always // try to reconnect. if self.target_peers.contains(id) { - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*id).build(), - handler, + dial_payload: (), }); } } @@ -470,7 +465,8 @@ impl NetworkBehaviour for Floodsub { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 43f2f79466d..f5bf175c500 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -200,7 +200,7 @@ impl From for PublishConfig { } type GossipsubNetworkBehaviourAction = - NetworkBehaviourAction>; + NetworkBehaviourAction>; /// Network behaviour that handles the gossipsub protocol. /// @@ -1139,10 +1139,9 @@ where if !self.peer_topics.contains_key(peer_id) { // Connect to peer debug!("Connecting to explicit peer {:?}", peer_id); - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer_id).build(), - handler, + dial_payload: (), }); } } @@ -1637,11 +1636,9 @@ where // mark as px peer self.px_peers.insert(peer_id); - // dial peer - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + dial_payload: (), }); } } @@ -3045,6 +3042,7 @@ where { type ConnectionHandler = GossipsubHandler; type OutEvent = GossipsubEvent; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { let protocol_config = ProtocolConfig::new( @@ -3437,7 +3435,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event.map_in(|e: Arc| { // clone send event reference if others references are present diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 71f4aae9b50..6124acde71b 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -1356,7 +1356,10 @@ fn test_explicit_peer_gets_connected() { .events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => opts.get_peer_id() == Some(peer), + NetworkBehaviourAction::Dial { + opts, + initial_in_event: _, + } => opts.get_peer_id() == Some(peer), _ => false, }) .count(); @@ -1397,8 +1400,10 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => - opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { + opts, + initial_in_event: _, + } => opts.get_peer_id() == Some(*peer), _ => false, }) .count(), @@ -1413,8 +1418,10 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => - opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { + opts, + initial_in_event: _, + } => opts.get_peer_id() == Some(*peer), _ => false, }) .count() @@ -1794,7 +1801,10 @@ fn test_connect_to_px_peers_on_handle_prune() { .events .iter() .filter_map(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => opts.get_peer_id(), + NetworkBehaviourAction::Dial { + opts, + initial_in_event: _, + } => opts.get_peer_id(), _ => None, }) .collect(); diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 92279765d5a..af300b21595 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -25,6 +25,7 @@ use libp2p_core::{ connection::ConnectionId, multiaddr::Protocol, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, PublicKey, }; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, IntoConnectionHandler, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, @@ -54,7 +55,7 @@ pub struct Behaviour { /// Pending replies to send. pending_replies: VecDeque, /// Pending events to be emitted when polled. - events: VecDeque>, + events: VecDeque>, /// Peers to which an active push with current information about /// the local peer should be sent. pending_push: HashSet, @@ -198,10 +199,9 @@ impl Behaviour { { for p in peers { if self.pending_push.insert(p) && !self.connected.contains_key(&p) { - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(p).build(), - handler, + dial_payload: (), }); } } @@ -263,7 +263,7 @@ impl NetworkBehaviour for Behaviour { fn inject_dial_failure( &mut self, peer_id: Option, - _: Self::ConnectionHandler, + _: Option, error: &DialError, ) { if let Some(peer_id) = peer_id { @@ -356,7 +356,8 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } @@ -452,6 +453,8 @@ impl NetworkBehaviour for Behaviour { fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { self.discovered_peers.get(peer) } + + type DialPayload = (); } /// Event emitted by the `Identify` behaviour. diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index d5009e0b3f7..459eb451af6 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -42,6 +42,7 @@ use instant::Instant; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, }; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ dial_opts::{self, DialOpts}, DialError, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -99,7 +100,7 @@ pub struct Kademlia { connection_idle_timeout: Duration, /// Queued events to return when the behaviour is being polled. - queued_events: VecDeque>>, + queued_events: VecDeque>>, /// The currently known addresses of the local node. local_addrs: HashSet, @@ -567,10 +568,9 @@ where RoutingUpdate::Failed } kbucket::InsertResult::Pending { disconnected } => { - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()).build(), - handler, + dial_payload: (), }); RoutingUpdate::Pending } @@ -1161,11 +1161,10 @@ where // // Only try dialing peer if not currently connected. if !self.connected_peers.contains(disconnected.preimage()) { - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()) .build(), - handler, + dial_payload: (), }) } } @@ -1785,6 +1784,7 @@ where { type ConnectionHandler = KademliaHandlerProto; type OutEvent = KademliaEvent; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { KademliaHandlerProto::new(KademliaHandlerConfig { @@ -1916,7 +1916,7 @@ where fn inject_dial_failure( &mut self, peer_id: Option, - _: Self::ConnectionHandler, + _: Option, error: &DialError, ) { let peer_id = match peer_id { @@ -2243,7 +2243,8 @@ where &mut self, cx: &mut Context<'_>, parameters: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { let now = Instant::now(); // Calculate the available capacity for queries triggered by background jobs. @@ -2341,10 +2342,9 @@ where }); } else if &peer_id != self.kbuckets.local_key().preimage() { query.inner.pending_rpcs.push((peer_id, event)); - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + dial_payload: (), }); } } diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index b19845ac1d7..dd783016183 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -35,6 +35,7 @@ use libp2p_swarm::{ use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; use std::{cmp, fmt, io, net::IpAddr, pin::Pin, task::Context, task::Poll, time::Instant}; +use void::Void; #[cfg(feature = "async-io")] use crate::behaviour::{socket::asio::AsyncUdpSocket, timer::asio::AsyncTimer}; @@ -120,6 +121,7 @@ where { type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = MdnsEvent; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { dummy::ConnectionHandler @@ -133,6 +135,19 @@ where .collect() } + fn inject_connection_closed( + &mut self, + peer: &PeerId, + _: &libp2p_core::connection::ConnectionId, + _: &libp2p_core::ConnectedPoint, + _: Self::ConnectionHandler, + remaining_established: usize, + ) { + if remaining_established == 0 { + self.expire_node(peer); + } + } + fn inject_event( &mut self, _: PeerId, @@ -149,24 +164,11 @@ where } } - fn inject_connection_closed( - &mut self, - peer: &PeerId, - _: &libp2p_core::connection::ConnectionId, - _: &libp2p_core::ConnectedPoint, - _: Self::ConnectionHandler, - remaining_established: usize, - ) { - if remaining_established == 0 { - self.expire_node(peer); - } - } - fn poll( &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll> { // Poll ifwatch. while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) { match event { diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 02babd2ea06..1207b1c3e6b 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -48,6 +48,7 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use std::{ collections::VecDeque, @@ -116,11 +117,19 @@ impl Default for Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; type OutEvent = Event; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { Handler::new(self.config.clone()) } + fn new_outbound_handler( + &mut self, + dial_payload: Option, + ) -> Self::ConnectionHandler { + todo!() + } + fn inject_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) { self.events.push_front(Event { peer, result }) } @@ -129,7 +138,8 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { if let Some(e) = self.events.pop_back() { let Event { result, peer } = &e; diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 68e69e20a28..2078eaab515 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -34,6 +34,7 @@ use futures::ready; use futures::stream::StreamExt; use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::{Multiaddr, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::dummy; use libp2p_swarm::{ @@ -118,6 +119,7 @@ impl Client { impl NetworkBehaviour for Client { type ConnectionHandler = handler::Prototype; type OutEvent = Event; + type DialPayload = handler::In; fn new_handler(&mut self) -> Self::ConnectionHandler { handler::Prototype::new(self.local_peer_id, None) @@ -231,7 +233,13 @@ impl NetworkBehaviour for Client { &mut self, cx: &mut Context<'_>, _poll_parameters: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll< + NetworkBehaviourAction< + Self::OutEvent, + THandlerInEvent, + Self::DialPayload, + >, + > { if let Some(event) = self.queued_actions.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); } @@ -252,19 +260,13 @@ impl NetworkBehaviour for Client { handler: NotifyHandler::One(*connection_id), event: Either::Left(handler::In::Reserve { to_listener }), }, - None => { - let handler = handler::Prototype::new( - self.local_peer_id, - Some(handler::In::Reserve { to_listener }), - ); - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) - .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() - .build(), - handler, - } - } + None => NetworkBehaviourAction::Dial { + opts: DialOpts::peer_id(relay_peer_id) + .addresses(vec![relay_addr]) + .extend_addresses_through_behaviour() + .build(), + dial_payload: handler::In::Reserve { to_listener }, + }, } } Some(transport::TransportToBehaviourMsg::DialReq { @@ -287,22 +289,16 @@ impl NetworkBehaviour for Client { dst_peer_id, }), }, - None => { - let handler = handler::Prototype::new( - self.local_peer_id, - Some(handler::In::EstablishCircuit { - send_back, - dst_peer_id, - }), - ); - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) - .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() - .build(), - handler, - } - } + None => NetworkBehaviourAction::Dial { + opts: DialOpts::peer_id(relay_peer_id) + .addresses(vec![relay_addr]) + .extend_addresses_through_behaviour() + .build(), + dial_payload: handler::In::EstablishCircuit { + send_back, + dst_peer_id, + }, + }, } } None => unreachable!( diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 5b1eb810f60..c073d3cf7b1 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -30,6 +30,7 @@ use instant::Instant; use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; use libp2p_core::PeerId; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ dummy, ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -217,6 +218,7 @@ impl Relay { impl NetworkBehaviour for Relay { type ConnectionHandler = handler::Prototype; type OutEvent = Event; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { handler::Prototype { @@ -620,7 +622,8 @@ impl NetworkBehaviour for Relay { &mut self, _cx: &mut Context<'_>, poll_parameters: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action.build(poll_parameters)); } @@ -723,7 +726,7 @@ impl Add for CircuitId { /// before being returned in [`Relay::poll`]. #[allow(clippy::large_enum_variant)] enum Action { - Done(NetworkBehaviourAction), + Done(NetworkBehaviourAction>), AcceptReservationPrototype { inbound_reservation_req: inbound_hop::ReservationReq, handler: NotifyHandler, @@ -731,8 +734,8 @@ enum Action { }, } -impl From> for Action { - fn from(action: NetworkBehaviourAction) -> Self { +impl From>> for Action { + fn from(action: NetworkBehaviourAction>) -> Self { Self::Done(action) } } @@ -741,7 +744,7 @@ impl Action { fn build( self, poll_parameters: &mut impl PollParameters, - ) -> NetworkBehaviourAction { + ) -> NetworkBehaviourAction> { match self { Action::Done(action) => action, Action::AcceptReservationPrototype { diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 5ceb945a4f1..6d704a31394 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -22,7 +22,7 @@ use crate::codec::{Cookie, ErrorCode, Namespace, NewRegistration, Registration, use crate::handler; use crate::handler::outbound; use crate::handler::outbound::OpenInfo; -use crate::substream_handler::SubstreamConnectionHandler; +use crate::substream_handler::{InEvent, SubstreamConnectionHandler}; use futures::future::BoxFuture; use futures::future::FutureExt; use futures::stream::FuturesUnordered; @@ -32,20 +32,17 @@ use libp2p_core::connection::ConnectionId; use libp2p_core::identity::error::SigningError; use libp2p_core::identity::Keypair; use libp2p_core::{Multiaddr, PeerId, PeerRecord}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; use std::collections::{HashMap, VecDeque}; use std::iter::FromIterator; use std::task::{Context, Poll}; +use void::Void; pub struct Behaviour { - events: VecDeque< - NetworkBehaviourAction< - Event, - SubstreamConnectionHandler, - >, - >, + events: VecDeque>>, keypair: Keypair, pending_register_requests: Vec<(Namespace, PeerId, Option)>, @@ -167,6 +164,7 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; type OutEvent = Event; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { let initial_keep_alive = Duration::from_secs(30); @@ -215,7 +213,8 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, poll_params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } @@ -272,12 +271,7 @@ fn handle_outbound_event( peer_id: PeerId, discovered_peers: &mut HashMap<(PeerId, Namespace), Vec>, expiring_registrations: &mut FuturesUnordered>, -) -> Vec< - NetworkBehaviourAction< - Event, - SubstreamConnectionHandler, - >, -> { +) -> Vec>> { match event { outbound::OutEvent::Registered { namespace, ttl } => { vec![NetworkBehaviourAction::GenerateEvent(Event::Registered { diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index dd4731d8a8d..41b16391ec1 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -20,7 +20,7 @@ use crate::codec::{Cookie, ErrorCode, Namespace, NewRegistration, Registration, Ttl}; use crate::handler::inbound; -use crate::substream_handler::{InboundSubstreamId, SubstreamConnectionHandler}; +use crate::substream_handler::{InEvent, InboundSubstreamId, SubstreamConnectionHandler}; use crate::{handler, MAX_TTL, MIN_TTL}; use bimap::BiMap; use futures::future::BoxFuture; @@ -29,6 +29,7 @@ use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use libp2p_core::connection::ConnectionId; use libp2p_core::PeerId; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -39,9 +40,7 @@ use std::time::Duration; use void::Void; pub struct Behaviour { - events: VecDeque< - NetworkBehaviourAction>, - >, + events: VecDeque>>, registrations: Registrations, } @@ -111,6 +110,7 @@ pub enum Event { impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; type OutEvent = Event; + type DialPayload = (); fn new_handler(&mut self) -> Self::ConnectionHandler { let initial_keep_alive = Duration::from_secs(30); @@ -147,7 +147,8 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { if let Poll::Ready(ExpiredRegistration(registration)) = self.registrations.poll(cx) { return Poll::Ready(NetworkBehaviourAction::GenerateEvent( Event::RegistrationExpired(registration), @@ -168,7 +169,7 @@ fn handle_inbound_event( connection: ConnectionId, id: InboundSubstreamId, registrations: &mut Registrations, -) -> Vec>> { +) -> Vec>> { match event { // bad registration inbound::OutEvent::RegistrationRequested(registration) diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 887a42a9b6a..d690aeeb34c 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -67,6 +67,7 @@ pub use handler::ProtocolSupport; use futures::channel::oneshot; use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ dial_opts::DialOpts, DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -315,7 +316,7 @@ where pending_events: VecDeque< NetworkBehaviourAction< RequestResponseEvent, - RequestResponseHandler, + RequestProtocol, >, >, /// The currently connected peers, their pending outbound and inbound responses and their known, @@ -384,10 +385,9 @@ where }; if let Some(request) = self.try_send_request(peer, request) { - let handler = self.new_handler(); self.pending_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer).build(), - handler, + dial_payload: (), }); self.pending_outbound_requests .entry(*peer) @@ -690,7 +690,7 @@ where fn inject_dial_failure( &mut self, peer: Option, - _: Self::ConnectionHandler, + _: Option, _: &DialError, ) { if let Some(peer) = peer { @@ -871,7 +871,8 @@ where &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { if let Some(ev) = self.pending_events.pop_front() { return Poll::Ready(ev); } else if self.pending_events.capacity() > EMPTY_QUEUE_SHRINK_THRESHOLD { @@ -880,6 +881,8 @@ where Poll::Pending } + + type DialPayload = (); } /// Internal threshold for when to shrink the capacity diff --git a/swarm-derive/tests/test.rs b/swarm-derive/tests/test.rs index 368fc7d326a..850c22cb904 100644 --- a/swarm-derive/tests/test.rs +++ b/swarm-derive/tests/test.rs @@ -387,7 +387,8 @@ fn custom_out_event_no_type_parameters() { &mut self, _ctx: &mut Context, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { Poll::Pending } } diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index f6c02822baa..d4dd1ca0b72 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -30,10 +30,10 @@ use libp2p_core::{ use std::{task::Context, task::Poll}; /// Custom event that can be received by the [`ConnectionHandler`]. -pub(crate) type THandlerInEvent = +pub type THandlerInEvent = <::Handler as ConnectionHandler>::InEvent; -pub(crate) type THandlerOutEvent = +pub type THandlerOutEvent = <::Handler as ConnectionHandler>::OutEvent; /// A [`NetworkBehaviour`] defines the behaviour of the local node on the network. @@ -429,7 +429,7 @@ pub enum NetworkBehaviourAction { /// # &mut self, /// # _: &mut Context<'_>, /// # _: &mut impl PollParameters, - /// # ) -> Poll> { + /// # ) -> Poll>> { /// # if let Some(action) = self.outbox_to_swarm.pop_front() { /// # return Poll::Ready(action); /// # } diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 093ee420cb5..556bdabe7bd 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -19,8 +19,8 @@ // DEALINGS IN THE SOFTWARE. use crate::{ - ConnectionHandler, DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, + behaviour::THandlerInEvent, ConnectionHandler, DialError, IntoConnectionHandler, + NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; use libp2p_core::{ connection::ConnectionId, multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId, @@ -82,7 +82,8 @@ where &mut self, _: &mut Context, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { self.next_action.take().map_or(Poll::Pending, Poll::Ready) } } @@ -398,7 +399,8 @@ where &mut self, cx: &mut Context, args: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> + { self.poll += 1; self.inner.poll(cx, args) } From 118ffb64b77146718f59c38db6f9ad8ddc6d10d0 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 9 Nov 2022 13:02:48 +1100 Subject: [PATCH 03/21] Deprecate `new_handler` --- swarm/src/behaviour.rs | 2 +- swarm/src/connection/pool.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index d4dd1ca0b72..29d0cfb97d5 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -142,7 +142,7 @@ pub trait NetworkBehaviour: 'static { /// /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and /// connection closing. - // TODO: Mark as deprecated. + #[deprecated(since = "0.41.0", note = "Implement `new_inbound_handler` and `new_outbound_handler` instead.")] fn new_handler(&mut self) -> Self::ConnectionHandler; fn new_inbound_handler(&mut self) -> Self::ConnectionHandler { diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 5b354a1a725..54c36afca28 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -28,7 +28,7 @@ use crate::{ }, transport::{Transport, TransportError}, ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, - NetworkBehaviour, PeerId, TBehaviourOutEvent, + PeerId, }; use concurrent_dial::ConcurrentDial; use fnv::FnvHashMap; From 377c351ed2dd1bc6501b1d2eb3676c0b70da83d1 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 09:31:50 +1100 Subject: [PATCH 04/21] WIP: Completely remove `IntoConnectionHandler` --- protocols/autonat/src/behaviour.rs | 26 ++-- protocols/autonat/src/behaviour/as_server.rs | 1 - protocols/dcutr/src/behaviour.rs | 144 ++++++++----------- protocols/dcutr/src/handler.rs | 75 +++++----- protocols/floodsub/src/layer.rs | 5 +- protocols/gossipsub/src/behaviour.rs | 10 +- protocols/gossipsub/src/behaviour/tests.rs | 22 +-- protocols/gossipsub/src/config.rs | 4 +- protocols/identify/src/behaviour.rs | 31 ++-- protocols/identify/src/handler.rs | 32 +---- protocols/kad/src/behaviour.rs | 43 +++--- protocols/kad/src/handler.rs | 53 +++---- protocols/mdns/src/behaviour.rs | 5 +- protocols/ping/src/lib.rs | 12 +- protocols/relay/src/v2/client.rs | 57 +++++--- protocols/relay/src/v2/client/handler.rs | 104 ++++++++------ protocols/relay/src/v2/relay.rs | 42 ++++-- protocols/relay/src/v2/relay/handler.rs | 87 ++++++----- protocols/rendezvous/src/client.rs | 5 +- protocols/rendezvous/src/server.rs | 5 +- protocols/request-response/src/lib.rs | 20 +-- swarm-derive/src/lib.rs | 116 +++------------ swarm-derive/tests/test.rs | 10 +- swarm/src/behaviour.rs | 101 +++---------- swarm/src/behaviour/either.rs | 45 +++--- swarm/src/behaviour/toggle.rs | 74 +++------- swarm/src/connection/pool.rs | 70 ++++----- swarm/src/dummy.rs | 14 +- swarm/src/handler.rs | 46 +----- swarm/src/handler/either.rs | 39 +---- swarm/src/handler/multi.rs | 70 +-------- swarm/src/handler/select.rs | 50 +------ swarm/src/keep_alive.rs | 14 +- swarm/src/lib.rs | 100 ++++--------- swarm/src/test.rs | 36 +++-- 35 files changed, 545 insertions(+), 1023 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index c144d377304..8883084fb9e 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -37,9 +37,7 @@ use libp2p_request_response::{ RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }; use libp2p_swarm::behaviour::THandlerInEvent; -use libp2p_swarm::{ - DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, -}; +use libp2p_swarm::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use std::{ collections::{HashMap, VecDeque}, iter, @@ -304,7 +302,6 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = as NetworkBehaviour>::ConnectionHandler; type OutEvent = Event; - type DialPayload = (); fn inject_connection_established( &mut self, @@ -358,7 +355,7 @@ impl NetworkBehaviour for Behaviour { peer: &PeerId, conn: &ConnectionId, endpoint: &ConnectedPoint, - handler: ::Handler, + handler: Self::ConnectionHandler, remaining_established: usize, ) { self.inner @@ -371,14 +368,9 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_dial_failure( - &mut self, - peer: Option, - initial_event: Option, - error: &DialError, - ) { - self.inner.inject_dial_failure(peer, initial_event, error); - if let Some(event) = self.as_server().on_outbound_dial_error(peer, error) { + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + self.inner.inject_dial_failure(_peer_id, _error); + if let Some(event) = self.as_server().on_outbound_dial_error(_peer_id, _error) { self.pending_out_events .push_back(Event::InboundProbe(event)); } @@ -472,8 +464,12 @@ impl NetworkBehaviour for Behaviour { } } - fn new_handler(&mut self) -> Self::ConnectionHandler { - self.inner.new_handler() + fn new_handler( + &mut self, + peer: &PeerId, + connected_point: &ConnectedPoint, + ) -> Self::ConnectionHandler { + self.inner.new_handler(peer, connected_point) } fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { diff --git a/protocols/autonat/src/behaviour/as_server.rs b/protocols/autonat/src/behaviour/as_server.rs index 48cb88b47c4..eab3fe73741 100644 --- a/protocols/autonat/src/behaviour/as_server.rs +++ b/protocols/autonat/src/behaviour/as_server.rs @@ -137,7 +137,6 @@ impl<'a> HandleInnerEvent for AsServer<'a> { .override_dial_concurrency_factor(NonZeroU8::new(1).expect("1 > 0")) .addresses(addrs) .build(), - dial_payload: (), }); } Err((status_text, error)) => { diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index acbef9e5980..5e8ead9dbe5 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -29,8 +29,8 @@ use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerUpgrErr, DialError, IntoConnectionHandler, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + dummy, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, NetworkBehaviour, + NetworkBehaviourAction, NotifyHandler, PollParameters, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; @@ -75,6 +75,9 @@ pub struct Behaviour { direct_connections: HashMap>, } +type Handler = + Either>; + impl Behaviour { pub fn new() -> Self { Behaviour { @@ -85,26 +88,17 @@ impl Behaviour { } impl NetworkBehaviour for Behaviour { - type ConnectionHandler = handler::Prototype; + type ConnectionHandler = Handler; type OutEvent = Event; - type DialPayload = handler::Prototype; - - fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::UnknownConnection - } - fn new_inbound_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::UnknownConnection - } - - fn new_outbound_handler( + fn new_handler( &mut self, - dial_payload: Option, + peer: &PeerId, + connected_point: &ConnectedPoint, ) -> Self::ConnectionHandler { - match dial_payload { - Some(prototype) => prototype, - None => handler::Prototype::UnknownConnection, - } + // handler::Prototype::UnknownConnection + + todo!() } fn addresses_of_peer(&mut self, _peer_id: &PeerId) -> Vec { @@ -156,42 +150,38 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_dial_failure( - &mut self, - peer_id: Option, - dial_payload: Option, - _error: &DialError, - ) { - if let Some(handler::Prototype::DirectConnection { - relayed_connection_id, - role: handler::Role::Initiator { attempt }, - }) = dial_payload - { - let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); - if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - self.queued_actions.push_back(ActionBuilder::Connect { - peer_id, - handler: NotifyHandler::One(relayed_connection_id), - attempt: attempt + 1, - }); - } else { - self.queued_actions.extend([ - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left( - handler::relayed::Command::UpgradeFinishedDontKeepAlive, - ), - } - .into(), - NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { - remote_peer_id: peer_id, - error: UpgradeError::Dial, - }) - .into(), - ]); - } - } + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + // TODO: Track state in behaviour + // if let Some(handler::Prototype::DirectConnection { + // relayed_connection_id, + // role: handler::Role::Initiator { attempt }, + // }) = dial_payload + // { + // let peer_id = _peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); + // if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { + // self.queued_actions.push_back(ActionBuilder::Connect { + // peer_id, + // handler: NotifyHandler::One(relayed_connection_id), + // attempt: attempt + 1, + // }); + // } else { + // self.queued_actions.extend([ + // NetworkBehaviourAction::NotifyHandler { + // peer_id, + // handler: NotifyHandler::One(relayed_connection_id), + // event: Either::Left( + // handler::relayed::Command::UpgradeFinishedDontKeepAlive, + // ), + // } + // .into(), + // NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { + // remote_peer_id: peer_id, + // error: UpgradeError::Dial, + // }) + // .into(), + // ]); + // } + // } } fn inject_connection_closed( @@ -199,7 +189,7 @@ impl NetworkBehaviour for Behaviour { peer_id: &PeerId, connection_id: &ConnectionId, connected_point: &ConnectedPoint, - _handler: <::ConnectionHandler as IntoConnectionHandler>::Handler, + _handler: Self::ConnectionHandler, _remaining_established: usize, ) { if !connected_point.is_relayed() { @@ -221,7 +211,7 @@ impl NetworkBehaviour for Behaviour { &mut self, event_source: PeerId, connection: ConnectionId, - handler_event: <::Handler as ConnectionHandler>::OutEvent, + handler_event: ::OutEvent, ) { match handler_event { Either::Left(handler::relayed::Event::InboundConnectRequest { @@ -259,10 +249,10 @@ impl NetworkBehaviour for Behaviour { .addresses(remote_addrs) .condition(dial_opts::PeerCondition::Always) .build(), - dial_payload: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Listener, - }, + // dial_payload: handler::Prototype::DirectConnection { + // relayed_connection_id: connection, + // role: handler::Role::Listener, + // }, } .into(), ); @@ -287,10 +277,10 @@ impl NetworkBehaviour for Behaviour { .addresses(remote_addrs) .override_role() .build(), - dial_payload: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Initiator { attempt }, - }, + // dial_payload: handler::Prototype::DirectConnection { + // relayed_connection_id: connection, + // role: handler::Role::Initiator { attempt }, + // }, } .into(), ); @@ -325,13 +315,8 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, poll_parameters: &mut impl PollParameters, - ) -> Poll< - NetworkBehaviourAction< - Self::OutEvent, - THandlerInEvent, - handler::Prototype, - >, - > { + ) -> Poll>> + { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action.build(poll_parameters)); } @@ -343,7 +328,7 @@ impl NetworkBehaviour for Behaviour { /// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`] /// before being returned in [`Behaviour::poll`]. enum ActionBuilder { - Done(NetworkBehaviourAction, handler::Prototype>), + Done(NetworkBehaviourAction>), Connect { attempt: u8, handler: NotifyHandler, @@ -356,16 +341,8 @@ enum ActionBuilder { }, } -impl From, handler::Prototype>> - for ActionBuilder -{ - fn from( - action: NetworkBehaviourAction< - Event, - THandlerInEvent, - handler::Prototype, - >, - ) -> Self { +impl From>> for ActionBuilder { + fn from(action: NetworkBehaviourAction>) -> Self { Self::Done(action) } } @@ -374,8 +351,7 @@ impl ActionBuilder { fn build( self, poll_parameters: &mut impl PollParameters, - ) -> NetworkBehaviourAction, handler::Prototype> - { + ) -> NetworkBehaviourAction> { let obs_addrs = || { poll_parameters .external_addresses() diff --git a/protocols/dcutr/src/handler.rs b/protocols/dcutr/src/handler.rs index e854b395308..41cd9f20355 100644 --- a/protocols/dcutr/src/handler.rs +++ b/protocols/dcutr/src/handler.rs @@ -25,7 +25,7 @@ use libp2p_core::upgrade::{self, DeniedUpgrade}; use libp2p_core::{ConnectedPoint, PeerId}; use libp2p_swarm::dummy; use libp2p_swarm::handler::SendWrapper; -use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler}; +use libp2p_swarm::ConnectionHandler; pub mod direct; pub mod relayed; @@ -43,39 +43,40 @@ pub enum Role { Listener, } -impl IntoConnectionHandler for Prototype { - type Handler = Either>; - - fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - match self { - Self::UnknownConnection => { - if endpoint.is_relayed() { - Either::Left(relayed::Handler::new(endpoint.clone())) - } else { - Either::Right(Either::Right(dummy::ConnectionHandler)) - } - } - Self::DirectConnection { - relayed_connection_id, - .. - } => { - assert!( - !endpoint.is_relayed(), - "`Prototype::DirectConnection` is never created for relayed connection." - ); - Either::Right(Either::Left(direct::Handler::new(relayed_connection_id))) - } - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - match self { - Prototype::UnknownConnection => upgrade::EitherUpgrade::A(SendWrapper( - upgrade::EitherUpgrade::A(protocol::inbound::Upgrade {}), - )), - Prototype::DirectConnection { .. } => { - upgrade::EitherUpgrade::A(SendWrapper(upgrade::EitherUpgrade::B(DeniedUpgrade))) - } - } - } -} +// TODO +// impl IntoConnectionHandler for Prototype { +// type Handler = Either>; +// +// fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { +// match self { +// Self::UnknownConnection => { +// if endpoint.is_relayed() { +// Either::Left(relayed::Handler::new(endpoint.clone())) +// } else { +// Either::Right(Either::Right(dummy::ConnectionHandler)) +// } +// } +// Self::DirectConnection { +// relayed_connection_id, +// .. +// } => { +// assert!( +// !endpoint.is_relayed(), +// "`Prototype::DirectConnection` is never created for relayed connection." +// ); +// Either::Right(Either::Left(direct::Handler::new(relayed_connection_id))) +// } +// } +// } +// +// fn inbound_protocol(&self) -> ::InboundProtocol { +// match self { +// Prototype::UnknownConnection => upgrade::EitherUpgrade::A(SendWrapper( +// upgrade::EitherUpgrade::A(protocol::inbound::Upgrade {}), +// )), +// Prototype::DirectConnection { .. } => { +// upgrade::EitherUpgrade::A(SendWrapper(upgrade::EitherUpgrade::B(DeniedUpgrade))) +// } +// } +// } +// } diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 08eb1946bcb..622aee823c3 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -105,7 +105,6 @@ impl Floodsub { if self.target_peers.insert(peer_id) { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - dial_payload: (), }); } } @@ -276,9 +275,8 @@ impl Floodsub { impl NetworkBehaviour for Floodsub { type ConnectionHandler = OneShotHandler; type OutEvent = FloodsubEvent; - type DialPayload = (); - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { Default::default() } @@ -337,7 +335,6 @@ impl NetworkBehaviour for Floodsub { if self.target_peers.contains(id) { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*id).build(), - dial_payload: (), }); } } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index f5bf175c500..d96d3696be8 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -41,8 +41,7 @@ use libp2p_core::{ multiaddr::Protocol::Ip6, ConnectedPoint, Multiaddr, PeerId, }; use libp2p_swarm::{ - dial_opts::DialOpts, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; use wasm_timer::Instant; @@ -1141,7 +1140,6 @@ where debug!("Connecting to explicit peer {:?}", peer_id); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer_id).build(), - dial_payload: (), }); } } @@ -1638,7 +1636,6 @@ where self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - dial_payload: (), }); } } @@ -3042,9 +3039,8 @@ where { type ConnectionHandler = GossipsubHandler; type OutEvent = GossipsubEvent; - type DialPayload = (); - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), @@ -3148,7 +3144,7 @@ where peer_id: &PeerId, connection_id: &ConnectionId, endpoint: &ConnectedPoint, - _: ::Handler, + _: Self::ConnectionHandler, remaining_established: usize, ) { // Remove IP from peer scoring system diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 6124acde71b..ce05104fe23 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -233,7 +233,7 @@ where // peer_connections.connections should never be empty. let mut active_connections = peer_connections.connections.len(); for conn_id in peer_connections.connections.clone() { - let handler = gs.new_handler(); + let handler = gs.new_handler(todo!(), todo!()); active_connections = active_connections.checked_sub(1).unwrap(); gs.inject_connection_closed( peer_id, @@ -1356,10 +1356,7 @@ fn test_explicit_peer_gets_connected() { .events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { - opts, - initial_in_event: _, - } => opts.get_peer_id() == Some(peer), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id() == Some(peer), _ => false, }) .count(); @@ -1400,10 +1397,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { - opts, - initial_in_event: _, - } => opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id() == Some(*peer), _ => false, }) .count(), @@ -1418,10 +1412,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { - opts, - initial_in_event: _, - } => opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id() == Some(*peer), _ => false, }) .count() @@ -1801,10 +1792,7 @@ fn test_connect_to_px_peers_on_handle_prune() { .events .iter() .filter_map(|e| match e { - NetworkBehaviourAction::Dial { - opts, - initial_in_event: _, - } => opts.get_peer_id(), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id(), _ => None, }) .collect(); diff --git a/protocols/gossipsub/src/config.rs b/protocols/gossipsub/src/config.rs index 34956fe614c..dfc16624c52 100644 --- a/protocols/gossipsub/src/config.rs +++ b/protocols/gossipsub/src/config.rs @@ -995,7 +995,7 @@ mod test { let mut gossipsub: Gossipsub = Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - let handler = gossipsub.new_handler(); + let handler = gossipsub.new_handler(todo!(), todo!()); let (protocol_config, _) = handler.listen_protocol().into_upgrade(); let protocol_ids = protocol_config.protocol_info(); @@ -1023,7 +1023,7 @@ mod test { let mut gossipsub: Gossipsub = Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - let handler = gossipsub.new_handler(); + let handler = gossipsub.new_handler(todo!(), todo!()); let (protocol_config, _) = handler.listen_protocol().into_upgrade(); let protocol_ids = protocol_config.protocol_info(); diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index af300b21595..439a6a45854 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -18,7 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::handler::{self, Proto, Push}; +use crate::handler::{self, Handler, Push}; use crate::protocol::{Info, ReplySubstream, UpgradeError}; use futures::prelude::*; use libp2p_core::{ @@ -28,8 +28,7 @@ use libp2p_core::{ use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, - IntoConnectionHandler, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; use lru::LruCache; use std::num::NonZeroUsize; @@ -201,7 +200,6 @@ impl Behaviour { if self.pending_push.insert(p) && !self.connected.contains_key(&p) { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(p).build(), - dial_payload: (), }); } } @@ -209,11 +207,11 @@ impl Behaviour { } impl NetworkBehaviour for Behaviour { - type ConnectionHandler = Proto; + type ConnectionHandler = Handler; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - Proto::new(self.config.initial_delay, self.config.interval) + fn new_handler(&mut self, peer: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { + Handler::new(self.config.initial_delay, self.config.interval, *peer) } fn inject_connection_established( @@ -249,7 +247,7 @@ impl NetworkBehaviour for Behaviour { peer_id: &PeerId, conn: &ConnectionId, _: &ConnectedPoint, - _: ::Handler, + _: Self::ConnectionHandler, remaining_established: usize, ) { if remaining_established == 0 { @@ -260,20 +258,15 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_dial_failure( - &mut self, - peer_id: Option, - _: Option, - error: &DialError, - ) { - if let Some(peer_id) = peer_id { + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + if let Some(peer_id) = _peer_id { if !self.connected.contains_key(&peer_id) { self.pending_push.remove(&peer_id); } } - if let Some(entry) = peer_id.and_then(|id| self.discovered_peers.get_mut(&id)) { - if let DialError::Transport(errors) = error { + if let Some(entry) = _peer_id.and_then(|id| self.discovered_peers.get_mut(&id)) { + if let DialError::Transport(errors) = _error { for (addr, _error) in errors { entry.remove(addr); } @@ -297,7 +290,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer_id: PeerId, connection: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, + event: ::OutEvent, ) { match event { handler::Event::Identified(mut info) => { @@ -453,8 +446,6 @@ impl NetworkBehaviour for Behaviour { fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { self.discovered_peers.get(peer) } - - type DialPayload = (); } /// Event emitted by the `Identify` behaviour. diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index 987b56496f5..d47d9c55f02 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -26,41 +26,15 @@ use futures::prelude::*; use futures_timer::Delay; use libp2p_core::either::{EitherError, EitherOutput}; use libp2p_core::upgrade::{EitherUpgrade, InboundUpgrade, OutboundUpgrade, SelectUpgrade}; -use libp2p_core::{ConnectedPoint, PeerId}; +use libp2p_core::PeerId; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, NegotiatedSubstream, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use log::warn; use smallvec::SmallVec; use std::{io, pin::Pin, task::Context, task::Poll, time::Duration}; -pub struct Proto { - initial_delay: Duration, - interval: Duration, -} - -impl Proto { - pub fn new(initial_delay: Duration, interval: Duration) -> Self { - Proto { - initial_delay, - interval, - } - } -} - -impl IntoConnectionHandler for Proto { - type Handler = Handler; - - fn into_handler(self, remote_peer_id: &PeerId, _endpoint: &ConnectedPoint) -> Self::Handler { - Handler::new(self.initial_delay, self.interval, *remote_peer_id) - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - SelectUpgrade::new(Protocol, PushProtocol::inbound()) - } -} - /// Protocol handler for sending and receiving identification requests. /// /// Outbound requests are sent periodically. The handler performs expects diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 459eb451af6..e44afa6151e 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -24,7 +24,7 @@ mod test; use crate::addresses::Addresses; use crate::handler::{ - KademliaHandlerConfig, KademliaHandlerEvent, KademliaHandlerIn, KademliaHandlerProto, + KademliaHandler, KademliaHandlerConfig, KademliaHandlerEvent, KademliaHandlerIn, KademliaRequestId, }; use crate::jobs::*; @@ -570,7 +570,6 @@ where kbucket::InsertResult::Pending { disconnected } => { self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()).build(), - dial_payload: (), }); RoutingUpdate::Pending } @@ -1164,7 +1163,6 @@ where self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()) .build(), - dial_payload: (), }) } } @@ -1782,16 +1780,23 @@ where for<'a> TStore: RecordStore<'a>, TStore: Send + 'static, { - type ConnectionHandler = KademliaHandlerProto; + type ConnectionHandler = KademliaHandler; type OutEvent = KademliaEvent; - type DialPayload = (); - fn new_handler(&mut self) -> Self::ConnectionHandler { - KademliaHandlerProto::new(KademliaHandlerConfig { - protocol_config: self.protocol_config.clone(), - allow_listening: true, - idle_timeout: self.connection_idle_timeout, - }) + fn new_handler( + &mut self, + peer: &PeerId, + connected_point: &ConnectedPoint, + ) -> Self::ConnectionHandler { + KademliaHandler::new( + KademliaHandlerConfig { + protocol_config: self.protocol_config.clone(), + allow_listening: true, + idle_timeout: self.connection_idle_timeout, + }, + connected_point.clone(), + *peer, + ) } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { @@ -1913,19 +1918,14 @@ where } } - fn inject_dial_failure( - &mut self, - peer_id: Option, - _: Option, - error: &DialError, - ) { - let peer_id = match peer_id { + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + let peer_id = match _peer_id { Some(id) => id, // Not interested in dial failures to unknown peers. None => return, }; - match error { + match _error { DialError::Banned | DialError::ConnectionLimit(_) | DialError::LocalPeerId @@ -1935,7 +1935,7 @@ where | DialError::ConnectionIo(_) | DialError::Transport(_) | DialError::NoAddresses => { - if let DialError::Transport(addresses) = error { + if let DialError::Transport(addresses) = _error { for (addr, _) in addresses { self.address_failed(peer_id, addr) } @@ -1962,7 +1962,7 @@ where id: &PeerId, _: &ConnectionId, _: &ConnectedPoint, - _: ::Handler, + _: Self::ConnectionHandler, remaining_established: usize, ) { if remaining_established == 0 { @@ -2344,7 +2344,6 @@ where query.inner.pending_rpcs.push((peer_id, event)); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - dial_payload: (), }); } } diff --git a/protocols/kad/src/handler.rs b/protocols/kad/src/handler.rs index a2efb9063fe..f2331b05973 100644 --- a/protocols/kad/src/handler.rs +++ b/protocols/kad/src/handler.rs @@ -32,8 +32,8 @@ use libp2p_core::{ ConnectedPoint, PeerId, }; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, NegotiatedSubstream, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use log::trace; use std::task::Waker; @@ -43,38 +43,23 @@ use std::{ const MAX_NUM_INBOUND_SUBSTREAMS: usize = 32; -/// A prototype from which [`KademliaHandler`]s can be constructed. -pub struct KademliaHandlerProto { - config: KademliaHandlerConfig, - _type: PhantomData, -} - -impl KademliaHandlerProto { - pub fn new(config: KademliaHandlerConfig) -> Self { - KademliaHandlerProto { - config, - _type: PhantomData, - } - } -} - -impl IntoConnectionHandler - for KademliaHandlerProto -{ - type Handler = KademliaHandler; - - fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - KademliaHandler::new(self.config, endpoint.clone(), *remote_peer_id) - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - if self.config.allow_listening { - upgrade::EitherUpgrade::A(self.config.protocol_config.clone()) - } else { - upgrade::EitherUpgrade::B(upgrade::DeniedUpgrade) - } - } -} +// impl IntoConnectionHandler +// for KademliaHandlerProto +// { +// type Handler = KademliaHandler; +// +// fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { +// KademliaHandler::new(self.config, endpoint.clone(), *remote_peer_id) +// } +// +// fn inbound_protocol(&self) -> ::InboundProtocol { +// if self.config.allow_listening { +// upgrade::EitherUpgrade::A(self.config.protocol_config.clone()) +// } else { +// upgrade::EitherUpgrade::B(upgrade::DeniedUpgrade) +// } +// } +// } /// Protocol handler that manages substreams for the Kademlia protocol /// on a single connection with a peer. diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index dd783016183..b7fe99179b6 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -28,7 +28,7 @@ use crate::MdnsConfig; use futures::Stream; use if_watch::{IfEvent, IfWatcher}; use libp2p_core::transport::ListenerId; -use libp2p_core::{Multiaddr, PeerId}; +use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::{ dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -121,9 +121,8 @@ where { type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = MdnsEvent; - type DialPayload = (); - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { dummy::ConnectionHandler } diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 1207b1c3e6b..5d9ec3d5da3 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -47,7 +47,7 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; -use libp2p_core::{connection::ConnectionId, PeerId}; +use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use std::{ @@ -117,19 +117,11 @@ impl Default for Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; type OutEvent = Event; - type DialPayload = (); - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { Handler::new(self.config.clone()) } - fn new_outbound_handler( - &mut self, - dial_payload: Option, - ) -> Self::ConnectionHandler { - todo!() - } - fn inject_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) { self.events.push_front(Event { peer, result }) } diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 2078eaab515..6c42dccce11 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -23,6 +23,7 @@ mod handler; pub mod transport; +use crate::v2::client::handler::Handler; use crate::v2::protocol::{self, inbound_stop, outbound_hop}; use bytes::Bytes; use either::Either; @@ -117,12 +118,41 @@ impl Client { } impl NetworkBehaviour for Client { - type ConnectionHandler = handler::Prototype; + type ConnectionHandler = Either; type OutEvent = Event; - type DialPayload = handler::In; - fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::new(self.local_peer_id, None) + fn new_handler( + &mut self, + peer: &PeerId, + connected_point: &ConnectedPoint, + ) -> Self::ConnectionHandler { + if connected_point.is_relayed() { + // if let Some(event) = self.initial_in { + // log::debug!( + // "Established relayed instead of direct connection to {:?}, \ + // dropping initial in event {:?}.", + // remote_peer_id, event + // ); + // } + + // TODO: Check local state for initial in? + + // Deny all substreams on relayed connection. + Either::Right(dummy::ConnectionHandler) + } else { + let mut handler = Handler::new( + self.local_peer_id, + *peer, + connected_point.get_remote_address().clone(), + ); + + // if let Some(event) = self.initial_in { + // handler.inject_event(event) + // } + // TODO: Grab event from local state + + Either::Left(handler) + } } fn inject_connection_established( @@ -233,13 +263,8 @@ impl NetworkBehaviour for Client { &mut self, cx: &mut Context<'_>, _poll_parameters: &mut impl PollParameters, - ) -> Poll< - NetworkBehaviourAction< - Self::OutEvent, - THandlerInEvent, - Self::DialPayload, - >, - > { + ) -> Poll>> + { if let Some(event) = self.queued_actions.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); } @@ -265,7 +290,7 @@ impl NetworkBehaviour for Client { .addresses(vec![relay_addr]) .extend_addresses_through_behaviour() .build(), - dial_payload: handler::In::Reserve { to_listener }, + // dial_payload: handler::In::Reserve { to_listener }, TODO }, } } @@ -294,10 +319,10 @@ impl NetworkBehaviour for Client { .addresses(vec![relay_addr]) .extend_addresses_through_behaviour() .build(), - dial_payload: handler::In::EstablishCircuit { - send_back, - dst_peer_id, - }, + // dial_payload: handler::In::EstablishCircuit { + // send_back, + // dst_peer_id, + // }, }, } } diff --git a/protocols/relay/src/v2/client/handler.rs b/protocols/relay/src/v2/client/handler.rs index a346a4eaeb3..8d5093cfa28 100644 --- a/protocols/relay/src/v2/client/handler.rs +++ b/protocols/relay/src/v2/client/handler.rs @@ -33,8 +33,8 @@ use libp2p_core::multiaddr::Protocol; use libp2p_core::{upgrade, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::handler::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, - IntoConnectionHandler, KeepAlive, NegotiatedSubstream, SubstreamProtocol, + dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use log::debug; use std::collections::{HashMap, VecDeque}; @@ -122,47 +122,48 @@ impl Prototype { } } -impl IntoConnectionHandler for Prototype { - type Handler = Either; - - fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - if endpoint.is_relayed() { - if let Some(event) = self.initial_in { - debug!( - "Established relayed instead of direct connection to {:?}, \ - dropping initial in event {:?}.", - remote_peer_id, event - ); - } - - // Deny all substreams on relayed connection. - Either::Right(dummy::ConnectionHandler) - } else { - let mut handler = Handler { - remote_peer_id: *remote_peer_id, - remote_addr: endpoint.get_remote_address().clone(), - local_peer_id: self.local_peer_id, - queued_events: Default::default(), - pending_error: Default::default(), - reservation: Reservation::None, - alive_lend_out_substreams: Default::default(), - circuit_deny_futs: Default::default(), - send_error_futs: Default::default(), - keep_alive: KeepAlive::Yes, - }; - - if let Some(event) = self.initial_in { - handler.inject_event(event) - } - - Either::Left(handler) - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - upgrade::EitherUpgrade::A(SendWrapper(inbound_stop::Upgrade {})) - } -} +// TODO +// impl IntoConnectionHandler for Prototype { +// type Handler = Either; +// +// fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { +// if endpoint.is_relayed() { +// if let Some(event) = self.initial_in { +// debug!( +// "Established relayed instead of direct connection to {:?}, \ +// dropping initial in event {:?}.", +// remote_peer_id, event +// ); +// } +// +// // Deny all substreams on relayed connection. +// Either::Right(dummy::ConnectionHandler) +// } else { +// let mut handler = Handler { +// remote_peer_id: *remote_peer_id, +// remote_addr: endpoint.get_remote_address().clone(), +// local_peer_id: self.local_peer_id, +// queued_events: Default::default(), +// pending_error: Default::default(), +// reservation: Reservation::None, +// alive_lend_out_substreams: Default::default(), +// circuit_deny_futs: Default::default(), +// send_error_futs: Default::default(), +// keep_alive: KeepAlive::Yes, +// }; +// +// if let Some(event) = self.initial_in { +// handler.inject_event(event) +// } +// +// Either::Left(handler) +// } +// } +// +// fn inbound_protocol(&self) -> ::InboundProtocol { +// upgrade::EitherUpgrade::A(SendWrapper(inbound_stop::Upgrade {})) +// } +// } pub struct Handler { local_peer_id: PeerId, @@ -209,6 +210,23 @@ pub struct Handler { send_error_futs: FuturesUnordered>, } +impl Handler { + pub fn new(local_peer_id: PeerId, remote_peer_id: PeerId, remote_addr: Multiaddr) -> Self { + Self { + local_peer_id, + remote_peer_id, + remote_addr, + pending_error: Default::default(), + keep_alive: KeepAlive::Yes, + queued_events: Default::default(), + reservation: Reservation::None, + alive_lend_out_substreams: Default::default(), + circuit_deny_futs: Default::default(), + send_error_futs: Default::default(), + } + } +} + impl ConnectionHandler for Handler { type InEvent = In; type OutEvent = Event; diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index c073d3cf7b1..cd584d71912 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -25,6 +25,7 @@ pub mod rate_limiter; use crate::v2::message_proto; use crate::v2::protocol::inbound_hop; +use crate::v2::relay::handler::Handler; use either::Either; use instant::Instant; use libp2p_core::connection::{ConnectedPoint, ConnectionId}; @@ -216,17 +217,22 @@ impl Relay { } impl NetworkBehaviour for Relay { - type ConnectionHandler = handler::Prototype; + type ConnectionHandler = Either; type OutEvent = Event; - type DialPayload = (); - - fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype { - config: handler::Config { - reservation_duration: self.config.reservation_duration, - max_circuit_duration: self.config.max_circuit_duration, - max_circuit_bytes: self.config.max_circuit_bytes, - }, + + fn new_handler(&mut self, _: &PeerId, endpoint: &ConnectedPoint) -> Self::ConnectionHandler { + if endpoint.is_relayed() { + // Deny all substreams on relayed connection. + Either::Right(dummy::ConnectionHandler) + } else { + Either::Left(Handler::new( + endpoint.clone(), + handler::Config { + reservation_duration: self.config.reservation_duration, + max_circuit_duration: self.config.max_circuit_duration, + max_circuit_bytes: self.config.max_circuit_bytes, + }, + )) } } @@ -726,7 +732,7 @@ impl Add for CircuitId { /// before being returned in [`Relay::poll`]. #[allow(clippy::large_enum_variant)] enum Action { - Done(NetworkBehaviourAction>), + Done(NetworkBehaviourAction>>), AcceptReservationPrototype { inbound_reservation_req: inbound_hop::ReservationReq, handler: NotifyHandler, @@ -734,8 +740,15 @@ enum Action { }, } -impl From>> for Action { - fn from(action: NetworkBehaviourAction>) -> Self { +impl From>>> + for Action +{ + fn from( + action: NetworkBehaviourAction< + Event, + THandlerInEvent>, + >, + ) -> Self { Self::Done(action) } } @@ -744,7 +757,8 @@ impl Action { fn build( self, poll_parameters: &mut impl PollParameters, - ) -> NetworkBehaviourAction> { + ) -> NetworkBehaviourAction>> + { match self { Action::Done(action) => action, Action::AcceptReservationPrototype { diff --git a/protocols/relay/src/v2/relay/handler.rs b/protocols/relay/src/v2/relay/handler.rs index 1c6987692fa..6a04729c168 100644 --- a/protocols/relay/src/v2/relay/handler.rs +++ b/protocols/relay/src/v2/relay/handler.rs @@ -36,8 +36,8 @@ use libp2p_core::{upgrade, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::handler::SendWrapper; use libp2p_swarm::handler::{InboundUpgradeSend, OutboundUpgradeSend}; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, - IntoConnectionHandler, KeepAlive, NegotiatedSubstream, SubstreamProtocol, + dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use std::collections::VecDeque; use std::fmt; @@ -341,38 +341,39 @@ pub struct Prototype { pub config: Config, } -impl IntoConnectionHandler for Prototype { - type Handler = Either; - - fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - if endpoint.is_relayed() { - // Deny all substreams on relayed connection. - Either::Right(dummy::ConnectionHandler) - } else { - Either::Left(Handler { - endpoint: endpoint.clone(), - config: self.config, - queued_events: Default::default(), - pending_error: Default::default(), - reservation_request_future: Default::default(), - circuit_accept_futures: Default::default(), - circuit_deny_futures: Default::default(), - alive_lend_out_substreams: Default::default(), - circuits: Default::default(), - active_reservation: Default::default(), - keep_alive: KeepAlive::Yes, - }) - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - upgrade::EitherUpgrade::A(SendWrapper(inbound_hop::Upgrade { - reservation_duration: self.config.reservation_duration, - max_circuit_duration: self.config.max_circuit_duration, - max_circuit_bytes: self.config.max_circuit_bytes, - })) - } -} +// TODO +// impl IntoConnectionHandler for Prototype { +// type Handler = Either; +// +// fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { +// if endpoint.is_relayed() { +// // Deny all substreams on relayed connection. +// Either::Right(dummy::ConnectionHandler) +// } else { +// Either::Left(Handler { +// endpoint: endpoint.clone(), +// config: self.config, +// queued_events: Default::default(), +// pending_error: Default::default(), +// reservation_request_future: Default::default(), +// circuit_accept_futures: Default::default(), +// circuit_deny_futures: Default::default(), +// alive_lend_out_substreams: Default::default(), +// circuits: Default::default(), +// active_reservation: Default::default(), +// keep_alive: KeepAlive::Yes, +// }) +// } +// } +// +// fn inbound_protocol(&self) -> ::InboundProtocol { +// upgrade::EitherUpgrade::A(SendWrapper(inbound_hop::Upgrade { +// reservation_duration: self.config.reservation_duration, +// max_circuit_duration: self.config.max_circuit_duration, +// max_circuit_bytes: self.config.max_circuit_bytes, +// })) +// } +// } /// [`ConnectionHandler`] that manages substreams for a relay on a single /// connection with a peer. @@ -429,6 +430,24 @@ pub struct Handler { circuits: Futures<(CircuitId, PeerId, Result<(), std::io::Error>)>, } +impl Handler { + pub fn new(endpoint: ConnectedPoint, config: Config) -> Self { + Self { + endpoint, + config, + queued_events: Default::default(), + pending_error: Default::default(), + keep_alive: KeepAlive::Yes, + reservation_request_future: Default::default(), + active_reservation: Default::default(), + circuit_accept_futures: Default::default(), + circuit_deny_futures: Default::default(), + alive_lend_out_substreams: Default::default(), + circuits: Default::default(), + } + } +} + enum ReservationRequestFuture { Accepting(BoxFuture<'static, Result<(), inbound_hop::UpgradeError>>), Denying(BoxFuture<'static, Result<(), inbound_hop::UpgradeError>>), diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 6d704a31394..725ad1a6a70 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -31,7 +31,7 @@ use instant::Duration; use libp2p_core::connection::ConnectionId; use libp2p_core::identity::error::SigningError; use libp2p_core::identity::Keypair; -use libp2p_core::{Multiaddr, PeerId, PeerRecord}; +use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, PeerRecord}; use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -164,9 +164,8 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; type OutEvent = Event; - type DialPayload = (); - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { let initial_keep_alive = Duration::from_secs(30); SubstreamConnectionHandler::new_outbound_only(initial_keep_alive) diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 41b16391ec1..aea6b87bb48 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -28,7 +28,7 @@ use futures::ready; use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use libp2p_core::connection::ConnectionId; -use libp2p_core::PeerId; +use libp2p_core::{ConnectedPoint, PeerId}; use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -110,9 +110,8 @@ pub enum Event { impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; type OutEvent = Event; - type DialPayload = (); - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { let initial_keep_alive = Duration::from_secs(30); SubstreamConnectionHandler::new_inbound_only(initial_keep_alive) diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index d690aeeb34c..49aafca7610 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -69,8 +69,8 @@ use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEve use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ - dial_opts::DialOpts, DialError, IntoConnectionHandler, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, + dial_opts::DialOpts, DialError, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, + PollParameters, }; use smallvec::SmallVec; use std::{ @@ -387,7 +387,6 @@ where if let Some(request) = self.try_send_request(peer, request) { self.pending_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer).build(), - dial_payload: (), }); self.pending_outbound_requests .entry(*peer) @@ -569,7 +568,7 @@ where type ConnectionHandler = RequestResponseHandler; type OutEvent = RequestResponseEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { RequestResponseHandler::new( self.inbound_protocols.clone(), self.codec.clone(), @@ -645,7 +644,7 @@ where peer_id: &PeerId, conn: &ConnectionId, _: &ConnectedPoint, - _: ::Handler, + _: Self::ConnectionHandler, remaining_established: usize, ) { let connections = self @@ -687,13 +686,8 @@ where } } - fn inject_dial_failure( - &mut self, - peer: Option, - _: Option, - _: &DialError, - ) { - if let Some(peer) = peer { + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + if let Some(peer) = _peer_id { // If there are pending outgoing requests when a dial failure occurs, // it is implied that we are not connected to the peer, since pending // outgoing requests are drained when a connection is established and @@ -881,8 +875,6 @@ where Poll::Pending } - - type DialPayload = (); } /// Internal threshold for when to shrink the capacity diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index a23028579ee..15793f6bd0e 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -51,9 +51,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let trait_to_impl = quote! {::libp2p::swarm::NetworkBehaviour}; let either_ident = quote! {::libp2p::core::either::EitherOutput}; let network_behaviour_action = quote! {::libp2p::swarm::NetworkBehaviourAction}; - let into_connection_handler = quote! {::libp2p::swarm::IntoConnectionHandler}; let connection_handler = quote! {::libp2p::swarm::ConnectionHandler}; - let into_proto_select_ident = quote! {::libp2p::swarm::IntoConnectionHandlerSelect}; + let proto_select_ident = quote! {::libp2p::swarm::ConnectionHandlerSelect}; let peer_id = quote! {::libp2p::core::PeerId}; let connection_id = quote! {::libp2p::core::connection::ConnectionId}; let dial_errors = quote! {Option<&Vec<::libp2p::core::Multiaddr>>}; @@ -236,60 +235,23 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .fields .iter() .enumerate() - // The outmost handler belongs to the last behaviour. - .rev() - .enumerate() - .map(move |(enum_n, (field_n, field))| { - let handler = if field_n == 0 { - // Given that the iterator is reversed, this is the innermost handler only. - quote! { let handler = handlers } - } else { - quote! { - let (handlers, handler) = handlers.into_inner() - } - }; - - let inject = match field.ident { - Some(ref i) => { - quote! { self.#i.inject_dial_failure(peer_id, handler, error) } - } - None => { - quote! { self.#enum_n.inject_dial_failure(peer_id, handler, error) } - } - }; - - quote! { - #handler; - #inject; - } + .map(move |(field_n, field)| match field.ident { + Some(ref i) => quote! { self.#i.inject_dial_failure(peer_id, error); }, + None => quote! { self.#field_n.inject_dial_failure(peer_id, error); }, }) }; // Build the list of statements to put in the body of `inject_listen_failure()`. let inject_listen_failure_stmts = { - data_struct.fields + data_struct + .fields .iter() .enumerate() - .rev() - .enumerate() - .map(move |(enum_n, (field_n, field))| { - let handler = if field_n == 0 { - quote! { let handler = handlers } - } else { - quote! { - let (handlers, handler) = handlers.into_inner() - } - }; - - let inject = match field.ident { - Some(ref i) => quote! { self.#i.inject_listen_failure(local_addr, send_back_addr, handler) }, - None => quote! { self.#enum_n.inject_listen_failure(local_addr, send_back_addr, handler) }, - }; - - quote! { - #handler; - #inject; + .map(move |(field_n, field)| match field.ident { + Some(ref i) => { + quote! { self.#i.inject_listen_failure(local_addr, send_back_addr); } } + None => quote! { self.#field_n.inject_listen_failure(local_addr, send_back_addr); }, }) }; @@ -405,7 +367,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let ty = &field.ty; let field_info = quote! { <#ty as #trait_to_impl>::ConnectionHandler }; match ph_ty { - Some(ev) => ph_ty = Some(quote! { #into_proto_select_ident<#ev, #field_info> }), + Some(ev) => ph_ty = Some(quote! { #proto_select_ident<#ev, #field_info> }), ref mut ev @ None => *ev = Some(field_info), } } @@ -425,13 +387,11 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }; let builder = quote! { - #field_name.new_handler() + #field_name.new_handler(peer, connected_point) }; match out_handler { - Some(h) => { - out_handler = Some(quote! { #into_connection_handler::select(#h, #builder) }) - } + Some(h) => out_handler = Some(quote! { #connection_handler::select(#h, #builder) }), ref mut h @ None => *h = Some(builder), } } @@ -457,38 +417,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { wrapped_event = quote!{ #either_ident::First(#wrapped_event) }; } - // `Dial` provides a handler of the specific behaviour triggering the - // event. Though in order for the final handler to be able to handle - // protocols of all behaviours, the provided handler needs to be - // combined with handlers of all other behaviours. - let provided_handler_and_new_handlers = { - let mut out_handler = None; - - for (f_n, f) in data_struct.fields.iter().enumerate() { - let f_name = match f.ident { - Some(ref i) => quote! { self.#i }, - None => quote! { self.#f_n }, - }; - - let builder = if field_n == f_n { - // The behaviour that triggered the event. Thus, instead of - // creating a new handler, use the provided handler. - quote! { provided_handler } - } else { - quote! { #f_name.new_handler() } - }; - - match out_handler { - Some(h) => { - out_handler = Some(quote! { #into_connection_handler::select(#h, #builder) }) - } - ref mut h @ None => *h = Some(builder), - } - } - - out_handler.unwrap_or(quote! {()}) // TODO: See test `empty`. - }; - let generate_event_match_arm = { // If the `NetworkBehaviour`'s `OutEvent` is generated by the derive macro, wrap the sub // `NetworkBehaviour` `OutEvent` in the variant of the generated `OutEvent`. If the @@ -516,8 +444,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { loop { match #trait_to_impl::poll(&mut self.#field, cx, poll_params) { #generate_event_match_arm - 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::Dial { opts }) => { + return std::task::Poll::Ready(#network_behaviour_action::Dial { opts }); } std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { peer_id, handler, event }) => { return std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { @@ -554,8 +482,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { type ConnectionHandler = #connection_handler_ty; type OutEvent = #out_event_reference; - fn new_handler(&mut self) -> Self::ConnectionHandler { - use #into_connection_handler; + fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Self::ConnectionHandler { + use #connection_handler; #new_handler } @@ -573,15 +501,15 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #(#inject_address_change_stmts);* } - fn inject_connection_closed(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, endpoint: &#connected_point, handlers: ::Handler, remaining_established: usize) { + fn inject_connection_closed(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, endpoint: &#connected_point, handlers: Self::ConnectionHandler, remaining_established: usize) { #(#inject_connection_closed_stmts);* } - fn inject_dial_failure(&mut self, peer_id: Option<#peer_id>, handlers: Self::ConnectionHandler, error: &#dial_error) { + fn inject_dial_failure(&mut self, peer_id: Option<#peer_id>, error: &#dial_error) { #(#inject_dial_failure_stmts);* } - fn inject_listen_failure(&mut self, local_addr: &#multiaddr, send_back_addr: &#multiaddr, handlers: Self::ConnectionHandler) { + fn inject_listen_failure(&mut self, local_addr: &#multiaddr, send_back_addr: &#multiaddr) { #(#inject_listen_failure_stmts);* } @@ -617,14 +545,14 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { &mut self, peer_id: #peer_id, connection_id: #connection_id, - event: <::Handler as #connection_handler>::OutEvent + event: ::OutEvent ) { match event { #(#inject_node_event_stmts),* } } - fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action> { + fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action::InEvent>> { use libp2p::futures::prelude::*; #(#poll_stmts)* std::task::Poll::Pending diff --git a/swarm-derive/tests/test.rs b/swarm-derive/tests/test.rs index 850c22cb904..3fe60a648ab 100644 --- a/swarm-derive/tests/test.rs +++ b/swarm-derive/tests/test.rs @@ -19,6 +19,8 @@ // DEALINGS IN THE SOFTWARE. use futures::prelude::*; +use libp2p::core::ConnectedPoint; +use libp2p::swarm::behaviour::THandlerInEvent; use libp2p::swarm::{dummy, NetworkBehaviour, SwarmEvent}; use libp2p::{identify, ping}; use libp2p_swarm_derive::*; @@ -355,9 +357,7 @@ fn generated_out_event_derive_debug() { #[test] fn custom_out_event_no_type_parameters() { use libp2p::core::connection::ConnectionId; - use libp2p::swarm::{ - ConnectionHandler, IntoConnectionHandler, NetworkBehaviourAction, PollParameters, - }; + use libp2p::swarm::{ConnectionHandler, NetworkBehaviourAction, PollParameters}; use libp2p::PeerId; use std::task::Context; use std::task::Poll; @@ -370,7 +370,7 @@ fn custom_out_event_no_type_parameters() { type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = void::Void; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { dummy::ConnectionHandler } @@ -378,7 +378,7 @@ fn custom_out_event_no_type_parameters() { &mut self, _peer: PeerId, _connection: ConnectionId, - message: <::Handler as ConnectionHandler>::OutEvent, + message: ::OutEvent, ) { void::unreachable(message); } diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 29d0cfb97d5..9f3479aa0a2 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -22,7 +22,7 @@ mod either; pub mod toggle; use crate::dial_opts::DialOpts; -use crate::handler::{ConnectionHandler, IntoConnectionHandler}; +use crate::handler::ConnectionHandler; use crate::{AddressRecord, AddressScore, DialError}; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, @@ -30,11 +30,9 @@ use libp2p_core::{ use std::{task::Context, task::Poll}; /// Custom event that can be received by the [`ConnectionHandler`]. -pub type THandlerInEvent = - <::Handler as ConnectionHandler>::InEvent; +pub type THandlerInEvent = ::InEvent; -pub type THandlerOutEvent = - <::Handler as ConnectionHandler>::OutEvent; +pub type THandlerOutEvent = ::OutEvent; /// A [`NetworkBehaviour`] defines the behaviour of the local node on the network. /// @@ -119,13 +117,11 @@ pub type THandlerOutEvent = /// ``` pub trait NetworkBehaviour: 'static { /// Handler for all the protocols the network behaviour supports. - type ConnectionHandler: IntoConnectionHandler; + type ConnectionHandler: ConnectionHandler; /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; - type DialPayload: Send + 'static; - /// Creates a new [`ConnectionHandler`] for a connection with a peer. /// /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] @@ -142,25 +138,11 @@ pub trait NetworkBehaviour: 'static { /// /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and /// connection closing. - #[deprecated(since = "0.41.0", note = "Implement `new_inbound_handler` and `new_outbound_handler` instead.")] - fn new_handler(&mut self) -> Self::ConnectionHandler; - - fn new_inbound_handler(&mut self) -> Self::ConnectionHandler { - self.new_handler() - } - - fn new_outbound_handler( + fn new_handler( &mut self, - dial_payload: Option, - ) -> Self::ConnectionHandler { - if dial_payload.is_some() { - log::warn!( - "Discarding dial_payload. Please stop using the deprecated `new_handler` function." - ) - } - - self.new_handler() - } + peer: &PeerId, + connected_point: &ConnectedPoint, + ) -> Self::ConnectionHandler; /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. @@ -192,7 +174,7 @@ pub trait NetworkBehaviour: 'static { _: &PeerId, _: &ConnectionId, _: &ConnectedPoint, - _: ::Handler, + _: Self::ConnectionHandler, _remaining_established: usize, ) { } @@ -216,17 +198,11 @@ pub trait NetworkBehaviour: 'static { &mut self, peer_id: PeerId, connection: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, + event: ::OutEvent, ); /// Indicates to the behaviour that the dial to a known or unknown node failed. - fn inject_dial_failure( - &mut self, - _peer_id: Option, - _dial_payload: Option, - _error: &DialError, - ) { - } + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) {} /// Indicates to the behaviour that an error happened on an incoming connection during its /// initial handshake. @@ -266,13 +242,7 @@ pub trait NetworkBehaviour: 'static { &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll< - NetworkBehaviourAction< - Self::OutEvent, - THandlerInEvent, - Self::DialPayload, - >, - >; + ) -> Poll>>; } /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. @@ -311,7 +281,7 @@ pub trait PollParameters { // [`NetworkBehaviourAction::map_in`], mapping the handler `InEvent` leaving the // handler itself untouched. #[derive(Debug)] -pub enum NetworkBehaviourAction { +pub enum NetworkBehaviourAction { /// Instructs the `Swarm` to return an event when it is being polled. GenerateEvent(TOutEvent), @@ -412,13 +382,12 @@ pub enum NetworkBehaviourAction { /// # unreachable!(); /// # } /// # - /// fn inject_dial_failure( + /// /// /// /// fn inject_dial_failure( /// &mut self, - /// _: Option, - /// handler: Self::ConnectionHandler, - /// _: &DialError, + /// _peer_id: Option, + /// _error: &DialError, /// ) { - /// // As expected, sending the message failed. But lucky us, we got the handler back, thus + /// /// /// // As expected, sending the message failed. But lucky us, we got the handler back, thus /// // the precious message is not lost and we can return it back to the user. /// let msg = handler.message.unwrap(); /// self.outbox_to_swarm @@ -500,10 +469,7 @@ pub enum NetworkBehaviourAction { /// # #[derive(Debug, PartialEq, Eq)] /// # struct PreciousMessage(String); /// ``` - Dial { - opts: DialOpts, - dial_payload: TDialPayload, - }, + Dial { opts: DialOpts }, /// Instructs the `Swarm` to send an event to the handler dedicated to a /// connection with a peer. @@ -563,17 +529,12 @@ pub enum NetworkBehaviourAction { }, } -impl NetworkBehaviourAction { +impl NetworkBehaviourAction { /// Map the handler event. - pub fn map_in( - self, - f: impl FnOnce(TInEvent) -> E, - ) -> NetworkBehaviourAction { + pub fn map_in(self, f: impl FnOnce(TInEvent) -> E) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, dial_payload } => { - NetworkBehaviourAction::Dial { opts, dial_payload } - } + NetworkBehaviourAction::Dial { opts } => NetworkBehaviourAction::Dial { opts }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -597,19 +558,10 @@ impl NetworkBehaviourAction( - self, - f: impl FnOnce(TOutEvent) -> E, - ) -> NetworkBehaviourAction { + pub fn map_out(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), - NetworkBehaviourAction::Dial { - opts, - dial_payload: initial_in_event, - } => NetworkBehaviourAction::Dial { - opts, - dial_payload: initial_in_event, - }, + NetworkBehaviourAction::Dial { opts } => NetworkBehaviourAction::Dial { opts }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -631,13 +583,6 @@ impl NetworkBehaviourAction( - self, - f: impl FnOnce(TDialPayload) -> E, - ) -> NetworkBehaviourAction { - todo!() - } } /// The options w.r.t. which connection handler to notify of an event. diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 4fcf8aa2523..7c6cf6e0bfc 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -19,7 +19,7 @@ // DEALINGS IN THE SOFTWARE. use crate::behaviour::THandlerInEvent; -use crate::handler::{either::IntoEitherHandler, ConnectionHandler, IntoConnectionHandler}; +use crate::handler::ConnectionHandler; use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use either::Either; use libp2p_core::{ @@ -33,14 +33,17 @@ where L: NetworkBehaviour, R: NetworkBehaviour, { - type ConnectionHandler = IntoEitherHandler; + type ConnectionHandler = Either; type OutEvent = Either; - type DialPayload = Either; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler( + &mut self, + peer: &PeerId, + connected_point: &ConnectedPoint, + ) -> Self::ConnectionHandler { match self { - Either::Left(a) => IntoEitherHandler::Left(a.new_handler()), - Either::Right(b) => IntoEitherHandler::Right(b.new_handler()), + Either::Left(a) => Either::Left(a.new_handler(peer, connected_point)), + Either::Right(b) => Either::Right(b.new_handler(peer, connected_point)), } } @@ -82,7 +85,7 @@ where peer_id: &PeerId, connection: &ConnectionId, endpoint: &ConnectedPoint, - handler: ::Handler, + handler: Self::ConnectionHandler, remaining_established: usize, ) { match (self, handler) { @@ -122,7 +125,7 @@ where &mut self, peer_id: PeerId, connection: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, + event: ::OutEvent, ) { match (self, event) { (Either::Left(behaviour), Either::Left(event)) => { @@ -135,21 +138,10 @@ where } } - fn inject_dial_failure( - &mut self, - peer_id: Option, - dial_payload: Option>, - error: &DialError, - ) { - match (self, dial_payload) { - (Either::Left(behaviour), Some(Either::Left(payload))) => { - behaviour.inject_dial_failure(peer_id, Some(payload), error) - } - (Either::Left(behaviour), None) => behaviour.inject_dial_failure(peer_id, None, error), - (Either::Right(behaviour), Some(Either::Right(payload))) => { - behaviour.inject_dial_failure(peer_id, Some(payload), error) - } - _ => unreachable!(), + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + match self { + Either::Left(behaviour) => behaviour.inject_dial_failure(_peer_id, _error), + Either::Right(behaviour) => behaviour.inject_dial_failure(_peer_id, _error), } } @@ -217,18 +209,15 @@ where NetworkBehaviourAction< Self::OutEvent, Either, THandlerInEvent>, - Either, >, > { let event = match self { Either::Left(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Left) - .map_in(Either::Left) - .map_dial_payload(Either::Left), + .map_in(Either::Left), Either::Right(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Right) - .map_in(Either::Right) - .map_dial_payload(Either::Right), + .map_in(Either::Right), }; Poll::Ready(event) diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 5f246b89029..bc2ecef75f1 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -20,8 +20,8 @@ use crate::behaviour::THandlerInEvent; use crate::handler::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; @@ -69,13 +69,19 @@ impl NetworkBehaviour for Toggle where TBehaviour: NetworkBehaviour, { - type ConnectionHandler = ToggleIntoConnectionHandler; + type ConnectionHandler = ToggleConnectionHandler; type OutEvent = TBehaviour::OutEvent; - type DialPayload = TBehaviour::DialPayload; - fn new_handler(&mut self) -> Self::ConnectionHandler { - ToggleIntoConnectionHandler { - inner: self.inner.as_mut().map(|i| i.new_handler()), + fn new_handler( + &mut self, + peer: &PeerId, + connected_point: &ConnectedPoint, + ) -> Self::ConnectionHandler { + ToggleConnectionHandler { + inner: self + .inner + .as_mut() + .map(|i| i.new_handler(peer, connected_point)), } } @@ -110,7 +116,7 @@ where peer_id: &PeerId, connection: &ConnectionId, endpoint: &ConnectedPoint, - handler: ::Handler, + handler: Self::ConnectionHandler, remaining_established: usize, ) { if let Some(inner) = self.inner.as_mut() { @@ -142,21 +148,16 @@ where &mut self, peer_id: PeerId, connection: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, + event: ::OutEvent, ) { if let Some(inner) = self.inner.as_mut() { inner.inject_event(peer_id, connection, event); } } - fn inject_dial_failure( - &mut self, - peer_id: Option, - dial_payload: Option, - error: &DialError, - ) { + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { if let Some(inner) = self.inner.as_mut() { - inner.inject_dial_failure(peer_id, dial_payload, error) + inner.inject_dial_failure(_peer_id, _error) } } @@ -212,13 +213,8 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll< - NetworkBehaviourAction< - Self::OutEvent, - THandlerInEvent, - Self::DialPayload, - >, - > { + ) -> Poll>> + { if let Some(inner) = self.inner.as_mut() { inner.poll(cx, params) } else { @@ -227,38 +223,6 @@ where } } -/// Implementation of `IntoConnectionHandler` that can be in the disabled state. -pub struct ToggleIntoConnectionHandler { - inner: Option, -} - -impl IntoConnectionHandler for ToggleIntoConnectionHandler -where - TInner: IntoConnectionHandler, -{ - type Handler = ToggleConnectionHandler; - - fn into_handler( - self, - remote_peer_id: &PeerId, - connected_point: &ConnectedPoint, - ) -> Self::Handler { - ToggleConnectionHandler { - inner: self - .inner - .map(|h| h.into_handler(remote_peer_id, connected_point)), - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - if let Some(inner) = self.inner.as_ref() { - EitherUpgrade::A(SendWrapper(inner.inbound_protocol())) - } else { - EitherUpgrade::B(SendWrapper(DeniedUpgrade)) - } - } -} - /// Implementation of [`ConnectionHandler`] that can be in the disabled state. pub struct ToggleConnectionHandler { inner: Option, diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 54c36afca28..8483d8f7c8c 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -27,8 +27,7 @@ use crate::{ PendingInboundConnectionError, PendingOutboundConnectionError, }, transport::{Transport, TransportError}, - ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, - PeerId, + ConnectedPoint, ConnectionHandler, Executor, Multiaddr, PeerId, }; use concurrent_dial::ConcurrentDial; use fnv::FnvHashMap; @@ -56,7 +55,7 @@ mod concurrent_dial; mod task; /// A connection `Pool` manages a set of connections for each peer. -pub struct Pool +pub struct Pool where TTrans: Transport, { @@ -66,16 +65,11 @@ where counters: ConnectionCounters, /// The managed connections of each peer that are currently considered established. - established: FnvHashMap< - PeerId, - FnvHashMap< - ConnectionId, - EstablishedConnection<::InEvent>, - >, - >, + established: + FnvHashMap>>, /// The pending connections that are currently being negotiated. - pending: HashMap>, + pending: HashMap, /// Next available identifier for a new connection / task. next_connection_id: ConnectionId, @@ -112,12 +106,10 @@ where /// Sender distributed to established tasks for reporting events back /// to the pool. - established_connection_events_tx: - mpsc::Sender>, + established_connection_events_tx: mpsc::Sender>, /// Receiver for events reported from established tasks. - established_connection_events_rx: - mpsc::Receiver>, + established_connection_events_rx: mpsc::Receiver>, } #[derive(Debug)] @@ -169,16 +161,15 @@ impl EstablishedConnection { } } -struct PendingConnection { +struct PendingConnection { /// [`PeerId`] of the remote peer. peer_id: Option, - dial_payload: Option, endpoint: PendingPoint, /// When dropped, notifies the task which then knows to terminate. abort_notifier: Option>, } -impl PendingConnection { +impl PendingConnection { fn is_for_same_remote_as(&self, other: PeerId) -> bool { self.peer_id.map_or(false, |peer| peer == other) } @@ -191,9 +182,7 @@ impl PendingConnection { } } -impl fmt::Debug - for Pool -{ +impl fmt::Debug for Pool { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.debug_struct("Pool") .field("counters", &self.counters) @@ -203,7 +192,7 @@ impl fmt::Debu /// Event that can happen on the `Pool`. #[derive(Debug)] -pub enum PoolEvent +pub enum PoolEvent where TTrans: Transport, { @@ -239,10 +228,10 @@ where connected: Connected, /// The error that occurred, if any. If `None`, the connection /// was closed by the local peer. - error: Option::Error>>, + error: Option>, /// The remaining established connections to the same peer. remaining_established_connection_ids: Vec, - handler: THandler::Handler, + handler: THandler, }, /// An outbound connection attempt failed. @@ -251,8 +240,6 @@ where id: ConnectionId, /// The error that occurred. error: PendingOutboundConnectionError, - /// TODO - dial_payload: Option, /// The (expected) peer of the failed connection. peer: Option, }, @@ -288,9 +275,9 @@ where }, } -impl Pool +impl Pool where - THandler: IntoConnectionHandler, + THandler: ConnectionHandler, TTrans: Transport, { /// Creates a new empty `Pool`. @@ -407,9 +394,9 @@ where } } -impl Pool +impl Pool where - THandler: IntoConnectionHandler, + THandler: ConnectionHandler, TTrans: Transport + 'static, TTrans::Output: Send + 'static, TTrans::Error: Send + 'static, @@ -434,16 +421,15 @@ where >, >, peer: Option, - dial_payload: Option, role_override: Endpoint, dial_concurrency_factor_override: Option, - ) -> Result)> + ) -> Result where TTrans: Send, TTrans::Dial: Send + 'static, { if let Err(limit) = self.counters.check_max_pending_outgoing() { - return Err((limit, dial_payload)); + return Err(limit); }; let dial = ConcurrentDial::new( @@ -472,7 +458,6 @@ where connection_id, PendingConnection { peer_id: peer, - dial_payload, endpoint, abort_notifier: Some(abort_notifier), }, @@ -516,7 +501,6 @@ where connection_id, PendingConnection { peer_id: None, - dial_payload: None, endpoint: endpoint.into(), abort_notifier: Some(abort_notifier), }, @@ -527,14 +511,13 @@ where /// Polls the connection pool for events. pub fn poll( &mut self, - mut new_handler_fn: impl FnMut(&ConnectedPoint, Option) -> THandler, + mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> THandler, cx: &mut Context<'_>, - ) -> Poll> + ) -> Poll> where TTrans: Transport, - THandler: IntoConnectionHandler + 'static, - THandler::Handler: ConnectionHandler + Send, - ::OutboundOpenInfo: Send, + THandler: ConnectionHandler + 'static, + ::OutboundOpenInfo: Send, { // Poll for events of established connections. // @@ -614,7 +597,6 @@ where } => { let PendingConnection { peer_id: expected_peer_id, - dial_payload, endpoint, abort_notifier: _, } = self @@ -716,7 +698,6 @@ where id, error: error .map(|t| vec![(endpoint.get_remote_address().clone(), t)]), - dial_payload, peer: expected_peer_id.or(Some(obtained_peer_id)), }) } @@ -751,8 +732,7 @@ where let connection = Connection::new( muxer, - new_handler_fn(&endpoint, dial_payload) - .into_handler(&obtained_peer_id, &endpoint), + new_handler_fn(&obtained_peer_id, &endpoint), self.substream_upgrade_protocol_override, self.max_negotiating_inbound_streams, ); @@ -778,7 +758,6 @@ where task::PendingConnectionEvent::PendingFailed { id, error } => { if let Some(PendingConnection { peer_id, - dial_payload: initial_event, endpoint, abort_notifier: _, }) = self.pending.remove(&id) @@ -790,7 +769,6 @@ where return Poll::Ready(PoolEvent::PendingOutboundConnectionError { id, error, - dial_payload: initial_event, peer: peer_id, }); } diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index c0bb16dfb13..6aaa191aaa1 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -3,8 +3,8 @@ use crate::handler::{InboundUpgradeSend, OutboundUpgradeSend}; use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol}; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; -use libp2p_core::PeerId; use libp2p_core::UpgradeError; +use libp2p_core::{ConnectedPoint, PeerId}; use std::task::{Context, Poll}; use void::Void; @@ -14,9 +14,8 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; - type DialPayload = Void; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { ConnectionHandler } @@ -28,13 +27,8 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll< - NetworkBehaviourAction< - Self::OutEvent, - THandlerInEvent, - Self::DialPayload, - >, - > { + ) -> Poll>> + { Poll::Pending } } diff --git a/swarm/src/handler.rs b/swarm/src/handler.rs index 5c60f2bf24a..00b4d385f1d 100644 --- a/swarm/src/handler.rs +++ b/swarm/src/handler.rs @@ -49,14 +49,14 @@ mod select; pub use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper, UpgradeInfoSend}; use instant::Instant; -use libp2p_core::{upgrade::UpgradeError, ConnectedPoint, Multiaddr, PeerId}; +use libp2p_core::{upgrade::UpgradeError, Multiaddr}; use std::{cmp::Ordering, error, fmt, task::Context, task::Poll, time::Duration}; pub use map_in::MapInEvent; pub use map_out::MapOutEvent; pub use one_shot::{OneShotHandler, OneShotHandlerConfig}; pub use pending::PendingConnectionHandler; -pub use select::{ConnectionHandlerSelect, IntoConnectionHandlerSelect}; +pub use select::ConnectionHandlerSelect; /// A handler for a set of protocols used on a connection with a remote. /// @@ -459,48 +459,6 @@ where } } -/// Prototype for a [`ConnectionHandler`]. -pub trait IntoConnectionHandler: Send + 'static { - /// The protocols handler. - type Handler: ConnectionHandler; - - /// Builds the protocols handler. - /// - /// The `PeerId` is the id of the node the handler is going to handle. - fn into_handler( - self, - remote_peer_id: &PeerId, - connected_point: &ConnectedPoint, - ) -> Self::Handler; - - /// Return the handler's inbound protocol. - fn inbound_protocol(&self) -> ::InboundProtocol; - - /// Builds an implementation of [`IntoConnectionHandler`] that handles both this protocol and the - /// other one together. - fn select(self, other: TProto2) -> IntoConnectionHandlerSelect - where - Self: Sized, - { - IntoConnectionHandlerSelect::new(self, other) - } -} - -impl IntoConnectionHandler for T -where - T: ConnectionHandler, -{ - type Handler = Self; - - fn into_handler(self, _: &PeerId, _: &ConnectedPoint) -> Self { - self - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - self.listen_protocol().into_upgrade().0 - } -} - /// How long the connection should be kept alive. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum KeepAlive { diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index 21d386ec56a..41067011b0c 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -19,8 +19,8 @@ // DEALINGS IN THE SOFTWARE. use crate::handler::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; use either::Either; @@ -29,41 +29,6 @@ use libp2p_core::upgrade::{EitherUpgrade, UpgradeError}; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; use std::task::{Context, Poll}; -pub enum IntoEitherHandler { - Left(L), - Right(R), -} - -/// Implementation of a [`IntoConnectionHandler`] that represents either of two [`IntoConnectionHandler`] -/// implementations. -impl IntoConnectionHandler for IntoEitherHandler -where - L: IntoConnectionHandler, - R: IntoConnectionHandler, -{ - type Handler = Either; - - fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler { - match self { - IntoEitherHandler::Left(into_handler) => Either::Left(into_handler.into_handler(p, c)), - IntoEitherHandler::Right(into_handler) => { - Either::Right(into_handler.into_handler(p, c)) - } - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - match self { - IntoEitherHandler::Left(into_handler) => { - EitherUpgrade::A(SendWrapper(into_handler.inbound_protocol())) - } - IntoEitherHandler::Right(into_handler) => { - EitherUpgrade::B(SendWrapper(into_handler.inbound_protocol())) - } - } - } -} - /// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`] /// implementations. impl ConnectionHandler for Either diff --git a/swarm/src/handler/multi.rs b/swarm/src/handler/multi.rs index 07c1168b132..4cef6ad9483 100644 --- a/swarm/src/handler/multi.rs +++ b/swarm/src/handler/multi.rs @@ -22,8 +22,8 @@ //! indexed by some key. use crate::handler::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend}; use crate::NegotiatedSubstream; @@ -329,72 +329,6 @@ impl IntoIterator for MultiHandler { } } -/// A [`IntoConnectionHandler`] for multiple other `IntoConnectionHandler`s. -#[derive(Clone)] -pub struct IntoMultiHandler { - handlers: HashMap, -} - -impl fmt::Debug for IntoMultiHandler -where - K: fmt::Debug + Eq + Hash, - H: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("IntoMultiHandler") - .field("handlers", &self.handlers) - .finish() - } -} - -impl IntoMultiHandler -where - K: Hash + Eq, - H: IntoConnectionHandler, -{ - /// Create and populate an `IntoMultiHandler` from the given iterator. - /// - /// It is an error for any two protocols handlers to share the same protocol name. - pub fn try_from_iter(iter: I) -> Result - where - I: IntoIterator, - { - let m = IntoMultiHandler { - handlers: HashMap::from_iter(iter), - }; - uniq_proto_names(m.handlers.values().map(|h| h.inbound_protocol()))?; - Ok(m) - } -} - -impl IntoConnectionHandler for IntoMultiHandler -where - K: Debug + Clone + Eq + Hash + Send + 'static, - H: IntoConnectionHandler, -{ - type Handler = MultiHandler; - - fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler { - MultiHandler { - handlers: self - .handlers - .into_iter() - .map(|(k, h)| (k, h.into_handler(p, c))) - .collect(), - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - Upgrade { - upgrades: self - .handlers - .iter() - .map(|(k, h)| (k.clone(), h.inbound_protocol())) - .collect(), - } - } -} - /// Index and protocol name pair used as `UpgradeInfo::Info`. #[derive(Debug, Clone)] pub struct IndexedProtoName(usize, H); diff --git a/swarm/src/handler/select.rs b/swarm/src/handler/select.rs index 70a6f3c26f6..0100a42abf2 100644 --- a/swarm/src/handler/select.rs +++ b/swarm/src/handler/select.rs @@ -19,8 +19,8 @@ // DEALINGS IN THE SOFTWARE. use crate::handler::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; @@ -31,52 +31,6 @@ use libp2p_core::{ }; use std::{cmp, task::Context, task::Poll}; -/// Implementation of `IntoConnectionHandler` that combines two protocols into one. -#[derive(Debug, Clone)] -pub struct IntoConnectionHandlerSelect { - /// The first protocol. - proto1: TProto1, - /// The second protocol. - proto2: TProto2, -} - -impl IntoConnectionHandlerSelect { - /// Builds a `IntoConnectionHandlerSelect`. - pub(crate) fn new(proto1: TProto1, proto2: TProto2) -> Self { - IntoConnectionHandlerSelect { proto1, proto2 } - } - - pub fn into_inner(self) -> (TProto1, TProto2) { - (self.proto1, self.proto2) - } -} - -impl IntoConnectionHandler for IntoConnectionHandlerSelect -where - TProto1: IntoConnectionHandler, - TProto2: IntoConnectionHandler, -{ - type Handler = ConnectionHandlerSelect; - - fn into_handler( - self, - remote_peer_id: &PeerId, - connected_point: &ConnectedPoint, - ) -> Self::Handler { - ConnectionHandlerSelect { - proto1: self.proto1.into_handler(remote_peer_id, connected_point), - proto2: self.proto2.into_handler(remote_peer_id, connected_point), - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - SelectUpgrade::new( - SendWrapper(self.proto1.inbound_protocol()), - SendWrapper(self.proto2.inbound_protocol()), - ) - } -} - /// Implementation of [`ConnectionHandler`] that combines two protocols into one. #[derive(Debug, Clone)] pub struct ConnectionHandlerSelect { diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index 7c2fdee70f6..597cd551603 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -4,11 +4,11 @@ use crate::handler::{ }; use crate::NegotiatedSubstream; use libp2p_core::connection::ConnectionId; -use libp2p_core::PeerId; use libp2p_core::{ upgrade::{DeniedUpgrade, InboundUpgrade, OutboundUpgrade}, Multiaddr, }; +use libp2p_core::{ConnectedPoint, PeerId}; use std::task::{Context, Poll}; use void::Void; @@ -24,9 +24,8 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; - type DialPayload = Void; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { ConnectionHandler } @@ -38,13 +37,8 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll< - NetworkBehaviourAction< - Self::OutEvent, - THandlerInEvent, - Self::DialPayload, - >, - > { + ) -> Poll>> + { Poll::Pending } } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 562ed1be1b7..447891f1a43 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -77,8 +77,7 @@ pub use connection::{ }; pub use handler::{ ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr, - IntoConnectionHandler, IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, - OneShotHandlerConfig, SubstreamProtocol, + KeepAlive, OneShotHandler, OneShotHandlerConfig, SubstreamProtocol, }; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; @@ -126,16 +125,13 @@ type THandler = ::ConnectionHandler; /// Custom event that can be received by the [`ConnectionHandler`] of the /// [`NetworkBehaviour`]. -type THandlerInEvent = - < as IntoConnectionHandler>::Handler as ConnectionHandler>::InEvent; +type THandlerInEvent = as ConnectionHandler>::InEvent; /// Custom event that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -type THandlerOutEvent = - < as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent; +type THandlerOutEvent = as ConnectionHandler>::OutEvent; /// Custom error that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -type THandlerErr = - < as IntoConnectionHandler>::Handler as ConnectionHandler>::Error; +type THandlerErr = as ConnectionHandler>::Error; /// Event generated by the `Swarm`. #[derive(Debug)] @@ -266,11 +262,7 @@ where transport: transport::Boxed<(PeerId, StreamMuxerBox)>, /// The nodes currently active. - pool: Pool< - THandler, - transport::Boxed<(PeerId, StreamMuxerBox)>, - TBehaviour::DialPayload, - >, + pool: Pool, transport::Boxed<(PeerId, StreamMuxerBox)>>, /// The local peer ID. local_peer_id: PeerId, @@ -372,14 +364,8 @@ where /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); /// ``` pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { - self.dial_with_payload(opts.into(), None) - } + let swarm_dial_opts = opts.into(); - fn dial_with_payload( - &mut self, - swarm_dial_opts: DialOpts, - payload: Option, - ) -> Result<(), DialError> { let (peer_id, addresses, dial_concurrency_factor_override, role_override) = match swarm_dial_opts.0 { // Dial a known peer. @@ -405,7 +391,6 @@ where if !condition_matched { self.behaviour.inject_dial_failure( Some(peer_id), - payload, &DialError::DialPeerConditionFalse(condition), ); @@ -415,8 +400,7 @@ where // Check if peer is banned. if self.banned_peers.contains(&peer_id) { let error = DialError::Banned; - self.behaviour - .inject_dial_failure(Some(peer_id), payload, &error); + self.behaviour.inject_dial_failure(Some(peer_id), &error); return Err(error); } @@ -452,8 +436,7 @@ where if addresses.is_empty() { let error = DialError::NoAddresses; - self.behaviour - .inject_dial_failure(Some(peer_id), payload, &error); + self.behaviour.inject_dial_failure(Some(peer_id), &error); return Err(error); }; @@ -528,14 +511,13 @@ where match self.pool.add_outgoing( dials, peer_id, - payload, role_override, dial_concurrency_factor_override, ) { Ok(_connection_id) => Ok(()), - Err((connection_limit, event)) => { + Err(connection_limit) => { let error = DialError::ConnectionLimit(connection_limit); - self.behaviour.inject_dial_failure(peer_id, event, &error); + self.behaviour.inject_dial_failure(peer_id, &error); Err(error) } } @@ -665,11 +647,7 @@ where fn handle_pool_event( &mut self, - event: PoolEvent< - THandler, - transport::Boxed<(PeerId, StreamMuxerBox)>, - TBehaviour::DialPayload, - >, + event: PoolEvent, transport::Boxed<(PeerId, StreamMuxerBox)>>, ) -> Option>> { match event { PoolEvent::ConnectionEstablished { @@ -720,15 +698,10 @@ where }); } } - PoolEvent::PendingOutboundConnectionError { - id: _, - error, - dial_payload: handler, - peer, - } => { + PoolEvent::PendingOutboundConnectionError { id: _, error, peer } => { let error = error.into(); - self.behaviour.inject_dial_failure(peer, handler, &error); + self.behaviour.inject_dial_failure(peer, &error); if let Some(peer) = peer { log::debug!("Connection attempt to {:?} failed with {:?}.", peer, error,); @@ -931,19 +904,15 @@ where fn handle_behaviour_event( &mut self, - event: NetworkBehaviourAction< - TBehaviour::OutEvent, - THandlerInEvent, - TBehaviour::DialPayload, - >, + event: NetworkBehaviourAction>, ) -> Option>> { match event { NetworkBehaviourAction::GenerateEvent(event) => { return Some(SwarmEvent::Behaviour(event)) } - NetworkBehaviourAction::Dial { opts, dial_payload } => { + NetworkBehaviourAction::Dial { opts } => { let peer_id = opts.get_peer_id(); - if let Ok(()) = self.dial_with_payload(opts, Some(dial_payload)) { + if let Ok(()) = self.dial(opts) { if let Some(peer_id) = peer_id { return Some(SwarmEvent::Dialing(peer_id)); } @@ -1090,15 +1059,7 @@ where // Poll the known peers. match this.pool.poll( - |endpoint, payload| match (endpoint, payload) { - (ConnectedPoint::Dialer { .. }, payload) => { - this.behaviour.new_outbound_handler(payload) - } - (ConnectedPoint::Listener { .. }, None) => this.behaviour.new_inbound_handler(), - (ConnectedPoint::Listener { .. }, Some(_)) => { - panic!("Not sure what to do with dial payload as a listener") - } - }, + |peer, connected_point| this.behaviour.new_handler(peer, connected_point), cx, ) { Poll::Pending => {} @@ -1175,7 +1136,7 @@ fn notify_one( /// was successfully sent to a handler, in either case the event is consumed. fn notify_any( ids: SmallVec<[ConnectionId; 10]>, - pool: &mut Pool, + pool: &mut Pool, event: THandlerInEvent, cx: &mut Context<'_>, ) -> Option<(THandlerInEvent, SmallVec<[ConnectionId; 10]>)> @@ -1183,8 +1144,7 @@ where TTrans: Transport, TTrans::Error: Send + 'static, TBehaviour: NetworkBehaviour, - THandler: IntoConnectionHandler, - THandler::Handler: ConnectionHandler< + THandler: ConnectionHandler< InEvent = THandlerInEvent, OutEvent = THandlerOutEvent, >, @@ -1401,14 +1361,16 @@ where /// Builds a `Swarm` with the current configuration. pub fn build(mut self) -> Swarm { - let supported_protocols = self - .behaviour - .new_handler() - .inbound_protocol() - .protocol_info() - .into_iter() - .map(|info| info.protocol_name().to_vec()) - .collect(); + let supported_protocols = todo!(); + + // let supported_protocols = self + // .behaviour + // .new_handler() + // .inbound_protocol() + // .protocol_info() + // .into_iter() + // .map(|info| info.protocol_name().to_vec()) + // .collect(); // If no executor has been explicitly configured, try to set up a thread pool. let pool_config = @@ -1630,7 +1592,7 @@ mod tests { ) -> bool where TBehaviour: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: Clone, + ::OutEvent: Clone, { swarm1 .behaviour() @@ -1650,7 +1612,7 @@ mod tests { ) -> bool where TBehaviour: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: Clone + ::OutEvent: Clone, { swarm1 .behaviour() diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 556bdabe7bd..fbe8e6ccd31 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -19,8 +19,8 @@ // DEALINGS IN THE SOFTWARE. use crate::{ - behaviour::THandlerInEvent, ConnectionHandler, DialError, IntoConnectionHandler, - NetworkBehaviour, NetworkBehaviourAction, PollParameters, + behaviour::THandlerInEvent, ConnectionHandler, DialError, NetworkBehaviour, + NetworkBehaviourAction, PollParameters, }; use libp2p_core::{ connection::ConnectionId, multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId, @@ -43,7 +43,7 @@ where /// The next action to return from `poll`. /// /// An action is only returned once. - pub next_action: Option>, + pub next_action: Option>>, } impl MockBehaviour @@ -68,7 +68,7 @@ where type ConnectionHandler = THandler; type OutEvent = TOutEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { self.handler_proto.clone() } @@ -103,7 +103,7 @@ where pub inject_event: Vec<( PeerId, ConnectionId, - <::Handler as ConnectionHandler>::OutEvent, + ::OutEvent, )>, pub inject_dial_failure: Vec>, pub inject_new_listener: Vec, @@ -222,14 +222,17 @@ where impl NetworkBehaviour for CallTraceBehaviour where TInner: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: - Clone, + ::OutEvent: Clone, { type ConnectionHandler = TInner::ConnectionHandler; type OutEvent = TInner::OutEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { - self.inner.new_handler() + fn new_handler( + &mut self, + peer: &PeerId, + connected_point: &ConnectedPoint, + ) -> Self::ConnectionHandler { + self.inner.new_handler(peer, connected_point) } fn addresses_of_peer(&mut self, p: &PeerId) -> Vec { @@ -283,7 +286,7 @@ where p: &PeerId, c: &ConnectionId, e: &ConnectedPoint, - handler: ::Handler, + handler: Self::ConnectionHandler, remaining_established: usize, ) { let mut other_closed_connections = self @@ -330,7 +333,7 @@ where &mut self, p: PeerId, c: ConnectionId, - e: <::Handler as ConnectionHandler>::OutEvent, + e: ::OutEvent, ) { assert!( self.inject_connection_established @@ -350,14 +353,9 @@ where self.inner.inject_event(p, c, e); } - fn inject_dial_failure( - &mut self, - p: Option, - handler: Self::ConnectionHandler, - error: &DialError, - ) { - self.inject_dial_failure.push(p); - self.inner.inject_dial_failure(p, handler, error); + fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + self.inject_dial_failure.push(_peer_id); + self.inner.inject_dial_failure(_peer_id, _error); } fn inject_new_listener(&mut self, id: ListenerId) { From 9972eb47b641dfea60b8378954d8cf7bcc189636 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 13:27:57 +1100 Subject: [PATCH 05/21] Set supported protocols upon connection establishment --- swarm/src/behaviour.rs | 2 +- swarm/src/connection/pool.rs | 16 +++++++++++++++- swarm/src/lib.rs | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 9f3479aa0a2..51542dcdb68 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -259,7 +259,7 @@ pub trait PollParameters { /// /// The iterator's elements are the ASCII names as reported on the wire. /// - /// Note that the list is computed once at initialization and never refreshed. + /// This list refreshed every time a new connection is established. fn supported_protocols(&self) -> Self::SupportedProtocolsIter; /// Returns the list of the addresses we're listening on. diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 8483d8f7c8c..92f81f1ba8b 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -20,6 +20,7 @@ // DEALINGS IN THE SOFTWARE. use crate::connection::Connection; +use crate::upgrade::UpgradeInfoSend; use crate::{ behaviour::{THandlerInEvent, THandlerOutEvent}, connection::{ @@ -40,6 +41,8 @@ use futures::{ }; use libp2p_core::connection::{ConnectionId, Endpoint, PendingPoint}; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerExt}; +use libp2p_core::ProtocolName; +use smallvec::SmallVec; use std::{ collections::{hash_map, HashMap}, convert::TryFrom as _, @@ -209,6 +212,8 @@ where /// Addresses are dialed in parallel. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. concurrent_dial_errors: Option)>>, + + supported_protocols: SmallVec<[Vec; 16]>, }, /// An established connection was closed. @@ -730,9 +735,17 @@ where }, ); + let handler = new_handler_fn(&obtained_peer_id, &endpoint); + let supported_protocols = handler + .listen_protocol() + .upgrade() + .protocol_info() + .map(|p| p.protocol_name().to_owned()) + .collect(); + let connection = Connection::new( muxer, - new_handler_fn(&obtained_peer_id, &endpoint), + handler, self.substream_upgrade_protocol_override, self.max_negotiating_inbound_streams, ); @@ -753,6 +766,7 @@ where id, other_established_connection_ids, concurrent_dial_errors, + supported_protocols, }); } task::PendingConnectionEvent::PendingFailed { id, error } => { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 447891f1a43..2119ce1f4af 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -656,6 +656,7 @@ where endpoint, other_established_connection_ids, concurrent_dial_errors, + supported_protocols, } => { if self.banned_peers.contains(&peer_id) { // Mark the connection for the banned peer as banned, thus withholding any @@ -690,6 +691,8 @@ where failed_addresses.as_ref(), non_banned_established, ); + self.supported_protocols = supported_protocols; + return Some(SwarmEvent::ConnectionEstablished { peer_id, num_established, From fb9cdbc7e7e27eea563c63a4947773b982f6d4e0 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 14:06:58 +1100 Subject: [PATCH 06/21] Remove TODOs --- protocols/dcutr/src/behaviour.rs | 132 +++++++++++++++-------- protocols/dcutr/src/handler.rs | 60 ----------- protocols/relay/src/v2/client.rs | 73 +++++++------ protocols/relay/src/v2/client/handler.rs | 65 +---------- protocols/relay/src/v2/relay/handler.rs | 42 +------- swarm/src/connection/pool.rs | 4 +- swarm/src/handler/either.rs | 2 +- swarm/src/handler/multi.rs | 2 +- swarm/src/handler/select.rs | 2 +- swarm/src/lib.rs | 17 +-- 10 files changed, 142 insertions(+), 257 deletions(-) diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 5e8ead9dbe5..aa8527fa0a2 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -32,6 +32,7 @@ use libp2p_swarm::{ dummy, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; +use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; use thiserror::Error; @@ -73,6 +74,10 @@ pub struct Behaviour { /// All direct (non-relayed) connections. direct_connections: HashMap>, + + awaiting_direct_inbound_connections: HashMap, + + awaiting_direct_outbound_connections: HashMap, } type Handler = @@ -83,6 +88,8 @@ impl Behaviour { Behaviour { queued_actions: Default::default(), direct_connections: Default::default(), + awaiting_direct_inbound_connections: Default::default(), + awaiting_direct_outbound_connections: Default::default(), } } } @@ -96,9 +103,53 @@ impl NetworkBehaviour for Behaviour { peer: &PeerId, connected_point: &ConnectedPoint, ) -> Self::ConnectionHandler { - // handler::Prototype::UnknownConnection + match ( + self.awaiting_direct_inbound_connections.entry(*peer), + self.awaiting_direct_outbound_connections.entry(*peer), + ) { + (Entry::Vacant(_), Entry::Occupied(occupied)) => { + if connected_point.is_relayed() { + log::debug!( + "Unexpected relay connection whilst awaiting direct outbound connection" + ); + + return Either::Left(handler::relayed::Handler::new(connected_point.clone())); + } + + let (relayed_connection_id, _) = occupied.remove(); + + Either::Right(Either::Left(handler::direct::Handler::new( + relayed_connection_id, + ))) + } + (Entry::Occupied(occupied), Entry::Vacant(_)) => { + if connected_point.is_relayed() { + log::debug!( + "Unexpected relay connection whilst awaiting direct inbound connection" + ); + + return Either::Left(handler::relayed::Handler::new(connected_point.clone())); + } + + let relayed_connection_id = occupied.remove(); + + Either::Right(Either::Left(handler::direct::Handler::new( + relayed_connection_id, + ))) + } + (Entry::Vacant(_), Entry::Vacant(_)) => { + if connected_point.is_relayed() { + Either::Right(Either::Right(dummy::ConnectionHandler)) + } else { + Either::Left(handler::relayed::Handler::new(connected_point.clone())) + } + } + (Entry::Occupied(_), Entry::Occupied(_)) => { + debug_assert!(false, "Should not have a pending outbound and pending inbound connection to same peer simultaneously"); - todo!() + Either::Right(Either::Right(dummy::ConnectionHandler)) + } + } } fn addresses_of_peer(&mut self, _peer_id: &PeerId) -> Vec { @@ -150,38 +201,39 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { - // TODO: Track state in behaviour - // if let Some(handler::Prototype::DirectConnection { - // relayed_connection_id, - // role: handler::Role::Initiator { attempt }, - // }) = dial_payload - // { - // let peer_id = _peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); - // if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - // self.queued_actions.push_back(ActionBuilder::Connect { - // peer_id, - // handler: NotifyHandler::One(relayed_connection_id), - // attempt: attempt + 1, - // }); - // } else { - // self.queued_actions.extend([ - // NetworkBehaviourAction::NotifyHandler { - // peer_id, - // handler: NotifyHandler::One(relayed_connection_id), - // event: Either::Left( - // handler::relayed::Command::UpgradeFinishedDontKeepAlive, - // ), - // } - // .into(), - // NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { - // remote_peer_id: peer_id, - // error: UpgradeError::Dial, - // }) - // .into(), - // ]); - // } - // } + fn inject_dial_failure(&mut self, maybe_peer_id: Option, _error: &DialError) { + let peer_id = match maybe_peer_id { + Some(peer_id) => peer_id, + None => return, + }; + + let (relayed_connection_id, attempt) = + match self.awaiting_direct_outbound_connections.remove(&peer_id) { + Some((relayed_connection_id, attempt)) => (relayed_connection_id, attempt), + None => return, + }; + + if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { + self.queued_actions.push_back(ActionBuilder::Connect { + peer_id, + handler: NotifyHandler::One(relayed_connection_id), + attempt: attempt + 1, + }); + } else { + self.queued_actions.extend([ + NetworkBehaviourAction::NotifyHandler { + peer_id, + handler: NotifyHandler::One(relayed_connection_id), + event: Either::Left(handler::relayed::Command::UpgradeFinishedDontKeepAlive), + } + .into(), + NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { + remote_peer_id: peer_id, + error: UpgradeError::Dial, + }) + .into(), + ]); + } } fn inject_connection_closed( @@ -249,13 +301,11 @@ impl NetworkBehaviour for Behaviour { .addresses(remote_addrs) .condition(dial_opts::PeerCondition::Always) .build(), - // dial_payload: handler::Prototype::DirectConnection { - // relayed_connection_id: connection, - // role: handler::Role::Listener, - // }, } .into(), ); + self.awaiting_direct_inbound_connections + .insert(event_source, connection); } Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { self.queued_actions.push_back( @@ -277,13 +327,11 @@ impl NetworkBehaviour for Behaviour { .addresses(remote_addrs) .override_role() .build(), - // dial_payload: handler::Prototype::DirectConnection { - // relayed_connection_id: connection, - // role: handler::Role::Initiator { attempt }, - // }, } .into(), ); + self.awaiting_direct_outbound_connections + .insert(event_source, (connection, attempt)); } Either::Right(Either::Left( handler::direct::Event::DirectConnectionUpgradeSucceeded { diff --git a/protocols/dcutr/src/handler.rs b/protocols/dcutr/src/handler.rs index 41cd9f20355..cc59e3ab4ce 100644 --- a/protocols/dcutr/src/handler.rs +++ b/protocols/dcutr/src/handler.rs @@ -18,65 +18,5 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::protocol; -use either::Either; -use libp2p_core::connection::ConnectionId; -use libp2p_core::upgrade::{self, DeniedUpgrade}; -use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::dummy; -use libp2p_swarm::handler::SendWrapper; -use libp2p_swarm::ConnectionHandler; - pub mod direct; pub mod relayed; - -pub enum Prototype { - DirectConnection { - role: Role, - relayed_connection_id: ConnectionId, - }, - UnknownConnection, -} - -pub enum Role { - Initiator { attempt: u8 }, - Listener, -} - -// TODO -// impl IntoConnectionHandler for Prototype { -// type Handler = Either>; -// -// fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { -// match self { -// Self::UnknownConnection => { -// if endpoint.is_relayed() { -// Either::Left(relayed::Handler::new(endpoint.clone())) -// } else { -// Either::Right(Either::Right(dummy::ConnectionHandler)) -// } -// } -// Self::DirectConnection { -// relayed_connection_id, -// .. -// } => { -// assert!( -// !endpoint.is_relayed(), -// "`Prototype::DirectConnection` is never created for relayed connection." -// ); -// Either::Right(Either::Left(direct::Handler::new(relayed_connection_id))) -// } -// } -// } -// -// fn inbound_protocol(&self) -> ::InboundProtocol { -// match self { -// Prototype::UnknownConnection => upgrade::EitherUpgrade::A(SendWrapper( -// upgrade::EitherUpgrade::A(protocol::inbound::Upgrade {}), -// )), -// Prototype::DirectConnection { .. } => { -// upgrade::EitherUpgrade::A(SendWrapper(upgrade::EitherUpgrade::B(DeniedUpgrade))) -// } -// } -// } -// } diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 6c42dccce11..0cd8f15f132 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -37,7 +37,7 @@ use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::dial_opts::DialOpts; -use libp2p_swarm::dummy; +use libp2p_swarm::{dummy, ConnectionHandler}; use libp2p_swarm::{ ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -98,6 +98,8 @@ pub struct Client { /// connection. directly_connected_peers: HashMap>, + initial_events: HashMap, + /// Queue of actions to return when polled. queued_actions: VecDeque, } @@ -111,6 +113,7 @@ impl Client { local_peer_id, from_transport, directly_connected_peers: Default::default(), + initial_events: Default::default(), queued_actions: Default::default(), }; (transport, behaviour) @@ -127,15 +130,14 @@ impl NetworkBehaviour for Client { connected_point: &ConnectedPoint, ) -> Self::ConnectionHandler { if connected_point.is_relayed() { - // if let Some(event) = self.initial_in { - // log::debug!( - // "Established relayed instead of direct connection to {:?}, \ - // dropping initial in event {:?}.", - // remote_peer_id, event - // ); - // } - - // TODO: Check local state for initial in? + if let Some(event) = self.initial_events.remove(peer) { + log::debug!( + "Established relayed instead of direct connection to {:?}, \ + dropping initial in event {:?}.", + peer, + event + ); + } // Deny all substreams on relayed connection. Either::Right(dummy::ConnectionHandler) @@ -146,10 +148,9 @@ impl NetworkBehaviour for Client { connected_point.get_remote_address().clone(), ); - // if let Some(event) = self.initial_in { - // handler.inject_event(event) - // } - // TODO: Grab event from local state + if let Some(event) = self.initial_events.remove(peer) { + handler.inject_event(event) + } Either::Left(handler) } @@ -285,13 +286,17 @@ impl NetworkBehaviour for Client { handler: NotifyHandler::One(*connection_id), event: Either::Left(handler::In::Reserve { to_listener }), }, - None => NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) - .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() - .build(), - // dial_payload: handler::In::Reserve { to_listener }, TODO - }, + None => { + self.initial_events + .insert(relay_peer_id, handler::In::Reserve { to_listener }); + + NetworkBehaviourAction::Dial { + opts: DialOpts::peer_id(relay_peer_id) + .addresses(vec![relay_addr]) + .extend_addresses_through_behaviour() + .build(), + } + } } } Some(transport::TransportToBehaviourMsg::DialReq { @@ -314,16 +319,22 @@ impl NetworkBehaviour for Client { dst_peer_id, }), }, - None => NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) - .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() - .build(), - // dial_payload: handler::In::EstablishCircuit { - // send_back, - // dst_peer_id, - // }, - }, + None => { + self.initial_events.insert( + relay_peer_id, + handler::In::EstablishCircuit { + send_back, + dst_peer_id, + }, + ); + + NetworkBehaviourAction::Dial { + opts: DialOpts::peer_id(relay_peer_id) + .addresses(vec![relay_addr]) + .extend_addresses_through_behaviour() + .build(), + } + } } } None => unreachable!( diff --git a/protocols/relay/src/v2/client/handler.rs b/protocols/relay/src/v2/client/handler.rs index 8d5093cfa28..df283308e8d 100644 --- a/protocols/relay/src/v2/client/handler.rs +++ b/protocols/relay/src/v2/client/handler.rs @@ -21,7 +21,6 @@ use crate::v2::client::transport; use crate::v2::message_proto::Status; use crate::v2::protocol::{self, inbound_stop, outbound_hop}; -use either::Either; use futures::channel::{mpsc, oneshot}; use futures::future::{BoxFuture, FutureExt}; use futures::sink::SinkExt; @@ -30,10 +29,10 @@ use futures_timer::Delay; use instant::Instant; use libp2p_core::either::EitherError; use libp2p_core::multiaddr::Protocol; -use libp2p_core::{upgrade, ConnectedPoint, Multiaddr, PeerId}; -use libp2p_swarm::handler::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; +use libp2p_core::{upgrade, Multiaddr, PeerId}; +use libp2p_swarm::handler::{InboundUpgradeSend, OutboundUpgradeSend}; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, NegotiatedSubstream, SubstreamProtocol, }; use log::debug; @@ -107,64 +106,6 @@ pub enum Event { }, } -pub struct Prototype { - local_peer_id: PeerId, - /// Initial [`In`] event from [`super::Client`] provided at creation time. - initial_in: Option, -} - -impl Prototype { - pub(crate) fn new(local_peer_id: PeerId, initial_in: Option) -> Self { - Self { - local_peer_id, - initial_in, - } - } -} - -// TODO -// impl IntoConnectionHandler for Prototype { -// type Handler = Either; -// -// fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { -// if endpoint.is_relayed() { -// if let Some(event) = self.initial_in { -// debug!( -// "Established relayed instead of direct connection to {:?}, \ -// dropping initial in event {:?}.", -// remote_peer_id, event -// ); -// } -// -// // Deny all substreams on relayed connection. -// Either::Right(dummy::ConnectionHandler) -// } else { -// let mut handler = Handler { -// remote_peer_id: *remote_peer_id, -// remote_addr: endpoint.get_remote_address().clone(), -// local_peer_id: self.local_peer_id, -// queued_events: Default::default(), -// pending_error: Default::default(), -// reservation: Reservation::None, -// alive_lend_out_substreams: Default::default(), -// circuit_deny_futs: Default::default(), -// send_error_futs: Default::default(), -// keep_alive: KeepAlive::Yes, -// }; -// -// if let Some(event) = self.initial_in { -// handler.inject_event(event) -// } -// -// Either::Left(handler) -// } -// } -// -// fn inbound_protocol(&self) -> ::InboundProtocol { -// upgrade::EitherUpgrade::A(SendWrapper(inbound_stop::Upgrade {})) -// } -// } - pub struct Handler { local_peer_id: PeerId, remote_peer_id: PeerId, diff --git a/protocols/relay/src/v2/relay/handler.rs b/protocols/relay/src/v2/relay/handler.rs index 6a04729c168..686cc130621 100644 --- a/protocols/relay/src/v2/relay/handler.rs +++ b/protocols/relay/src/v2/relay/handler.rs @@ -23,7 +23,6 @@ use crate::v2::message_proto::Status; use crate::v2::protocol::{inbound_hop, outbound_stop}; use crate::v2::relay::CircuitId; use bytes::Bytes; -use either::Either; use futures::channel::oneshot::{self, Canceled}; use futures::future::{BoxFuture, FutureExt, TryFutureExt}; use futures::io::AsyncWriteExt; @@ -33,10 +32,9 @@ use instant::Instant; use libp2p_core::connection::ConnectionId; use libp2p_core::either::EitherError; use libp2p_core::{upgrade, ConnectedPoint, Multiaddr, PeerId}; -use libp2p_swarm::handler::SendWrapper; use libp2p_swarm::handler::{InboundUpgradeSend, OutboundUpgradeSend}; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, NegotiatedSubstream, SubstreamProtocol, }; use std::collections::VecDeque; @@ -337,44 +335,6 @@ impl fmt::Debug for Event { } } -pub struct Prototype { - pub config: Config, -} - -// TODO -// impl IntoConnectionHandler for Prototype { -// type Handler = Either; -// -// fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { -// if endpoint.is_relayed() { -// // Deny all substreams on relayed connection. -// Either::Right(dummy::ConnectionHandler) -// } else { -// Either::Left(Handler { -// endpoint: endpoint.clone(), -// config: self.config, -// queued_events: Default::default(), -// pending_error: Default::default(), -// reservation_request_future: Default::default(), -// circuit_accept_futures: Default::default(), -// circuit_deny_futures: Default::default(), -// alive_lend_out_substreams: Default::default(), -// circuits: Default::default(), -// active_reservation: Default::default(), -// keep_alive: KeepAlive::Yes, -// }) -// } -// } -// -// fn inbound_protocol(&self) -> ::InboundProtocol { -// upgrade::EitherUpgrade::A(SendWrapper(inbound_hop::Upgrade { -// reservation_duration: self.config.reservation_duration, -// max_circuit_duration: self.config.max_circuit_duration, -// max_circuit_bytes: self.config.max_circuit_bytes, -// })) -// } -// } - /// [`ConnectionHandler`] that manages substreams for a relay on a single /// connection with a peer. pub struct Handler { diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 92f81f1ba8b..e3094db2b77 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -433,9 +433,7 @@ where TTrans: Send, TTrans::Dial: Send + 'static, { - if let Err(limit) = self.counters.check_max_pending_outgoing() { - return Err(limit); - }; + self.counters.check_max_pending_outgoing()?; let dial = ConcurrentDial::new( dials, diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index 41067011b0c..81451d3a9b2 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -26,7 +26,7 @@ use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; use either::Either; use libp2p_core::either::{EitherError, EitherOutput}; use libp2p_core::upgrade::{EitherUpgrade, UpgradeError}; -use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; +use libp2p_core::Multiaddr; use std::task::{Context, Poll}; /// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`] diff --git a/swarm/src/handler/multi.rs b/swarm/src/handler/multi.rs index 4cef6ad9483..ff4e3b8a00d 100644 --- a/swarm/src/handler/multi.rs +++ b/swarm/src/handler/multi.rs @@ -29,7 +29,7 @@ use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend}; use crate::NegotiatedSubstream; use futures::{future::BoxFuture, prelude::*}; use libp2p_core::upgrade::{NegotiationError, ProtocolError, ProtocolName, UpgradeError}; -use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; +use libp2p_core::Multiaddr; use rand::Rng; use std::{ cmp, diff --git a/swarm/src/handler/select.rs b/swarm/src/handler/select.rs index 0100a42abf2..47437f7b15b 100644 --- a/swarm/src/handler/select.rs +++ b/swarm/src/handler/select.rs @@ -27,7 +27,7 @@ use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; use libp2p_core::{ either::{EitherError, EitherOutput}, upgrade::{EitherUpgrade, NegotiationError, ProtocolError, SelectUpgrade, UpgradeError}, - ConnectedPoint, Multiaddr, PeerId, + Multiaddr, }; use std::{cmp, task::Context, task::Poll}; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 2119ce1f4af..f2172fec763 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -94,7 +94,6 @@ use libp2p_core::{ multihash::Multihash, muxing::StreamMuxerBox, transport::{self, ListenerId, TransportError, TransportEvent}, - upgrade::ProtocolName, Endpoint, Executor, Multiaddr, Negotiated, PeerId, Transport, }; use registry::{AddressIntoIter, Addresses}; @@ -108,7 +107,6 @@ use std::{ pin::Pin, task::{Context, Poll}, }; -use upgrade::UpgradeInfoSend as _; /// Substream for which a protocol has been chosen. /// @@ -1363,18 +1361,7 @@ where } /// Builds a `Swarm` with the current configuration. - pub fn build(mut self) -> Swarm { - let supported_protocols = todo!(); - - // let supported_protocols = self - // .behaviour - // .new_handler() - // .inbound_protocol() - // .protocol_info() - // .into_iter() - // .map(|info| info.protocol_name().to_vec()) - // .collect(); - + pub fn build(self) -> Swarm { // If no executor has been explicitly configured, try to set up a thread pool. let pool_config = self.pool_config.or_else_with_executor(|| { @@ -1395,7 +1382,7 @@ where transport: self.transport, pool: Pool::new(self.local_peer_id, pool_config, self.connection_limits), behaviour: self.behaviour, - supported_protocols, + supported_protocols: Default::default(), listened_addrs: HashMap::new(), external_addrs: Addresses::default(), banned_peers: HashSet::new(), From a96780d080d51498105192a6187c6588263052e4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 14:10:20 +1100 Subject: [PATCH 07/21] Fix bad boolean logic --- protocols/dcutr/src/behaviour.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index aa8527fa0a2..5de42c24e02 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -139,9 +139,9 @@ impl NetworkBehaviour for Behaviour { } (Entry::Vacant(_), Entry::Vacant(_)) => { if connected_point.is_relayed() { - Either::Right(Either::Right(dummy::ConnectionHandler)) - } else { Either::Left(handler::relayed::Handler::new(connected_point.clone())) + } else { + Either::Right(Either::Right(dummy::ConnectionHandler)) } } (Entry::Occupied(_), Entry::Occupied(_)) => { From 900edefe6a37b66322fc38a8e4d7d984b095b8c9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 14:15:59 +1100 Subject: [PATCH 08/21] Fix gossipsub tests --- protocols/gossipsub/src/behaviour/tests.rs | 2 +- protocols/gossipsub/src/config.rs | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index ce05104fe23..dc93b5da5ce 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -233,7 +233,7 @@ where // peer_connections.connections should never be empty. let mut active_connections = peer_connections.connections.len(); for conn_id in peer_connections.connections.clone() { - let handler = gs.new_handler(todo!(), todo!()); + let handler = gs.new_handler(peer_id, &fake_endpoint); active_connections = active_connections.checked_sub(1).unwrap(); gs.inject_connection_closed( peer_id, diff --git a/protocols/gossipsub/src/config.rs b/protocols/gossipsub/src/config.rs index dfc16624c52..2af454048f3 100644 --- a/protocols/gossipsub/src/config.rs +++ b/protocols/gossipsub/src/config.rs @@ -889,7 +889,7 @@ mod test { use crate::types::PeerKind; use crate::Topic; use crate::{Gossipsub, MessageAuthenticity}; - use libp2p_core::UpgradeInfo; + use libp2p_core::{ConnectedPoint, Endpoint, Multiaddr, UpgradeInfo}; use libp2p_swarm::{ConnectionHandler, NetworkBehaviour}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -995,7 +995,7 @@ mod test { let mut gossipsub: Gossipsub = Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - let handler = gossipsub.new_handler(todo!(), todo!()); + let handler = gossipsub.new_handler(&PeerId::random(), &fake_endpoint()); let (protocol_config, _) = handler.listen_protocol().into_upgrade(); let protocol_ids = protocol_config.protocol_info(); @@ -1023,7 +1023,7 @@ mod test { let mut gossipsub: Gossipsub = Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - let handler = gossipsub.new_handler(todo!(), todo!()); + let handler = gossipsub.new_handler(&PeerId::random(), &fake_endpoint()); let (protocol_config, _) = handler.listen_protocol().into_upgrade(); let protocol_ids = protocol_config.protocol_info(); @@ -1032,4 +1032,11 @@ mod test { assert_eq!(protocol_ids[0].protocol_id, b"purple".to_vec()); assert_eq!(protocol_ids[0].kind, PeerKind::Gossipsub); } + + fn fake_endpoint() -> ConnectedPoint { + ConnectedPoint::Dialer { + address: Multiaddr::empty(), + role_override: Endpoint::Dialer, + } + } } From d1eea3a871aee563d297191360a0b5d36780440d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 14:16:39 +1100 Subject: [PATCH 09/21] Fix clippy warning --- swarm/src/connection/pool.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index e3094db2b77..f43f1ca71e4 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -195,6 +195,7 @@ impl fmt::Debug for Pool where TTrans: Transport, From 98bf9278a3456d3b0fa771ee72c299653e526fc5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 14:24:14 +1100 Subject: [PATCH 10/21] Update docs --- protocols/kad/src/handler.rs | 18 ---- protocols/mdns/src/behaviour.rs | 30 +++--- swarm/src/behaviour.rs | 184 +------------------------------- 3 files changed, 19 insertions(+), 213 deletions(-) diff --git a/protocols/kad/src/handler.rs b/protocols/kad/src/handler.rs index f2331b05973..75afda56e99 100644 --- a/protocols/kad/src/handler.rs +++ b/protocols/kad/src/handler.rs @@ -43,24 +43,6 @@ use std::{ const MAX_NUM_INBOUND_SUBSTREAMS: usize = 32; -// impl IntoConnectionHandler -// for KademliaHandlerProto -// { -// type Handler = KademliaHandler; -// -// fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { -// KademliaHandler::new(self.config, endpoint.clone(), *remote_peer_id) -// } -// -// fn inbound_protocol(&self) -> ::InboundProtocol { -// if self.config.allow_listening { -// upgrade::EitherUpgrade::A(self.config.protocol_config.clone()) -// } else { -// upgrade::EitherUpgrade::B(upgrade::DeniedUpgrade) -// } -// } -// } - /// Protocol handler that manages substreams for the Kademlia protocol /// on a single connection with a peer. /// diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index b7fe99179b6..35ce4aeb383 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -28,7 +28,7 @@ use crate::MdnsConfig; use futures::Stream; use if_watch::{IfEvent, IfWatcher}; use libp2p_core::transport::ListenerId; -use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; +use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::{ dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -122,7 +122,7 @@ where type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = MdnsEvent; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { + fn new_handler(&mut self, _: &PeerId, _: &libp2p_core::ConnectedPoint) -> Self::ConnectionHandler { dummy::ConnectionHandler } @@ -134,19 +134,6 @@ where .collect() } - fn inject_connection_closed( - &mut self, - peer: &PeerId, - _: &libp2p_core::connection::ConnectionId, - _: &libp2p_core::ConnectedPoint, - _: Self::ConnectionHandler, - remaining_established: usize, - ) { - if remaining_established == 0 { - self.expire_node(peer); - } - } - fn inject_event( &mut self, _: PeerId, @@ -163,6 +150,19 @@ where } } + fn inject_connection_closed( + &mut self, + peer: &PeerId, + _: &libp2p_core::connection::ConnectionId, + _: &libp2p_core::ConnectedPoint, + _: Self::ConnectionHandler, + remaining_established: usize, + ) { + if remaining_established == 0 { + self.expire_node(peer); + } + } + fn poll( &mut self, cx: &mut Context<'_>, diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index b514fc7153c..e534f2a1ceb 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -288,188 +288,12 @@ pub enum NetworkBehaviourAction { /// Instructs the swarm to start a dial. /// - /// On success, [`NetworkBehaviour::inject_connection_established`] is invoked. - /// On failure, [`NetworkBehaviour::inject_dial_failure`] is invoked. + /// On success, [`NetworkBehaviour::new_handler`] is called with the [`PeerId`] and [`ConnectedPoint`] + /// of the newly established connection. /// - /// Note that the provided handler is returned to the [`NetworkBehaviour`] on connection failure - /// and connection closing. Thus it can be used to carry state, which otherwise would have to be - /// tracked in the [`NetworkBehaviour`] itself. E.g. a message destined to an unconnected peer - /// can be included in the handler, and thus directly send on connection success or extracted by - /// the [`NetworkBehaviour`] on connection failure. + /// Once the handler is constructed, [`NetworkBehaviour::inject_connection_established`] will be called. /// - /// # Example carrying state in the handler - /// - /// ```rust - /// # use futures::executor::block_on; - /// # use futures::stream::StreamExt; - /// # use libp2p_core::connection::ConnectionId; - /// # use libp2p_core::identity; - /// # use libp2p_core::transport::{MemoryTransport, Transport}; - /// # use libp2p_core::upgrade::{self, DeniedUpgrade, InboundUpgrade, OutboundUpgrade}; - /// # use libp2p_core::PeerId; - /// # use libp2p_plaintext::PlainText2Config; - /// # use libp2p_swarm::{ - /// # DialError, IntoConnectionHandler, KeepAlive, NegotiatedSubstream, - /// # NetworkBehaviour, NetworkBehaviourAction, PollParameters, ConnectionHandler, - /// # ConnectionHandlerEvent, ConnectionHandlerUpgrErr, SubstreamProtocol, Swarm, SwarmEvent, - /// # }; - /// # use libp2p_swarm::dial_opts::{DialOpts, PeerCondition}; - /// # use libp2p_yamux as yamux; - /// # use std::collections::VecDeque; - /// # use std::task::{Context, Poll}; - /// # use void::Void; - /// # - /// # let local_key = identity::Keypair::generate_ed25519(); - /// # let local_public_key = local_key.public(); - /// # let local_peer_id = PeerId::from(local_public_key.clone()); - /// # - /// # let transport = MemoryTransport::default() - /// # .upgrade(upgrade::Version::V1) - /// # .authenticate(PlainText2Config { local_public_key }) - /// # .multiplex(yamux::YamuxConfig::default()) - /// # .boxed(); - /// # - /// # let mut swarm = Swarm::new(transport, MyBehaviour::default(), local_peer_id); - /// # - /// // Super precious message that we should better not lose. - /// let message = PreciousMessage("My precious message".to_string()); - /// - /// // Unfortunately this peer is offline, thus sending our message to it will fail. - /// let offline_peer = PeerId::random(); - /// - /// // Let's send it anyways. We should get it back in case connecting to the peer fails. - /// swarm.behaviour_mut().send(offline_peer, message); - /// - /// block_on(async { - /// // As expected, sending failed. But great news, we got our message back. - /// matches!( - /// swarm.next().await.expect("Infinite stream"), - /// SwarmEvent::Behaviour(PreciousMessage(_)) - /// ); - /// }); - /// - /// #[derive(Default)] - /// struct MyBehaviour { - /// outbox_to_swarm: VecDeque>, - /// } - /// - /// impl MyBehaviour { - /// fn send(&mut self, peer_id: PeerId, msg: PreciousMessage) { - /// self.outbox_to_swarm - /// .push_back(NetworkBehaviourAction::Dial { - /// opts: DialOpts::peer_id(peer_id) - /// .condition(PeerCondition::Always) - /// .build(), - /// handler: MyHandler { message: Some(msg) }, - /// }); - /// } - /// } - /// # - /// impl NetworkBehaviour for MyBehaviour { - /// # type ConnectionHandler = MyHandler; - /// # type OutEvent = PreciousMessage; - /// # - /// # fn new_handler(&mut self) -> Self::ConnectionHandler { - /// # MyHandler { message: None } - /// # } - /// # - /// # - /// # fn inject_event( - /// # &mut self, - /// # _: PeerId, - /// # _: ConnectionId, - /// # _: <::Handler as ConnectionHandler>::OutEvent, - /// # ) { - /// # unreachable!(); - /// # } - /// # - /// /// /// /// fn inject_dial_failure( - /// &mut self, - /// _peer_id: Option, - /// _error: &DialError, - /// ) { - /// /// /// // As expected, sending the message failed. But lucky us, we got the handler back, thus - /// // the precious message is not lost and we can return it back to the user. - /// let msg = handler.message.unwrap(); - /// self.outbox_to_swarm - /// .push_back(NetworkBehaviourAction::GenerateEvent(msg)) - /// } - /// # - /// # fn poll( - /// # &mut self, - /// # _: &mut Context<'_>, - /// # _: &mut impl PollParameters, - /// # ) -> Poll>> { - /// # if let Some(action) = self.outbox_to_swarm.pop_front() { - /// # return Poll::Ready(action); - /// # } - /// # Poll::Pending - /// # } - /// } - /// - /// # struct MyHandler { - /// # message: Option, - /// # } - /// # - /// # impl ConnectionHandler for MyHandler { - /// # type InEvent = Void; - /// # type OutEvent = Void; - /// # type Error = Void; - /// # type InboundProtocol = DeniedUpgrade; - /// # type OutboundProtocol = DeniedUpgrade; - /// # type InboundOpenInfo = (); - /// # type OutboundOpenInfo = Void; - /// # - /// # fn listen_protocol( - /// # &self, - /// # ) -> SubstreamProtocol { - /// # SubstreamProtocol::new(DeniedUpgrade, ()) - /// # } - /// # - /// # fn inject_fully_negotiated_inbound( - /// # &mut self, - /// # _: >::Output, - /// # _: Self::InboundOpenInfo, - /// # ) { - /// # } - /// # - /// # fn inject_fully_negotiated_outbound( - /// # &mut self, - /// # _: >::Output, - /// # _: Self::OutboundOpenInfo, - /// # ) { - /// # } - /// # - /// # fn inject_event(&mut self, _event: Self::InEvent) {} - /// # - /// # fn inject_dial_upgrade_error( - /// # &mut self, - /// # _: Self::OutboundOpenInfo, - /// # _: ConnectionHandlerUpgrErr, - /// # ) { - /// # } - /// # - /// # fn connection_keep_alive(&self) -> KeepAlive { - /// # KeepAlive::Yes - /// # } - /// # - /// # fn poll( - /// # &mut self, - /// # _: &mut Context<'_>, - /// # ) -> Poll< - /// # ConnectionHandlerEvent< - /// # Self::OutboundProtocol, - /// # Self::OutboundOpenInfo, - /// # Self::OutEvent, - /// # Self::Error, - /// # >, - /// # > { - /// # todo!("If `Self::message.is_some()` send the message to the remote.") - /// # } - /// # } - /// # #[derive(Debug, PartialEq, Eq)] - /// # struct PreciousMessage(String); - /// ``` + /// In case the dial fails, the behaviour is notified via [`NetworkBehaviour::inject_dial_failure`]. Dial { opts: DialOpts }, /// Instructs the `Swarm` to send an event to the handler dedicated to a From 1cef941cc80976fc3b983c137158556dd8235e6e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 19:22:29 +1100 Subject: [PATCH 11/21] Reduce diff --- protocols/autonat/src/behaviour.rs | 6 +++--- protocols/identify/src/behaviour.rs | 8 ++++---- protocols/kad/src/behaviour.rs | 8 ++++---- protocols/mdns/src/behaviour.rs | 6 +++++- protocols/request-response/src/lib.rs | 4 ++-- swarm/src/behaviour/either.rs | 6 +++--- swarm/src/behaviour/toggle.rs | 4 ++-- swarm/src/test.rs | 6 +++--- 8 files changed, 26 insertions(+), 22 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 8883084fb9e..28e5f667a63 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -368,9 +368,9 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { - self.inner.inject_dial_failure(_peer_id, _error); - if let Some(event) = self.as_server().on_outbound_dial_error(_peer_id, _error) { + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { + self.inner.inject_dial_failure(peer_id, error); + if let Some(event) = self.as_server().on_outbound_dial_error(peer_id, error) { self.pending_out_events .push_back(Event::InboundProbe(event)); } diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 439a6a45854..0273c8a12f3 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -258,15 +258,15 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { - if let Some(peer_id) = _peer_id { + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { + if let Some(peer_id) = peer_id { if !self.connected.contains_key(&peer_id) { self.pending_push.remove(&peer_id); } } - if let Some(entry) = _peer_id.and_then(|id| self.discovered_peers.get_mut(&id)) { - if let DialError::Transport(errors) = _error { + if let Some(entry) = peer_id.and_then(|id| self.discovered_peers.get_mut(&id)) { + if let DialError::Transport(errors) = error { for (addr, _error) in errors { entry.remove(addr); } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index e44afa6151e..0c7250cfcf9 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1918,14 +1918,14 @@ where } } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { - let peer_id = match _peer_id { + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { + let peer_id = match peer_id { Some(id) => id, // Not interested in dial failures to unknown peers. None => return, }; - match _error { + match error { DialError::Banned | DialError::ConnectionLimit(_) | DialError::LocalPeerId @@ -1935,7 +1935,7 @@ where | DialError::ConnectionIo(_) | DialError::Transport(_) | DialError::NoAddresses => { - if let DialError::Transport(addresses) = _error { + if let DialError::Transport(addresses) = error { for (addr, _) in addresses { self.address_failed(peer_id, addr) } diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 35ce4aeb383..c2392e4a417 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -122,7 +122,11 @@ where type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = MdnsEvent; - fn new_handler(&mut self, _: &PeerId, _: &libp2p_core::ConnectedPoint) -> Self::ConnectionHandler { + fn new_handler( + &mut self, + _: &PeerId, + _: &libp2p_core::ConnectedPoint, + ) -> Self::ConnectionHandler { dummy::ConnectionHandler } diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 49aafca7610..63c200a87b4 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -686,8 +686,8 @@ where } } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { - if let Some(peer) = _peer_id { + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { + if let Some(peer) = peer_id { // If there are pending outgoing requests when a dial failure occurs, // it is implied that we are not connected to the peer, since pending // outgoing requests are drained when a connection is established and diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 7c6cf6e0bfc..71551ce8132 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -138,10 +138,10 @@ where } } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { match self { - Either::Left(behaviour) => behaviour.inject_dial_failure(_peer_id, _error), - Either::Right(behaviour) => behaviour.inject_dial_failure(_peer_id, _error), + Either::Left(behaviour) => behaviour.inject_dial_failure(peer_id, error), + Either::Right(behaviour) => behaviour.inject_dial_failure(peer_id, error), } } diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index bc2ecef75f1..947e5308fd1 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -155,9 +155,9 @@ where } } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { if let Some(inner) = self.inner.as_mut() { - inner.inject_dial_failure(_peer_id, _error) + inner.inject_dial_failure(peer_id, error) } } diff --git a/swarm/src/test.rs b/swarm/src/test.rs index fbe8e6ccd31..9f022204fa2 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -353,9 +353,9 @@ where self.inner.inject_event(p, c, e); } - fn inject_dial_failure(&mut self, _peer_id: Option, _error: &DialError) { - self.inject_dial_failure.push(_peer_id); - self.inner.inject_dial_failure(_peer_id, _error); + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { + self.inject_dial_failure.push(peer_id); + self.inner.inject_dial_failure(peer_id, error); } fn inject_new_listener(&mut self, id: ListenerId) { From ca3ef3e294b1c1b5d0ae1776554867b48330c77d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 15 Nov 2022 19:48:13 +1100 Subject: [PATCH 12/21] Fix clippy errors --- protocols/request-response/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 63c200a87b4..8f1f0181c83 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -686,7 +686,7 @@ where } } - fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { + fn inject_dial_failure(&mut self, peer_id: Option, _: &DialError) { if let Some(peer) = peer_id { // If there are pending outgoing requests when a dial failure occurs, // it is implied that we are not connected to the peer, since pending From d95b038f0054ed2962ead20b3713b67da6c48dda Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 17 Nov 2022 09:28:16 +1100 Subject: [PATCH 13/21] Update swarm/src/behaviour.rs Co-authored-by: Max Inden --- 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 e534f2a1ceb..18a83220347 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -260,7 +260,7 @@ pub trait PollParameters { /// /// The iterator's elements are the ASCII names as reported on the wire. /// - /// This list refreshed every time a new connection is established. + /// This list is refreshed every time a new connection is established. fn supported_protocols(&self) -> Self::SupportedProtocolsIter; /// Returns the list of the addresses we're listening on. From edbbe41fe11198706badb50ddd6ee318bab1e79f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 17 Nov 2022 12:39:48 +1100 Subject: [PATCH 14/21] Add changelog entry --- swarm/CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index f04da3da77b..de3e3404ccd 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -54,7 +54,8 @@ ``` - Without - Spawns the tasks on the current task, this may result in bad performance so try to use an executor where possible. Previously this was just a fallback when no executor was specified and constructing a `ThreadPool` failed. + Spawns the tasks on the current task, this may result in bad performance so try to use an executor where possible. + Previously this was just a fallback when no executor was specified and constructing a `ThreadPool` failed. New ```rust @@ -66,6 +67,10 @@ - `SwarmBuilder::new` - `SwarmBuilder::executor` +- Remove `IntoConnectionHandler` abstraction and change the signature of `NetworkBehaviour::new_handler` to accept `PeerId` and `ConnectedPoint`. + Previously, this information was only available as part of `IntoConnectionHandler::into_handler` but it is now passed to the `NetworkBehaviour` directly. + See [PR 3099]. + [PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055 [PR 3097]: https://github.com/libp2p/rust-libp2p/pull/3097 [Issue 3107]: https://github.com/libp2p/rust-libp2p/issues/3107 From a9422483c1081be1ffe8861cd5963b69db6e1b9c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 18 Nov 2022 14:57:09 +1100 Subject: [PATCH 15/21] Remove unnecessary bounds --- swarm/src/behaviour.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 582e0c8d2a2..57c85388588 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -604,7 +604,7 @@ impl Default for CloseConnection { /// Enumeration with the list of the possible events /// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event). -pub enum FromSwarm<'a, Handler: ConnectionHandler> { +pub enum FromSwarm<'a, Handler> { /// Informs the behaviour about a newly established connection to a peer. ConnectionEstablished(ConnectionEstablished<'a>), /// Informs the behaviour about a closed connection to a peer. @@ -658,7 +658,7 @@ pub struct ConnectionEstablished<'a> { /// This event is always paired with an earlier /// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID /// and endpoint. -pub struct ConnectionClosed<'a, Handler: ConnectionHandler> { +pub struct ConnectionClosed<'a, Handler> { pub peer_id: PeerId, pub connection_id: ConnectionId, pub endpoint: &'a ConnectedPoint, @@ -745,14 +745,11 @@ pub struct ExpiredExternalAddr<'a> { pub addr: &'a Multiaddr, } -impl<'a, Handler: ConnectionHandler> FromSwarm<'a, Handler> { +impl<'a, Handler> FromSwarm<'a, Handler> { fn map_handler( self, map_handler: impl FnOnce(Handler) -> NewHandler, - ) -> FromSwarm<'a, NewHandler> - where - NewHandler: ConnectionHandler, - { + ) -> FromSwarm<'a, NewHandler> { self.maybe_map_handler(|h| Some(map_handler(h))) .expect("To return Some as all closures return Some.") } @@ -760,10 +757,7 @@ impl<'a, Handler: ConnectionHandler> FromSwarm<'a, Handler> { fn maybe_map_handler( self, map_handler: impl FnOnce(Handler) -> Option, - ) -> Option> - where - NewHandler: ConnectionHandler, - { + ) -> Option> { match self { FromSwarm::ConnectionClosed(ConnectionClosed { peer_id, From 05781343e3c403ad490b803f8003fb4e82d56d87 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 18 Nov 2022 16:23:46 +1100 Subject: [PATCH 16/21] Remove old example --- swarm/src/behaviour.rs | 51 +----------------------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 57c85388588..51d0e85dfa6 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -411,56 +411,7 @@ pub enum NetworkBehaviourAction { GenerateEvent(TOutEvent), /// Instructs the swarm to start a dial. - /// - /// On success, [`NetworkBehaviour::inject_connection_established`] is invoked. - /// On failure, [`NetworkBehaviour::inject_dial_failure`] is invoked. - /// - /// Note that the provided handler is returned to the [`NetworkBehaviour`] on connection failure - /// and connection closing. Thus it can be used to carry state, which otherwise would have to be - /// tracked in the [`NetworkBehaviour`] itself. E.g. a message destined to an unconnected peer - /// can be included in the handler, and thus directly send on connection success or extracted by - /// the [`NetworkBehaviour`] on connection failure. - /// - /// # Example carrying state in the handler - /// - /// ```rust - /// # use futures::executor::block_on; - /// # use futures::stream::StreamExt; - /// # use libp2p_core::connection::ConnectionId; - /// # use libp2p_core::identity; - /// # use libp2p_core::transport::{MemoryTransport, Transport}; - /// # use libp2p_core::upgrade::{self, DeniedUpgrade, InboundUpgrade, OutboundUpgrade}; - /// # use libp2p_core::PeerId; - /// # use libp2p_plaintext::PlainText2Config; - /// # use libp2p_swarm::{ - /// # DialError, IntoConnectionHandler, KeepAlive, NegotiatedSubstream, - /// # NetworkBehaviour, NetworkBehaviourAction, PollParameters, ConnectionHandler, - /// # ConnectionHandlerEvent, ConnectionHandlerUpgrErr, SubstreamProtocol, Swarm, SwarmEvent, - /// # }; - /// # use libp2p_swarm::dial_opts::{DialOpts, PeerCondition}; - /// # use libp2p_yamux as yamux; - /// # use std::collections::VecDeque; - /// # use std::task::{Context, Poll}; - /// # use void::Void; - /// # - /// # let local_key = identity::Keypair::generate_ed25519(); - /// # let local_public_key = local_key.public(); - /// # let local_peer_id = PeerId::from(local_public_key.clone()); - /// # - /// # let transport = MemoryTransport::default() - /// # .upgrade(upgrade::Version::V1) - /// # .authenticate(PlainText2Config { local_public_key }) - /// # .multiplex(yamux::YamuxConfig::default()) - /// # .boxed(); - /// # - /// # let mut swarm = Swarm::new(transport, MyBehaviour::default(), local_peer_id); - /// # - /// // Super precious message that we should better not lose. - /// let message = PreciousMessage("My precious message".to_string()); - /// - /// // Unfortunately this peer is offline, thus sending our message to it will fail. - /// let offline_peer = PeerId::random(); - /// + /// /// In case the dial fails, the behaviour is notified via [`NetworkBehaviour::inject_dial_failure`]. Dial { opts: DialOpts }, From f7def2b0c1cec91ef230041984c10489740cb2d3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 18 Nov 2022 18:26:01 +1100 Subject: [PATCH 17/21] fmt --- 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 51d0e85dfa6..fb280a884c0 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -411,7 +411,7 @@ pub enum NetworkBehaviourAction { GenerateEvent(TOutEvent), /// Instructs the swarm to start a dial. - /// + /// /// In case the dial fails, the behaviour is notified via [`NetworkBehaviour::inject_dial_failure`]. Dial { opts: DialOpts }, From a5a728b611557fecc5b41a47143159e921f773e2 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 18 Nov 2022 19:04:26 +1100 Subject: [PATCH 18/21] Make `new_handler` fallible --- protocols/autonat/src/behaviour.rs | 4 +-- protocols/dcutr/src/behaviour.rs | 29 ++++++++++++++-------- protocols/floodsub/src/layer.rs | 10 +++++--- protocols/gossipsub/src/behaviour.rs | 12 +++++++-- protocols/gossipsub/src/behaviour/tests.rs | 2 +- protocols/gossipsub/src/config.rs | 8 ++++-- protocols/identify/src/behaviour.rs | 15 ++++++++--- protocols/kad/src/behaviour.rs | 10 ++++---- protocols/mdns/src/behaviour.rs | 6 ++--- protocols/ping/src/lib.rs | 10 +++++--- protocols/relay/src/v2/client.rs | 8 +++--- protocols/relay/src/v2/relay.rs | 14 +++++++---- protocols/rendezvous/src/client.rs | 12 ++++++--- protocols/rendezvous/src/server.rs | 12 ++++++--- protocols/request-response/src/lib.rs | 12 ++++++--- swarm-derive/src/lib.rs | 9 ++++--- swarm/src/behaviour.rs | 6 ++++- swarm/src/behaviour/either.rs | 12 ++++----- swarm/src/behaviour/toggle.rs | 16 ++++++------ swarm/src/connection/pool.rs | 6 +++-- swarm/src/dummy.rs | 11 +++++--- swarm/src/keep_alive.rs | 11 +++++--- swarm/src/lib.rs | 1 + swarm/src/test.rs | 19 ++++++++++---- swarm/tests/swarm_derive.rs | 9 +++++-- 25 files changed, 177 insertions(+), 87 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 7290f2fa433..70cd4236e42 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -35,7 +35,7 @@ use libp2p_request_response::{ ProtocolSupport, RequestId, RequestResponse, RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }; -use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ behaviour::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, @@ -461,7 +461,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Self::ConnectionHandler { + ) -> Result { self.inner.new_handler(peer, connected_point) } diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 30bac00916e..ed24f1038ae 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -27,7 +27,8 @@ use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, + ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, + THandlerInEvent, }; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ @@ -215,7 +216,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Self::ConnectionHandler { + ) -> Result { match ( self.awaiting_direct_inbound_connections.entry(*peer), self.awaiting_direct_outbound_connections.entry(*peer), @@ -226,14 +227,16 @@ impl NetworkBehaviour for Behaviour { "Unexpected relay connection whilst awaiting direct outbound connection" ); - return Either::Left(handler::relayed::Handler::new(connected_point.clone())); + return Ok(Either::Left(handler::relayed::Handler::new( + connected_point.clone(), + ))); } let (relayed_connection_id, _) = occupied.remove(); - Either::Right(Either::Left(handler::direct::Handler::new( + Ok(Either::Right(Either::Left(handler::direct::Handler::new( relayed_connection_id, - ))) + )))) } (Entry::Occupied(occupied), Entry::Vacant(_)) => { if connected_point.is_relayed() { @@ -241,26 +244,30 @@ impl NetworkBehaviour for Behaviour { "Unexpected relay connection whilst awaiting direct inbound connection" ); - return Either::Left(handler::relayed::Handler::new(connected_point.clone())); + return Ok(Either::Left(handler::relayed::Handler::new( + connected_point.clone(), + ))); } let relayed_connection_id = occupied.remove(); - Either::Right(Either::Left(handler::direct::Handler::new( + Ok(Either::Right(Either::Left(handler::direct::Handler::new( relayed_connection_id, - ))) + )))) } (Entry::Vacant(_), Entry::Vacant(_)) => { if connected_point.is_relayed() { - Either::Left(handler::relayed::Handler::new(connected_point.clone())) + Ok(Either::Left(handler::relayed::Handler::new( + connected_point.clone(), + ))) } else { - Either::Right(Either::Right(dummy::ConnectionHandler)) + Ok(Either::Right(Either::Right(dummy::ConnectionHandler))) } } (Entry::Occupied(_), Entry::Occupied(_)) => { debug_assert!(false, "Should not have a pending outbound and pending inbound connection to same peer simultaneously"); - Either::Right(Either::Right(dummy::ConnectionHandler)) + Ok(Either::Right(Either::Right(dummy::ConnectionHandler))) } } } diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index abcfbeae30d..7e8aa28aa7b 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -27,8 +27,8 @@ use crate::FloodsubConfig; use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::ConnectionHandler; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, @@ -336,8 +336,12 @@ impl NetworkBehaviour for Floodsub { type ConnectionHandler = OneShotHandler; type OutEvent = FloodsubEvent; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - Default::default() + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { + Ok(Default::default()) } fn on_connection_handler_event( diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index ab6f0f87ba1..3e79ff7d55a 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -66,6 +66,7 @@ use crate::types::{ }; use crate::types::{GossipsubRpc, PeerConnections, PeerKind}; use crate::{rpc_proto, TopicScoreParams}; +use libp2p_swarm::behaviour::ConnectionDenied; use std::{cmp::Ordering::Equal, fmt::Debug}; use wasm_timer::Interval; @@ -3297,7 +3298,11 @@ where type ConnectionHandler = GossipsubHandler; type OutEvent = GossipsubEvent; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), @@ -3306,7 +3311,10 @@ where self.config.support_floodsub(), ); - GossipsubHandler::new(protocol_config, self.config.idle_timeout()) + Ok(GossipsubHandler::new( + protocol_config, + self.config.idle_timeout(), + )) } fn on_connection_handler_event( diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index ac0da445623..9dd7a66c9ea 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -235,7 +235,7 @@ where // peer_connections.connections should never be empty. let mut active_connections = peer_connections.connections.len(); for connection_id in peer_connections.connections.clone() { - let handler = gs.new_handler(peer_id, &fake_endpoint); + let handler = gs.new_handler(peer_id, &fake_endpoint).unwrap(); active_connections = active_connections.checked_sub(1).unwrap(); gs.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { peer_id: *peer_id, diff --git a/protocols/gossipsub/src/config.rs b/protocols/gossipsub/src/config.rs index 2af454048f3..0e4965e7fb0 100644 --- a/protocols/gossipsub/src/config.rs +++ b/protocols/gossipsub/src/config.rs @@ -995,7 +995,9 @@ mod test { let mut gossipsub: Gossipsub = Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - let handler = gossipsub.new_handler(&PeerId::random(), &fake_endpoint()); + let handler = gossipsub + .new_handler(&PeerId::random(), &fake_endpoint()) + .unwrap(); let (protocol_config, _) = handler.listen_protocol().into_upgrade(); let protocol_ids = protocol_config.protocol_info(); @@ -1023,7 +1025,9 @@ mod test { let mut gossipsub: Gossipsub = Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - let handler = gossipsub.new_handler(&PeerId::random(), &fake_endpoint()); + let handler = gossipsub + .new_handler(&PeerId::random(), &fake_endpoint()) + .unwrap(); let (protocol_config, _) = handler.listen_protocol().into_upgrade(); let protocol_ids = protocol_config.protocol_info(); diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 1c3528ef866..46d1880f62a 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -25,7 +25,8 @@ use libp2p_core::{ connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Multiaddr, PeerId, PublicKey, }; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, + ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, + THandlerInEvent, }; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, @@ -238,8 +239,16 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; type OutEvent = Event; - fn new_handler(&mut self, peer: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - Handler::new(self.config.initial_delay, self.config.interval, *peer) + fn new_handler( + &mut self, + peer: &PeerId, + _: &ConnectedPoint, + ) -> Result { + Ok(Handler::new( + self.config.initial_delay, + self.config.interval, + *peer, + )) } fn on_connection_handler_event( diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 6d1bb7eda72..4c207bb7f5d 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -41,8 +41,8 @@ use fnv::{FnvHashMap, FnvHashSet}; use instant::Instant; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredListenAddr, - FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, + AddressChange, ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, + ExpiredListenAddr, FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, }; use libp2p_swarm::{ dial_opts::{self, DialOpts}, @@ -1943,8 +1943,8 @@ where &mut self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint, - ) -> Self::ConnectionHandler { - KademliaHandler::new( + ) -> Result { + Ok(KademliaHandler::new( KademliaHandlerConfig { protocol_config: self.protocol_config.clone(), allow_listening: true, @@ -1952,7 +1952,7 @@ where }, endpoint.clone(), *remote_peer_id, - ) + )) } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 4f723e6a314..9d8c471314a 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -28,7 +28,7 @@ use crate::Config; use futures::Stream; use if_watch::IfEvent; use libp2p_core::{Multiaddr, PeerId}; -use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionDenied, FromSwarm}; use libp2p_swarm::{ dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -172,8 +172,8 @@ where &mut self, _: &PeerId, _: &libp2p_core::ConnectedPoint, - ) -> Self::ConnectionHandler { - dummy::ConnectionHandler + ) -> Result { + Ok(dummy::ConnectionHandler) } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index f1e07e2424e..e1ba31143eb 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -48,7 +48,7 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -120,8 +120,12 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; type OutEvent = Event; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - Handler::new(self.config.clone()) + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> std::result::Result { + Ok(Handler::new(self.config.clone())) } fn on_connection_handler_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) { diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index db3008bb4dc..f5aa268d380 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -35,8 +35,8 @@ use futures::ready; use futures::stream::StreamExt; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{dummy, ConnectionHandler}; use libp2p_swarm::{ @@ -159,7 +159,7 @@ impl NetworkBehaviour for Client { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Self::ConnectionHandler { + ) -> Result { if connected_point.is_relayed() { if let Some(event) = self.initial_events.remove(peer) { log::debug!( @@ -171,7 +171,7 @@ impl NetworkBehaviour for Client { } // Deny all substreams on relayed connection. - Either::Right(dummy::ConnectionHandler) + Ok(Either::Right(dummy::ConnectionHandler)) } else { let mut handler = Handler::new( self.local_peer_id, @@ -184,7 +184,7 @@ impl NetworkBehaviour for Client { handler.inject_event(event) } - Either::Left(handler) + Ok(Either::Left(handler)) } } diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 32a18e2fabd..41bde8dfed4 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -31,8 +31,8 @@ use instant::Instant; use libp2p_core::connection::ConnectionId; use libp2p_core::multiaddr::Protocol; use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ dummy, ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -254,19 +254,23 @@ impl NetworkBehaviour for Relay { type ConnectionHandler = Either; type OutEvent = Event; - fn new_handler(&mut self, _: &PeerId, endpoint: &ConnectedPoint) -> Self::ConnectionHandler { + fn new_handler( + &mut self, + _: &PeerId, + endpoint: &ConnectedPoint, + ) -> Result { if endpoint.is_relayed() { // Deny all substreams on relayed connection. - Either::Right(dummy::ConnectionHandler) + Ok(Either::Right(dummy::ConnectionHandler)) } else { - Either::Left(Handler::new( + Ok(Either::Left(Handler::new( endpoint.clone(), handler::Config { reservation_duration: self.config.reservation_duration, max_circuit_duration: self.config.max_circuit_duration, max_circuit_bytes: self.config.max_circuit_bytes, }, - )) + ))) } } diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 6da036c3c7d..44e5d4db3a9 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -32,8 +32,8 @@ use libp2p_core::connection::ConnectionId; use libp2p_core::identity::error::SigningError; use libp2p_core::identity::Keypair; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, PeerRecord}; -use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -166,10 +166,16 @@ impl NetworkBehaviour for Behaviour { SubstreamConnectionHandler; type OutEvent = Event; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { let initial_keep_alive = Duration::from_secs(30); - SubstreamConnectionHandler::new_outbound_only(initial_keep_alive) + Ok(SubstreamConnectionHandler::new_outbound_only( + initial_keep_alive, + )) } fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 79a3a1c0b9f..22a72b1f689 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -29,8 +29,8 @@ use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -112,10 +112,16 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; type OutEvent = Event; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { let initial_keep_alive = Duration::from_secs(30); - SubstreamConnectionHandler::new_inbound_only(initial_keep_alive) + Ok(SubstreamConnectionHandler::new_inbound_only( + initial_keep_alive, + )) } fn on_connection_handler_event( diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index cc232329f27..5c403429fbe 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -67,7 +67,7 @@ pub use handler::ProtocolSupport; use futures::channel::oneshot; use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, @@ -694,14 +694,18 @@ where type ConnectionHandler = RequestResponseHandler; type OutEvent = RequestResponseEvent; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - RequestResponseHandler::new( + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { + Ok(RequestResponseHandler::new( self.inbound_protocols.clone(), self.codec.clone(), self.config.connection_keep_alive, self.config.request_timeout, self.next_inbound_id.clone(), - ) + )) } fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 832f0c4e0e6..f7f004347a8 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -52,6 +52,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude }); let multiaddr = quote! { #prelude_path::Multiaddr }; + let connection_denied = quote! { #prelude_path::ConnectionDenied }; let trait_to_impl = quote! { #prelude_path::NetworkBehaviour }; let either_ident = quote! { #prelude_path::EitherOutput }; let network_behaviour_action = quote! { #prelude_path::NetworkBehaviourAction }; @@ -463,7 +464,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }; let builder = quote! { - #field_name.new_handler(peer, connected_point) + #field_name.new_handler(peer, connected_point)? }; match out_handler { @@ -558,9 +559,11 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { type ConnectionHandler = #connection_handler_ty; type OutEvent = #out_event_reference; - fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Self::ConnectionHandler { + #[allow(clippy::needless_question_mark)] + fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Result { use #connection_handler; - #new_handler + + Ok(#new_handler) } fn addresses_of_peer(&mut self, peer_id: &#peer_id) -> Vec<#multiaddr> { diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index fb280a884c0..c1eeba5c409 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -143,7 +143,7 @@ pub trait NetworkBehaviour: 'static { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Self::ConnectionHandler; + ) -> Result; /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. @@ -370,6 +370,10 @@ pub trait NetworkBehaviour: 'static { ) -> Poll>>; } +#[derive(Debug)] +#[non_exhaustive] +pub enum ConnectionDenied {} + /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. pub trait PollParameters { /// Iterator returned by [`supported_protocols`](PollParameters::supported_protocols). diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 03bb128e13e..f7ac2871dcc 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -18,10 +18,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::behaviour::THandlerInEvent; use crate::behaviour::{ self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; +use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use either::Either; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -39,11 +39,11 @@ where &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Self::ConnectionHandler { - match self { - Either::Left(a) => Either::Left(a.new_handler(peer, connected_point)), - Either::Right(b) => Either::Right(b.new_handler(peer, connected_point)), - } + ) -> Result { + Ok(match self { + Either::Left(a) => Either::Left(a.new_handler(peer, connected_point)?), + Either::Right(b) => Either::Right(b.new_handler(peer, connected_point)?), + }) } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 18ad5d4af1e..c424a5e9a42 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -18,8 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::behaviour::THandlerInEvent; use crate::behaviour::{inject_from_swarm, FromSwarm}; +use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use crate::handler::{ ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, @@ -76,13 +76,13 @@ where &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Self::ConnectionHandler { - ToggleConnectionHandler { - inner: self - .inner - .as_mut() - .map(|i| i.new_handler(peer, connected_point)), - } + ) -> Result { + Ok(ToggleConnectionHandler { + inner: match self.inner.as_mut() { + None => None, + Some(inner) => Some(inner.new_handler(peer, connected_point)?), + }, + }) } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index fa7339e09d8..40bc4e62af8 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -19,6 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::ConnectionDenied; use crate::connection::Connection; use crate::upgrade::UpgradeInfoSend; use crate::{ @@ -533,7 +534,7 @@ where /// Polls the connection pool for events. pub fn poll( &mut self, - mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> THandler, + mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> Result, cx: &mut Context<'_>, ) -> Poll> where @@ -752,7 +753,8 @@ where }, ); - let handler = new_handler_fn(&obtained_peer_id, &endpoint); + let handler = + new_handler_fn(&obtained_peer_id, &endpoint).expect("empty to empty"); let supported_protocols = handler .listen_protocol() .upgrade() diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index f91fed3f971..a1cfe910bd2 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,5 +1,6 @@ use crate::behaviour::{ - FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, }; use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -19,8 +20,12 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - ConnectionHandler + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { + Ok(ConnectionHandler) } fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index fcaf27b5d6c..651a75456f4 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -1,5 +1,6 @@ use crate::behaviour::{ - FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, }; use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -24,8 +25,12 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - ConnectionHandler + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { + Ok(ConnectionHandler) } fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 0113791b4ba..e217dea530a 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -73,6 +73,7 @@ pub mod keep_alive; pub mod derive_prelude { pub use crate::behaviour::AddressChange; pub use crate::behaviour::ConnectionClosed; + pub use crate::behaviour::ConnectionDenied; pub use crate::behaviour::ConnectionEstablished; pub use crate::behaviour::DialFailure; pub use crate::behaviour::ExpiredExternalAddr; diff --git a/swarm/src/test.rs b/swarm/src/test.rs index b28c7e3b9a9..59ab424f893 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -19,8 +19,9 @@ // DEALINGS IN THE SOFTWARE. use crate::behaviour::{ - ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, - FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, + ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, ExpiredExternalAddr, + ExpiredListenAddr, FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, + NewListener, }; use crate::{ behaviour::THandlerInEvent, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, @@ -72,8 +73,12 @@ where type ConnectionHandler = THandler; type OutEvent = TOutEvent; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - self.handler_proto.clone() + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { + Ok(self.handler_proto.clone()) } fn addresses_of_peer(&mut self, p: &PeerId) -> Vec { @@ -370,7 +375,11 @@ where type ConnectionHandler = TInner::ConnectionHandler; type OutEvent = TInner::OutEvent; - fn new_handler(&mut self, peer: &PeerId, endpoint: &ConnectedPoint) -> Self::ConnectionHandler { + fn new_handler( + &mut self, + peer: &PeerId, + endpoint: &ConnectedPoint, + ) -> Result { self.inner.new_handler(peer, endpoint) } diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 7e0896fe3db..8c1f2d7b252 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -21,6 +21,7 @@ use futures::StreamExt; use libp2p_identify as identify; use libp2p_ping as ping; +use libp2p_swarm::behaviour::ConnectionDenied; use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent}; use std::fmt::Debug; @@ -386,8 +387,12 @@ fn custom_out_event_no_type_parameters() { type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = void::Void; - fn new_handler(&mut self, _: &PeerId, _: &ConnectedPoint) -> Self::ConnectionHandler { - dummy::ConnectionHandler + fn new_handler( + &mut self, + _: &PeerId, + _: &ConnectedPoint, + ) -> Result { + Ok(dummy::ConnectionHandler) } fn on_connection_handler_event( From 19348e91839bec12ea3821771915cbdf7a28a438 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 22 Nov 2022 20:17:04 +1100 Subject: [PATCH 19/21] Allow each `NetworkBehaviour` to have their own `ConnectionDenied` reason --- examples/file-sharing.rs | 1 + misc/metrics/src/identify.rs | 6 ++- misc/metrics/src/lib.rs | 6 ++- misc/metrics/src/swarm.rs | 7 ++- protocols/autonat/Cargo.toml | 1 + protocols/autonat/src/behaviour.rs | 6 ++- protocols/dcutr/src/behaviour.rs | 7 +-- protocols/floodsub/Cargo.toml | 1 + protocols/floodsub/src/layer.rs | 6 ++- protocols/gossipsub/Cargo.toml | 26 +++++------ protocols/gossipsub/src/behaviour.rs | 5 +- protocols/identify/src/behaviour.rs | 7 +-- protocols/kad/src/behaviour.rs | 8 ++-- protocols/mdns/src/behaviour.rs | 5 +- protocols/ping/src/lib.rs | 6 ++- protocols/relay/src/v2/client.rs | 6 ++- protocols/relay/src/v2/relay.rs | 6 ++- protocols/rendezvous/src/client.rs | 8 ++-- protocols/rendezvous/src/server.rs | 5 +- protocols/rendezvous/tests/harness.rs | 23 +++++---- protocols/request-response/Cargo.toml | 1 + protocols/request-response/src/lib.rs | 6 ++- swarm-derive/src/lib.rs | 67 +++++++++++++++++++++++++-- swarm/src/behaviour.rs | 8 ++-- swarm/src/behaviour/either.rs | 14 ++++-- swarm/src/behaviour/toggle.rs | 5 +- swarm/src/connection/pool.rs | 29 +++++++++--- swarm/src/dummy.rs | 32 ++++++------- swarm/src/keep_alive.rs | 32 ++++++------- swarm/src/lib.rs | 51 ++++++++++++++++---- swarm/src/test.rs | 12 +++-- swarm/tests/swarm_derive.rs | 38 +++++++-------- 32 files changed, 296 insertions(+), 145 deletions(-) diff --git a/examples/file-sharing.rs b/examples/file-sharing.rs index 620ce6cd5d9..009b36201e9 100644 --- a/examples/file-sharing.rs +++ b/examples/file-sharing.rs @@ -408,6 +408,7 @@ mod network { &mut self, event: SwarmEvent< ComposedEvent, + ComposedBehaviourConnectionDenied, EitherError, io::Error>, >, ) { diff --git a/misc/metrics/src/identify.rs b/misc/metrics/src/identify.rs index 688c67a6190..dfde64c2672 100644 --- a/misc/metrics/src/identify.rs +++ b/misc/metrics/src/identify.rs @@ -193,8 +193,10 @@ impl super::Recorder for Metrics { } } -impl super::Recorder> for Metrics { - fn record(&self, event: &libp2p_swarm::SwarmEvent) { +impl + super::Recorder> for Metrics +{ + fn record(&self, event: &libp2p_swarm::SwarmEvent) { if let libp2p_swarm::SwarmEvent::ConnectionClosed { peer_id, num_established, diff --git a/misc/metrics/src/lib.rs b/misc/metrics/src/lib.rs index 351887260df..edd096d5061 100644 --- a/misc/metrics/src/lib.rs +++ b/misc/metrics/src/lib.rs @@ -142,8 +142,10 @@ impl Recorder for Metrics { } } -impl Recorder> for Metrics { - fn record(&self, event: &libp2p_swarm::SwarmEvent) { +impl Recorder> + for Metrics +{ + fn record(&self, event: &libp2p_swarm::SwarmEvent) { self.swarm.record(event); #[cfg(feature = "identify")] diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index c4fa8712d14..082191371fe 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -139,8 +139,10 @@ impl Metrics { } } -impl super::Recorder> for Metrics { - fn record(&self, event: &libp2p_swarm::SwarmEvent) { +impl + super::Recorder> for Metrics +{ + fn record(&self, event: &libp2p_swarm::SwarmEvent) { match event { libp2p_swarm::SwarmEvent::Behaviour(_) => {} libp2p_swarm::SwarmEvent::ConnectionEstablished { endpoint, .. } => { @@ -269,6 +271,7 @@ impl super::Recorder { self.dial_attempt.inc(); } + libp2p_swarm::SwarmEvent::ConnectionDenied { .. } => {} } } } diff --git a/protocols/autonat/Cargo.toml b/protocols/autonat/Cargo.toml index 80bbb54fcbb..b1659aae788 100644 --- a/protocols/autonat/Cargo.toml +++ b/protocols/autonat/Cargo.toml @@ -24,6 +24,7 @@ libp2p-request-response = { version = "0.23.0", path = "../request-response" } log = "0.4" rand = "0.8" prost = "0.11" +void = "1.0.2" [dev-dependencies] async-std = { version = "1.10", features = ["attributes"] } diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 70cd4236e42..45bb3660fd9 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -35,7 +35,7 @@ use libp2p_request_response::{ ProtocolSupport, RequestId, RequestResponse, RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ behaviour::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, @@ -50,6 +50,7 @@ use std::{ task::{Context, Poll}, time::Duration, }; +use void::Void; /// Config for the [`Behaviour`]. #[derive(Debug, Clone, PartialEq, Eq)] @@ -410,6 +411,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = as NetworkBehaviour>::ConnectionHandler; + type ConnectionDenied = Void; type OutEvent = Event; fn poll(&mut self, cx: &mut Context<'_>, params: &mut impl PollParameters) -> Poll { @@ -461,7 +463,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { self.inner.new_handler(peer, connected_point) } diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 7be0af12d34..f1c5894c13d 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -27,8 +27,7 @@ use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, - THandlerInEvent, + ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, }; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ @@ -39,6 +38,7 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; use thiserror::Error; +use void::Void; const MAX_NUMBER_OF_UPGRADE_ATTEMPTS: u8 = 3; @@ -210,13 +210,14 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { match ( self.awaiting_direct_inbound_connections.entry(*peer), self.awaiting_direct_outbound_connections.entry(*peer), diff --git a/protocols/floodsub/Cargo.toml b/protocols/floodsub/Cargo.toml index 70731cd3eea..79f06e25ff6 100644 --- a/protocols/floodsub/Cargo.toml +++ b/protocols/floodsub/Cargo.toml @@ -21,6 +21,7 @@ prost = "0.11" rand = "0.8" smallvec = "1.6.1" thiserror = "1.0.37" +void = "1.0.2" [build-dependencies] prost-build = "0.11" diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 7e8aa28aa7b..10b0c82d8fa 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -27,8 +27,8 @@ use crate::FloodsubConfig; use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::ConnectionHandler; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, @@ -39,6 +39,7 @@ use smallvec::SmallVec; use std::collections::hash_map::{DefaultHasher, HashMap}; use std::task::{Context, Poll}; use std::{collections::VecDeque, iter}; +use void::Void; /// Network behaviour that handles the floodsub protocol. pub struct Floodsub { @@ -334,13 +335,14 @@ impl Floodsub { impl NetworkBehaviour for Floodsub { type ConnectionHandler = OneShotHandler; + type ConnectionDenied = Void; type OutEvent = FloodsubEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(Default::default()) } diff --git a/protocols/gossipsub/Cargo.toml b/protocols/gossipsub/Cargo.toml index 6ab3a8c1df3..1005dac5a89 100644 --- a/protocols/gossipsub/Cargo.toml +++ b/protocols/gossipsub/Cargo.toml @@ -11,29 +11,29 @@ keywords = ["peer-to-peer", "libp2p", "networking"] categories = ["network-programming", "asynchronous"] [dependencies] -libp2p-swarm = { version = "0.41.0", path = "../../swarm" } -libp2p-core = { version = "0.38.0", path = "../../core" } -bytes = "1.0" +asynchronous-codec = "0.6" +base64 = "0.13.0" byteorder = "1.3.4" +bytes = "1.0" fnv = "1.0.7" futures = "0.3.5" -rand = "0.8" -asynchronous-codec = "0.6" -unsigned-varint = { version = "0.7.0", features = ["asynchronous_codec"] } +hex_fmt = "0.3.0" +instant = "0.1.11" +libp2p-core = { version = "0.38.0", path = "../../core" } +libp2p-swarm = { version = "0.41.0", path = "../../swarm" } log = "0.4.11" -sha2 = "0.10.0" -base64 = "0.13.0" -smallvec = "1.6.1" +prometheus-client = "0.18.0" # Metrics dependencies prost = "0.11" prost-codec = { version = "0.3", path = "../../misc/prost-codec" } -hex_fmt = "0.3.0" +rand = "0.8" regex = "1.5.5" serde = { version = "1", optional = true, features = ["derive"] } +sha2 = "0.10.0" +smallvec = "1.6.1" thiserror = "1.0" +unsigned-varint = { version = "0.7.0", features = ["asynchronous_codec"] } +void = "1.0.2" wasm-timer = "0.2.5" -instant = "0.1.11" -# Metrics dependencies -prometheus-client = "0.18.0" [dev-dependencies] async-std = "1.6.3" diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 3e79ff7d55a..d012c732a75 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -35,6 +35,7 @@ use log::{debug, error, trace, warn}; use prometheus_client::registry::Registry; use prost::Message; use rand::{seq::SliceRandom, thread_rng}; +use void::Void; use libp2p_core::{ connection::ConnectionId, identity::Keypair, multiaddr::Protocol::Ip4, @@ -66,7 +67,6 @@ use crate::types::{ }; use crate::types::{GossipsubRpc, PeerConnections, PeerKind}; use crate::{rpc_proto, TopicScoreParams}; -use libp2p_swarm::behaviour::ConnectionDenied; use std::{cmp::Ordering::Equal, fmt::Debug}; use wasm_timer::Interval; @@ -3296,13 +3296,14 @@ where F: Send + 'static + TopicSubscriptionFilter, { type ConnectionHandler = GossipsubHandler; + type ConnectionDenied = Void; type OutEvent = GossipsubEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 46d1880f62a..0ec1eb0a4b3 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -25,8 +25,7 @@ use libp2p_core::{ connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Multiaddr, PeerId, PublicKey, }; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, - THandlerInEvent, + ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, }; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, @@ -42,6 +41,7 @@ use std::{ task::Poll, time::Duration, }; +use void::Void; /// Network behaviour that automatically identifies nodes periodically, returns information /// about them, and answers identify queries from other nodes. @@ -237,13 +237,14 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, peer: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(Handler::new( self.config.initial_delay, self.config.interval, diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 4c207bb7f5d..656b8846ece 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -41,8 +41,8 @@ use fnv::{FnvHashMap, FnvHashSet}; use instant::Instant; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - AddressChange, ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, - ExpiredListenAddr, FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, + AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredListenAddr, + FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, }; use libp2p_swarm::{ dial_opts::{self, DialOpts}, @@ -57,6 +57,7 @@ use std::task::{Context, Poll}; use std::vec; use std::{borrow::Cow, time::Duration}; use thiserror::Error; +use void::Void; pub use crate::query::QueryStats; @@ -1937,13 +1938,14 @@ where TStore: Send + 'static, { type ConnectionHandler = KademliaHandler; + type ConnectionDenied = Void; type OutEvent = KademliaEvent; fn new_handler( &mut self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(KademliaHandler::new( KademliaHandlerConfig { protocol_config: self.protocol_config.clone(), diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 9d8c471314a..dcd9960fd66 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -28,7 +28,7 @@ use crate::Config; use futures::Stream; use if_watch::IfEvent; use libp2p_core::{Multiaddr, PeerId}; -use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionDenied, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -166,13 +166,14 @@ where P: Provider, { type ConnectionHandler = dummy::ConnectionHandler; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &libp2p_core::ConnectedPoint, - ) -> Result { + ) -> Result { Ok(dummy::ConnectionHandler) } diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index e1ba31143eb..6e3f6469892 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -48,7 +48,7 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -56,6 +56,7 @@ use std::{ collections::VecDeque, task::{Context, Poll}, }; +use void::Void; #[deprecated(since = "0.39.1", note = "Use libp2p::ping::Config instead.")] pub type PingConfig = Config; @@ -118,13 +119,14 @@ impl Default for Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> std::result::Result { + ) -> std::result::Result { Ok(Handler::new(self.config.clone())) } diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index f5aa268d380..72fe027130d 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -35,8 +35,8 @@ use futures::ready; use futures::stream::StreamExt; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{dummy, ConnectionHandler}; use libp2p_swarm::{ @@ -48,6 +48,7 @@ use std::io::{Error, ErrorKind, IoSlice}; use std::ops::DerefMut; use std::pin::Pin; use std::task::{Context, Poll}; +use void::Void; /// The events produced by the [`Client`] behaviour. #[derive(Debug)] @@ -153,13 +154,14 @@ impl Client { impl NetworkBehaviour for Client { type ConnectionHandler = Either; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { if connected_point.is_relayed() { if let Some(event) = self.initial_events.remove(peer) { log::debug!( diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 41bde8dfed4..905d8f0cdc9 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -31,8 +31,8 @@ use instant::Instant; use libp2p_core::connection::ConnectionId; use libp2p_core::multiaddr::Protocol; use libp2p_core::{ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ dummy, ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -42,6 +42,7 @@ use std::num::NonZeroU32; use std::ops::Add; use std::task::{Context, Poll}; use std::time::Duration; +use void::Void; use super::protocol::outbound_stop; @@ -252,13 +253,14 @@ impl Relay { impl NetworkBehaviour for Relay { type ConnectionHandler = Either; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result { if endpoint.is_relayed() { // Deny all substreams on relayed connection. Ok(Either::Right(dummy::ConnectionHandler)) diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 4a92d6339ed..363db55bf17 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -32,8 +32,8 @@ use libp2p_core::connection::ConnectionId; use libp2p_core::identity::error::SigningError; use libp2p_core::identity::Keypair; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, PeerRecord}; +use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; -use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -162,15 +162,15 @@ pub enum Event { } impl NetworkBehaviour for Behaviour { - type ConnectionHandler = - SubstreamConnectionHandler; + type ConnectionHandler = SubstreamConnectionHandler; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { let initial_keep_alive = Duration::from_secs(30); Ok(SubstreamConnectionHandler::new_outbound_only( diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 22a72b1f689..031e95a94b2 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -29,8 +29,8 @@ use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; -use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -110,13 +110,14 @@ pub enum Event { impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; + type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { let initial_keep_alive = Duration::from_secs(30); Ok(SubstreamConnectionHandler::new_inbound_only( diff --git a/protocols/rendezvous/tests/harness.rs b/protocols/rendezvous/tests/harness.rs index 523f34c76db..04477a63db0 100644 --- a/protocols/rendezvous/tests/harness.rs +++ b/protocols/rendezvous/tests/harness.rs @@ -64,11 +64,11 @@ fn get_rand_memory_address() -> Multiaddr { .unwrap() } -pub async fn await_event_or_timeout( - swarm: &mut (impl Stream> + FusedStream + Unpin), -) -> SwarmEvent +pub async fn await_event_or_timeout( + swarm: &mut (impl Stream> + FusedStream + Unpin), +) -> SwarmEvent where - SwarmEvent: Debug, + SwarmEvent: Debug, { tokio::time::timeout( Duration::from_secs(30), @@ -80,13 +80,16 @@ where .expect("network behaviour to emit an event within 30 seconds") } -pub async fn await_events_or_timeout( - swarm_1: &mut (impl Stream> + FusedStream + Unpin), - swarm_2: &mut (impl Stream> + FusedStream + Unpin), -) -> (SwarmEvent, SwarmEvent) +pub async fn await_events_or_timeout( + swarm_1: &mut (impl Stream> + FusedStream + Unpin), + swarm_2: &mut (impl Stream> + FusedStream + Unpin), +) -> ( + SwarmEvent, + SwarmEvent, +) where - SwarmEvent: Debug, - SwarmEvent: Debug, + SwarmEvent: Debug, + SwarmEvent: Debug, { tokio::time::timeout( Duration::from_secs(30), diff --git a/protocols/request-response/Cargo.toml b/protocols/request-response/Cargo.toml index 4069873d280..3ef9a512c90 100644 --- a/protocols/request-response/Cargo.toml +++ b/protocols/request-response/Cargo.toml @@ -21,6 +21,7 @@ log = "0.4.11" rand = "0.8" smallvec = "1.6.1" unsigned-varint = { version = "0.7", features = ["std", "futures"] } +void = "1.0.2" [dev-dependencies] async-std = "1.6.2" diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 5c403429fbe..88758ac5f71 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -67,7 +67,7 @@ pub use handler::ProtocolSupport; use futures::channel::oneshot; use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, @@ -81,6 +81,7 @@ use std::{ task::{Context, Poll}, time::Duration, }; +use void::Void; /// An inbound request or response. #[derive(Debug)] @@ -692,13 +693,14 @@ where TCodec: RequestResponseCodec + Send + Clone + 'static, { type ConnectionHandler = RequestResponseHandler; + type ConnectionDenied = Void; type OutEvent = RequestResponseEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(RequestResponseHandler::new( self.inbound_protocols.clone(), self.codec.clone(), diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index f7f004347a8..4609c4140c7 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -52,7 +52,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude }); let multiaddr = quote! { #prelude_path::Multiaddr }; - let connection_denied = quote! { #prelude_path::ConnectionDenied }; let trait_to_impl = quote! { #prelude_path::NetworkBehaviour }; let either_ident = quote! { #prelude_path::EitherOutput }; let network_behaviour_action = quote! { #prelude_path::NetworkBehaviourAction }; @@ -145,6 +144,56 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } }; + let (connection_denied_ty, connection_denied_ty_definition) = { + let name: syn::Type = + syn::parse_str(&(ast.ident.to_string() + "ConnectionDenied")).unwrap(); + let definition = { + let fields = data_struct + .fields + .iter() + .map(|field| { + let variant: syn::Variant = syn::parse_str( + &field + .ident + .clone() + .expect("Fields of NetworkBehaviour implementation to be named.") + .to_string() + .to_upper_camel_case(), + ) + .unwrap(); + let ty = &field.ty; + quote! {#variant(<#ty as #trait_to_impl>::ConnectionDenied)} + }) + .collect::>(); + let visibility = &ast.vis; + + Some(quote! { + #visibility enum #name #impl_generics + #where_clause + { + #(#fields),* + } + + impl #impl_generics ::std::fmt::Debug for #name #ty_generics #where_clause { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.debug_struct("#name").finish() + } + } + + impl #impl_generics ::std::fmt::Display for #name #ty_generics #where_clause { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + Ok(()) + } + } + + impl #impl_generics ::std::error::Error for #name #ty_generics #where_clause { + // TODO: Implement `source` + } + }) + }; + (name, definition) + }; + // Build the `where ...` clause of the trait implementation. let where_clause = { let additional = data_struct @@ -463,8 +512,18 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { None => quote! { self.#field_n }, }; + let variant_name: syn::Variant = syn::parse_str( + &field + .ident + .clone() + .expect("Fields of NetworkBehaviour implementation to be named.") + .to_string() + .to_upper_camel_case(), + ) + .unwrap(); + let builder = quote! { - #field_name.new_handler(peer, connected_point)? + #field_name.new_handler(peer, connected_point).map_err(#connection_denied_ty::#variant_name)? }; match out_handler { @@ -552,15 +611,17 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { // Now the magic happens. let final_quote = quote! { #out_event_definition + #connection_denied_ty_definition impl #impl_generics #trait_to_impl for #name #ty_generics #where_clause { type ConnectionHandler = #connection_handler_ty; + type ConnectionDenied = #connection_denied_ty #ty_generics; type OutEvent = #out_event_reference; #[allow(clippy::needless_question_mark)] - fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Result { + fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Result { use #connection_handler; Ok(#new_handler) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index c1eeba5c409..6abf94c140a 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -120,6 +120,8 @@ pub trait NetworkBehaviour: 'static { /// Handler for all the protocols the network behaviour supports. type ConnectionHandler: ConnectionHandler; + type ConnectionDenied: std::error::Error + Send + 'static; + /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; @@ -143,7 +145,7 @@ pub trait NetworkBehaviour: 'static { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result; + ) -> Result; /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. @@ -370,10 +372,6 @@ pub trait NetworkBehaviour: 'static { ) -> Poll>>; } -#[derive(Debug)] -#[non_exhaustive] -pub enum ConnectionDenied {} - /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. pub trait PollParameters { /// Iterator returned by [`supported_protocols`](PollParameters::supported_protocols). diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index f7ac2871dcc..869a0058057 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -18,10 +18,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::THandlerInEvent; use crate::behaviour::{ self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; -use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use either::Either; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -33,16 +33,22 @@ where R: NetworkBehaviour, { type ConnectionHandler = Either; + type ConnectionDenied = Either; type OutEvent = Either; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(match self { - Either::Left(a) => Either::Left(a.new_handler(peer, connected_point)?), - Either::Right(b) => Either::Right(b.new_handler(peer, connected_point)?), + Either::Left(a) => { + Either::Left(a.new_handler(peer, connected_point).map_err(Either::Left)?) + } + Either::Right(b) => Either::Right( + b.new_handler(peer, connected_point) + .map_err(Either::Right)?, + ), }) } diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index c424a5e9a42..f1707da3c0e 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -18,8 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::THandlerInEvent; use crate::behaviour::{inject_from_swarm, FromSwarm}; -use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use crate::handler::{ ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, @@ -70,13 +70,14 @@ where TBehaviour: NetworkBehaviour, { type ConnectionHandler = ToggleConnectionHandler; + type ConnectionDenied = TBehaviour::ConnectionDenied; type OutEvent = TBehaviour::OutEvent; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(ToggleConnectionHandler { inner: match self.inner.as_mut() { None => None, diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 40bc4e62af8..380be8d6051 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -19,7 +19,6 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::behaviour::ConnectionDenied; use crate::connection::Connection; use crate::upgrade::UpgradeInfoSend; use crate::{ @@ -216,7 +215,7 @@ impl fmt::Debug for Pool +pub enum PoolEvent where TTrans: Transport, { @@ -260,6 +259,13 @@ where handler: THandler, }, + ConnectionDenied { + id: ConnectionId, + peer_id: PeerId, + endpoint: ConnectedPoint, + reason: TReason, + }, + /// An outbound connection attempt failed. PendingOutboundConnectionError { /// The ID of the failed connection. @@ -532,11 +538,11 @@ where } /// Polls the connection pool for events. - pub fn poll( + pub fn poll( &mut self, - mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> Result, + mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> Result, cx: &mut Context<'_>, - ) -> Poll> + ) -> Poll> where TTrans: Transport, THandler: ConnectionHandler + 'static, @@ -753,8 +759,17 @@ where }, ); - let handler = - new_handler_fn(&obtained_peer_id, &endpoint).expect("empty to empty"); + let handler = match new_handler_fn(&obtained_peer_id, &endpoint) { + Ok(handler) => handler, + Err(reason) => { + return Poll::Ready(PoolEvent::ConnectionDenied { + id, + peer_id: obtained_peer_id, + endpoint, + reason, + }) + } + }; let supported_protocols = handler .listen_protocol() .upgrade() diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index a1cfe910bd2..3e9cb35ac73 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,6 +1,5 @@ use crate::behaviour::{ - ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerInEvent, + FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -18,29 +17,17 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; + type ConnectionDenied = Void; type OutEvent = Void; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(ConnectionHandler) } - fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { - void::unreachable(event) - } - - fn poll( - &mut self, - _: &mut Context<'_>, - _: &mut impl PollParameters, - ) -> Poll>> - { - Poll::Pending - } - fn on_swarm_event(&mut self, event: FromSwarm) { match event { FromSwarm::ConnectionEstablished(_) @@ -57,6 +44,19 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredExternalAddr(_) => {} } } + + fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + void::unreachable(event) + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> + { + Poll::Pending + } } /// An implementation of [`ConnectionHandler`] that neither handles any protocols nor does it keep the connection alive. diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index 651a75456f4..d3192eb8e3c 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -1,6 +1,5 @@ use crate::behaviour::{ - ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerInEvent, + FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -23,29 +22,17 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; + type ConnectionDenied = Void; type OutEvent = Void; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(ConnectionHandler) } - fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { - void::unreachable(event) - } - - fn poll( - &mut self, - _: &mut Context<'_>, - _: &mut impl PollParameters, - ) -> Poll>> - { - Poll::Pending - } - fn on_swarm_event(&mut self, event: FromSwarm) { match event { FromSwarm::ConnectionEstablished(_) @@ -62,6 +49,19 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredExternalAddr(_) => {} } } + + fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + void::unreachable(event) + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> + { + Poll::Pending + } } /// Implementation of [`ConnectionHandler`] that doesn't handle anything but keeps the connection alive. diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 5f6269c34d9..40bf8d69b81 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -73,7 +73,6 @@ pub mod keep_alive; pub mod derive_prelude { pub use crate::behaviour::AddressChange; pub use crate::behaviour::ConnectionClosed; - pub use crate::behaviour::ConnectionDenied; pub use crate::behaviour::ConnectionEstablished; pub use crate::behaviour::DialFailure; pub use crate::behaviour::ExpiredExternalAddr; @@ -169,7 +168,7 @@ type THandlerErr = as ConnectionHandler>::Erro /// Event generated by the `Swarm`. #[derive(Debug)] -pub enum SwarmEvent { +pub enum SwarmEvent { /// Event generated by the `NetworkBehaviour`. Behaviour(TBehaviourOutEvent), /// A connection to the given peer has been opened. @@ -186,6 +185,15 @@ pub enum SwarmEvent { /// of dial attempts that failed before the one successful dial. concurrent_dial_errors: Option)>>, }, + /// A connection to the given peer has been opened. + ConnectionDenied { + /// Identity of the peer that we have connected to. + peer_id: PeerId, + /// Endpoint of the connection that has been opened. + endpoint: ConnectedPoint, + /// The reason why the connection was denied. + reason: TReason, + }, /// A connection with the given peer has been closed, /// possibly as a result of an error. ConnectionClosed { @@ -772,8 +780,14 @@ where fn handle_pool_event( &mut self, - event: PoolEvent, transport::Boxed<(PeerId, StreamMuxerBox)>>, - ) -> Option>> { + event: PoolEvent< + THandler, + transport::Boxed<(PeerId, StreamMuxerBox)>, + TBehaviour::ConnectionDenied, + >, + ) -> Option< + SwarmEvent>, + > { match event { PoolEvent::ConnectionEstablished { peer_id, @@ -932,6 +946,18 @@ where ); } } + PoolEvent::ConnectionDenied { + peer_id, + endpoint, + reason, + .. + } => { + return Some(SwarmEvent::ConnectionDenied { + peer_id, + endpoint, + reason, + }) + } } None @@ -943,7 +969,9 @@ where as Transport>::ListenerUpgrade, io::Error, >, - ) -> Option>> { + ) -> Option< + SwarmEvent>, + > { match event { TransportEvent::Incoming { listener_id: _, @@ -1045,7 +1073,9 @@ where fn handle_behaviour_event( &mut self, event: NetworkBehaviourAction>, - ) -> Option>> { + ) -> Option< + SwarmEvent>, + > { match event { NetworkBehaviourAction::GenerateEvent(event) => { return Some(SwarmEvent::Behaviour(event)) @@ -1131,7 +1161,8 @@ where fn poll_next_event( mut self: Pin<&mut Self>, cx: &mut Context<'_>, - ) -> Poll>> { + ) -> Poll>> + { // We use a `this` variable because the compiler can't mutably borrow multiple times // across a `Deref`. let this = &mut *self; @@ -1328,7 +1359,11 @@ impl Stream for Swarm where TBehaviour: NetworkBehaviour, { - type Item = SwarmEvent, THandlerErr>; + type Item = SwarmEvent< + TBehaviourOutEvent, + TBehaviour::ConnectionDenied, + THandlerErr, + >; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().poll_next_event(cx).map(Some) diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 59ab424f893..106aaceb4df 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -19,9 +19,8 @@ // DEALINGS IN THE SOFTWARE. use crate::behaviour::{ - ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, ExpiredExternalAddr, - ExpiredListenAddr, FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, - NewListener, + ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, + FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, }; use crate::{ behaviour::THandlerInEvent, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, @@ -32,6 +31,7 @@ use libp2p_core::{ }; use std::collections::HashMap; use std::task::{Context, Poll}; +use void::Void; /// A `MockBehaviour` is a `NetworkBehaviour` that allows for /// the instrumentation of return values, without keeping @@ -71,13 +71,14 @@ where TOutEvent: Send + 'static, { type ConnectionHandler = THandler; + type ConnectionDenied = Void; type OutEvent = TOutEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(self.handler_proto.clone()) } @@ -373,13 +374,14 @@ where ::OutEvent: Clone, { type ConnectionHandler = TInner::ConnectionHandler; + type ConnectionDenied = TInner::ConnectionDenied; type OutEvent = TInner::OutEvent; fn new_handler( &mut self, peer: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result { self.inner.new_handler(peer, endpoint) } diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 8c1f2d7b252..5429181591a 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -21,7 +21,6 @@ use futures::StreamExt; use libp2p_identify as identify; use libp2p_ping as ping; -use libp2p_swarm::behaviour::ConnectionDenied; use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent}; use std::fmt::Debug; @@ -385,16 +384,34 @@ fn custom_out_event_no_type_parameters() { impl NetworkBehaviour for TemplatedBehaviour { type ConnectionHandler = dummy::ConnectionHandler; + type ConnectionDenied = void::Void; type OutEvent = void::Void; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(dummy::ConnectionHandler) } + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(_) + | FromSwarm::ConnectionClosed(_) + | FromSwarm::AddressChange(_) + | FromSwarm::DialFailure(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } + fn on_connection_handler_event( &mut self, _peer: PeerId, @@ -412,23 +429,6 @@ fn custom_out_event_no_type_parameters() { { Poll::Pending } - - fn on_swarm_event(&mut self, event: FromSwarm) { - match event { - FromSwarm::ConnectionEstablished(_) - | FromSwarm::ConnectionClosed(_) - | FromSwarm::AddressChange(_) - | FromSwarm::DialFailure(_) - | FromSwarm::ListenFailure(_) - | FromSwarm::NewListener(_) - | FromSwarm::NewListenAddr(_) - | FromSwarm::ExpiredListenAddr(_) - | FromSwarm::ListenerError(_) - | FromSwarm::ListenerClosed(_) - | FromSwarm::NewExternalAddr(_) - | FromSwarm::ExpiredExternalAddr(_) => {} - } - } } #[derive(NetworkBehaviour)] From a269e9d36e31635fd628bfc114b087810a696c6c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 7 Dec 2022 12:36:53 +1100 Subject: [PATCH 20/21] Revert "Allow each `NetworkBehaviour` to have their own `ConnectionDenied` reason" This reverts commit 19348e91839bec12ea3821771915cbdf7a28a438. --- examples/file-sharing.rs | 1 - misc/metrics/src/identify.rs | 6 +-- misc/metrics/src/lib.rs | 6 +-- misc/metrics/src/swarm.rs | 7 +-- protocols/autonat/Cargo.toml | 1 - protocols/autonat/src/behaviour.rs | 6 +-- protocols/dcutr/src/behaviour.rs | 7 ++- protocols/floodsub/Cargo.toml | 1 - protocols/floodsub/src/layer.rs | 6 +-- protocols/gossipsub/Cargo.toml | 26 +++++------ protocols/gossipsub/src/behaviour.rs | 5 +- protocols/identify/src/behaviour.rs | 7 ++- protocols/kad/src/behaviour.rs | 8 ++-- protocols/mdns/src/behaviour.rs | 5 +- protocols/ping/src/lib.rs | 6 +-- protocols/relay/src/v2/client.rs | 6 +-- protocols/relay/src/v2/relay.rs | 6 +-- protocols/rendezvous/src/client.rs | 8 ++-- protocols/rendezvous/src/server.rs | 5 +- protocols/rendezvous/tests/harness.rs | 23 ++++----- protocols/request-response/Cargo.toml | 1 - protocols/request-response/src/lib.rs | 6 +-- swarm-derive/src/lib.rs | 67 ++------------------------- swarm/src/behaviour.rs | 8 ++-- swarm/src/behaviour/either.rs | 14 ++---- swarm/src/behaviour/toggle.rs | 5 +- swarm/src/connection/pool.rs | 29 +++--------- swarm/src/dummy.rs | 32 ++++++------- swarm/src/keep_alive.rs | 32 ++++++------- swarm/src/lib.rs | 51 ++++---------------- swarm/src/test.rs | 12 ++--- swarm/tests/swarm_derive.rs | 38 +++++++-------- 32 files changed, 145 insertions(+), 296 deletions(-) diff --git a/examples/file-sharing.rs b/examples/file-sharing.rs index 6271aa7d293..ef7d1fdf57d 100644 --- a/examples/file-sharing.rs +++ b/examples/file-sharing.rs @@ -408,7 +408,6 @@ mod network { &mut self, event: SwarmEvent< ComposedEvent, - ComposedBehaviourConnectionDenied, EitherError, io::Error>, >, ) { diff --git a/misc/metrics/src/identify.rs b/misc/metrics/src/identify.rs index dfde64c2672..688c67a6190 100644 --- a/misc/metrics/src/identify.rs +++ b/misc/metrics/src/identify.rs @@ -193,10 +193,8 @@ impl super::Recorder for Metrics { } } -impl - super::Recorder> for Metrics -{ - fn record(&self, event: &libp2p_swarm::SwarmEvent) { +impl super::Recorder> for Metrics { + fn record(&self, event: &libp2p_swarm::SwarmEvent) { if let libp2p_swarm::SwarmEvent::ConnectionClosed { peer_id, num_established, diff --git a/misc/metrics/src/lib.rs b/misc/metrics/src/lib.rs index edd096d5061..351887260df 100644 --- a/misc/metrics/src/lib.rs +++ b/misc/metrics/src/lib.rs @@ -142,10 +142,8 @@ impl Recorder for Metrics { } } -impl Recorder> - for Metrics -{ - fn record(&self, event: &libp2p_swarm::SwarmEvent) { +impl Recorder> for Metrics { + fn record(&self, event: &libp2p_swarm::SwarmEvent) { self.swarm.record(event); #[cfg(feature = "identify")] diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index 082191371fe..c4fa8712d14 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -139,10 +139,8 @@ impl Metrics { } } -impl - super::Recorder> for Metrics -{ - fn record(&self, event: &libp2p_swarm::SwarmEvent) { +impl super::Recorder> for Metrics { + fn record(&self, event: &libp2p_swarm::SwarmEvent) { match event { libp2p_swarm::SwarmEvent::Behaviour(_) => {} libp2p_swarm::SwarmEvent::ConnectionEstablished { endpoint, .. } => { @@ -271,7 +269,6 @@ impl libp2p_swarm::SwarmEvent::Dialing(_) => { self.dial_attempt.inc(); } - libp2p_swarm::SwarmEvent::ConnectionDenied { .. } => {} } } } diff --git a/protocols/autonat/Cargo.toml b/protocols/autonat/Cargo.toml index b1659aae788..80bbb54fcbb 100644 --- a/protocols/autonat/Cargo.toml +++ b/protocols/autonat/Cargo.toml @@ -24,7 +24,6 @@ libp2p-request-response = { version = "0.23.0", path = "../request-response" } log = "0.4" rand = "0.8" prost = "0.11" -void = "1.0.2" [dev-dependencies] async-std = { version = "1.10", features = ["attributes"] } diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 45bb3660fd9..70cd4236e42 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -35,7 +35,7 @@ use libp2p_request_response::{ ProtocolSupport, RequestId, RequestResponse, RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }; -use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ behaviour::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, @@ -50,7 +50,6 @@ use std::{ task::{Context, Poll}, time::Duration, }; -use void::Void; /// Config for the [`Behaviour`]. #[derive(Debug, Clone, PartialEq, Eq)] @@ -411,7 +410,6 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = as NetworkBehaviour>::ConnectionHandler; - type ConnectionDenied = Void; type OutEvent = Event; fn poll(&mut self, cx: &mut Context<'_>, params: &mut impl PollParameters) -> Poll { @@ -463,7 +461,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { self.inner.new_handler(peer, connected_point) } diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index f1c5894c13d..7be0af12d34 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -27,7 +27,8 @@ use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, + ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, + THandlerInEvent, }; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ @@ -38,7 +39,6 @@ use std::collections::hash_map::Entry; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; use thiserror::Error; -use void::Void; const MAX_NUMBER_OF_UPGRADE_ATTEMPTS: u8 = 3; @@ -210,14 +210,13 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { match ( self.awaiting_direct_inbound_connections.entry(*peer), self.awaiting_direct_outbound_connections.entry(*peer), diff --git a/protocols/floodsub/Cargo.toml b/protocols/floodsub/Cargo.toml index 79f06e25ff6..70731cd3eea 100644 --- a/protocols/floodsub/Cargo.toml +++ b/protocols/floodsub/Cargo.toml @@ -21,7 +21,6 @@ prost = "0.11" rand = "0.8" smallvec = "1.6.1" thiserror = "1.0.37" -void = "1.0.2" [build-dependencies] prost-build = "0.11" diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 10b0c82d8fa..7e8aa28aa7b 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -27,8 +27,8 @@ use crate::FloodsubConfig; use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::ConnectionHandler; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, @@ -39,7 +39,6 @@ use smallvec::SmallVec; use std::collections::hash_map::{DefaultHasher, HashMap}; use std::task::{Context, Poll}; use std::{collections::VecDeque, iter}; -use void::Void; /// Network behaviour that handles the floodsub protocol. pub struct Floodsub { @@ -335,14 +334,13 @@ impl Floodsub { impl NetworkBehaviour for Floodsub { type ConnectionHandler = OneShotHandler; - type ConnectionDenied = Void; type OutEvent = FloodsubEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(Default::default()) } diff --git a/protocols/gossipsub/Cargo.toml b/protocols/gossipsub/Cargo.toml index 1005dac5a89..6ab3a8c1df3 100644 --- a/protocols/gossipsub/Cargo.toml +++ b/protocols/gossipsub/Cargo.toml @@ -11,29 +11,29 @@ keywords = ["peer-to-peer", "libp2p", "networking"] categories = ["network-programming", "asynchronous"] [dependencies] -asynchronous-codec = "0.6" -base64 = "0.13.0" -byteorder = "1.3.4" +libp2p-swarm = { version = "0.41.0", path = "../../swarm" } +libp2p-core = { version = "0.38.0", path = "../../core" } bytes = "1.0" +byteorder = "1.3.4" fnv = "1.0.7" futures = "0.3.5" -hex_fmt = "0.3.0" -instant = "0.1.11" -libp2p-core = { version = "0.38.0", path = "../../core" } -libp2p-swarm = { version = "0.41.0", path = "../../swarm" } +rand = "0.8" +asynchronous-codec = "0.6" +unsigned-varint = { version = "0.7.0", features = ["asynchronous_codec"] } log = "0.4.11" -prometheus-client = "0.18.0" # Metrics dependencies +sha2 = "0.10.0" +base64 = "0.13.0" +smallvec = "1.6.1" prost = "0.11" prost-codec = { version = "0.3", path = "../../misc/prost-codec" } -rand = "0.8" +hex_fmt = "0.3.0" regex = "1.5.5" serde = { version = "1", optional = true, features = ["derive"] } -sha2 = "0.10.0" -smallvec = "1.6.1" thiserror = "1.0" -unsigned-varint = { version = "0.7.0", features = ["asynchronous_codec"] } -void = "1.0.2" wasm-timer = "0.2.5" +instant = "0.1.11" +# Metrics dependencies +prometheus-client = "0.18.0" [dev-dependencies] async-std = "1.6.3" diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index d012c732a75..3e79ff7d55a 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -35,7 +35,6 @@ use log::{debug, error, trace, warn}; use prometheus_client::registry::Registry; use prost::Message; use rand::{seq::SliceRandom, thread_rng}; -use void::Void; use libp2p_core::{ connection::ConnectionId, identity::Keypair, multiaddr::Protocol::Ip4, @@ -67,6 +66,7 @@ use crate::types::{ }; use crate::types::{GossipsubRpc, PeerConnections, PeerKind}; use crate::{rpc_proto, TopicScoreParams}; +use libp2p_swarm::behaviour::ConnectionDenied; use std::{cmp::Ordering::Equal, fmt::Debug}; use wasm_timer::Interval; @@ -3296,14 +3296,13 @@ where F: Send + 'static + TopicSubscriptionFilter, { type ConnectionHandler = GossipsubHandler; - type ConnectionDenied = Void; type OutEvent = GossipsubEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 0ec1eb0a4b3..46d1880f62a 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -25,7 +25,8 @@ use libp2p_core::{ connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Multiaddr, PeerId, PublicKey, }; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, + ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, + THandlerInEvent, }; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, @@ -41,7 +42,6 @@ use std::{ task::Poll, time::Duration, }; -use void::Void; /// Network behaviour that automatically identifies nodes periodically, returns information /// about them, and answers identify queries from other nodes. @@ -237,14 +237,13 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, peer: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(Handler::new( self.config.initial_delay, self.config.interval, diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 138ca7e710e..bc5a69b2316 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -41,8 +41,8 @@ use fnv::{FnvHashMap, FnvHashSet}; use instant::Instant; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredListenAddr, - FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, + AddressChange, ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, + ExpiredListenAddr, FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, }; use libp2p_swarm::{ dial_opts::{self, DialOpts}, @@ -57,7 +57,6 @@ use std::task::{Context, Poll}; use std::vec; use std::{borrow::Cow, time::Duration}; use thiserror::Error; -use void::Void; pub use crate::query::QueryStats; @@ -1974,14 +1973,13 @@ where TStore: Send + 'static, { type ConnectionHandler = KademliaHandler; - type ConnectionDenied = Void; type OutEvent = KademliaEvent; fn new_handler( &mut self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(KademliaHandler::new( KademliaHandlerConfig { protocol_config: self.protocol_config.clone(), diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index dcd9960fd66..9d8c471314a 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -28,7 +28,7 @@ use crate::Config; use futures::Stream; use if_watch::IfEvent; use libp2p_core::{Multiaddr, PeerId}; -use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionDenied, FromSwarm}; use libp2p_swarm::{ dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -166,14 +166,13 @@ where P: Provider, { type ConnectionHandler = dummy::ConnectionHandler; - type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &libp2p_core::ConnectedPoint, - ) -> Result { + ) -> Result { Ok(dummy::ConnectionHandler) } diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 6e3f6469892..e1ba31143eb 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -48,7 +48,7 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -56,7 +56,6 @@ use std::{ collections::VecDeque, task::{Context, Poll}, }; -use void::Void; #[deprecated(since = "0.39.1", note = "Use libp2p::ping::Config instead.")] pub type PingConfig = Config; @@ -119,14 +118,13 @@ impl Default for Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> std::result::Result { + ) -> std::result::Result { Ok(Handler::new(self.config.clone())) } diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 72fe027130d..f5aa268d380 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -35,8 +35,8 @@ use futures::ready; use futures::stream::StreamExt; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{dummy, ConnectionHandler}; use libp2p_swarm::{ @@ -48,7 +48,6 @@ use std::io::{Error, ErrorKind, IoSlice}; use std::ops::DerefMut; use std::pin::Pin; use std::task::{Context, Poll}; -use void::Void; /// The events produced by the [`Client`] behaviour. #[derive(Debug)] @@ -154,14 +153,13 @@ impl Client { impl NetworkBehaviour for Client { type ConnectionHandler = Either; - type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { if connected_point.is_relayed() { if let Some(event) = self.initial_events.remove(peer) { log::debug!( diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 905d8f0cdc9..41bde8dfed4 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -31,8 +31,8 @@ use instant::Instant; use libp2p_core::connection::ConnectionId; use libp2p_core::multiaddr::Protocol; use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ dummy, ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -42,7 +42,6 @@ use std::num::NonZeroU32; use std::ops::Add; use std::task::{Context, Poll}; use std::time::Duration; -use void::Void; use super::protocol::outbound_stop; @@ -253,14 +252,13 @@ impl Relay { impl NetworkBehaviour for Relay { type ConnectionHandler = Either; - type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result { if endpoint.is_relayed() { // Deny all substreams on relayed connection. Ok(Either::Right(dummy::ConnectionHandler)) diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 363db55bf17..4a92d6339ed 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -32,8 +32,8 @@ use libp2p_core::connection::ConnectionId; use libp2p_core::identity::error::SigningError; use libp2p_core::identity::Keypair; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, PeerRecord}; -use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -162,15 +162,15 @@ pub enum Event { } impl NetworkBehaviour for Behaviour { - type ConnectionHandler = SubstreamConnectionHandler; - type ConnectionDenied = Void; + type ConnectionHandler = + SubstreamConnectionHandler; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { let initial_keep_alive = Duration::from_secs(30); Ok(SubstreamConnectionHandler::new_outbound_only( diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 031e95a94b2..22a72b1f689 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -29,8 +29,8 @@ use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -110,14 +110,13 @@ pub enum Event { impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; - type ConnectionDenied = Void; type OutEvent = Event; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { let initial_keep_alive = Duration::from_secs(30); Ok(SubstreamConnectionHandler::new_inbound_only( diff --git a/protocols/rendezvous/tests/harness.rs b/protocols/rendezvous/tests/harness.rs index 04477a63db0..523f34c76db 100644 --- a/protocols/rendezvous/tests/harness.rs +++ b/protocols/rendezvous/tests/harness.rs @@ -64,11 +64,11 @@ fn get_rand_memory_address() -> Multiaddr { .unwrap() } -pub async fn await_event_or_timeout( - swarm: &mut (impl Stream> + FusedStream + Unpin), -) -> SwarmEvent +pub async fn await_event_or_timeout( + swarm: &mut (impl Stream> + FusedStream + Unpin), +) -> SwarmEvent where - SwarmEvent: Debug, + SwarmEvent: Debug, { tokio::time::timeout( Duration::from_secs(30), @@ -80,16 +80,13 @@ where .expect("network behaviour to emit an event within 30 seconds") } -pub async fn await_events_or_timeout( - swarm_1: &mut (impl Stream> + FusedStream + Unpin), - swarm_2: &mut (impl Stream> + FusedStream + Unpin), -) -> ( - SwarmEvent, - SwarmEvent, -) +pub async fn await_events_or_timeout( + swarm_1: &mut (impl Stream> + FusedStream + Unpin), + swarm_2: &mut (impl Stream> + FusedStream + Unpin), +) -> (SwarmEvent, SwarmEvent) where - SwarmEvent: Debug, - SwarmEvent: Debug, + SwarmEvent: Debug, + SwarmEvent: Debug, { tokio::time::timeout( Duration::from_secs(30), diff --git a/protocols/request-response/Cargo.toml b/protocols/request-response/Cargo.toml index 3ef9a512c90..4069873d280 100644 --- a/protocols/request-response/Cargo.toml +++ b/protocols/request-response/Cargo.toml @@ -21,7 +21,6 @@ log = "0.4.11" rand = "0.8" smallvec = "1.6.1" unsigned-varint = { version = "0.7", features = ["std", "futures"] } -void = "1.0.2" [dev-dependencies] async-std = "1.6.2" diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 88758ac5f71..5c403429fbe 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -67,7 +67,7 @@ pub use handler::ProtocolSupport; use futures::channel::oneshot; use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; -use libp2p_swarm::behaviour::THandlerInEvent; +use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, @@ -81,7 +81,6 @@ use std::{ task::{Context, Poll}, time::Duration, }; -use void::Void; /// An inbound request or response. #[derive(Debug)] @@ -693,14 +692,13 @@ where TCodec: RequestResponseCodec + Send + Clone + 'static, { type ConnectionHandler = RequestResponseHandler; - type ConnectionDenied = Void; type OutEvent = RequestResponseEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(RequestResponseHandler::new( self.inbound_protocols.clone(), self.codec.clone(), diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 4609c4140c7..f7f004347a8 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -52,6 +52,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude }); let multiaddr = quote! { #prelude_path::Multiaddr }; + let connection_denied = quote! { #prelude_path::ConnectionDenied }; let trait_to_impl = quote! { #prelude_path::NetworkBehaviour }; let either_ident = quote! { #prelude_path::EitherOutput }; let network_behaviour_action = quote! { #prelude_path::NetworkBehaviourAction }; @@ -144,56 +145,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } }; - let (connection_denied_ty, connection_denied_ty_definition) = { - let name: syn::Type = - syn::parse_str(&(ast.ident.to_string() + "ConnectionDenied")).unwrap(); - let definition = { - let fields = data_struct - .fields - .iter() - .map(|field| { - let variant: syn::Variant = syn::parse_str( - &field - .ident - .clone() - .expect("Fields of NetworkBehaviour implementation to be named.") - .to_string() - .to_upper_camel_case(), - ) - .unwrap(); - let ty = &field.ty; - quote! {#variant(<#ty as #trait_to_impl>::ConnectionDenied)} - }) - .collect::>(); - let visibility = &ast.vis; - - Some(quote! { - #visibility enum #name #impl_generics - #where_clause - { - #(#fields),* - } - - impl #impl_generics ::std::fmt::Debug for #name #ty_generics #where_clause { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - f.debug_struct("#name").finish() - } - } - - impl #impl_generics ::std::fmt::Display for #name #ty_generics #where_clause { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - Ok(()) - } - } - - impl #impl_generics ::std::error::Error for #name #ty_generics #where_clause { - // TODO: Implement `source` - } - }) - }; - (name, definition) - }; - // Build the `where ...` clause of the trait implementation. let where_clause = { let additional = data_struct @@ -512,18 +463,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { None => quote! { self.#field_n }, }; - let variant_name: syn::Variant = syn::parse_str( - &field - .ident - .clone() - .expect("Fields of NetworkBehaviour implementation to be named.") - .to_string() - .to_upper_camel_case(), - ) - .unwrap(); - let builder = quote! { - #field_name.new_handler(peer, connected_point).map_err(#connection_denied_ty::#variant_name)? + #field_name.new_handler(peer, connected_point)? }; match out_handler { @@ -611,17 +552,15 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { // Now the magic happens. let final_quote = quote! { #out_event_definition - #connection_denied_ty_definition impl #impl_generics #trait_to_impl for #name #ty_generics #where_clause { type ConnectionHandler = #connection_handler_ty; - type ConnectionDenied = #connection_denied_ty #ty_generics; type OutEvent = #out_event_reference; #[allow(clippy::needless_question_mark)] - fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Result { + fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Result { use #connection_handler; Ok(#new_handler) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 6abf94c140a..c1eeba5c409 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -120,8 +120,6 @@ pub trait NetworkBehaviour: 'static { /// Handler for all the protocols the network behaviour supports. type ConnectionHandler: ConnectionHandler; - type ConnectionDenied: std::error::Error + Send + 'static; - /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; @@ -145,7 +143,7 @@ pub trait NetworkBehaviour: 'static { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result; + ) -> Result; /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. @@ -372,6 +370,10 @@ pub trait NetworkBehaviour: 'static { ) -> Poll>>; } +#[derive(Debug)] +#[non_exhaustive] +pub enum ConnectionDenied {} + /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. pub trait PollParameters { /// Iterator returned by [`supported_protocols`](PollParameters::supported_protocols). diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 869a0058057..f7ac2871dcc 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -18,10 +18,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::behaviour::THandlerInEvent; use crate::behaviour::{ self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; +use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use either::Either; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -33,22 +33,16 @@ where R: NetworkBehaviour, { type ConnectionHandler = Either; - type ConnectionDenied = Either; type OutEvent = Either; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(match self { - Either::Left(a) => { - Either::Left(a.new_handler(peer, connected_point).map_err(Either::Left)?) - } - Either::Right(b) => Either::Right( - b.new_handler(peer, connected_point) - .map_err(Either::Right)?, - ), + Either::Left(a) => Either::Left(a.new_handler(peer, connected_point)?), + Either::Right(b) => Either::Right(b.new_handler(peer, connected_point)?), }) } diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index f1707da3c0e..c424a5e9a42 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -18,8 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::behaviour::THandlerInEvent; use crate::behaviour::{inject_from_swarm, FromSwarm}; +use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use crate::handler::{ ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, @@ -70,14 +70,13 @@ where TBehaviour: NetworkBehaviour, { type ConnectionHandler = ToggleConnectionHandler; - type ConnectionDenied = TBehaviour::ConnectionDenied; type OutEvent = TBehaviour::OutEvent; fn new_handler( &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(ToggleConnectionHandler { inner: match self.inner.as_mut() { None => None, diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 380be8d6051..40bc4e62af8 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -19,6 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::ConnectionDenied; use crate::connection::Connection; use crate::upgrade::UpgradeInfoSend; use crate::{ @@ -215,7 +216,7 @@ impl fmt::Debug for Pool +pub enum PoolEvent where TTrans: Transport, { @@ -259,13 +260,6 @@ where handler: THandler, }, - ConnectionDenied { - id: ConnectionId, - peer_id: PeerId, - endpoint: ConnectedPoint, - reason: TReason, - }, - /// An outbound connection attempt failed. PendingOutboundConnectionError { /// The ID of the failed connection. @@ -538,11 +532,11 @@ where } /// Polls the connection pool for events. - pub fn poll( + pub fn poll( &mut self, - mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> Result, + mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> Result, cx: &mut Context<'_>, - ) -> Poll> + ) -> Poll> where TTrans: Transport, THandler: ConnectionHandler + 'static, @@ -759,17 +753,8 @@ where }, ); - let handler = match new_handler_fn(&obtained_peer_id, &endpoint) { - Ok(handler) => handler, - Err(reason) => { - return Poll::Ready(PoolEvent::ConnectionDenied { - id, - peer_id: obtained_peer_id, - endpoint, - reason, - }) - } - }; + let handler = + new_handler_fn(&obtained_peer_id, &endpoint).expect("empty to empty"); let supported_protocols = handler .listen_protocol() .upgrade() diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 3e9cb35ac73..a1cfe910bd2 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,5 +1,6 @@ use crate::behaviour::{ - FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, }; use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -17,17 +18,29 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; - type ConnectionDenied = Void; type OutEvent = Void; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(ConnectionHandler) } + fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + void::unreachable(event) + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> + { + Poll::Pending + } + fn on_swarm_event(&mut self, event: FromSwarm) { match event { FromSwarm::ConnectionEstablished(_) @@ -44,19 +57,6 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredExternalAddr(_) => {} } } - - fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { - void::unreachable(event) - } - - fn poll( - &mut self, - _: &mut Context<'_>, - _: &mut impl PollParameters, - ) -> Poll>> - { - Poll::Pending - } } /// An implementation of [`ConnectionHandler`] that neither handles any protocols nor does it keep the connection alive. diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index d3192eb8e3c..651a75456f4 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -1,5 +1,6 @@ use crate::behaviour::{ - FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, }; use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -22,17 +23,29 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; - type ConnectionDenied = Void; type OutEvent = Void; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(ConnectionHandler) } + fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + void::unreachable(event) + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> + { + Poll::Pending + } + fn on_swarm_event(&mut self, event: FromSwarm) { match event { FromSwarm::ConnectionEstablished(_) @@ -49,19 +62,6 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredExternalAddr(_) => {} } } - - fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { - void::unreachable(event) - } - - fn poll( - &mut self, - _: &mut Context<'_>, - _: &mut impl PollParameters, - ) -> Poll>> - { - Poll::Pending - } } /// Implementation of [`ConnectionHandler`] that doesn't handle anything but keeps the connection alive. diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 11263e8e2d2..ce4354a0ab2 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -73,6 +73,7 @@ pub mod keep_alive; pub mod derive_prelude { pub use crate::behaviour::AddressChange; pub use crate::behaviour::ConnectionClosed; + pub use crate::behaviour::ConnectionDenied; pub use crate::behaviour::ConnectionEstablished; pub use crate::behaviour::DialFailure; pub use crate::behaviour::ExpiredExternalAddr; @@ -168,7 +169,7 @@ type THandlerErr = as ConnectionHandler>::Erro /// Event generated by the `Swarm`. #[derive(Debug)] -pub enum SwarmEvent { +pub enum SwarmEvent { /// Event generated by the `NetworkBehaviour`. Behaviour(TBehaviourOutEvent), /// A connection to the given peer has been opened. @@ -185,15 +186,6 @@ pub enum SwarmEvent { /// of dial attempts that failed before the one successful dial. concurrent_dial_errors: Option)>>, }, - /// A connection to the given peer has been opened. - ConnectionDenied { - /// Identity of the peer that we have connected to. - peer_id: PeerId, - /// Endpoint of the connection that has been opened. - endpoint: ConnectedPoint, - /// The reason why the connection was denied. - reason: TReason, - }, /// A connection with the given peer has been closed, /// possibly as a result of an error. ConnectionClosed { @@ -803,14 +795,8 @@ where fn handle_pool_event( &mut self, - event: PoolEvent< - THandler, - transport::Boxed<(PeerId, StreamMuxerBox)>, - TBehaviour::ConnectionDenied, - >, - ) -> Option< - SwarmEvent>, - > { + event: PoolEvent, transport::Boxed<(PeerId, StreamMuxerBox)>>, + ) -> Option>> { match event { PoolEvent::ConnectionEstablished { peer_id, @@ -969,18 +955,6 @@ where ); } } - PoolEvent::ConnectionDenied { - peer_id, - endpoint, - reason, - .. - } => { - return Some(SwarmEvent::ConnectionDenied { - peer_id, - endpoint, - reason, - }) - } } None @@ -992,9 +966,7 @@ where as Transport>::ListenerUpgrade, io::Error, >, - ) -> Option< - SwarmEvent>, - > { + ) -> Option>> { match event { TransportEvent::Incoming { listener_id: _, @@ -1096,9 +1068,7 @@ where fn handle_behaviour_event( &mut self, event: NetworkBehaviourAction>, - ) -> Option< - SwarmEvent>, - > { + ) -> Option>> { match event { NetworkBehaviourAction::GenerateEvent(event) => { return Some(SwarmEvent::Behaviour(event)) @@ -1184,8 +1154,7 @@ where fn poll_next_event( mut self: Pin<&mut Self>, cx: &mut Context<'_>, - ) -> Poll>> - { + ) -> Poll>> { // We use a `this` variable because the compiler can't mutably borrow multiple times // across a `Deref`. let this = &mut *self; @@ -1382,11 +1351,7 @@ impl Stream for Swarm where TBehaviour: NetworkBehaviour, { - type Item = SwarmEvent< - TBehaviourOutEvent, - TBehaviour::ConnectionDenied, - THandlerErr, - >; + type Item = SwarmEvent, THandlerErr>; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { self.as_mut().poll_next_event(cx).map(Some) diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 106aaceb4df..59ab424f893 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -19,8 +19,9 @@ // DEALINGS IN THE SOFTWARE. use crate::behaviour::{ - ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, - FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, + ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, ExpiredExternalAddr, + ExpiredListenAddr, FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, + NewListener, }; use crate::{ behaviour::THandlerInEvent, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, @@ -31,7 +32,6 @@ use libp2p_core::{ }; use std::collections::HashMap; use std::task::{Context, Poll}; -use void::Void; /// A `MockBehaviour` is a `NetworkBehaviour` that allows for /// the instrumentation of return values, without keeping @@ -71,14 +71,13 @@ where TOutEvent: Send + 'static, { type ConnectionHandler = THandler; - type ConnectionDenied = Void; type OutEvent = TOutEvent; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(self.handler_proto.clone()) } @@ -374,14 +373,13 @@ where ::OutEvent: Clone, { type ConnectionHandler = TInner::ConnectionHandler; - type ConnectionDenied = TInner::ConnectionDenied; type OutEvent = TInner::OutEvent; fn new_handler( &mut self, peer: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result { self.inner.new_handler(peer, endpoint) } diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 5429181591a..8c1f2d7b252 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -21,6 +21,7 @@ use futures::StreamExt; use libp2p_identify as identify; use libp2p_ping as ping; +use libp2p_swarm::behaviour::ConnectionDenied; use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent}; use std::fmt::Debug; @@ -384,34 +385,16 @@ fn custom_out_event_no_type_parameters() { impl NetworkBehaviour for TemplatedBehaviour { type ConnectionHandler = dummy::ConnectionHandler; - type ConnectionDenied = void::Void; type OutEvent = void::Void; fn new_handler( &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result { Ok(dummy::ConnectionHandler) } - fn on_swarm_event(&mut self, event: FromSwarm) { - match event { - FromSwarm::ConnectionEstablished(_) - | FromSwarm::ConnectionClosed(_) - | FromSwarm::AddressChange(_) - | FromSwarm::DialFailure(_) - | FromSwarm::ListenFailure(_) - | FromSwarm::NewListener(_) - | FromSwarm::NewListenAddr(_) - | FromSwarm::ExpiredListenAddr(_) - | FromSwarm::ListenerError(_) - | FromSwarm::ListenerClosed(_) - | FromSwarm::NewExternalAddr(_) - | FromSwarm::ExpiredExternalAddr(_) => {} - } - } - fn on_connection_handler_event( &mut self, _peer: PeerId, @@ -429,6 +412,23 @@ fn custom_out_event_no_type_parameters() { { Poll::Pending } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(_) + | FromSwarm::ConnectionClosed(_) + | FromSwarm::AddressChange(_) + | FromSwarm::DialFailure(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } } #[derive(NetworkBehaviour)] From dcb4f96b4f2445eb76f4cc392694a8922ddebd7b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 7 Dec 2022 12:51:56 +1100 Subject: [PATCH 21/21] Always box cause for denied connection --- misc/metrics/src/swarm.rs | 17 ++++++++++++++ protocols/autonat/src/behaviour.rs | 4 ++-- protocols/dcutr/src/behaviour.rs | 5 ++--- protocols/floodsub/src/layer.rs | 4 ++-- protocols/gossipsub/src/behaviour.rs | 3 +-- protocols/identify/src/behaviour.rs | 5 ++--- protocols/kad/src/behaviour.rs | 6 ++--- protocols/mdns/src/behaviour.rs | 4 ++-- protocols/ping/src/lib.rs | 5 +++-- protocols/relay/src/v2/client.rs | 4 ++-- protocols/relay/src/v2/relay.rs | 4 ++-- protocols/rendezvous/src/client.rs | 4 ++-- protocols/rendezvous/src/server.rs | 4 ++-- protocols/request-response/src/lib.rs | 4 ++-- swarm-derive/src/lib.rs | 3 +-- swarm/src/behaviour.rs | 6 +---- swarm/src/behaviour/either.rs | 4 ++-- swarm/src/behaviour/toggle.rs | 4 ++-- swarm/src/connection/pool.rs | 32 ++++++++++++++++++++++----- swarm/src/dummy.rs | 5 ++--- swarm/src/keep_alive.rs | 5 ++--- swarm/src/lib.rs | 20 ++++++++++++++++- swarm/src/test.rs | 9 ++++---- swarm/tests/swarm_derive.rs | 3 +-- 24 files changed, 105 insertions(+), 59 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index c4fa8712d14..9d89944b49d 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -31,6 +31,8 @@ pub struct Metrics { connections_established: Family, connections_closed: Family, + connections_denied: Family, + new_listen_addr: Family, expired_listen_addr: Family, @@ -60,6 +62,13 @@ impl Metrics { Box::new(connections_incoming_error.clone()), ); + let connections_denied = Family::default(); + sub_registry.register( + "connections_denied", + "Number of denied connections", + Box::new(connections_denied.clone()), + ); + let new_listen_addr = Family::default(); sub_registry.register( "new_listen_addr", @@ -128,6 +137,7 @@ impl Metrics { connections_incoming_error, connections_established, connections_closed, + connections_denied, new_listen_addr, expired_listen_addr, listener_closed, @@ -269,6 +279,13 @@ impl super::Recorder { self.dial_attempt.inc(); } + libp2p_swarm::SwarmEvent::ConnectionDenied { endpoint, .. } => { + self.connections_denied + .get_or_create(&AddressLabels { + protocols: protocol_stack::as_string(endpoint.get_remote_address()), + }) + .inc(); + } } } } diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 70cd4236e42..c8453661d77 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -35,7 +35,7 @@ use libp2p_request_response::{ ProtocolSupport, RequestId, RequestResponse, RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, }; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ behaviour::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, @@ -461,7 +461,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result> { self.inner.new_handler(peer, connected_point) } diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 7be0af12d34..240b742804c 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -27,8 +27,7 @@ use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, - THandlerInEvent, + ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, }; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ @@ -216,7 +215,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result> { match ( self.awaiting_direct_inbound_connections.entry(*peer), self.awaiting_direct_outbound_connections.entry(*peer), diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 7e8aa28aa7b..58fc40a9f25 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -27,8 +27,8 @@ use crate::FloodsubConfig; use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::ConnectionHandler; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, @@ -340,7 +340,7 @@ impl NetworkBehaviour for Floodsub { &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(Default::default()) } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 3e79ff7d55a..43dd133468c 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -66,7 +66,6 @@ use crate::types::{ }; use crate::types::{GossipsubRpc, PeerConnections, PeerKind}; use crate::{rpc_proto, TopicScoreParams}; -use libp2p_swarm::behaviour::ConnectionDenied; use std::{cmp::Ordering::Equal, fmt::Debug}; use wasm_timer::Interval; @@ -3302,7 +3301,7 @@ where &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 46d1880f62a..fa7c5e9e219 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -25,8 +25,7 @@ use libp2p_core::{ connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Multiaddr, PeerId, PublicKey, }; use libp2p_swarm::behaviour::{ - ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, FromSwarm, - THandlerInEvent, + ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, THandlerInEvent, }; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, @@ -243,7 +242,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(Handler::new( self.config.initial_delay, self.config.interval, diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index bc5a69b2316..38bcf052d86 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -41,8 +41,8 @@ use fnv::{FnvHashMap, FnvHashSet}; use instant::Instant; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ - AddressChange, ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, - ExpiredListenAddr, FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, + AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredListenAddr, + FromSwarm, NewExternalAddr, NewListenAddr, THandlerInEvent, }; use libp2p_swarm::{ dial_opts::{self, DialOpts}, @@ -1979,7 +1979,7 @@ where &mut self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(KademliaHandler::new( KademliaHandlerConfig { protocol_config: self.protocol_config.clone(), diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 9d8c471314a..4fa105ec8e8 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -28,7 +28,7 @@ use crate::Config; use futures::Stream; use if_watch::IfEvent; use libp2p_core::{Multiaddr, PeerId}; -use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionDenied, FromSwarm}; +use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -172,7 +172,7 @@ where &mut self, _: &PeerId, _: &libp2p_core::ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(dummy::ConnectionHandler) } diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index e1ba31143eb..80b14e1dc44 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -48,7 +48,7 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, PeerId}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -124,7 +124,8 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> std::result::Result { + ) -> std::result::Result> + { Ok(Handler::new(self.config.clone())) } diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index f5aa268d380..76527af3591 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -35,8 +35,8 @@ use futures::ready; use futures::stream::StreamExt; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{dummy, ConnectionHandler}; use libp2p_swarm::{ @@ -159,7 +159,7 @@ impl NetworkBehaviour for Client { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result> { if connected_point.is_relayed() { if let Some(event) = self.initial_events.remove(peer) { log::debug!( diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 41bde8dfed4..b6be9d9197d 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -31,8 +31,8 @@ use instant::Instant; use libp2p_core::connection::ConnectionId; use libp2p_core::multiaddr::Protocol; use libp2p_core::{ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; use libp2p_swarm::{ dummy, ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -258,7 +258,7 @@ impl NetworkBehaviour for Relay { &mut self, _: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result> { if endpoint.is_relayed() { // Deny all substreams on relayed connection. Ok(Either::Right(dummy::ConnectionHandler)) diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 4a92d6339ed..9406ec82753 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -32,8 +32,8 @@ use libp2p_core::connection::ConnectionId; use libp2p_core::identity::error::SigningError; use libp2p_core::identity::Keypair; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, PeerRecord}; +use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; -use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -170,7 +170,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { let initial_keep_alive = Duration::from_secs(30); Ok(SubstreamConnectionHandler::new_outbound_only( diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 22a72b1f689..2c10f14253c 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -29,8 +29,8 @@ use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use libp2p_core::connection::ConnectionId; use libp2p_core::{ConnectedPoint, PeerId}; +use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::behaviour::THandlerInEvent; -use libp2p_swarm::behaviour::{ConnectionDenied, FromSwarm}; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -116,7 +116,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { let initial_keep_alive = Duration::from_secs(30); Ok(SubstreamConnectionHandler::new_inbound_only( diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 5c403429fbe..3cf0f94c0e2 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -67,7 +67,7 @@ pub use handler::ProtocolSupport; use futures::channel::oneshot; use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; -use libp2p_swarm::behaviour::{ConnectionDenied, THandlerInEvent}; +use libp2p_swarm::behaviour::THandlerInEvent; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, @@ -698,7 +698,7 @@ where &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(RequestResponseHandler::new( self.inbound_protocols.clone(), self.codec.clone(), diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index f7f004347a8..66ad8887a54 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -52,7 +52,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude }); let multiaddr = quote! { #prelude_path::Multiaddr }; - let connection_denied = quote! { #prelude_path::ConnectionDenied }; let trait_to_impl = quote! { #prelude_path::NetworkBehaviour }; let either_ident = quote! { #prelude_path::EitherOutput }; let network_behaviour_action = quote! { #prelude_path::NetworkBehaviourAction }; @@ -560,7 +559,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { type OutEvent = #out_event_reference; #[allow(clippy::needless_question_mark)] - fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Result { + fn new_handler(&mut self, peer: &#peer_id, connected_point: &#connected_point) -> Result> { use #connection_handler; Ok(#new_handler) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index c1eeba5c409..07cb18f3e84 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -143,7 +143,7 @@ pub trait NetworkBehaviour: 'static { &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result; + ) -> Result>; /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. @@ -370,10 +370,6 @@ pub trait NetworkBehaviour: 'static { ) -> Poll>>; } -#[derive(Debug)] -#[non_exhaustive] -pub enum ConnectionDenied {} - /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. pub trait PollParameters { /// Iterator returned by [`supported_protocols`](PollParameters::supported_protocols). diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index f7ac2871dcc..f187392831f 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -18,10 +18,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::THandlerInEvent; use crate::behaviour::{ self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; -use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use either::Either; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -39,7 +39,7 @@ where &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(match self { Either::Left(a) => Either::Left(a.new_handler(peer, connected_point)?), Either::Right(b) => Either::Right(b.new_handler(peer, connected_point)?), diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index c424a5e9a42..399058bfe32 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -18,8 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::THandlerInEvent; use crate::behaviour::{inject_from_swarm, FromSwarm}; -use crate::behaviour::{ConnectionDenied, THandlerInEvent}; use crate::handler::{ ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, @@ -76,7 +76,7 @@ where &mut self, peer: &PeerId, connected_point: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(ToggleConnectionHandler { inner: match self.inner.as_mut() { None => None, diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 40bc4e62af8..65d842200d4 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -18,8 +18,6 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. - -use crate::behaviour::ConnectionDenied; use crate::connection::Connection; use crate::upgrade::UpgradeInfoSend; use crate::{ @@ -44,6 +42,7 @@ use libp2p_core::connection::{ConnectionId, Endpoint, PendingPoint}; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerExt}; use libp2p_core::ProtocolName; use smallvec::SmallVec; +use std::error::Error; use std::{ collections::{hash_map, HashMap}, convert::TryFrom as _, @@ -260,6 +259,17 @@ where handler: THandler, }, + /// A [NetworkBehaviour] denied a just established connection by not producing a [`ConnectionHandler`] from [`NetworkBehaviour::new_handler`]. + /// + /// [NetworkBehaviour]: crate::NetworkBehaviour + /// [NetworkBehaviour::new_handler]: crate::NetworkBehaviour::new_handler + ConnectionDenied { + id: ConnectionId, + peer_id: PeerId, + endpoint: ConnectedPoint, + cause: Box, + }, + /// An outbound connection attempt failed. PendingOutboundConnectionError { /// The ID of the failed connection. @@ -534,7 +544,10 @@ where /// Polls the connection pool for events. pub fn poll( &mut self, - mut new_handler_fn: impl FnMut(&PeerId, &ConnectedPoint) -> Result, + mut new_handler_fn: impl FnMut( + &PeerId, + &ConnectedPoint, + ) -> Result>, cx: &mut Context<'_>, ) -> Poll> where @@ -753,8 +766,17 @@ where }, ); - let handler = - new_handler_fn(&obtained_peer_id, &endpoint).expect("empty to empty"); + let handler = match new_handler_fn(&obtained_peer_id, &endpoint) { + Ok(handler) => handler, + Err(cause) => { + return Poll::Ready(PoolEvent::ConnectionDenied { + id, + peer_id: obtained_peer_id, + endpoint, + cause, + }) + } + }; let supported_protocols = handler .listen_protocol() .upgrade() diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index a1cfe910bd2..880605452a3 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,6 +1,5 @@ use crate::behaviour::{ - ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerInEvent, + FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -24,7 +23,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(ConnectionHandler) } diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index 651a75456f4..a778a5f85db 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -1,6 +1,5 @@ use crate::behaviour::{ - ConnectionDenied, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerInEvent, + FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, @@ -29,7 +28,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(ConnectionHandler) } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ce4354a0ab2..9cc217a90a8 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -73,7 +73,6 @@ pub mod keep_alive; pub mod derive_prelude { pub use crate::behaviour::AddressChange; pub use crate::behaviour::ConnectionClosed; - pub use crate::behaviour::ConnectionDenied; pub use crate::behaviour::ConnectionEstablished; pub use crate::behaviour::DialFailure; pub use crate::behaviour::ExpiredExternalAddr; @@ -199,6 +198,13 @@ pub enum SwarmEvent { /// active close. cause: Option>, }, + ConnectionDenied { + /// Identity of the peer that we have connected to. + peer_id: PeerId, + /// Endpoint of the connection that has been closed. + endpoint: ConnectedPoint, + cause: Box, + }, /// A new connection arrived on a listener and is in the process of protocol negotiation. /// /// A corresponding [`ConnectionEstablished`](SwarmEvent::ConnectionEstablished), @@ -931,6 +937,18 @@ where num_established, }); } + PoolEvent::ConnectionDenied { + peer_id, + endpoint, + cause, + .. + } => { + return Some(SwarmEvent::ConnectionDenied { + peer_id, + endpoint, + cause, + }) + } PoolEvent::ConnectionEvent { peer_id, id, event } => { if self.banned_peer_connections.contains(&id) { log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id); diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 59ab424f893..1d03eec55bb 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -19,9 +19,8 @@ // DEALINGS IN THE SOFTWARE. use crate::behaviour::{ - ConnectionClosed, ConnectionDenied, ConnectionEstablished, DialFailure, ExpiredExternalAddr, - ExpiredListenAddr, FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, - NewListener, + ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, + FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, }; use crate::{ behaviour::THandlerInEvent, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, @@ -77,7 +76,7 @@ where &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(self.handler_proto.clone()) } @@ -379,7 +378,7 @@ where &mut self, peer: &PeerId, endpoint: &ConnectedPoint, - ) -> Result { + ) -> Result> { self.inner.new_handler(peer, endpoint) } diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 8c1f2d7b252..ce8417e19f7 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -21,7 +21,6 @@ use futures::StreamExt; use libp2p_identify as identify; use libp2p_ping as ping; -use libp2p_swarm::behaviour::ConnectionDenied; use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent}; use std::fmt::Debug; @@ -391,7 +390,7 @@ fn custom_out_event_no_type_parameters() { &mut self, _: &PeerId, _: &ConnectedPoint, - ) -> Result { + ) -> Result> { Ok(dummy::ConnectionHandler) }