diff --git a/protocols/autonat/CHANGELOG.md b/protocols/autonat/CHANGELOG.md index 7cbcc4d87c6..ac7af065ba8 100644 --- a/protocols/autonat/CHANGELOG.md +++ b/protocols/autonat/CHANGELOG.md @@ -6,6 +6,11 @@ - Update to `libp2p-request-response` `v0.23.0`. +- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 + # 0.8.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index b39a7b141b4..cc0adc51c02 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -29,15 +29,19 @@ pub use as_server::{InboundProbeError, InboundProbeEvent}; use futures_timer::Delay; use instant::Instant; use libp2p_core::{ - connection::ConnectionId, multiaddr::Protocol, transport::ListenerId, ConnectedPoint, Endpoint, - Multiaddr, PeerId, + connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Endpoint, Multiaddr, PeerId, }; use libp2p_request_response::{ - handler::RequestResponseHandlerEvent, ProtocolSupport, RequestId, RequestResponse, - RequestResponseConfig, RequestResponseEvent, RequestResponseMessage, ResponseChannel, + ProtocolSupport, RequestId, RequestResponse, RequestResponseConfig, RequestResponseEvent, + RequestResponseMessage, ResponseChannel, }; use libp2p_swarm::{ - DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + behaviour::{ + AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, + ExpiredListenAddr, FromSwarm, + }, + ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, + PollParameters, }; use std::{ collections::{HashMap, VecDeque}, @@ -298,28 +302,17 @@ impl Behaviour { ongoing_inbound: &mut self.ongoing_inbound, } } -} - -impl NetworkBehaviour for Behaviour { - type ConnectionHandler = as NetworkBehaviour>::ConnectionHandler; - type OutEvent = Event; - fn inject_connection_established( + fn on_connection_established( &mut self, - peer: &PeerId, - conn: &ConnectionId, - endpoint: &ConnectedPoint, - failed_addresses: Option<&Vec>, - other_established: usize, - ) { - self.inner.inject_connection_established( - peer, - conn, + ConnectionEstablished { + peer_id: peer, + connection_id: conn, endpoint, - failed_addresses, - other_established, - ); - let connections = self.connected.entry(*peer).or_default(); + .. + }: ConnectionEstablished, + ) { + let connections = self.connected.entry(peer).or_default(); let addr = endpoint.get_remote_address(); let observed_addr = if !endpoint.is_relayed() && (!self.config.only_global_ips || addr.is_global_ip()) { @@ -327,14 +320,14 @@ impl NetworkBehaviour for Behaviour { } else { None }; - connections.insert(*conn, observed_addr); + connections.insert(conn, observed_addr); match endpoint { ConnectedPoint::Dialer { address, role_override: Endpoint::Dialer, } => { - if let Some(event) = self.as_server().on_outbound_connection(peer, address) { + if let Some(event) = self.as_server().on_outbound_connection(&peer, address) { self.pending_out_events .push_back(Event::InboundProbe(event)); } @@ -351,50 +344,69 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - peer: &PeerId, - conn: &ConnectionId, - endpoint: &ConnectedPoint, - handler: ::Handler, - remaining_established: usize, + ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler, + remaining_established, + }: ConnectionClosed<::ConnectionHandler>, ) { self.inner - .inject_connection_closed(peer, conn, endpoint, handler, remaining_established); + .on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler, + remaining_established, + })); + if remaining_established == 0 { - self.connected.remove(peer); + self.connected.remove(&peer_id); } else { - let connections = self.connected.get_mut(peer).expect("Peer is connected."); - connections.remove(conn); + let connections = self + .connected + .get_mut(&peer_id) + .expect("Peer is connected."); + connections.remove(&connection_id); } } - fn inject_dial_failure( + fn on_dial_failure( &mut self, - peer: Option, - handler: Self::ConnectionHandler, - error: &DialError, + DialFailure { + peer_id, + handler, + error, + }: DialFailure<::ConnectionHandler>, ) { - self.inner.inject_dial_failure(peer, handler, error); - if let Some(event) = self.as_server().on_outbound_dial_error(peer, error) { + self.inner + .on_swarm_event(FromSwarm::DialFailure(DialFailure { + peer_id, + handler, + error, + })); + if let Some(event) = self.as_server().on_outbound_dial_error(peer_id, error) { self.pending_out_events .push_back(Event::InboundProbe(event)); } } - fn inject_address_change( + fn on_address_change( &mut self, - peer: &PeerId, - conn: &ConnectionId, - old: &ConnectedPoint, - new: &ConnectedPoint, + AddressChange { + peer_id: peer, + connection_id: conn, + old, + new, + }: AddressChange, ) { - self.inner.inject_address_change(peer, conn, old, new); - if old.is_relayed() && new.is_relayed() { return; } - let connections = self.connected.get_mut(peer).expect("Peer is connected."); + let connections = self.connected.get_mut(&peer).expect("Peer is connected."); let addr = new.get_remote_address(); let observed_addr = if !new.is_relayed() && (!self.config.only_global_ips || addr.is_global_ip()) { @@ -402,28 +414,13 @@ impl NetworkBehaviour for Behaviour { } else { None }; - connections.insert(*conn, observed_addr); - } - - fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - self.inner.inject_new_listen_addr(id, addr); - self.as_client().on_new_address(); - } - - fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - self.inner.inject_expired_listen_addr(id, addr); - self.as_client().on_expired_address(addr); - } - - fn inject_new_external_addr(&mut self, addr: &Multiaddr) { - self.inner.inject_new_external_addr(addr); - self.as_client().on_new_address(); + connections.insert(conn, observed_addr); } +} - fn inject_expired_external_addr(&mut self, addr: &Multiaddr) { - self.inner.inject_expired_external_addr(addr); - self.as_client().on_expired_address(addr); - } +impl NetworkBehaviour for Behaviour { + type ConnectionHandler = as NetworkBehaviour>::ConnectionHandler; + type OutEvent = Event; fn poll(&mut self, cx: &mut Context<'_>, params: &mut impl PollParameters) -> Poll { loop { @@ -478,35 +475,65 @@ impl NetworkBehaviour for Behaviour { self.inner.addresses_of_peer(peer) } - fn inject_event( - &mut self, - peer_id: PeerId, - conn: ConnectionId, - event: RequestResponseHandlerEvent, - ) { - self.inner.inject_event(peer_id, conn, event) + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.inner + .on_swarm_event(FromSwarm::ConnectionEstablished(connection_established)); + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure), + FromSwarm::AddressChange(address_change) => { + self.inner + .on_swarm_event(FromSwarm::AddressChange(address_change)); + self.on_address_change(address_change) + } + listen_addr @ FromSwarm::NewListenAddr(_) => { + self.inner.on_swarm_event(listen_addr); + self.as_client().on_new_address(); + } + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => { + self.inner + .on_swarm_event(FromSwarm::ExpiredListenAddr(ExpiredListenAddr { + listener_id, + addr, + })); + self.as_client().on_expired_address(addr); + } + FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => { + self.inner + .on_swarm_event(FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr })); + self.as_client().on_expired_address(addr); + } + external_addr @ FromSwarm::NewExternalAddr(_) => { + self.inner.on_swarm_event(external_addr); + self.as_client().on_new_address(); + } + listen_failure @ FromSwarm::ListenFailure(_) => { + self.inner.on_swarm_event(listen_failure) + } + new_listener @ FromSwarm::NewListener(_) => self.inner.on_swarm_event(new_listener), + listener_error @ FromSwarm::ListenerError(_) => { + self.inner.on_swarm_event(listener_error) + } + listener_closed @ FromSwarm::ListenerClosed(_) => { + self.inner.on_swarm_event(listener_closed) + } + } } - fn inject_listen_failure( + fn on_connection_handler_event( &mut self, - local_addr: &Multiaddr, - send_back_addr: &Multiaddr, - handler: Self::ConnectionHandler, + peer_id: PeerId, + connection_id: ConnectionId, + event: <::Handler as + ConnectionHandler>::OutEvent, ) { self.inner - .inject_listen_failure(local_addr, send_back_addr, handler) - } - - fn inject_new_listener(&mut self, id: ListenerId) { - self.inner.inject_new_listener(id) - } - - fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { - self.inner.inject_listener_error(id, err) - } - - fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) { - self.inner.inject_listener_closed(id, reason) + .on_connection_handler_event(peer_id, connection_id, event) } } diff --git a/protocols/dcutr/CHANGELOG.md b/protocols/dcutr/CHANGELOG.md index b7890a8d6fb..4f850ed5ce2 100644 --- a/protocols/dcutr/CHANGELOG.md +++ b/protocols/dcutr/CHANGELOG.md @@ -6,6 +6,11 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 + # 0.7.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 5d93d90b339..df4aabfb4e8 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -26,10 +26,11 @@ use either::Either; use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; use libp2p_core::{Multiaddr, PeerId}; +use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerUpgrErr, DialError, IntoConnectionHandler, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + ConnectionHandler, ConnectionHandlerUpgrErr, IntoConnectionHandler, NetworkBehaviour, + NetworkBehaviourAction, NotifyHandler, PollParameters, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; @@ -81,30 +82,18 @@ impl Behaviour { direct_connections: Default::default(), } } -} -impl NetworkBehaviour for Behaviour { - type ConnectionHandler = handler::Prototype; - type OutEvent = Event; - - fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::UnknownConnection - } - - fn addresses_of_peer(&mut self, _peer_id: &PeerId) -> Vec { - vec![] - } - - fn inject_connection_established( + fn on_connection_established( &mut self, - peer_id: &PeerId, - connection_id: &ConnectionId, - connected_point: &ConnectedPoint, - _failed_addresses: Option<&Vec>, - _other_established: usize, + ConnectionEstablished { + peer_id, + connection_id, + endpoint: connected_point, + .. + }: ConnectionEstablished, ) { if connected_point.is_relayed() { - if connected_point.is_listener() && !self.direct_connections.contains_key(peer_id) { + if connected_point.is_listener() && !self.direct_connections.contains_key(&peer_id) { // TODO: Try dialing the remote peer directly. Specification: // // > The protocol starts with the completion of a relay connection from A to B. Upon @@ -116,13 +105,13 @@ impl NetworkBehaviour for Behaviour { // https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol self.queued_actions.extend([ ActionBuilder::Connect { - peer_id: *peer_id, + peer_id, attempt: 1, - handler: NotifyHandler::One(*connection_id), + handler: NotifyHandler::One(connection_id), }, NetworkBehaviourAction::GenerateEvent( Event::InitiatedDirectConnectionUpgrade { - remote_peer_id: *peer_id, + remote_peer_id: peer_id, local_relayed_addr: match connected_point { ConnectedPoint::Listener { local_addr, .. } => local_addr.clone(), ConnectedPoint::Dialer { .. } => unreachable!("Due to outer if."), @@ -134,17 +123,17 @@ impl NetworkBehaviour for Behaviour { } } else { self.direct_connections - .entry(*peer_id) + .entry(peer_id) .or_default() - .insert(*connection_id); + .insert(connection_id); } } - fn inject_dial_failure( + fn on_dial_failure( &mut self, - peer_id: Option, - handler: Self::ConnectionHandler, - _error: &DialError, + DialFailure { + peer_id, handler, .. + }: DialFailure<::ConnectionHandler>, ) { if let handler::Prototype::DirectConnection { relayed_connection_id, @@ -178,34 +167,45 @@ impl NetworkBehaviour for Behaviour { } } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - peer_id: &PeerId, - connection_id: &ConnectionId, - connected_point: &ConnectedPoint, - _handler: <::ConnectionHandler as IntoConnectionHandler>::Handler, - _remaining_established: usize, + ConnectionClosed { + peer_id, + connection_id, + endpoint: connected_point, + .. + }: ConnectionClosed<::ConnectionHandler>, ) { if !connected_point.is_relayed() { let connections = self .direct_connections - .get_mut(peer_id) + .get_mut(&peer_id) .expect("Peer of direct connection to be tracked."); connections - .remove(connection_id) + .remove(&connection_id) .then(|| ()) .expect("Direct connection to be tracked."); if connections.is_empty() { - self.direct_connections.remove(peer_id); + self.direct_connections.remove(&peer_id); } } } +} + +impl NetworkBehaviour for Behaviour { + type ConnectionHandler = handler::Prototype; + type OutEvent = Event; + + fn new_handler(&mut self) -> Self::ConnectionHandler { + handler::Prototype::UnknownConnection + } - fn inject_event( + fn on_connection_handler_event( &mut self, event_source: PeerId, connection: ConnectionId, - handler_event: <::Handler as ConnectionHandler>::OutEvent, + handler_event: <::Handler as + ConnectionHandler>::OutEvent, ) { match handler_event { Either::Left(handler::relayed::Event::InboundConnectRequest { @@ -316,6 +316,27 @@ impl NetworkBehaviour for Behaviour { Poll::Pending } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure), + FromSwarm::AddressChange(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } } /// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`] diff --git a/protocols/floodsub/CHANGELOG.md b/protocols/floodsub/CHANGELOG.md index 7ecf156034b..128d22fb575 100644 --- a/protocols/floodsub/CHANGELOG.md +++ b/protocols/floodsub/CHANGELOG.md @@ -4,6 +4,11 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `Floodsub`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 + # 0.40.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 4256e39b7dc..776c0e8551b 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -27,11 +27,12 @@ use crate::FloodsubConfig; use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; use libp2p_core::{connection::ConnectionId, PeerId}; -use libp2p_core::{ConnectedPoint, Multiaddr}; +use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, PollParameters, }; +use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler}; use log::warn; use smallvec::SmallVec; use std::collections::hash_map::{DefaultHasher, HashMap}; @@ -276,23 +277,14 @@ impl Floodsub { }); } } -} -impl NetworkBehaviour for Floodsub { - type ConnectionHandler = OneShotHandler; - type OutEvent = FloodsubEvent; - - fn new_handler(&mut self) -> Self::ConnectionHandler { - Default::default() - } - - fn inject_connection_established( + fn on_connection_established( &mut self, - id: &PeerId, - _: &ConnectionId, - _: &ConnectedPoint, - _: Option<&Vec>, - other_established: usize, + ConnectionEstablished { + peer_id, + other_established, + .. + }: ConnectionEstablished, ) { if other_established > 0 { // We only care about the first time a peer connects. @@ -300,11 +292,11 @@ impl NetworkBehaviour for Floodsub { } // We need to send our subscriptions to the newly-connected node. - if self.target_peers.contains(id) { + if self.target_peers.contains(&peer_id) { for topic in self.subscribed_topics.iter().cloned() { self.events .push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: *id, + peer_id, handler: NotifyHandler::Any, event: FloodsubRpc { messages: Vec::new(), @@ -317,41 +309,51 @@ impl NetworkBehaviour for Floodsub { } } - self.connected_peers.insert(*id, SmallVec::new()); + self.connected_peers.insert(peer_id, SmallVec::new()); } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - id: &PeerId, - _: &ConnectionId, - _: &ConnectedPoint, - _: Self::ConnectionHandler, - remaining_established: usize, + ConnectionClosed { + peer_id, + remaining_established, + .. + }: ConnectionClosed<::ConnectionHandler>, ) { if remaining_established > 0 { // we only care about peer disconnections return; } - let was_in = self.connected_peers.remove(id); + let was_in = self.connected_peers.remove(&peer_id); debug_assert!(was_in.is_some()); // 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) { + if self.target_peers.contains(&peer_id) { let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(*id).build(), + opts: DialOpts::peer_id(peer_id).build(), handler, }); } } +} - fn inject_event( +impl NetworkBehaviour for Floodsub { + type ConnectionHandler = OneShotHandler; + type OutEvent = FloodsubEvent; + + fn new_handler(&mut self) -> Self::ConnectionHandler { + Default::default() + } + + fn on_connection_handler_event( &mut self, propagation_source: PeerId, - _connection: ConnectionId, - event: InnerMessage, + _connection_id: ConnectionId, + event: <::Handler as + ConnectionHandler>::OutEvent, ) { // We ignore successful sends or timeouts. let event = match event { @@ -477,6 +479,27 @@ impl NetworkBehaviour for Floodsub { Poll::Pending } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::AddressChange(_) + | FromSwarm::DialFailure(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } } /// Transmission between the `OneShotHandler` and the `FloodsubHandler`. diff --git a/protocols/gossipsub/CHANGELOG.md b/protocols/gossipsub/CHANGELOG.md index 4ddb017b7a8..0cdc6e99cfd 100644 --- a/protocols/gossipsub/CHANGELOG.md +++ b/protocols/gossipsub/CHANGELOG.md @@ -8,7 +8,11 @@ - Refactoring GossipsubCodec to use common protobuf Codec. See [PR 3070]. +- Replace `Gossipsub`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + [PR 3070]: https://github.com/libp2p/rust-libp2p/pull/3070 +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 # 0.42.0 diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 8fe6fc94b4a..c361fc4fdbc 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -38,10 +38,12 @@ use rand::{seq::SliceRandom, thread_rng}; use libp2p_core::{ connection::ConnectionId, identity::Keypair, multiaddr::Protocol::Ip4, - multiaddr::Protocol::Ip6, ConnectedPoint, Multiaddr, PeerId, + multiaddr::Protocol::Ip6, Multiaddr, PeerId, }; use libp2p_swarm::{ - dial_opts::DialOpts, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, + behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, + dial_opts::DialOpts, + ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; use wasm_timer::Instant; @@ -3028,57 +3030,30 @@ where Ok(rpc_list) } -} - -fn get_ip_addr(addr: &Multiaddr) -> Option { - addr.iter().find_map(|p| match p { - Ip4(addr) => Some(IpAddr::V4(addr)), - Ip6(addr) => Some(IpAddr::V6(addr)), - _ => None, - }) -} -impl NetworkBehaviour for Gossipsub -where - C: Send + 'static + DataTransform, - F: Send + 'static + TopicSubscriptionFilter, -{ - type ConnectionHandler = GossipsubHandler; - type OutEvent = GossipsubEvent; - - fn new_handler(&mut self) -> Self::ConnectionHandler { - let protocol_config = ProtocolConfig::new( - self.config.protocol_id().clone(), - self.config.custom_id_version().clone(), - self.config.max_transmit_size(), - self.config.validation_mode().clone(), - self.config.support_floodsub(), - ); - - GossipsubHandler::new(protocol_config, self.config.idle_timeout()) - } - - fn inject_connection_established( + fn on_connection_established( &mut self, - peer_id: &PeerId, - connection_id: &ConnectionId, - endpoint: &ConnectedPoint, - _: Option<&Vec>, - other_established: usize, + ConnectionEstablished { + peer_id, + connection_id, + endpoint, + other_established, + .. + }: ConnectionEstablished, ) { // Diverging from the go implementation we only want to consider a peer as outbound peer // if its first connection is outbound. - if endpoint.is_dialer() && other_established == 0 && !self.px_peers.contains(peer_id) { + if endpoint.is_dialer() && other_established == 0 && !self.px_peers.contains(&peer_id) { // The first connection is outbound and it is not a peer from peer exchange => mark // it as outbound peer - self.outbound_peers.insert(*peer_id); + self.outbound_peers.insert(peer_id); } // Add the IP to the peer scoring system if let Some((peer_score, ..)) = &mut self.peer_score { if let Some(ip) = get_ip_addr(endpoint.get_remote_address()) { - peer_score.add_ip(peer_id, ip); + peer_score.add_ip(&peer_id, ip); } else { trace!( "Couldn't extract ip from endpoint of peer {} with endpoint {:?}", @@ -3094,17 +3069,17 @@ where // update the type of peer that this is in order to determine which kind of routing should // occur. self.connected_peers - .entry(*peer_id) + .entry(peer_id) .or_insert(PeerConnections { kind: PeerKind::Floodsub, connections: vec![], }) .connections - .push(*connection_id); + .push(connection_id); if other_established == 0 { // Ignore connections from blacklisted peers. - if self.blacklisted_peers.contains(peer_id) { + if self.blacklisted_peers.contains(&peer_id) { debug!("Ignoring connection from blacklisted peer: {}", peer_id); } else { debug!("New peer connected: {}", peer_id); @@ -3121,7 +3096,7 @@ where // send our subscriptions to the peer if self .send_message( - *peer_id, + peer_id, GossipsubRpc { messages: Vec::new(), subscriptions, @@ -3137,26 +3112,28 @@ where } // Insert an empty set of the topics of this peer until known. - self.peer_topics.insert(*peer_id, Default::default()); + self.peer_topics.insert(peer_id, Default::default()); if let Some((peer_score, ..)) = &mut self.peer_score { - peer_score.add_peer(*peer_id); + peer_score.add_peer(peer_id); } } } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - peer_id: &PeerId, - connection_id: &ConnectionId, - endpoint: &ConnectedPoint, - _: ::Handler, - remaining_established: usize, + ConnectionClosed { + peer_id, + connection_id, + endpoint, + remaining_established, + .. + }: ConnectionClosed<::ConnectionHandler>, ) { // Remove IP from peer scoring system if let Some((peer_score, ..)) = &mut self.peer_score { if let Some(ip) = get_ip_addr(endpoint.get_remote_address()) { - peer_score.remove_ip(peer_id, &ip); + peer_score.remove_ip(&peer_id, &ip); } else { trace!( "Couldn't extract ip from endpoint of peer {} with endpoint {:?}", @@ -3168,24 +3145,24 @@ where if remaining_established != 0 { // Remove the connection from the list - if let Some(connections) = self.connected_peers.get_mut(peer_id) { + if let Some(connections) = self.connected_peers.get_mut(&peer_id) { let index = connections .connections .iter() - .position(|v| v == connection_id) + .position(|v| v == &connection_id) .expect("Previously established connection to peer must be present"); connections.connections.remove(index); // If there are more connections and this peer is in a mesh, inform the first connection // handler. if !connections.connections.is_empty() { - if let Some(topics) = self.peer_topics.get(peer_id) { + if let Some(topics) = self.peer_topics.get(&peer_id) { for topic in topics { if let Some(mesh_peers) = self.mesh.get(topic) { - if mesh_peers.contains(peer_id) { + if mesh_peers.contains(&peer_id) { self.events .push_back(NetworkBehaviourAction::NotifyHandler { - peer_id: *peer_id, + peer_id, event: Arc::new(GossipsubHandlerIn::JoinedMesh), handler: NotifyHandler::One(connections.connections[0]), }); @@ -3200,11 +3177,11 @@ where // remove from mesh, topic_peers, peer_topic and the fanout debug!("Peer disconnected: {}", peer_id); { - let topics = match self.peer_topics.get(peer_id) { + let topics = match self.peer_topics.get(&peer_id) { Some(topics) => topics, None => { debug_assert!( - self.blacklisted_peers.contains(peer_id), + self.blacklisted_peers.contains(&peer_id), "Disconnected node not in connected list" ); return; @@ -3216,7 +3193,7 @@ where // check the mesh for the topic if let Some(mesh_peers) = self.mesh.get_mut(topic) { // check if the peer is in the mesh and remove it - if mesh_peers.remove(peer_id) { + if mesh_peers.remove(&peer_id) { if let Some(m) = self.metrics.as_mut() { m.peers_removed(topic, Churn::Dc, 1); m.set_mesh_peers(topic, mesh_peers.len()); @@ -3226,7 +3203,7 @@ where // remove from topic_peers if let Some(peer_list) = self.topic_peers.get_mut(topic) { - if !peer_list.remove(peer_id) { + if !peer_list.remove(&peer_id) { // debugging purposes warn!( "Disconnected node: {} not in topic_peers peer list", @@ -3246,72 +3223,104 @@ where // remove from fanout self.fanout .get_mut(topic) - .map(|peers| peers.remove(peer_id)); + .map(|peers| peers.remove(&peer_id)); } } // Forget px and outbound status for this peer - self.px_peers.remove(peer_id); - self.outbound_peers.remove(peer_id); + self.px_peers.remove(&peer_id); + self.outbound_peers.remove(&peer_id); // Remove peer from peer_topics and connected_peers // NOTE: It is possible the peer has already been removed from all mappings if it does not // support the protocol. - self.peer_topics.remove(peer_id); + self.peer_topics.remove(&peer_id); // If metrics are enabled, register the disconnection of a peer based on its protocol. if let Some(metrics) = self.metrics.as_mut() { let peer_kind = &self .connected_peers - .get(peer_id) + .get(&peer_id) .expect("Connected peer must be registered") .kind; metrics.peer_protocol_disconnected(peer_kind.clone()); } - self.connected_peers.remove(peer_id); + self.connected_peers.remove(&peer_id); if let Some((peer_score, ..)) = &mut self.peer_score { - peer_score.remove_peer(peer_id); + peer_score.remove_peer(&peer_id); } } } - fn inject_address_change( + fn on_address_change( &mut self, - peer: &PeerId, - _: &ConnectionId, - endpoint_old: &ConnectedPoint, - endpoint_new: &ConnectedPoint, + AddressChange { + peer_id, + old: endpoint_old, + new: endpoint_new, + .. + }: AddressChange, ) { // Exchange IP in peer scoring system if let Some((peer_score, ..)) = &mut self.peer_score { if let Some(ip) = get_ip_addr(endpoint_old.get_remote_address()) { - peer_score.remove_ip(peer, &ip); + peer_score.remove_ip(&peer_id, &ip); } else { trace!( "Couldn't extract ip from endpoint of peer {} with endpoint {:?}", - peer, + &peer_id, endpoint_old ) } if let Some(ip) = get_ip_addr(endpoint_new.get_remote_address()) { - peer_score.add_ip(peer, ip); + peer_score.add_ip(&peer_id, ip); } else { trace!( "Couldn't extract ip from endpoint of peer {} with endpoint {:?}", - peer, + peer_id, endpoint_new ) } } } +} + +fn get_ip_addr(addr: &Multiaddr) -> Option { + addr.iter().find_map(|p| match p { + Ip4(addr) => Some(IpAddr::V4(addr)), + Ip6(addr) => Some(IpAddr::V6(addr)), + _ => None, + }) +} + +impl NetworkBehaviour for Gossipsub +where + C: Send + 'static + DataTransform, + F: Send + 'static + TopicSubscriptionFilter, +{ + type ConnectionHandler = GossipsubHandler; + type OutEvent = GossipsubEvent; - fn inject_event( + fn new_handler(&mut self) -> Self::ConnectionHandler { + let protocol_config = ProtocolConfig::new( + self.config.protocol_id().clone(), + self.config.custom_id_version().clone(), + self.config.max_transmit_size(), + self.config.validation_mode().clone(), + self.config.support_floodsub(), + ); + + GossipsubHandler::new(protocol_config, self.config.idle_timeout()) + } + + fn on_connection_handler_event( &mut self, propagation_source: PeerId, - _: ConnectionId, - handler_event: HandlerEvent, + _connection_id: ConnectionId, + handler_event: <::Handler as + ConnectionHandler>::OutEvent, ) { match handler_event { HandlerEvent::PeerKind(kind) => { @@ -3333,7 +3342,8 @@ where )); } else if let Some(conn) = self.connected_peers.get_mut(&propagation_source) { // Only change the value if the old value is Floodsub (the default set in - // inject_connection_established). All other PeerKind changes are ignored. + // `NetworkBehaviour::on_event` with FromSwarm::ConnectionEstablished). + // All other PeerKind changes are ignored. debug!( "New peer type found: {} for peer: {}", kind, propagation_source @@ -3458,6 +3468,27 @@ where Poll::Pending } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::AddressChange(address_change) => self.on_address_change(address_change), + FromSwarm::DialFailure(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } } /// This is called when peers are added to any mesh. It checks if the peer existed diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 71f4aae9b50..9bf32d8ff43 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -31,7 +31,7 @@ use crate::{ }; use async_std::net::Ipv4Addr; use byteorder::{BigEndian, ByteOrder}; -use libp2p_core::Endpoint; +use libp2p_core::{ConnectedPoint, Endpoint}; use rand::Rng; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -181,25 +181,27 @@ where F: TopicSubscriptionFilter + Clone + Default + Send + 'static, { let peer = PeerId::random(); - gs.inject_connection_established( - &peer, - &ConnectionId::new(0), - &if outbound { - ConnectedPoint::Dialer { - address, - role_override: Endpoint::Dialer, - } - } else { - ConnectedPoint::Listener { - local_addr: Multiaddr::empty(), - send_back_addr: address, - } - }, - None, - 0, // first connection - ); + let endpoint = if outbound { + ConnectedPoint::Dialer { + address, + role_override: Endpoint::Dialer, + } + } else { + ConnectedPoint::Listener { + local_addr: Multiaddr::empty(), + send_back_addr: address, + } + }; + + gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id: peer, + connection_id: ConnectionId::new(0), + endpoint: &endpoint, + failed_addresses: &[], + other_established: 0, // first connection + })); if let Some(kind) = kind { - gs.inject_event(peer, ConnectionId::new(1), HandlerEvent::PeerKind(kind)); + gs.on_connection_handler_event(peer, ConnectionId::new(1), HandlerEvent::PeerKind(kind)); } if explicit { gs.add_explicit_peer(&peer); @@ -232,16 +234,16 @@ where }; // this is not relevant // peer_connections.connections should never be empty. let mut active_connections = peer_connections.connections.len(); - for conn_id in peer_connections.connections.clone() { + for connection_id in peer_connections.connections.clone() { let handler = gs.new_handler(); active_connections = active_connections.checked_sub(1).unwrap(); - gs.inject_connection_closed( - peer_id, - &conn_id, - &fake_endpoint, + gs.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id: *peer_id, + connection_id, + endpoint: &fake_endpoint, handler, - active_connections, - ); + remaining_established: active_connections, + })); } } } @@ -545,16 +547,16 @@ fn test_join() { for _ in 0..3 { let random_peer = PeerId::random(); // inform the behaviour of a new peer - gs.inject_connection_established( - &random_peer, - &ConnectionId::new(1), - &ConnectedPoint::Dialer { + gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id: random_peer, + connection_id: ConnectionId::new(1), + endpoint: &ConnectedPoint::Dialer { address: "/ip4/127.0.0.1".parse::().unwrap(), role_override: Endpoint::Dialer, }, - None, - 0, - ); + failed_addresses: &[], + other_established: 0, + })); // add the new peer to the fanout let fanout_peers = gs.fanout.get_mut(&topic_hashes[1]).unwrap(); @@ -2349,12 +2351,6 @@ fn test_add_outbound_peers_if_min_is_not_satisfied() { ); } -//TODO add a test that ensures that new outbound connections are recognized as such. -// This is at the moment done in behaviour with relying on the fact that the call to -// `inject_connection_established` for the first connection is done before `inject_connected` -// gets called. For all further connections `inject_connection_established` should get called -// after `inject_connected`. - #[test] fn test_prune_negative_scored_peers() { let config = GossipsubConfig::default(); @@ -2983,7 +2979,7 @@ fn test_ignore_rpc_from_peers_below_graylist_threshold() { gs.events.clear(); //receive from p1 - gs.inject_event( + gs.on_connection_handler_event( p1, ConnectionId::new(0), HandlerEvent::Message { @@ -3009,7 +3005,7 @@ fn test_ignore_rpc_from_peers_below_graylist_threshold() { }; //receive from p2 - gs.inject_event( + gs.on_connection_handler_event( p2, ConnectionId::new(0), HandlerEvent::Message { @@ -3621,7 +3617,7 @@ fn test_scoring_p4_invalid_signature() { //peer 0 delivers message with invalid signature let m = random_message(&mut seq, &topics); - gs.inject_event( + gs.on_connection_handler_event( peers[0], ConnectionId::new(0), HandlerEvent::Message { @@ -4105,16 +4101,16 @@ fn test_scoring_p6() { //add additional connection for 3 others with addr for id in others.iter().take(3) { - gs.inject_connection_established( - id, - &ConnectionId::new(0), - &ConnectedPoint::Dialer { + gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id: *id, + connection_id: ConnectionId::new(0), + endpoint: &ConnectedPoint::Dialer { address: addr.clone(), role_override: Endpoint::Dialer, }, - None, - 0, - ); + failed_addresses: &[], + other_established: 0, + })); } //penalties apply squared @@ -4126,16 +4122,16 @@ fn test_scoring_p6() { //add additional connection for 3 of the peers to addr2 for peer in peers.iter().take(3) { - gs.inject_connection_established( - peer, - &ConnectionId::new(0), - &ConnectedPoint::Dialer { + gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id: *peer, + connection_id: ConnectionId::new(0), + endpoint: &ConnectedPoint::Dialer { address: addr2.clone(), role_override: Endpoint::Dialer, }, - None, - 1, - ); + failed_addresses: &[], + other_established: 1, + })); } //double penalties for the first three of each @@ -4156,16 +4152,16 @@ fn test_scoring_p6() { ); //two times same ip doesn't count twice - gs.inject_connection_established( - &peers[0], - &ConnectionId::new(0), - &ConnectedPoint::Dialer { + gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id: peers[0], + connection_id: ConnectionId::new(0), + endpoint: &ConnectedPoint::Dialer { address: addr, role_override: Endpoint::Dialer, }, - None, - 2, - ); + failed_addresses: &[], + other_established: 2, + })); //nothing changed //double penalties for the first three of each @@ -5203,7 +5199,7 @@ fn test_subscribe_and_graft_with_negative_score() { _ => None, }); for message in messages_to_p1 { - gs1.inject_event( + gs1.on_connection_handler_event( p2, connection_id, HandlerEvent::Message { diff --git a/protocols/identify/CHANGELOG.md b/protocols/identify/CHANGELOG.md index 40f20b96ce6..a91ce9789f2 100644 --- a/protocols/identify/CHANGELOG.md +++ b/protocols/identify/CHANGELOG.md @@ -8,6 +8,10 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 [PR 2995]: https://github.com/libp2p/rust-libp2p/pull/2995 # 0.40.0 diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 2215fde0ee8..10bfab3ed7d 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -22,9 +22,9 @@ use crate::handler::{self, Proto, Push}; use crate::protocol::{Info, ReplySubstream, UpgradeError}; use futures::prelude::*; use libp2p_core::{ - connection::ConnectionId, multiaddr::Protocol, transport::ListenerId, ConnectedPoint, - Multiaddr, PeerId, PublicKey, + connection::ConnectionId, multiaddr::Protocol, ConnectedPoint, Multiaddr, PeerId, PublicKey, }; +use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, IntoConnectionHandler, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, @@ -206,23 +206,16 @@ impl Behaviour { } } } -} -impl NetworkBehaviour for Behaviour { - type ConnectionHandler = Proto; - type OutEvent = Event; - - fn new_handler(&mut self) -> Self::ConnectionHandler { - Proto::new(self.config.initial_delay, self.config.interval) - } - - fn inject_connection_established( + fn on_connection_established( &mut self, - peer_id: &PeerId, - conn: &ConnectionId, - endpoint: &ConnectedPoint, - failed_addresses: Option<&Vec>, - _other_established: usize, + ConnectionEstablished { + peer_id, + connection_id: conn, + endpoint, + failed_addresses, + .. + }: ConnectionEstablished, ) { let addr = match endpoint { ConnectedPoint::Dialer { address, .. } => address.clone(), @@ -230,70 +223,27 @@ impl NetworkBehaviour for Behaviour { }; self.connected - .entry(*peer_id) + .entry(peer_id) .or_default() - .insert(*conn, addr); + .insert(conn, addr); - if let Some(entry) = self.discovered_peers.get_mut(peer_id) { - for addr in failed_addresses - .into_iter() - .flat_map(|addresses| addresses.iter()) - { + if let Some(entry) = self.discovered_peers.get_mut(&peer_id) { + for addr in failed_addresses { entry.remove(addr); } } } +} - fn inject_connection_closed( - &mut self, - peer_id: &PeerId, - conn: &ConnectionId, - _: &ConnectedPoint, - _: ::Handler, - remaining_established: usize, - ) { - if remaining_established == 0 { - self.connected.remove(peer_id); - self.pending_push.remove(peer_id); - } else if let Some(addrs) = self.connected.get_mut(peer_id) { - addrs.remove(conn); - } - } - - fn inject_dial_failure( - &mut self, - peer_id: Option, - _: Self::ConnectionHandler, - 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 { - for (addr, _error) in errors { - entry.remove(addr); - } - } - } - } - - fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) { - if self.config.push_listen_addr_updates { - self.pending_push.extend(self.connected.keys()); - } - } +impl NetworkBehaviour for Behaviour { + type ConnectionHandler = Proto; + type OutEvent = Event; - fn inject_expired_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) { - if self.config.push_listen_addr_updates { - self.pending_push.extend(self.connected.keys()); - } + fn new_handler(&mut self) -> Self::ConnectionHandler { + Proto::new(self.config.initial_delay, self.config.interval) } - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: PeerId, connection: ConnectionId, @@ -333,8 +283,9 @@ impl NetworkBehaviour for Behaviour { .get(&peer_id) .and_then(|addrs| addrs.get(&connection)) .expect( - "`inject_event` is only called with an established connection \ - and `inject_connection_established` ensures there is an entry; qed", + "`on_connection_handler_event` is only called \ + with an established connection and calling `NetworkBehaviour::on_event` \ + with `FromSwarm::ConnectionEstablished ensures there is an entry; qed", ); self.pending_replies.push_back(Reply::Queued { peer: peer_id, @@ -452,6 +403,59 @@ impl NetworkBehaviour for Behaviour { fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { self.discovered_peers.get(peer) } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + connection_id, + remaining_established, + .. + }) => { + if remaining_established == 0 { + self.connected.remove(&peer_id); + self.pending_push.remove(&peer_id); + } else if let Some(addrs) = self.connected.get_mut(&peer_id) { + addrs.remove(&connection_id); + } + } + FromSwarm::DialFailure(DialFailure { peer_id, error, .. }) => { + 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 { + for (addr, _error) in errors { + entry.remove(addr); + } + } + } + } + FromSwarm::NewListenAddr(_) => { + if self.config.push_listen_addr_updates { + self.pending_push.extend(self.connected.keys()); + } + } + FromSwarm::ExpiredListenAddr(_) => { + if self.config.push_listen_addr_updates { + self.pending_push.extend(self.connected.keys()); + } + } + FromSwarm::AddressChange(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } } /// Event emitted by the `Identify` behaviour. diff --git a/protocols/kad/CHANGELOG.md b/protocols/kad/CHANGELOG.md index 3d996c677a3..a4b23ebd757 100644 --- a/protocols/kad/CHANGELOG.md +++ b/protocols/kad/CHANGELOG.md @@ -4,6 +4,11 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `Kademlia`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 + # 0.41.0 - Remove deprecated `set_protocol_name()` from `KademliaConfig` & `KademliaProtocolConfig`. diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index d5009e0b3f7..b113deb64d5 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -39,8 +39,10 @@ use crate::record::{ use crate::K_VALUE; use fnv::{FnvHashMap, FnvHashSet}; use instant::Instant; -use libp2p_core::{ - connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, +use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; +use libp2p_swarm::behaviour::{ + AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredListenAddr, + FromSwarm, NewExternalAddr, NewListenAddr, }; use libp2p_swarm::{ dial_opts::{self, DialOpts}, @@ -1771,62 +1773,18 @@ where } } } -} - -/// Exponentially decrease the given duration (base 2). -fn exp_decrease(ttl: Duration, exp: u32) -> Duration { - Duration::from_secs(ttl.as_secs().checked_shr(exp).unwrap_or(0)) -} - -impl NetworkBehaviour for Kademlia -where - for<'a> TStore: RecordStore<'a>, - TStore: Send + 'static, -{ - type ConnectionHandler = KademliaHandlerProto; - type OutEvent = KademliaEvent; - 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 addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { - // We should order addresses from decreasing likelyhood of connectivity, so start with - // the addresses of that peer in the k-buckets. - let key = kbucket::Key::from(*peer_id); - let mut peer_addrs = - if let kbucket::Entry::Present(mut entry, _) = self.kbuckets.entry(&key) { - let addrs = entry.value().iter().cloned().collect::>(); - debug_assert!(!addrs.is_empty(), "Empty peer addresses in routing table."); - addrs - } else { - Vec::new() - }; - - // We add to that a temporary list of addresses from the ongoing queries. - for query in self.queries.iter() { - if let Some(addrs) = query.inner.addresses.get(peer_id) { - peer_addrs.extend(addrs.iter().cloned()) - } - } - - peer_addrs - } - - fn inject_connection_established( + fn on_connection_established( &mut self, - peer_id: &PeerId, - _: &ConnectionId, - _: &ConnectedPoint, - errors: Option<&Vec>, - other_established: usize, + ConnectionEstablished { + peer_id, + failed_addresses, + other_established, + .. + }: ConnectionEstablished, ) { - for addr in errors.map(|a| a.iter()).into_iter().flatten() { - self.address_failed(*peer_id, addr); + for addr in failed_addresses { + self.address_failed(peer_id, addr); } // When a connection is established, we don't know yet whether the @@ -1842,7 +1800,7 @@ where q.inner .pending_rpcs .iter() - .position(|(p, _)| p == peer_id) + .position(|(p, _)| p == &peer_id) .map(|p| q.inner.pending_rpcs.remove(p)) }) { self.queued_events @@ -1853,21 +1811,23 @@ where }); } - self.connected_peers.insert(*peer_id); + self.connected_peers.insert(peer_id); } } - fn inject_address_change( + fn on_address_change( &mut self, - peer: &PeerId, - _: &ConnectionId, - old: &ConnectedPoint, - new: &ConnectedPoint, + AddressChange { + peer_id: peer, + old, + new, + .. + }: AddressChange, ) { let (old, new) = (old.get_remote_address(), new.get_remote_address()); // Update routing table. - if let Some(addrs) = self.kbuckets.entry(&kbucket::Key::from(*peer)).value() { + if let Some(addrs) = self.kbuckets.entry(&kbucket::Key::from(peer)).value() { if addrs.replace(old, new) { debug!( "Address '{}' replaced with '{}' for peer '{}'.", @@ -1877,14 +1837,14 @@ where debug!( "Address '{}' not replaced with '{}' for peer '{}' as old address wasn't \ present.", - old, new, peer, + old, new, peer ); } } else { debug!( "Address '{}' not replaced with '{}' for peer '{}' as peer is not present in the \ routing table.", - old, new, peer, + old, new, peer ); } @@ -1903,7 +1863,7 @@ where // large performance impact. If so, the code below might be worth // revisiting. for query in self.queries.iter_mut() { - if let Some(addrs) = query.inner.addresses.get_mut(peer) { + if let Some(addrs) = query.inner.addresses.get_mut(&peer) { for addr in addrs.iter_mut() { if addr == old { *addr = new.clone(); @@ -1913,11 +1873,11 @@ where } } - fn inject_dial_failure( + fn on_dial_failure( &mut self, - peer_id: Option, - _: Self::ConnectionHandler, - error: &DialError, + DialFailure { peer_id, error, .. }: DialFailure< + ::ConnectionHandler, + >, ) { let peer_id = match peer_id { Some(id) => id, @@ -1957,24 +1917,69 @@ where } } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - id: &PeerId, - _: &ConnectionId, - _: &ConnectedPoint, - _: ::Handler, - remaining_established: usize, + ConnectionClosed { + peer_id, + remaining_established, + .. + }: ConnectionClosed<::ConnectionHandler>, ) { if remaining_established == 0 { for query in self.queries.iter_mut() { - query.on_failure(id); + query.on_failure(&peer_id); } - self.connection_updated(*id, None, NodeStatus::Disconnected); - self.connected_peers.remove(id); + self.connection_updated(peer_id, None, NodeStatus::Disconnected); + self.connected_peers.remove(&peer_id); } } +} - fn inject_event( +/// Exponentially decrease the given duration (base 2). +fn exp_decrease(ttl: Duration, exp: u32) -> Duration { + Duration::from_secs(ttl.as_secs().checked_shr(exp).unwrap_or(0)) +} + +impl NetworkBehaviour for Kademlia +where + for<'a> TStore: RecordStore<'a>, + TStore: Send + 'static, +{ + type ConnectionHandler = KademliaHandlerProto; + type OutEvent = KademliaEvent; + + 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 addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { + // We should order addresses from decreasing likelyhood of connectivity, so start with + // the addresses of that peer in the k-buckets. + let key = kbucket::Key::from(*peer_id); + let mut peer_addrs = + if let kbucket::Entry::Present(mut entry, _) = self.kbuckets.entry(&key) { + let addrs = entry.value().iter().cloned().collect::>(); + debug_assert!(!addrs.is_empty(), "Empty peer addresses in routing table."); + addrs + } else { + Vec::new() + }; + + // We add to that a temporary list of addresses from the ongoing queries. + for query in self.queries.iter() { + if let Some(addrs) = query.inner.addresses.get(peer_id) { + peer_addrs.extend(addrs.iter().cloned()) + } + } + + peer_addrs + } + + fn on_connection_handler_event( &mut self, source: PeerId, connection: ConnectionId, @@ -2225,20 +2230,6 @@ where }; } - fn inject_new_listen_addr(&mut self, _id: ListenerId, addr: &Multiaddr) { - self.local_addrs.insert(addr.clone()); - } - - fn inject_expired_listen_addr(&mut self, _id: ListenerId, addr: &Multiaddr) { - self.local_addrs.remove(addr); - } - - fn inject_new_external_addr(&mut self, addr: &Multiaddr) { - if self.local_addrs.len() < MAX_LOCAL_EXTERNAL_ADDRS { - self.local_addrs.insert(addr.clone()); - } - } - fn poll( &mut self, cx: &mut Context<'_>, @@ -2360,6 +2351,35 @@ where } } } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure), + FromSwarm::AddressChange(address_change) => self.on_address_change(address_change), + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { addr, .. }) => { + self.local_addrs.remove(addr); + } + FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => { + if self.local_addrs.len() < MAX_LOCAL_EXTERNAL_ADDRS { + self.local_addrs.insert(addr.clone()); + } + } + FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => { + self.local_addrs.insert(addr.clone()); + } + FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } } /// A quorum w.r.t. the configured replication factor specifies the minimum diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index 47da12904bb..5af60dc0c29 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -1277,7 +1277,7 @@ fn manual_bucket_inserts() { } #[test] -fn network_behaviour_inject_address_change() { +fn network_behaviour_on_address_change() { let local_peer_id = PeerId::random(); let remote_peer_id = PeerId::random(); @@ -1293,7 +1293,13 @@ fn network_behaviour_inject_address_change() { }; // Mimick a connection being established. - kademlia.inject_connection_established(&remote_peer_id, &connection_id, &endpoint, None, 0); + kademlia.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id: remote_peer_id, + connection_id, + endpoint: &endpoint, + failed_addresses: &[], + other_established: 0, + })); // At this point the remote is not yet known to support the // configured protocol name, so the peer is not yet in the @@ -1302,7 +1308,7 @@ fn network_behaviour_inject_address_change() { // Mimick the connection handler confirming the protocol for // the test connection, so that the peer is added to the routing table. - kademlia.inject_event( + kademlia.on_connection_handler_event( remote_peer_id, connection_id, KademliaHandlerEvent::ProtocolConfirmed { endpoint }, @@ -1313,18 +1319,18 @@ fn network_behaviour_inject_address_change() { kademlia.addresses_of_peer(&remote_peer_id), ); - kademlia.inject_address_change( - &remote_peer_id, - &connection_id, - &ConnectedPoint::Dialer { + kademlia.on_swarm_event(FromSwarm::AddressChange(AddressChange { + peer_id: remote_peer_id, + connection_id, + old: &ConnectedPoint::Dialer { address: old_address, role_override: Endpoint::Dialer, }, - &ConnectedPoint::Dialer { + new: &ConnectedPoint::Dialer { address: new_address.clone(), role_override: Endpoint::Dialer, }, - ); + })); assert_eq!( vec![new_address], diff --git a/protocols/mdns/CHANGELOG.md b/protocols/mdns/CHANGELOG.md index b75746c62b9..aa7e60c846e 100644 --- a/protocols/mdns/CHANGELOG.md +++ b/protocols/mdns/CHANGELOG.md @@ -4,8 +4,12 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `GenMdns`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + - Use `trust-dns-proto` to parse DNS messages. See [PR 3102]. +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 [PR 3102]: https://github.com/libp2p/rust-libp2p/pull/3102 # 0.41.0 diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index b19845ac1d7..9c635886b6b 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -27,8 +27,8 @@ use crate::behaviour::{socket::AsyncSocket, timer::Builder}; use crate::MdnsConfig; use futures::Stream; use if_watch::{IfEvent, IfWatcher}; -use libp2p_core::transport::ListenerId; use libp2p_core::{Multiaddr, PeerId}; +use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ dummy, ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; @@ -133,7 +133,7 @@ where .collect() } - fn inject_event( + fn on_connection_handler_event( &mut self, _: PeerId, _: libp2p_core::connection::ConnectionId, @@ -142,23 +142,33 @@ where void::unreachable(ev) } - fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) { - log::trace!("waking interface state because listening address changed"); - for iface in self.iface_states.values_mut() { - iface.fire_timer(); - } - } - - 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 on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + remaining_established, + .. + }) => { + if remaining_established == 0 { + self.expire_node(&peer_id); + } + } + FromSwarm::NewListener(_) => { + log::trace!("waking interface state because listening address changed"); + for iface in self.iface_states.values_mut() { + iface.fire_timer(); + } + } + FromSwarm::ConnectionEstablished(_) + | FromSwarm::DialFailure(_) + | FromSwarm::AddressChange(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} } } diff --git a/protocols/ping/CHANGELOG.md b/protocols/ping/CHANGELOG.md index d9011e22444..26fc9835e4d 100644 --- a/protocols/ping/CHANGELOG.md +++ b/protocols/ping/CHANGELOG.md @@ -4,6 +4,11 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `Behaviour`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 + # 0.40.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 02babd2ea06..6e481500df9 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -48,7 +48,9 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, PeerId}; -use libp2p_swarm::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use libp2p_swarm::{ + behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, +}; use std::{ collections::VecDeque, task::{Context, Poll}, @@ -121,7 +123,7 @@ impl NetworkBehaviour for Behaviour { Handler::new(self.config.clone()) } - fn inject_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) { + fn on_connection_handler_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) { self.events.push_front(Event { peer, result }) } @@ -144,4 +146,24 @@ impl NetworkBehaviour for Behaviour { Poll::Pending } } + + fn on_swarm_event( + &mut self, + event: libp2p_swarm::behaviour::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(_) => {} + } + } } diff --git a/protocols/relay/CHANGELOG.md b/protocols/relay/CHANGELOG.md index 088dd802d4b..27f567c81d8 100644 --- a/protocols/relay/CHANGELOG.md +++ b/protocols/relay/CHANGELOG.md @@ -6,6 +6,11 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `Client` and `Relay`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 + # 0.13.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 68e69e20a28..d9a2d977588 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -32,10 +32,10 @@ use futures::future::{BoxFuture, FutureExt}; use futures::io::{AsyncRead, AsyncWrite}; use futures::ready; use futures::stream::StreamExt; -use libp2p_core::connection::{ConnectedPoint, ConnectionId}; -use libp2p_core::{Multiaddr, PeerId}; +use libp2p_core::connection::ConnectionId; +use libp2p_core::PeerId; +use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; -use libp2p_swarm::dummy; use libp2p_swarm::{ ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, @@ -113,47 +113,23 @@ impl Client { }; (transport, behaviour) } -} - -impl NetworkBehaviour for Client { - type ConnectionHandler = handler::Prototype; - type OutEvent = Event; - - fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::new(self.local_peer_id, None) - } - - fn inject_connection_established( - &mut self, - peer_id: &PeerId, - connection_id: &ConnectionId, - endpoint: &ConnectedPoint, - _failed_addresses: Option<&Vec>, - _other_established: usize, - ) { - if !endpoint.is_relayed() { - self.directly_connected_peers - .entry(*peer_id) - .or_default() - .push(*connection_id); - } - } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - peer_id: &PeerId, - connection_id: &ConnectionId, - endpoint: &ConnectedPoint, - _handler: Either, - _remaining_established: usize, + ConnectionClosed { + peer_id, + connection_id, + endpoint, + .. + }: ConnectionClosed<::ConnectionHandler>, ) { if !endpoint.is_relayed() { - match self.directly_connected_peers.entry(*peer_id) { + match self.directly_connected_peers.entry(peer_id) { hash_map::Entry::Occupied(mut connections) => { let position = connections .get() .iter() - .position(|c| c == connection_id) + .position(|c| c == &connection_id) .expect("Connection to be known."); connections.get_mut().remove(position); @@ -167,8 +143,48 @@ impl NetworkBehaviour for Client { }; } } +} + +impl NetworkBehaviour for Client { + type ConnectionHandler = handler::Prototype; + type OutEvent = Event; + + fn new_handler(&mut self) -> Self::ConnectionHandler { + handler::Prototype::new(self.local_peer_id, None) + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id, + connection_id, + endpoint, + .. + }) => { + if !endpoint.is_relayed() { + self.directly_connected_peers + .entry(peer_id) + .or_default() + .push(connection_id); + } + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::AddressChange(_) + | FromSwarm::DialFailure(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } - fn inject_event( + fn on_connection_handler_event( &mut self, event_source: PeerId, _connection: ConnectionId, diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index a53024b3e94..42ccdd69069 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -27,11 +27,12 @@ use crate::v2::message_proto; use crate::v2::protocol::inbound_hop; use either::Either; use instant::Instant; -use libp2p_core::connection::{ConnectedPoint, ConnectionId}; +use libp2p_core::connection::ConnectionId; use libp2p_core::multiaddr::Protocol; use libp2p_core::PeerId; +use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - dummy, ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, + ConnectionHandlerUpgrErr, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; use std::collections::{hash_map, HashMap, HashSet, VecDeque}; @@ -212,32 +213,17 @@ impl Relay { queued_actions: Default::default(), } } -} - -impl NetworkBehaviour for Relay { - type ConnectionHandler = handler::Prototype; - type OutEvent = Event; - - 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 inject_connection_closed( + fn on_connection_closed( &mut self, - peer: &PeerId, - connection: &ConnectionId, - _: &ConnectedPoint, - _handler: Either, - _remaining_established: usize, + ConnectionClosed { + peer_id, + connection_id, + .. + }: ConnectionClosed<::ConnectionHandler>, ) { - if let hash_map::Entry::Occupied(mut peer) = self.reservations.entry(*peer) { - peer.get_mut().remove(connection); + if let hash_map::Entry::Occupied(mut peer) = self.reservations.entry(peer_id) { + peer.get_mut().remove(&connection_id); if peer.get().is_empty() { peer.remove(); } @@ -245,7 +231,7 @@ impl NetworkBehaviour for Relay { for circuit in self .circuits - .remove_by_connection(*peer, *connection) + .remove_by_connection(peer_id, connection_id) .iter() // Only emit [`CircuitClosed`] for accepted requests. .filter(|c| matches!(c.status, CircuitStatus::Accepted)) @@ -260,8 +246,42 @@ impl NetworkBehaviour for Relay { ); } } +} + +impl NetworkBehaviour for Relay { + type ConnectionHandler = handler::Prototype; + type OutEvent = Event; + + 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 on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::ConnectionEstablished(_) + | FromSwarm::DialFailure(_) + | FromSwarm::AddressChange(_) + | FromSwarm::ListenFailure(_) + | FromSwarm::NewListener(_) + | FromSwarm::NewListenAddr(_) + | FromSwarm::ExpiredListenAddr(_) + | FromSwarm::ListenerError(_) + | FromSwarm::ListenerClosed(_) + | FromSwarm::NewExternalAddr(_) + | FromSwarm::ExpiredExternalAddr(_) => {} + } + } - fn inject_event( + fn on_connection_handler_event( &mut self, event_source: PeerId, connection: ConnectionId, diff --git a/protocols/rendezvous/CHANGELOG.md b/protocols/rendezvous/CHANGELOG.md index 8f25041503d..e081eb2fd71 100644 --- a/protocols/rendezvous/CHANGELOG.md +++ b/protocols/rendezvous/CHANGELOG.md @@ -1,11 +1,15 @@ # 0.11.0 [unreleased] -- De- and encode protobuf messages using `prost-codec`. See [PR 3058]. +- De- and encode protobuf messages using `prost-codec`. See [PR 3058]. - Update to `libp2p-core` `v0.38.0`. - Update to `libp2p-swarm` `v0.41.0`. +- Replace `Client` and `Server`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 [PR 3058]: https://github.com/libp2p/rust-libp2p/pull/3058 # 0.10.0 diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 1eed9831cc6..5d44354992e 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -32,6 +32,7 @@ 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::FromSwarm; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -183,7 +184,7 @@ impl NetworkBehaviour for Behaviour { .collect() } - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: PeerId, connection_id: ConnectionId, @@ -265,6 +266,23 @@ impl NetworkBehaviour for Behaviour { 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(_) => {} + } + } } fn handle_outbound_event( diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 4dfad583565..4126b6e3e28 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -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::FromSwarm; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; @@ -118,7 +119,7 @@ impl NetworkBehaviour for Behaviour { SubstreamConnectionHandler::new_inbound_only(initial_keep_alive) } - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: PeerId, connection: ConnectionId, @@ -160,6 +161,23 @@ impl NetworkBehaviour for Behaviour { 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(_) => {} + } + } } fn handle_inbound_event( diff --git a/protocols/request-response/CHANGELOG.md b/protocols/request-response/CHANGELOG.md index f70e2f99a62..59409581c90 100644 --- a/protocols/request-response/CHANGELOG.md +++ b/protocols/request-response/CHANGELOG.md @@ -4,6 +4,11 @@ - Update to `libp2p-swarm` `v0.41.0`. +- Replace `RequestResponse`'s `NetworkBehaviour` implemention `inject_*` methods with the new `on_*` methods. + See [PR 3011]. + +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 + # 0.22.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 887a42a9b6a..68c6212579c 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -68,8 +68,9 @@ use futures::channel::oneshot; use handler::{RequestProtocol, RequestResponseHandler, RequestResponseHandlerEvent}; use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::{ - dial_opts::DialOpts, DialError, IntoConnectionHandler, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, + behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, + dial_opts::DialOpts, + IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; use smallvec::SmallVec; use std::{ @@ -560,42 +561,15 @@ where .get_mut(peer) .and_then(|connections| connections.iter_mut().find(|c| c.id == connection)) } -} - -impl NetworkBehaviour for RequestResponse -where - TCodec: RequestResponseCodec + Send + Clone + 'static, -{ - type ConnectionHandler = RequestResponseHandler; - type OutEvent = RequestResponseEvent; - - fn new_handler(&mut self) -> Self::ConnectionHandler { - 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 { - let mut addresses = Vec::new(); - if let Some(connections) = self.connected.get(peer) { - addresses.extend(connections.iter().filter_map(|c| c.address.clone())) - } - if let Some(more) = self.addresses.get(peer) { - addresses.extend(more.into_iter().cloned()); - } - addresses - } - - fn inject_address_change( + fn on_address_change( &mut self, - peer: &PeerId, - conn: &ConnectionId, - _old: &ConnectedPoint, - new: &ConnectedPoint, + AddressChange { + peer_id, + connection_id, + new, + .. + }: AddressChange, ) { let new_address = match new { ConnectedPoint::Dialer { address, .. } => Some(address.clone()), @@ -603,72 +577,75 @@ where }; let connections = self .connected - .get_mut(peer) + .get_mut(&peer_id) .expect("Address change can only happen on an established connection."); let connection = connections .iter_mut() - .find(|c| &c.id == conn) + .find(|c| c.id == connection_id) .expect("Address change can only happen on an established connection."); connection.address = new_address; } - fn inject_connection_established( + fn on_connection_established( &mut self, - peer: &PeerId, - conn: &ConnectionId, - endpoint: &ConnectedPoint, - _errors: Option<&Vec>, - other_established: usize, + ConnectionEstablished { + peer_id, + connection_id, + endpoint, + other_established, + .. + }: ConnectionEstablished, ) { let address = match endpoint { ConnectedPoint::Dialer { address, .. } => Some(address.clone()), ConnectedPoint::Listener { .. } => None, }; self.connected - .entry(*peer) + .entry(peer_id) .or_default() - .push(Connection::new(*conn, address)); + .push(Connection::new(connection_id, address)); if other_established == 0 { - if let Some(pending) = self.pending_outbound_requests.remove(peer) { + if let Some(pending) = self.pending_outbound_requests.remove(&peer_id) { for request in pending { - let request = self.try_send_request(peer, request); + let request = self.try_send_request(&peer_id, request); assert!(request.is_none()); } } } } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - peer_id: &PeerId, - conn: &ConnectionId, - _: &ConnectedPoint, - _: ::Handler, - remaining_established: usize, + ConnectionClosed { + peer_id, + connection_id, + remaining_established, + .. + }: ConnectionClosed<::ConnectionHandler>, ) { let connections = self .connected - .get_mut(peer_id) + .get_mut(&peer_id) .expect("Expected some established connection to peer before closing."); let connection = connections .iter() - .position(|c| &c.id == conn) + .position(|c| c.id == connection_id) .map(|p: usize| connections.remove(p)) .expect("Expected connection to be established before closing."); debug_assert_eq!(connections.is_empty(), remaining_established == 0); if connections.is_empty() { - self.connected.remove(peer_id); + self.connected.remove(&peer_id); } for request_id in connection.pending_outbound_responses { self.pending_events .push_back(NetworkBehaviourAction::GenerateEvent( RequestResponseEvent::InboundFailure { - peer: *peer_id, + peer: peer_id, request_id, error: InboundFailure::ConnectionClosed, }, @@ -679,7 +656,7 @@ where self.pending_events .push_back(NetworkBehaviourAction::GenerateEvent( RequestResponseEvent::OutboundFailure { - peer: *peer_id, + peer: peer_id, request_id, error: OutboundFailure::ConnectionClosed, }, @@ -687,13 +664,11 @@ where } } - fn inject_dial_failure( + fn on_dial_failure( &mut self, - peer: Option, - _: Self::ConnectionHandler, - _: &DialError, + DialFailure { peer_id, .. }: DialFailure<::ConnectionHandler>, ) { - if let Some(peer) = peer { + 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 @@ -714,12 +689,63 @@ where } } } +} + +impl NetworkBehaviour for RequestResponse +where + TCodec: RequestResponseCodec + Send + Clone + 'static, +{ + type ConnectionHandler = RequestResponseHandler; + type OutEvent = RequestResponseEvent; + + fn new_handler(&mut self) -> Self::ConnectionHandler { + 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 { + let mut addresses = Vec::new(); + if let Some(connections) = self.connected.get(peer) { + addresses.extend(connections.iter().filter_map(|c| c.address.clone())) + } + if let Some(more) = self.addresses.get(peer) { + addresses.extend(more.into_iter().cloned()); + } + addresses + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::AddressChange(address_change) => self.on_address_change(address_change), + FromSwarm::DialFailure(dial_failure) => self.on_dial_failure(dial_failure), + FromSwarm::ListenFailure(_) => {} + FromSwarm::NewListener(_) => {} + FromSwarm::NewListenAddr(_) => {} + FromSwarm::ExpiredListenAddr(_) => {} + FromSwarm::ListenerError(_) => {} + FromSwarm::ListenerClosed(_) => {} + FromSwarm::NewExternalAddr(_) => {} + FromSwarm::ExpiredExternalAddr(_) => {} + } + } - fn inject_event( + fn on_connection_handler_event( &mut self, peer: PeerId, connection: ConnectionId, - event: RequestResponseHandlerEvent, + event: <::Handler as + libp2p_swarm::ConnectionHandler>::OutEvent, ) { match event { RequestResponseHandlerEvent::Response { diff --git a/swarm-derive/CHANGELOG.md b/swarm-derive/CHANGELOG.md index fc5fb868a7e..106c3a653c6 100644 --- a/swarm-derive/CHANGELOG.md +++ b/swarm-derive/CHANGELOG.md @@ -1,8 +1,13 @@ -# 0.30.2 [unreleased] +# 0.30.2 - [unreleased] + +- Replace `NetworkBehaviour` Derive macro deprecated `inject_*` method implementations + with the new `on_swarm_event` and `on_connection_handler_event`. + See [PR 3011]. - Add `prelude` configuration option. The derive-macro generates code that needs to refer to various symbols. See [PR 3055]. +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 [PR 3055]: https://github.com/libp2p/rust-libp2p/pull/3055 # 0.30.1 diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index fc8596e8be9..4af70e6a84a 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -48,7 +48,6 @@ fn build(ast: &DeriveInput) -> TokenStream { fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let name = &ast.ident; let (_, ty_generics, where_clause) = ast.generics.split_for_impl(); - let prelude_path = parse_attribute_value_by_key::(ast, "prelude") .unwrap_or_else(|| syn::parse_quote! { ::libp2p::swarm::derive_prelude }); @@ -61,11 +60,20 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let into_proto_select_ident = quote! { #prelude_path::IntoConnectionHandlerSelect }; let peer_id = quote! { #prelude_path::PeerId }; let connection_id = quote! { #prelude_path::ConnectionId }; - let dial_errors = quote! {Option<&Vec<#prelude_path::Multiaddr>> }; - let connected_point = quote! { #prelude_path::ConnectedPoint }; - let listener_id = quote! { #prelude_path::ListenerId }; - let dial_error = quote! { #prelude_path::DialError }; let poll_parameters = quote! { #prelude_path::PollParameters }; + let from_swarm = quote! { #prelude_path::FromSwarm }; + let connection_established = quote! { #prelude_path::ConnectionEstablished }; + let address_change = quote! { #prelude_path::AddressChange }; + let connection_closed = quote! { #prelude_path::ConnectionClosed }; + let dial_failure = quote! { #prelude_path::DialFailure }; + let listen_failure = quote! { #prelude_path::ListenFailure }; + let new_listener = quote! { #prelude_path::NewListener }; + let new_listen_addr = quote! { #prelude_path::NewListenAddr }; + let expired_listen_addr = quote! { #prelude_path::ExpiredListenAddr }; + let new_external_addr = quote! { #prelude_path::NewExternalAddr }; + let expired_external_addr = quote! { #prelude_path::ExpiredExternalAddr }; + let listener_error = quote! { #prelude_path::ListenerError }; + let listener_closed = quote! { #prelude_path::ListenerClosed }; // Build the generics. let impl_generics = { @@ -171,35 +179,50 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }) }; - // Build the list of statements to put in the body of `inject_connection_established()`. - let inject_connection_established_stmts = { - data_struct.fields.iter().enumerate().map(move |(field_n, field)| { - match field.ident { - Some(ref i) => quote!{ self.#i.inject_connection_established(peer_id, connection_id, endpoint, errors, other_established); }, - None => quote!{ self.#field_n.inject_connection_established(peer_id, connection_id, endpoint, errors, other_established); }, - } - }) + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::ConnectionEstablished` variant. + let on_connection_established_stmts = { + data_struct + .fields + .iter() + .enumerate() + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_connection_established(&peer_id, &connection_id, endpoint, Some(&failed_addresses.into()), other_established);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_connection_established(&peer_id, &connection_id, endpoint, Some(&failed_addresses.into()), other_established);}, + }) }; - // Build the list of statements to put in the body of `inject_address_change()`. - let inject_address_change_stmts = { - data_struct.fields.iter().enumerate().map(move |(field_n, field)| { - match field.ident { - Some(ref i) => quote!{ self.#i.inject_address_change(peer_id, connection_id, old, new); }, - None => quote!{ self.#field_n.inject_address_change(peer_id, connection_id, old, new); }, - } - }) + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::AddressChange variant`. + let on_address_change_stmts = { + data_struct + .fields + .iter() + .enumerate() + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_address_change(&peer_id, &connection_id, old, new);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_address_change(&peer_id, &connection_id, old, new);}, + }) }; - // Build the list of statements to put in the body of `inject_connection_closed()`. - let inject_connection_closed_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::ConnectionClosed` variant. + let on_connection_closed_stmts = { data_struct.fields .iter() .enumerate() // The outmost handler belongs to the last behaviour. .rev() .enumerate() - .map(move |(enum_n, (field_n, field))| { + .map(|(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 } @@ -209,8 +232,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } }; let inject = match field.ident { - Some(ref i) => quote!{ self.#i.inject_connection_closed(peer_id, connection_id, endpoint, handler, remaining_established) }, - None => quote!{ self.#enum_n.inject_connection_closed(peer_id, connection_id, endpoint, handler, remaining_established) }, + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_connection_closed(&peer_id, &connection_id, endpoint, handler, remaining_established);}, + None => quote! { + #[allow(deprecated)] + self.#enum_n.inject_connection_closed(&peer_id, &connection_id, endpoint, handler, remaining_established);}, }; quote! { @@ -220,8 +247,9 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }) }; - // Build the list of statements to put in the body of `inject_dial_failure()`. - let inject_dial_failure_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::DialFailure` variant. + let on_dial_failure_stmts = { data_struct .fields .iter() @@ -229,7 +257,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { // The outmost handler belongs to the last behaviour. .rev() .enumerate() - .map(move |(enum_n, (field_n, field))| { + .map(|(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 } @@ -240,12 +268,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }; 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) } - } + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_dial_failure(peer_id, handler, error);}, + None => quote! { + #[allow(deprecated)] + self.#enum_n.inject_dial_failure(peer_id, handler, error);}, }; quote! { @@ -255,138 +283,186 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }) }; - // Build the list of statements to put in the body of `inject_listen_failure()`. - let inject_listen_failure_stmts = { - 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() - } - }; + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::ListenFailure` variant. + let on_listen_failure_stmts = + { + data_struct.fields.iter().enumerate().rev().enumerate().map( + |(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) }, - }; + let inject = match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_listen_failure(local_addr, send_back_addr, handler);}, + None => quote! { + #[allow(deprecated)] + self.#enum_n.inject_listen_failure(local_addr, send_back_addr, handler);}, + }; - quote! { - #handler; - #inject; - } - }) - }; + quote! { + #handler; + #inject; + } + }, + ) + }; - // Build the list of statements to put in the body of `inject_new_listener()`. - let inject_new_listener_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::NewListener` variant. + let on_new_listener_stmts = { data_struct .fields .iter() .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote! { self.#i.inject_new_listener(id); }, - None => quote! { self.#field_n.inject_new_listener(id); }, + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_new_listener(listener_id);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_new_listener(listener_id);}, }) }; - // Build the list of statements to put in the body of `inject_new_listen_addr()`. - let inject_new_listen_addr_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::NewListenAddr` variant. + let on_new_listen_addr_stmts = { data_struct .fields .iter() .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote! { self.#i.inject_new_listen_addr(id, addr); }, - None => quote! { self.#field_n.inject_new_listen_addr(id, addr); }, + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_new_listen_addr(listener_id, addr);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_new_listen_addr(listener_id, addr);}, }) }; - // Build the list of statements to put in the body of `inject_expired_listen_addr()`. - let inject_expired_listen_addr_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::ExpiredListenAddr` variant. + let on_expired_listen_addr_stmts = { data_struct .fields .iter() .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote! { self.#i.inject_expired_listen_addr(id, addr); }, - None => quote! { self.#field_n.inject_expired_listen_addr(id, addr); }, + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_expired_listen_addr(listener_id, addr);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_expired_listen_addr(listener_id, addr);}, }) }; - // Build the list of statements to put in the body of `inject_new_external_addr()`. - let inject_new_external_addr_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::NewExternalAddr` variant. + let on_new_external_addr_stmts = { data_struct .fields .iter() .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote! { self.#i.inject_new_external_addr(addr); }, - None => quote! { self.#field_n.inject_new_external_addr(addr); }, + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_new_external_addr(addr);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_new_external_addr(addr);}, }) }; - // Build the list of statements to put in the body of `inject_expired_external_addr()`. - let inject_expired_external_addr_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::ExpiredExternalAddr` variant. + let on_expired_external_addr_stmts = { data_struct .fields .iter() .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote! { self.#i.inject_expired_external_addr(addr); }, - None => quote! { self.#field_n.inject_expired_external_addr(addr); }, + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_expired_external_addr(addr);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_expired_external_addr(addr);}, }) }; - // Build the list of statements to put in the body of `inject_listener_error()`. - let inject_listener_error_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::ListenerError` variant. + let on_listener_error_stmts = { data_struct .fields .iter() .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote!(self.#i.inject_listener_error(id, err);), - None => quote!(self.#field_n.inject_listener_error(id, err);), + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_listener_error(listener_id, err);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_listener_error(listener_id, err);}, }) }; - // Build the list of statements to put in the body of `inject_listener_closed()`. - let inject_listener_closed_stmts = { + // Build the list of statements to put in the body of `on_swarm_event()` + // for the `FromSwarm::ListenerClosed` variant. + let on_listener_closed_stmts = { data_struct .fields .iter() .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote!(self.#i.inject_listener_closed(id, reason);), - None => quote!(self.#field_n.inject_listener_closed(id, reason);), + .map(|(field_n, field)| match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_listener_closed(listener_id, reason);}, + None => quote! { + #[allow(deprecated)] + self.#field_n.inject_listener_closed(listener_id, reason);}, }) }; - // Build the list of variants to put in the body of `inject_event()`. + // Build the list of variants to put in the body of `on_connection_handler_event()`. // // The event type is a construction of nested `#either_ident`s of the events of the children. - // We call `inject_event` on the corresponding child. - let inject_node_event_stmts = data_struct.fields.iter().enumerate().enumerate().map(|(enum_n, (field_n, field))| { - let mut elem = if enum_n != 0 { - quote!{ #either_ident::Second(ev) } - } else { - quote!{ ev } - }; + // We call `on_connection_handler_event` on the corresponding child. + let on_node_event_stmts = + data_struct + .fields + .iter() + .enumerate() + .enumerate() + .map(|(enum_n, (field_n, field))| { + let mut elem = if enum_n != 0 { + quote! { #either_ident::Second(ev) } + } else { + quote! { ev } + }; - for _ in 0 .. data_struct.fields.len() - 1 - enum_n { - elem = quote!{ #either_ident::First(#elem) }; - } + for _ in 0..data_struct.fields.len() - 1 - enum_n { + elem = quote! { #either_ident::First(#elem) }; + } - Some(match field.ident { - Some(ref i) => quote!{ #elem => #trait_to_impl::inject_event(&mut self.#i, peer_id, connection_id, ev) }, - None => quote!{ #elem => #trait_to_impl::inject_event(&mut self.#field_n, peer_id, connection_id, ev) }, - }) - }); + Some(match field.ident { + Some(ref i) => quote! { #elem => { + #[allow(deprecated)] + #trait_to_impl::inject_event(&mut self.#i, peer_id, connection_id, ev) }}, + None => quote! { #elem => { + #[allow(deprecated)] + #trait_to_impl::inject_event(&mut self.#field_n, peer_id, connection_id, ev) }}, + }) + }); // The [`ConnectionHandler`] associated type. let connection_handler_ty = { @@ -555,62 +631,14 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { out } - fn inject_connection_established(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, endpoint: &#connected_point, errors: #dial_errors, other_established: usize) { - #(#inject_connection_established_stmts);* - } - - fn inject_address_change(&mut self, peer_id: &#peer_id, connection_id: &#connection_id, old: &#connected_point, new: &#connected_point) { - #(#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) { - #(#inject_connection_closed_stmts);* - } - - fn inject_dial_failure(&mut self, peer_id: Option<#peer_id>, handlers: Self::ConnectionHandler, error: &#dial_error) { - #(#inject_dial_failure_stmts);* - } - - fn inject_listen_failure(&mut self, local_addr: &#multiaddr, send_back_addr: &#multiaddr, handlers: Self::ConnectionHandler) { - #(#inject_listen_failure_stmts);* - } - - fn inject_new_listener(&mut self, id: #listener_id) { - #(#inject_new_listener_stmts);* - } - - fn inject_new_listen_addr(&mut self, id: #listener_id, addr: &#multiaddr) { - #(#inject_new_listen_addr_stmts);* - } - - fn inject_expired_listen_addr(&mut self, id: #listener_id, addr: &#multiaddr) { - #(#inject_expired_listen_addr_stmts);* - } - - fn inject_new_external_addr(&mut self, addr: &#multiaddr) { - #(#inject_new_external_addr_stmts);* - } - - fn inject_expired_external_addr(&mut self, addr: &#multiaddr) { - #(#inject_expired_external_addr_stmts);* - } - - fn inject_listener_error(&mut self, id: #listener_id, err: &(dyn std::error::Error + 'static)) { - #(#inject_listener_error_stmts);* - } - - fn inject_listener_closed(&mut self, id: #listener_id, reason: std::result::Result<(), &std::io::Error>) { - #(#inject_listener_closed_stmts);* - } - - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: #peer_id, connection_id: #connection_id, event: <::Handler as #connection_handler>::OutEvent ) { match event { - #(#inject_node_event_stmts),* + #(#on_node_event_stmts),* } } @@ -619,6 +647,48 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #(#poll_stmts)* std::task::Poll::Pending } + + fn on_swarm_event(&mut self, event: #from_swarm) { + match event { + #from_swarm::ConnectionEstablished( + #connection_established { peer_id, connection_id, endpoint, failed_addresses, other_established }) + => { #(#on_connection_established_stmts)* } + #from_swarm::AddressChange( + #address_change { peer_id, connection_id, old, new }) + => { #(#on_address_change_stmts)* } + #from_swarm::ConnectionClosed( + #connection_closed { peer_id, connection_id, endpoint, handler: handlers, remaining_established }) + => { #(#on_connection_closed_stmts)* } + #from_swarm::DialFailure( + #dial_failure { peer_id, handler: handlers, error }) + => { #(#on_dial_failure_stmts)* } + #from_swarm::ListenFailure( + #listen_failure { local_addr, send_back_addr, handler: handlers }) + => { #(#on_listen_failure_stmts)* } + #from_swarm::NewListener( + #new_listener { listener_id }) + => { #(#on_new_listener_stmts)* } + #from_swarm::NewListenAddr( + #new_listen_addr { listener_id, addr }) + => { #(#on_new_listen_addr_stmts)* } + #from_swarm::ExpiredListenAddr( + #expired_listen_addr { listener_id, addr }) + => { #(#on_expired_listen_addr_stmts)* } + #from_swarm::NewExternalAddr( + #new_external_addr { addr }) + => { #(#on_new_external_addr_stmts)* } + #from_swarm::ExpiredExternalAddr( + #expired_external_addr { addr }) + => { #(#on_expired_external_addr_stmts)* } + #from_swarm::ListenerError( + #listener_error { listener_id, err }) + => { #(#on_listener_error_stmts)* } + #from_swarm::ListenerClosed( + #listener_closed { listener_id, reason }) + => { #(#on_listener_closed_stmts)* } + _ => {} + } + } } }; diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index f04da3da77b..1d0c5882868 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -2,6 +2,20 @@ - Update to `libp2p-core` `v0.38.0`. +- Add new `on_swarm_event` method to `NetworkBehaviour` that accepts a `FromSwarm` enum and update + `inject_*` methods to call `on_swarm_event` with the respective `FromSwarm` variant and deprecate + `inject_*`. + To migrate, users should replace the `NetworkBehaviour::inject_*` calls with a single + implementation of `NetworkBehaviour::on_swarm_event` treating each `FromSwarm` variant in + the same way its corresponding `inject_*` call was treated. + See [PR 3011]. + +- Add new `on_connection_handler_event` method with the same signature as `inject_event`, make the + default implementation of `inject_event` call `on_connection_handler_event` and deprecate it. + To migrate, users should replace the `NetworkBehaviour::inject_event` call + with `NetworkBehaviour::on_connection_handler_event`. + See [PR 3011]. + - Export `NetworkBehaviour` derive as `libp2p_swarm::NetworkBehaviour`. This follows the convention of other popular libraries. `serde` for example exports the `Serialize` trait and macro as `serde::Serialize`. See [PR 3055]. @@ -9,7 +23,7 @@ - Feature-gate `NetworkBehaviour` macro behind `macros` feature flag. See [PR 3055]. - Make executor in Swarm constructor explicit. See [PR 3097]. - + Supported executors: - Tokio @@ -26,7 +40,7 @@ let swarm = Swarm::with_tokio_executor(transport, behaviour, peer_id); ``` - Async Std - + Previously ```rust let swarm = SwarmBuilder::new(transport, behaviour, peer_id) @@ -40,7 +54,7 @@ let swarm = Swarm::with_async_std_executor(transport, behaviour, peer_id); ``` - ThreadPool (see [Issue 3107]) - + In most cases ThreadPool can be replaced by executors or spawning on the local task. Previously @@ -53,19 +67,20 @@ let swarm = Swarm::with_threadpool_executor(transport, behaviour, peer_id); ``` - 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. New ```rust let swarm = Swarm::without_executor(transport, behaviour, peer_id); ``` - + Deprecated APIs: - `Swarm::new` - `SwarmBuilder::new` - `SwarmBuilder::executor` +[PR 3011]: https://github.com/libp2p/rust-libp2p/pull/3011 [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 diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 46f2d7c5012..6240e570888 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -153,39 +153,90 @@ pub trait NetworkBehaviour: 'static { vec![] } + /// Informs the behaviour about an event from the [`Swarm`](crate::Swarm). + fn on_swarm_event(&mut self, _event: FromSwarm) {} + + /// Informs the behaviour about an event generated by the [`ConnectionHandler`] dedicated to the + /// peer identified by `peer_id`. for the behaviour. + /// + /// The [`PeerId`] is guaranteed to be in a connected state. In other words, + /// [`FromSwarm::ConnectionEstablished`] has previously been received with this [`PeerId`]. + fn on_connection_handler_event( + &mut self, + _peer_id: PeerId, + _connection_id: ConnectionId, + _event: <::Handler as + ConnectionHandler>::OutEvent, + ) { + } + /// Informs the behaviour about a newly established connection to a peer. + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::ConnectionEstablished` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_connection_established( &mut self, - _peer_id: &PeerId, - _connection_id: &ConnectionId, - _endpoint: &ConnectedPoint, - _failed_addresses: Option<&Vec>, - _other_established: usize, + peer_id: &PeerId, + connection_id: &ConnectionId, + endpoint: &ConnectedPoint, + failed_addresses: Option<&Vec>, + other_established: usize, ) { + self.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id: *peer_id, + connection_id: *connection_id, + endpoint, + failed_addresses: failed_addresses + .map(|v| v.as_slice()) + .unwrap_or_else(|| &[]), + other_established, + })); } /// Informs the behaviour about a closed connection to a peer. /// /// A call to this method is always paired with an earlier call to /// [`NetworkBehaviour::inject_connection_established`] with the same peer ID, connection ID and endpoint. + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::ConnectionClosed` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_connection_closed( &mut self, - _: &PeerId, - _: &ConnectionId, - _: &ConnectedPoint, - _: ::Handler, - _remaining_established: usize, + peer_id: &PeerId, + connection_id: &ConnectionId, + endpoint: &ConnectedPoint, + handler: ::Handler, + remaining_established: usize, ) { + self.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id: *peer_id, + connection_id: *connection_id, + endpoint, + handler, + remaining_established, + })); } /// Informs the behaviour that the [`ConnectedPoint`] of an existing connection has changed. + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::AddressChange` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_address_change( &mut self, - _: &PeerId, - _: &ConnectionId, - _old: &ConnectedPoint, - _new: &ConnectedPoint, + peer_id: &PeerId, + connection_id: &ConnectionId, + old: &ConnectedPoint, + new: &ConnectedPoint, ) { + self.on_swarm_event(FromSwarm::AddressChange(AddressChange { + peer_id: *peer_id, + connection_id: *connection_id, + old, + new, + })); } /// Informs the behaviour about an event generated by the handler dedicated to the peer identified by `peer_id`. @@ -193,20 +244,35 @@ pub trait NetworkBehaviour: 'static { /// /// The `peer_id` is guaranteed to be in a connected state. In other words, /// [`NetworkBehaviour::inject_connection_established`] has previously been called with this `PeerId`. + #[deprecated( + since = "0.40.2", + note = "Implement `NetworkBehaviour::on_connection_handler_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_event( &mut self, peer_id: PeerId, connection: ConnectionId, event: <::Handler as ConnectionHandler>::OutEvent, - ); + ) { + self.on_connection_handler_event(peer_id, connection, event); + } /// Indicates to the behaviour that the dial to a known or unknown node failed. + #[deprecated( + since = "0.40.2", + note = "Handle `InEvent::DialFailure` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_dial_failure( &mut self, - _peer_id: Option, - _handler: Self::ConnectionHandler, - _error: &DialError, + peer_id: Option, + handler: Self::ConnectionHandler, + error: &DialError, ) { + self.on_swarm_event(FromSwarm::DialFailure(DialFailure { + peer_id, + handler, + error, + })); } /// Indicates to the behaviour that an error happened on an incoming connection during its @@ -214,36 +280,98 @@ pub trait NetworkBehaviour: 'static { /// /// This can include, for example, an error during the handshake of the encryption layer, or the /// connection unexpectedly closed. + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::ListenFailure` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] fn inject_listen_failure( &mut self, - _local_addr: &Multiaddr, - _send_back_addr: &Multiaddr, - _handler: Self::ConnectionHandler, + local_addr: &Multiaddr, + send_back_addr: &Multiaddr, + handler: Self::ConnectionHandler, ) { + self.on_swarm_event(FromSwarm::ListenFailure(ListenFailure { + local_addr, + send_back_addr, + handler, + })); } /// Indicates to the behaviour that a new listener was created. - fn inject_new_listener(&mut self, _id: ListenerId) {} + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::NewListener` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_new_listener(&mut self, id: ListenerId) { + self.on_swarm_event(FromSwarm::NewListener(NewListener { listener_id: id })); + } /// Indicates to the behaviour that we have started listening on a new multiaddr. - fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {} + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::NewListenAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { + self.on_swarm_event(FromSwarm::NewListenAddr(NewListenAddr { + listener_id: id, + addr, + })); + } /// Indicates to the behaviour that a multiaddr we were listening on has expired, - /// which means that we are no longer listening in it. - fn inject_expired_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {} + /// which means that we are no longer listening on it. + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::ExpiredListenAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { + self.on_swarm_event(FromSwarm::ExpiredListenAddr(ExpiredListenAddr { + listener_id: id, + addr, + })); + } /// A listener experienced an error. - fn inject_listener_error(&mut self, _id: ListenerId, _err: &(dyn std::error::Error + 'static)) { + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::ListenerError` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { + self.on_swarm_event(FromSwarm::ListenerError(ListenerError { + listener_id: id, + err, + })); } /// A listener closed. - fn inject_listener_closed(&mut self, _id: ListenerId, _reason: Result<(), &std::io::Error>) {} + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::ListenerClosed` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) { + self.on_swarm_event(FromSwarm::ListenerClosed(ListenerClosed { + listener_id: id, + reason, + })); + } /// Indicates to the behaviour that we have discovered a new external address for us. - fn inject_new_external_addr(&mut self, _addr: &Multiaddr) {} + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::NewExternalAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_new_external_addr(&mut self, addr: &Multiaddr) { + self.on_swarm_event(FromSwarm::NewExternalAddr(NewExternalAddr { addr })); + } /// Indicates to the behaviour that an external address was removed. - fn inject_expired_external_addr(&mut self, _addr: &Multiaddr) {} + #[deprecated( + since = "0.40.2", + note = "Handle `FromSwarm::ExpiredExternalAddr` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." + )] + fn inject_expired_external_addr(&mut self, addr: &Multiaddr) { + self.on_swarm_event(FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr })); + } /// Polls for things that swarm should do. /// @@ -722,3 +850,364 @@ impl Default for CloseConnection { CloseConnection::All } } + +/// Enumeration with the list of the possible events +/// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event). +pub enum FromSwarm<'a, Handler: IntoConnectionHandler> { + /// Informs the behaviour about a newly established connection to a peer. + ConnectionEstablished(ConnectionEstablished<'a>), + /// Informs the behaviour about a closed connection to a peer. + /// + /// This event is always paired with an earlier + /// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID + /// and endpoint. + ConnectionClosed(ConnectionClosed<'a, Handler>), + /// Informs the behaviour that the [`ConnectedPoint`] of an existing + /// connection has changed. + AddressChange(AddressChange<'a>), + /// Informs the behaviour that the dial to a known + /// or unknown node failed. + DialFailure(DialFailure<'a, Handler>), + /// Informs the behaviour that an error + /// happened on an incoming connection during its initial handshake. + /// + /// This can include, for example, an error during the handshake of the encryption layer, or the + /// connection unexpectedly closed. + ListenFailure(ListenFailure<'a, Handler>), + /// Informs the behaviour that a new listener was created. + NewListener(NewListener), + /// Informs the behaviour that we have started listening on a new multiaddr. + NewListenAddr(NewListenAddr<'a>), + /// Informs the behaviour that a multiaddr + /// we were listening on has expired, + /// which means that we are no longer listening on it. + ExpiredListenAddr(ExpiredListenAddr<'a>), + /// Informs the behaviour that a listener experienced an error. + ListenerError(ListenerError<'a>), + /// Informs the behaviour that a listener closed. + ListenerClosed(ListenerClosed<'a>), + /// Informs the behaviour that we have discovered a new external address for us. + NewExternalAddr(NewExternalAddr<'a>), + /// Informs the behaviour that an external address was removed. + ExpiredExternalAddr(ExpiredExternalAddr<'a>), +} + +/// [`FromSwarm`] variant that informs the behaviour about a newly established connection to a peer. +#[derive(Clone, Copy)] +pub struct ConnectionEstablished<'a> { + pub peer_id: PeerId, + pub connection_id: ConnectionId, + pub endpoint: &'a ConnectedPoint, + pub failed_addresses: &'a [Multiaddr], + pub other_established: usize, +} + +/// [`FromSwarm`] variant that informs the behaviour about a closed connection to a peer. +/// +/// This event is always paired with an earlier +/// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID +/// and endpoint. +pub struct ConnectionClosed<'a, Handler: IntoConnectionHandler> { + pub peer_id: PeerId, + pub connection_id: ConnectionId, + pub endpoint: &'a ConnectedPoint, + pub handler: ::Handler, + pub remaining_established: usize, +} + +/// [`FromSwarm`] variant that informs the behaviour that the [`ConnectedPoint`] of an existing +/// connection has changed. +#[derive(Clone, Copy)] +pub struct AddressChange<'a> { + pub peer_id: PeerId, + pub connection_id: ConnectionId, + pub old: &'a ConnectedPoint, + pub new: &'a ConnectedPoint, +} + +/// [`FromSwarm`] variant that informs the behaviour that the dial to a known +/// or unknown node failed. +#[derive(Clone, Copy)] +pub struct DialFailure<'a, Handler> { + pub peer_id: Option, + pub handler: Handler, + pub error: &'a DialError, +} + +/// [`FromSwarm`] variant that informs the behaviour that an error +/// happened on an incoming connection during its initial handshake. +/// +/// This can include, for example, an error during the handshake of the encryption layer, or the +/// connection unexpectedly closed. +#[derive(Clone, Copy)] +pub struct ListenFailure<'a, Handler> { + pub local_addr: &'a Multiaddr, + pub send_back_addr: &'a Multiaddr, + pub handler: Handler, +} + +/// [`FromSwarm`] variant that informs the behaviour that a new listener was created. +#[derive(Clone, Copy)] +pub struct NewListener { + pub listener_id: ListenerId, +} + +/// [`FromSwarm`] variant that informs the behaviour +/// that we have started listening on a new multiaddr. +#[derive(Clone, Copy)] +pub struct NewListenAddr<'a> { + pub listener_id: ListenerId, + pub addr: &'a Multiaddr, +} + +/// [`FromSwarm`] variant that informs the behaviour that a multiaddr +/// we were listening on has expired, +/// which means that we are no longer listening on it. +#[derive(Clone, Copy)] +pub struct ExpiredListenAddr<'a> { + pub listener_id: ListenerId, + pub addr: &'a Multiaddr, +} + +/// [`FromSwarm`] variant that informs the behaviour that a listener experienced an error. +#[derive(Clone, Copy)] +pub struct ListenerError<'a> { + pub listener_id: ListenerId, + pub err: &'a (dyn std::error::Error + 'static), +} + +/// [`FromSwarm`] variant that informs the behaviour that a listener closed. +#[derive(Clone, Copy)] +pub struct ListenerClosed<'a> { + pub listener_id: ListenerId, + pub reason: Result<(), &'a std::io::Error>, +} + +/// [`FromSwarm`] variant that informs the behaviour +/// that we have discovered a new external address for us. +#[derive(Clone, Copy)] +pub struct NewExternalAddr<'a> { + pub addr: &'a Multiaddr, +} + +/// [`FromSwarm`] variant that informs the behaviour that an external address was removed. +#[derive(Clone, Copy)] +pub struct ExpiredExternalAddr<'a> { + pub addr: &'a Multiaddr, +} + +impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { + fn map_handler( + self, + map_into_handler: impl FnOnce(Handler) -> NewHandler, + map_handler: impl FnOnce( + ::Handler, + ) -> ::Handler, + ) -> FromSwarm<'a, NewHandler> + where + NewHandler: IntoConnectionHandler, + { + self.maybe_map_handler(|h| Some(map_into_handler(h)), |h| Some(map_handler(h))) + .expect("To return Some as all closures return Some.") + } + + fn maybe_map_handler( + self, + map_into_handler: impl FnOnce(Handler) -> Option, + map_handler: impl FnOnce( + ::Handler, + ) -> Option<::Handler>, + ) -> Option> + where + NewHandler: IntoConnectionHandler, + { + match self { + FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler, + remaining_established, + }) => Some(FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler: map_handler(handler)?, + remaining_established, + })), + FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id, + connection_id, + endpoint, + failed_addresses, + other_established, + }) => Some(FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id, + connection_id, + endpoint, + failed_addresses, + other_established, + })), + FromSwarm::AddressChange(AddressChange { + peer_id, + connection_id, + old, + new, + }) => Some(FromSwarm::AddressChange(AddressChange { + peer_id, + connection_id, + old, + new, + })), + FromSwarm::DialFailure(DialFailure { + peer_id, + handler, + error, + }) => Some(FromSwarm::DialFailure(DialFailure { + peer_id, + handler: map_into_handler(handler)?, + error, + })), + FromSwarm::ListenFailure(ListenFailure { + local_addr, + send_back_addr, + handler, + }) => Some(FromSwarm::ListenFailure(ListenFailure { + local_addr, + send_back_addr, + handler: map_into_handler(handler)?, + })), + FromSwarm::NewListener(NewListener { listener_id }) => { + Some(FromSwarm::NewListener(NewListener { listener_id })) + } + FromSwarm::NewListenAddr(NewListenAddr { listener_id, addr }) => { + Some(FromSwarm::NewListenAddr(NewListenAddr { + listener_id, + addr, + })) + } + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => { + Some(FromSwarm::ExpiredListenAddr(ExpiredListenAddr { + listener_id, + addr, + })) + } + FromSwarm::ListenerError(ListenerError { listener_id, err }) => { + Some(FromSwarm::ListenerError(ListenerError { listener_id, err })) + } + FromSwarm::ListenerClosed(ListenerClosed { + listener_id, + reason, + }) => Some(FromSwarm::ListenerClosed(ListenerClosed { + listener_id, + reason, + })), + FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => { + Some(FromSwarm::NewExternalAddr(NewExternalAddr { addr })) + } + FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => { + Some(FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr })) + } + } + } +} + +/// Helper function to call [`NetworkBehaviour`]'s `inject_*` methods given a `FromSwarm. +/// TODO: Remove this function when we remove the remaining `inject_*` calls +/// from [`Either`] and [`Toggle`]. +pub(crate) fn inject_from_swarm( + behaviour: &mut T, + event: FromSwarm, +) { + match event { + FromSwarm::ConnectionEstablished(ConnectionEstablished { + peer_id, + connection_id, + endpoint, + failed_addresses, + other_established, + }) => { + #[allow(deprecated)] + behaviour.inject_connection_established( + &peer_id, + &connection_id, + endpoint, + Some(&failed_addresses.into()), + other_established, + ); + } + FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler, + remaining_established, + }) => { + #[allow(deprecated)] + behaviour.inject_connection_closed( + &peer_id, + &connection_id, + endpoint, + handler, + remaining_established, + ); + } + FromSwarm::AddressChange(AddressChange { + peer_id, + connection_id, + old, + new, + }) => { + #[allow(deprecated)] + behaviour.inject_address_change(&peer_id, &connection_id, old, new); + } + FromSwarm::DialFailure(DialFailure { + peer_id, + handler, + error, + }) => { + #[allow(deprecated)] + behaviour.inject_dial_failure(peer_id, handler, error); + } + FromSwarm::ListenFailure(ListenFailure { + local_addr, + send_back_addr, + handler, + }) => { + #[allow(deprecated)] + behaviour.inject_listen_failure(local_addr, send_back_addr, handler); + } + FromSwarm::NewListener(NewListener { listener_id }) => { + #[allow(deprecated)] + behaviour.inject_new_listener(listener_id); + } + FromSwarm::NewListenAddr(NewListenAddr { listener_id, addr }) => { + #[allow(deprecated)] + behaviour.inject_new_listen_addr(listener_id, addr); + } + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => { + #[allow(deprecated)] + behaviour.inject_expired_listen_addr(listener_id, addr); + } + FromSwarm::ListenerError(ListenerError { listener_id, err }) => { + #[allow(deprecated)] + behaviour.inject_listener_error(listener_id, err); + } + FromSwarm::ListenerClosed(ListenerClosed { + listener_id, + reason, + }) => { + #[allow(deprecated)] + behaviour.inject_listener_closed(listener_id, reason); + } + FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => { + #[allow(deprecated)] + behaviour.inject_new_external_addr(addr); + } + FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => + { + #[allow(deprecated)] + behaviour.inject_expired_external_addr(addr) + } + } +} diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 6bb1d95a519..4154db1a0de 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -18,12 +18,12 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::handler::{either::IntoEitherHandler, ConnectionHandler, IntoConnectionHandler}; -use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; -use either::Either; -use libp2p_core::{ - connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, +use crate::behaviour::{ + self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; +use crate::handler::either::IntoEitherHandler; +use either::Either; +use libp2p_core::{Multiaddr, PeerId}; use std::{task::Context, task::Poll}; /// Implementation of [`NetworkBehaviour`] that can be either of two implementations. @@ -49,173 +49,50 @@ where } } - fn inject_connection_established( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - errors: Option<&Vec>, - other_established: usize, - ) { + fn on_swarm_event(&mut self, event: behaviour::FromSwarm) { match self { - Either::Left(a) => a.inject_connection_established( - peer_id, - connection, - endpoint, - errors, - other_established, - ), - Either::Right(b) => b.inject_connection_established( - peer_id, - connection, - endpoint, - errors, - other_established, - ), - } - } - - fn inject_connection_closed( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - handler: ::Handler, - remaining_established: usize, - ) { - match (self, handler) { - (Either::Left(behaviour), Either::Left(handler)) => behaviour.inject_connection_closed( - peer_id, - connection, - endpoint, - handler, - remaining_established, + Either::Left(b) => inject_from_swarm( + b, + event.map_handler( + |h| h.unwrap_left(), + |h| match h { + Either::Left(h) => h, + Either::Right(_) => unreachable!(), + }, + ), ), - (Either::Right(behaviour), Either::Right(handler)) => behaviour - .inject_connection_closed( - peer_id, - connection, - endpoint, - handler, - remaining_established, + Either::Right(b) => inject_from_swarm( + b, + event.map_handler( + |h| h.unwrap_right(), + |h| match h { + Either::Right(h) => h, + Either::Left(_) => unreachable!(), + }, ), - _ => unreachable!(), - } - } - - fn inject_address_change( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - old: &ConnectedPoint, - new: &ConnectedPoint, - ) { - match self { - Either::Left(a) => a.inject_address_change(peer_id, connection, old, new), - Either::Right(b) => b.inject_address_change(peer_id, connection, old, new), + ), } } - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: PeerId, - connection: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, + connection_id: libp2p_core::connection::ConnectionId, + event: crate::THandlerOutEvent, ) { match (self, event) { - (Either::Left(behaviour), Either::Left(event)) => { - behaviour.inject_event(peer_id, connection, event) - } - (Either::Right(behaviour), Either::Right(event)) => { - behaviour.inject_event(peer_id, connection, event) - } - _ => unreachable!(), - } - } - - fn inject_dial_failure( - &mut self, - peer_id: Option, - handler: Self::ConnectionHandler, - error: &DialError, - ) { - match (self, handler) { - (Either::Left(behaviour), IntoEitherHandler::Left(handler)) => { - behaviour.inject_dial_failure(peer_id, handler, error) - } - (Either::Right(behaviour), IntoEitherHandler::Right(handler)) => { - behaviour.inject_dial_failure(peer_id, handler, 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::Left(left), Either::Left(event)) => { + #[allow(deprecated)] + left.inject_event(peer_id, connection_id, event); } - (Either::Right(behaviour), IntoEitherHandler::Right(handler)) => { - behaviour.inject_listen_failure(local_addr, send_back_addr, handler) + (Either::Right(right), Either::Right(event)) => { + #[allow(deprecated)] + right.inject_event(peer_id, connection_id, event); } _ => unreachable!(), } } - fn inject_new_listener(&mut self, id: ListenerId) { - match self { - Either::Left(a) => a.inject_new_listener(id), - Either::Right(b) => b.inject_new_listener(id), - } - } - - fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_new_listen_addr(id, addr), - Either::Right(b) => b.inject_new_listen_addr(id, addr), - } - } - - fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_expired_listen_addr(id, addr), - Either::Right(b) => b.inject_expired_listen_addr(id, addr), - } - } - - fn inject_new_external_addr(&mut self, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_new_external_addr(addr), - Either::Right(b) => b.inject_new_external_addr(addr), - } - } - - fn inject_expired_external_addr(&mut self, addr: &Multiaddr) { - match self { - Either::Left(a) => a.inject_expired_external_addr(addr), - Either::Right(b) => b.inject_expired_external_addr(addr), - } - } - - fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { - match self { - Either::Left(a) => a.inject_listener_error(id, err), - Either::Right(b) => b.inject_listener_error(id, err), - } - } - - fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) { - match self { - Either::Left(a) => a.inject_listener_closed(id, reason), - Either::Right(b) => b.inject_listener_closed(id, reason), - } - } - fn poll( &mut self, cx: &mut Context<'_>, diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 8f91c236148..4b01138a596 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -18,17 +18,16 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::{inject_from_swarm, FromSwarm}; use crate::handler::{ ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, KeepAlive, SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; -use crate::{DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use either::Either; use libp2p_core::{ - connection::ConnectionId, either::{EitherError, EitherOutput}, - transport::ListenerId, upgrade::{DeniedUpgrade, EitherUpgrade}, ConnectedPoint, Multiaddr, PeerId, }; @@ -84,134 +83,23 @@ where .unwrap_or_else(Vec::new) } - fn inject_connection_established( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - errors: Option<&Vec>, - other_established: usize, - ) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_connection_established( - peer_id, - connection, - endpoint, - errors, - other_established, - ) - } - } - - fn inject_connection_closed( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - endpoint: &ConnectedPoint, - handler: ::Handler, - remaining_established: usize, - ) { - if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_connection_closed( - peer_id, - connection, - endpoint, - handler, - remaining_established, - ) + fn on_swarm_event(&mut self, event: FromSwarm) { + if let Some(behaviour) = &mut self.inner { + if let Some(event) = event.maybe_map_handler(|h| h.inner, |h| h.inner) { + inject_from_swarm(behaviour, event); } } } - fn inject_address_change( - &mut self, - peer_id: &PeerId, - connection: &ConnectionId, - old: &ConnectedPoint, - new: &ConnectedPoint, - ) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_address_change(peer_id, connection, old, new) - } - } - - fn inject_event( + fn on_connection_handler_event( &mut self, peer_id: PeerId, - connection: ConnectionId, - event: <::Handler as ConnectionHandler>::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, - handler: Self::ConnectionHandler, - error: &DialError, + connection_id: libp2p_core::connection::ConnectionId, + event: crate::THandlerOutEvent, ) { - if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_dial_failure(peer_id, handler, error) - } - } - } - - fn inject_listen_failure( - &mut self, - local_addr: &Multiaddr, - send_back_addr: &Multiaddr, - handler: Self::ConnectionHandler, - ) { - if let Some(inner) = self.inner.as_mut() { - if let Some(handler) = handler.inner { - inner.inject_listen_failure(local_addr, send_back_addr, handler) - } - } - } - - fn inject_new_listener(&mut self, id: ListenerId) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_new_listener(id) - } - } - - fn inject_new_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_new_listen_addr(id, addr) - } - } - - fn inject_expired_listen_addr(&mut self, id: ListenerId, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_expired_listen_addr(id, addr) - } - } - - fn inject_new_external_addr(&mut self, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_new_external_addr(addr) - } - } - - fn inject_expired_external_addr(&mut self, addr: &Multiaddr) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_expired_external_addr(addr) - } - } - - fn inject_listener_error(&mut self, id: ListenerId, err: &(dyn std::error::Error + 'static)) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_listener_error(id, err) - } - } - - fn inject_listener_closed(&mut self, id: ListenerId, reason: Result<(), &std::io::Error>) { - if let Some(inner) = self.inner.as_mut() { - inner.inject_listener_closed(id, reason) + if let Some(behaviour) = &mut self.inner { + #[allow(deprecated)] + behaviour.inject_event(peer_id, connection_id, event) } } diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 61f055915b3..6c51065a9e1 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,4 +1,4 @@ -use crate::behaviour::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use crate::handler::{InboundUpgradeSend, OutboundUpgradeSend}; use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol}; use libp2p_core::connection::ConnectionId; @@ -19,7 +19,7 @@ impl NetworkBehaviour for Behaviour { ConnectionHandler } - fn inject_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { void::unreachable(event) } @@ -30,6 +30,23 @@ impl NetworkBehaviour for Behaviour { ) -> Poll> { 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(_) => {} + } + } } /// An implementation of [`ConnectionHandler`] that neither handles any protocols nor does it keep the connection alive. diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index 21d386ec56a..53007b5a181 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -29,6 +29,8 @@ use libp2p_core::upgrade::{EitherUpgrade, UpgradeError}; use libp2p_core::{ConnectedPoint, Multiaddr, PeerId}; use std::task::{Context, Poll}; +/// Auxiliary type to allow implementing [`IntoConnectionHandler`]. As [`IntoConnectionHandler`] is +/// already implemented for T, we cannot implement it for Either. pub enum IntoEitherHandler { Left(L), Right(R), @@ -64,6 +66,29 @@ where } } +// Taken from https://github.com/bluss/either. +impl IntoEitherHandler { + /// Returns the left value. + pub fn unwrap_left(self) -> L { + match self { + IntoEitherHandler::Left(l) => l, + IntoEitherHandler::Right(_) => { + panic!("called `IntoEitherHandler::unwrap_left()` on a `Right` value.",) + } + } + } + + /// Returns the right value. + pub fn unwrap_right(self) -> R { + match self { + IntoEitherHandler::Right(r) => r, + IntoEitherHandler::Left(_) => { + panic!("called `IntoEitherHandler::unwrap_right()` on a `Left` value.",) + } + } + } +} + /// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`] /// implementations. impl ConnectionHandler for Either diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index ea5d5ee6399..29a0eca1e21 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::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use crate::handler::{ ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, }; @@ -29,7 +29,7 @@ impl NetworkBehaviour for Behaviour { ConnectionHandler } - fn inject_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { void::unreachable(event) } @@ -40,6 +40,23 @@ impl NetworkBehaviour for Behaviour { ) -> Poll> { 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(_) => {} + } + } } /// 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 6fc1b8707c3..7894f1e576a 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -71,6 +71,19 @@ pub mod keep_alive; /// Bundles all symbols required for the [`libp2p_swarm_derive::NetworkBehaviour`] macro. #[doc(hidden)] pub mod derive_prelude { + pub use crate::behaviour::AddressChange; + pub use crate::behaviour::ConnectionClosed; + pub use crate::behaviour::ConnectionEstablished; + pub use crate::behaviour::DialFailure; + pub use crate::behaviour::ExpiredExternalAddr; + pub use crate::behaviour::ExpiredListenAddr; + pub use crate::behaviour::FromSwarm; + pub use crate::behaviour::ListenFailure; + pub use crate::behaviour::ListenerClosed; + pub use crate::behaviour::ListenerError; + pub use crate::behaviour::NewExternalAddr; + pub use crate::behaviour::NewListenAddr; + pub use crate::behaviour::NewListener; pub use crate::ConnectionHandler; pub use crate::DialError; pub use crate::IntoConnectionHandler; @@ -432,6 +445,7 @@ where /// Depending on the underlying transport, one listener may have multiple listening addresses. pub fn listen_on(&mut self, addr: Multiaddr) -> Result> { let id = self.transport.listen_on(addr)?; + #[allow(deprecated)] self.behaviour.inject_new_listener(id); Ok(id) } @@ -500,6 +514,7 @@ where PeerCondition::Always => true, }; if !condition_matched { + #[allow(deprecated)] self.behaviour.inject_dial_failure( Some(peer_id), handler, @@ -512,6 +527,7 @@ where // Check if peer is banned. if self.banned_peers.contains(&peer_id) { let error = DialError::Banned; + #[allow(deprecated)] self.behaviour .inject_dial_failure(Some(peer_id), handler, &error); return Err(error); @@ -549,6 +565,7 @@ where if addresses.is_empty() { let error = DialError::NoAddresses; + #[allow(deprecated)] self.behaviour .inject_dial_failure(Some(peer_id), handler, &error); return Err(error); @@ -632,6 +649,7 @@ where Ok(_connection_id) => Ok(()), Err((connection_limit, handler)) => { let error = DialError::ConnectionLimit(connection_limit); + #[allow(deprecated)] self.behaviour.inject_dial_failure(peer_id, handler, &error); Err(error) } @@ -673,12 +691,14 @@ where let result = self.external_addrs.add(a.clone(), s); let expired = match &result { AddAddressResult::Inserted { expired } => { + #[allow(deprecated)] self.behaviour.inject_new_external_addr(&a); expired } AddAddressResult::Updated { expired } => expired, }; for a in expired { + #[allow(deprecated)] self.behaviour.inject_expired_external_addr(&a.addr); } result @@ -692,6 +712,7 @@ where /// otherwise. pub fn remove_external_address(&mut self, addr: &Multiaddr) -> bool { if self.external_addrs.remove(addr) { + #[allow(deprecated)] self.behaviour.inject_expired_external_addr(addr); true } else { @@ -798,6 +819,7 @@ where let failed_addresses = concurrent_dial_errors .as_ref() .map(|es| es.iter().map(|(a, _)| a).cloned().collect()); + #[allow(deprecated)] self.behaviour.inject_connection_established( &peer_id, &id, @@ -821,6 +843,7 @@ where } => { let error = error.into(); + #[allow(deprecated)] self.behaviour.inject_dial_failure(peer, handler, &error); if let Some(peer) = peer { @@ -842,6 +865,7 @@ where handler, } => { log::debug!("Incoming connection failed: {:?}", error); + #[allow(deprecated)] self.behaviour .inject_listen_failure(&local_addr, &send_back_addr, handler); return Some(SwarmEvent::IncomingConnectionError { @@ -882,6 +906,7 @@ where .into_iter() .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) .count(); + #[allow(deprecated)] self.behaviour.inject_connection_closed( &peer_id, &id, @@ -901,6 +926,7 @@ where if self.banned_peer_connections.contains(&id) { log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id); } else { + #[allow(deprecated)] self.behaviour.inject_event(peer_id, id, event); } } @@ -911,6 +937,7 @@ where old_endpoint, } => { if !self.banned_peer_connections.contains(&id) { + #[allow(deprecated)] self.behaviour.inject_address_change( &peer_id, &id, @@ -954,6 +981,7 @@ where }); } Err((connection_limit, handler)) => { + #[allow(deprecated)] self.behaviour .inject_listen_failure(&local_addr, &send_back_addr, handler); log::warn!("Incoming connection rejected: {:?}", connection_limit); @@ -969,6 +997,7 @@ where if !addrs.contains(&listen_addr) { addrs.push(listen_addr.clone()) } + #[allow(deprecated)] self.behaviour .inject_new_listen_addr(listener_id, &listen_addr); return Some(SwarmEvent::NewListenAddr { @@ -988,6 +1017,7 @@ where if let Some(addrs) = self.listened_addrs.get_mut(&listener_id) { addrs.retain(|a| a != &listen_addr); } + #[allow(deprecated)] self.behaviour .inject_expired_listen_addr(listener_id, &listen_addr); return Some(SwarmEvent::ExpiredListenAddr { @@ -1002,8 +1032,10 @@ where log::debug!("Listener {:?}; Closed by {:?}.", listener_id, reason); let addrs = self.listened_addrs.remove(&listener_id).unwrap_or_default(); for addr in addrs.iter() { + #[allow(deprecated)] self.behaviour.inject_expired_listen_addr(listener_id, addr); } + #[allow(deprecated)] self.behaviour.inject_listener_closed( listener_id, match &reason { @@ -1018,6 +1050,7 @@ where }); } TransportEvent::ListenerError { listener_id, error } => { + #[allow(deprecated)] self.behaviour.inject_listener_error(listener_id, &error); return Some(SwarmEvent::ListenerError { listener_id, error }); } @@ -1868,7 +1901,7 @@ mod tests { // The banned connection was established. Check that it was not reported to // the behaviour of the banning swarm. assert_eq!( - swarm2.behaviour.inject_connection_established.len(), s2_expected_conns, + swarm2.behaviour.on_connection_established.len(), s2_expected_conns, "No additional closed connections should be reported for the banned peer" ); @@ -1882,7 +1915,7 @@ mod tests { if swarm2.network_info().num_peers() == 0 { // The banned connection has closed. Check that it was not reported. assert_eq!( - swarm2.behaviour.inject_connection_closed.len(), s2_expected_conns, + swarm2.behaviour.on_connection_closed.len(), s2_expected_conns, "No additional closed connections should be reported for the banned peer" ); assert!(swarm2.banned_peer_connections.is_empty()); @@ -1897,7 +1930,7 @@ mod tests { } } Stage::Reconnecting => { - if swarm1.behaviour.inject_connection_established.len() == s1_expected_conns + if swarm1.behaviour.on_connection_established.len() == s1_expected_conns && swarm2.behaviour.assert_connected(s2_expected_conns, 2) { return Poll::Ready(()); @@ -2082,9 +2115,8 @@ mod tests { State::Connecting => { if swarms_connected(&swarm1, &swarm2, num_connections) { disconnected_conn_id = { - let conn_id = swarm2.behaviour.inject_connection_established - [num_connections / 2] - .1; + let conn_id = + swarm2.behaviour.on_connection_established[num_connections / 2].1; swarm2.behaviour.inner().next_action.replace( NetworkBehaviourAction::CloseConnection { peer_id: swarm1_id, @@ -2100,20 +2132,17 @@ mod tests { for s in &[&swarm1, &swarm2] { assert!(s .behaviour - .inject_connection_closed + .on_connection_closed .iter() .all(|(.., remaining_conns)| *remaining_conns > 0)); - assert_eq!( - s.behaviour.inject_connection_established.len(), - num_connections - ); + assert_eq!(s.behaviour.on_connection_established.len(), num_connections); s.behaviour.assert_connected(num_connections, 1); } if [&swarm1, &swarm2] .iter() - .all(|s| s.behaviour.inject_connection_closed.len() == 1) + .all(|s| s.behaviour.on_connection_closed.len() == 1) { - let conn_id = swarm2.behaviour.inject_connection_closed[0].1; + let conn_id = swarm2.behaviour.on_connection_closed[0].1; assert_eq!(Some(conn_id), disconnected_conn_id); return Poll::Ready(()); } diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 093ee420cb5..94a5fbfef54 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -18,8 +18,12 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::behaviour::{ + ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, + FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, +}; use crate::{ - ConnectionHandler, DialError, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, + ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; use libp2p_core::{ @@ -76,8 +80,6 @@ where self.addresses.get(p).map_or(Vec::new(), |v| v.clone()) } - fn inject_event(&mut self, _: PeerId, _: ConnectionId, _: THandler::OutEvent) {} - fn poll( &mut self, _: &mut Context, @@ -85,6 +87,32 @@ where ) -> Poll> { self.next_action.take().map_or(Poll::Pending, Poll::Ready) } + + 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_id: PeerId, + _connection_id: ConnectionId, + _event: <::Handler as + ConnectionHandler>::OutEvent, + ) { + } } /// A `CallTraceBehaviour` is a `NetworkBehaviour` that tracks @@ -97,43 +125,45 @@ where inner: TInner, pub addresses_of_peer: Vec, - pub inject_connection_established: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>, - pub inject_connection_closed: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>, - pub inject_event: Vec<( + pub on_connection_established: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>, + pub on_connection_closed: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>, + pub on_event: Vec<( PeerId, ConnectionId, <::Handler as ConnectionHandler>::OutEvent, )>, - pub inject_dial_failure: Vec>, - pub inject_new_listener: Vec, - pub inject_new_listen_addr: Vec<(ListenerId, Multiaddr)>, - pub inject_new_external_addr: Vec, - pub inject_expired_listen_addr: Vec<(ListenerId, Multiaddr)>, - pub inject_expired_external_addr: Vec, - pub inject_listener_error: Vec, - pub inject_listener_closed: Vec<(ListenerId, bool)>, + pub on_dial_failure: Vec>, + pub on_new_listener: Vec, + pub on_new_listen_addr: Vec<(ListenerId, Multiaddr)>, + pub on_new_external_addr: Vec, + pub on_expired_listen_addr: Vec<(ListenerId, Multiaddr)>, + pub on_expired_external_addr: Vec, + pub on_listener_error: Vec, + pub on_listener_closed: Vec<(ListenerId, bool)>, pub poll: usize, } impl CallTraceBehaviour where TInner: NetworkBehaviour, + <::Handler as ConnectionHandler>::OutEvent: + Clone, { pub fn new(inner: TInner) -> Self { Self { inner, addresses_of_peer: Vec::new(), - inject_connection_established: Vec::new(), - inject_connection_closed: Vec::new(), - inject_event: Vec::new(), - inject_dial_failure: Vec::new(), - inject_new_listener: Vec::new(), - inject_new_listen_addr: Vec::new(), - inject_new_external_addr: Vec::new(), - inject_expired_listen_addr: Vec::new(), - inject_expired_external_addr: Vec::new(), - inject_listener_error: Vec::new(), - inject_listener_closed: Vec::new(), + on_connection_established: Vec::new(), + on_connection_closed: Vec::new(), + on_event: Vec::new(), + on_dial_failure: Vec::new(), + on_new_listener: Vec::new(), + on_new_listen_addr: Vec::new(), + on_new_external_addr: Vec::new(), + on_expired_listen_addr: Vec::new(), + on_expired_external_addr: Vec::new(), + on_listener_error: Vec::new(), + on_listener_closed: Vec::new(), poll: 0, } } @@ -141,15 +171,15 @@ where #[allow(dead_code)] pub fn reset(&mut self) { self.addresses_of_peer = Vec::new(); - self.inject_connection_established = Vec::new(); - self.inject_connection_closed = Vec::new(); - self.inject_event = Vec::new(); - self.inject_dial_failure = Vec::new(); - self.inject_new_listen_addr = Vec::new(); - self.inject_new_external_addr = Vec::new(); - self.inject_expired_listen_addr = Vec::new(); - self.inject_listener_error = Vec::new(); - self.inject_listener_closed = Vec::new(); + self.on_connection_established = Vec::new(); + self.on_connection_closed = Vec::new(); + self.on_event = Vec::new(); + self.on_dial_failure = Vec::new(); + self.on_new_listen_addr = Vec::new(); + self.on_new_external_addr = Vec::new(); + self.on_expired_listen_addr = Vec::new(); + self.on_listener_error = Vec::new(); + self.on_listener_closed = Vec::new(); self.poll = 0; } @@ -158,12 +188,12 @@ where } pub fn num_connections_to_peer(&self, peer: PeerId) -> usize { - self.inject_connection_established + self.on_connection_established .iter() .filter(|(peer_id, _, _, _)| *peer_id == peer) .count() - self - .inject_connection_closed + .on_connection_closed .iter() .filter(|(peer_id, _, _, _)| *peer_id == peer) .count() @@ -178,9 +208,9 @@ where expected_closed_connections: usize, expected_disconnections: usize, ) -> bool { - if self.inject_connection_closed.len() == expected_closed_connections { + if self.on_connection_closed.len() == expected_closed_connections { assert_eq!( - self.inject_connection_closed + self.on_connection_closed .iter() .filter(|(.., remaining_established)| { *remaining_established == 0 }) .count(), @@ -201,9 +231,9 @@ where expected_established_connections: usize, expected_connections: usize, ) -> bool { - if self.inject_connection_established.len() == expected_established_connections { + if self.on_connection_established.len() == expected_established_connections { assert_eq!( - self.inject_connection_established + self.on_connection_established .iter() .filter(|(.., reported_aditional_connections)| { *reported_aditional_connections == 0 @@ -216,40 +246,23 @@ where false } -} - -impl NetworkBehaviour for CallTraceBehaviour -where - TInner: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: - Clone, -{ - type ConnectionHandler = TInner::ConnectionHandler; - type OutEvent = TInner::OutEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { - self.inner.new_handler() - } - - fn addresses_of_peer(&mut self, p: &PeerId) -> Vec { - self.addresses_of_peer.push(*p); - self.inner.addresses_of_peer(p) - } - - fn inject_connection_established( + fn on_connection_established( &mut self, - p: &PeerId, - c: &ConnectionId, - e: &ConnectedPoint, - errors: Option<&Vec>, - other_established: usize, + ConnectionEstablished { + peer_id, + connection_id, + endpoint, + failed_addresses, + other_established, + }: ConnectionEstablished, ) { let mut other_peer_connections = self - .inject_connection_established + .on_connection_established .iter() .rev() // take last to first .filter_map(|(peer, .., other_established)| { - if p == peer { + if &peer_id == peer { Some(other_established) } else { None @@ -271,26 +284,39 @@ where } else { assert_eq!(other_established, 0) } - self.inject_connection_established - .push((*p, *c, e.clone(), other_established)); - self.inner - .inject_connection_established(p, c, e, errors, other_established); + self.on_connection_established.push(( + peer_id, + connection_id, + endpoint.clone(), + other_established, + )); + let errors = Some(failed_addresses.to_vec()); + #[allow(deprecated)] + self.inner.inject_connection_established( + &peer_id, + &connection_id, + endpoint, + errors.as_ref(), + other_established, + ); } - fn inject_connection_closed( + fn on_connection_closed( &mut self, - p: &PeerId, - c: &ConnectionId, - e: &ConnectedPoint, - handler: ::Handler, - remaining_established: usize, + ConnectionClosed { + peer_id, + connection_id, + endpoint, + handler, + remaining_established, + }: ConnectionClosed<::ConnectionHandler>, ) { let mut other_closed_connections = self - .inject_connection_established + .on_connection_established .iter() .rev() // take last to first .filter_map(|(peer, .., remaining_established)| { - if p == peer { + if &peer_id == peer { Some(remaining_established) } else { None @@ -313,87 +339,133 @@ where assert_eq!(remaining_established, 0) } assert!( - self.inject_connection_established + self.on_connection_established .iter() - .any(|(peer, conn_id, endpoint, _)| (peer, conn_id, endpoint) == (p, c, e)), + .any(|(peer, conn_id, endpoint, _)| (peer, conn_id, endpoint) + == (&peer_id, &connection_id, endpoint)), "`inject_connection_closed` is called only for connections for \ which `inject_connection_established` was called first." ); - self.inject_connection_closed - .push((*p, *c, e.clone(), remaining_established)); - self.inner - .inject_connection_closed(p, c, e, handler, remaining_established); + self.on_connection_closed.push(( + peer_id, + connection_id, + endpoint.clone(), + remaining_established, + )); + #[allow(deprecated)] + self.inner.inject_connection_closed( + &peer_id, + &connection_id, + endpoint, + handler, + remaining_established, + ); + } +} + +impl NetworkBehaviour for CallTraceBehaviour +where + TInner: NetworkBehaviour, + <::Handler as ConnectionHandler>::OutEvent: + Clone, +{ + type ConnectionHandler = TInner::ConnectionHandler; + type OutEvent = TInner::OutEvent; + + fn new_handler(&mut self) -> Self::ConnectionHandler { + self.inner.new_handler() } - fn inject_event( + fn addresses_of_peer(&mut self, p: &PeerId) -> Vec { + self.addresses_of_peer.push(*p); + self.inner.addresses_of_peer(p) + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionEstablished(connection_established) => { + self.on_connection_established(connection_established) + } + FromSwarm::ConnectionClosed(connection_closed) => { + self.on_connection_closed(connection_closed) + } + FromSwarm::DialFailure(DialFailure { + peer_id, + handler, + error, + }) => { + self.on_dial_failure.push(peer_id); + #[allow(deprecated)] + self.inner.inject_dial_failure(peer_id, handler, error); + } + FromSwarm::NewListener(NewListener { listener_id }) => { + self.on_new_listener.push(listener_id); + #[allow(deprecated)] + self.inner.inject_new_listener(listener_id); + } + FromSwarm::NewListenAddr(NewListenAddr { listener_id, addr }) => { + self.on_new_listen_addr.push((listener_id, addr.clone())); + #[allow(deprecated)] + self.inner.inject_new_listen_addr(listener_id, addr); + } + FromSwarm::ExpiredListenAddr(ExpiredListenAddr { listener_id, addr }) => { + self.on_expired_listen_addr + .push((listener_id, addr.clone())); + #[allow(deprecated)] + self.inner.inject_expired_listen_addr(listener_id, addr); + } + FromSwarm::NewExternalAddr(NewExternalAddr { addr }) => { + self.on_new_external_addr.push(addr.clone()); + #[allow(deprecated)] + self.inner.inject_new_external_addr(addr); + } + FromSwarm::ExpiredExternalAddr(ExpiredExternalAddr { addr }) => { + self.on_expired_external_addr.push(addr.clone()); + #[allow(deprecated)] + self.inner.inject_expired_external_addr(addr); + } + FromSwarm::ListenerError(ListenerError { listener_id, err }) => { + self.on_listener_error.push(listener_id); + #[allow(deprecated)] + self.inner.inject_listener_error(listener_id, err); + } + FromSwarm::ListenerClosed(ListenerClosed { + listener_id, + reason, + }) => { + self.on_listener_closed.push((listener_id, reason.is_ok())); + #[allow(deprecated)] + self.inner.inject_listener_closed(listener_id, reason); + } + _ => {} + } + } + + fn on_connection_handler_event( &mut self, p: PeerId, c: ConnectionId, e: <::Handler as ConnectionHandler>::OutEvent, ) { assert!( - self.inject_connection_established + self.on_connection_established .iter() .any(|(peer_id, conn_id, ..)| *peer_id == p && c == *conn_id), - "`inject_event` is called for reported connections." + "`on_connection_handler_event` is called for reported connections." ); assert!( !self - .inject_connection_closed + .on_connection_closed .iter() .any(|(peer_id, conn_id, ..)| *peer_id == p && c == *conn_id), - "`inject_event` is never called for closed connections." + "`on_connection_handler_event` is never called for closed connections." ); - self.inject_event.push((p, c, e.clone())); + self.on_event.push((p, c, e.clone())); + #[allow(deprecated)] 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_new_listener(&mut self, id: ListenerId) { - self.inject_new_listener.push(id); - self.inner.inject_new_listener(id); - } - - fn inject_new_listen_addr(&mut self, id: ListenerId, a: &Multiaddr) { - self.inject_new_listen_addr.push((id, a.clone())); - self.inner.inject_new_listen_addr(id, a); - } - - fn inject_expired_listen_addr(&mut self, id: ListenerId, a: &Multiaddr) { - self.inject_expired_listen_addr.push((id, a.clone())); - self.inner.inject_expired_listen_addr(id, a); - } - - fn inject_new_external_addr(&mut self, a: &Multiaddr) { - self.inject_new_external_addr.push(a.clone()); - self.inner.inject_new_external_addr(a); - } - - fn inject_expired_external_addr(&mut self, a: &Multiaddr) { - self.inject_expired_external_addr.push(a.clone()); - self.inner.inject_expired_external_addr(a); - } - - fn inject_listener_error(&mut self, l: ListenerId, e: &(dyn std::error::Error + 'static)) { - self.inject_listener_error.push(l); - self.inner.inject_listener_error(l, e); - } - - fn inject_listener_closed(&mut self, l: ListenerId, r: Result<(), &std::io::Error>) { - self.inject_listener_closed.push((l, r.is_ok())); - self.inner.inject_listener_closed(l, r); - } - fn poll( &mut self, cx: &mut Context, diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index a6c8a19db4a..84fb3bf4683 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -21,7 +21,7 @@ use futures::StreamExt; use libp2p_identify as identify; use libp2p_ping as ping; -use libp2p_swarm::{dummy, NetworkBehaviour, SwarmEvent}; +use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent}; use std::fmt::Debug; /// Small utility to check that a type implements `NetworkBehaviour`. @@ -390,7 +390,7 @@ fn custom_out_event_no_type_parameters() { dummy::ConnectionHandler } - fn inject_event( + fn on_connection_handler_event( &mut self, _peer: PeerId, _connection: ConnectionId, @@ -406,6 +406,23 @@ fn custom_out_event_no_type_parameters() { ) -> Poll> { 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)]