From 9b01d61c08138ab4476d32d2e266a3de8c52dc85 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 14 Dec 2022 12:40:28 +1100 Subject: [PATCH 001/177] Use GATs to avoid lifetimes on trait interface --- protocols/kad/src/behaviour.rs | 6 ++---- protocols/kad/src/jobs.rs | 4 ++-- protocols/kad/src/record/store.rs | 26 ++++++++++++++---------- protocols/kad/src/record/store/memory.rs | 22 ++++++++++---------- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 42081b22108..7589cc57578 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -401,8 +401,7 @@ impl KademliaConfig { impl Kademlia where - for<'a> TStore: RecordStore<'a>, - TStore: Send + 'static, + TStore: RecordStore + Send + 'static, { /// Creates a new `Kademlia` network behaviour with a default configuration. pub fn new(id: PeerId, store: TStore) -> Self { @@ -1987,8 +1986,7 @@ fn exp_decrease(ttl: Duration, exp: u32) -> Duration { impl NetworkBehaviour for Kademlia where - for<'a> TStore: RecordStore<'a>, - TStore: Send + 'static, + TStore: RecordStore + Send + 'static, { type ConnectionHandler = KademliaHandlerProto; type OutEvent = KademliaEvent; diff --git a/protocols/kad/src/jobs.rs b/protocols/kad/src/jobs.rs index 8855026e8d5..7fbb6e00d75 100644 --- a/protocols/kad/src/jobs.rs +++ b/protocols/kad/src/jobs.rs @@ -193,7 +193,7 @@ impl PutRecordJob { /// to be run. pub fn poll(&mut self, cx: &mut Context<'_>, store: &mut T, now: Instant) -> Poll where - for<'a> T: RecordStore<'a>, + T: RecordStore, { if self.inner.check_ready(cx, now) { let publish = self.next_publish.map_or(false, |t_pub| now >= t_pub); @@ -294,7 +294,7 @@ impl AddProviderJob { now: Instant, ) -> Poll where - for<'a> T: RecordStore<'a>, + T: RecordStore, { if self.inner.check_ready(cx, now) { let records = store diff --git a/protocols/kad/src/record/store.rs b/protocols/kad/src/record/store.rs index 9e75e5a3e8a..5c25bc8b2fa 100644 --- a/protocols/kad/src/record/store.rs +++ b/protocols/kad/src/record/store.rs @@ -64,36 +64,40 @@ pub enum Error { /// content. Just like a regular record, a provider record is distributed /// to the closest nodes to the key. /// -pub trait RecordStore<'a> { - type RecordsIter: Iterator>; - type ProvidedIter: Iterator>; +pub trait RecordStore { + type RecordsIter<'a>: Iterator> + where + Self: 'a; + type ProvidedIter<'a>: Iterator> + where + Self: 'a; /// Gets a record from the store, given its key. - fn get(&'a self, k: &Key) -> Option>; + fn get(&self, k: &Key) -> Option>; /// Puts a record into the store. - fn put(&'a mut self, r: Record) -> Result<()>; + fn put(&mut self, r: Record) -> Result<()>; /// Removes the record with the given key from the store. - fn remove(&'a mut self, k: &Key); + fn remove(&mut self, k: &Key); /// Gets an iterator over all (value-) records currently stored. - fn records(&'a self) -> Self::RecordsIter; + fn records(&self) -> Self::RecordsIter<'_>; /// Adds a provider record to the store. /// /// A record store only needs to store a number of provider records /// for a key corresponding to the replication factor and should /// store those records whose providers are closest to the key. - fn add_provider(&'a mut self, record: ProviderRecord) -> Result<()>; + fn add_provider(&mut self, record: ProviderRecord) -> Result<()>; /// Gets a copy of the stored provider records for the given key. - fn providers(&'a self, key: &Key) -> Vec; + fn providers(&self, key: &Key) -> Vec; /// Gets an iterator over all stored provider records for which the /// node owning the store is itself the provider. - fn provided(&'a self) -> Self::ProvidedIter; + fn provided(&self) -> Self::ProvidedIter<'_>; /// Removes a provider record from the store. - fn remove_provider(&'a mut self, k: &Key, p: &PeerId); + fn remove_provider(&mut self, k: &Key, p: &PeerId); } diff --git a/protocols/kad/src/record/store/memory.rs b/protocols/kad/src/record/store/memory.rs index 39d17d37c2b..87951637889 100644 --- a/protocols/kad/src/record/store/memory.rs +++ b/protocols/kad/src/record/store/memory.rs @@ -96,20 +96,20 @@ impl MemoryStore { } } -impl<'a> RecordStore<'a> for MemoryStore { - type RecordsIter = +impl RecordStore for MemoryStore { + type RecordsIter<'a> = iter::Map, fn(&'a Record) -> Cow<'a, Record>>; - type ProvidedIter = iter::Map< + type ProvidedIter<'a> = iter::Map< hash_set::Iter<'a, ProviderRecord>, fn(&'a ProviderRecord) -> Cow<'a, ProviderRecord>, >; - fn get(&'a self, k: &Key) -> Option> { + fn get(&self, k: &Key) -> Option> { self.records.get(k).map(Cow::Borrowed) } - fn put(&'a mut self, r: Record) -> Result<()> { + fn put(&mut self, r: Record) -> Result<()> { if r.value.len() >= self.config.max_value_bytes { return Err(Error::ValueTooLarge); } @@ -131,15 +131,15 @@ impl<'a> RecordStore<'a> for MemoryStore { Ok(()) } - fn remove(&'a mut self, k: &Key) { + fn remove(&mut self, k: &Key) { self.records.remove(k); } - fn records(&'a self) -> Self::RecordsIter { + fn records(&self) -> Self::RecordsIter<'_> { self.records.values().map(Cow::Borrowed) } - fn add_provider(&'a mut self, record: ProviderRecord) -> Result<()> { + fn add_provider(&mut self, record: ProviderRecord) -> Result<()> { let num_keys = self.providers.len(); // Obtain the entry @@ -189,17 +189,17 @@ impl<'a> RecordStore<'a> for MemoryStore { Ok(()) } - fn providers(&'a self, key: &Key) -> Vec { + fn providers(&self, key: &Key) -> Vec { self.providers .get(key) .map_or_else(Vec::new, |ps| ps.clone().into_vec()) } - fn provided(&'a self) -> Self::ProvidedIter { + fn provided(&self) -> Self::ProvidedIter<'_> { self.provided.iter().map(Cow::Borrowed) } - fn remove_provider(&'a mut self, key: &Key, provider: &PeerId) { + fn remove_provider(&mut self, key: &Key, provider: &PeerId) { if let hash_map::Entry::Occupied(mut e) = self.providers.entry(key.clone()) { let providers = e.get_mut(); if let Some(i) = providers.iter().position(|p| &p.provider == provider) { From 4d246dc6475a5a3f275e8aa5f5d649f9d559ee01 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 14 Dec 2022 12:41:50 +1100 Subject: [PATCH 002/177] Bump MSRV accordingly --- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- protocols/kad/CHANGELOG.md | 2 ++ protocols/kad/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8df2d37c210..be066b37b46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ - Remove `SimpleProtocol` due to being unused. See [`libp2p::core::upgrade`](https://docs.rs/libp2p/0.50.0/libp2p/core/upgrade/index.html) for alternatives. See [PR 3191]. +- Bump MSRV to 1.65.0. + - Update individual crates. - Update to [`libp2p-dcutr` `v0.9.0`](protocols/dcutr/CHANGELOG.md#090). diff --git a/Cargo.toml b/Cargo.toml index eaed637a2d8..07f1d1fbc1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "libp2p" edition = "2021" -rust-version = "1.62.0" +rust-version = "1.65.0" description = "Peer-to-peer networking library" version = "0.51.0" authors = ["Parity Technologies "] diff --git a/protocols/kad/CHANGELOG.md b/protocols/kad/CHANGELOG.md index f126a519958..2edc45aeea6 100644 --- a/protocols/kad/CHANGELOG.md +++ b/protocols/kad/CHANGELOG.md @@ -2,6 +2,8 @@ - Update to `libp2p-swarm` `v0.42.0`. +- Bump MSRV to 1.65.0. + # 0.42.0 - Update to `libp2p-core` `v0.38.0`. diff --git a/protocols/kad/Cargo.toml b/protocols/kad/Cargo.toml index bf7a456df0e..8f8d8fad56e 100644 --- a/protocols/kad/Cargo.toml +++ b/protocols/kad/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "libp2p-kad" edition = "2021" -rust-version = "1.62.0" +rust-version = "1.65.0" description = "Kademlia protocol for libp2p" version = "0.43.0" authors = ["Parity Technologies "] From 74a275866640624e241b85a22eeee381fb393880 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 14 Dec 2022 12:54:31 +1100 Subject: [PATCH 003/177] Bump MSRV of libp2p-metrics --- misc/metrics/CHANGELOG.md | 2 ++ misc/metrics/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/metrics/CHANGELOG.md b/misc/metrics/CHANGELOG.md index 70cfd948e6a..bb6680530bd 100644 --- a/misc/metrics/CHANGELOG.md +++ b/misc/metrics/CHANGELOG.md @@ -2,6 +2,8 @@ - Add `connections_establishment_duration` metric. See [PR 3134]. +- Bump MSRV to 1.65.0. + - Update to `libp2p-dcutr` `v0.9.0`. - Update to `libp2p-ping` `v0.42.0`. diff --git a/misc/metrics/Cargo.toml b/misc/metrics/Cargo.toml index f1dc7526386..ba440704746 100644 --- a/misc/metrics/Cargo.toml +++ b/misc/metrics/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "libp2p-metrics" edition = "2021" -rust-version = "1.62.0" +rust-version = "1.65.0" description = "Metrics for libp2p" version = "0.12.0" authors = ["Max Inden "] From c1e880ca25151664a5cb392479918ffa73b5460e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Dec 2022 15:35:56 +1100 Subject: [PATCH 004/177] Refactor dialling to have a more linear flow --- swarm/src/dial_opts.rs | 100 +++++++++++++++++++++++ swarm/src/lib.rs | 179 +++++++++++++---------------------------- 2 files changed, 155 insertions(+), 124 deletions(-) diff --git a/swarm/src/dial_opts.rs b/swarm/src/dial_opts.rs index edc69484b68..acc1b69a617 100644 --- a/swarm/src/dial_opts.rs +++ b/swarm/src/dial_opts.rs @@ -20,6 +20,8 @@ // DEALINGS IN THE SOFTWARE. use libp2p_core::connection::Endpoint; +use libp2p_core::multiaddr::Protocol; +use libp2p_core::multihash::Multihash; use libp2p_core::{Multiaddr, PeerId}; use std::num::NonZeroU8; @@ -79,6 +81,104 @@ impl DialOpts { DialOpts(Opts::WithoutPeerIdWithAddress(_)) => None, } } + + /// Retrieves the [`PeerId`] from the [`DialOpts`] if specified or otherwise tries to parse it + /// from the multihash in the `/p2p` part of the address, if present. + /// + /// Note: A [`Multiaddr`] with something else other than a [`PeerId`] within the `/p2p` protocol is invalid as per specification. + /// Unfortunately, we are not making good use of the type system here. + /// Really, this function should be merged with [`DialOpts::get_peer_id`] above. + /// If it weren't for the parsing error, the function signatures would be the same. + /// + /// See . + pub(crate) fn get_or_parse_peer_id(&self) -> Result, Multihash> { + match self { + DialOpts(Opts::WithPeerId(WithPeerId { peer_id, .. })) => Ok(Some(*peer_id)), + DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { + peer_id, .. + })) => Ok(Some(*peer_id)), + DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { + address, .. + })) => { + let peer_id = address + .iter() + .last() + .and_then(|p| { + if let Protocol::P2p(ma) = p { + Some(PeerId::try_from(ma)) + } else { + None + } + }) + .transpose()?; + + Ok(peer_id) + } + } + } + + pub(crate) fn get_addresses(&self) -> Vec { + match self { + DialOpts(Opts::WithPeerId(WithPeerId { .. })) => vec![], + DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { + addresses, .. + })) => addresses.clone(), + DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { + address, .. + })) => vec![address.clone()], + } + } + + pub(crate) fn extend_addresses_through_behaviour(&self) -> bool { + match self { + DialOpts(Opts::WithPeerId(WithPeerId { .. })) => true, + DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { + extend_addresses_through_behaviour, + .. + })) => *extend_addresses_through_behaviour, + DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. })) => true, + } + } + + pub(crate) fn peer_condition(&self) -> PeerCondition { + match self { + DialOpts( + Opts::WithPeerId(WithPeerId { condition, .. }) + | Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { condition, .. }), + ) => *condition, + DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. })) => { + PeerCondition::Always + } + } + } + + pub(crate) fn dial_concurrency_override(&self) -> Option { + match self { + DialOpts(Opts::WithPeerId(WithPeerId { + dial_concurrency_factor_override, + .. + })) => *dial_concurrency_factor_override, + DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { + dial_concurrency_factor_override, + .. + })) => *dial_concurrency_factor_override, + DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. })) => None, + } + } + + pub(crate) fn role_override(&self) -> Endpoint { + match self { + DialOpts(Opts::WithPeerId(WithPeerId { role_override, .. })) => *role_override, + DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { + role_override, + .. + })) => *role_override, + DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { + role_override, + .. + })) => *role_override, + } + } } impl From for DialOpts { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index cf6051e1e85..ed0a89dea35 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -122,7 +122,6 @@ pub use registry::{AddAddressResult, AddressRecord, AddressScore}; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; use dial_opts::{DialOpts, PeerCondition}; -use either::Either; use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream}; use libp2p_core::connection::ConnectionId; use libp2p_core::muxing::SubstreamBox; @@ -138,7 +137,6 @@ use libp2p_core::{ use registry::{AddressIntoIter, Addresses}; use smallvec::SmallVec; use std::collections::{HashMap, HashSet}; -use std::iter; use std::num::{NonZeroU32, NonZeroU8, NonZeroUsize}; use std::{ convert::TryFrom, @@ -507,139 +505,72 @@ where fn dial_with_handler( &mut self, - swarm_dial_opts: DialOpts, + dial_opts: DialOpts, handler: ::ConnectionHandler, ) -> Result<(), DialError> { - let (peer_id, addresses, dial_concurrency_factor_override, role_override) = - match swarm_dial_opts.0 { - // Dial a known peer. - dial_opts::Opts::WithPeerId(dial_opts::WithPeerId { - peer_id, - condition, - role_override, - dial_concurrency_factor_override, - }) - | dial_opts::Opts::WithPeerIdWithAddresses(dial_opts::WithPeerIdWithAddresses { - peer_id, - condition, - role_override, - dial_concurrency_factor_override, - .. - }) => { - // Check [`PeerCondition`] if provided. - let condition_matched = match condition { - PeerCondition::Disconnected => !self.is_connected(&peer_id), - PeerCondition::NotDialing => !self.pool.is_dialing(peer_id), - PeerCondition::Always => true, - }; - if !condition_matched { - #[allow(deprecated)] - self.behaviour.inject_dial_failure( - Some(peer_id), - handler, - &DialError::DialPeerConditionFalse(condition), - ); - - return Err(DialError::DialPeerConditionFalse(condition)); - } + let peer_id = dial_opts + .get_or_parse_peer_id() + .map_err(DialError::InvalidPeerId)?; + let condition = dial_opts.peer_condition(); + + let should_dial = match (condition, peer_id) { + (PeerCondition::Always, _) => true, + (PeerCondition::Disconnected, None) => true, + (PeerCondition::NotDialing, None) => true, + (PeerCondition::Disconnected, Some(peer_id)) => !self.pool.is_connected(peer_id), + (PeerCondition::NotDialing, Some(peer_id)) => !self.pool.is_dialing(peer_id), + }; - // 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); - } + if !should_dial { + let e = DialError::DialPeerConditionFalse(condition); - // Retrieve the addresses to dial. - let addresses = { - let mut addresses = match swarm_dial_opts.0 { - dial_opts::Opts::WithPeerId(dial_opts::WithPeerId { .. }) => { - self.behaviour.addresses_of_peer(&peer_id) - } - dial_opts::Opts::WithPeerIdWithAddresses( - dial_opts::WithPeerIdWithAddresses { - peer_id, - mut addresses, - extend_addresses_through_behaviour, - .. - }, - ) => { - if extend_addresses_through_behaviour { - addresses.extend(self.behaviour.addresses_of_peer(&peer_id)) - } - addresses - } - dial_opts::Opts::WithoutPeerIdWithAddress { .. } => { - unreachable!("Due to outer match.") - } - }; + #[allow(deprecated)] + self.behaviour.inject_dial_failure(peer_id, handler, &e); - let mut unique_addresses = HashSet::new(); - addresses.retain(|addr| { - !self.listened_addrs.values().flatten().any(|a| a == addr) - && unique_addresses.insert(addr.clone()) - }); + return Err(e); + } - if addresses.is_empty() { - let error = DialError::NoAddresses; - #[allow(deprecated)] - self.behaviour - .inject_dial_failure(Some(peer_id), handler, &error); - return Err(error); - }; + if let Some(peer_id) = peer_id { + // 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); + } + } - addresses - }; + let addresses = { + let mut addresses = dial_opts.get_addresses(); - ( - Some(peer_id), - Either::Left(addresses.into_iter()), - dial_concurrency_factor_override, - role_override, - ) + if let Some(peer_id) = peer_id { + if dial_opts.extend_addresses_through_behaviour() { + addresses.extend(self.behaviour.addresses_of_peer(&peer_id)); } - // Dial an unknown peer. - dial_opts::Opts::WithoutPeerIdWithAddress( - dial_opts::WithoutPeerIdWithAddress { - address, - role_override, - }, - ) => { - // If the address ultimately encapsulates an expected peer ID, dial that peer - // such that any mismatch is detected. We do not "pop off" the `P2p` protocol - // from the address, because it may be used by the `Transport`, i.e. `P2p` - // is a protocol component that can influence any transport, like `libp2p-dns`. - let peer_id = match address - .iter() - .last() - .and_then(|p| { - if let Protocol::P2p(ma) = p { - Some(PeerId::try_from(ma)) - } else { - None - } - }) - .transpose() - { - Ok(peer_id) => peer_id, - Err(multihash) => return Err(DialError::InvalidPeerId(multihash)), - }; + } - ( - peer_id, - Either::Right(iter::once(address)), - None, - role_override, - ) - } + let mut unique_addresses = HashSet::new(); + addresses.retain(|addr| { + !self.listened_addrs.values().flatten().any(|a| a == addr) + && unique_addresses.insert(addr.clone()) + }); + + if addresses.is_empty() { + let error = DialError::NoAddresses; + #[allow(deprecated)] + self.behaviour.inject_dial_failure(peer_id, handler, &error); + return Err(error); }; + addresses + }; + let dials = addresses + .into_iter() .map(|a| match p2p_addr(peer_id, a) { Ok(address) => { - let dial = match role_override { + let dial = match dial_opts.role_override() { Endpoint::Dialer => self.transport.dial(address.clone()), Endpoint::Listener => self.transport.dial_as_listener(address.clone()), }; @@ -662,8 +593,8 @@ where dials, peer_id, handler, - role_override, - dial_concurrency_factor_override, + dial_opts.role_override(), + dial_opts.dial_concurrency_override(), ) { Ok(_connection_id) => Ok(()), Err((connection_limit, handler)) => { @@ -1088,9 +1019,9 @@ where return Some(SwarmEvent::Behaviour(event)) } NetworkBehaviourAction::Dial { opts, handler } => { - let peer_id = opts.get_peer_id(); + let peer_id = opts.get_or_parse_peer_id(); if let Ok(()) = self.dial_with_handler(opts, handler) { - if let Some(peer_id) = peer_id { + if let Ok(Some(peer_id)) = peer_id { return Some(SwarmEvent::Dialing(peer_id)); } } From 82ae04da4dfb77a40f2573e6bb6648cc3e7eb1c0 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Dec 2022 16:25:22 +1100 Subject: [PATCH 005/177] Introduce new callbacks for connection management --- core/src/connection.rs | 11 +- protocols/dcutr/src/behaviour.rs | 2 +- protocols/floodsub/src/layer.rs | 2 +- protocols/gossipsub/src/behaviour.rs | 2 +- protocols/identify/src/behaviour.rs | 2 +- protocols/kad/src/behaviour.rs | 2 +- protocols/ping/src/lib.rs | 2 +- protocols/relay/src/v2/client.rs | 2 +- protocols/relay/src/v2/relay.rs | 2 +- protocols/rendezvous/src/client.rs | 2 +- protocols/rendezvous/src/server.rs | 2 +- protocols/request-response/src/lib.rs | 2 +- swarm/src/behaviour.rs | 486 +++++++------------------- swarm/src/behaviour/either.rs | 7 +- swarm/src/behaviour/toggle.rs | 4 +- swarm/src/connection/pool.rs | 166 ++++----- swarm/src/dummy.rs | 4 +- swarm/src/keep_alive.rs | 3 +- swarm/src/lib.rs | 263 +++++++++----- swarm/src/test.rs | 4 +- swarm/tests/swarm_derive.rs | 2 +- 21 files changed, 424 insertions(+), 548 deletions(-) diff --git a/core/src/connection.rs b/core/src/connection.rs index 91008408fe2..7e4e524ce93 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -21,7 +21,7 @@ use crate::multiaddr::{Multiaddr, Protocol}; /// Connection identifier. -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ConnectionId(usize); impl ConnectionId { @@ -30,16 +30,15 @@ impl ConnectionId { /// This is primarily useful for creating connection IDs /// in test environments. There is in general no guarantee /// that all connection IDs are based on non-negative integers. + #[deprecated(note = "IDs must be unique and should not be constructed directly.")] pub fn new(id: usize) -> Self { Self(id) } } -impl std::ops::Add for ConnectionId { - type Output = Self; - - fn add(self, other: usize) -> Self { - Self(self.0 + other) +impl Default for ConnectionId { + fn default() -> Self { + Self(rand::random()) } } diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 15dfe078bfe..8654aaca0fe 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -314,7 +314,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action.build(self.local_peer_id, &self.external_addresses)); } diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 776c0e8551b..47d32283aab 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -472,7 +472,7 @@ impl NetworkBehaviour for Floodsub { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index c361fc4fdbc..6260798eb0c 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -3447,7 +3447,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event.map_in(|e: Arc| { // clone send event reference if others references are present diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index beb264da789..f935cbe8a75 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -310,7 +310,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 42081b22108..96de726a8f3 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -2295,7 +2295,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { let now = Instant::now(); // Calculate the available capacity for queries triggered by background jobs. diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 6e481500df9..ff1a99fd1a5 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -131,7 +131,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(e) = self.events.pop_back() { let Event { result, peer } = &e; diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index d9a2d977588..0b8de8f4af2 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -247,7 +247,7 @@ impl NetworkBehaviour for Client { &mut self, cx: &mut Context<'_>, _poll_parameters: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.queued_actions.pop_front() { return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); } diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 97f7099c95d..46879061c83 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -645,7 +645,7 @@ impl NetworkBehaviour for Relay { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action.build(self.local_peer_id, &self.external_addresses)); } diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 599fc8f508f..a82800b9281 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -220,7 +220,7 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 4126b6e3e28..2ecc118494d 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -148,7 +148,7 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Poll::Ready(ExpiredRegistration(registration)) = self.registrations.poll(cx) { return Poll::Ready(NetworkBehaviourAction::GenerateEvent( Event::RegistrationExpired(registration), diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index f5fa3067f80..a8972253ce0 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -931,7 +931,7 @@ where &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(ev) = self.pending_events.pop_front() { return Poll::Ready(ev); } else if self.pending_events.capacity() > EMPTY_QUEUE_SHRINK_THRESHOLD { diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 141d6c3efbd..e4eac61be2a 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -19,28 +19,16 @@ // DEALINGS IN THE SOFTWARE. mod either; -mod external_addresses; -mod listen_addresses; pub mod toggle; -pub use external_addresses::ExternalAddresses; -pub use listen_addresses::ListenAddresses; - use crate::dial_opts::DialOpts; use crate::handler::{ConnectionHandler, IntoConnectionHandler}; use crate::{AddressRecord, AddressScore, DialError}; use libp2p_core::{ - connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, + connection::ConnectionId, transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId, }; use std::{task::Context, task::Poll}; -/// Custom event that can be received by the [`ConnectionHandler`]. -pub(crate) type THandlerInEvent = - <::Handler as ConnectionHandler>::InEvent; - -pub(crate) type THandlerOutEvent = - <::Handler as ConnectionHandler>::OutEvent; - /// A [`NetworkBehaviour`] defines the behaviour of the local node on the network. /// /// In contrast to [`Transport`](libp2p_core::Transport) which defines **how** to send bytes on the @@ -123,30 +111,119 @@ pub(crate) type THandlerOutEvent = /// } /// } /// ``` -pub trait NetworkBehaviour: 'static { +pub trait NetworkBehaviour: Sized + 'static { /// Handler for all the protocols the network behaviour supports. type ConnectionHandler: IntoConnectionHandler; /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; - /// Creates a new [`ConnectionHandler`] for a connection with a peer. + // /// Creates a new [`ConnectionHandler`] for a connection with a peer. + // /// + // /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] + // /// emitted a dial request, this method is called. + // /// + // /// The returned object is a handler for that specific connection, and will be moved to a + // /// background task dedicated to that connection. + // /// + // /// The network behaviour (ie. the implementation of this trait) and the handlers it has spawned + // /// (ie. the objects returned by `new_handler`) can communicate by passing messages. Messages + // /// sent from the handler to the behaviour are injected with [`NetworkBehaviour::inject_event`], + // /// and the behaviour can send a message to the handler by making [`NetworkBehaviour::poll`] + // /// return [`NetworkBehaviourAction::NotifyHandler`]. + // /// + // /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and + // /// connection closing. + #[deprecated(note = "Override the ")] + fn new_handler(&mut self) -> Self::ConnectionHandler; + + /// Callback that is invoked for every new inbound connection. /// - /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] - /// emitted a dial request, this method is called. + /// At this point in the connection lifecycle, only the remote's and our local address are known. + /// We have also already allocated a [`ConnectionId`]. /// - /// The returned object is a handler for that specific connection, and will be moved to a - /// background task dedicated to that connection. + /// Any error returned from this function will immediately abort the dial attempt. + fn handle_pending_inbound_connection( + &mut self, + _connection_id: ConnectionId, + _local_addr: &Multiaddr, + _remote_addr: &Multiaddr, + ) -> Result<(), Box> { + Ok(()) + } + + /// Callback that is invoked for every established inbound connection. /// - /// The network behaviour (ie. the implementation of this trait) and the handlers it has spawned - /// (ie. the objects returned by `new_handler`) can communicate by passing messages. Messages - /// sent from the handler to the behaviour are injected with [`NetworkBehaviour::inject_event`], - /// and the behaviour can send a message to the handler by making [`NetworkBehaviour::poll`] - /// return [`NetworkBehaviourAction::NotifyHandler`]. + /// This is invoked once another peer has successfully dialed us. /// - /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and - /// connection closing. - fn new_handler(&mut self) -> Self::ConnectionHandler; + /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial. + /// In order to actually use this connection, this function must return a [`ConnectionHandler`]. + /// Returning an error will immediately close the connection. + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + _connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result< + ::Handler, + Box, + > { + #[allow(deprecated)] + Ok(self.new_handler().into_handler( + &peer, + &ConnectedPoint::Listener { + local_addr: local_addr.clone(), + send_back_addr: remote_addr.clone(), + }, + )) + } + + /// Callback that is invoked for every outbound connection attempt. + /// + /// We have access to: + /// + /// - The [`PeerId`], if known. Remember that we can dial without a [`PeerId`]. + /// - All addresses passes to [`DialOpts`] are passed in here too. + /// - The effective [`Role`](Endpoint) of this peer in the dial attempt. Typically, this is set to [`Endpoint::Dialer`] except if we are attempting a hole-punch. + /// - The [`ConnectionId`] identifying the future connection resulting from this dial, if successful. + /// + /// Any error returned from this function will immediately abort the dial attempt. + fn handle_pending_outbound_connection( + &mut self, + _maybe_peer: Option, + _addresses: &[&Multiaddr], + _effective_role: Endpoint, + _connection_id: ConnectionId, + ) -> Result, Box> { + Ok(vec![]) + } + + /// Callback that is invoked for every established outbound connection. + /// + /// This is invoked once we have successfully dialed a peer. + /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial. + /// In order to actually use this connection, this function must return a [`ConnectionHandler`]. + /// Returning an error will immediately close the connection. + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + _connection_id: ConnectionId, + ) -> Result< + ::Handler, + Box, + > { + #[allow(deprecated)] + Ok(self.new_handler().into_handler( + &peer, + &ConnectedPoint::Dialer { + address: addr.clone(), + role_override, + }, + )) + } /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. @@ -154,6 +231,7 @@ pub trait NetworkBehaviour: 'static { /// The addresses will be tried in the order returned by this function, which means that they /// should be ordered by decreasing likelihood of reachability. In other words, the first /// address should be the most likely to be reachable. + #[deprecated(note = "Use `NetworkBehaviour::handle_pending_outbound_connection` instead.")] fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { vec![] } @@ -170,8 +248,7 @@ pub trait NetworkBehaviour: 'static { &mut self, _peer_id: PeerId, _connection_id: ConnectionId, - _event: <::Handler as - ConnectionHandler>::OutEvent, + _event: <::Handler as ConnectionHandler>::OutEvent, ) { } @@ -267,17 +344,8 @@ pub trait NetworkBehaviour: 'static { 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, - ) { - self.on_swarm_event(FromSwarm::DialFailure(DialFailure { - peer_id, - handler, - error, - })); + fn inject_dial_failure(&mut self, peer_id: Option, error: &DialError) { + self.on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, error })); } /// Indicates to the behaviour that an error happened on an incoming connection during its @@ -289,16 +357,10 @@ pub trait NetworkBehaviour: 'static { 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, - ) { + fn inject_listen_failure(&mut self, local_addr: &Multiaddr, send_back_addr: &Multiaddr) { self.on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, - handler, })); } @@ -386,7 +448,7 @@ pub trait NetworkBehaviour: 'static { &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll>; + ) -> Poll>>; } /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. @@ -437,200 +499,12 @@ pub trait PollParameters { // [`NetworkBehaviourAction::map_in`], mapping the handler `InEvent` leaving the // handler itself untouched. #[derive(Debug)] -pub enum NetworkBehaviourAction< - TOutEvent, - THandler: IntoConnectionHandler, - TInEvent = THandlerInEvent, -> { +pub enum NetworkBehaviourAction { /// Instructs the `Swarm` to return an event when it is being polled. GenerateEvent(TOutEvent), /// Instructs the swarm to start a dial. - /// - /// On success, [`NetworkBehaviour::inject_connection_established`] is invoked. - /// On failure, [`NetworkBehaviour::inject_dial_failure`] is invoked. - /// - /// Note that the provided handler is returned to the [`NetworkBehaviour`] on connection failure - /// and connection closing. Thus it can be used to carry state, which otherwise would have to be - /// tracked in the [`NetworkBehaviour`] itself. E.g. a message destined to an unconnected peer - /// can be included in the handler, and thus directly send on connection success or extracted by - /// the [`NetworkBehaviour`] on connection failure. - /// - /// # Example carrying state in the handler - /// - /// ```rust - /// # use futures::executor::block_on; - /// # use futures::stream::StreamExt; - /// # use libp2p_core::connection::ConnectionId; - /// # use libp2p_core::identity; - /// # use libp2p_core::transport::{MemoryTransport, Transport}; - /// # use libp2p_core::upgrade::{self, DeniedUpgrade, InboundUpgrade, OutboundUpgrade}; - /// # use libp2p_core::PeerId; - /// # use libp2p_plaintext::PlainText2Config; - /// # use libp2p_swarm::{ - /// # DialError, IntoConnectionHandler, KeepAlive, NegotiatedSubstream, - /// # NetworkBehaviour, NetworkBehaviourAction, PollParameters, ConnectionHandler, - /// # ConnectionHandlerEvent, ConnectionHandlerUpgrErr, SubstreamProtocol, Swarm, SwarmEvent, - /// # }; - /// # use libp2p_swarm::dial_opts::{DialOpts, PeerCondition}; - /// # use libp2p_yamux as yamux; - /// # use std::collections::VecDeque; - /// # use std::task::{Context, Poll}; - /// # use void::Void; - /// # - /// # let local_key = identity::Keypair::generate_ed25519(); - /// # let local_public_key = local_key.public(); - /// # let local_peer_id = PeerId::from(local_public_key.clone()); - /// # - /// # let transport = MemoryTransport::default() - /// # .upgrade(upgrade::Version::V1) - /// # .authenticate(PlainText2Config { local_public_key }) - /// # .multiplex(yamux::YamuxConfig::default()) - /// # .boxed(); - /// # - /// # let mut swarm = Swarm::with_threadpool_executor(transport, MyBehaviour::default(), local_peer_id); - /// # - /// // Super precious message that we should better not lose. - /// let message = PreciousMessage("My precious message".to_string()); - /// - /// // Unfortunately this peer is offline, thus sending our message to it will fail. - /// let offline_peer = PeerId::random(); - /// - /// // Let's send it anyways. We should get it back in case connecting to the peer fails. - /// swarm.behaviour_mut().send(offline_peer, message); - /// - /// block_on(async { - /// // As expected, sending failed. But great news, we got our message back. - /// matches!( - /// swarm.next().await.expect("Infinite stream"), - /// SwarmEvent::Behaviour(PreciousMessage(_)) - /// ); - /// }); - /// - /// #[derive(Default)] - /// struct MyBehaviour { - /// outbox_to_swarm: VecDeque>, - /// } - /// - /// impl MyBehaviour { - /// fn send(&mut self, peer_id: PeerId, msg: PreciousMessage) { - /// self.outbox_to_swarm - /// .push_back(NetworkBehaviourAction::Dial { - /// opts: DialOpts::peer_id(peer_id) - /// .condition(PeerCondition::Always) - /// .build(), - /// handler: MyHandler { message: Some(msg) }, - /// }); - /// } - /// } - /// # - /// impl NetworkBehaviour for MyBehaviour { - /// # type ConnectionHandler = MyHandler; - /// # type OutEvent = PreciousMessage; - /// # - /// # fn new_handler(&mut self) -> Self::ConnectionHandler { - /// # MyHandler { message: None } - /// # } - /// # - /// # - /// # fn inject_event( - /// # &mut self, - /// # _: PeerId, - /// # _: ConnectionId, - /// # _: <::Handler as ConnectionHandler>::OutEvent, - /// # ) { - /// # unreachable!(); - /// # } - /// # - /// fn inject_dial_failure( - /// &mut self, - /// _: Option, - /// handler: Self::ConnectionHandler, - /// _: &DialError, - /// ) { - /// // As expected, sending the message failed. But lucky us, we got the handler back, thus - /// // the precious message is not lost and we can return it back to the user. - /// let msg = handler.message.unwrap(); - /// self.outbox_to_swarm - /// .push_back(NetworkBehaviourAction::GenerateEvent(msg)) - /// } - /// # - /// # fn poll( - /// # &mut self, - /// # _: &mut Context<'_>, - /// # _: &mut impl PollParameters, - /// # ) -> Poll> { - /// # if let Some(action) = self.outbox_to_swarm.pop_front() { - /// # return Poll::Ready(action); - /// # } - /// # Poll::Pending - /// # } - /// } - /// - /// # struct MyHandler { - /// # message: Option, - /// # } - /// # - /// # impl ConnectionHandler for MyHandler { - /// # type InEvent = Void; - /// # type OutEvent = Void; - /// # type Error = Void; - /// # type InboundProtocol = DeniedUpgrade; - /// # type OutboundProtocol = DeniedUpgrade; - /// # type InboundOpenInfo = (); - /// # type OutboundOpenInfo = Void; - /// # - /// # fn listen_protocol( - /// # &self, - /// # ) -> SubstreamProtocol { - /// # SubstreamProtocol::new(DeniedUpgrade, ()) - /// # } - /// # - /// # fn inject_fully_negotiated_inbound( - /// # &mut self, - /// # _: >::Output, - /// # _: Self::InboundOpenInfo, - /// # ) { - /// # } - /// # - /// # fn inject_fully_negotiated_outbound( - /// # &mut self, - /// # _: >::Output, - /// # _: Self::OutboundOpenInfo, - /// # ) { - /// # } - /// # - /// # fn inject_event(&mut self, _event: Self::InEvent) {} - /// # - /// # fn inject_dial_upgrade_error( - /// # &mut self, - /// # _: Self::OutboundOpenInfo, - /// # _: ConnectionHandlerUpgrErr, - /// # ) { - /// # } - /// # - /// # fn connection_keep_alive(&self) -> KeepAlive { - /// # KeepAlive::Yes - /// # } - /// # - /// # fn poll( - /// # &mut self, - /// # _: &mut Context<'_>, - /// # ) -> Poll< - /// # ConnectionHandlerEvent< - /// # Self::OutboundProtocol, - /// # Self::OutboundOpenInfo, - /// # Self::OutEvent, - /// # Self::Error, - /// # >, - /// # > { - /// # todo!("If `Self::message.is_some()` send the message to the remote.") - /// # } - /// # } - /// # #[derive(Debug, PartialEq, Eq)] - /// # struct PreciousMessage(String); - /// ``` - Dial { opts: DialOpts, handler: THandler }, + Dial { opts: DialOpts, id: ConnectionId }, /// Instructs the `Swarm` to send an event to the handler dedicated to a /// connection with a peer. @@ -690,18 +564,16 @@ pub enum NetworkBehaviourAction< }, } -impl - NetworkBehaviourAction -{ +impl NetworkBehaviourAction { /// Map the handler event. pub fn map_in( self, f: impl FnOnce(TInEventOld) -> TInEventNew, - ) -> NetworkBehaviourAction { + ) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => { - NetworkBehaviourAction::Dial { opts, handler } + NetworkBehaviourAction::Dial { opts, id } => { + NetworkBehaviourAction::Dial { opts, id } } NetworkBehaviourAction::NotifyHandler { peer_id, @@ -731,52 +603,9 @@ impl NetworkBehaviourAction(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), - NetworkBehaviourAction::Dial { opts, handler } => { - NetworkBehaviourAction::Dial { opts, handler } - } - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - } => NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - }, - NetworkBehaviourAction::ReportObservedAddr { address, score } => { - NetworkBehaviourAction::ReportObservedAddr { address, score } + NetworkBehaviourAction::Dial { opts, id } => { + NetworkBehaviourAction::Dial { opts, id } } - NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - } => NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - }, - } - } -} - -impl NetworkBehaviourAction -where - THandlerOld: IntoConnectionHandler, - ::Handler: ConnectionHandler, -{ - /// Map the handler. - pub fn map_handler( - self, - f: impl FnOnce(THandlerOld) -> THandlerNew, - ) -> NetworkBehaviourAction - where - THandlerNew: IntoConnectionHandler, - ::Handler: ConnectionHandler, - { - match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial { - opts, - handler: f(handler), - }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -800,50 +629,6 @@ where } } -impl NetworkBehaviourAction -where - THandlerOld: IntoConnectionHandler, - ::Handler: ConnectionHandler, -{ - /// Map the handler and handler event. - pub fn map_handler_and_in( - self, - f_handler: impl FnOnce(THandlerOld) -> THandlerNew, - f_in_event: impl FnOnce(TInEventOld) -> TInEventNew, - ) -> NetworkBehaviourAction - where - THandlerNew: IntoConnectionHandler, - ::Handler: ConnectionHandler, - { - match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial { - opts, - handler: f_handler(handler), - }, - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - } => NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event: f_in_event(event), - }, - NetworkBehaviourAction::ReportObservedAddr { address, score } => { - NetworkBehaviourAction::ReportObservedAddr { address, score } - } - NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - } => NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - }, - } - } -} - /// The options w.r.t. which connection handler to notify of an event. #[derive(Debug, Clone)] pub enum NotifyHandler { @@ -884,13 +669,13 @@ pub enum FromSwarm<'a, Handler: IntoConnectionHandler> { AddressChange(AddressChange<'a>), /// Informs the behaviour that the dial to a known /// or unknown node failed. - DialFailure(DialFailure<'a, Handler>), + DialFailure(DialFailure<'a>), /// 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>), + ListenFailure(ListenFailure<'a>), /// Informs the behaviour that a new listener was created. NewListener(NewListener), /// Informs the behaviour that we have started listening on a new multiaddr. @@ -945,9 +730,8 @@ pub struct AddressChange<'a> { /// [`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 struct DialFailure<'a> { pub peer_id: Option, - pub handler: Handler, pub error: &'a DialError, } @@ -957,10 +741,9 @@ pub struct DialFailure<'a, Handler> { /// 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 struct ListenFailure<'a> { 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. @@ -1076,23 +859,15 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { old, new, })), - FromSwarm::DialFailure(DialFailure { - peer_id, - handler, - error, - }) => Some(FromSwarm::DialFailure(DialFailure { - peer_id, - handler: map_into_handler(handler)?, - error, - })), + FromSwarm::DialFailure(DialFailure { peer_id, error }) => { + Some(FromSwarm::DialFailure(DialFailure { peer_id, 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 })) @@ -1178,21 +953,16 @@ pub(crate) fn inject_from_swarm( #[allow(deprecated)] behaviour.inject_address_change(&peer_id, &connection_id, old, new); } - FromSwarm::DialFailure(DialFailure { - peer_id, - handler, - error, - }) => { + FromSwarm::DialFailure(DialFailure { peer_id, error }) => { #[allow(deprecated)] - behaviour.inject_dial_failure(peer_id, handler, error); + behaviour.inject_dial_failure(peer_id, error); } FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, - handler, }) => { #[allow(deprecated)] - behaviour.inject_listen_failure(local_addr, send_back_addr, handler); + behaviour.inject_listen_failure(local_addr, send_back_addr); } FromSwarm::NewListener(NewListener { listener_id }) => { #[allow(deprecated)] diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 4154db1a0de..e72a7ea01ac 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -25,6 +25,7 @@ use crate::handler::either::IntoEitherHandler; use either::Either; use libp2p_core::{Multiaddr, PeerId}; use std::{task::Context, task::Poll}; +use crate::THandlerInEvent; /// Implementation of [`NetworkBehaviour`] that can be either of two implementations. impl NetworkBehaviour for Either @@ -97,14 +98,14 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { let event = match self { Either::Left(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Left) - .map_handler_and_in(IntoEitherHandler::Left, Either::Left), + .map_in(Either::Left), Either::Right(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Right) - .map_handler_and_in(IntoEitherHandler::Right, Either::Right), + .map_in(Either::Right), }; Poll::Ready(event) diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 81255a40274..962a933a972 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -25,7 +25,7 @@ use crate::handler::{ KeepAlive, ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; -use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent}; use either::Either; use libp2p_core::{ either::{EitherError, EitherOutput}, @@ -108,7 +108,7 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(inner) = self.inner.as_mut() { inner.poll(cx, params).map(|action| { action.map_handler(|h| ToggleIntoConnectionHandler { inner: Some(h) }) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 7a81c57e2df..3f3818d340f 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -18,16 +18,15 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. - use crate::connection::Connection; +use crate::upgrade::UpgradeInfoSend; use crate::{ - behaviour::{THandlerInEvent, THandlerOutEvent}, connection::{ Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError, }, transport::{Transport, TransportError}, - ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, PeerId, + ConnectedPoint, ConnectionHandler, Executor, Multiaddr, PeerId, }; use concurrent_dial::ConcurrentDial; use fnv::FnvHashMap; @@ -38,9 +37,11 @@ use futures::{ ready, stream::FuturesUnordered, }; -use instant::Instant; use libp2p_core::connection::{ConnectionId, Endpoint, PendingPoint}; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerExt}; +use libp2p_core::ProtocolName; +use smallvec::SmallVec; +use std::error::Error; use std::{ collections::{hash_map, HashMap}, convert::TryFrom as _, @@ -82,7 +83,7 @@ impl ExecSwitch { pub struct Pool where TTrans: Transport, - THandler: IntoConnectionHandler, + THandler: ConnectionHandler, { local_id: PeerId, @@ -90,19 +91,11 @@ where counters: ConnectionCounters, /// The managed connections of each peer that are currently considered established. - established: FnvHashMap< - PeerId, - FnvHashMap< - ConnectionId, - EstablishedConnection<::InEvent>, - >, - >, + established: + FnvHashMap>>, /// The pending connections that are currently being negotiated. - pending: HashMap>, - - /// Next available identifier for a new connection / task. - next_connection_id: ConnectionId, + pending: HashMap, /// Size of the task command buffer (per task). task_command_buffer_size: usize, @@ -131,12 +124,10 @@ where /// Sender distributed to established tasks for reporting events back /// to the pool. - established_connection_events_tx: - mpsc::Sender>, + established_connection_events_tx: mpsc::Sender>, /// Receiver for events reported from established tasks. - established_connection_events_rx: - mpsc::Receiver>, + established_connection_events_rx: mpsc::Receiver>, } #[derive(Debug)] @@ -188,19 +179,15 @@ impl EstablishedConnection { } } -struct PendingConnection { +struct PendingConnection { /// [`PeerId`] of the remote peer. peer_id: Option, - /// Handler to handle connection once no longer pending but established. - handler: THandler, endpoint: PendingPoint, /// When dropped, notifies the task which then knows to terminate. abort_notifier: Option>, - /// The moment we became aware of this possible connection, useful for timing metrics. - accepted_at: Instant, } -impl PendingConnection { +impl PendingConnection { fn is_for_same_remote_as(&self, other: PeerId) -> bool { self.peer_id.map_or(false, |peer| peer == other) } @@ -213,7 +200,7 @@ impl PendingConnection { } } -impl fmt::Debug for Pool { +impl fmt::Debug for Pool { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.debug_struct("Pool") .field("counters", &self.counters) @@ -223,7 +210,8 @@ impl fmt::Debug for Pool +#[allow(clippy::large_enum_variant)] +pub enum PoolEvent where TTrans: Transport, { @@ -240,8 +228,8 @@ where /// Addresses are dialed in parallel. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. concurrent_dial_errors: Option)>>, - /// How long it took to establish this connection. - established_in: std::time::Duration, + + supported_protocols: SmallVec<[Vec; 16]>, }, /// An established connection was closed. @@ -261,10 +249,22 @@ where connected: Connected, /// The error that occurred, if any. If `None`, the connection /// was closed by the local peer. - error: Option::Error>>, + error: Option>, /// The remaining established connections to the same peer. remaining_established_connection_ids: Vec, - handler: THandler::Handler, + handler: THandler, + }, + + /// A [NetworkBehaviour] denied a just established connection by not producing a [`ConnectionHandler`] from [NetworkBehaviour::handle_established_outbound_connection] or [NetworkBehaviour::handle_established_inbound_connection]. + /// + /// [NetworkBehaviour]: crate::NetworkBehaviour + /// [NetworkBehaviour::handle_established_inbound_connection]: crate::NetworkBehaviour::handle_established_inbound_connection + /// [NetworkBehaviour::handle_established_outbound_connection]: crate::NetworkBehaviour::handle_established_outbound_connection + EstablishedConnectionDenied { + id: ConnectionId, + peer_id: PeerId, + endpoint: ConnectedPoint, + cause: Box, }, /// An outbound connection attempt failed. @@ -273,8 +273,6 @@ where id: ConnectionId, /// The error that occurred. error: PendingOutboundConnectionError, - /// The handler that was supposed to handle the connection. - handler: THandler, /// The (expected) peer of the failed connection. peer: Option, }, @@ -289,8 +287,6 @@ where local_addr: Multiaddr, /// The error that occurred. error: PendingInboundConnectionError, - /// The handler that was supposed to handle the connection. - handler: THandler, }, /// A node has produced an event. @@ -314,12 +310,13 @@ where impl Pool where - THandler: IntoConnectionHandler, + THandler: ConnectionHandler, TTrans: Transport, { /// Creates a new empty `Pool`. pub fn new(local_id: PeerId, config: PoolConfig, limits: ConnectionLimits) -> Self { - let (pending_connection_events_tx, pending_connection_events_rx) = mpsc::channel(0); + let (pending_connection_events_tx, pending_connection_events_rx) = + mpsc::channel(config.task_event_buffer_size); let (established_connection_events_tx, established_connection_events_rx) = mpsc::channel(config.task_event_buffer_size); let executor = match config.executor { @@ -331,7 +328,6 @@ where counters: ConnectionCounters::new(limits), established: Default::default(), pending: Default::default(), - next_connection_id: ConnectionId::new(0), task_command_buffer_size: config.task_command_buffer_size, dial_concurrency_factor: config.dial_concurrency_factor, substream_upgrade_protocol_override: config.substream_upgrade_protocol_override, @@ -417,13 +413,6 @@ where self.established.keys() } - fn next_connection_id(&mut self) -> ConnectionId { - let connection_id = self.next_connection_id; - self.next_connection_id = self.next_connection_id + 1; - - connection_id - } - fn spawn(&mut self, task: BoxFuture<'static, ()>) { self.executor.spawn(task) } @@ -431,7 +420,7 @@ where impl Pool where - THandler: IntoConnectionHandler, + THandler: ConnectionHandler, TTrans: Transport + 'static, TTrans::Output: Send + 'static, TTrans::Error: Send + 'static, @@ -456,25 +445,21 @@ where >, >, peer: Option, - handler: THandler, role_override: Endpoint, dial_concurrency_factor_override: Option, - ) -> Result + connection_id: ConnectionId + ) -> Result<(), ConnectionLimit> where TTrans: Send, TTrans::Dial: Send + 'static, { - if let Err(limit) = self.counters.check_max_pending_outgoing() { - return Err((limit, handler)); - }; + self.counters.check_max_pending_outgoing()?; let dial = ConcurrentDial::new( dials, dial_concurrency_factor_override.unwrap_or(self.dial_concurrency_factor), ); - let connection_id = self.next_connection_id(); - let (abort_notifier, abort_receiver) = oneshot::channel(); self.spawn( @@ -494,13 +479,12 @@ where connection_id, PendingConnection { peer_id: peer, - handler, endpoint, abort_notifier: Some(abort_notifier), - accepted_at: Instant::now(), }, ); - Ok(connection_id) + + Ok(()) } /// Adds a pending incoming connection to the pool in the form of a @@ -511,19 +495,15 @@ where pub fn add_incoming( &mut self, future: TFut, - handler: THandler, info: IncomingInfo<'_>, - ) -> Result + connection_id: ConnectionId + ) -> Result<(), ConnectionLimit> where TFut: Future> + Send + 'static, { let endpoint = info.create_connected_point(); - if let Err(limit) = self.counters.check_max_pending_incoming() { - return Err((limit, handler)); - } - - let connection_id = self.next_connection_id(); + self.counters.check_max_pending_incoming()?; let (abort_notifier, abort_receiver) = oneshot::channel(); @@ -542,22 +522,28 @@ where connection_id, PendingConnection { peer_id: None, - handler, endpoint: endpoint.into(), abort_notifier: Some(abort_notifier), - accepted_at: Instant::now(), }, ); - Ok(connection_id) + + Ok(()) } /// Polls the connection pool for events. - pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> + pub fn poll( + &mut self, + mut new_handler_fn: impl FnMut( + PeerId, + &ConnectedPoint, + ConnectionId + ) -> Result>, + cx: &mut Context<'_>, + ) -> Poll> where TTrans: Transport, - THandler: IntoConnectionHandler + 'static, - THandler::Handler: ConnectionHandler + Send, - ::OutboundOpenInfo: Send, + THandler: ConnectionHandler + 'static, + ::OutboundOpenInfo: Send, { // Poll for events of established connections. // @@ -637,10 +623,8 @@ where } => { let PendingConnection { peer_id: expected_peer_id, - handler, endpoint, abort_notifier: _, - accepted_at, } = self .pending .remove(&id) @@ -740,7 +724,6 @@ where id, error: error .map(|t| vec![(endpoint.get_remote_address().clone(), t)]), - handler, peer: expected_peer_id.or(Some(obtained_peer_id)), }) } @@ -751,7 +734,6 @@ where return Poll::Ready(PoolEvent::PendingInboundConnectionError { id, error, - handler, send_back_addr, local_addr, }) @@ -774,9 +756,27 @@ where }, ); + let handler = match new_handler_fn(obtained_peer_id, &endpoint, id) { + Ok(handler) => handler, + Err(cause) => { + return Poll::Ready(PoolEvent::EstablishedConnectionDenied { + id, + peer_id: obtained_peer_id, + endpoint, + cause, + }) + } + }; + let supported_protocols = handler + .listen_protocol() + .upgrade() + .protocol_info() + .map(|p| p.protocol_name().to_owned()) + .collect(); + let connection = Connection::new( muxer, - handler.into_handler(&obtained_peer_id, &endpoint), + handler, self.substream_upgrade_protocol_override, self.max_negotiating_inbound_streams, ); @@ -790,23 +790,21 @@ where ) .boxed(), ); - let established_in = accepted_at.elapsed(); + return Poll::Ready(PoolEvent::ConnectionEstablished { peer_id: obtained_peer_id, endpoint, id, other_established_connection_ids, concurrent_dial_errors, - established_in, + supported_protocols, }); } task::PendingConnectionEvent::PendingFailed { id, error } => { if let Some(PendingConnection { peer_id, - handler, endpoint, abort_notifier: _, - accepted_at: _, // Ignoring the time it took for the connection to fail. }) = self.pending.remove(&id) { self.counters.dec_pending(&endpoint); @@ -816,7 +814,6 @@ where return Poll::Ready(PoolEvent::PendingOutboundConnectionError { id, error, - handler, peer: peer_id, }); } @@ -830,7 +827,6 @@ where return Poll::Ready(PoolEvent::PendingInboundConnectionError { id, error, - handler, send_back_addr, local_addr, }); @@ -1111,6 +1107,12 @@ impl PoolConfig { } } + /// Configures the executor to use for spawning connection background tasks. + pub fn with_executor(mut self, executor: Box) -> Self { + self.executor = Some(executor); + self + } + /// Sets the maximum number of events sent to a connection's background task /// that may be buffered, if the task cannot keep up with their consumption and /// delivery to the connection handler. diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 4ec58581c2e..e05c2f0bf6a 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -2,7 +2,7 @@ use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, Poll use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; -use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol}; +use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandlerInEvent}; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::PeerId; @@ -29,7 +29,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { Poll::Pending } diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index bd1ed812b8b..2ff2d22eee8 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -8,6 +8,7 @@ use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::PeerId; use std::task::{Context, Poll}; use void::Void; +use crate::THandlerInEvent; /// Implementation of [`NetworkBehaviour`] that doesn't do anything other than keep all connections alive. /// @@ -34,7 +35,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { Poll::Pending } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index cf6051e1e85..401549d7424 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -85,9 +85,8 @@ pub mod derive_prelude { pub use crate::behaviour::NewListenAddr; pub use crate::behaviour::NewListener; pub use crate::ConnectionHandler; + pub use crate::ConnectionHandlerSelect; pub use crate::DialError; - pub use crate::IntoConnectionHandler; - pub use crate::IntoConnectionHandlerSelect; pub use crate::NetworkBehaviour; pub use crate::NetworkBehaviourAction; pub use crate::PollParameters; @@ -101,8 +100,7 @@ pub mod derive_prelude { } pub use behaviour::{ - CloseConnection, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, }; pub use connection::pool::{ConnectionCounters, ConnectionLimits}; pub use connection::{ @@ -112,13 +110,13 @@ pub use connection::{ pub use executor::Executor; pub use handler::{ ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr, - IntoConnectionHandler, IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, - OneShotHandlerConfig, SubstreamProtocol, + KeepAlive, OneShotHandler, OneShotHandlerConfig, SubstreamProtocol, }; #[cfg(feature = "macros")] pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; +use crate::handler::IntoConnectionHandler; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; use dial_opts::{DialOpts, PeerCondition}; @@ -132,7 +130,6 @@ use libp2p_core::{ multihash::Multihash, muxing::StreamMuxerBox, transport::{self, ListenerId, TransportError, TransportEvent}, - upgrade::ProtocolName, Endpoint, Multiaddr, Negotiated, PeerId, Transport, }; use registry::{AddressIntoIter, Addresses}; @@ -146,7 +143,6 @@ use std::{ pin::Pin, task::{Context, Poll}, }; -use upgrade::UpgradeInfoSend as _; /// Substream for which a protocol has been chosen. /// @@ -159,20 +155,17 @@ type TBehaviourOutEvent = ::OutEvent /// [`ConnectionHandler`] of the [`NetworkBehaviour`] for all the protocols the [`NetworkBehaviour`] /// supports. -type THandler = ::ConnectionHandler; +type THandler = <::ConnectionHandler as IntoConnectionHandler>::Handler; /// Custom event that can be received by the [`ConnectionHandler`] of the /// [`NetworkBehaviour`]. -type THandlerInEvent = - < as IntoConnectionHandler>::Handler as ConnectionHandler>::InEvent; +type THandlerInEvent = as ConnectionHandler>::InEvent; /// Custom event that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -type THandlerOutEvent = - < as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent; +type THandlerOutEvent = as ConnectionHandler>::OutEvent; /// Custom error that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -type THandlerErr = - < as IntoConnectionHandler>::Handler as ConnectionHandler>::Error; +type THandlerErr = as ConnectionHandler>::Error; /// Event generated by the `Swarm`. #[derive(Debug)] @@ -192,8 +185,6 @@ pub enum SwarmEvent { /// Addresses are dialed concurrently. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. concurrent_dial_errors: Option)>>, - /// How long it took to establish this connection - established_in: std::time::Duration, }, /// A connection with the given peer has been closed, /// possibly as a result of an error. @@ -208,6 +199,13 @@ pub enum SwarmEvent { /// active close. cause: Option>, }, + ConnectionDenied { + /// Identity of the peer that we have connected to. + peer_id: PeerId, + /// Endpoint of the connection that has been closed. + endpoint: ConnectedPoint, + cause: Box, + }, /// A new connection arrived on a listener and is in the process of protocol negotiation. /// /// A corresponding [`ConnectionEstablished`](SwarmEvent::ConnectionEstablished), @@ -345,6 +343,19 @@ impl Swarm where TBehaviour: NetworkBehaviour, { + /// Builds a new `Swarm`. + #[deprecated( + since = "0.41.0", + note = "This constructor is considered ambiguous regarding the executor. Use one of the new, executor-specific constructors or `Swarm::with_threadpool_executor` for the same behaviour." + )] + pub fn new( + transport: transport::Boxed<(PeerId, StreamMuxerBox)>, + behaviour: TBehaviour, + local_peer_id: PeerId, + ) -> Self { + Self::with_threadpool_executor(transport, behaviour, local_peer_id) + } + /// Builds a new `Swarm` with a provided executor. pub fn with_executor( transport: transport::Boxed<(PeerId, StreamMuxerBox)>, @@ -488,7 +499,7 @@ where /// # use libp2p_core::transport::dummy::DummyTransport; /// # use libp2p_swarm::dummy; /// # - /// let mut swarm = Swarm::without_executor( + /// let mut swarm = Swarm::new( /// DummyTransport::new().boxed(), /// dummy::Behaviour, /// PeerId::random(), @@ -501,14 +512,16 @@ where /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); /// ``` pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { - let handler = self.behaviour.new_handler(); - self.dial_with_handler(opts.into(), handler) + let swarm_dial_opts = opts.into(); + let id = ConnectionId::default(); + + self.dial_with_id(swarm_dial_opts, id) } - fn dial_with_handler( + fn dial_with_id( &mut self, swarm_dial_opts: DialOpts, - handler: ::ConnectionHandler, + connection_id: ConnectionId, ) -> Result<(), DialError> { let (peer_id, addresses, dial_concurrency_factor_override, role_override) = match swarm_dial_opts.0 { @@ -536,7 +549,6 @@ where #[allow(deprecated)] self.behaviour.inject_dial_failure( Some(peer_id), - handler, &DialError::DialPeerConditionFalse(condition), ); @@ -547,8 +559,7 @@ where if self.banned_peers.contains(&peer_id) { let error = DialError::Banned; #[allow(deprecated)] - self.behaviour - .inject_dial_failure(Some(peer_id), handler, &error); + self.behaviour.inject_dial_failure(Some(peer_id), &error); return Err(error); } @@ -585,8 +596,7 @@ where if addresses.is_empty() { let error = DialError::NoAddresses; #[allow(deprecated)] - self.behaviour - .inject_dial_failure(Some(peer_id), handler, &error); + self.behaviour.inject_dial_failure(Some(peer_id), &error); return Err(error); }; @@ -636,7 +646,20 @@ where } }; + let more_addresses = match self.behaviour.handle_pending_outbound_connection( + peer_id, + &[], // TODO: Fill in existing addresses here. + role_override, + connection_id, + ) { + Ok(more_addresses) => more_addresses, + Err(_) => { + todo!("return dial error") + } + }; + let dials = addresses + .chain(more_addresses) .map(|a| match p2p_addr(peer_id, a) { Ok(address) => { let dial = match role_override { @@ -661,15 +684,15 @@ where match self.pool.add_outgoing( dials, peer_id, - handler, role_override, dial_concurrency_factor_override, + connection_id, ) { Ok(_connection_id) => Ok(()), - Err((connection_limit, handler)) => { - let error = DialError::ConnectionLimit(connection_limit); + Err(connection_limit) => { + let error = DialError::ConnectionLimit(connection_limit); // TODO: Remove `ConnectionLimit`. #[allow(deprecated)] - self.behaviour.inject_dial_failure(peer_id, handler, &error); + self.behaviour.inject_dial_failure(peer_id, &error); Err(error) } } @@ -811,7 +834,7 @@ where endpoint, other_established_connection_ids, concurrent_dial_errors, - established_in, + supported_protocols, } => { if self.banned_peers.contains(&peer_id) { // Mark the connection for the banned peer as banned, thus withholding any @@ -847,25 +870,21 @@ where failed_addresses.as_ref(), non_banned_established, ); + self.supported_protocols = supported_protocols; + return Some(SwarmEvent::ConnectionEstablished { peer_id, num_established, endpoint, concurrent_dial_errors, - established_in, }); } } - PoolEvent::PendingOutboundConnectionError { - id: _, - error, - handler, - peer, - } => { + PoolEvent::PendingOutboundConnectionError { id: _, error, peer } => { let error = error.into(); #[allow(deprecated)] - self.behaviour.inject_dial_failure(peer, handler, &error); + self.behaviour.inject_dial_failure(peer, &error); if let Some(peer) = peer { log::debug!("Connection attempt to {:?} failed with {:?}.", peer, error,); @@ -883,12 +902,11 @@ where send_back_addr, local_addr, error, - handler, } => { log::debug!("Incoming connection failed: {:?}", error); #[allow(deprecated)] self.behaviour - .inject_listen_failure(&local_addr, &send_back_addr, handler); + .inject_listen_failure(&local_addr, &send_back_addr); return Some(SwarmEvent::IncomingConnectionError { local_addr, send_back_addr, @@ -943,6 +961,18 @@ where num_established, }); } + PoolEvent::EstablishedConnectionDenied { + peer_id, + endpoint, + cause, + .. + } => { + return Some(SwarmEvent::ConnectionDenied { + peer_id, + endpoint, + cause, + }) + } PoolEvent::ConnectionEvent { peer_id, id, event } => { if self.banned_peer_connections.contains(&id) { log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id); @@ -986,14 +1016,26 @@ where local_addr, send_back_addr, } => { - let handler = self.behaviour.new_handler(); + let connection_id = ConnectionId::default(); + + match self.behaviour.handle_pending_inbound_connection( + connection_id, + &local_addr, + &send_back_addr, + ) { + Ok(()) => {} + Err(_) => { + todo!("return error") + } + } + match self.pool.add_incoming( upgrade, - handler, IncomingInfo { local_addr: &local_addr, send_back_addr: &send_back_addr, }, + connection_id, ) { Ok(_connection_id) => { return Some(SwarmEvent::IncomingConnection { @@ -1001,10 +1043,10 @@ where send_back_addr, }); } - Err((connection_limit, handler)) => { + Err(connection_limit) => { #[allow(deprecated)] self.behaviour - .inject_listen_failure(&local_addr, &send_back_addr, handler); + .inject_listen_failure(&local_addr, &send_back_addr); log::warn!("Incoming connection rejected: {:?}", connection_limit); } }; @@ -1087,9 +1129,12 @@ where NetworkBehaviourAction::GenerateEvent(event) => { return Some(SwarmEvent::Behaviour(event)) } - NetworkBehaviourAction::Dial { opts, handler } => { + NetworkBehaviourAction::Dial { + opts, + id: connection_id, + } => { let peer_id = opts.get_peer_id(); - if let Ok(()) = self.dial_with_handler(opts, handler) { + if let Ok(()) = self.dial_with_id(opts, connection_id) { if let Some(peer_id) = peer_id { return Some(SwarmEvent::Dialing(peer_id)); } @@ -1235,7 +1280,29 @@ where } // Poll the known peers. - match this.pool.poll(cx) { + match this.pool.poll( + |peer, connected_point, connection_id| match connected_point { + ConnectedPoint::Dialer { + address, + role_override, + } => this.behaviour.handle_established_outbound_connection( + peer, + address, + *role_override, + connection_id, + ), + ConnectedPoint::Listener { + local_addr, + send_back_addr, + } => this.behaviour.handle_established_inbound_connection( + peer, + connection_id, + local_addr, + send_back_addr, + ), + }, + cx, + ) { Poll::Pending => {} Poll::Ready(pool_event) => { if let Some(swarm_event) = this.handle_pool_event(pool_event) { @@ -1318,8 +1385,7 @@ where TTrans: Transport, TTrans::Error: Send + 'static, TBehaviour: NetworkBehaviour, - THandler: IntoConnectionHandler, - THandler::Handler: ConnectionHandler< + THandler: ConnectionHandler< InEvent = THandlerInEvent, OutEvent = THandlerOutEvent, >, @@ -1424,6 +1490,35 @@ impl SwarmBuilder where TBehaviour: NetworkBehaviour, { + /// Creates a new `SwarmBuilder` from the given transport, behaviour and + /// local peer ID. The `Swarm` with its underlying `Network` is obtained + /// via [`SwarmBuilder::build`]. + #[deprecated( + since = "0.41.0", + note = "Use `SwarmBuilder::with_executor` or `SwarmBuilder::without_executor` instead." + )] + pub fn new( + transport: transport::Boxed<(PeerId, StreamMuxerBox)>, + behaviour: TBehaviour, + local_peer_id: PeerId, + ) -> Self { + let executor: Option> = match ThreadPoolBuilder::new() + .name_prefix("libp2p-swarm-task-") + .create() + .ok() + { + Some(tp) => Some(Box::new(tp)), + None => None, + }; + SwarmBuilder { + local_peer_id, + transport, + behaviour, + pool_config: PoolConfig::new(executor), + connection_limits: Default::default(), + } + } + /// Creates a new [`SwarmBuilder`] from the given transport, behaviour, local peer ID and /// executor. The `Swarm` with its underlying `Network` is obtained via /// [`SwarmBuilder::build`]. @@ -1501,6 +1596,17 @@ where } } + /// Configures the `Executor` to use for spawning background tasks. + /// + /// By default, unless another executor has been configured, + /// [`SwarmBuilder::build`] will try to set up a + /// [`ThreadPool`](futures::executor::ThreadPool). + #[deprecated(since = "0.41.0", note = "Use `SwarmBuilder::with_executor` instead.")] + pub fn executor(mut self, executor: Box) -> Self { + self.pool_config = self.pool_config.with_executor(executor); + self + } + /// Configures the number of events from the [`NetworkBehaviour`] in /// destination to the [`ConnectionHandler`] that can be buffered before /// the [`Swarm`] has to wait. An individual buffer with this number of @@ -1585,22 +1691,13 @@ where } /// Builds a `Swarm` with the current configuration. - pub fn build(mut self) -> Swarm { - let supported_protocols = self - .behaviour - .new_handler() - .inbound_protocol() - .protocol_info() - .into_iter() - .map(|info| info.protocol_name().to_vec()) - .collect(); - + pub fn build(self) -> Swarm { Swarm { local_peer_id: self.local_peer_id, transport: self.transport, pool: Pool::new(self.local_peer_id, self.pool_config, self.connection_limits), behaviour: self.behaviour, - supported_protocols, + supported_protocols: Default::default(), listened_addrs: HashMap::new(), external_addrs: Addresses::default(), banned_peers: HashSet::new(), @@ -1658,27 +1755,33 @@ impl From> for DialError { impl fmt::Display for DialError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - DialError::ConnectionLimit(err) => write!(f, "Dial error: {err}"), + DialError::ConnectionLimit(err) => write!(f, "Dial error: {}", err), DialError::NoAddresses => write!(f, "Dial error: no addresses for peer."), DialError::LocalPeerId => write!(f, "Dial error: tried to dial local peer id."), DialError::Banned => write!(f, "Dial error: peer is banned."), DialError::DialPeerConditionFalse(c) => { - write!(f, "Dial error: condition {c:?} for dialing peer was false.") + write!( + f, + "Dial error: condition {:?} for dialing peer was false.", + c + ) } DialError::Aborted => write!( f, "Dial error: Pending connection attempt has been aborted." ), DialError::InvalidPeerId(multihash) => { - write!(f, "Dial error: multihash {multihash:?} is not a PeerId") + write!(f, "Dial error: multihash {:?} is not a PeerId", multihash) } DialError::WrongPeerId { obtained, endpoint } => write!( f, - "Dial error: Unexpected peer ID {obtained} at {endpoint:?}." + "Dial error: Unexpected peer ID {} at {:?}.", + obtained, endpoint ), DialError::ConnectionIo(e) => write!( f, - "Dial error: An I/O error occurred on the connection: {e:?}." + "Dial error: An I/O error occurred on the connection: {:?}.", + e ), DialError::Transport(errors) => { write!(f, "Failed to negotiate transport protocol(s): [")?; @@ -1831,7 +1934,7 @@ mod tests { ) -> bool where TBehaviour: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: Clone, + ::OutEvent: Clone, { swarm1 .behaviour() @@ -1851,7 +1954,7 @@ mod tests { ) -> bool where TBehaviour: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: Clone + ::OutEvent: Clone, { swarm1 .behaviour() @@ -2257,7 +2360,7 @@ mod tests { panic!("Unexpected transport event.") } Either::Right((e, _)) => { - panic!("Expect swarm to not emit any event {e:?}") + panic!("Expect swarm to not emit any event {:?}", e) } } } @@ -2265,7 +2368,7 @@ mod tests { match swarm.next().await.unwrap() { SwarmEvent::OutgoingConnectionError { .. } => {} - e => panic!("Unexpected swarm event {e:?}"), + e => panic!("Unexpected swarm event {:?}", e), } }) } @@ -2305,7 +2408,7 @@ mod tests { assert_eq!(limit.current, outgoing_limit); assert_eq!(limit.limit, outgoing_limit); } - e => panic!("Unexpected error: {e:?}"), + e => panic!("Unexpected error: {:?}", e), } let info = network.network_info(); @@ -2345,7 +2448,7 @@ mod tests { let listen_addr = async_std::task::block_on(poll_fn(|cx| { match ready!(network1.poll_next_unpin(cx)).unwrap() { SwarmEvent::NewListenAddr { address, .. } => Poll::Ready(address), - e => panic!("Unexpected network event: {e:?}"), + e => panic!("Unexpected network event: {:?}", e), } })); @@ -2384,7 +2487,7 @@ mod tests { Poll::Pending => { network_1_pending = true; } - e => panic!("Unexpected network event: {e:?}"), + e => panic!("Unexpected network event: {:?}", e), } match network2.poll_next_unpin(cx) { @@ -2402,7 +2505,7 @@ mod tests { Poll::Pending => { network_2_pending = true; } - e => panic!("Unexpected network event: {e:?}"), + e => panic!("Unexpected network event: {:?}", e), } if network_1_pending && network_2_pending { @@ -2472,7 +2575,7 @@ mod tests { Poll::Ready(Some(SwarmEvent::OutgoingConnectionError { peer_id, error, .. })) => Poll::Ready((peer_id, error)), - Poll::Ready(x) => panic!("unexpected {x:?}"), + Poll::Ready(x) => panic!("unexpected {:?}", x), Poll::Pending => Poll::Pending, } })); @@ -2488,7 +2591,7 @@ mod tests { } ); } - x => panic!("wrong error {x:?}"), + x => panic!("wrong error {:?}", x), } } @@ -2549,7 +2652,7 @@ mod tests { assert_eq!(local_addr, local_address); } Poll::Ready(ev) => { - panic!("Unexpected event: {ev:?}") + panic!("Unexpected event: {:?}", ev) } Poll::Pending => break Poll::Pending, } @@ -2625,7 +2728,7 @@ mod tests { listener.listen_on(multiaddr![Memory(0u64)]).unwrap(); let listener_address = match block_on(listener.next()).unwrap() { SwarmEvent::NewListenAddr { address, .. } => address, - e => panic!("Unexpected network event: {e:?}"), + e => panic!("Unexpected network event: {:?}", e), }; dialer @@ -2645,7 +2748,7 @@ mod tests { error: DialError::Aborted, .. } => {} - e => panic!("Unexpected swarm event {e:?}."), + e => panic!("Unexpected swarm event {:?}.", e), } } diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 94a5fbfef54..88b1a226413 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -84,7 +84,7 @@ where &mut self, _: &mut Context, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { self.next_action.take().map_or(Poll::Pending, Poll::Ready) } @@ -470,7 +470,7 @@ where &mut self, cx: &mut Context, args: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { self.poll += 1; self.inner.poll(cx, args) } diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 84fb3bf4683..79ab2f62abd 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -403,7 +403,7 @@ fn custom_out_event_no_type_parameters() { &mut self, _ctx: &mut Context, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { Poll::Pending } From c494cd4368f871682c0f7108de43797fbb87d91a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Dec 2022 16:55:44 +1100 Subject: [PATCH 006/177] Fix up some more code --- protocols/autonat/src/behaviour.rs | 28 +--- protocols/autonat/src/behaviour/as_server.rs | 2 +- protocols/dcutr/src/behaviour.rs | 137 ++++++++++--------- protocols/floodsub/src/layer.rs | 15 +- protocols/gossipsub/src/behaviour.rs | 16 +-- protocols/identify/src/behaviour.rs | 7 +- protocols/kad/src/behaviour.rs | 17 +-- protocols/mdns/src/behaviour.rs | 4 +- protocols/ping/src/lib.rs | 2 +- protocols/relay/src/v2/client.rs | 31 +++-- protocols/relay/src/v2/relay.rs | 2 +- protocols/rendezvous/src/client.rs | 19 +-- protocols/rendezvous/src/server.rs | 7 +- protocols/request-response/src/lib.rs | 14 +- swarm/src/behaviour.rs | 41 +++--- swarm/src/behaviour/either.rs | 24 ++-- swarm/src/behaviour/toggle.rs | 6 +- swarm/src/connection/pool.rs | 13 +- swarm/src/connection/pool/task.rs | 5 +- swarm/src/dummy.rs | 4 +- swarm/src/handler.rs | 1 + swarm/src/keep_alive.rs | 2 +- swarm/src/lib.rs | 20 +-- 23 files changed, 194 insertions(+), 223 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 17ee817b4a6..ff0125f011d 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -40,7 +40,7 @@ use libp2p_swarm::{ ExpiredListenAddr, FromSwarm, }, ConnectionHandler, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, PollParameters, + NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use std::{ collections::{HashMap, VecDeque}, @@ -210,10 +210,7 @@ pub struct Behaviour { last_probe: Option, pending_actions: VecDeque< - NetworkBehaviourAction< - ::OutEvent, - ::ConnectionHandler, - >, + NetworkBehaviourAction<::OutEvent, THandlerInEvent>, >, probe_id: ProbeId, @@ -387,20 +384,9 @@ impl Behaviour { } } - fn on_dial_failure( - &mut self, - DialFailure { - peer_id, - handler, - error, - }: DialFailure<::ConnectionHandler>, - ) { + fn on_dial_failure(&mut self, DialFailure { peer_id, error, id }: DialFailure) { self.inner - .on_swarm_event(FromSwarm::DialFailure(DialFailure { - peer_id, - handler, - error, - })); + .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, error, id })); if let Some(event) = self.as_server().on_outbound_dial_error(peer_id, error) { self.pending_actions .push_back(NetworkBehaviourAction::GenerateEvent(Event::InboundProbe( @@ -563,10 +549,8 @@ impl NetworkBehaviour for Behaviour { } } -type Action = NetworkBehaviourAction< - ::OutEvent, - ::ConnectionHandler, ->; +type Action = + NetworkBehaviourAction<::OutEvent, THandlerInEvent>; // Trait implemented for `AsClient` and `AsServer` to handle events from the inner [`request_response::Behaviour`] Protocol. trait HandleInnerEvent { diff --git a/protocols/autonat/src/behaviour/as_server.rs b/protocols/autonat/src/behaviour/as_server.rs index 8d08f7ed8d0..3aa62c67eb6 100644 --- a/protocols/autonat/src/behaviour/as_server.rs +++ b/protocols/autonat/src/behaviour/as_server.rs @@ -138,7 +138,7 @@ impl<'a> HandleInnerEvent for AsServer<'a> { ) .addresses(addrs) .build(), - handler: self.inner.new_handler(), + id: Default::default(), }, ]) } diff --git a/protocols/dcutr/src/behaviour.rs b/protocols/dcutr/src/behaviour.rs index 8654aaca0fe..12e87b3c852 100644 --- a/protocols/dcutr/src/behaviour.rs +++ b/protocols/dcutr/src/behaviour.rs @@ -30,7 +30,7 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailu use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ ConnectionHandler, ConnectionHandlerUpgrErr, ExternalAddresses, IntoConnectionHandler, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; @@ -134,42 +134,41 @@ impl Behaviour { } } - fn on_dial_failure( - &mut self, - DialFailure { - peer_id, handler, .. - }: DialFailure<::ConnectionHandler>, - ) { - if let handler::Prototype::DirectConnection { - relayed_connection_id, - role: handler::Role::Initiator { attempt }, - } = handler - { - let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); - if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - self.queued_actions.push_back(ActionBuilder::Connect { - peer_id, - handler: NotifyHandler::One(relayed_connection_id), - attempt: attempt + 1, - }); - } else { - self.queued_actions.extend([ - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left( - handler::relayed::Command::UpgradeFinishedDontKeepAlive, - ), - } - .into(), - NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { - remote_peer_id: peer_id, - error: UpgradeError::Dial, - }) - .into(), - ]); - } - } + fn on_dial_failure(&mut self, DialFailure { peer_id, id, .. }: DialFailure) { + // TODO: To properly count connection attempts, we need count number of unique connection IDs we get here. + // That is not pretty in case we ever get a collision. How do we prevent a collision? + // We could also reuse that connection ID and count the number of attempts through that. + + // if let handler::Prototype::DirectConnection { + // relayed_connection_id, + // role: handler::Role::Initiator { attempt }, + // } = handler + // { + // let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); + // if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { + // self.queued_actions.push_back(ActionBuilder::Connect { + // peer_id, + // handler: NotifyHandler::One(relayed_connection_id), + // attempt: attempt + 1, + // }); + // } else { + // self.queued_actions.extend([ + // NetworkBehaviourAction::NotifyHandler { + // peer_id, + // handler: NotifyHandler::One(relayed_connection_id), + // event: Either::Left( + // handler::relayed::Command::UpgradeFinishedDontKeepAlive, + // ), + // } + // .into(), + // NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { + // remote_peer_id: peer_id, + // error: UpgradeError::Dial, + // }) + // .into(), + // ]); + // } + // } } fn on_connection_closed( @@ -242,19 +241,20 @@ impl NetworkBehaviour for Behaviour { ); } Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => { - self.queued_actions.push_back( - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(event_source) - .addresses(remote_addrs) - .condition(dial_opts::PeerCondition::Always) - .build(), - handler: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Listener, - }, - } - .into(), - ); + // self.queued_actions.push_back( + // NetworkBehaviourAction::Dial { + // opts: DialOpts::peer_id(event_source) + // .addresses(remote_addrs) + // .condition(dial_opts::PeerCondition::Always) + // .build(), + // handler: handler::Prototype::DirectConnection { + // relayed_connection_id: connection, + // role: handler::Role::Listener, + // }, + // } + // .into(), + // ); + todo!() } Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { self.queued_actions.push_back( @@ -269,20 +269,21 @@ impl NetworkBehaviour for Behaviour { remote_addrs, attempt, }) => { - self.queued_actions.push_back( - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(event_source) - .condition(dial_opts::PeerCondition::Always) - .addresses(remote_addrs) - .override_role() - .build(), - handler: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Initiator { attempt }, - }, - } - .into(), - ); + // self.queued_actions.push_back( + // NetworkBehaviourAction::Dial { + // opts: DialOpts::peer_id(event_source) + // .condition(dial_opts::PeerCondition::Always) + // .addresses(remote_addrs) + // .override_role() + // .build(), + // handler: handler::Prototype::DirectConnection { + // relayed_connection_id: connection, + // role: handler::Role::Initiator { attempt }, + // }, + // } + // .into(), + // ); + todo!() } Either::Right(Either::Left( handler::direct::Event::DirectConnectionUpgradeSucceeded { @@ -349,7 +350,7 @@ impl NetworkBehaviour for Behaviour { /// A [`NetworkBehaviourAction`], either complete, or still requiring data from [`PollParameters`] /// before being returned in [`Behaviour::poll`]. enum ActionBuilder { - Done(NetworkBehaviourAction), + Done(NetworkBehaviourAction>), Connect { attempt: u8, handler: NotifyHandler, @@ -362,8 +363,8 @@ enum ActionBuilder { }, } -impl From> for ActionBuilder { - fn from(action: NetworkBehaviourAction) -> Self { +impl From>> for ActionBuilder { + fn from(action: NetworkBehaviourAction>) -> Self { Self::Done(action) } } @@ -373,7 +374,7 @@ impl ActionBuilder { self, local_peer_id: PeerId, external_addresses: &ExternalAddresses, - ) -> NetworkBehaviourAction { + ) -> NetworkBehaviourAction> { let obs_addrs = || { external_addresses .iter() diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 47d32283aab..0c17ecddb83 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -30,7 +30,7 @@ use libp2p_core::{connection::ConnectionId, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, - PollParameters, + PollParameters, THandlerInEvent, }; use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler}; use log::warn; @@ -42,12 +42,7 @@ use std::{collections::VecDeque, iter}; /// Network behaviour that handles the floodsub protocol. pub struct Floodsub { /// Events that need to be yielded to the outside when polling. - events: VecDeque< - NetworkBehaviourAction< - FloodsubEvent, - OneShotHandler, - >, - >, + events: VecDeque>>, config: FloodsubConfig, @@ -108,10 +103,9 @@ impl Floodsub { } if self.target_peers.insert(peer_id) { - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + id: Default::default(), }); } } @@ -331,10 +325,9 @@ impl Floodsub { // We can be disconnected by the remote in case of inactivity for example, so we always // try to reconnect. if self.target_peers.contains(&peer_id) { - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + id: Default::default(), }); } } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 6260798eb0c..e6b0fa86002 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -44,7 +44,7 @@ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, dial_opts::DialOpts, ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use wasm_timer::Instant; @@ -201,8 +201,7 @@ impl From for PublishConfig { } } -type GossipsubNetworkBehaviourAction = - NetworkBehaviourAction>; +type GossipsubNetworkBehaviourAction = NetworkBehaviourAction; /// Network behaviour that handles the gossipsub protocol. /// @@ -1640,10 +1639,9 @@ where self.px_peers.insert(peer_id); // dial peer - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + id: Default::default(), }); } } @@ -3449,10 +3447,10 @@ where _: &mut impl PollParameters, ) -> Poll>> { if let Some(event) = self.events.pop_front() { - return Poll::Ready(event.map_in(|e: Arc| { - // clone send event reference if others references are present - Arc::try_unwrap(e).unwrap_or_else(|e| (*e).clone()) - })); + // return Poll::Ready(event.map_in(|e: Arc| { + // // clone send event reference if others references are present + // Arc::try_unwrap(e).unwrap_or_else(|e| (*e).clone()) + // })); } // update scores diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index f935cbe8a75..29b766293ef 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -27,7 +27,7 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailu use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, + NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, }; use lru::LruCache; use std::num::NonZeroUsize; @@ -54,7 +54,7 @@ pub struct Behaviour { /// with current information about the local peer. requests: Vec, /// Pending events to be emitted when polled. - events: VecDeque>, + events: VecDeque>>, /// The addresses of all peers that we have discovered. discovered_peers: PeerCache, @@ -199,10 +199,9 @@ impl Behaviour { if !self.requests.contains(&request) { self.requests.push(request); - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(p).build(), - handler, + id: Default::default(), }); } } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 96de726a8f3..7d73c1350e6 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -46,7 +46,7 @@ use libp2p_swarm::behaviour::{ use libp2p_swarm::{ dial_opts::{self, DialOpts}, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use log::{debug, info, warn}; use smallvec::SmallVec; @@ -101,7 +101,7 @@ pub struct Kademlia { connection_idle_timeout: Duration, /// Queued events to return when the behaviour is being polled. - queued_events: VecDeque>>, + queued_events: VecDeque>>, listen_addresses: ListenAddresses, @@ -572,10 +572,9 @@ where RoutingUpdate::Failed } kbucket::InsertResult::Pending { disconnected } => { - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()).build(), - handler, + id: Default::default(), }); RoutingUpdate::Pending } @@ -1222,11 +1221,10 @@ where // // Only try dialing peer if not currently connected. if !self.connected_peers.contains(disconnected.preimage()) { - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()) .build(), - handler, + id: Default::default(), }) } } @@ -1918,12 +1916,7 @@ where } } - fn on_dial_failure( - &mut self, - DialFailure { peer_id, error, .. }: DialFailure< - ::ConnectionHandler, - >, - ) { + fn on_dial_failure(&mut self, DialFailure { peer_id, error, .. }: DialFailure) { let peer_id = match peer_id { Some(id) => id, // Not interested in dial failures to unknown peers. diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 815a23c9bdc..19bc518d320 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -31,7 +31,7 @@ use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ dummy, ConnectionHandler, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, + PollParameters, THandlerInEvent, }; use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; @@ -231,7 +231,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { // Poll ifwatch. while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) { match event { diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index ff1a99fd1a5..23dccc769dc 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -49,7 +49,7 @@ use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, PeerId}; use libp2p_swarm::{ - behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use std::{ collections::VecDeque, diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 0b8de8f4af2..31e0392cabf 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -38,7 +38,7 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{hash_map, HashMap, VecDeque}; use std::io::{Error, ErrorKind, IoSlice}; @@ -269,16 +269,18 @@ impl NetworkBehaviour for Client { event: Either::Left(handler::In::Reserve { to_listener }), }, None => { - let handler = handler::Prototype::new( - self.local_peer_id, - Some(handler::In::Reserve { to_listener }), - ); + // let handler = handler::Prototype::new( + // self.local_peer_id, + // Some(handler::In::Reserve { to_listener }), + // ); + // TODO NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(relay_peer_id) .addresses(vec![relay_addr]) .extend_addresses_through_behaviour() .build(), - handler, + + id: Default::default(), } } } @@ -304,19 +306,20 @@ impl NetworkBehaviour for Client { }), }, None => { - let handler = handler::Prototype::new( - self.local_peer_id, - Some(handler::In::EstablishCircuit { - send_back, - dst_peer_id, - }), - ); + // let handler = handler::Prototype::new( + // self.local_peer_id, + // Some(handler::In::EstablishCircuit { + // send_back, + // dst_peer_id, + // }), + // ); + // TODO NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(relay_peer_id) .addresses(vec![relay_addr]) .extend_addresses_through_behaviour() .build(), - handler, + id: Default::default(), } } } diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 46879061c83..9cbc47fbe62 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -33,7 +33,7 @@ use libp2p_core::PeerId; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{hash_map, HashMap, HashSet, VecDeque}; use std::num::NonZeroU32; diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index a82800b9281..9f49b578ef3 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -22,7 +22,7 @@ use crate::codec::{Cookie, ErrorCode, Namespace, NewRegistration, Registration, use crate::handler; use crate::handler::outbound; use crate::handler::outbound::OpenInfo; -use crate::substream_handler::SubstreamConnectionHandler; +use crate::substream_handler::{InEvent, SubstreamConnectionHandler}; use futures::future::BoxFuture; use futures::future::FutureExt; use futures::stream::FuturesUnordered; @@ -35,19 +35,15 @@ use libp2p_core::{Multiaddr, PeerId, PeerRecord}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, + PollParameters, THandlerInEvent, }; use std::collections::{HashMap, VecDeque}; use std::iter::FromIterator; use std::task::{Context, Poll}; +use void::Void; pub struct Behaviour { - events: VecDeque< - NetworkBehaviourAction< - Event, - SubstreamConnectionHandler, - >, - >, + events: VecDeque>>, keypair: Keypair, pending_register_requests: Vec<(Namespace, PeerId, Option)>, @@ -294,12 +290,7 @@ fn handle_outbound_event( peer_id: PeerId, discovered_peers: &mut HashMap<(PeerId, Namespace), Vec>, expiring_registrations: &mut FuturesUnordered>, -) -> Vec< - NetworkBehaviourAction< - Event, - SubstreamConnectionHandler, - >, -> { +) -> Vec>> { match event { outbound::OutEvent::Registered { namespace, ttl } => { vec![NetworkBehaviourAction::GenerateEvent(Event::Registered { diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 2ecc118494d..5563435b8bc 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -32,6 +32,7 @@ use libp2p_core::PeerId; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandlerInEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::iter::FromIterator; @@ -40,9 +41,7 @@ use std::time::Duration; use void::Void; pub struct Behaviour { - events: VecDeque< - NetworkBehaviourAction>, - >, + events: VecDeque>>, registrations: Registrations, } @@ -186,7 +185,7 @@ fn handle_inbound_event( connection: ConnectionId, id: InboundSubstreamId, registrations: &mut Registrations, -) -> Vec>> { +) -> Vec>> { match event { // bad registration inbound::OutEvent::RegistrationRequested(registration) diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index a8972253ce0..ea24c7548fb 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -75,6 +75,7 @@ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandlerInEvent, }; use smallvec::SmallVec; use std::{ @@ -348,8 +349,9 @@ where /// The protocol codec for reading and writing requests and responses. codec: TCodec, /// Pending events to return from `poll`. - pending_events: - VecDeque, Handler>>, + pending_events: VecDeque< + NetworkBehaviourAction, THandlerInEvent>, + >, /// The currently connected peers, their pending outbound and inbound responses and their known, /// reachable addresses, if any. connected: HashMap>, @@ -416,10 +418,9 @@ where }; if let Some(request) = self.try_send_request(peer, request) { - let handler = self.new_handler(); self.pending_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer).build(), - handler, + id: Default::default(), }); self.pending_outbound_requests .entry(*peer) @@ -695,10 +696,7 @@ where } } - fn on_dial_failure( - &mut self, - DialFailure { peer_id, .. }: DialFailure<::ConnectionHandler>, - ) { + fn on_dial_failure(&mut self, DialFailure { peer_id, .. }: DialFailure) { 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 diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index e4eac61be2a..0991d4d8a91 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -19,11 +19,16 @@ // DEALINGS IN THE SOFTWARE. mod either; +mod external_addresses; +mod listen_addresses; pub mod toggle; +pub use external_addresses::ExternalAddresses; +pub use listen_addresses::ListenAddresses; + use crate::dial_opts::DialOpts; use crate::handler::{ConnectionHandler, IntoConnectionHandler}; -use crate::{AddressRecord, AddressScore, DialError}; +use crate::{AddressRecord, AddressScore, DialError, THandlerInEvent}; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId, }; @@ -345,7 +350,11 @@ pub trait NetworkBehaviour: Sized + 'static { 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, error: &DialError) { - self.on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, error })); + self.on_swarm_event(FromSwarm::DialFailure(DialFailure { + peer_id, + error, + id: todo!("remove deprecated APIs first"), + })); } /// Indicates to the behaviour that an error happened on an incoming connection during its @@ -361,6 +370,7 @@ pub trait NetworkBehaviour: Sized + 'static { self.on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, + id: todo!("remove deprecated APIs first"), })); } @@ -572,9 +582,7 @@ impl NetworkBehaviourAction { ) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, id } => { - NetworkBehaviourAction::Dial { opts, id } - } + NetworkBehaviourAction::Dial { opts, id } => NetworkBehaviourAction::Dial { opts, id }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -598,14 +606,12 @@ impl NetworkBehaviourAction { } } -impl NetworkBehaviourAction { +impl NetworkBehaviourAction { /// Map the event the swarm will return. - pub fn map_out(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction { + pub fn map_out(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), - NetworkBehaviourAction::Dial { opts, id } => { - NetworkBehaviourAction::Dial { opts, id } - } + NetworkBehaviourAction::Dial { opts, id } => NetworkBehaviourAction::Dial { opts, id }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -733,6 +739,7 @@ pub struct AddressChange<'a> { pub struct DialFailure<'a> { pub peer_id: Option, pub error: &'a DialError, + pub id: ConnectionId, } /// [`FromSwarm`] variant that informs the behaviour that an error @@ -744,6 +751,7 @@ pub struct DialFailure<'a> { pub struct ListenFailure<'a> { pub local_addr: &'a Multiaddr, pub send_back_addr: &'a Multiaddr, + pub id: ConnectionId, } /// [`FromSwarm`] variant that informs the behaviour that a new listener was created. @@ -799,7 +807,6 @@ pub struct ExpiredExternalAddr<'a> { impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { fn map_handler( self, - map_into_handler: impl FnOnce(Handler) -> NewHandler, map_handler: impl FnOnce( ::Handler, ) -> ::Handler, @@ -807,13 +814,12 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { where NewHandler: IntoConnectionHandler, { - self.maybe_map_handler(|h| Some(map_into_handler(h)), |h| Some(map_handler(h))) + self.maybe_map_handler(|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>, @@ -859,15 +865,17 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { old, new, })), - FromSwarm::DialFailure(DialFailure { peer_id, error }) => { - Some(FromSwarm::DialFailure(DialFailure { peer_id, error })) + FromSwarm::DialFailure(DialFailure { peer_id, error, id }) => { + Some(FromSwarm::DialFailure(DialFailure { peer_id, error, id })) } FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, + id, }) => Some(FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, + id, })), FromSwarm::NewListener(NewListener { listener_id }) => { Some(FromSwarm::NewListener(NewListener { listener_id })) @@ -953,13 +961,14 @@ pub(crate) fn inject_from_swarm( #[allow(deprecated)] behaviour.inject_address_change(&peer_id, &connection_id, old, new); } - FromSwarm::DialFailure(DialFailure { peer_id, error }) => { + FromSwarm::DialFailure(DialFailure { peer_id, error, id }) => { #[allow(deprecated)] behaviour.inject_dial_failure(peer_id, error); } FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, + id, }) => { #[allow(deprecated)] behaviour.inject_listen_failure(local_addr, send_back_addr); diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index e72a7ea01ac..13fcb6f7e05 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -22,10 +22,10 @@ use crate::behaviour::{ self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; use crate::handler::either::IntoEitherHandler; +use crate::THandlerInEvent; use either::Either; use libp2p_core::{Multiaddr, PeerId}; use std::{task::Context, task::Poll}; -use crate::THandlerInEvent; /// Implementation of [`NetworkBehaviour`] that can be either of two implementations. impl NetworkBehaviour for Either @@ -54,23 +54,17 @@ where match self { Either::Left(b) => inject_from_swarm( b, - event.map_handler( - |h| h.unwrap_left(), - |h| match h { - Either::Left(h) => h, - Either::Right(_) => unreachable!(), - }, - ), + event.map_handler(|h| match h { + Either::Left(h) => h, + Either::Right(_) => unreachable!(), + }), ), Either::Right(b) => inject_from_swarm( b, - event.map_handler( - |h| h.unwrap_right(), - |h| match h { - Either::Right(h) => h, - Either::Left(_) => unreachable!(), - }, - ), + event.map_handler(|h| match h { + Either::Right(h) => h, + Either::Left(_) => unreachable!(), + }), ), } } diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 962a933a972..f67e37bf599 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -86,7 +86,7 @@ where 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) { + if let Some(event) = event.maybe_map_handler(|h| h.inner) { inject_from_swarm(behaviour, event); } } @@ -110,9 +110,7 @@ where params: &mut impl PollParameters, ) -> Poll>> { if let Some(inner) = self.inner.as_mut() { - inner.poll(cx, params).map(|action| { - action.map_handler(|h| ToggleIntoConnectionHandler { inner: Some(h) }) - }) + inner.poll(cx, params) } else { Poll::Pending } diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 3f3818d340f..ae0bf94014f 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -211,9 +211,10 @@ impl fmt::Debug for Pool +pub enum PoolEvent where TTrans: Transport, + THandler: ConnectionHandler, { /// A new connection has been established. ConnectionEstablished { @@ -294,7 +295,7 @@ where id: ConnectionId, peer_id: PeerId, /// The produced event. - event: THandlerOutEvent, + event: THandler::OutEvent, }, /// The connection to a node has changed its address. @@ -349,7 +350,7 @@ where pub fn get_established( &mut self, id: ConnectionId, - ) -> Option<&mut EstablishedConnection>> { + ) -> Option<&mut EstablishedConnection> { self.established .values_mut() .find_map(|connections| connections.get_mut(&id)) @@ -447,7 +448,7 @@ where peer: Option, role_override: Endpoint, dial_concurrency_factor_override: Option, - connection_id: ConnectionId + connection_id: ConnectionId, ) -> Result<(), ConnectionLimit> where TTrans: Send, @@ -496,7 +497,7 @@ where &mut self, future: TFut, info: IncomingInfo<'_>, - connection_id: ConnectionId + connection_id: ConnectionId, ) -> Result<(), ConnectionLimit> where TFut: Future> + Send + 'static, @@ -536,7 +537,7 @@ where mut new_handler_fn: impl FnMut( PeerId, &ConnectedPoint, - ConnectionId + ConnectionId, ) -> Result>, cx: &mut Context<'_>, ) -> Poll> diff --git a/swarm/src/connection/pool/task.rs b/swarm/src/connection/pool/task.rs index 8e1129d8cae..99b6947903d 100644 --- a/swarm/src/connection/pool/task.rs +++ b/swarm/src/connection/pool/task.rs @@ -72,7 +72,10 @@ where } #[derive(Debug)] -pub enum EstablishedConnectionEvent { +pub enum EstablishedConnectionEvent +where + THandler: ConnectionHandler, +{ /// A node we are connected to has changed its address. AddressChange { id: ConnectionId, diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index e05c2f0bf6a..2a9ec75bccb 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -2,7 +2,9 @@ use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, Poll use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; -use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandlerInEvent}; +use crate::{ + ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandlerInEvent, +}; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::PeerId; diff --git a/swarm/src/handler.rs b/swarm/src/handler.rs index 2a4e1d44483..e1a5571815c 100644 --- a/swarm/src/handler.rs +++ b/swarm/src/handler.rs @@ -583,6 +583,7 @@ where } /// Prototype for a [`ConnectionHandler`]. +#[deprecated(note = "Override one of the `handle_` callbacks on `NetworkBehaviour` instead.")] pub trait IntoConnectionHandler: Send + 'static { /// The protocols handler. type Handler: ConnectionHandler; diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index 2ff2d22eee8..7e2c822fb31 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -3,12 +3,12 @@ use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, SubstreamProtocol, }; +use crate::THandlerInEvent; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::PeerId; use std::task::{Context, Poll}; use void::Void; -use crate::THandlerInEvent; /// Implementation of [`NetworkBehaviour`] that doesn't do anything other than keep all connections alive. /// diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 401549d7424..0bfc9442490 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -100,7 +100,8 @@ pub mod derive_prelude { } pub use behaviour::{ - CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + CloseConnection, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, + NotifyHandler, PollParameters, }; pub use connection::pool::{ConnectionCounters, ConnectionLimits}; pub use connection::{ @@ -110,13 +111,13 @@ pub use connection::{ pub use executor::Executor; pub use handler::{ ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr, - KeepAlive, OneShotHandler, OneShotHandlerConfig, SubstreamProtocol, + IntoConnectionHandler, IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, + OneShotHandlerConfig, SubstreamProtocol, }; #[cfg(feature = "macros")] pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; -use crate::handler::IntoConnectionHandler; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; use dial_opts::{DialOpts, PeerCondition}; @@ -155,17 +156,18 @@ type TBehaviourOutEvent = ::OutEvent /// [`ConnectionHandler`] of the [`NetworkBehaviour`] for all the protocols the [`NetworkBehaviour`] /// supports. -type THandler = <::ConnectionHandler as IntoConnectionHandler>::Handler; +pub type THandler = + <::ConnectionHandler as IntoConnectionHandler>::Handler; /// Custom event that can be received by the [`ConnectionHandler`] of the /// [`NetworkBehaviour`]. -type THandlerInEvent = as ConnectionHandler>::InEvent; +pub type THandlerInEvent = as ConnectionHandler>::InEvent; /// Custom event that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -type THandlerOutEvent = as ConnectionHandler>::OutEvent; +pub type THandlerOutEvent = as ConnectionHandler>::OutEvent; /// Custom error that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -type THandlerErr = as ConnectionHandler>::Error; +pub type THandlerErr = as ConnectionHandler>::Error; /// Event generated by the `Swarm`. #[derive(Debug)] @@ -185,6 +187,8 @@ pub enum SwarmEvent { /// Addresses are dialed concurrently. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. concurrent_dial_errors: Option)>>, + /// How long it took to establish this connection + established_in: std::time::Duration, }, /// A connection with the given peer has been closed, /// possibly as a result of an error. @@ -1123,7 +1127,7 @@ where fn handle_behaviour_event( &mut self, - event: NetworkBehaviourAction, + event: NetworkBehaviourAction>, ) -> Option>> { match event { NetworkBehaviourAction::GenerateEvent(event) => { From 2c23ac29c93e640cd596533bfb3d2a1ba30b590b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Dec 2022 16:57:09 +1100 Subject: [PATCH 007/177] Complete deprecation notice --- swarm/src/behaviour.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 0991d4d8a91..c33028470e5 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -139,7 +139,9 @@ pub trait NetworkBehaviour: Sized + 'static { // /// // /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and // /// connection closing. - #[deprecated(note = "Override the ")] + #[deprecated( + note = "Use one or more of `NetworkBehaviour::{handle_pending_inbound_connection,handle_established_inbound_connection,handle_pending_outbound_connection,handle_established_outbound_connection}` instead." + )] fn new_handler(&mut self) -> Self::ConnectionHandler; /// Callback that is invoked for every new inbound connection. From b65bbbcb67d138b79de5969411e9d50b8c4e131b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Dec 2022 16:59:14 +1100 Subject: [PATCH 008/177] Fix some more errors --- protocols/gossipsub/src/behaviour.rs | 3 +-- protocols/relay/src/v2/relay.rs | 8 ++++---- swarm/src/lib.rs | 1 + 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index e6b0fa86002..7868b38af11 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -1140,10 +1140,9 @@ where if !self.peer_topics.contains_key(peer_id) { // Connect to peer debug!("Connecting to explicit peer {:?}", peer_id); - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer_id).build(), - handler, + id: Default::default(), }); } } diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 9cbc47fbe62..9f7d751ea4b 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -748,7 +748,7 @@ impl Add for CircuitId { /// before being returned in [`Relay::poll`]. #[allow(clippy::large_enum_variant)] enum Action { - Done(NetworkBehaviourAction), + Done(NetworkBehaviourAction>), AcceptReservationPrototype { inbound_reservation_req: inbound_hop::ReservationReq, handler: NotifyHandler, @@ -756,8 +756,8 @@ enum Action { }, } -impl From> for Action { - fn from(action: NetworkBehaviourAction) -> Self { +impl From>> for Action { + fn from(action: NetworkBehaviourAction>) -> Self { Self::Done(action) } } @@ -767,7 +767,7 @@ impl Action { self, local_peer_id: PeerId, external_addresses: &ExternalAddresses, - ) -> NetworkBehaviourAction { + ) -> NetworkBehaviourAction> { match self { Action::Done(action) => action, Action::AcceptReservationPrototype { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 0bfc9442490..6aea5fd67e3 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -881,6 +881,7 @@ where num_established, endpoint, concurrent_dial_errors, + established_in: todo!(), }); } } From acfc50e80bf9911454b27b13818d697c147c53ae Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Dec 2022 17:01:07 +1100 Subject: [PATCH 009/177] Refine deprecation message --- swarm/src/handler.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swarm/src/handler.rs b/swarm/src/handler.rs index e1a5571815c..5ce819f58b4 100644 --- a/swarm/src/handler.rs +++ b/swarm/src/handler.rs @@ -583,7 +583,9 @@ where } /// Prototype for a [`ConnectionHandler`]. -#[deprecated(note = "Override one of the `handle_` callbacks on `NetworkBehaviour` instead.")] +#[deprecated( + note = "Implement `ConnectionHandler` directly and use `NetworkBehaviour::{handle_pending_inbound_connection,handle_pending_outbound_connection}` to handle pending connections." +)] pub trait IntoConnectionHandler: Send + 'static { /// The protocols handler. type Handler: ConnectionHandler; From ca0498533fb98d6960c1c82946bb7283c3a2a1b9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Dec 2022 17:07:21 +1100 Subject: [PATCH 010/177] Delegate to `addresses_of_peer` by default --- swarm/src/behaviour.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index c33028470e5..f1b1b6d1c49 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -198,12 +198,16 @@ pub trait NetworkBehaviour: Sized + 'static { /// Any error returned from this function will immediately abort the dial attempt. fn handle_pending_outbound_connection( &mut self, - _maybe_peer: Option, + maybe_peer: Option, _addresses: &[&Multiaddr], _effective_role: Endpoint, _connection_id: ConnectionId, ) -> Result, Box> { - Ok(vec![]) + if let Some(peer_id) = maybe_peer { + Ok(self.addresses_of_peer(&peer_id)) + } else { + vec![] + } } /// Callback that is invoked for every established outbound connection. From 6a734543eae8409e22591188758052791140038d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 19 Dec 2022 17:58:06 +1100 Subject: [PATCH 011/177] Add hack to clear listen addresses --- swarm/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ed0a89dea35..5b09bd2cc38 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -2447,6 +2447,8 @@ mod tests { _ => panic!("Was expecting the listen address to be reported"), })); + swarm.listened_addrs.clear(); // This is a hack to actually execute the dial to ourselves which would otherwise be filtered. + swarm.dial(local_address.clone()).unwrap(); let mut got_dial_err = false; From e6e33c57f15ce45912323d31514068405bf7dea7 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 20 Dec 2022 13:45:46 +1100 Subject: [PATCH 012/177] Add changelog entry --- protocols/kad/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protocols/kad/CHANGELOG.md b/protocols/kad/CHANGELOG.md index 2edc45aeea6..31912fc738d 100644 --- a/protocols/kad/CHANGELOG.md +++ b/protocols/kad/CHANGELOG.md @@ -2,8 +2,12 @@ - Update to `libp2p-swarm` `v0.42.0`. +- Remove lifetime from `RecordStore` and use GATs instead. See [PR 3239]. + - Bump MSRV to 1.65.0. +[PR 3239]: https://github.com/libp2p/rust-libp2p/pull/3239 + # 0.42.0 - Update to `libp2p-core` `v0.38.0`. From 9a5ce29239cb94933341f2d33bed98247de13af2 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 13:25:59 +1100 Subject: [PATCH 013/177] Use an atomic counter to avoid collisions on connection IDs --- core/src/connection.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/connection.rs b/core/src/connection.rs index 7e4e524ce93..717076f9c96 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -19,10 +19,13 @@ // DEALINGS IN THE SOFTWARE. use crate::multiaddr::{Multiaddr, Protocol}; +use std::sync::atomic::{AtomicU64, Ordering}; + +static NEXT_CONNECTION_ID: AtomicU64 = AtomicU64::new(0); /// Connection identifier. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct ConnectionId(usize); +pub struct ConnectionId(u64); impl ConnectionId { /// Creates a `ConnectionId` from a non-negative integer. @@ -32,13 +35,13 @@ impl ConnectionId { /// that all connection IDs are based on non-negative integers. #[deprecated(note = "IDs must be unique and should not be constructed directly.")] pub fn new(id: usize) -> Self { - Self(id) + Self(id as u64) } } impl Default for ConnectionId { fn default() -> Self { - Self(rand::random()) + Self(NEXT_CONNECTION_ID.fetch_add(1, Ordering::SeqCst)) } } From 1662273ba3e85f5d1f11f9e20dd0162487b53927 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 13:29:45 +1100 Subject: [PATCH 014/177] Fix minor compile error --- swarm/src/behaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index f1b1b6d1c49..62c9250de30 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -206,7 +206,7 @@ pub trait NetworkBehaviour: Sized + 'static { if let Some(peer_id) = maybe_peer { Ok(self.addresses_of_peer(&peer_id)) } else { - vec![] + Ok(vec![]) } } From 5c944e68f1338b44cf5c8a8eae14454960d6a68b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:06:08 +1100 Subject: [PATCH 015/177] Fill in a few more bits --- swarm/src/connection/pool.rs | 12 +++++++ swarm/src/lib.rs | 62 +++++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index ae0bf94014f..518abd76653 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -256,6 +256,18 @@ where handler: THandler, }, + /// A [NetworkBehaviour] denied a pending connection through either [NetworkBehaviour::handle_pending_inbound_connection] or [NetworkBehaviour::handle_pending_outbound_connection]. + /// + /// [NetworkBehaviour]: crate::NetworkBehaviour + /// [NetworkBehaviour::handle_pending_inbound_connection]: crate::NetworkBehaviour::handle_pending_inbound_connection + /// [NetworkBehaviour::handle_pending_outbound_connection]: crate::NetworkBehaviour::handle_pending_outbound_connection + PendingConnectionDenied { + id: ConnectionId, + peer_id: Option, + endpoint: PendingPoint, + cause: Box, + }, + /// A [NetworkBehaviour] denied a just established connection by not producing a [`ConnectionHandler`] from [NetworkBehaviour::handle_established_outbound_connection] or [NetworkBehaviour::handle_established_inbound_connection]. /// /// [NetworkBehaviour]: crate::NetworkBehaviour diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 6aea5fd67e3..0a758c2d6a6 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -118,12 +118,14 @@ pub use handler::{ pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; +use crate::behaviour::FromSwarm; +use crate::derive_prelude::DialFailure; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; use dial_opts::{DialOpts, PeerCondition}; use either::Either; use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream}; -use libp2p_core::connection::ConnectionId; +use libp2p_core::connection::{ConnectionId, PendingPoint}; use libp2p_core::muxing::SubstreamBox; use libp2p_core::{ connection::ConnectedPoint, @@ -190,6 +192,19 @@ pub enum SwarmEvent { /// How long it took to establish this connection established_in: std::time::Duration, }, + PendingConnectionDenied { + peer_id: Option, + endpoint: PendingPoint, + cause: Box, + }, + EstablishedConnectionDenied { + /// Identity of the peer that we have connected to. + peer_id: PeerId, + /// Endpoint of the connection that has been closed. + endpoint: ConnectedPoint, + cause: Box, + }, + /// A connection with the given peer has been closed, /// possibly as a result of an error. ConnectionClosed { @@ -203,13 +218,6 @@ pub enum SwarmEvent { /// active close. cause: Option>, }, - ConnectionDenied { - /// Identity of the peer that we have connected to. - peer_id: PeerId, - /// Endpoint of the connection that has been closed. - endpoint: ConnectedPoint, - cause: Box, - }, /// A new connection arrived on a listener and is in the process of protocol negotiation. /// /// A corresponding [`ConnectionEstablished`](SwarmEvent::ConnectionEstablished), @@ -515,11 +523,13 @@ where /// // Dial an unknown peer. /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); /// ``` - pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { + pub fn dial(&mut self, opts: impl Into) -> Result { let swarm_dial_opts = opts.into(); let id = ConnectionId::default(); - self.dial_with_id(swarm_dial_opts, id) + self.dial_with_id(swarm_dial_opts, id)?; + + Ok(id) } fn dial_with_id( @@ -657,8 +667,17 @@ where connection_id, ) { Ok(more_addresses) => more_addresses, - Err(_) => { - todo!("return dial error") + Err(cause) => { + let error = DialError::Denied { cause }; + + self.behaviour + .on_swarm_event(FromSwarm::DialFailure(DialFailure { + peer_id, + id: connection_id, + error: &error, + })); + + return Err(error); } }; @@ -972,7 +991,7 @@ where cause, .. } => { - return Some(SwarmEvent::ConnectionDenied { + return Some(SwarmEvent::EstablishedConnectionDenied { peer_id, endpoint, cause, @@ -1029,8 +1048,17 @@ where &send_back_addr, ) { Ok(()) => {} - Err(_) => { - todo!("return error") + Err(error) => { + // TODO: self.behaviour.on_swarm_event(FromSwarm::ListenFailure()) + + return Some(SwarmEvent::PendingConnectionDenied { + peer_id: None, + endpoint: PendingPoint::Listener { + local_addr, + send_back_addr, + }, + cause: error, + }); } } @@ -1737,6 +1765,10 @@ pub enum DialError { obtained: PeerId, endpoint: ConnectedPoint, }, + // TODO: Should this include the role_override? + Denied { + cause: Box, + }, /// An I/O error occurred on the connection. ConnectionIo(io::Error), /// An error occurred while negotiating the transport protocol(s) on a connection. From 59bcc9f1a152487d47f2823ef5a4af4013b727f3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:13:17 +1100 Subject: [PATCH 016/177] Don't be generic over transport --- swarm/src/connection/pool.rs | 46 ++++++++++--------------------- swarm/src/connection/pool/task.rs | 35 ++++++++++------------- swarm/src/lib.rs | 12 ++++---- 3 files changed, 35 insertions(+), 58 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 7a81c57e2df..482c27493c8 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -26,7 +26,7 @@ use crate::{ Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError, }, - transport::{Transport, TransportError}, + transport::TransportError, ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, PeerId, }; use concurrent_dial::ConcurrentDial; @@ -79,9 +79,8 @@ impl ExecSwitch { } /// A connection `Pool` manages a set of connections for each peer. -pub struct Pool +pub struct Pool where - TTrans: Transport, THandler: IntoConnectionHandler, { local_id: PeerId, @@ -124,10 +123,10 @@ where /// Sender distributed to pending tasks for reporting events back /// to the pool. - pending_connection_events_tx: mpsc::Sender>, + pending_connection_events_tx: mpsc::Sender, /// Receiver for events reported from pending tasks. - pending_connection_events_rx: mpsc::Receiver>, + pending_connection_events_rx: mpsc::Receiver, /// Sender distributed to established tasks for reporting events back /// to the pool. @@ -213,7 +212,7 @@ impl PendingConnection { } } -impl fmt::Debug for Pool { +impl fmt::Debug for Pool { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.debug_struct("Pool") .field("counters", &self.counters) @@ -223,10 +222,7 @@ impl fmt::Debug for Pool -where - TTrans: Transport, -{ +pub enum PoolEvent { /// A new connection has been established. ConnectionEstablished { id: ConnectionId, @@ -239,7 +235,7 @@ where /// [`Some`] when the new connection is an outgoing connection. /// Addresses are dialed in parallel. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. - concurrent_dial_errors: Option)>>, + concurrent_dial_errors: Option)>>, /// How long it took to establish this connection. established_in: std::time::Duration, }, @@ -272,7 +268,7 @@ where /// The ID of the failed connection. id: ConnectionId, /// The error that occurred. - error: PendingOutboundConnectionError, + error: PendingOutboundConnectionError, /// The handler that was supposed to handle the connection. handler: THandler, /// The (expected) peer of the failed connection. @@ -288,7 +284,7 @@ where /// Local connection address. local_addr: Multiaddr, /// The error that occurred. - error: PendingInboundConnectionError, + error: PendingInboundConnectionError, /// The handler that was supposed to handle the connection. handler: THandler, }, @@ -312,10 +308,9 @@ where }, } -impl Pool +impl Pool where THandler: IntoConnectionHandler, - TTrans: Transport, { /// Creates a new empty `Pool`. pub fn new(local_id: PeerId, config: PoolConfig, limits: ConnectionLimits) -> Self { @@ -429,12 +424,9 @@ where } } -impl Pool +impl Pool where THandler: IntoConnectionHandler, - TTrans: Transport + 'static, - TTrans::Output: Send + 'static, - TTrans::Error: Send + 'static, { /// Adds a pending outgoing connection to the pool in the form of a `Future` /// that establishes and negotiates the connection. @@ -448,10 +440,7 @@ where 'static, ( Multiaddr, - Result< - ::Output, - TransportError<::Error>, - >, + Result<(PeerId, StreamMuxerBox), TransportError>, ), >, >, @@ -459,11 +448,7 @@ where handler: THandler, role_override: Endpoint, dial_concurrency_factor_override: Option, - ) -> Result - where - TTrans: Send, - TTrans::Dial: Send + 'static, - { + ) -> Result { if let Err(limit) = self.counters.check_max_pending_outgoing() { return Err((limit, handler)); }; @@ -515,7 +500,7 @@ where info: IncomingInfo<'_>, ) -> Result where - TFut: Future> + Send + 'static, + TFut: Future> + Send + 'static, { let endpoint = info.create_connected_point(); @@ -552,9 +537,8 @@ where } /// Polls the connection pool for events. - pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> + pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> where - TTrans: Transport, THandler: IntoConnectionHandler + 'static, THandler::Handler: ConnectionHandler + Send, ::OutboundOpenInfo: Send, diff --git a/swarm/src/connection/pool/task.rs b/swarm/src/connection/pool/task.rs index 8e1129d8cae..f6e98beb092 100644 --- a/swarm/src/connection/pool/task.rs +++ b/swarm/src/connection/pool/task.rs @@ -26,7 +26,7 @@ use crate::{ connection::{ self, ConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError, }, - transport::{Transport, TransportError}, + transport::{TransportError}, ConnectionHandler, Multiaddr, PeerId, }; use futures::{ @@ -35,6 +35,8 @@ use futures::{ SinkExt, StreamExt, }; use libp2p_core::connection::ConnectionId; +use libp2p_core::muxing::StreamMuxerBox; +use libp2p_core::transport::Boxed; use std::pin::Pin; use void::Void; @@ -48,25 +50,21 @@ pub enum Command { Close, } -#[derive(Debug)] -pub enum PendingConnectionEvent -where - TTrans: Transport, -{ +pub enum PendingConnectionEvent { ConnectionEstablished { id: ConnectionId, - output: TTrans::Output, + output: (PeerId, StreamMuxerBox), /// [`Some`] when the new connection is an outgoing connection. /// Addresses are dialed in parallel. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. - outgoing: Option<(Multiaddr, Vec<(Multiaddr, TransportError)>)>, + outgoing: Option<(Multiaddr, Vec<(Multiaddr, TransportError)>)>, }, /// A pending connection failed. PendingFailed { id: ConnectionId, error: Either< - PendingOutboundConnectionError, - PendingInboundConnectionError, + PendingOutboundConnectionError, + PendingInboundConnectionError, >, }, } @@ -97,14 +95,12 @@ pub enum EstablishedConnectionEvent { }, } -pub async fn new_for_pending_outgoing_connection( +pub async fn new_for_pending_outgoing_connection( connection_id: ConnectionId, - dial: ConcurrentDial, + dial: ConcurrentDial>, abort_receiver: oneshot::Receiver, - mut events: mpsc::Sender>, -) where - TTrans: Transport, -{ + mut events: mpsc::Sender, +) { match futures::future::select(abort_receiver, Box::pin(dial)).await { Either::Left((Err(oneshot::Canceled), _)) => { let _ = events @@ -135,14 +131,13 @@ pub async fn new_for_pending_outgoing_connection( } } -pub async fn new_for_pending_incoming_connection( +pub async fn new_for_pending_incoming_connection( connection_id: ConnectionId, future: TFut, abort_receiver: oneshot::Receiver, - mut events: mpsc::Sender>, + mut events: mpsc::Sender, ) where - TTrans: Transport, - TFut: Future> + Send + 'static, + TFut: Future> + Send + 'static, { match futures::future::select(abort_receiver, Box::pin(future)).await { Either::Left((Err(oneshot::Canceled), _)) => { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index cf6051e1e85..ac7bf603e93 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -305,7 +305,7 @@ where transport: transport::Boxed<(PeerId, StreamMuxerBox)>, /// The nodes currently active. - pool: Pool, transport::Boxed<(PeerId, StreamMuxerBox)>>, + pool: Pool>, /// The local peer ID. local_peer_id: PeerId, @@ -802,7 +802,7 @@ where fn handle_pool_event( &mut self, - event: PoolEvent, transport::Boxed<(PeerId, StreamMuxerBox)>>, + event: PoolEvent>, ) -> Option>> { match event { PoolEvent::ConnectionEstablished { @@ -1199,7 +1199,7 @@ where } } PendingNotifyHandler::Any(ids) => { - match notify_any::<_, _, TBehaviour>(ids, &mut this.pool, event, cx) { + match notify_any::<_, TBehaviour>(ids, &mut this.pool, event, cx) { None => continue, Some((event, ids)) => { let handler = PendingNotifyHandler::Any(ids); @@ -1308,15 +1308,13 @@ fn notify_one( /// /// Returns `None` if either all connections are closing or the event /// was successfully sent to a handler, in either case the event is consumed. -fn notify_any( +fn notify_any( ids: SmallVec<[ConnectionId; 10]>, - pool: &mut Pool, + pool: &mut Pool, event: THandlerInEvent, cx: &mut Context<'_>, ) -> Option<(THandlerInEvent, SmallVec<[ConnectionId; 10]>)> where - TTrans: Transport, - TTrans::Error: Send + 'static, TBehaviour: NetworkBehaviour, THandler: IntoConnectionHandler, THandler::Handler: ConnectionHandler< From a1c55b20e85eb68141c3130760ab4bd54f8dbe49 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:28:37 +1100 Subject: [PATCH 017/177] Remove type parameter for transport error --- misc/metrics/src/swarm.rs | 6 ++---- swarm/CHANGELOG.md | 4 ++++ swarm/src/connection/error.rs | 7 +++---- swarm/src/connection/pool.rs | 6 +++--- swarm/src/connection/pool/task.rs | 7 ++----- swarm/src/lib.rs | 6 +++--- 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index a003ab56570..b171f48b6e3 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -370,10 +370,8 @@ enum PendingInboundConnectionError { ConnectionLimit, } -impl From<&libp2p_swarm::PendingInboundConnectionError> - for PendingInboundConnectionError -{ - fn from(error: &libp2p_swarm::PendingInboundConnectionError) -> Self { +impl From<&libp2p_swarm::PendingInboundConnectionError> for PendingInboundConnectionError { + fn from(error: &libp2p_swarm::PendingInboundConnectionError) -> Self { match error { libp2p_swarm::PendingInboundConnectionError::WrongPeerId { .. } => { PendingInboundConnectionError::WrongPeerId diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index da77ae72209..e17d2c77660 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -7,9 +7,13 @@ - Add `estblished_in` to `SwarmEvent::ConnectionEstablished`. See [PR 3134]. +- Remove type parameter from `PendingOutboundConnectionError` and `PendingInboundConnectionError`. + These two types are always used with `std::io::Error`. See [PR XXXX. + [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 [PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153 +[PR XXXX]: https://github.com/libp2p/rust-libp2p/pull/XXXX # 0.41.1 diff --git a/swarm/src/connection/error.rs b/swarm/src/connection/error.rs index 541d458df0c..9226035968c 100644 --- a/swarm/src/connection/error.rs +++ b/swarm/src/connection/error.rs @@ -76,12 +76,11 @@ impl From for ConnectionError { /// Note: Addresses for an outbound connection are dialed in parallel. Thus, compared to /// [`PendingInboundConnectionError`], one or more [`TransportError`]s can occur for a single /// connection. -pub type PendingOutboundConnectionError = - PendingConnectionError)>>; +pub type PendingOutboundConnectionError = + PendingConnectionError)>>; /// Errors that can occur in the context of a pending incoming `Connection`. -pub type PendingInboundConnectionError = - PendingConnectionError>; +pub type PendingInboundConnectionError = PendingConnectionError>; /// Errors that can occur in the context of a pending `Connection`. #[derive(Debug)] diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 482c27493c8..3d4bde9614b 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -268,7 +268,7 @@ pub enum PoolEvent { /// The ID of the failed connection. id: ConnectionId, /// The error that occurred. - error: PendingOutboundConnectionError, + error: PendingOutboundConnectionError, /// The handler that was supposed to handle the connection. handler: THandler, /// The (expected) peer of the failed connection. @@ -284,7 +284,7 @@ pub enum PoolEvent { /// Local connection address. local_addr: Multiaddr, /// The error that occurred. - error: PendingInboundConnectionError, + error: PendingInboundConnectionError, /// The handler that was supposed to handle the connection. handler: THandler, }, @@ -661,7 +661,7 @@ where ), }; - let error: Result<(), PendingInboundConnectionError<_>> = self + let error: Result<(), PendingInboundConnectionError> = self .counters // Check general established connection limit. .check_max_established(&endpoint) diff --git a/swarm/src/connection/pool/task.rs b/swarm/src/connection/pool/task.rs index f6e98beb092..a0f4ba9235e 100644 --- a/swarm/src/connection/pool/task.rs +++ b/swarm/src/connection/pool/task.rs @@ -26,7 +26,7 @@ use crate::{ connection::{ self, ConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError, }, - transport::{TransportError}, + transport::TransportError, ConnectionHandler, Multiaddr, PeerId, }; use futures::{ @@ -62,10 +62,7 @@ pub enum PendingConnectionEvent { /// A pending connection failed. PendingFailed { id: ConnectionId, - error: Either< - PendingOutboundConnectionError, - PendingInboundConnectionError, - >, + error: Either, }, } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ac7bf603e93..bd0c517c248 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -234,7 +234,7 @@ pub enum SwarmEvent { /// Address used to send back data to the remote. send_back_addr: Multiaddr, /// The error that happened. - error: PendingInboundConnectionError, + error: PendingInboundConnectionError, }, /// Outgoing connection attempt failed. OutgoingConnectionError { @@ -1639,8 +1639,8 @@ pub enum DialError { Transport(Vec<(Multiaddr, TransportError)>), } -impl From> for DialError { - fn from(error: PendingOutboundConnectionError) -> Self { +impl From for DialError { + fn from(error: PendingOutboundConnectionError) -> Self { match error { PendingConnectionError::ConnectionLimit(limit) => DialError::ConnectionLimit(limit), PendingConnectionError::Aborted => DialError::Aborted, From 7132ff54ede2c268d5477741899e695e0d74b06b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:30:15 +1100 Subject: [PATCH 018/177] Remove unnecessary type hint --- swarm/src/connection/pool.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 3d4bde9614b..30dff859d51 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -661,7 +661,7 @@ where ), }; - let error: Result<(), PendingInboundConnectionError> = self + let error = self .counters // Check general established connection limit. .check_max_established(&endpoint) From 01efa8f8d734ee17164c3282b8e1b6388d7630e6 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:35:44 +1100 Subject: [PATCH 019/177] Remove type parameters from `ConcurrentDial` --- swarm/src/connection/pool/concurrent_dial.rs | 39 ++++++++------------ swarm/src/connection/pool/task.rs | 3 +- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/swarm/src/connection/pool/concurrent_dial.rs b/swarm/src/connection/pool/concurrent_dial.rs index 5ba71f54fd0..ede8b4e68e0 100644 --- a/swarm/src/connection/pool/concurrent_dial.rs +++ b/swarm/src/connection/pool/concurrent_dial.rs @@ -19,7 +19,7 @@ // DEALINGS IN THE SOFTWARE. use crate::{ - transport::{Transport, TransportError}, + transport::{TransportError}, Multiaddr, }; use futures::{ @@ -27,36 +27,32 @@ use futures::{ ready, stream::{FuturesUnordered, StreamExt}, }; +use libp2p_core::muxing::StreamMuxerBox; +use libp2p_core::PeerId; use std::{ num::NonZeroU8, pin::Pin, task::{Context, Poll}, }; -type Dial = BoxFuture< +type Dial = BoxFuture< 'static, ( Multiaddr, - Result<::Output, TransportError<::Error>>, + Result<(PeerId, StreamMuxerBox), TransportError>, ), >; -pub struct ConcurrentDial { - dials: FuturesUnordered>, - pending_dials: Box> + Send>, - errors: Vec<(Multiaddr, TransportError)>, +pub struct ConcurrentDial { + dials: FuturesUnordered, + pending_dials: Box + Send>, + errors: Vec<(Multiaddr, TransportError)>, } -impl Unpin for ConcurrentDial {} +impl Unpin for ConcurrentDial {} -impl ConcurrentDial -where - TTrans: Transport + Send + 'static, - TTrans::Output: Send, - TTrans::Error: Send, - TTrans::Dial: Send + 'static, -{ - pub(crate) fn new(pending_dials: Vec>, concurrency_factor: NonZeroU8) -> Self { +impl ConcurrentDial { + pub(crate) fn new(pending_dials: Vec, concurrency_factor: NonZeroU8) -> Self { let mut pending_dials = pending_dials.into_iter(); let dials = FuturesUnordered::new(); @@ -75,20 +71,17 @@ where } } -impl Future for ConcurrentDial -where - TTrans: Transport, -{ +impl Future for ConcurrentDial { type Output = Result< // Either one dial succeeded, returning the negotiated [`PeerId`], the address, the // muxer and the addresses and errors of the dials that failed before. ( Multiaddr, - TTrans::Output, - Vec<(Multiaddr, TransportError)>, + (PeerId, StreamMuxerBox), + Vec<(Multiaddr, TransportError)>, ), // Or all dials failed, thus returning the address and error for each dial. - Vec<(Multiaddr, TransportError)>, + Vec<(Multiaddr, TransportError)>, >; fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { diff --git a/swarm/src/connection/pool/task.rs b/swarm/src/connection/pool/task.rs index a0f4ba9235e..326e381d76f 100644 --- a/swarm/src/connection/pool/task.rs +++ b/swarm/src/connection/pool/task.rs @@ -36,7 +36,6 @@ use futures::{ }; use libp2p_core::connection::ConnectionId; use libp2p_core::muxing::StreamMuxerBox; -use libp2p_core::transport::Boxed; use std::pin::Pin; use void::Void; @@ -94,7 +93,7 @@ pub enum EstablishedConnectionEvent { pub async fn new_for_pending_outgoing_connection( connection_id: ConnectionId, - dial: ConcurrentDial>, + dial: ConcurrentDial, abort_receiver: oneshot::Receiver, mut events: mpsc::Sender, ) { From b0f2678b93d30a838096832bfaa8e4af440dffa5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:44:27 +1100 Subject: [PATCH 020/177] Fix rustfmt --- swarm/src/connection/pool/concurrent_dial.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/swarm/src/connection/pool/concurrent_dial.rs b/swarm/src/connection/pool/concurrent_dial.rs index ede8b4e68e0..7bd9e7f1f66 100644 --- a/swarm/src/connection/pool/concurrent_dial.rs +++ b/swarm/src/connection/pool/concurrent_dial.rs @@ -18,10 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::{ - transport::{TransportError}, - Multiaddr, -}; +use crate::{transport::TransportError, Multiaddr}; use futures::{ future::{BoxFuture, Future}, ready, From d3a259e0298b8c35f553b3f412d16a9e43f72950 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:54:47 +1100 Subject: [PATCH 021/177] Remove `PendingConnectionDenied` This is handled by `DialError` and `ListenFailure`. --- swarm/src/connection/pool.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 4ac9af13c8c..ec8c7f7ff81 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -256,18 +256,6 @@ where handler: THandler, }, - /// A [NetworkBehaviour] denied a pending connection through either [NetworkBehaviour::handle_pending_inbound_connection] or [NetworkBehaviour::handle_pending_outbound_connection]. - /// - /// [NetworkBehaviour]: crate::NetworkBehaviour - /// [NetworkBehaviour::handle_pending_inbound_connection]: crate::NetworkBehaviour::handle_pending_inbound_connection - /// [NetworkBehaviour::handle_pending_outbound_connection]: crate::NetworkBehaviour::handle_pending_outbound_connection - PendingConnectionDenied { - id: ConnectionId, - peer_id: Option, - endpoint: PendingPoint, - cause: Box, - }, - /// A [NetworkBehaviour] denied a just established connection by not producing a [`ConnectionHandler`] from [NetworkBehaviour::handle_established_outbound_connection] or [NetworkBehaviour::handle_established_inbound_connection]. /// /// [NetworkBehaviour]: crate::NetworkBehaviour From e89ec574b20c4f3771796e15756fea87d687dc0a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:56:07 +1100 Subject: [PATCH 022/177] Handle new DialError variants --- swarm/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 2d8963f32ac..fb565d1c03b 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1755,6 +1755,9 @@ impl fmt::Display for DialError { Ok(()) } + DialError::Denied { .. } => { + write!(f, "Dial was denied") + } } } } @@ -1782,6 +1785,7 @@ impl error::Error for DialError { DialError::WrongPeerId { .. } => None, DialError::ConnectionIo(_) => None, DialError::Transport(_) => None, + DialError::Denied { cause } => Some(cause.as_ref()), } } } From b0ee1406c17d24e04d127e82380fdf82e6622030 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 14:57:31 +1100 Subject: [PATCH 023/177] Make `libp2p-kad` compile --- protocols/kad/src/behaviour.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 25ddf775221..9021d6d6f80 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -62,7 +62,10 @@ pub use crate::query::QueryStats; /// `Kademlia` is a `NetworkBehaviour` that implements the libp2p /// Kademlia protocol. -pub struct Kademlia { +pub struct Kademlia +where + TStore: RecordStore + Send + 'static, +{ /// The Kademlia routing table. kbuckets: KBucketsTable, Addresses>, From 20d93bbb45126876de6f12aef10a71a6738a8178 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 15:03:49 +1100 Subject: [PATCH 024/177] Fix a few more errors --- protocols/gossipsub/src/behaviour.rs | 6 +++--- protocols/gossipsub/src/subscription_filter.rs | 4 ++-- protocols/gossipsub/src/transform.rs | 2 +- swarm-derive/src/lib.rs | 3 ++- swarm/src/lib.rs | 3 +++ 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index a3f4bd94e6d..d746cba2fc0 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -219,7 +219,7 @@ pub struct Gossipsub< config: GossipsubConfig, /// Events that need to be yielded to the outside when polling. - events: VecDeque>, + events: VecDeque>>, /// Pools non-urgent control messages between heartbeats. control_pool: HashMap>, @@ -3490,7 +3490,7 @@ fn peer_added_to_mesh( new_topics: Vec<&TopicHash>, mesh: &HashMap>, known_topics: Option<&BTreeSet>, - events: &mut VecDeque>, + events: &mut VecDeque>>, connections: &HashMap, ) { // Ensure there is an active connection @@ -3531,7 +3531,7 @@ fn peer_removed_from_mesh( old_topic: &TopicHash, mesh: &HashMap>, known_topics: Option<&BTreeSet>, - events: &mut VecDeque>, + events: &mut VecDeque>>, connections: &HashMap, ) { // Ensure there is an active connection diff --git a/protocols/gossipsub/src/subscription_filter.rs b/protocols/gossipsub/src/subscription_filter.rs index ec6cb6756ba..63e1b6a598e 100644 --- a/protocols/gossipsub/src/subscription_filter.rs +++ b/protocols/gossipsub/src/subscription_filter.rs @@ -23,7 +23,7 @@ use crate::TopicHash; use log::debug; use std::collections::{BTreeSet, HashMap, HashSet}; -pub trait TopicSubscriptionFilter { +pub trait TopicSubscriptionFilter: Send + 'static { /// Returns true iff the topic is of interest and we can subscribe to it. fn can_subscribe(&mut self, topic_hash: &TopicHash) -> bool; @@ -193,7 +193,7 @@ where impl TopicSubscriptionFilter for CallbackSubscriptionFilter where - T: FnMut(&TopicHash) -> bool, + T: FnMut(&TopicHash) -> bool + Send + 'static, { fn can_subscribe(&mut self, topic_hash: &TopicHash) -> bool { (self.0)(topic_hash) diff --git a/protocols/gossipsub/src/transform.rs b/protocols/gossipsub/src/transform.rs index ed11c78e5e0..fc4a44d62c9 100644 --- a/protocols/gossipsub/src/transform.rs +++ b/protocols/gossipsub/src/transform.rs @@ -35,7 +35,7 @@ use crate::{GossipsubMessage, RawGossipsubMessage, TopicHash}; /// outbound transform MUST leave the underlying data un-modified. /// /// By default, this is the identity transform for all fields in [`GossipsubMessage`]. -pub trait DataTransform { +pub trait DataTransform: Send + 'static { /// Takes a [`RawGossipsubMessage`] received and converts it to a [`GossipsubMessage`]. fn inbound_transform( &self, diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index b142ea77c67..142ced11d6b 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -74,6 +74,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let expired_external_addr = quote! { #prelude_path::ExpiredExternalAddr }; let listener_error = quote! { #prelude_path::ListenerError }; let listener_closed = quote! { #prelude_path::ListenerClosed }; + let t_handler_in_event = quote! { #prelude_path::THandlerInEvent }; // Build the generics. let impl_generics = { @@ -642,7 +643,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } } - fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action> { + fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action>> { use #prelude_path::futures::*; #(#poll_stmts)* std::task::Poll::Pending diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index fb565d1c03b..57262c21419 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -87,9 +87,12 @@ pub mod derive_prelude { pub use crate::ConnectionHandler; pub use crate::ConnectionHandlerSelect; pub use crate::DialError; + pub use crate::IntoConnectionHandler; + pub use crate::IntoConnectionHandlerSelect; pub use crate::NetworkBehaviour; pub use crate::NetworkBehaviourAction; pub use crate::PollParameters; + pub use crate::THandlerInEvent; pub use futures::prelude as futures; pub use libp2p_core::connection::ConnectionId; pub use libp2p_core::either::EitherOutput; From 138feb262774f267509d293c2ac7638eeb76f9f3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 21 Dec 2022 15:18:44 +1100 Subject: [PATCH 025/177] No more compile errors! --- examples/file-sharing.rs | 2 +- misc/metrics/src/swarm.rs | 3 + protocols/gossipsub/src/behaviour/tests.rs | 10 ++-- protocols/kad/src/behaviour.rs | 4 +- protocols/rendezvous/examples/discover.rs | 2 +- swarm-derive/src/lib.rs | 69 +++------------------- swarm/src/behaviour.rs | 26 ++++---- swarm/src/lib.rs | 64 ++++++++------------ swarm/src/test.rs | 20 +++---- swarm/tests/swarm_derive.rs | 2 +- 10 files changed, 71 insertions(+), 131 deletions(-) diff --git a/examples/file-sharing.rs b/examples/file-sharing.rs index b38f456972b..38844702fd3 100644 --- a/examples/file-sharing.rs +++ b/examples/file-sharing.rs @@ -547,7 +547,7 @@ mod network { .swarm .dial(peer_addr.with(Protocol::P2p(peer_id.into()))) { - Ok(()) => { + Ok(_) => { e.insert(sender); } Err(e) => { diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index b171f48b6e3..fb9ddf74c49 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -251,6 +251,9 @@ impl super::Recorder { record(OutgoingConnectionErrorError::ConnectionIo) } + libp2p_swarm::DialError::Denied { .. } => { + todo!() + } }; } libp2p_swarm::SwarmEvent::BannedPeer { endpoint, .. } => { diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index f5fd8a3dc40..740f3d50a0f 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -1356,7 +1356,7 @@ fn test_explicit_peer_gets_connected() { .events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => opts.get_peer_id() == Some(peer), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(peer), _ => false, }) .count(); @@ -1397,8 +1397,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => - opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(*peer), _ => false, }) .count(), @@ -1413,8 +1412,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => - opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(*peer), _ => false, }) .count() @@ -1794,7 +1792,7 @@ fn test_connect_to_px_peers_on_handle_prune() { .events .iter() .filter_map(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => opts.get_peer_id(), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id(), _ => None, }) .collect(); diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 9021d6d6f80..67a03a6ae84 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1954,6 +1954,7 @@ where DialError::DialPeerConditionFalse(dial_opts::PeerCondition::Always) => { unreachable!("DialPeerCondition::Always can not trigger DialPeerConditionFalse."); } + DialError::Denied { .. } => todo!(), } } @@ -2388,10 +2389,9 @@ where }); } else if &peer_id != self.kbuckets.local_key().preimage() { query.inner.pending_rpcs.push((peer_id, event)); - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + id: Default::default(), }); } } diff --git a/protocols/rendezvous/examples/discover.rs b/protocols/rendezvous/examples/discover.rs index 274432bc2d3..d12dd5cee0c 100644 --- a/protocols/rendezvous/examples/discover.rs +++ b/protocols/rendezvous/examples/discover.rs @@ -95,7 +95,7 @@ async fn main() { address.clone() }; - swarm.dial(address_with_p2p).unwrap() + swarm.dial(address_with_p2p).unwrap(); } } } diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 142ced11d6b..9777163a6b4 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -259,26 +259,16 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .rev() .enumerate() .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 } - } else { - quote! { - let (handlers, handler) = handlers.into_inner() - } - }; - let inject = match field.ident { Some(ref i) => quote! { #[allow(deprecated)] - self.#i.inject_dial_failure(peer_id, handler, error);}, + self.#i.inject_dial_failure(peer_id, error, id);}, None => quote! { #[allow(deprecated)] - self.#enum_n.inject_dial_failure(peer_id, handler, error);}, + self.#enum_n.inject_dial_failure(peer_id, error, id);}, }; quote! { - #handler; #inject; } }) @@ -290,25 +280,16 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { { 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! { #[allow(deprecated)] - self.#i.inject_listen_failure(local_addr, send_back_addr, handler);}, + self.#i.inject_listen_failure(local_addr, send_back_addr, id);}, None => quote! { #[allow(deprecated)] - self.#enum_n.inject_listen_failure(local_addr, send_back_addr, handler);}, + self.#enum_n.inject_listen_failure(local_addr, send_back_addr, id);}, }; quote! { - #handler; #inject; } }, @@ -524,38 +505,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { wrapped_event = quote!{ #either_ident::First(#wrapped_event) }; } - // `Dial` provides a handler of the specific behaviour triggering the - // event. Though in order for the final handler to be able to handle - // protocols of all behaviours, the provided handler needs to be - // combined with handlers of all other behaviours. - let provided_handler_and_new_handlers = { - let mut out_handler = None; - - for (f_n, f) in data_struct.fields.iter().enumerate() { - let f_name = match f.ident { - Some(ref i) => quote! { self.#i }, - None => quote! { self.#f_n }, - }; - - let builder = if field_n == f_n { - // The behaviour that triggered the event. Thus, instead of - // creating a new handler, use the provided handler. - quote! { provided_handler } - } else { - quote! { #f_name.new_handler() } - }; - - match out_handler { - Some(h) => { - out_handler = Some(quote! { #into_connection_handler::select(#h, #builder) }) - } - ref mut h @ None => *h = Some(builder), - } - } - - out_handler.unwrap_or(quote! {()}) // TODO: See test `empty`. - }; - let generate_event_match_arm = { // If the `NetworkBehaviour`'s `OutEvent` is generated by the derive macro, wrap the sub // `NetworkBehaviour` `OutEvent` in the variant of the generated `OutEvent`. If the @@ -583,8 +532,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { loop { match #trait_to_impl::poll(&mut self.#field, cx, poll_params) { #generate_event_match_arm - std::task::Poll::Ready(#network_behaviour_action::Dial { opts, handler: provided_handler }) => { - return std::task::Poll::Ready(#network_behaviour_action::Dial { opts, handler: #provided_handler_and_new_handlers }); + std::task::Poll::Ready(#network_behaviour_action::Dial { opts, id }) => { + return std::task::Poll::Ready(#network_behaviour_action::Dial { opts, id }); } std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { peer_id, handler, event }) => { return std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { @@ -643,7 +592,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } } - fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action>> { + fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action>> { use #prelude_path::futures::*; #(#poll_stmts)* std::task::Poll::Pending @@ -661,10 +610,10 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #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 }) + #dial_failure { peer_id, error, id }) => { #(#on_dial_failure_stmts)* } #from_swarm::ListenFailure( - #listen_failure { local_addr, send_back_addr, handler: handlers }) + #listen_failure { local_addr, send_back_addr, id }) => { #(#on_listen_failure_stmts)* } #from_swarm::NewListener( #new_listener { listener_id }) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index c162075ef53..7c7418892a5 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -355,12 +355,13 @@ pub trait NetworkBehaviour: Sized + 'static { 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, error: &DialError) { - self.on_swarm_event(FromSwarm::DialFailure(DialFailure { - peer_id, - error, - id: todo!("remove deprecated APIs first"), - })); + fn inject_dial_failure( + &mut self, + peer_id: Option, + error: &DialError, + id: ConnectionId, + ) { + self.on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, error, id })); } /// Indicates to the behaviour that an error happened on an incoming connection during its @@ -372,11 +373,16 @@ pub trait NetworkBehaviour: Sized + 'static { 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) { + fn inject_listen_failure( + &mut self, + local_addr: &Multiaddr, + send_back_addr: &Multiaddr, + id: ConnectionId, + ) { self.on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, - id: todo!("remove deprecated APIs first"), + id, })); } @@ -969,7 +975,7 @@ pub(crate) fn inject_from_swarm( } FromSwarm::DialFailure(DialFailure { peer_id, error, id }) => { #[allow(deprecated)] - behaviour.inject_dial_failure(peer_id, error); + behaviour.inject_dial_failure(peer_id, error, id); } FromSwarm::ListenFailure(ListenFailure { local_addr, @@ -977,7 +983,7 @@ pub(crate) fn inject_from_swarm( id, }) => { #[allow(deprecated)] - behaviour.inject_listen_failure(local_addr, send_back_addr); + behaviour.inject_listen_failure(local_addr, send_back_addr, id); } FromSwarm::NewListener(NewListener { listener_id }) => { #[allow(deprecated)] diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 57262c21419..d0fc029b3ea 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -193,19 +193,6 @@ pub enum SwarmEvent { /// How long it took to establish this connection established_in: std::time::Duration, }, - PendingConnectionDenied { - peer_id: Option, - endpoint: PendingPoint, - cause: Box, - }, - EstablishedConnectionDenied { - /// Identity of the peer that we have connected to. - peer_id: PeerId, - /// Endpoint of the connection that has been closed. - endpoint: ConnectedPoint, - cause: Box, - }, - /// A connection with the given peer has been closed, /// possibly as a result of an error. ConnectionClosed { @@ -555,7 +542,8 @@ where let e = DialError::DialPeerConditionFalse(condition); #[allow(deprecated)] - self.behaviour.inject_dial_failure(peer_id, &e); + self.behaviour + .inject_dial_failure(peer_id, &e, connection_id); return Err(e); } @@ -565,7 +553,8 @@ where if self.banned_peers.contains(&peer_id) { let error = DialError::Banned; #[allow(deprecated)] - self.behaviour.inject_dial_failure(Some(peer_id), &error); + self.behaviour + .inject_dial_failure(Some(peer_id), &error, connection_id); return Err(error); } } @@ -587,7 +576,8 @@ where Err(cause) => { let error = DialError::Denied { cause }; - self.behaviour.inject_dial_failure(peer_id, &error); + self.behaviour + .inject_dial_failure(peer_id, &error, connection_id); return Err(error); } @@ -602,7 +592,8 @@ where if addresses_from_opts.is_empty() { let error = DialError::NoAddresses; #[allow(deprecated)] - self.behaviour.inject_dial_failure(peer_id, &error); + self.behaviour + .inject_dial_failure(peer_id, &error, connection_id); return Err(error); }; @@ -643,7 +634,8 @@ where Err(connection_limit) => { let error = DialError::ConnectionLimit(connection_limit); // TODO: Remove `ConnectionLimit`. #[allow(deprecated)] - self.behaviour.inject_dial_failure(peer_id, &error); + self.behaviour + .inject_dial_failure(peer_id, &error, connection_id); Err(error) } } @@ -832,11 +824,11 @@ where }); } } - PoolEvent::PendingOutboundConnectionError { id: _, error, peer } => { + PoolEvent::PendingOutboundConnectionError { id, error, peer } => { let error = error.into(); #[allow(deprecated)] - self.behaviour.inject_dial_failure(peer, &error); + self.behaviour.inject_dial_failure(peer, &error, id); if let Some(peer) = peer { log::debug!("Connection attempt to {:?} failed with {:?}.", peer, error,); @@ -850,7 +842,7 @@ where }); } PoolEvent::PendingInboundConnectionError { - id: _, + id, send_back_addr, local_addr, error, @@ -858,7 +850,7 @@ where log::debug!("Incoming connection failed: {:?}", error); #[allow(deprecated)] self.behaviour - .inject_listen_failure(&local_addr, &send_back_addr); + .inject_listen_failure(&local_addr, &send_back_addr, id); return Some(SwarmEvent::IncomingConnectionError { local_addr, send_back_addr, @@ -919,11 +911,7 @@ where cause, .. } => { - return Some(SwarmEvent::EstablishedConnectionDenied { - peer_id, - endpoint, - cause, - }) + return Some(todo!("Report connection error event, these are currently modeled in a weird way where we split them by incoming/outgoing on the `SwarmEvent` level but everywhere else by established/pending")) } PoolEvent::ConnectionEvent { peer_id, id, event } => { if self.banned_peer_connections.contains(&id) { @@ -979,14 +967,7 @@ where Err(error) => { // TODO: self.behaviour.on_swarm_event(FromSwarm::ListenFailure()) - return Some(SwarmEvent::PendingConnectionDenied { - peer_id: None, - endpoint: PendingPoint::Listener { - local_addr, - send_back_addr, - }, - cause: error, - }); + return Some(todo!("Report connection error event, these are currently modeled in a weird way where we split them by incoming/outgoing on the `SwarmEvent` level but everywhere else by established/pending")); } } @@ -998,7 +979,7 @@ where }, connection_id, ) { - Ok(_connection_id) => { + Ok(()) => { return Some(SwarmEvent::IncomingConnection { local_addr, send_back_addr, @@ -1006,8 +987,11 @@ where } Err(connection_limit) => { #[allow(deprecated)] - self.behaviour - .inject_listen_failure(&local_addr, &send_back_addr); + self.behaviour.inject_listen_failure( + &local_addr, + &send_back_addr, + connection_id, + ); log::warn!("Incoming connection rejected: {:?}", connection_limit); } }; @@ -1901,7 +1885,7 @@ mod tests { ) -> bool where TBehaviour: NetworkBehaviour, - ::OutEvent: Clone, + THandlerOutEvent: Clone, { swarm1 .behaviour() @@ -1921,7 +1905,7 @@ mod tests { ) -> bool where TBehaviour: NetworkBehaviour, - ::OutEvent: Clone, + THandlerOutEvent: Clone, { swarm1 .behaviour() diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 88b1a226413..476f9424020 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -24,7 +24,7 @@ use crate::behaviour::{ }; use crate::{ ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, + PollParameters, THandlerInEvent, }; use libp2p_core::{ connection::ConnectionId, multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId, @@ -37,7 +37,9 @@ use std::task::{Context, Poll}; /// any further state. pub struct MockBehaviour where - THandler: ConnectionHandler, + THandler: ConnectionHandler + Clone, + THandler::OutEvent: Clone, + TOutEvent: Send + 'static, { /// The prototype protocols handler that is cloned for every /// invocation of `new_handler`. @@ -47,12 +49,14 @@ where /// The next action to return from `poll`. /// /// An action is only returned once. - pub next_action: Option>, + pub next_action: Option>>, } impl MockBehaviour where - THandler: ConnectionHandler, + THandler: ConnectionHandler + Clone, + THandler::OutEvent: Clone, + TOutEvent: Send + 'static, { pub fn new(handler_proto: THandler) -> Self { MockBehaviour { @@ -389,14 +393,10 @@ where FromSwarm::ConnectionClosed(connection_closed) => { self.on_connection_closed(connection_closed) } - FromSwarm::DialFailure(DialFailure { - peer_id, - handler, - error, - }) => { + FromSwarm::DialFailure(DialFailure { peer_id, error, id }) => { self.on_dial_failure.push(peer_id); #[allow(deprecated)] - self.inner.inject_dial_failure(peer_id, handler, error); + self.inner.inject_dial_failure(peer_id, error, id); } FromSwarm::NewListener(NewListener { listener_id }) => { self.on_new_listener.push(listener_id); diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 456cb053c06..118b279bfc5 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::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent}; +use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent, THandlerInEvent}; use std::fmt::Debug; /// Small utility to check that a type implements `NetworkBehaviour`. From 796432a789f2743f3d430ff2382bd5ed0b809385 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 11:08:49 +1100 Subject: [PATCH 026/177] Undo explicit `Sized` bound --- swarm/src/behaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 7c7418892a5..5a42e7b54d9 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -116,7 +116,7 @@ use std::{task::Context, task::Poll}; /// } /// } /// ``` -pub trait NetworkBehaviour: Sized + 'static { +pub trait NetworkBehaviour: 'static { /// Handler for all the protocols the network behaviour supports. type ConnectionHandler: IntoConnectionHandler; From dfd349fefbbd8327a8c9a7c398f8e7b580d2b2ae Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 11:12:48 +1100 Subject: [PATCH 027/177] Let user know that we are discarding addresses --- core/src/connection.rs | 8 ++++++++ core/src/lib.rs | 2 ++ swarm/src/lib.rs | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/core/src/connection.rs b/core/src/connection.rs index 717076f9c96..4bcf6a2b7ea 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -19,6 +19,8 @@ // DEALINGS IN THE SOFTWARE. use crate::multiaddr::{Multiaddr, Protocol}; +use std::fmt; +use std::fmt::Debug; use std::sync::atomic::{AtomicU64, Ordering}; static NEXT_CONNECTION_ID: AtomicU64 = AtomicU64::new(0); @@ -45,6 +47,12 @@ impl Default for ConnectionId { } } +impl fmt::Display for ConnectionId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + /// The endpoint roles associated with a peer-to-peer communication channel. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum Endpoint { diff --git a/core/src/lib.rs b/core/src/lib.rs index 2b20f5156e4..953bca551d7 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -37,6 +37,8 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +extern crate core; + #[allow(clippy::derive_partial_eq_without_eq)] mod keys_proto { include!(concat!(env!("OUT_DIR"), "/keys_proto.rs")); diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index d0fc029b3ea..ee2e9deb4de 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -571,6 +571,12 @@ where Ok(addresses) => { if dial_opts.extend_addresses_through_behaviour() { addresses_from_opts.extend(addresses) + } else { + let num_addresses = addresses.len(); + + if num_addresses > 0 { + log::debug!("discarding {num_addresses} addresses from `NetworkBehaviour` because `DialOpts::extend_addresses_through_behaviour is `false` for connection {connection_id}") + } } } Err(cause) => { From 600791dcfdde317ae8004a02d6309c9fb951c078 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 11:13:58 +1100 Subject: [PATCH 028/177] Fix unused variable warning --- swarm-derive/src/lib.rs | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 9777163a6b4..bb1636018a6 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -254,11 +254,10 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { data_struct .fields .iter() - .enumerate() // The outmost handler belongs to the last behaviour. .rev() .enumerate() - .map(|(enum_n, (field_n, field))| { + .map(|(enum_n, field)| { let inject = match field.ident { Some(ref i) => quote! { #[allow(deprecated)] @@ -276,25 +275,27 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { // 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 inject = match field.ident { - Some(ref i) => quote! { - #[allow(deprecated)] - self.#i.inject_listen_failure(local_addr, send_back_addr, id);}, - None => quote! { - #[allow(deprecated)] - self.#enum_n.inject_listen_failure(local_addr, send_back_addr, id);}, - }; + let on_listen_failure_stmts = { + data_struct + .fields + .iter() + .rev() + .enumerate() + .map(|(enum_n, field)| { + let inject = match field.ident { + Some(ref i) => quote! { + #[allow(deprecated)] + self.#i.inject_listen_failure(local_addr, send_back_addr, id);}, + None => quote! { + #[allow(deprecated)] + self.#enum_n.inject_listen_failure(local_addr, send_back_addr, id);}, + }; - quote! { - #inject; - } - }, - ) - }; + quote! { + #inject; + } + }) + }; // Build the list of statements to put in the body of `on_swarm_event()` // for the `FromSwarm::NewListener` variant. From 72fecc8c1e7dc2737005ed8121f494a6f9f9ce18 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 11:16:40 +1100 Subject: [PATCH 029/177] Fix unused import warnings --- protocols/autonat/src/behaviour/as_server.rs | 2 +- protocols/rendezvous/src/client.rs | 3 +-- swarm/src/lib.rs | 4 +--- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/protocols/autonat/src/behaviour/as_server.rs b/protocols/autonat/src/behaviour/as_server.rs index 3aa62c67eb6..6efc9bb06d7 100644 --- a/protocols/autonat/src/behaviour/as_server.rs +++ b/protocols/autonat/src/behaviour/as_server.rs @@ -29,7 +29,7 @@ use libp2p_request_response::{ }; use libp2p_swarm::{ dial_opts::{DialOpts, PeerCondition}, - DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + DialError, NetworkBehaviourAction, PollParameters, }; use std::{ collections::{HashMap, HashSet, VecDeque}, diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 9f49b578ef3..3524c5052cb 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -22,7 +22,7 @@ use crate::codec::{Cookie, ErrorCode, Namespace, NewRegistration, Registration, use crate::handler; use crate::handler::outbound; use crate::handler::outbound::OpenInfo; -use crate::substream_handler::{InEvent, SubstreamConnectionHandler}; +use crate::substream_handler::SubstreamConnectionHandler; use futures::future::BoxFuture; use futures::future::FutureExt; use futures::stream::FuturesUnordered; @@ -40,7 +40,6 @@ use libp2p_swarm::{ use std::collections::{HashMap, VecDeque}; use std::iter::FromIterator; use std::task::{Context, Poll}; -use void::Void; pub struct Behaviour { events: VecDeque>>, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ee2e9deb4de..b4ffa3c2b7a 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -121,13 +121,11 @@ pub use handler::{ pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; -use crate::behaviour::FromSwarm; -use crate::derive_prelude::DialFailure; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; use dial_opts::{DialOpts, PeerCondition}; use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream}; -use libp2p_core::connection::{ConnectionId, PendingPoint}; +use libp2p_core::connection::ConnectionId; use libp2p_core::muxing::SubstreamBox; use libp2p_core::{ connection::ConnectedPoint, From 62b11aa343d69e245699866b927621cc68f1e18a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 11:48:30 +1100 Subject: [PATCH 030/177] Port `dcutr` protocol --- protocols/dcutr/src/behaviour_impl.rs | 202 +++++++++++++++++--------- protocols/dcutr/src/handler.rs | 54 ------- swarm/src/behaviour.rs | 26 ++-- 3 files changed, 147 insertions(+), 135 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 34eb7a525ef..4ca33ffea3c 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -21,16 +21,17 @@ //! [`NetworkBehaviour`] to act as a direct connection upgrade through relay node. use crate::handler; +use crate::handler::{direct, relayed, Role}; use crate::protocol; use either::Either; use libp2p_core::connection::{ConnectedPoint, ConnectionId}; use libp2p_core::multiaddr::Protocol; -use libp2p_core::{Multiaddr, PeerId}; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerUpgrErr, ExternalAddresses, IntoConnectionHandler, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + dummy, ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, + NotifyHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; @@ -70,6 +71,8 @@ pub struct Behaviour { /// Queue of actions to return when polled. queued_actions: VecDeque, + direct_outgoing_connection_attempts: HashMap, + /// All direct (non-relayed) connections. direct_connections: HashMap>, @@ -82,6 +85,7 @@ impl Behaviour { pub fn new(local_peer_id: PeerId) -> Self { Behaviour { queued_actions: Default::default(), + direct_outgoing_connection_attempts: Default::default(), direct_connections: Default::default(), external_addresses: Default::default(), local_peer_id, @@ -135,40 +139,35 @@ impl Behaviour { } fn on_dial_failure(&mut self, DialFailure { peer_id, id, .. }: DialFailure) { - // TODO: To properly count connection attempts, we need count number of unique connection IDs we get here. - // That is not pretty in case we ever get a collision. How do we prevent a collision? - // We could also reuse that connection ID and count the number of attempts through that. - - // if let handler::Prototype::DirectConnection { - // relayed_connection_id, - // role: handler::Role::Initiator { attempt }, - // } = handler - // { - // let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); - // if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - // self.queued_actions.push_back(ActionBuilder::Connect { - // peer_id, - // handler: NotifyHandler::One(relayed_connection_id), - // attempt: attempt + 1, - // }); - // } else { - // self.queued_actions.extend([ - // NetworkBehaviourAction::NotifyHandler { - // peer_id, - // handler: NotifyHandler::One(relayed_connection_id), - // event: Either::Left( - // handler::relayed::Command::UpgradeFinishedDontKeepAlive, - // ), - // } - // .into(), - // NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { - // remote_peer_id: peer_id, - // error: Error::Dial, - // }) - // .into(), - // ]); - // } - // } + let Some((relayed_connection_id, role)) = self.direct_outgoing_connection_attempts.remove(&id) else { + return; + }; + let Role::Initiator { attempt } = role else { + return; + }; + + let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); + if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { + self.queued_actions.push_back(ActionBuilder::Connect { + peer_id, + handler: NotifyHandler::One(relayed_connection_id), + attempt: attempt + 1, + }); + } else { + self.queued_actions.extend([ + NetworkBehaviourAction::NotifyHandler { + peer_id, + handler: NotifyHandler::One(relayed_connection_id), + event: Either::Left(handler::relayed::Command::UpgradeFinishedDontKeepAlive), + } + .into(), + NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { + remote_peer_id: peer_id, + error: Error::Dial, + }) + .into(), + ]); + } } fn on_connection_closed( @@ -197,19 +196,82 @@ impl Behaviour { } impl NetworkBehaviour for Behaviour { - type ConnectionHandler = handler::Prototype; + type ConnectionHandler = + Either>; type OutEvent = Event; + #[allow(deprecated)] fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::UnknownConnection + unreachable!("We override the new callbacks.") + } + + fn handle_established_inbound_connection( + &mut self, + _peer: PeerId, + _connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { + let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. + + // TODO: Why are we ignoring `Role`? + let Some((relayed_connection_id, _role)) = self.direct_outgoing_connection_attempts.remove(&_connection_id) else { + + let handler = if is_relayed { + Either::Left(relayed::Handler::new(ConnectedPoint::Listener { local_addr: local_addr.clone(), send_back_addr: remote_addr.clone() })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. + } else { + Either::Right(Either::Right(dummy::ConnectionHandler)) + }; + + return Ok(handler) + }; + + assert!( + !is_relayed, + "`Prototype::DirectConnection` is never created for relayed connection." + ); + + Ok(Either::Right(Either::Left(direct::Handler::new( + relayed_connection_id, + )))) + } + + fn handle_established_outbound_connection( + &mut self, + _peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + _connection_id: ConnectionId, + ) -> Result, Box> { + let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. + + // TODO: Why are we ignoring `Role`? + let Some((relayed_connection_id, _role)) = self.direct_outgoing_connection_attempts.remove(&_connection_id) else { + + let handler = if is_relayed { + Either::Left(relayed::Handler::new(ConnectedPoint::Dialer { address: addr.clone(), role_override })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. + } else { + Either::Right(Either::Right(dummy::ConnectionHandler)) + }; + + return Ok(handler) + }; + + assert!( + !is_relayed, + "`Prototype::DirectConnection` is never created for relayed connection." + ); + + Ok(Either::Right(Either::Left(direct::Handler::new( + relayed_connection_id, + )))) } fn on_connection_handler_event( &mut self, event_source: PeerId, - connection: ConnectionId, - handler_event: <::Handler as - ConnectionHandler>::OutEvent, + relayed_connection_id: ConnectionId, + handler_event: THandlerOutEvent, ) { match handler_event { Either::Left(handler::relayed::Event::InboundConnectRequest { @@ -219,7 +281,7 @@ impl NetworkBehaviour for Behaviour { self.queued_actions.extend([ ActionBuilder::AcceptInboundConnect { peer_id: event_source, - handler: NotifyHandler::One(connection), + handler: NotifyHandler::One(relayed_connection_id), inbound_connect, }, NetworkBehaviourAction::GenerateEvent( @@ -241,20 +303,18 @@ impl NetworkBehaviour for Behaviour { ); } Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => { - // self.queued_actions.push_back( - // NetworkBehaviourAction::Dial { - // opts: DialOpts::peer_id(event_source) - // .addresses(remote_addrs) - // .condition(dial_opts::PeerCondition::Always) - // .build(), - // handler: handler::Prototype::DirectConnection { - // relayed_connection_id: connection, - // role: handler::Role::Listener, - // }, - // } - // .into(), - // ); - todo!() + let (action, connection_id) = NetworkBehaviourAction::dial( + DialOpts::peer_id(event_source) + .addresses(remote_addrs) + .condition(dial_opts::PeerCondition::Always) + .build(), + ); + + self.queued_actions.push_back(action.into()); + self.direct_outgoing_connection_attempts.insert( + connection_id, + (relayed_connection_id, handler::Role::Listener), + ); } Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { self.queued_actions.push_back( @@ -269,21 +329,19 @@ impl NetworkBehaviour for Behaviour { remote_addrs, attempt, }) => { - // self.queued_actions.push_back( - // NetworkBehaviourAction::Dial { - // opts: DialOpts::peer_id(event_source) - // .condition(dial_opts::PeerCondition::Always) - // .addresses(remote_addrs) - // .override_role() - // .build(), - // handler: handler::Prototype::DirectConnection { - // relayed_connection_id: connection, - // role: handler::Role::Initiator { attempt }, - // }, - // } - // .into(), - // ); - todo!() + let (action, connection_id) = NetworkBehaviourAction::dial( + DialOpts::peer_id(event_source) + .addresses(remote_addrs) + .condition(dial_opts::PeerCondition::Always) + .override_role() + .build(), + ); + + self.queued_actions.push_back(action.into()); + self.direct_outgoing_connection_attempts.insert( + connection_id, + (relayed_connection_id, handler::Role::Initiator { attempt }), + ); } Either::Right(Either::Left( handler::direct::Event::DirectConnectionUpgradeSucceeded { diff --git a/protocols/dcutr/src/handler.rs b/protocols/dcutr/src/handler.rs index e854b395308..ca4fcafc5f4 100644 --- a/protocols/dcutr/src/handler.rs +++ b/protocols/dcutr/src/handler.rs @@ -18,64 +18,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::protocol; -use either::Either; -use libp2p_core::connection::ConnectionId; -use libp2p_core::upgrade::{self, DeniedUpgrade}; -use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::dummy; -use libp2p_swarm::handler::SendWrapper; -use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler}; - pub mod direct; pub mod relayed; -pub enum Prototype { - DirectConnection { - role: Role, - relayed_connection_id: ConnectionId, - }, - UnknownConnection, -} - pub enum Role { Initiator { attempt: u8 }, Listener, } - -impl IntoConnectionHandler for Prototype { - type Handler = Either>; - - fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - match self { - Self::UnknownConnection => { - if endpoint.is_relayed() { - Either::Left(relayed::Handler::new(endpoint.clone())) - } else { - Either::Right(Either::Right(dummy::ConnectionHandler)) - } - } - Self::DirectConnection { - relayed_connection_id, - .. - } => { - assert!( - !endpoint.is_relayed(), - "`Prototype::DirectConnection` is never created for relayed connection." - ); - Either::Right(Either::Left(direct::Handler::new(relayed_connection_id))) - } - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - match self { - Prototype::UnknownConnection => upgrade::EitherUpgrade::A(SendWrapper( - upgrade::EitherUpgrade::A(protocol::inbound::Upgrade {}), - )), - Prototype::DirectConnection { .. } => { - upgrade::EitherUpgrade::A(SendWrapper(upgrade::EitherUpgrade::B(DeniedUpgrade))) - } - } - } -} diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 5a42e7b54d9..6ec2263836e 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -28,7 +28,7 @@ pub use listen_addresses::ListenAddresses; use crate::dial_opts::DialOpts; use crate::handler::{ConnectionHandler, IntoConnectionHandler}; -use crate::{AddressRecord, AddressScore, DialError, THandlerInEvent}; +use crate::{AddressRecord, AddressScore, DialError, THandler, THandlerInEvent}; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId, }; @@ -172,10 +172,7 @@ pub trait NetworkBehaviour: 'static { _connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result< - ::Handler, - Box, - > { + ) -> Result, Box> { #[allow(deprecated)] Ok(self.new_handler().into_handler( &peer, @@ -222,10 +219,7 @@ pub trait NetworkBehaviour: 'static { addr: &Multiaddr, role_override: Endpoint, _connection_id: ConnectionId, - ) -> Result< - ::Handler, - Box, - > { + ) -> Result, Box> { #[allow(deprecated)] Ok(self.new_handler().into_handler( &peer, @@ -586,6 +580,20 @@ pub enum NetworkBehaviourAction { }, } +impl NetworkBehaviourAction { + /// TODO: Docs + pub fn dial(opts: impl Into) -> (Self, ConnectionId) { + let id = ConnectionId::default(); + + let action = Self::Dial { + opts: opts.into(), + id, + }; + + (action, id) + } +} + impl NetworkBehaviourAction { /// Map the handler event. pub fn map_in( From 75d1f5af5ff09b703b80c32d11fe9af64f9c6c73 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 12:31:10 +1100 Subject: [PATCH 031/177] Re-implement relay --- protocols/autonat/src/behaviour.rs | 5 +- protocols/floodsub/src/layer.rs | 6 +- protocols/gossipsub/src/behaviour.rs | 5 +- protocols/identify/src/behaviour.rs | 4 +- protocols/kad/src/behaviour.rs | 4 +- protocols/mdns/src/behaviour.rs | 5 +- protocols/ping/src/lib.rs | 10 ++- protocols/relay/src/v2/client.rs | 107 ++++++++++++++++------- protocols/relay/src/v2/client/handler.rs | 81 ++++------------- protocols/relay/src/v2/relay.rs | 64 ++++++++++++-- protocols/relay/src/v2/relay/handler.rs | 60 ++++--------- protocols/rendezvous/src/client.rs | 4 +- protocols/rendezvous/src/server.rs | 4 +- protocols/request-response/src/lib.rs | 5 +- swarm/src/behaviour.rs | 4 +- swarm/src/behaviour/either.rs | 5 +- swarm/src/behaviour/toggle.rs | 7 +- swarm/src/dummy.rs | 10 ++- swarm/src/keep_alive.rs | 9 +- swarm/src/test.rs | 7 +- swarm/tests/swarm_derive.rs | 6 +- 21 files changed, 231 insertions(+), 181 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index ff0125f011d..b3fba150a1f 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -40,7 +40,7 @@ use libp2p_swarm::{ ExpiredListenAddr, FromSwarm, }, ConnectionHandler, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, PollParameters, THandlerInEvent, + NetworkBehaviourAction, PollParameters, THandlerInEvent, THandlerOutEvent, }; use std::{ collections::{HashMap, VecDeque}, @@ -541,8 +541,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer_id: PeerId, connection_id: ConnectionId, - event: <::Handler as - ConnectionHandler>::OutEvent, + event: THandlerOutEvent, ) { self.inner .on_connection_handler_event(peer_id, connection_id, event) diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 0c17ecddb83..0f7d598c3ed 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -30,9 +30,8 @@ use libp2p_core::{connection::ConnectionId, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, - PollParameters, THandlerInEvent, + PollParameters, THandlerInEvent, THandlerOutEvent, }; -use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler}; use log::warn; use smallvec::SmallVec; use std::collections::hash_map::{DefaultHasher, HashMap}; @@ -345,8 +344,7 @@ impl NetworkBehaviour for Floodsub { &mut self, propagation_source: PeerId, _connection_id: ConnectionId, - event: <::Handler as - ConnectionHandler>::OutEvent, + event: THandlerOutEvent, ) { // We ignore successful sends or timeouts. let event = match event { diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index d746cba2fc0..74419e2a99c 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -43,7 +43,7 @@ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, dial_opts::DialOpts, ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandlerInEvent, + NotifyHandler, PollParameters, THandlerInEvent, THandlerOutEvent, }; use wasm_timer::Instant; @@ -3313,8 +3313,7 @@ where &mut self, propagation_source: PeerId, _connection_id: ConnectionId, - handler_event: <::Handler as - ConnectionHandler>::OutEvent, + handler_event: THandlerOutEvent, ) { match handler_event { HandlerEvent::PeerKind(kind) => { diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 29b766293ef..d3f189a40de 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -27,7 +27,7 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailu use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, THandlerOutEvent, }; use lru::LruCache; use std::num::NonZeroUsize; @@ -253,7 +253,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer_id: PeerId, connection_id: ConnectionId, - event: <::Handler as ConnectionHandler>::OutEvent, + event: THandlerOutEvent, ) { match event { handler::Event::Identified(mut info) => { diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 67a03a6ae84..5405b537726 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -46,7 +46,7 @@ use libp2p_swarm::behaviour::{ use libp2p_swarm::{ dial_opts::{self, DialOpts}, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandlerInEvent, + NotifyHandler, PollParameters, THandlerInEvent, THandlerOutEvent, }; use log::{debug, info, warn}; use smallvec::SmallVec; @@ -2023,7 +2023,7 @@ where &mut self, source: PeerId, connection: ConnectionId, - event: KademliaHandlerEvent, + event: THandlerOutEvent, ) { match event { KademliaHandlerEvent::ProtocolConfirmed { endpoint } => { diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 19bc518d320..969c91e1341 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -27,11 +27,12 @@ use crate::behaviour::{socket::AsyncSocket, timer::Builder}; use crate::Config; use futures::Stream; use if_watch::IfEvent; +use libp2p_core::connection::ConnectionId; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ dummy, ConnectionHandler, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, THandlerInEvent, + PollParameters, THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; @@ -190,7 +191,7 @@ where &mut self, _: PeerId, _: libp2p_core::connection::ConnectionId, - ev: ::OutEvent, + ev: THandlerOutEvent, ) { void::unreachable(ev) } diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 23dccc769dc..e163386faa7 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -49,7 +49,8 @@ use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, PeerId}; use libp2p_swarm::{ - behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, THandlerOutEvent, }; use std::{ collections::VecDeque, @@ -123,7 +124,12 @@ impl NetworkBehaviour for Behaviour { Handler::new(self.config.clone()) } - fn on_connection_handler_event(&mut self, peer: PeerId, _: ConnectionId, result: Result) { + fn on_connection_handler_event( + &mut self, + peer: PeerId, + _: ConnectionId, + result: THandlerOutEvent, + ) { self.events.push_front(Event { peer, result }) } diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 31e0392cabf..63d0e4c3fd5 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -32,13 +32,16 @@ use futures::future::{BoxFuture, FutureExt}; use futures::io::{AsyncRead, AsyncWrite}; use futures::ready; use futures::stream::StreamExt; +use handler::Handler; use libp2p_core::connection::ConnectionId; -use libp2p_core::PeerId; +use libp2p_core::multiaddr::Protocol; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ - ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandlerInEvent, + dummy, ConnectionHandler, ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, + NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, THandlerInEvent, + THandlerOutEvent, }; use std::collections::{hash_map, HashMap, VecDeque}; use std::io::{Error, ErrorKind, IoSlice}; @@ -98,6 +101,8 @@ pub struct Client { /// Queue of actions to return when polled. queued_actions: VecDeque, + + pending_events: HashMap, } impl Client { @@ -110,6 +115,7 @@ impl Client { from_transport, directly_connected_peers: Default::default(), queued_actions: Default::default(), + pending_events: Default::default(), }; (transport, behaviour) } @@ -146,11 +152,55 @@ impl Client { } impl NetworkBehaviour for Client { - type ConnectionHandler = handler::Prototype; + type ConnectionHandler = Either; type OutEvent = Event; fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::new(self.local_peer_id, None) + unreachable!("We override the new callbacks.") + } + + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { + let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. + + if is_relayed { + return Ok(Either::Right(dummy::ConnectionHandler)); + } + + let mut handler = Handler::new(self.local_peer_id, peer, remote_addr.clone()); + + if let Some(event) = self.pending_events.remove(&connection_id) { + handler.on_behaviour_event(event) + } + + Ok(Either::Left(handler)) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + _role_override: Endpoint, + connection_id: ConnectionId, + ) -> Result, Box> { + let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. + + if is_relayed { + return Ok(Either::Right(dummy::ConnectionHandler)); + } + + let mut handler = Handler::new(self.local_peer_id, peer, addr.clone()); + + if let Some(event) = self.pending_events.remove(&connection_id) { + handler.on_behaviour_event(event) + } + + Ok(Either::Left(handler)) } fn on_swarm_event(&mut self, event: FromSwarm) { @@ -188,9 +238,9 @@ impl NetworkBehaviour for Client { &mut self, event_source: PeerId, _connection: ConnectionId, - handler_event: Either, + _event: THandlerOutEvent, ) { - let handler_event = match handler_event { + let handler_event = match _event { Either::Left(e) => e, Either::Right(v) => void::unreachable(v), }; @@ -269,19 +319,16 @@ impl NetworkBehaviour for Client { event: Either::Left(handler::In::Reserve { to_listener }), }, None => { - // let handler = handler::Prototype::new( - // self.local_peer_id, - // Some(handler::In::Reserve { to_listener }), - // ); - // TODO - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) + let (action, connection_id) = NetworkBehaviourAction::dial( + DialOpts::peer_id(relay_peer_id) .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() + .extend_addresses_through_behaviour() // TODO: Why? .build(), + ); + self.pending_events + .insert(connection_id, handler::In::Reserve { to_listener }); - id: Default::default(), - } + action } } } @@ -306,21 +353,21 @@ impl NetworkBehaviour for Client { }), }, None => { - // let handler = handler::Prototype::new( - // self.local_peer_id, - // Some(handler::In::EstablishCircuit { - // send_back, - // dst_peer_id, - // }), - // ); - // TODO - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) + let (action, connection_id) = NetworkBehaviourAction::dial( + DialOpts::peer_id(relay_peer_id) .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() + .extend_addresses_through_behaviour() // TODO: Why? .build(), - id: Default::default(), - } + ); + self.pending_events.insert( + connection_id, + handler::In::EstablishCircuit { + send_back, + dst_peer_id, + }, + ); + + action } } } diff --git a/protocols/relay/src/v2/client/handler.rs b/protocols/relay/src/v2/client/handler.rs index 5d01cf9dbce..7f53a45ea50 100644 --- a/protocols/relay/src/v2/client/handler.rs +++ b/protocols/relay/src/v2/client/handler.rs @@ -21,7 +21,6 @@ use crate::v2::client::transport; use crate::v2::message_proto::Status; use crate::v2::protocol::{self, inbound_stop, outbound_hop}; -use either::Either; use futures::channel::{mpsc, oneshot}; use futures::future::{BoxFuture, FutureExt}; use futures::sink::SinkExt; @@ -30,14 +29,14 @@ use futures_timer::Delay; use instant::Instant; use libp2p_core::either::EitherError; use libp2p_core::multiaddr::Protocol; -use libp2p_core::{upgrade, ConnectedPoint, Multiaddr, PeerId}; +use libp2p_core::{upgrade, Multiaddr, PeerId}; use libp2p_swarm::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, - ListenUpgradeError, SendWrapper, + ListenUpgradeError, }; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, - IntoConnectionHandler, KeepAlive, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + SubstreamProtocol, }; use log::debug; use std::collections::{HashMap, VecDeque}; @@ -110,63 +109,6 @@ pub enum Event { }, } -pub struct Prototype { - local_peer_id: PeerId, - /// Initial [`In`] event from [`super::Client`] provided at creation time. - initial_in: Option, -} - -impl Prototype { - pub(crate) fn new(local_peer_id: PeerId, initial_in: Option) -> Self { - Self { - local_peer_id, - initial_in, - } - } -} - -impl IntoConnectionHandler for Prototype { - type Handler = Either; - - fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - if endpoint.is_relayed() { - if let Some(event) = self.initial_in { - debug!( - "Established relayed instead of direct connection to {:?}, \ - dropping initial in event {:?}.", - remote_peer_id, event - ); - } - - // Deny all substreams on relayed connection. - Either::Right(dummy::ConnectionHandler) - } else { - let mut handler = Handler { - remote_peer_id: *remote_peer_id, - remote_addr: endpoint.get_remote_address().clone(), - local_peer_id: self.local_peer_id, - queued_events: Default::default(), - pending_error: Default::default(), - reservation: Reservation::None, - alive_lend_out_substreams: Default::default(), - circuit_deny_futs: Default::default(), - send_error_futs: Default::default(), - keep_alive: KeepAlive::Yes, - }; - - if let Some(event) = self.initial_in { - handler.on_behaviour_event(event) - } - - Either::Left(handler) - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - upgrade::EitherUpgrade::A(SendWrapper(inbound_stop::Upgrade {})) - } -} - pub struct Handler { local_peer_id: PeerId, remote_peer_id: PeerId, @@ -213,6 +155,21 @@ pub struct Handler { } impl Handler { + pub fn new(local_peer_id: PeerId, remote_peer_id: PeerId, remote_addr: Multiaddr) -> Self { + Self { + local_peer_id, + remote_peer_id, + remote_addr, + pending_error: Default::default(), + keep_alive: KeepAlive::Yes, + queued_events: Default::default(), + reservation: Reservation::None, + alive_lend_out_substreams: Default::default(), + circuit_deny_futs: Default::default(), + send_error_futs: Default::default(), + } + } + fn on_fully_negotiated_inbound( &mut self, FullyNegotiatedInbound { diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 9f7d751ea4b..2eda7043d8c 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -25,17 +25,19 @@ pub mod rate_limiter; use crate::v2::message_proto; use crate::v2::protocol::inbound_hop; +use crate::v2::relay::handler::Handler; use either::Either; use instant::Instant; use libp2p_core::connection::ConnectionId; use libp2p_core::multiaddr::Protocol; -use libp2p_core::PeerId; +use libp2p_core::{ConnectedPoint, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandlerInEvent, + dummy, ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, + NotifyHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{hash_map, HashMap, HashSet, VecDeque}; +use std::error::Error; use std::num::NonZeroU32; use std::ops::Add; use std::task::{Context, Poll}; @@ -252,17 +254,65 @@ impl Relay { } impl NetworkBehaviour for Relay { - type ConnectionHandler = handler::Prototype; + type ConnectionHandler = Either; type OutEvent = Event; fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype { - config: handler::Config { + unreachable!("We override the new callbacks.") + } + + fn handle_established_inbound_connection( + &mut self, + _peer: PeerId, + _connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { + let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. + + if is_relayed { + // Deny all substreams on relayed connection. + return Ok(Either::Right(dummy::ConnectionHandler)); + } + + Ok(Either::Left(Handler::new( + ConnectedPoint::Listener { + local_addr: local_addr.clone(), + send_back_addr: remote_addr.clone(), + }, + handler::Config { reservation_duration: self.config.reservation_duration, max_circuit_duration: self.config.max_circuit_duration, max_circuit_bytes: self.config.max_circuit_bytes, }, + ))) + } + + fn handle_established_outbound_connection( + &mut self, + _peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + _connection_id: ConnectionId, + ) -> Result, Box> { + let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. + + if is_relayed { + // Deny all substreams on relayed connection. + return Ok(Either::Right(dummy::ConnectionHandler)); } + + Ok(Either::Left(Handler::new( + ConnectedPoint::Dialer { + address: addr.clone(), + role_override, + }, + 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) { @@ -290,7 +340,7 @@ impl NetworkBehaviour for Relay { &mut self, event_source: PeerId, connection: ConnectionId, - event: Either, + event: THandlerOutEvent, ) { let event = match event { Either::Left(e) => e, diff --git a/protocols/relay/src/v2/relay/handler.rs b/protocols/relay/src/v2/relay/handler.rs index ef8b40755b2..e82ef6f7211 100644 --- a/protocols/relay/src/v2/relay/handler.rs +++ b/protocols/relay/src/v2/relay/handler.rs @@ -23,7 +23,6 @@ use crate::v2::message_proto::Status; use crate::v2::protocol::{inbound_hop, outbound_stop}; use crate::v2::relay::CircuitId; use bytes::Bytes; -use either::Either; use futures::channel::oneshot::{self, Canceled}; use futures::future::{BoxFuture, FutureExt, TryFutureExt}; use futures::io::AsyncWriteExt; @@ -35,11 +34,11 @@ use libp2p_core::either::EitherError; use libp2p_core::{upgrade, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, - ListenUpgradeError, SendWrapper, + ListenUpgradeError, }; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, - IntoConnectionHandler, KeepAlive, NegotiatedSubstream, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use std::collections::VecDeque; use std::fmt; @@ -339,43 +338,6 @@ impl fmt::Debug for Event { } } -pub struct Prototype { - pub config: Config, -} - -impl IntoConnectionHandler for Prototype { - type Handler = Either; - - fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - if endpoint.is_relayed() { - // Deny all substreams on relayed connection. - Either::Right(dummy::ConnectionHandler) - } else { - Either::Left(Handler { - endpoint: endpoint.clone(), - config: self.config, - queued_events: Default::default(), - pending_error: Default::default(), - reservation_request_future: Default::default(), - circuit_accept_futures: Default::default(), - circuit_deny_futures: Default::default(), - alive_lend_out_substreams: Default::default(), - circuits: Default::default(), - active_reservation: Default::default(), - keep_alive: KeepAlive::Yes, - }) - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - upgrade::EitherUpgrade::A(SendWrapper(inbound_hop::Upgrade { - reservation_duration: self.config.reservation_duration, - max_circuit_duration: self.config.max_circuit_duration, - max_circuit_bytes: self.config.max_circuit_bytes, - })) - } -} - /// [`ConnectionHandler`] that manages substreams for a relay on a single /// connection with a peer. pub struct Handler { @@ -432,6 +394,22 @@ pub struct Handler { } impl Handler { + pub fn new(endpoint: ConnectedPoint, config: Config) -> Self { + Self { + endpoint, + config, + queued_events: Default::default(), + pending_error: Default::default(), + keep_alive: KeepAlive::Yes, + reservation_request_future: Default::default(), + active_reservation: Default::default(), + circuit_accept_futures: Default::default(), + circuit_deny_futures: Default::default(), + alive_lend_out_substreams: Default::default(), + circuits: Default::default(), + } + } + fn on_fully_negotiated_inbound( &mut self, FullyNegotiatedInbound { diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 3524c5052cb..83d889d79bb 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -35,7 +35,7 @@ use libp2p_core::{Multiaddr, PeerId, PeerRecord}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, THandlerInEvent, + PollParameters, THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, VecDeque}; use std::iter::FromIterator; @@ -187,7 +187,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer_id: PeerId, connection_id: ConnectionId, - event: handler::OutboundOutEvent, + event: THandlerOutEvent, ) { let new_events = match event { handler::OutboundOutEvent::InboundEvent { message, .. } => void::unreachable(message), diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 5563435b8bc..9418f885805 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -32,7 +32,7 @@ use libp2p_core::PeerId; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandlerInEvent, + THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::iter::FromIterator; @@ -122,7 +122,7 @@ impl NetworkBehaviour for Behaviour { &mut self, peer_id: PeerId, connection: ConnectionId, - event: handler::InboundOutEvent, + event: THandlerOutEvent, ) { let new_events = match event { handler::InboundOutEvent::InboundEvent { id, message } => { diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index ea24c7548fb..9f9a1133ae4 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -75,7 +75,7 @@ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandlerInEvent, + THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::{ @@ -773,8 +773,7 @@ where &mut self, peer: PeerId, connection: ConnectionId, - event: <::Handler as - libp2p_swarm::ConnectionHandler>::OutEvent, + event: THandlerOutEvent, ) { match event { handler::Event::Response { diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 6ec2263836e..1238e0570a1 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -28,7 +28,7 @@ pub use listen_addresses::ListenAddresses; use crate::dial_opts::DialOpts; use crate::handler::{ConnectionHandler, IntoConnectionHandler}; -use crate::{AddressRecord, AddressScore, DialError, THandler, THandlerInEvent}; +use crate::{AddressRecord, AddressScore, DialError, THandler, THandlerInEvent, THandlerOutEvent}; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId, }; @@ -253,7 +253,7 @@ pub trait NetworkBehaviour: 'static { &mut self, _peer_id: PeerId, _connection_id: ConnectionId, - _event: <::Handler as ConnectionHandler>::OutEvent, + _event: THandlerOutEvent, ) { } diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 13fcb6f7e05..a43c89d193d 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -22,8 +22,9 @@ use crate::behaviour::{ self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; use crate::handler::either::IntoEitherHandler; -use crate::THandlerInEvent; +use crate::{THandlerInEvent, THandlerOutEvent}; use either::Either; +use libp2p_core::connection::ConnectionId; use libp2p_core::{Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -73,7 +74,7 @@ where &mut self, peer_id: PeerId, connection_id: libp2p_core::connection::ConnectionId, - event: crate::THandlerOutEvent, + event: THandlerOutEvent, ) { match (self, event) { (Either::Left(left), Either::Left(event)) => { diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index f67e37bf599..fba069030b4 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -25,8 +25,11 @@ use crate::handler::{ KeepAlive, ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; -use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent}; +use crate::{ + NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, THandlerOutEvent, +}; use either::Either; +use libp2p_core::connection::ConnectionId; use libp2p_core::{ either::{EitherError, EitherOutput}, upgrade::{DeniedUpgrade, EitherUpgrade}, @@ -96,7 +99,7 @@ where &mut self, peer_id: PeerId, connection_id: libp2p_core::connection::ConnectionId, - event: crate::THandlerOutEvent, + event: THandlerOutEvent, ) { if let Some(behaviour) = &mut self.inner { #[allow(deprecated)] diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 2a9ec75bccb..0f3e2433bf8 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -3,7 +3,8 @@ use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; use crate::{ - ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandlerInEvent, + ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, + THandlerInEvent, THandlerOutEvent, }; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; @@ -23,7 +24,12 @@ impl NetworkBehaviour for Behaviour { ConnectionHandler } - fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + fn on_connection_handler_event( + &mut self, + _: PeerId, + _: ConnectionId, + event: THandlerOutEvent, + ) { void::unreachable(event) } diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index 7e2c822fb31..cc1415d00d9 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -3,7 +3,7 @@ use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, SubstreamProtocol, }; -use crate::THandlerInEvent; +use crate::{THandlerInEvent, THandlerOutEvent}; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::PeerId; @@ -27,7 +27,12 @@ impl NetworkBehaviour for Behaviour { ConnectionHandler } - fn on_connection_handler_event(&mut self, _: PeerId, _: ConnectionId, event: Void) { + fn on_connection_handler_event( + &mut self, + _: PeerId, + _: ConnectionId, + event: THandlerOutEvent, + ) { void::unreachable(event) } diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 476f9424020..fc795bfb6f7 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -24,7 +24,7 @@ use crate::behaviour::{ }; use crate::{ ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, THandlerInEvent, + PollParameters, THandlerInEvent, THandlerOutEvent, }; use libp2p_core::{ connection::ConnectionId, multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId, @@ -113,8 +113,7 @@ where &mut self, _peer_id: PeerId, _connection_id: ConnectionId, - _event: <::Handler as - ConnectionHandler>::OutEvent, + _event: THandlerOutEvent, ) { } } @@ -445,7 +444,7 @@ where &mut self, p: PeerId, c: ConnectionId, - e: <::Handler as ConnectionHandler>::OutEvent, + e: THandlerOutEvent, ) { assert!( self.on_connection_established diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 118b279bfc5..4f15e14eb6f 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -21,7 +21,9 @@ use futures::StreamExt; use libp2p_identify as identify; use libp2p_ping as ping; -use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent, THandlerInEvent}; +use libp2p_swarm::{ + behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent, THandlerInEvent, THandlerOutEvent, +}; use std::fmt::Debug; /// Small utility to check that a type implements `NetworkBehaviour`. @@ -392,7 +394,7 @@ fn custom_out_event_no_type_parameters() { &mut self, _peer: PeerId, _connection: ConnectionId, - message: <::Handler as ConnectionHandler>::OutEvent, + message: THandlerOutEvent, ) { void::unreachable(message); } From 03dd88f7570f9650a707c3f5d850a4760c3033c9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 12:33:08 +1100 Subject: [PATCH 032/177] Fix some deprecation warnings --- protocols/autonat/src/behaviour.rs | 4 ++-- protocols/gossipsub/src/behaviour.rs | 4 ++-- protocols/identify/src/behaviour.rs | 6 +++--- protocols/mdns/src/behaviour.rs | 5 ++--- protocols/request-response/src/lib.rs | 4 ++-- swarm/src/behaviour/either.rs | 1 - swarm/src/behaviour/toggle.rs | 1 - swarm/tests/swarm_derive.rs | 4 +--- 8 files changed, 12 insertions(+), 17 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index b3fba150a1f..929b9ede393 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -39,8 +39,8 @@ use libp2p_swarm::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, FromSwarm, }, - ConnectionHandler, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, PollParameters, THandlerInEvent, THandlerOutEvent, + ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, THandlerOutEvent, }; use std::{ collections::{HashMap, VecDeque}, diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 74419e2a99c..a3b12032878 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -42,8 +42,8 @@ use libp2p_core::{ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, dial_opts::DialOpts, - ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandlerInEvent, THandlerOutEvent, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + THandlerOutEvent, }; use wasm_timer::Instant; diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index d3f189a40de..f10c4b36a45 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -25,9 +25,9 @@ use libp2p_core::{ }; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::{ - dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, - ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, THandlerOutEvent, + dial_opts::DialOpts, AddressScore, ConnectionHandlerUpgrErr, DialError, ExternalAddresses, + ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandlerInEvent, THandlerOutEvent, }; use lru::LruCache; use std::num::NonZeroUsize; diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 969c91e1341..30a7d653223 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -27,12 +27,11 @@ use crate::behaviour::{socket::AsyncSocket, timer::Builder}; use crate::Config; use futures::Stream; use if_watch::IfEvent; -use libp2p_core::connection::ConnectionId; use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - dummy, ConnectionHandler, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, THandlerInEvent, THandlerOutEvent, + dummy, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 9f9a1133ae4..a0a917b2a0b 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -74,8 +74,8 @@ use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, - IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandlerInEvent, THandlerOutEvent, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + THandlerOutEvent, }; use smallvec::SmallVec; use std::{ diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index a43c89d193d..5651c61a1d8 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -24,7 +24,6 @@ use crate::behaviour::{ use crate::handler::either::IntoEitherHandler; use crate::{THandlerInEvent, THandlerOutEvent}; use either::Either; -use libp2p_core::connection::ConnectionId; use libp2p_core::{Multiaddr, PeerId}; use std::{task::Context, task::Poll}; diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index fba069030b4..c784b40c251 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -29,7 +29,6 @@ use crate::{ NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, THandlerOutEvent, }; use either::Either; -use libp2p_core::connection::ConnectionId; use libp2p_core::{ either::{EitherError, EitherOutput}, upgrade::{DeniedUpgrade, EitherUpgrade}, diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 4f15e14eb6f..10f995e5f1f 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -372,9 +372,7 @@ fn generated_out_event_derive_debug() { fn custom_out_event_no_type_parameters() { use libp2p_core::connection::ConnectionId; use libp2p_core::PeerId; - use libp2p_swarm::{ - ConnectionHandler, IntoConnectionHandler, NetworkBehaviourAction, PollParameters, - }; + use libp2p_swarm::{NetworkBehaviourAction, PollParameters}; use std::task::Context; use std::task::Poll; From 760604fd4d09f1124e7d72625608bc6385516030 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 12:37:41 +1100 Subject: [PATCH 033/177] Fix some deprecation warnings kad --- protocols/kad/src/behaviour.rs | 57 ++++++++++++++++++++++++++++------ protocols/kad/src/handler.rs | 37 ++-------------------- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 5405b537726..ec8bbf322d9 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -24,7 +24,7 @@ mod test; use crate::addresses::Addresses; use crate::handler::{ - KademliaHandlerConfig, KademliaHandlerEvent, KademliaHandlerIn, KademliaHandlerProto, + KademliaHandler, KademliaHandlerConfig, KademliaHandlerEvent, KademliaHandlerIn, KademliaRequestId, }; use crate::jobs::*; @@ -39,18 +39,19 @@ use crate::record::{ use crate::K_VALUE; use fnv::{FnvHashMap, FnvHashSet}; use instant::Instant; -use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; +use libp2p_core::{connection::ConnectionId, ConnectedPoint, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm, }; use libp2p_swarm::{ dial_opts::{self, DialOpts}, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandlerInEvent, THandlerOutEvent, + NotifyHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use log::{debug, info, warn}; use smallvec::SmallVec; use std::collections::{BTreeMap, HashSet, VecDeque}; +use std::error::Error; use std::fmt; use std::num::NonZeroUsize; use std::task::{Context, Poll}; @@ -1985,15 +1986,53 @@ impl NetworkBehaviour for Kademlia where TStore: RecordStore + Send + 'static, { - type ConnectionHandler = KademliaHandlerProto; + type ConnectionHandler = KademliaHandler; 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, - }) + unreachable!("We override the new callbacks!") + } + + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + _: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { + Ok(KademliaHandler::new( + KademliaHandlerConfig { + protocol_config: self.protocol_config.clone(), + allow_listening: true, + idle_timeout: self.connection_idle_timeout, + }, + ConnectedPoint::Listener { + local_addr: local_addr.clone(), + send_back_addr: remote_addr.clone(), + }, + peer, + )) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(KademliaHandler::new( + KademliaHandlerConfig { + protocol_config: self.protocol_config.clone(), + allow_listening: true, + idle_timeout: self.connection_idle_timeout, + }, + ConnectedPoint::Dialer { + address: addr.clone(), + role_override, + }, + peer, + )) } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { diff --git a/protocols/kad/src/handler.rs b/protocols/kad/src/handler.rs index 37f41a8cd8a..c9c7db0e1fa 100644 --- a/protocols/kad/src/handler.rs +++ b/protocols/kad/src/handler.rs @@ -31,8 +31,8 @@ use libp2p_swarm::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, NegotiatedSubstream, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use log::trace; use std::task::Waker; @@ -42,39 +42,6 @@ use std::{ const MAX_NUM_INBOUND_SUBSTREAMS: usize = 32; -/// A prototype from which [`KademliaHandler`]s can be constructed. -pub struct KademliaHandlerProto { - config: KademliaHandlerConfig, - _type: PhantomData, -} - -impl KademliaHandlerProto { - pub fn new(config: KademliaHandlerConfig) -> Self { - KademliaHandlerProto { - config, - _type: PhantomData, - } - } -} - -impl IntoConnectionHandler - for KademliaHandlerProto -{ - type Handler = KademliaHandler; - - fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - KademliaHandler::new(self.config, endpoint.clone(), *remote_peer_id) - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - if self.config.allow_listening { - upgrade::EitherUpgrade::A(self.config.protocol_config.clone()) - } else { - upgrade::EitherUpgrade::B(upgrade::DeniedUpgrade) - } - } -} - /// Protocol handler that manages substreams for the Kademlia protocol /// on a single connection with a peer. /// From 87ad92b4c7ecbeb8f6205dba338eadf9b291c1a5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 12:40:01 +1100 Subject: [PATCH 034/177] Port autonat --- protocols/autonat/src/behaviour.rs | 58 +++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 929b9ede393..8aaba19d6e1 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -40,8 +40,9 @@ use libp2p_swarm::{ ExpiredListenAddr, FromSwarm, }, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerInEvent, THandlerOutEvent, + THandler, THandlerInEvent, THandlerOutEvent, }; +use std::error::Error; use std::{ collections::{HashMap, VecDeque}, iter, @@ -476,12 +477,59 @@ impl NetworkBehaviour for Behaviour { } } - fn new_handler(&mut self) -> Self::ConnectionHandler { - self.inner.new_handler() + fn handle_pending_inbound_connection( + &mut self, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result<(), Box> { + self.inner + .handle_pending_inbound_connection(connection_id, local_addr, remote_addr) + } + + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { + self.inner.handle_established_inbound_connection( + peer, + connection_id, + local_addr, + remote_addr, + ) + } + + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + addresses: &[Multiaddr], + effective_role: Endpoint, + connection_id: ConnectionId, + ) -> Result, Box> { + self.inner.handle_pending_outbound_connection( + maybe_peer, + addresses, + effective_role, + connection_id, + ) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + connection_id: ConnectionId, + ) -> Result, Box> { + self.inner + .handle_established_outbound_connection(peer, addr, role_override, connection_id) } - fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { - self.inner.addresses_of_peer(peer) + fn new_handler(&mut self) -> Self::ConnectionHandler { + unreachable!("We override the new callbacks.") } fn on_swarm_event(&mut self, event: FromSwarm) { From 6f5a2c8b960d101eae51f9d48492ba6d3be41d71 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 12:44:53 +1100 Subject: [PATCH 035/177] Port identify --- protocols/identify/src/behaviour.rs | 53 +++++++++++++++++++++------ protocols/identify/src/handler.rs | 57 ++--------------------------- 2 files changed, 45 insertions(+), 65 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index f10c4b36a45..a92fd8a7ef2 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -18,18 +18,19 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::handler::{self, InEvent, Proto}; +use crate::handler::{self, Handler, InEvent}; use crate::protocol::{Info, Protocol, UpgradeError}; use libp2p_core::{ - connection::ConnectionId, multiaddr, ConnectedPoint, Multiaddr, PeerId, PublicKey, + connection::ConnectionId, multiaddr, ConnectedPoint, Endpoint, Multiaddr, PeerId, PublicKey, }; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandlerUpgrErr, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandlerInEvent, THandlerOutEvent, + THandler, THandlerInEvent, THandlerOutEvent, }; use lru::LruCache; +use std::error::Error; use std::num::NonZeroUsize; use std::{ collections::{HashMap, HashSet, VecDeque}, @@ -236,17 +237,11 @@ impl Behaviour { } impl NetworkBehaviour for Behaviour { - type ConnectionHandler = Proto; + type ConnectionHandler = Handler; type OutEvent = Event; fn new_handler(&mut self) -> Self::ConnectionHandler { - Proto::new( - self.config.initial_delay, - self.config.interval, - self.config.local_public_key.clone(), - self.config.protocol_version.clone(), - self.config.agent_version.clone(), - ) + unreachable!("We override the new callbacks") } fn on_connection_handler_event( @@ -428,6 +423,42 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredExternalAddr(_) => {} } } + + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + _: ConnectionId, + _: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { + Ok(Handler::new( + self.config.initial_delay, + self.config.interval, + peer, + self.config.local_public_key.clone(), + self.config.protocol_version.clone(), + self.config.agent_version.clone(), + remote_addr.clone(), + )) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(Handler::new( + self.config.initial_delay, + self.config.interval, + peer, + self.config.local_public_key.clone(), + self.config.protocol_version.clone(), + self.config.agent_version.clone(), + addr.clone(), // TODO: This is weird? That is the public address we dialed, shouldn't need to tell the other party? + )) + } } /// Event emitted by the `Identify` behaviour. diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index 21063acc661..9e69c665b1c 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -27,70 +27,19 @@ use futures::stream::FuturesUnordered; use futures_timer::Delay; use libp2p_core::either::{EitherError, EitherOutput}; use libp2p_core::upgrade::{EitherUpgrade, SelectUpgrade}; -use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, PublicKey}; +use libp2p_core::{Multiaddr, PeerId, PublicKey}; use libp2p_swarm::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, - KeepAlive, NegotiatedSubstream, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use log::warn; use smallvec::SmallVec; use std::collections::VecDeque; use std::{io, pin::Pin, task::Context, task::Poll, time::Duration}; -pub struct Proto { - initial_delay: Duration, - interval: Duration, - public_key: PublicKey, - protocol_version: String, - agent_version: String, -} - -impl Proto { - pub fn new( - initial_delay: Duration, - interval: Duration, - public_key: PublicKey, - protocol_version: String, - agent_version: String, - ) -> Self { - Proto { - initial_delay, - interval, - public_key, - protocol_version, - agent_version, - } - } -} - -impl IntoConnectionHandler for Proto { - type Handler = Handler; - - fn into_handler(self, remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - let observed_addr = match endpoint { - ConnectedPoint::Dialer { address, .. } => address, - ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr, - }; - - Handler::new( - self.initial_delay, - self.interval, - *remote_peer_id, - self.public_key, - self.protocol_version, - self.agent_version, - observed_addr.clone(), - ) - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - SelectUpgrade::new(Identify, Push::inbound()) - } -} - /// Protocol handler for sending and receiving identification requests. /// /// Outbound requests are sent periodically. The handler performs expects From e455317c4e63633c7cc4f5949c084c3abdee5da4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 13:29:30 +1100 Subject: [PATCH 036/177] Fix more deprecation warnings --- protocols/autonat/src/behaviour.rs | 4 - protocols/dcutr/src/behaviour_impl.rs | 5 - protocols/floodsub/src/layer.rs | 24 +++- protocols/gossipsub/src/behaviour.rs | 46 ++++++-- protocols/identify/src/behaviour.rs | 4 - protocols/kad/src/behaviour.rs | 4 - protocols/mdns/src/behaviour.rs | 55 ++++++--- protocols/ping/src/lib.rs | 65 +++++++---- protocols/relay/src/v2/client.rs | 4 - protocols/relay/src/v2/relay.rs | 4 - protocols/rendezvous/src/client.rs | 88 ++++++++++----- protocols/rendezvous/src/server.rs | 28 ++++- protocols/request-response/src/lib.rs | 53 +++++++-- swarm/src/behaviour.rs | 5 +- swarm/src/behaviour/either.rs | 100 ++++++++++++++-- swarm/src/behaviour/external_addresses.rs | 4 +- swarm/src/behaviour/listen_addresses.rs | 4 +- swarm/src/behaviour/toggle.rs | 132 ++++++++++++++-------- swarm/src/dummy.rs | 48 +++++--- swarm/src/handler.rs | 1 + swarm/src/handler/either.rs | 63 +---------- swarm/src/handler/select.rs | 12 +- swarm/src/keep_alive.rs | 25 +++- 23 files changed, 513 insertions(+), 265 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 8aaba19d6e1..1df90c92a83 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -528,10 +528,6 @@ impl NetworkBehaviour for Behaviour { .handle_established_outbound_connection(peer, addr, role_override, connection_id) } - fn new_handler(&mut self) -> Self::ConnectionHandler { - unreachable!("We override the new callbacks.") - } - fn on_swarm_event(&mut self, event: FromSwarm) { self.listen_addresses.on_swarm_event(&event); self.external_addresses.on_swarn_event(&event); diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 4ca33ffea3c..e60333c7ab5 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -200,11 +200,6 @@ impl NetworkBehaviour for Behaviour { Either>; type OutEvent = Event; - #[allow(deprecated)] - fn new_handler(&mut self) -> Self::ConnectionHandler { - unreachable!("We override the new callbacks.") - } - fn handle_established_inbound_connection( &mut self, _peer: PeerId, diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 0f7d598c3ed..60103f438a3 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -26,11 +26,11 @@ use crate::topic::Topic; use crate::FloodsubConfig; use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; -use libp2p_core::{connection::ConnectionId, PeerId}; +use libp2p_core::{connection::ConnectionId, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, - PollParameters, THandlerInEvent, THandlerOutEvent, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use log::warn; use smallvec::SmallVec; @@ -336,8 +336,24 @@ impl NetworkBehaviour for Floodsub { type ConnectionHandler = OneShotHandler; type OutEvent = FloodsubEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { - Default::default() + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> std::result::Result, Box> { + Ok(Default::default()) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> std::result::Result, Box> { + Ok(Default::default()) } fn on_connection_handler_event( diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index a3b12032878..3fcebf722c8 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -37,13 +37,13 @@ use rand::{seq::SliceRandom, thread_rng}; use libp2p_core::{ connection::ConnectionId, identity::Keypair, multiaddr::Protocol::Ip4, - multiaddr::Protocol::Ip6, Multiaddr, PeerId, + multiaddr::Protocol::Ip6, Endpoint, Multiaddr, PeerId, }; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, dial_opts::DialOpts, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, - THandlerOutEvent, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, + THandlerInEvent, THandlerOutEvent, }; use wasm_timer::Instant; @@ -2226,7 +2226,7 @@ where let score_p1 = *scores.get(p1).unwrap_or(&0.0); let score_p2 = *scores.get(p2).unwrap_or(&0.0); - score_p1.partial_cmp(&score_p2).unwrap_or(Ordering::Equal) + score_p1.partial_cmp(&score_p2).unwrap_or(Equal) }); // shuffle everything except the last retain_scores many peers (the best ones) shuffled[..peers.len() - self.config.retain_scores()].shuffle(&mut rng); @@ -3297,7 +3297,34 @@ where type ConnectionHandler = GossipsubHandler; type OutEvent = GossipsubEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, Box> { + 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(), + ); + + Ok(GossipsubHandler::new( + protocol_config, + self.config.idle_timeout(), + )) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), @@ -3306,7 +3333,10 @@ where self.config.support_floodsub(), ); - GossipsubHandler::new(protocol_config, self.config.idle_timeout()) + Ok(GossipsubHandler::new( + protocol_config, + self.config.idle_timeout(), + )) } fn on_connection_handler_event( @@ -3646,7 +3676,7 @@ fn validate_config( Ok(()) } -impl fmt::Debug for Gossipsub { +impl Debug for Gossipsub { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Gossipsub") .field("config", &self.config) @@ -3664,7 +3694,7 @@ impl fmt::Debug for Gossipsub) -> fmt::Result { match self { PublishConfig::Signing { author, .. } => { diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index a92fd8a7ef2..a474746168b 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -240,10 +240,6 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - unreachable!("We override the new callbacks") - } - fn on_connection_handler_event( &mut self, peer_id: PeerId, diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index ec8bbf322d9..370622b23a0 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1989,10 +1989,6 @@ where type ConnectionHandler = KademliaHandler; type OutEvent = KademliaEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { - unreachable!("We override the new callbacks!") - } - fn handle_established_inbound_connection( &mut self, peer: PeerId, diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 30a7d653223..f509a8000f8 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -27,14 +27,16 @@ use crate::behaviour::{socket::AsyncSocket, timer::Builder}; use crate::Config; use futures::Stream; use if_watch::IfEvent; -use libp2p_core::{Multiaddr, PeerId}; +use libp2p_core::connection::ConnectionId; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - dummy, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + dummy, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; +use std::error::Error; use std::{cmp, fmt, io, net::IpAddr, pin::Pin, task::Context, task::Poll, time::Instant}; /// An abstraction to allow for compatibility with various async runtimes. @@ -174,25 +176,43 @@ where type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - dummy::ConnectionHandler + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, Box> { + Ok(dummy::ConnectionHandler) } - fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { - self.discovered_nodes + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + _addresses: &[Multiaddr], + _effective_role: Endpoint, + _connection_id: ConnectionId, + ) -> Result, Box> { + let Some(peer_id) = maybe_peer else { + return Ok(vec![]) + }; + + Ok(self + .discovered_nodes .iter() - .filter(|(peer, _, _)| peer == peer_id) + .filter(|(peer, _, _)| peer == &peer_id) .map(|(_, addr, _)| addr.clone()) - .collect() + .collect()) } - fn on_connection_handler_event( + fn handle_established_outbound_connection( &mut self, _: PeerId, - _: libp2p_core::connection::ConnectionId, - ev: THandlerOutEvent, - ) { - void::unreachable(ev) + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(dummy::ConnectionHandler) } fn on_swarm_event(&mut self, event: FromSwarm) { @@ -227,6 +247,15 @@ where } } + fn on_connection_handler_event( + &mut self, + _: PeerId, + _: libp2p_core::connection::ConnectionId, + ev: THandlerOutEvent, + ) { + void::unreachable(ev) + } + fn poll( &mut self, cx: &mut Context<'_>, diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index e163386faa7..e54c7205ff7 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -47,11 +47,12 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; -use libp2p_core::{connection::ConnectionId, PeerId}; +use libp2p_core::{connection::ConnectionId, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::{ - behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; +use std::error::Error; use std::{ collections::VecDeque, task::{Context, Poll}, @@ -120,8 +121,44 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - Handler::new(self.config.clone()) + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> std::result::Result, Box> { + Ok(Handler::new(self.config.clone())) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> std::result::Result, Box> { + Ok(Handler::new(self.config.clone())) + } + + 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(_) => {} + } } fn on_connection_handler_event( @@ -152,24 +189,4 @@ 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/src/v2/client.rs b/protocols/relay/src/v2/client.rs index 63d0e4c3fd5..abc803298a4 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -155,10 +155,6 @@ impl NetworkBehaviour for Client { type ConnectionHandler = Either; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - unreachable!("We override the new callbacks.") - } - fn handle_established_inbound_connection( &mut self, peer: PeerId, diff --git a/protocols/relay/src/v2/relay.rs b/protocols/relay/src/v2/relay.rs index 2eda7043d8c..1ca087edea0 100644 --- a/protocols/relay/src/v2/relay.rs +++ b/protocols/relay/src/v2/relay.rs @@ -257,10 +257,6 @@ impl NetworkBehaviour for Relay { type ConnectionHandler = Either; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - unreachable!("We override the new callbacks.") - } - fn handle_established_inbound_connection( &mut self, _peer: PeerId, diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 83d889d79bb..f32fbdbd001 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -31,13 +31,14 @@ use instant::Duration; use libp2p_core::connection::ConnectionId; use libp2p_core::identity::error::SigningError; use libp2p_core::identity::Keypair; -use libp2p_core::{Multiaddr, PeerId, PeerRecord}; +use libp2p_core::{Endpoint, Multiaddr, PeerId, PeerRecord}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, THandlerInEvent, THandlerOutEvent, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, VecDeque}; +use std::error::Error; use std::iter::FromIterator; use std::task::{Context, Poll}; @@ -168,19 +169,67 @@ impl NetworkBehaviour for Behaviour { SubstreamConnectionHandler; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - let initial_keep_alive = Duration::from_secs(30); - - SubstreamConnectionHandler::new_outbound_only(initial_keep_alive) + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, Box> { + Ok(SubstreamConnectionHandler::new_outbound_only( + Duration::from_secs(30), + )) } - fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { - self.discovered_peers + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + _addresses: &[Multiaddr], + _effective_role: Endpoint, + _connection_id: ConnectionId, + ) -> Result, Box> { + let Some(peer) = maybe_peer else { + return Ok(vec![]) + }; + + Ok(self + .discovered_peers .iter() - .filter_map(|((candidate, _), addresses)| (candidate == peer).then_some(addresses)) + .filter_map(|((candidate, _), addresses)| (candidate == &peer).then_some(addresses)) .flatten() .cloned() - .collect() + .collect()) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(SubstreamConnectionHandler::new_outbound_only( + Duration::from_secs(30), + )) + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + self.external_addresses.on_swarn_event(&event); + + 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( @@ -263,25 +312,6 @@ impl NetworkBehaviour for Behaviour { Poll::Pending } - - fn on_swarm_event(&mut self, event: FromSwarm) { - self.external_addresses.on_swarn_event(&event); - - 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 9418f885805..a83d25d0595 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -28,11 +28,11 @@ use futures::ready; use futures::stream::FuturesUnordered; use futures::{FutureExt, StreamExt}; use libp2p_core::connection::ConnectionId; -use libp2p_core::PeerId; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandlerInEvent, THandlerOutEvent, + THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::iter::FromIterator; @@ -112,10 +112,28 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - let initial_keep_alive = Duration::from_secs(30); + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, Box> { + Ok(SubstreamConnectionHandler::new_inbound_only( + Duration::from_secs(30), + )) + } - SubstreamConnectionHandler::new_inbound_only(initial_keep_alive) + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(SubstreamConnectionHandler::new_inbound_only( + Duration::from_secs(30), + )) } fn on_connection_handler_event( diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index a0a917b2a0b..65655642d10 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -70,12 +70,12 @@ pub use handler::ProtocolSupport; use futures::channel::oneshot; use handler::{Handler, RequestProtocol}; -use libp2p_core::{connection::ConnectionId, ConnectedPoint, Multiaddr, PeerId}; +use libp2p_core::{connection::ConnectionId, ConnectedPoint, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, - THandlerOutEvent, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, + THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::{ @@ -727,25 +727,58 @@ where type ConnectionHandler = Handler; type OutEvent = Event; - fn new_handler(&mut self) -> Self::ConnectionHandler { - Handler::new( + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, Box> { + Ok(Handler::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 { + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + _addresses: &[Multiaddr], + _effective_role: Endpoint, + _connection_id: ConnectionId, + ) -> Result, Box> { + let Some(peer) = maybe_peer else { + return Ok(vec![]) + }; + let mut addresses = Vec::new(); - if let Some(connections) = self.connected.get(peer) { + 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) { + if let Some(more) = self.addresses.get(&peer) { addresses.extend(more.into_iter().cloned()); } - addresses + + Ok(addresses) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(Handler::new( + self.inbound_protocols.clone(), + self.codec.clone(), + self.config.connection_keep_alive, + self.config.request_timeout, + self.next_inbound_id.clone(), + )) } fn on_swarm_event(&mut self, event: FromSwarm) { diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 1238e0570a1..fc5651fcbf9 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -140,9 +140,12 @@ pub trait NetworkBehaviour: 'static { // /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and // /// connection closing. #[deprecated( + since = "0.42.0", note = "Use one or more of `NetworkBehaviour::{handle_pending_inbound_connection,handle_established_inbound_connection,handle_pending_outbound_connection,handle_established_outbound_connection}` instead." )] - fn new_handler(&mut self) -> Self::ConnectionHandler; + fn new_handler(&mut self) -> Self::ConnectionHandler { + panic!("You must implement `handle_established_inbound_connection` and `handle_established_outbound_connection`.") + } /// Callback that is invoked for every new inbound connection. /// diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 5651c61a1d8..ca3d314238e 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -21,10 +21,11 @@ use crate::behaviour::{ self, inject_from_swarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, }; -use crate::handler::either::IntoEitherHandler; -use crate::{THandlerInEvent, THandlerOutEvent}; +use crate::{THandler, THandlerInEvent, THandlerOutEvent}; use either::Either; -use libp2p_core::{Multiaddr, PeerId}; +use libp2p_core::connection::ConnectionId; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; +use std::error::Error; use std::{task::Context, task::Poll}; /// Implementation of [`NetworkBehaviour`] that can be either of two implementations. @@ -33,20 +34,99 @@ where L: NetworkBehaviour, R: NetworkBehaviour, { - type ConnectionHandler = IntoEitherHandler; + type ConnectionHandler = Either, THandler>; type OutEvent = Either; - fn new_handler(&mut self) -> Self::ConnectionHandler { + fn handle_pending_inbound_connection( + &mut self, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result<(), Box> { + match self { + Either::Left(inner) => { + inner.handle_pending_inbound_connection(connection_id, local_addr, remote_addr)? + } + Either::Right(inner) => { + inner.handle_pending_inbound_connection(connection_id, local_addr, remote_addr)? + } + }; + + Ok(()) + } + + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { match self { - Either::Left(a) => IntoEitherHandler::Left(a.new_handler()), - Either::Right(b) => IntoEitherHandler::Right(b.new_handler()), + Either::Left(inner) => Ok(Either::Left(inner.handle_established_inbound_connection( + peer, + connection_id, + local_addr, + remote_addr, + )?)), + Either::Right(inner) => { + Ok(Either::Right(inner.handle_established_inbound_connection( + peer, + connection_id, + local_addr, + remote_addr, + )?)) + } } } - fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + addresses: &[Multiaddr], + effective_role: Endpoint, + connection_id: ConnectionId, + ) -> Result, Box> { + let addresses = match self { + Either::Left(inner) => inner.handle_pending_outbound_connection( + maybe_peer, + addresses, + effective_role, + connection_id, + )?, + Either::Right(inner) => inner.handle_pending_outbound_connection( + maybe_peer, + addresses, + effective_role, + connection_id, + )?, + }; + + Ok(addresses) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + connection_id: ConnectionId, + ) -> Result, Box> { match self { - Either::Left(a) => a.addresses_of_peer(peer_id), - Either::Right(b) => b.addresses_of_peer(peer_id), + Either::Left(inner) => Ok(Either::Left(inner.handle_established_outbound_connection( + peer, + addr, + role_override, + connection_id, + )?)), + Either::Right(inner) => Ok(Either::Right( + inner.handle_established_outbound_connection( + peer, + addr, + role_override, + connection_id, + )?, + )), } } diff --git a/swarm/src/behaviour/external_addresses.rs b/swarm/src/behaviour/external_addresses.rs index 0ce07962e7e..5e221a004b8 100644 --- a/swarm/src/behaviour/external_addresses.rs +++ b/swarm/src/behaviour/external_addresses.rs @@ -1,5 +1,4 @@ use crate::behaviour::{ExpiredExternalAddr, FromSwarm, NewExternalAddr}; -use crate::IntoConnectionHandler; use libp2p_core::Multiaddr; use std::collections::HashSet; @@ -31,9 +30,10 @@ impl ExternalAddresses { } /// Feed a [`FromSwarm`] event to this struct. + #[allow(deprecated)] pub fn on_swarn_event(&mut self, event: &FromSwarm) where - THandler: IntoConnectionHandler, + THandler: crate::IntoConnectionHandler, { match event { FromSwarm::NewExternalAddr(NewExternalAddr { addr, .. }) => { diff --git a/swarm/src/behaviour/listen_addresses.rs b/swarm/src/behaviour/listen_addresses.rs index 37a7d05d12c..855c7ea76a5 100644 --- a/swarm/src/behaviour/listen_addresses.rs +++ b/swarm/src/behaviour/listen_addresses.rs @@ -1,5 +1,4 @@ use crate::behaviour::{ExpiredListenAddr, FromSwarm, NewListenAddr}; -use crate::IntoConnectionHandler; use libp2p_core::Multiaddr; use std::collections::HashSet; @@ -16,9 +15,10 @@ impl ListenAddresses { } /// Feed a [`FromSwarm`] event to this struct. + #[allow(deprecated)] pub fn on_swarm_event(&mut self, event: &FromSwarm) where - THandler: IntoConnectionHandler, + THandler: crate::IntoConnectionHandler, { match event { FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => { diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index c784b40c251..a7e90ed1ed6 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -21,19 +21,22 @@ use crate::behaviour::{inject_from_swarm, FromSwarm}; use crate::handler::{ ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, - DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, IntoConnectionHandler, - KeepAlive, ListenUpgradeError, SubstreamProtocol, + DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, + ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; use crate::{ - NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, THandlerOutEvent, + NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, + THandlerOutEvent, }; use either::Either; +use libp2p_core::connection::ConnectionId; use libp2p_core::{ either::{EitherError, EitherOutput}, upgrade::{DeniedUpgrade, EitherUpgrade}, - ConnectedPoint, Multiaddr, PeerId, + Endpoint, Multiaddr, PeerId, }; +use std::error::Error; use std::{task::Context, task::Poll}; /// Implementation of `NetworkBehaviour` that can be either in the disabled or enabled state. @@ -70,20 +73,89 @@ impl NetworkBehaviour for Toggle where TBehaviour: NetworkBehaviour, { - type ConnectionHandler = ToggleIntoConnectionHandler; + type ConnectionHandler = ToggleConnectionHandler>; type OutEvent = TBehaviour::OutEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { - ToggleIntoConnectionHandler { - inner: self.inner.as_mut().map(|i| i.new_handler()), - } + fn handle_pending_inbound_connection( + &mut self, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result<(), Box> { + let Some(inner) = self.inner.as_mut() else { + return Ok(()) + }; + + inner.handle_pending_inbound_connection(connection_id, local_addr, remote_addr)?; + + Ok(()) } - fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { - self.inner - .as_mut() - .map(|b| b.addresses_of_peer(peer_id)) - .unwrap_or_else(Vec::new) + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, Box> { + let Some(inner) = self.inner.as_mut() else { + return Ok(ToggleConnectionHandler { inner: None }) + }; + + let handler = inner.handle_established_inbound_connection( + peer, + connection_id, + local_addr, + remote_addr, + )?; + + Ok(ToggleConnectionHandler { + inner: Some(handler), + }) + } + + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + addresses: &[Multiaddr], + effective_role: Endpoint, + connection_id: ConnectionId, + ) -> Result, Box> { + let Some(inner) = self.inner.as_mut() else { + return Ok(vec![]) + }; + + let addresses = inner.handle_pending_outbound_connection( + maybe_peer, + addresses, + effective_role, + connection_id, + )?; + + Ok(addresses) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + connection_id: ConnectionId, + ) -> Result, Box> { + let Some(inner) = self.inner.as_mut() else { + return Ok(ToggleConnectionHandler { inner: None }) + }; + + let handler = inner.handle_established_outbound_connection( + peer, + addr, + role_override, + connection_id, + )?; + + Ok(ToggleConnectionHandler { + inner: Some(handler), + }) } fn on_swarm_event(&mut self, event: FromSwarm) { @@ -119,38 +191,6 @@ where } } -/// Implementation of `IntoConnectionHandler` that can be in the disabled state. -pub struct ToggleIntoConnectionHandler { - inner: Option, -} - -impl IntoConnectionHandler for ToggleIntoConnectionHandler -where - TInner: IntoConnectionHandler, -{ - type Handler = ToggleConnectionHandler; - - fn into_handler( - self, - remote_peer_id: &PeerId, - connected_point: &ConnectedPoint, - ) -> Self::Handler { - ToggleConnectionHandler { - inner: self - .inner - .map(|h| h.into_handler(remote_peer_id, connected_point)), - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - if let Some(inner) = self.inner.as_ref() { - EitherUpgrade::A(SendWrapper(inner.inbound_protocol())) - } else { - EitherUpgrade::B(SendWrapper(DeniedUpgrade)) - } - } -} - /// Implementation of [`ConnectionHandler`] that can be in the disabled state. pub struct ToggleConnectionHandler { inner: Option, diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 0f3e2433bf8..f813d00db4d 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,15 +1,17 @@ use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::derive_prelude::Multiaddr; use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; use crate::{ - ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, + ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandler, THandlerInEvent, THandlerOutEvent, }; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; -use libp2p_core::PeerId; use libp2p_core::UpgradeError; +use libp2p_core::{Endpoint, PeerId}; +use std::error::Error; use std::task::{Context, Poll}; use void::Void; @@ -20,25 +22,24 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; - fn new_handler(&mut self) -> Self::ConnectionHandler { - ConnectionHandler - } - - fn on_connection_handler_event( + fn handle_established_inbound_connection( &mut self, _: PeerId, _: ConnectionId, - event: THandlerOutEvent, - ) { - void::unreachable(event) + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, Box> { + Ok(ConnectionHandler) } - fn poll( + fn handle_established_outbound_connection( &mut self, - _: &mut Context<'_>, - _: &mut impl PollParameters, - ) -> Poll>> { - Poll::Pending + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(ConnectionHandler) } fn on_swarm_event(&mut self, event: FromSwarm) { @@ -57,6 +58,23 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredExternalAddr(_) => {} } } + + fn on_connection_handler_event( + &mut self, + _: PeerId, + _: ConnectionId, + event: THandlerOutEvent, + ) { + void::unreachable(event) + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> { + Poll::Pending + } } /// An implementation of [`ConnectionHandler`] that neither handles any protocols nor does it keep the connection alive. diff --git a/swarm/src/handler.rs b/swarm/src/handler.rs index 5ce819f58b4..e44563852df 100644 --- a/swarm/src/handler.rs +++ b/swarm/src/handler.rs @@ -612,6 +612,7 @@ pub trait IntoConnectionHandler: Send + 'static { } } +#[allow(deprecated)] impl IntoConnectionHandler for T where T: ConnectionHandler, diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index e6d16ed1133..176de7202af 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -21,75 +21,14 @@ use crate::handler::{ AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, - IntoConnectionHandler, KeepAlive, ListenUpgradeError, SubstreamProtocol, + KeepAlive, ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; use either::Either; use libp2p_core::either::{EitherError, EitherOutput}; use libp2p_core::upgrade::{EitherUpgrade, UpgradeError}; -use libp2p_core::{ConnectedPoint, 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), -} - -/// Implementation of a [`IntoConnectionHandler`] that represents either of two [`IntoConnectionHandler`] -/// implementations. -impl IntoConnectionHandler for IntoEitherHandler -where - L: IntoConnectionHandler, - R: IntoConnectionHandler, -{ - type Handler = Either; - - fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler { - match self { - IntoEitherHandler::Left(into_handler) => Either::Left(into_handler.into_handler(p, c)), - IntoEitherHandler::Right(into_handler) => { - Either::Right(into_handler.into_handler(p, c)) - } - } - } - - fn inbound_protocol(&self) -> ::InboundProtocol { - match self { - IntoEitherHandler::Left(into_handler) => { - EitherUpgrade::A(SendWrapper(into_handler.inbound_protocol())) - } - IntoEitherHandler::Right(into_handler) => { - EitherUpgrade::B(SendWrapper(into_handler.inbound_protocol())) - } - } - } -} - -// 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/handler/select.rs b/swarm/src/handler/select.rs index 65508c0b6a5..2338f40d866 100644 --- a/swarm/src/handler/select.rs +++ b/swarm/src/handler/select.rs @@ -20,8 +20,8 @@ use crate::handler::{ ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, - DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, IntoConnectionHandler, - KeepAlive, ListenUpgradeError, SubstreamProtocol, + DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, + ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; @@ -52,10 +52,12 @@ impl IntoConnectionHandlerSelect { } } -impl IntoConnectionHandler for IntoConnectionHandlerSelect +#[allow(deprecated)] +impl crate::handler::IntoConnectionHandler + for IntoConnectionHandlerSelect where - TProto1: IntoConnectionHandler, - TProto2: IntoConnectionHandler, + TProto1: crate::handler::IntoConnectionHandler, + TProto2: crate::handler::IntoConnectionHandler, { type Handler = ConnectionHandlerSelect; diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index cc1415d00d9..7358465f93c 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -3,10 +3,11 @@ use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, SubstreamProtocol, }; -use crate::{THandlerInEvent, THandlerOutEvent}; +use crate::{THandler, THandlerInEvent, THandlerOutEvent}; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; -use libp2p_core::PeerId; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; +use std::error::Error; use std::task::{Context, Poll}; use void::Void; @@ -23,8 +24,24 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; type OutEvent = Void; - fn new_handler(&mut self) -> Self::ConnectionHandler { - ConnectionHandler + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, Box> { + Ok(ConnectionHandler) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, Box> { + Ok(ConnectionHandler) } fn on_connection_handler_event( From 912f35daaece6d560b1fe7b003c4807589025825 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 13:29:38 +1100 Subject: [PATCH 037/177] Ignore clippy warning --- swarm/src/connection/pool.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index ec8c7f7ff81..0f9d4a951d1 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -212,6 +212,7 @@ where /// Event that can happen on the `Pool`. #[derive(Debug)] +#[allow(clippy::large_enum_variant)] pub enum PoolEvent where THandler: ConnectionHandler, From c5cbfbdc0f21e3ecc525dcc5eea99cdc9fa84a0b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 13:58:32 +1100 Subject: [PATCH 038/177] Fix derive and remove todo --- swarm-derive/src/lib.rs | 140 ++++++++++++++++++++++++++++------- swarm/src/connection/pool.rs | 11 ++- swarm/src/lib.rs | 5 +- 3 files changed, 126 insertions(+), 30 deletions(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index bb1636018a6..ba5bae9948d 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -57,7 +57,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let network_behaviour_action = quote! { #prelude_path::NetworkBehaviourAction }; let into_connection_handler = quote! { #prelude_path::IntoConnectionHandler }; let connection_handler = quote! { #prelude_path::ConnectionHandler }; - let into_proto_select_ident = quote! { #prelude_path::IntoConnectionHandlerSelect }; + let proto_select_ident = quote! { #prelude_path::ConnectionHandlerSelect }; let peer_id = quote! { #prelude_path::PeerId }; let connection_id = quote! { #prelude_path::ConnectionId }; let poll_parameters = quote! { #prelude_path::PollParameters }; @@ -75,6 +75,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let listener_error = quote! { #prelude_path::ListenerError }; let listener_closed = quote! { #prelude_path::ListenerClosed }; let t_handler_in_event = quote! { #prelude_path::THandlerInEvent }; + let t_handler = quote! { #prelude_path::THandler }; + let endpoint = quote! { #prelude_path::Endpoint }; // Build the generics. let impl_generics = { @@ -168,18 +170,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } }; - // Build the list of statements to put in the body of `addresses_of_peer()`. - let addresses_of_peer_stmts = { - data_struct - .fields - .iter() - .enumerate() - .map(move |(field_n, field)| match field.ident { - Some(ref i) => quote! { out.extend(self.#i.addresses_of_peer(peer_id)); }, - None => quote! { out.extend(self.#field_n.addresses_of_peer(peer_id)); }, - }) - }; - // Build the list of statements to put in the body of `on_swarm_event()` // for the `FromSwarm::ConnectionEstablished` variant. let on_connection_established_stmts = { @@ -454,7 +444,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let ty = &field.ty; let field_info = quote! { <#ty as #trait_to_impl>::ConnectionHandler }; match ph_ty { - Some(ev) => ph_ty = Some(quote! { #into_proto_select_ident<#ev, #field_info> }), + Some(ev) => ph_ty = Some(quote! { #proto_select_ident<#ev, #field_info> }), ref mut ev @ None => *ev = Some(field_info), } } @@ -462,9 +452,25 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { ph_ty.unwrap_or(quote! {()}) // TODO: `!` instead }; - // The content of `new_handler()`. - // Example output: `self.field1.select(self.field2.select(self.field3))`. - let new_handler = { + // The content of `handle_pending_inbound_connection`. + let handle_pending_inbound_connection_stmts = + data_struct + .fields + .iter() + .enumerate() + .map(|(field_n, field)| { + match field.ident { + Some(ref i) => quote! { + #trait_to_impl::handle_pending_inbound_connection(&mut self.#i, connection_id, local_addr, remote_addr)?; + }, + None => quote! { + #trait_to_impl::handle_pending_inbound_connection(&mut self.#field_n, connection_id, local_addr, remote_addr)?; + } + } + }); + + // The content of `handle_established_inbound_connection`. + let handle_established_inbound_connection = { let mut out_handler = None; for (field_n, field) in data_struct.fields.iter().enumerate() { @@ -474,13 +480,61 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }; let builder = quote! { - #field_name.new_handler() + #field_name.handle_established_inbound_connection(peer, connection_id, local_addr, remote_addr)? }; match out_handler { - Some(h) => { - out_handler = Some(quote! { #into_connection_handler::select(#h, #builder) }) - } + Some(h) => out_handler = Some(quote! { #connection_handler::select(#h, #builder) }), + ref mut h @ None => *h = Some(builder), + } + } + + out_handler.unwrap_or(quote! {()}) // TODO: See test `empty`. + }; + + // The content of `handle_pending_outbound_connection`. + let handle_pending_outbound_connection = { + let extend_stmts = + data_struct + .fields + .iter() + .enumerate() + .map(|(field_n, field)| { + match field.ident { + Some(ref i) => quote! { + combined_addresses.extend(#trait_to_impl::handle_pending_outbound_connection(&mut self.#i, maybe_peer, addresses, effective_role, connection_id)?); + }, + None => quote! { + combined_addresses.extend(#trait_to_impl::handle_pending_outbound_connection(&mut self.#field_n, maybe_peer, addresses, effective_role, connection_id)?); + } + } + }); + + quote! { + let mut combined_addresses = vec![]; + + #(#extend_stmts)* + + Ok(combined_addresses) + } + }; + + // The content of `handle_established_outbound_connection`. + let handle_established_outbound_connection = { + let mut out_handler = None; + + for (field_n, field) in data_struct.fields.iter().enumerate() { + let field_name = match field.ident { + Some(ref i) => quote! { self.#i }, + None => quote! { self.#field_n }, + }; + + let builder = quote! { + #field_name.handle_established_outbound_connection(peer, addr, role_override, connection_id)? + }; + + match out_handler { + Some(h) => out_handler = Some(quote! { #connection_handler::select(#h, #builder) }), ref mut h @ None => *h = Some(builder), } } @@ -571,15 +625,45 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { type ConnectionHandler = #connection_handler_ty; type OutEvent = #out_event_reference; - fn new_handler(&mut self) -> Self::ConnectionHandler { - use #into_connection_handler; - #new_handler + fn handle_pending_inbound_connection( + &mut self, + connection_id: #connection_id, + local_addr: &#multiaddr, + remote_addr: &#multiaddr, + ) -> Result<(), Box> { + #(#handle_pending_inbound_connection_stmts)* + + Ok(()) + } + + fn handle_established_inbound_connection( + &mut self, + peer: #peer_id, + connection_id: #connection_id, + local_addr: &#multiaddr, + remote_addr: &#multiaddr, + ) -> Result<#t_handler, Box> { + Ok(#handle_established_inbound_connection) + } + + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option<#peer_id>, + addresses: &[#multiaddr], + effective_role: #endpoint, + connection_id: #connection_id, + ) -> Result<::std::vec::Vec<#multiaddr>, Box> { + #handle_pending_outbound_connection } - fn addresses_of_peer(&mut self, peer_id: &#peer_id) -> Vec<#multiaddr> { - let mut out = Vec::new(); - #(#addresses_of_peer_stmts);* - out + fn handle_established_outbound_connection( + &mut self, + peer: #peer_id, + addr: &#multiaddr, + role_override: #endpoint, + connection_id: #connection_id, + ) -> Result<#t_handler, Box> { + Ok(#handle_established_outbound_connection) } fn on_connection_handler_event( diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 0f9d4a951d1..6071ae4bc2f 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -37,6 +37,7 @@ use futures::{ ready, stream::FuturesUnordered, }; +use instant::Instant; use libp2p_core::connection::{ConnectionId, Endpoint, PendingPoint}; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerExt}; use libp2p_core::ProtocolName; @@ -184,6 +185,8 @@ struct PendingConnection { endpoint: PendingPoint, /// When dropped, notifies the task which then knows to terminate. abort_notifier: Option>, + /// The moment we became aware of this possible connection, useful for timing metrics. + accepted_at: Instant, } impl PendingConnection { @@ -230,7 +233,8 @@ where /// Addresses are dialed in parallel. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. concurrent_dial_errors: Option)>>, - + /// How long it took to establish this connection. + established_in: std::time::Duration, supported_protocols: SmallVec<[Vec; 16]>, }, @@ -472,6 +476,7 @@ where peer_id: peer, endpoint, abort_notifier: Some(abort_notifier), + accepted_at: Instant::now(), }, ); @@ -515,6 +520,7 @@ where peer_id: None, endpoint: endpoint.into(), abort_notifier: Some(abort_notifier), + accepted_at: Instant::now(), }, ); @@ -615,6 +621,7 @@ where peer_id: expected_peer_id, endpoint, abort_notifier: _, + accepted_at, } = self .pending .remove(&id) @@ -787,6 +794,7 @@ where id, other_established_connection_ids, concurrent_dial_errors, + established_in: accepted_at.elapsed(), supported_protocols, }); } @@ -795,6 +803,7 @@ where peer_id, endpoint, abort_notifier: _, + accepted_at, }) = self.pending.remove(&id) { self.counters.dec_pending(&endpoint); diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index b4ffa3c2b7a..469180a4e3a 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -92,12 +92,14 @@ pub mod derive_prelude { pub use crate::NetworkBehaviour; pub use crate::NetworkBehaviourAction; pub use crate::PollParameters; + pub use crate::THandler; pub use crate::THandlerInEvent; pub use futures::prelude as futures; pub use libp2p_core::connection::ConnectionId; pub use libp2p_core::either::EitherOutput; pub use libp2p_core::transport::ListenerId; pub use libp2p_core::ConnectedPoint; + pub use libp2p_core::Endpoint; pub use libp2p_core::Multiaddr; pub use libp2p_core::PeerId; } @@ -782,6 +784,7 @@ where other_established_connection_ids, concurrent_dial_errors, supported_protocols, + established_in } => { if self.banned_peers.contains(&peer_id) { // Mark the connection for the banned peer as banned, thus withholding any @@ -824,7 +827,7 @@ where num_established, endpoint, concurrent_dial_errors, - established_in: todo!(), + established_in, }); } } From 0b10f4580d57349c9c3d15c80d0af75c52b3eadb Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:04:36 +1100 Subject: [PATCH 039/177] Make derive tests compile by using type alias --- swarm-derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index ba5bae9948d..59398af4967 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -442,7 +442,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let mut ph_ty = None; for field in data_struct.fields.iter() { let ty = &field.ty; - let field_info = quote! { <#ty as #trait_to_impl>::ConnectionHandler }; + let field_info = quote! { #t_handler<#ty> }; match ph_ty { Some(ev) => ph_ty = Some(quote! { #proto_select_ident<#ev, #field_info> }), ref mut ev @ None => *ev = Some(field_info), From dc59e81addc2d065868496fad9a827e5d562bb2f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:05:28 +1100 Subject: [PATCH 040/177] Ignore clippy warnings in generated code --- swarm-derive/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 59398af4967..2a8f5bbec34 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -625,6 +625,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { type ConnectionHandler = #connection_handler_ty; type OutEvent = #out_event_reference; + #[allow(clippy::needless_question_mark)] fn handle_pending_inbound_connection( &mut self, connection_id: #connection_id, @@ -636,6 +637,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { Ok(()) } + #[allow(clippy::needless_question_mark)] fn handle_established_inbound_connection( &mut self, peer: #peer_id, @@ -646,6 +648,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { Ok(#handle_established_inbound_connection) } + #[allow(clippy::needless_question_mark)] fn handle_pending_outbound_connection( &mut self, maybe_peer: Option<#peer_id>, @@ -656,6 +659,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #handle_pending_outbound_connection } + #[allow(clippy::needless_question_mark)] fn handle_established_outbound_connection( &mut self, peer: #peer_id, From ceda44c1c19c55720dbc76e8552f60493144f45b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:12:17 +1100 Subject: [PATCH 041/177] Fix more warnings by allowing deprecations --- protocols/gossipsub/src/behaviour.rs | 2 +- protocols/kad/src/behaviour/test.rs | 2 +- swarm-derive/src/lib.rs | 4 ++-- swarm/src/behaviour.rs | 11 ++++++++++- swarm/src/connection/pool.rs | 2 +- swarm/src/handler/multi.rs | 4 +++- swarm/src/lib.rs | 9 ++++++--- swarm/src/test.rs | 16 +++++----------- 8 files changed, 29 insertions(+), 21 deletions(-) diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 3fcebf722c8..6052460e093 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -19,7 +19,7 @@ // DEALINGS IN THE SOFTWARE. use std::{ - cmp::{max, Ordering}, + cmp::max, collections::HashSet, collections::VecDeque, collections::{BTreeSet, HashMap}, diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index bf3bd7cf17a..392e4e034e3 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -1294,7 +1294,7 @@ fn network_behaviour_on_address_change() { let local_peer_id = PeerId::random(); let remote_peer_id = PeerId::random(); - let connection_id = ConnectionId::new(1); + let connection_id = ConnectionId::default(); let old_address: Multiaddr = Protocol::Memory(1).into(); let new_address: Multiaddr = Protocol::Memory(2).into(); diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 2a8f5bbec34..c4615f0a319 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -55,7 +55,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let trait_to_impl = quote! { #prelude_path::NetworkBehaviour }; let either_ident = quote! { #prelude_path::EitherOutput }; let network_behaviour_action = quote! { #prelude_path::NetworkBehaviourAction }; - let into_connection_handler = quote! { #prelude_path::IntoConnectionHandler }; let connection_handler = quote! { #prelude_path::ConnectionHandler }; let proto_select_ident = quote! { #prelude_path::ConnectionHandlerSelect }; let peer_id = quote! { #prelude_path::PeerId }; @@ -75,6 +74,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let listener_error = quote! { #prelude_path::ListenerError }; let listener_closed = quote! { #prelude_path::ListenerClosed }; let t_handler_in_event = quote! { #prelude_path::THandlerInEvent }; + let t_handler_out_event = quote! { #prelude_path::THandlerOutEvent }; let t_handler = quote! { #prelude_path::THandler }; let endpoint = quote! { #prelude_path::Endpoint }; @@ -674,7 +674,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { &mut self, peer_id: #peer_id, connection_id: #connection_id, - event: <::Handler as #connection_handler>::OutEvent + event: #t_handler_out_event ) { match event { #(#on_node_event_stmts),* diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index fc5651fcbf9..659e1315a6c 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -27,7 +27,9 @@ pub use external_addresses::ExternalAddresses; pub use listen_addresses::ListenAddresses; use crate::dial_opts::DialOpts; -use crate::handler::{ConnectionHandler, IntoConnectionHandler}; +use crate::handler::ConnectionHandler; +#[allow(deprecated)] +use crate::handler::IntoConnectionHandler; use crate::{AddressRecord, AddressScore, DialError, THandler, THandlerInEvent, THandlerOutEvent}; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId, @@ -118,6 +120,7 @@ use std::{task::Context, task::Poll}; /// ``` pub trait NetworkBehaviour: 'static { /// Handler for all the protocols the network behaviour supports. + #[allow(deprecated)] type ConnectionHandler: IntoConnectionHandler; /// Event generated by the `NetworkBehaviour` and that the swarm will report back. @@ -203,6 +206,7 @@ pub trait NetworkBehaviour: 'static { _effective_role: Endpoint, _connection_id: ConnectionId, ) -> Result, Box> { + #[allow(deprecated)] if let Some(peer_id) = maybe_peer { Ok(self.addresses_of_peer(&peer_id)) } else { @@ -292,6 +296,7 @@ pub trait NetworkBehaviour: 'static { since = "0.40.2", note = "Handle `FromSwarm::ConnectionClosed` in `NetworkBehaviour::on_swarm_event` instead. The default implementation of this `inject_*` method delegates to it." )] + #[allow(deprecated)] fn inject_connection_closed( &mut self, peer_id: &PeerId, @@ -338,6 +343,7 @@ pub trait NetworkBehaviour: 'static { since = "0.40.2", note = "Implement `NetworkBehaviour::on_connection_handler_event` instead. The default implementation of this `inject_*` method delegates to it." )] + #[allow(deprecated)] fn inject_event( &mut self, peer_id: PeerId, @@ -684,6 +690,7 @@ impl Default for CloseConnection { /// Enumeration with the list of the possible events /// to pass to [`on_swarm_event`](NetworkBehaviour::on_swarm_event). +#[allow(deprecated)] pub enum FromSwarm<'a, Handler: IntoConnectionHandler> { /// Informs the behaviour about a newly established connection to a peer. ConnectionEstablished(ConnectionEstablished<'a>), @@ -738,6 +745,7 @@ pub struct ConnectionEstablished<'a> { /// This event is always paired with an earlier /// [`FromSwarm::ConnectionEstablished`] with the same peer ID, connection ID /// and endpoint. +#[allow(deprecated)] pub struct ConnectionClosed<'a, Handler: IntoConnectionHandler> { pub peer_id: PeerId, pub connection_id: ConnectionId, @@ -827,6 +835,7 @@ pub struct ExpiredExternalAddr<'a> { pub addr: &'a Multiaddr, } +#[allow(deprecated)] impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { fn map_handler( self, diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 6071ae4bc2f..9b6a9ba6d29 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -803,7 +803,7 @@ where peer_id, endpoint, abort_notifier: _, - accepted_at, + accepted_at: _, }) = self.pending.remove(&id) { self.counters.dec_pending(&endpoint); diff --git a/swarm/src/handler/multi.rs b/swarm/src/handler/multi.rs index d80b51c52a8..0aa42d18599 100644 --- a/swarm/src/handler/multi.rs +++ b/swarm/src/handler/multi.rs @@ -22,9 +22,11 @@ //! indexed by some key. use crate::handler::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, IntoConnectionHandler, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, }; +#[allow(deprecated)] +use crate::handler::IntoConnectionHandler; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend}; use crate::NegotiatedSubstream; use futures::{future::BoxFuture, prelude::*}; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 469180a4e3a..89ce823a9b8 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -87,13 +87,12 @@ pub mod derive_prelude { pub use crate::ConnectionHandler; pub use crate::ConnectionHandlerSelect; pub use crate::DialError; - pub use crate::IntoConnectionHandler; - pub use crate::IntoConnectionHandlerSelect; pub use crate::NetworkBehaviour; pub use crate::NetworkBehaviourAction; pub use crate::PollParameters; pub use crate::THandler; pub use crate::THandlerInEvent; + pub use crate::THandlerOutEvent; pub use futures::prelude as futures; pub use libp2p_core::connection::ConnectionId; pub use libp2p_core::either::EitherOutput; @@ -116,9 +115,11 @@ pub use connection::{ pub use executor::Executor; pub use handler::{ ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr, - IntoConnectionHandler, IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, + IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, OneShotHandlerConfig, SubstreamProtocol, }; +#[allow(deprecated)] +pub use handler::IntoConnectionHandler; #[cfg(feature = "macros")] pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; @@ -159,6 +160,7 @@ type TBehaviourOutEvent = ::OutEvent /// [`ConnectionHandler`] of the [`NetworkBehaviour`] for all the protocols the [`NetworkBehaviour`] /// supports. +#[allow(deprecated)] pub type THandler = <::ConnectionHandler as IntoConnectionHandler>::Handler; @@ -582,6 +584,7 @@ where Err(cause) => { let error = DialError::Denied { cause }; + #[allow(deprecated)] self.behaviour .inject_dial_failure(peer_id, &error, connection_id); diff --git a/swarm/src/test.rs b/swarm/src/test.rs index fc795bfb6f7..0b919efa82e 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -23,8 +23,8 @@ use crate::behaviour::{ FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, }; use crate::{ - ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, THandlerInEvent, THandlerOutEvent, + ConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + THandlerOutEvent, }; use libp2p_core::{ connection::ConnectionId, multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId, @@ -130,11 +130,7 @@ where pub addresses_of_peer: 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 on_event: Vec<(PeerId, ConnectionId, THandlerOutEvent)>, pub on_dial_failure: Vec>, pub on_new_listener: Vec, pub on_new_listen_addr: Vec<(ListenerId, Multiaddr)>, @@ -149,8 +145,7 @@ where impl CallTraceBehaviour where TInner: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: - Clone, + THandlerOutEvent: Clone, { pub fn new(inner: TInner) -> Self { Self { @@ -369,8 +364,7 @@ where impl NetworkBehaviour for CallTraceBehaviour where TInner: NetworkBehaviour, - <::Handler as ConnectionHandler>::OutEvent: - Clone, + THandlerOutEvent: Clone, { type ConnectionHandler = TInner::ConnectionHandler; type OutEvent = TInner::OutEvent; From 18426d125261dd4a779f5fd66a9668668ee55612 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:26:46 +1100 Subject: [PATCH 042/177] Remove unnecessary `extern crate` --- core/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index 953bca551d7..2b20f5156e4 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -37,8 +37,6 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -extern crate core; - #[allow(clippy::derive_partial_eq_without_eq)] mod keys_proto { include!(concat!(env!("OUT_DIR"), "/keys_proto.rs")); From bae533e893ffa6fb087c168fe2b4e8b4d66c21e1 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:42:00 +1100 Subject: [PATCH 043/177] Revert let-else usage --- swarm/src/behaviour/toggle.rs | 20 ++++++++++++-------- swarm/src/handler/multi.rs | 8 ++++---- swarm/src/lib.rs | 8 ++++---- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index a7e90ed1ed6..93f42baac44 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -82,8 +82,9 @@ where local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result<(), Box> { - let Some(inner) = self.inner.as_mut() else { - return Ok(()) + let inner = match self.inner.as_mut() { + None => return Ok(()), + Some(inner) => inner, }; inner.handle_pending_inbound_connection(connection_id, local_addr, remote_addr)?; @@ -98,8 +99,9 @@ where local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, Box> { - let Some(inner) = self.inner.as_mut() else { - return Ok(ToggleConnectionHandler { inner: None }) + let inner = match self.inner.as_mut() { + None => return Ok(ToggleConnectionHandler { inner: None }), + Some(inner) => inner, }; let handler = inner.handle_established_inbound_connection( @@ -121,8 +123,9 @@ where effective_role: Endpoint, connection_id: ConnectionId, ) -> Result, Box> { - let Some(inner) = self.inner.as_mut() else { - return Ok(vec![]) + let inner = match self.inner.as_mut() { + None => return Ok(vec![]), + Some(inner) => inner, }; let addresses = inner.handle_pending_outbound_connection( @@ -142,8 +145,9 @@ where role_override: Endpoint, connection_id: ConnectionId, ) -> Result, Box> { - let Some(inner) = self.inner.as_mut() else { - return Ok(ToggleConnectionHandler { inner: None }) + let inner = match self.inner.as_mut() { + None => return Ok(ToggleConnectionHandler { inner: None }), + Some(inner) => inner, }; let handler = inner.handle_established_outbound_connection( diff --git a/swarm/src/handler/multi.rs b/swarm/src/handler/multi.rs index 0aa42d18599..403df0ab49a 100644 --- a/swarm/src/handler/multi.rs +++ b/swarm/src/handler/multi.rs @@ -21,12 +21,12 @@ //! A [`ConnectionHandler`] implementation that combines multiple other [`ConnectionHandler`]s //! indexed by some key. -use crate::handler::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, - KeepAlive, SubstreamProtocol, -}; #[allow(deprecated)] use crate::handler::IntoConnectionHandler; +use crate::handler::{ + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + SubstreamProtocol, +}; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend}; use crate::NegotiatedSubstream; use futures::{future::BoxFuture, prelude::*}; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 89ce823a9b8..0645a1bf5a3 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -113,13 +113,13 @@ pub use connection::{ PendingOutboundConnectionError, }; pub use executor::Executor; +#[allow(deprecated)] +pub use handler::IntoConnectionHandler; pub use handler::{ ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerSelect, ConnectionHandlerUpgrErr, - IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, - OneShotHandlerConfig, SubstreamProtocol, + IntoConnectionHandlerSelect, KeepAlive, OneShotHandler, OneShotHandlerConfig, + SubstreamProtocol, }; -#[allow(deprecated)] -pub use handler::IntoConnectionHandler; #[cfg(feature = "macros")] pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; From 80295acb6b60366a5e86a219fba6992b3276604c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:44:28 +1100 Subject: [PATCH 044/177] Less let else --- protocols/request-response/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 65655642d10..54cb44217f3 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -750,8 +750,9 @@ where _effective_role: Endpoint, _connection_id: ConnectionId, ) -> Result, Box> { - let Some(peer) = maybe_peer else { - return Ok(vec![]) + let peer = match maybe_peer { + None => return Ok(vec![]), + Some(peer) => peer }; let mut addresses = Vec::new(); From 05988cc0a4dfe899b3553ddefa3be188be5781d4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:48:21 +1100 Subject: [PATCH 045/177] No let else in mdns --- protocols/mdns/src/behaviour.rs | 5 +++-- protocols/request-response/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index f509a8000f8..453f7be9996 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -193,8 +193,9 @@ where _effective_role: Endpoint, _connection_id: ConnectionId, ) -> Result, Box> { - let Some(peer_id) = maybe_peer else { - return Ok(vec![]) + let peer_id = match maybe_peer { + None => return Ok(vec![]), + Some(peer) => peer, }; Ok(self diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 54cb44217f3..ff72fa906a8 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -752,7 +752,7 @@ where ) -> Result, Box> { let peer = match maybe_peer { None => return Ok(vec![]), - Some(peer) => peer + Some(peer) => peer, }; let mut addresses = Vec::new(); From f22f5a219f0909331bbaa47071d7d46258721263 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:51:07 +1100 Subject: [PATCH 046/177] No let-else in dcutr --- protocols/dcutr/src/behaviour_impl.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index e60333c7ab5..20b2c3f3785 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -139,11 +139,14 @@ impl Behaviour { } fn on_dial_failure(&mut self, DialFailure { peer_id, id, .. }: DialFailure) { - let Some((relayed_connection_id, role)) = self.direct_outgoing_connection_attempts.remove(&id) else { - return; - }; - let Role::Initiator { attempt } = role else { - return; + let (relayed_connection_id, role) = + match self.direct_outgoing_connection_attempts.remove(&id) { + None => return, + Some((relayed_connection_id, role)) => (relayed_connection_id, role), + }; + let attempt = match role { + Role::Listener => return, + Role::Initiator { attempt } => attempt, }; let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); From c7871d19fa48a69a4e52337b4f2f88927a60c342 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:51:47 +1100 Subject: [PATCH 047/177] No let else in rendezvous --- protocols/rendezvous/src/client.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index f32fbdbd001..95657ed131c 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -188,8 +188,9 @@ impl NetworkBehaviour for Behaviour { _effective_role: Endpoint, _connection_id: ConnectionId, ) -> Result, Box> { - let Some(peer) = maybe_peer else { - return Ok(vec![]) + let peer = match maybe_peer { + None => return Ok(vec![]), + Some(peer) => peer, }; Ok(self From 10c316172c23d4def8bee4dcfb2bf131f48cbeea Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 14:56:47 +1100 Subject: [PATCH 048/177] Last let-else usage --- protocols/dcutr/src/behaviour_impl.rs | 60 +++++++++++++++++---------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 20b2c3f3785..90680ca158c 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -206,22 +206,30 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, _peer: PeerId, - _connection_id: ConnectionId, + connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, Box> { let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - // TODO: Why are we ignoring `Role`? - let Some((relayed_connection_id, _role)) = self.direct_outgoing_connection_attempts.remove(&_connection_id) else { - - let handler = if is_relayed { - Either::Left(relayed::Handler::new(ConnectedPoint::Listener { local_addr: local_addr.clone(), send_back_addr: remote_addr.clone() })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. - } else { - Either::Right(Either::Right(dummy::ConnectionHandler)) - }; - - return Ok(handler) + let relayed_connection_id = match self + .direct_outgoing_connection_attempts + .remove(&connection_id) + { + None => { + let handler = if is_relayed { + Either::Left(relayed::Handler::new(ConnectedPoint::Listener { + local_addr: local_addr.clone(), + send_back_addr: remote_addr.clone(), + })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. + } else { + Either::Right(Either::Right(dummy::ConnectionHandler)) + }; + + return Ok(handler); + } + // TODO: Why are we ignoring `Role`? + Some((relayed_connection_id, _)) => relayed_connection_id, }; assert!( @@ -239,20 +247,28 @@ impl NetworkBehaviour for Behaviour { _peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - _connection_id: ConnectionId, + connection_id: ConnectionId, ) -> Result, Box> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - // TODO: Why are we ignoring `Role`? - let Some((relayed_connection_id, _role)) = self.direct_outgoing_connection_attempts.remove(&_connection_id) else { - - let handler = if is_relayed { - Either::Left(relayed::Handler::new(ConnectedPoint::Dialer { address: addr.clone(), role_override })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. - } else { - Either::Right(Either::Right(dummy::ConnectionHandler)) - }; - - return Ok(handler) + let relayed_connection_id = match self + .direct_outgoing_connection_attempts + .remove(&connection_id) + { + None => { + let handler = if is_relayed { + Either::Left(relayed::Handler::new(ConnectedPoint::Dialer { + address: addr.clone(), + role_override, + })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. + } else { + Either::Right(Either::Right(dummy::ConnectionHandler)) + }; + + return Ok(handler); + } + // TODO: Why are we ignoring `Role`? + Some((relayed_connection_id, _)) => relayed_connection_id, }; assert!( From de2d837df88d2b79756118ac26e9f1d3760b1318 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:03:20 +1100 Subject: [PATCH 049/177] Remove fn from bad merge --- protocols/floodsub/src/layer.rs | 4 ++-- swarm/src/connection/pool.rs | 6 ----- swarm/src/lib.rs | 40 --------------------------------- 3 files changed, 2 insertions(+), 48 deletions(-) diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 60103f438a3..9628ff779ec 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -342,7 +342,7 @@ impl NetworkBehaviour for Floodsub { _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> std::result::Result, Box> { + ) -> Result, Box> { Ok(Default::default()) } @@ -352,7 +352,7 @@ impl NetworkBehaviour for Floodsub { _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> std::result::Result, Box> { + ) -> Result, Box> { Ok(Default::default()) } diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 9b6a9ba6d29..38ed5e9023a 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -1106,12 +1106,6 @@ impl PoolConfig { } } - /// Configures the executor to use for spawning connection background tasks. - pub fn with_executor(mut self, executor: Box) -> Self { - self.executor = Some(executor); - self - } - /// Sets the maximum number of events sent to a connection's background task /// that may be buffered, if the task cannot keep up with their consumption and /// delivery to the connection handler. diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 0645a1bf5a3..f602aac8c77 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1443,35 +1443,6 @@ impl SwarmBuilder where TBehaviour: NetworkBehaviour, { - /// Creates a new `SwarmBuilder` from the given transport, behaviour and - /// local peer ID. The `Swarm` with its underlying `Network` is obtained - /// via [`SwarmBuilder::build`]. - #[deprecated( - since = "0.41.0", - note = "Use `SwarmBuilder::with_executor` or `SwarmBuilder::without_executor` instead." - )] - pub fn new( - transport: transport::Boxed<(PeerId, StreamMuxerBox)>, - behaviour: TBehaviour, - local_peer_id: PeerId, - ) -> Self { - let executor: Option> = match ThreadPoolBuilder::new() - .name_prefix("libp2p-swarm-task-") - .create() - .ok() - { - Some(tp) => Some(Box::new(tp)), - None => None, - }; - SwarmBuilder { - local_peer_id, - transport, - behaviour, - pool_config: PoolConfig::new(executor), - connection_limits: Default::default(), - } - } - /// Creates a new [`SwarmBuilder`] from the given transport, behaviour, local peer ID and /// executor. The `Swarm` with its underlying `Network` is obtained via /// [`SwarmBuilder::build`]. @@ -1549,17 +1520,6 @@ where } } - /// Configures the `Executor` to use for spawning background tasks. - /// - /// By default, unless another executor has been configured, - /// [`SwarmBuilder::build`] will try to set up a - /// [`ThreadPool`](futures::executor::ThreadPool). - #[deprecated(since = "0.41.0", note = "Use `SwarmBuilder::with_executor` instead.")] - pub fn executor(mut self, executor: Box) -> Self { - self.pool_config = self.pool_config.with_executor(executor); - self - } - /// Configures the number of events from the [`NetworkBehaviour`] in /// destination to the [`ConnectionHandler`] that can be buffered before /// the [`Swarm`] has to wait. An individual buffer with this number of From a6616aafc57631a73001cc747de987d442f447cc Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:07:53 +1100 Subject: [PATCH 050/177] Minimize diff --- protocols/relay/src/v2/client.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/relay/src/v2/client.rs b/protocols/relay/src/v2/client.rs index abc803298a4..d51b387c1ae 100644 --- a/protocols/relay/src/v2/client.rs +++ b/protocols/relay/src/v2/client.rs @@ -234,9 +234,9 @@ impl NetworkBehaviour for Client { &mut self, event_source: PeerId, _connection: ConnectionId, - _event: THandlerOutEvent, + handler_event: THandlerOutEvent, ) { - let handler_event = match _event { + let handler_event = match handler_event { Either::Left(e) => e, Either::Right(v) => void::unreachable(v), }; From 848ac794032ee67ac8814e3a49801d75bf8cdfac Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:08:30 +1100 Subject: [PATCH 051/177] Attempt to minimize diff --- protocols/rendezvous/src/client.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 95657ed131c..9e6e586e00f 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -193,13 +193,15 @@ impl NetworkBehaviour for Behaviour { Some(peer) => peer, }; - Ok(self + let addresses = self .discovered_peers .iter() .filter_map(|((candidate, _), addresses)| (candidate == &peer).then_some(addresses)) .flatten() .cloned() - .collect()) + .collect(); + + Ok(addresses) } fn handle_established_outbound_connection( From 65521e25bc63db809a5692f2b79110b12b739bd7 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:10:13 +1100 Subject: [PATCH 052/177] Undo re-ordering to reduce diff --- protocols/rendezvous/src/client.rs | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 9e6e586e00f..b81cb452c99 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -216,25 +216,6 @@ impl NetworkBehaviour for Behaviour { )) } - fn on_swarm_event(&mut self, event: FromSwarm) { - self.external_addresses.on_swarn_event(&event); - - 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, @@ -315,6 +296,25 @@ impl NetworkBehaviour for Behaviour { Poll::Pending } + + fn on_swarm_event(&mut self, event: FromSwarm) { + self.external_addresses.on_swarn_event(&event); + + 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( From 6f7d7f0f8861f5c4aee0b268204c8164480d14f8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:13:52 +1100 Subject: [PATCH 053/177] Minimize diff (and fix bad merge) --- swarm/src/connection/pool.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 38ed5e9023a..ab4319910df 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -320,8 +320,7 @@ where { /// Creates a new empty `Pool`. pub fn new(local_id: PeerId, config: PoolConfig, limits: ConnectionLimits) -> Self { - let (pending_connection_events_tx, pending_connection_events_rx) = - mpsc::channel(config.task_event_buffer_size); + let (pending_connection_events_tx, pending_connection_events_rx) = mpsc::channel(0); let (established_connection_events_tx, established_connection_events_rx) = mpsc::channel(config.task_event_buffer_size); let executor = match config.executor { @@ -787,14 +786,14 @@ where ) .boxed(), ); - + let established_in = accepted_at.elapsed(); return Poll::Ready(PoolEvent::ConnectionEstablished { peer_id: obtained_peer_id, endpoint, id, other_established_connection_ids, concurrent_dial_errors, - established_in: accepted_at.elapsed(), + established_in, supported_protocols, }); } @@ -803,7 +802,7 @@ where peer_id, endpoint, abort_notifier: _, - accepted_at: _, + accepted_at: _, // Ignoring the time it took for the connection to fail. }) = self.pending.remove(&id) { self.counters.dec_pending(&endpoint); From 27f04cc99d7404e92e2d040edf2a671dd29b6db4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:16:32 +1100 Subject: [PATCH 054/177] Remove default impl for `ConnectionId` in favor of `next` --- core/src/connection.rs | 5 ++--- protocols/autonat/src/behaviour/as_server.rs | 2 +- protocols/floodsub/src/layer.rs | 4 ++-- protocols/gossipsub/src/behaviour.rs | 4 ++-- protocols/identify/src/behaviour.rs | 2 +- protocols/kad/src/behaviour.rs | 6 +++--- protocols/kad/src/behaviour/test.rs | 2 +- protocols/request-response/src/lib.rs | 2 +- swarm/src/behaviour.rs | 2 +- swarm/src/lib.rs | 4 ++-- 10 files changed, 16 insertions(+), 17 deletions(-) diff --git a/core/src/connection.rs b/core/src/connection.rs index 4bcf6a2b7ea..a4cc1f5d4c2 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -39,10 +39,9 @@ impl ConnectionId { pub fn new(id: usize) -> Self { Self(id as u64) } -} -impl Default for ConnectionId { - fn default() -> Self { + /// Allocates a new [`ConnectionId`]. + pub fn next() -> Self { Self(NEXT_CONNECTION_ID.fetch_add(1, Ordering::SeqCst)) } } diff --git a/protocols/autonat/src/behaviour/as_server.rs b/protocols/autonat/src/behaviour/as_server.rs index 6efc9bb06d7..303e95b198b 100644 --- a/protocols/autonat/src/behaviour/as_server.rs +++ b/protocols/autonat/src/behaviour/as_server.rs @@ -138,7 +138,7 @@ impl<'a> HandleInnerEvent for AsServer<'a> { ) .addresses(addrs) .build(), - id: Default::default(), + id: ConnectionId::next(), }, ]) } diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 9628ff779ec..306371c90db 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -104,7 +104,7 @@ impl Floodsub { if self.target_peers.insert(peer_id) { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - id: Default::default(), + id: ConnectionId::next(), }); } } @@ -326,7 +326,7 @@ impl Floodsub { if self.target_peers.contains(&peer_id) { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - id: Default::default(), + id: ConnectionId::next(), }); } } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 6052460e093..7a5a5e4d49c 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -1139,7 +1139,7 @@ where debug!("Connecting to explicit peer {:?}", peer_id); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer_id).build(), - id: Default::default(), + id: ConnectionId::next(), }); } } @@ -1637,7 +1637,7 @@ where // dial peer self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - id: Default::default(), + id: ConnectionId::next(), }); } } diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index a474746168b..ea3b81e2a3b 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -202,7 +202,7 @@ impl Behaviour { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(p).build(), - id: Default::default(), + id: ConnectionId::next(), }); } } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 370622b23a0..1ee58c11951 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -577,7 +577,7 @@ where kbucket::InsertResult::Pending { disconnected } => { self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()).build(), - id: Default::default(), + id: ConnectionId::next(), }); RoutingUpdate::Pending } @@ -1227,7 +1227,7 @@ where self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()) .build(), - id: Default::default(), + id: ConnectionId::next(), }) } } @@ -2426,7 +2426,7 @@ where query.inner.pending_rpcs.push((peer_id, event)); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - id: Default::default(), + id: ConnectionId::next(), }); } } diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index 392e4e034e3..7c93e456404 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -1294,7 +1294,7 @@ fn network_behaviour_on_address_change() { let local_peer_id = PeerId::random(); let remote_peer_id = PeerId::random(); - let connection_id = ConnectionId::default(); + let connection_id = ConnectionId::next(); let old_address: Multiaddr = Protocol::Memory(1).into(); let new_address: Multiaddr = Protocol::Memory(2).into(); diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index ff72fa906a8..dcaca77221b 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -420,7 +420,7 @@ where if let Some(request) = self.try_send_request(peer, request) { self.pending_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer).build(), - id: Default::default(), + id: ConnectionId::next(), }); self.pending_outbound_requests .entry(*peer) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 659e1315a6c..75025947fe7 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -592,7 +592,7 @@ pub enum NetworkBehaviourAction { impl NetworkBehaviourAction { /// TODO: Docs pub fn dial(opts: impl Into) -> (Self, ConnectionId) { - let id = ConnectionId::default(); + let id = ConnectionId::next(); let action = Self::Dial { opts: opts.into(), diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index f602aac8c77..86cb2323fd0 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -515,7 +515,7 @@ where /// ``` pub fn dial(&mut self, opts: impl Into) -> Result { let swarm_dial_opts = opts.into(); - let id = ConnectionId::default(); + let id = ConnectionId::next(); self.dial_with_id(swarm_dial_opts, id)?; @@ -966,7 +966,7 @@ where local_addr, send_back_addr, } => { - let connection_id = ConnectionId::default(); + let connection_id = ConnectionId::next(); match self.behaviour.handle_pending_inbound_connection( connection_id, From 2b13bd4718e85dd074112feca69aef2578da911b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:19:51 +1100 Subject: [PATCH 055/177] Deprecate `IntoMultiHandler` --- swarm/src/handler/multi.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swarm/src/handler/multi.rs b/swarm/src/handler/multi.rs index 403df0ab49a..611316ce25b 100644 --- a/swarm/src/handler/multi.rs +++ b/swarm/src/handler/multi.rs @@ -346,10 +346,12 @@ impl IntoIterator for MultiHandler { /// A [`IntoConnectionHandler`] for multiple other `IntoConnectionHandler`s. #[derive(Clone)] +#[deprecated(note = "Use `MultiHandler` directly.")] pub struct IntoMultiHandler { handlers: HashMap, } +#[allow(deprecated)] impl fmt::Debug for IntoMultiHandler where K: fmt::Debug + Eq + Hash, @@ -362,6 +364,7 @@ where } } +#[allow(deprecated)] impl IntoMultiHandler where K: Hash + Eq, @@ -382,6 +385,7 @@ where } } +#[allow(deprecated)] impl IntoConnectionHandler for IntoMultiHandler where K: Debug + Clone + Eq + Hash + Send + 'static, From e8c9942fef6d0eecc995f31f504ad130ba52bcbd Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:39:36 +1100 Subject: [PATCH 056/177] Implement dial failure reporting --- swarm/src/lib.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 86cb2323fd0..f2aedc83c4b 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -124,6 +124,7 @@ pub use handler::{ pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; +use crate::behaviour::{DialFailure, FromSwarm}; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; use dial_opts::{DialOpts, PeerCondition}; @@ -787,7 +788,7 @@ where other_established_connection_ids, concurrent_dial_errors, supported_protocols, - established_in + established_in, } => { if self.banned_peers.contains(&peer_id) { // Mark the connection for the banned peer as banned, thus withholding any @@ -919,9 +920,34 @@ where peer_id, endpoint, cause, - .. + id, } => { - return Some(todo!("Report connection error event, these are currently modeled in a weird way where we split them by incoming/outgoing on the `SwarmEvent` level but everywhere else by established/pending")) + match endpoint { + ConnectedPoint::Dialer { .. } => { + let dial_error = DialError::Denied { cause }; + self.behaviour + .on_swarm_event(FromSwarm::DialFailure(DialFailure { + id, + error: &dial_error, + peer_id: Some(peer_id), + })); + + return Some(SwarmEvent::OutgoingConnectionError { + peer_id: Some(peer_id), + error: dial_error, + }); + } + ConnectedPoint::Listener { + local_addr, + send_back_addr, + } => return Some(SwarmEvent::IncomingConnectionError { + send_back_addr, + local_addr, + error: todo!( + "Got a 'pending' error here but we have an established connection ..." + ), + }), + } } PoolEvent::ConnectionEvent { peer_id, id, event } => { if self.banned_peer_connections.contains(&id) { From f51f0aa57052b2f9ed45b1d456fd01002f9d53a3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 23 Dec 2022 22:41:26 +1100 Subject: [PATCH 057/177] Fix formatting --- swarm/src/lib.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index f2aedc83c4b..017bc7461ef 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -921,34 +921,34 @@ where endpoint, cause, id, - } => { - match endpoint { - ConnectedPoint::Dialer { .. } => { - let dial_error = DialError::Denied { cause }; - self.behaviour - .on_swarm_event(FromSwarm::DialFailure(DialFailure { - id, - error: &dial_error, - peer_id: Some(peer_id), - })); - - return Some(SwarmEvent::OutgoingConnectionError { + } => match endpoint { + ConnectedPoint::Dialer { .. } => { + let dial_error = DialError::Denied { cause }; + self.behaviour + .on_swarm_event(FromSwarm::DialFailure(DialFailure { + id, + error: &dial_error, peer_id: Some(peer_id), - error: dial_error, - }); - } - ConnectedPoint::Listener { - local_addr, - send_back_addr, - } => return Some(SwarmEvent::IncomingConnectionError { + })); + + return Some(SwarmEvent::OutgoingConnectionError { + peer_id: Some(peer_id), + error: dial_error, + }); + } + ConnectedPoint::Listener { + local_addr, + send_back_addr, + } => { + return Some(SwarmEvent::IncomingConnectionError { send_back_addr, local_addr, error: todo!( "Got a 'pending' error here but we have an established connection ..." ), - }), + }) } - } + }, PoolEvent::ConnectionEvent { peer_id, id, event } => { if self.banned_peer_connections.contains(&id) { log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id); From 3a84c141787d2206db1ace365fa1b19082d9f00a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 11 Jan 2023 16:13:16 +1100 Subject: [PATCH 058/177] Use single quotes to avoid running commands --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ce4fc5fdea..a25fdf3c4e0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -299,10 +299,10 @@ jobs: - name: Check PR title length run: | - title="${{ github.event.pull_request.title }}" + title='${{ github.event.pull_request.title }}' title_length=${#title} if [ $title_length -gt 72 ] then echo "PR title is too long (greater than 72 characters)" exit 1 - fi \ No newline at end of file + fi From 458aa533d9489aa374658bdba808f45446d4925d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Jan 2023 11:47:28 +1100 Subject: [PATCH 059/177] Use intermediary variable --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a25fdf3c4e0..c8725c7a332 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -298,9 +298,10 @@ jobs: require_scope: false - name: Check PR title length + env: + TITLE: ${{ github.event.pull_request.title }} run: | - title='${{ github.event.pull_request.title }}' - title_length=${#title} + title_length=${#TITLE} if [ $title_length -gt 72 ] then echo "PR title is too long (greater than 72 characters)" From d0d8b774536831db7a508a871d473a5702f86393 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Jan 2023 12:30:54 +1100 Subject: [PATCH 060/177] Make connection IDs globally unique --- core/src/connection.rs | 21 ++++++--------------- protocols/gossipsub/src/behaviour/tests.rs | 22 +++++++++++----------- protocols/kad/src/behaviour/test.rs | 2 +- swarm/src/connection/pool.rs | 15 ++------------- 4 files changed, 20 insertions(+), 40 deletions(-) diff --git a/core/src/connection.rs b/core/src/connection.rs index 91008408fe2..39a85750909 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -19,27 +19,18 @@ // DEALINGS IN THE SOFTWARE. use crate::multiaddr::{Multiaddr, Protocol}; +use std::sync::atomic::{AtomicUsize, Ordering}; + +static NEXT_CONNECTION_ID: AtomicUsize = AtomicUsize::new(0); /// Connection identifier. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct ConnectionId(usize); impl ConnectionId { - /// Creates a `ConnectionId` from a non-negative integer. - /// - /// This is primarily useful for creating connection IDs - /// in test environments. There is in general no guarantee - /// that all connection IDs are based on non-negative integers. - pub fn new(id: usize) -> Self { - Self(id) - } -} - -impl std::ops::Add for ConnectionId { - type Output = Self; - - fn add(self, other: usize) -> Self { - Self(self.0 + other) + /// Returns the next available [`ConnectionId`]. + pub fn next() -> Self { + Self(NEXT_CONNECTION_ID.fetch_add(1, Ordering::SeqCst)) } } diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 26af832e05f..7aa9adccbbc 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -225,13 +225,13 @@ where gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id: peer, - connection_id: ConnectionId::new(0), + connection_id: ConnectionId::next(), endpoint: &endpoint, failed_addresses: &[], other_established: 0, // first connection })); if let Some(kind) = kind { - gs.on_connection_handler_event(peer, ConnectionId::new(1), HandlerEvent::PeerKind(kind)); + gs.on_connection_handler_event(peer, ConnectionId::next(), HandlerEvent::PeerKind(kind)); } if explicit { gs.add_explicit_peer(&peer); @@ -579,7 +579,7 @@ fn test_join() { // inform the behaviour of a new peer gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id: random_peer, - connection_id: ConnectionId::new(1), + connection_id: ConnectionId::next(), endpoint: &ConnectedPoint::Dialer { address: "/ip4/127.0.0.1".parse::().unwrap(), role_override: Endpoint::Dialer, @@ -959,7 +959,7 @@ fn test_get_random_peers() { *p, PeerConnections { kind: PeerKind::Gossipsubv1_1, - connections: vec![ConnectionId::new(1)], + connections: vec![ConnectionId::next()], }, ) }) @@ -3009,7 +3009,7 @@ fn test_ignore_rpc_from_peers_below_graylist_threshold() { //receive from p1 gs.on_connection_handler_event( p1, - ConnectionId::new(0), + ConnectionId::next(), HandlerEvent::Message { rpc: GossipsubRpc { messages: vec![raw_message1], @@ -3035,7 +3035,7 @@ fn test_ignore_rpc_from_peers_below_graylist_threshold() { //receive from p2 gs.on_connection_handler_event( p2, - ConnectionId::new(0), + ConnectionId::next(), HandlerEvent::Message { rpc: GossipsubRpc { messages: vec![raw_message3], @@ -3647,7 +3647,7 @@ fn test_scoring_p4_invalid_signature() { gs.on_connection_handler_event( peers[0], - ConnectionId::new(0), + ConnectionId::next(), HandlerEvent::Message { rpc: GossipsubRpc { messages: vec![], @@ -4131,7 +4131,7 @@ fn test_scoring_p6() { for id in others.iter().take(3) { gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id: *id, - connection_id: ConnectionId::new(0), + connection_id: ConnectionId::next(), endpoint: &ConnectedPoint::Dialer { address: addr.clone(), role_override: Endpoint::Dialer, @@ -4152,7 +4152,7 @@ fn test_scoring_p6() { for peer in peers.iter().take(3) { gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id: *peer, - connection_id: ConnectionId::new(0), + connection_id: ConnectionId::next(), endpoint: &ConnectedPoint::Dialer { address: addr2.clone(), role_override: Endpoint::Dialer, @@ -4182,7 +4182,7 @@ fn test_scoring_p6() { //two times same ip doesn't count twice gs.on_swarm_event(FromSwarm::ConnectionEstablished(ConnectionEstablished { peer_id: peers[0], - connection_id: ConnectionId::new(0), + connection_id: ConnectionId::next(), endpoint: &ConnectedPoint::Dialer { address: addr, role_override: Endpoint::Dialer, @@ -5194,7 +5194,7 @@ fn test_subscribe_and_graft_with_negative_score() { let (mut gs2, _, _) = inject_nodes1().create_network(); - let connection_id = ConnectionId::new(0); + let connection_id = ConnectionId::next(); let topic = Topic::new("test"); diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index bf3bd7cf17a..7c93e456404 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -1294,7 +1294,7 @@ fn network_behaviour_on_address_change() { let local_peer_id = PeerId::random(); let remote_peer_id = PeerId::random(); - let connection_id = ConnectionId::new(1); + let connection_id = ConnectionId::next(); let old_address: Multiaddr = Protocol::Memory(1).into(); let new_address: Multiaddr = Protocol::Memory(2).into(); diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 30dff859d51..cf2392ab4d3 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -100,9 +100,6 @@ where /// The pending connections that are currently being negotiated. pending: HashMap>, - /// Next available identifier for a new connection / task. - next_connection_id: ConnectionId, - /// Size of the task command buffer (per task). task_command_buffer_size: usize, @@ -326,7 +323,6 @@ where counters: ConnectionCounters::new(limits), established: Default::default(), pending: Default::default(), - next_connection_id: ConnectionId::new(0), task_command_buffer_size: config.task_command_buffer_size, dial_concurrency_factor: config.dial_concurrency_factor, substream_upgrade_protocol_override: config.substream_upgrade_protocol_override, @@ -412,13 +408,6 @@ where self.established.keys() } - fn next_connection_id(&mut self) -> ConnectionId { - let connection_id = self.next_connection_id; - self.next_connection_id = self.next_connection_id + 1; - - connection_id - } - fn spawn(&mut self, task: BoxFuture<'static, ()>) { self.executor.spawn(task) } @@ -458,7 +447,7 @@ where dial_concurrency_factor_override.unwrap_or(self.dial_concurrency_factor), ); - let connection_id = self.next_connection_id(); + let connection_id = ConnectionId::next(); let (abort_notifier, abort_receiver) = oneshot::channel(); @@ -508,7 +497,7 @@ where return Err((limit, handler)); } - let connection_id = self.next_connection_id(); + let connection_id = ConnectionId::next(); let (abort_notifier, abort_receiver) = oneshot::channel(); From 11e5f74b33efb207a8dc82999a36bf6d50f47d1a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Jan 2023 12:33:23 +1100 Subject: [PATCH 061/177] Deprecate old new function --- core/src/connection.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/src/connection.rs b/core/src/connection.rs index 39a85750909..3949921c3e1 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -28,6 +28,16 @@ static NEXT_CONNECTION_ID: AtomicUsize = AtomicUsize::new(0); pub struct ConnectionId(usize); impl ConnectionId { + /// Creates a `ConnectionId` from a non-negative integer. + /// + /// This is primarily useful for creating connection IDs + /// in test environments. There is in general no guarantee + /// that all connection IDs are based on non-negative integers. + #[deprecated(since = "0.39.0", note = "Use `ConnectionId::next` instead.")] + pub fn new(id: usize) -> Self { + Self(id) + } + /// Returns the next available [`ConnectionId`]. pub fn next() -> Self { Self(NEXT_CONNECTION_ID.fetch_add(1, Ordering::SeqCst)) From 47cf01ff7bcfd4f7d9a31d30690021fe2b61ce3b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Jan 2023 12:34:39 +1100 Subject: [PATCH 062/177] Add changelog entry --- core/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index a7e24f5d616..18a45cccfaf 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.39.0 [unreleased] + +- Deprecate `ConnectionId::new` in favor of `ConnectionId::next`. See [PR 3327]. + +[PR 3327]: https://github.com/libp2p/rust-libp2p/pull/3327 + # 0.38.0 - Remove deprecated functions `StreamMuxerExt::next_{inbound,outbound}`. See [PR 3031]. From f77e443797d36b5e700c0b63cce4e6bce7e821a9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Jan 2023 13:30:45 +1100 Subject: [PATCH 063/177] Remove `handler` field from `NetworkBehaviourAction::Dial` --- protocols/autonat/src/behaviour.rs | 19 +- protocols/autonat/src/behaviour/as_server.rs | 4 +- protocols/floodsub/src/layer.rs | 17 +- protocols/gossipsub/src/behaviour.rs | 16 +- protocols/gossipsub/src/behaviour/tests.rs | 10 +- protocols/identify/src/behaviour.rs | 9 +- protocols/kad/src/behaviour.rs | 22 +- protocols/mdns/src/behaviour.rs | 3 +- protocols/ping/src/lib.rs | 4 +- protocols/rendezvous/src/client.rs | 21 +- protocols/rendezvous/src/server.rs | 11 +- protocols/request-response/src/lib.rs | 16 +- swarm-derive/src/lib.rs | 122 ++----- swarm/src/behaviour.rs | 336 ++----------------- swarm/src/behaviour/either.rs | 29 +- swarm/src/behaviour/toggle.rs | 10 +- swarm/src/connection/pool.rs | 57 ++-- swarm/src/dummy.rs | 6 +- swarm/src/keep_alive.rs | 3 +- swarm/src/lib.rs | 49 ++- swarm/src/test.rs | 12 +- swarm/tests/swarm_derive.rs | 4 +- 22 files changed, 204 insertions(+), 576 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 995ee44072e..ea13afe8650 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -40,7 +40,7 @@ use libp2p_swarm::{ ExpiredListenAddr, FromSwarm, }, ConnectionHandler, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, PollParameters, + NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use std::{ collections::{HashMap, VecDeque}, @@ -210,10 +210,7 @@ pub struct Behaviour { last_probe: Option, pending_actions: VecDeque< - NetworkBehaviourAction< - ::OutEvent, - ::ConnectionHandler, - >, + NetworkBehaviourAction<::OutEvent, THandlerInEvent>, >, probe_id: ProbeId, @@ -391,14 +388,14 @@ impl Behaviour { &mut self, DialFailure { peer_id, - handler, + connection_id, error, - }: DialFailure<::ConnectionHandler>, + }: DialFailure, ) { self.inner .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, - handler, + connection_id, error, })); if let Some(event) = self.as_server().on_outbound_dial_error(peer_id, error) { @@ -563,10 +560,8 @@ impl NetworkBehaviour for Behaviour { } } -type Action = NetworkBehaviourAction< - ::OutEvent, - ::ConnectionHandler, ->; +type Action = + NetworkBehaviourAction<::OutEvent, THandlerInEvent>; // Trait implemented for `AsClient` and `AsServer` to handle events from the inner [`request_response::Behaviour`] Protocol. trait HandleInnerEvent { diff --git a/protocols/autonat/src/behaviour/as_server.rs b/protocols/autonat/src/behaviour/as_server.rs index 8d08f7ed8d0..ea1e59821d4 100644 --- a/protocols/autonat/src/behaviour/as_server.rs +++ b/protocols/autonat/src/behaviour/as_server.rs @@ -29,7 +29,7 @@ use libp2p_request_response::{ }; use libp2p_swarm::{ dial_opts::{DialOpts, PeerCondition}, - DialError, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + DialError, NetworkBehaviourAction, PollParameters, }; use std::{ collections::{HashMap, HashSet, VecDeque}, @@ -138,7 +138,7 @@ impl<'a> HandleInnerEvent for AsServer<'a> { ) .addresses(addrs) .build(), - handler: self.inner.new_handler(), + connection_id: ConnectionId::next(), }, ]) } diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 776c0e8551b..109ebdca84a 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -30,7 +30,7 @@ use libp2p_core::{connection::ConnectionId, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, OneShotHandler, - PollParameters, + PollParameters, THandlerInEvent, }; use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler}; use log::warn; @@ -42,12 +42,7 @@ use std::{collections::VecDeque, iter}; /// Network behaviour that handles the floodsub protocol. pub struct Floodsub { /// Events that need to be yielded to the outside when polling. - events: VecDeque< - NetworkBehaviourAction< - FloodsubEvent, - OneShotHandler, - >, - >, + events: VecDeque>, config: FloodsubConfig, @@ -108,10 +103,9 @@ impl Floodsub { } if self.target_peers.insert(peer_id) { - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + connection_id: ConnectionId::next(), }); } } @@ -331,10 +325,9 @@ impl Floodsub { // We can be disconnected by the remote in case of inactivity for example, so we always // try to reconnect. if self.target_peers.contains(&peer_id) { - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + connection_id: ConnectionId::next(), }); } } @@ -472,7 +465,7 @@ impl NetworkBehaviour for Floodsub { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index fce25c12aff..3962433f56b 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -43,7 +43,7 @@ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, dial_opts::DialOpts, ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use wasm_timer::Instant; @@ -216,7 +216,7 @@ pub struct Gossipsub { config: GossipsubConfig, /// Events that need to be yielded to the outside when polling. - events: VecDeque>, + events: VecDeque>, /// Pools non-urgent control messages between heartbeats. control_pool: HashMap>, @@ -1134,10 +1134,9 @@ where if !self.peer_topics.contains_key(peer_id) { // Connect to peer debug!("Connecting to explicit peer {:?}", peer_id); - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer_id).build(), - handler, + connection_id: ConnectionId::next(), }); } } @@ -1635,10 +1634,9 @@ where self.px_peers.insert(peer_id); // dial peer - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + connection_id: ConnectionId::next(), }); } } @@ -3442,7 +3440,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } @@ -3491,7 +3489,7 @@ fn peer_added_to_mesh( new_topics: Vec<&TopicHash>, mesh: &HashMap>, known_topics: Option<&BTreeSet>, - events: &mut VecDeque>, + events: &mut VecDeque>, connections: &HashMap, ) { // Ensure there is an active connection @@ -3532,7 +3530,7 @@ fn peer_removed_from_mesh( old_topic: &TopicHash, mesh: &HashMap>, known_topics: Option<&BTreeSet>, - events: &mut VecDeque>, + events: &mut VecDeque>, connections: &HashMap, ) { // Ensure there is an active connection diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 7aa9adccbbc..65914d6feea 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -1386,7 +1386,7 @@ fn test_explicit_peer_gets_connected() { .events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => opts.get_peer_id() == Some(peer), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(peer), _ => false, }) .count(); @@ -1427,8 +1427,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => - opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(*peer), _ => false, }) .count(), @@ -1443,8 +1442,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => - opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(*peer), _ => false, }) .count() @@ -1824,7 +1822,7 @@ fn test_connect_to_px_peers_on_handle_prune() { .events .iter() .filter_map(|e| match e { - NetworkBehaviourAction::Dial { opts, handler: _ } => opts.get_peer_id(), + NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id(), _ => None, }) .collect(); diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 123c8140ecd..64e765f6e22 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -27,7 +27,7 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailu use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, + NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, }; use lru::LruCache; use std::num::NonZeroUsize; @@ -54,7 +54,7 @@ pub struct Behaviour { /// with current information about the local peer. requests: Vec, /// Pending events to be emitted when polled. - events: VecDeque>, + events: VecDeque>, /// The addresses of all peers that we have discovered. discovered_peers: PeerCache, @@ -199,10 +199,9 @@ impl Behaviour { if !self.requests.contains(&request) { self.requests.push(request); - let handler = self.new_handler(); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(p).build(), - handler, + connection_id: ConnectionId::next(), }); } } @@ -310,7 +309,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 6ceb8c73d54..48cf8dd9695 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -46,7 +46,7 @@ use libp2p_swarm::behaviour::{ use libp2p_swarm::{ dial_opts::{self, DialOpts}, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use log::{debug, info, warn}; use smallvec::SmallVec; @@ -101,7 +101,7 @@ pub struct Kademlia { connection_idle_timeout: Duration, /// Queued events to return when the behaviour is being polled. - queued_events: VecDeque>>, + queued_events: VecDeque>>, listen_addresses: ListenAddresses, @@ -571,10 +571,9 @@ where RoutingUpdate::Failed } kbucket::InsertResult::Pending { disconnected } => { - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()).build(), - handler, + connection_id: ConnectionId::next(), }); RoutingUpdate::Pending } @@ -1221,11 +1220,10 @@ where // // Only try dialing peer if not currently connected. if !self.connected_peers.contains(disconnected.preimage()) { - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()) .build(), - handler, + connection_id: ConnectionId::next(), }) } } @@ -1917,12 +1915,7 @@ where } } - fn on_dial_failure( - &mut self, - DialFailure { peer_id, error, .. }: DialFailure< - ::ConnectionHandler, - >, - ) { + fn on_dial_failure(&mut self, DialFailure { peer_id, error, .. }: DialFailure) { let peer_id = match peer_id { Some(id) => id, // Not interested in dial failures to unknown peers. @@ -2293,7 +2286,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { let now = Instant::now(); // Calculate the available capacity for queries triggered by background jobs. @@ -2392,10 +2385,9 @@ where }); } else if &peer_id != self.kbuckets.local_key().preimage() { query.inner.pending_rpcs.push((peer_id, event)); - let handler = self.new_handler(); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - handler, + connection_id: ConnectionId::next(), }); } } diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 815a23c9bdc..e1b19a90acc 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -36,6 +36,7 @@ use libp2p_swarm::{ use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; use std::{cmp, fmt, io, net::IpAddr, pin::Pin, task::Context, task::Poll, time::Instant}; +use void::Void; /// An abstraction to allow for compatibility with various async runtimes. pub trait Provider: 'static { @@ -231,7 +232,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll> { // Poll ifwatch. while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) { match event { diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 6e481500df9..23dccc769dc 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -49,7 +49,7 @@ use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{connection::ConnectionId, PeerId}; use libp2p_swarm::{ - behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + behaviour::FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, }; use std::{ collections::VecDeque, @@ -131,7 +131,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(e) = self.events.pop_back() { let Event { result, peer } = &e; diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 41c4daf0ec6..66e62602ae6 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -22,7 +22,7 @@ use crate::codec::{Cookie, ErrorCode, Namespace, NewRegistration, Registration, use crate::handler; use crate::handler::outbound; use crate::handler::outbound::OpenInfo; -use crate::substream_handler::SubstreamConnectionHandler; +use crate::substream_handler::{InEvent, SubstreamConnectionHandler}; use futures::future::BoxFuture; use futures::future::FutureExt; use futures::stream::FuturesUnordered; @@ -35,19 +35,15 @@ use libp2p_core::{Multiaddr, PeerId, PeerRecord}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, + PollParameters, THandlerInEvent, }; use std::collections::{HashMap, VecDeque}; use std::iter::FromIterator; use std::task::{Context, Poll}; +use void::Void; pub struct Behaviour { - events: VecDeque< - NetworkBehaviourAction< - Event, - SubstreamConnectionHandler, - >, - >, + events: VecDeque>>, keypair: Keypair, pending_register_requests: Vec<(Namespace, PeerId, Option)>, @@ -220,7 +216,7 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } @@ -294,12 +290,7 @@ fn handle_outbound_event( peer_id: PeerId, discovered_peers: &mut HashMap<(PeerId, Namespace), Vec>, expiring_registrations: &mut FuturesUnordered>, -) -> Vec< - NetworkBehaviourAction< - Event, - SubstreamConnectionHandler, - >, -> { +) -> Vec>> { match event { outbound::OutEvent::Registered { namespace, ttl } => { vec![NetworkBehaviourAction::GenerateEvent(Event::Registered { diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 4126b6e3e28..840611eddb0 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -20,7 +20,7 @@ use crate::codec::{Cookie, ErrorCode, Namespace, NewRegistration, Registration, Ttl}; use crate::handler::inbound; -use crate::substream_handler::{InboundSubstreamId, SubstreamConnectionHandler}; +use crate::substream_handler::{InEvent, InboundSubstreamId, SubstreamConnectionHandler}; use crate::{handler, MAX_TTL, MIN_TTL}; use bimap::BiMap; use futures::future::BoxFuture; @@ -32,6 +32,7 @@ use libp2p_core::PeerId; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandlerInEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::iter::FromIterator; @@ -40,9 +41,7 @@ use std::time::Duration; use void::Void; pub struct Behaviour { - events: VecDeque< - NetworkBehaviourAction>, - >, + events: VecDeque>>, registrations: Registrations, } @@ -148,7 +147,7 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Poll::Ready(ExpiredRegistration(registration)) = self.registrations.poll(cx) { return Poll::Ready(NetworkBehaviourAction::GenerateEvent( Event::RegistrationExpired(registration), @@ -186,7 +185,7 @@ fn handle_inbound_event( connection: ConnectionId, id: InboundSubstreamId, registrations: &mut Registrations, -) -> Vec>> { +) -> Vec>> { match event { // bad registration inbound::OutEvent::RegistrationRequested(registration) diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index f5fa3067f80..a5e3ae95b82 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -75,6 +75,7 @@ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandlerInEvent, }; use smallvec::SmallVec; use std::{ @@ -348,8 +349,9 @@ where /// The protocol codec for reading and writing requests and responses. codec: TCodec, /// Pending events to return from `poll`. - pending_events: - VecDeque, Handler>>, + pending_events: VecDeque< + NetworkBehaviourAction, RequestProtocol>, + >, /// The currently connected peers, their pending outbound and inbound responses and their known, /// reachable addresses, if any. connected: HashMap>, @@ -416,10 +418,9 @@ where }; if let Some(request) = self.try_send_request(peer, request) { - let handler = self.new_handler(); self.pending_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer).build(), - handler, + connection_id: ConnectionId::next(), }); self.pending_outbound_requests .entry(*peer) @@ -695,10 +696,7 @@ where } } - fn on_dial_failure( - &mut self, - DialFailure { peer_id, .. }: DialFailure<::ConnectionHandler>, - ) { + fn on_dial_failure(&mut self, DialFailure { peer_id, .. }: DialFailure) { 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 @@ -931,7 +929,7 @@ where &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(ev) = self.pending_events.pop_front() { return Poll::Ready(ev); } else if self.pending_events.capacity() > EMPTY_QUEUE_SHRINK_THRESHOLD { diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 489ec8c7bc6..9ff690b323b 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -74,6 +74,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let expired_external_addr = quote! { #prelude_path::ExpiredExternalAddr }; let listener_error = quote! { #prelude_path::ListenerError }; let listener_closed = quote! { #prelude_path::ListenerClosed }; + let t_handler_in_event = quote! { #prelude_path::THandlerInEvent }; // Build the generics. let impl_generics = { @@ -289,37 +290,24 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .fields .iter() .enumerate() - // The outmost handler belongs to the last behaviour. - .rev() - .enumerate() - .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 } - } else { - quote! { - let (handlers, handler) = handlers.into_inner() - } - }; - + .map(|(enum_n, field)| { let inject = match field.ident { Some(ref i) => quote! { self.#i.on_swarm_event(#from_swarm::DialFailure(#dial_failure { peer_id, - handler, + connection_id, error, })); }, None => quote! { self.#enum_n.on_swarm_event(#from_swarm::DialFailure(#dial_failure { peer_id, - handler, + connection_id, error, })); }, }; quote! { - #handler; #inject; } }) @@ -327,42 +315,32 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { // 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.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { - local_addr, - send_back_addr, - handler, - })); - }, - None => quote! { - self.#enum_n.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { - local_addr, - send_back_addr, - handler, - })); - }, - }; + let on_listen_failure_stmts = { + data_struct + .fields + .iter() + .enumerate() + .map(|(enum_n, field)| { + let inject = match field.ident { + Some(ref i) => quote! { + self.#i.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { + local_addr, + send_back_addr, + })); + }, + None => quote! { + self.#enum_n.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { + local_addr, + send_back_addr, + })); + }, + }; - quote! { - #handler; - #inject; - } - }, - ) - }; + quote! { + #inject; + } + }) + }; // Build the list of statements to put in the body of `on_swarm_event()` // for the `FromSwarm::NewListener` variant. @@ -607,38 +585,6 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { wrapped_event = quote!{ #either_ident::First(#wrapped_event) }; } - // `Dial` provides a handler of the specific behaviour triggering the - // event. Though in order for the final handler to be able to handle - // protocols of all behaviours, the provided handler needs to be - // combined with handlers of all other behaviours. - let provided_handler_and_new_handlers = { - let mut out_handler = None; - - for (f_n, f) in data_struct.fields.iter().enumerate() { - let f_name = match f.ident { - Some(ref i) => quote! { self.#i }, - None => quote! { self.#f_n }, - }; - - let builder = if field_n == f_n { - // The behaviour that triggered the event. Thus, instead of - // creating a new handler, use the provided handler. - quote! { provided_handler } - } else { - quote! { #f_name.new_handler() } - }; - - match out_handler { - Some(h) => { - out_handler = Some(quote! { #into_connection_handler::select(#h, #builder) }) - } - ref mut h @ None => *h = Some(builder), - } - } - - out_handler.unwrap_or(quote! {()}) // TODO: See test `empty`. - }; - let generate_event_match_arm = { // If the `NetworkBehaviour`'s `OutEvent` is generated by the derive macro, wrap the sub // `NetworkBehaviour` `OutEvent` in the variant of the generated `OutEvent`. If the @@ -666,8 +612,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { loop { match #trait_to_impl::poll(&mut self.#field, cx, poll_params) { #generate_event_match_arm - std::task::Poll::Ready(#network_behaviour_action::Dial { opts, handler: provided_handler }) => { - return std::task::Poll::Ready(#network_behaviour_action::Dial { opts, handler: #provided_handler_and_new_handlers }); + std::task::Poll::Ready(#network_behaviour_action::Dial { opts, connection_id }) => { + return std::task::Poll::Ready(#network_behaviour_action::Dial { opts, connection_id }); } std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { peer_id, handler, event }) => { return std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { @@ -726,7 +672,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } } - fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action> { + fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action>> { use #prelude_path::futures::*; #(#poll_stmts)* std::task::Poll::Pending @@ -744,10 +690,10 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #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 }) + #dial_failure { peer_id, connection_id, error }) => { #(#on_dial_failure_stmts)* } #from_swarm::ListenFailure( - #listen_failure { local_addr, send_back_addr, handler: handlers }) + #listen_failure { local_addr, send_back_addr }) => { #(#on_listen_failure_stmts)* } #from_swarm::NewListener( #new_listener { listener_id }) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 6fc494b1578..d964e2a103f 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -28,19 +28,12 @@ pub use listen_addresses::ListenAddresses; use crate::dial_opts::DialOpts; use crate::handler::{ConnectionHandler, IntoConnectionHandler}; -use crate::{AddressRecord, AddressScore, DialError}; +use crate::{AddressRecord, AddressScore, DialError, THandlerInEvent}; use libp2p_core::{ connection::ConnectionId, transport::ListenerId, ConnectedPoint, Multiaddr, PeerId, }; use std::{task::Context, task::Poll}; -/// Custom event that can be received by the [`ConnectionHandler`]. -pub(crate) type THandlerInEvent = - <::Handler as ConnectionHandler>::InEvent; - -pub(crate) type THandlerOutEvent = - <::Handler as ConnectionHandler>::OutEvent; - /// A [`NetworkBehaviour`] defines the behaviour of the local node on the network. /// /// In contrast to [`Transport`](libp2p_core::Transport) which defines **how** to send bytes on the @@ -184,7 +177,7 @@ pub trait NetworkBehaviour: 'static { &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll>; + ) -> Poll>>; } /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. @@ -230,16 +223,8 @@ pub trait PollParameters { /// in whose context it is executing. /// /// [`Swarm`]: super::Swarm -// -// Note: `TInEvent` is needed to be able to implement -// [`NetworkBehaviourAction::map_in`], mapping the handler `InEvent` leaving the -// handler itself untouched. #[derive(Debug)] -pub enum NetworkBehaviourAction< - TOutEvent, - THandler: IntoConnectionHandler, - TInEvent = THandlerInEvent, -> { +pub enum NetworkBehaviourAction { /// Instructs the `Swarm` to return an event when it is being polled. GenerateEvent(TOutEvent), @@ -248,177 +233,13 @@ pub enum NetworkBehaviourAction< /// On success, [`NetworkBehaviour::on_swarm_event`] with `ConnectionEstablished` is invoked. /// On failure, [`NetworkBehaviour::on_swarm_event`] with `DialFailure` is invoked. /// - /// Note that the provided handler is returned to the [`NetworkBehaviour`] on connection failure - /// and connection closing. Thus it can be used to carry state, which otherwise would have to be - /// tracked in the [`NetworkBehaviour`] itself. E.g. a message destined to an unconnected peer - /// can be included in the handler, and thus directly send on connection success or extracted by - /// the [`NetworkBehaviour`] on connection failure. - /// - /// # Example carrying state in the handler - /// - /// ```rust - /// # use futures::executor::block_on; - /// # use futures::stream::StreamExt; - /// # use libp2p_core::connection::ConnectionId; - /// # use libp2p_core::identity; - /// # use libp2p_core::transport::{MemoryTransport, Transport}; - /// # use libp2p_core::upgrade::{self, DeniedUpgrade, InboundUpgrade, OutboundUpgrade}; - /// # use libp2p_core::PeerId; - /// # use libp2p_plaintext::PlainText2Config; - /// # use libp2p_swarm::{ - /// # FromSwarm, DialFailure, DialError, IntoConnectionHandler, KeepAlive, NegotiatedSubstream, - /// # NetworkBehaviour, NetworkBehaviourAction, PollParameters, ConnectionHandler, - /// # ConnectionHandlerEvent, ConnectionHandlerUpgrErr, SubstreamProtocol, Swarm, SwarmEvent, - /// # }; - /// # use libp2p_swarm::handler::ConnectionEvent; - /// # use libp2p_swarm::dial_opts::{DialOpts, PeerCondition}; - /// # use libp2p_yamux as yamux; - /// # use std::collections::VecDeque; - /// # use std::task::{Context, Poll}; - /// # use void::Void; - /// # - /// # let local_key = identity::Keypair::generate_ed25519(); - /// # let local_public_key = local_key.public(); - /// # let local_peer_id = PeerId::from(local_public_key.clone()); - /// # - /// # let transport = MemoryTransport::default() - /// # .upgrade(upgrade::Version::V1) - /// # .authenticate(PlainText2Config { local_public_key }) - /// # .multiplex(yamux::YamuxConfig::default()) - /// # .boxed(); - /// # - /// # let mut swarm = Swarm::with_threadpool_executor(transport, MyBehaviour::default(), local_peer_id); - /// # - /// // Super precious message that we should better not lose. - /// let message = PreciousMessage("My precious message".to_string()); - /// - /// // Unfortunately this peer is offline, thus sending our message to it will fail. - /// let offline_peer = PeerId::random(); - /// - /// // Let's send it anyways. We should get it back in case connecting to the peer fails. - /// swarm.behaviour_mut().send(offline_peer, message); - /// - /// block_on(async { - /// // As expected, sending failed. But great news, we got our message back. - /// matches!( - /// swarm.next().await.expect("Infinite stream"), - /// SwarmEvent::Behaviour(PreciousMessage(_)) - /// ); - /// }); - /// - /// #[derive(Default)] - /// struct MyBehaviour { - /// outbox_to_swarm: VecDeque>, - /// } - /// - /// impl MyBehaviour { - /// fn send(&mut self, peer_id: PeerId, msg: PreciousMessage) { - /// self.outbox_to_swarm - /// .push_back(NetworkBehaviourAction::Dial { - /// opts: DialOpts::peer_id(peer_id) - /// .condition(PeerCondition::Always) - /// .build(), - /// handler: MyHandler { message: Some(msg) }, - /// }); - /// } - /// } - /// # - /// impl NetworkBehaviour for MyBehaviour { - /// # type ConnectionHandler = MyHandler; - /// # type OutEvent = PreciousMessage; - /// # - /// # fn new_handler(&mut self) -> Self::ConnectionHandler { - /// # MyHandler { message: None } - /// # } - /// # - /// # - /// # fn on_connection_handler_event( - /// # &mut self, - /// # _: PeerId, - /// # _: ConnectionId, - /// # _: <::Handler as ConnectionHandler>::OutEvent, - /// # ) { - /// # unreachable!(); - /// # } - /// # - /// fn on_swarm_event( - /// &mut self, - /// event: FromSwarm, - /// ) { - /// // As expected, sending the message failed. But lucky us, we got the handler back, thus - /// // the precious message is not lost and we can return it back to the user. - /// if let FromSwarm::DialFailure(DialFailure { handler, .. }) = event { - /// let msg = handler.message.unwrap(); - /// self.outbox_to_swarm - /// .push_back(NetworkBehaviourAction::GenerateEvent(msg)) - /// } - /// } - /// # - /// # fn poll( - /// # &mut self, - /// # _: &mut Context<'_>, - /// # _: &mut impl PollParameters, - /// # ) -> Poll> { - /// # if let Some(action) = self.outbox_to_swarm.pop_front() { - /// # return Poll::Ready(action); - /// # } - /// # Poll::Pending - /// # } - /// } - /// - /// # struct MyHandler { - /// # message: Option, - /// # } - /// # - /// # impl ConnectionHandler for MyHandler { - /// # type InEvent = Void; - /// # type OutEvent = Void; - /// # type Error = Void; - /// # type InboundProtocol = DeniedUpgrade; - /// # type OutboundProtocol = DeniedUpgrade; - /// # type InboundOpenInfo = (); - /// # type OutboundOpenInfo = Void; - /// # - /// # fn listen_protocol( - /// # &self, - /// # ) -> SubstreamProtocol { - /// # SubstreamProtocol::new(DeniedUpgrade, ()) - /// # } - /// # - /// # fn on_behaviour_event(&mut self, _event: Self::InEvent) {} - /// # - /// # fn on_connection_event( - /// # &mut self, - /// # event: ConnectionEvent< - /// # Self::InboundProtocol, - /// # Self::OutboundProtocol, - /// # Self::InboundOpenInfo, - /// # Self::OutboundOpenInfo, - /// # >, - /// # ) {} - /// # - /// # fn connection_keep_alive(&self) -> KeepAlive { - /// # KeepAlive::Yes - /// # } - /// # - /// # fn poll( - /// # &mut self, - /// # _: &mut Context<'_>, - /// # ) -> Poll< - /// # ConnectionHandlerEvent< - /// # Self::OutboundProtocol, - /// # Self::OutboundOpenInfo, - /// # Self::OutEvent, - /// # Self::Error, - /// # >, - /// # > { - /// # todo!("If `Self::message.is_some()` send the message to the remote.") - /// # } - /// # } - /// # #[derive(Debug, PartialEq, Eq)] - /// # struct PreciousMessage(String); - /// ``` - Dial { opts: DialOpts, handler: THandler }, + /// The provided [`ConnectionId`] will be used throughout the connection's lifecycle to associate + /// events with it. This allows a [`NetworkBehaviour`] to identify a connection that resulted out + /// of its own dial request. + Dial { + opts: DialOpts, + connection_id: ConnectionId, + }, /// Instructs the `Swarm` to send an event to the handler dedicated to a /// connection with a peer. @@ -478,19 +299,21 @@ pub enum NetworkBehaviourAction< }, } -impl - NetworkBehaviourAction -{ +impl NetworkBehaviourAction { /// Map the handler event. pub fn map_in( self, f: impl FnOnce(TInEventOld) -> TInEventNew, - ) -> NetworkBehaviourAction { + ) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => { - NetworkBehaviourAction::Dial { opts, handler } - } + NetworkBehaviourAction::Dial { + opts, + connection_id, + } => NetworkBehaviourAction::Dial { + opts, + connection_id, + }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -514,100 +337,20 @@ impl } } -impl NetworkBehaviourAction { +impl NetworkBehaviourAction { /// Map the event the swarm will return. - pub fn map_out(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction { - match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), - NetworkBehaviourAction::Dial { opts, handler } => { - NetworkBehaviourAction::Dial { opts, handler } - } - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - } => NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - }, - NetworkBehaviourAction::ReportObservedAddr { address, score } => { - NetworkBehaviourAction::ReportObservedAddr { address, score } - } - NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - } => NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - }, - } - } -} - -impl NetworkBehaviourAction -where - THandlerOld: IntoConnectionHandler, - ::Handler: ConnectionHandler, -{ - /// Map the handler. - pub fn map_handler( + pub fn map_out( self, - f: impl FnOnce(THandlerOld) -> THandlerNew, - ) -> NetworkBehaviourAction - where - THandlerNew: IntoConnectionHandler, - ::Handler: ConnectionHandler, - { + f: impl FnOnce(TOutEvent) -> E, + ) -> NetworkBehaviourAction { match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial { + NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), + NetworkBehaviourAction::Dial { opts, - handler: f(handler), - }, - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - } => NetworkBehaviourAction::NotifyHandler { - peer_id, - handler, - event, - }, - NetworkBehaviourAction::ReportObservedAddr { address, score } => { - NetworkBehaviourAction::ReportObservedAddr { address, score } - } - NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - } => NetworkBehaviourAction::CloseConnection { - peer_id, - connection, - }, - } - } -} - -impl NetworkBehaviourAction -where - THandlerOld: IntoConnectionHandler, - ::Handler: ConnectionHandler, -{ - /// Map the handler and handler event. - pub fn map_handler_and_in( - self, - f_handler: impl FnOnce(THandlerOld) -> THandlerNew, - f_in_event: impl FnOnce(TInEventOld) -> TInEventNew, - ) -> NetworkBehaviourAction - where - THandlerNew: IntoConnectionHandler, - ::Handler: ConnectionHandler, - { - match self { - NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial { + connection_id, + } => NetworkBehaviourAction::Dial { opts, - handler: f_handler(handler), + connection_id, }, NetworkBehaviourAction::NotifyHandler { peer_id, @@ -616,7 +359,7 @@ where } => NetworkBehaviourAction::NotifyHandler { peer_id, handler, - event: f_in_event(event), + event, }, NetworkBehaviourAction::ReportObservedAddr { address, score } => { NetworkBehaviourAction::ReportObservedAddr { address, score } @@ -672,13 +415,13 @@ pub enum FromSwarm<'a, Handler: IntoConnectionHandler> { AddressChange(AddressChange<'a>), /// Informs the behaviour that the dial to a known /// or unknown node failed. - DialFailure(DialFailure<'a, Handler>), + DialFailure(DialFailure<'a>), /// 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>), + ListenFailure(ListenFailure<'a>), /// Informs the behaviour that a new listener was created. NewListener(NewListener), /// Informs the behaviour that we have started listening on a new multiaddr. @@ -733,10 +476,10 @@ pub struct AddressChange<'a> { /// [`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 struct DialFailure<'a> { pub peer_id: Option, - pub handler: Handler, pub error: &'a DialError, + pub connection_id: ConnectionId, } /// [`FromSwarm`] variant that informs the behaviour that an error @@ -745,10 +488,9 @@ pub struct DialFailure<'a, Handler> { /// 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 struct ListenFailure<'a> { 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. @@ -804,7 +546,6 @@ pub struct ExpiredExternalAddr<'a> { impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { fn map_handler( self, - map_into_handler: impl FnOnce(Handler) -> NewHandler, map_handler: impl FnOnce( ::Handler, ) -> ::Handler, @@ -812,13 +553,12 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { where NewHandler: IntoConnectionHandler, { - self.maybe_map_handler(|h| Some(map_into_handler(h)), |h| Some(map_handler(h))) + self.maybe_map_handler(|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>, @@ -866,21 +606,19 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { })), FromSwarm::DialFailure(DialFailure { peer_id, - handler, error, + connection_id, }) => Some(FromSwarm::DialFailure(DialFailure { peer_id, - handler: map_into_handler(handler)?, error, + connection_id, })), 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 })) diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 073a0275548..b43ef73fbe8 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -20,6 +20,7 @@ use crate::behaviour::{self, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use crate::handler::either::IntoEitherHandler; +use crate::THandlerInEvent; use either::Either; use libp2p_core::{Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -49,20 +50,14 @@ where fn on_swarm_event(&mut self, event: behaviour::FromSwarm) { match self { - Either::Left(b) => b.on_swarm_event(event.map_handler( - |h| h.unwrap_left(), - |h| match h { - Either::Left(h) => h, - Either::Right(_) => unreachable!(), - }, - )), - Either::Right(b) => b.on_swarm_event(event.map_handler( - |h| h.unwrap_right(), - |h| match h { - Either::Right(h) => h, - Either::Left(_) => unreachable!(), - }, - )), + Either::Left(b) => b.on_swarm_event(event.map_handler(|h| match h { + Either::Left(h) => h, + Either::Right(_) => unreachable!(), + })), + Either::Right(b) => b.on_swarm_event(event.map_handler(|h| match h { + Either::Right(h) => h, + Either::Left(_) => unreachable!(), + })), } } @@ -87,14 +82,14 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { let event = match self { Either::Left(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Left) - .map_handler_and_in(IntoEitherHandler::Left, Either::Left), + .map_in(Either::Left), Either::Right(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Right) - .map_handler_and_in(IntoEitherHandler::Right, Either::Right), + .map_in(Either::Right), }; Poll::Ready(event) diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index ae198dc2bd3..6edcc3bd9ce 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -25,7 +25,7 @@ use crate::handler::{ IntoConnectionHandler, KeepAlive, ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; -use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters}; +use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent}; use either::Either; use libp2p_core::{ either::{EitherError, EitherOutput}, @@ -86,7 +86,7 @@ where 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) { + if let Some(event) = event.maybe_map_handler(|h| h.inner) { behaviour.on_swarm_event(event); } } @@ -107,11 +107,9 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(inner) = self.inner.as_mut() { - inner.poll(cx, params).map(|action| { - action.map_handler(|h| ToggleIntoConnectionHandler { inner: Some(h) }) - }) + inner.poll(cx, params) } else { Poll::Pending } diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index cf2392ab4d3..60a96173030 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -21,7 +21,6 @@ use crate::connection::Connection; use crate::{ - behaviour::{THandlerInEvent, THandlerOutEvent}, connection::{ Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError, @@ -98,7 +97,7 @@ where >, /// The pending connections that are currently being negotiated. - pending: HashMap>, + pending: HashMap, /// Size of the task command buffer (per task). task_command_buffer_size: usize, @@ -184,11 +183,9 @@ impl EstablishedConnection { } } -struct PendingConnection { +struct PendingConnection { /// [`PeerId`] of the remote peer. peer_id: Option, - /// Handler to handle connection once no longer pending but established. - handler: THandler, endpoint: PendingPoint, /// When dropped, notifies the task which then knows to terminate. abort_notifier: Option>, @@ -196,7 +193,7 @@ struct PendingConnection { accepted_at: Instant, } -impl PendingConnection { +impl PendingConnection { fn is_for_same_remote_as(&self, other: PeerId) -> bool { self.peer_id.map_or(false, |peer| peer == other) } @@ -266,8 +263,6 @@ pub enum PoolEvent { id: ConnectionId, /// The error that occurred. error: PendingOutboundConnectionError, - /// The handler that was supposed to handle the connection. - handler: THandler, /// The (expected) peer of the failed connection. peer: Option, }, @@ -282,8 +277,6 @@ pub enum PoolEvent { local_addr: Multiaddr, /// The error that occurred. error: PendingInboundConnectionError, - /// The handler that was supposed to handle the connection. - handler: THandler, }, /// A node has produced an event. @@ -291,7 +284,7 @@ pub enum PoolEvent { id: ConnectionId, peer_id: PeerId, /// The produced event. - event: THandlerOutEvent, + event: <::Handler as ConnectionHandler>::OutEvent, }, /// The connection to a node has changed its address. @@ -344,7 +337,11 @@ where pub fn get_established( &mut self, id: ConnectionId, - ) -> Option<&mut EstablishedConnection>> { + ) -> Option< + &mut EstablishedConnection< + <::Handler as ConnectionHandler>::InEvent, + >, + > { self.established .values_mut() .find_map(|connections| connections.get_mut(&id)) @@ -434,21 +431,17 @@ where >, >, peer: Option, - handler: THandler, role_override: Endpoint, dial_concurrency_factor_override: Option, - ) -> Result { - if let Err(limit) = self.counters.check_max_pending_outgoing() { - return Err((limit, handler)); - }; + connection_id: ConnectionId, + ) -> Result<(), ConnectionLimit> { + self.counters.check_max_pending_outgoing()?; let dial = ConcurrentDial::new( dials, dial_concurrency_factor_override.unwrap_or(self.dial_concurrency_factor), ); - let connection_id = ConnectionId::next(); - let (abort_notifier, abort_receiver) = oneshot::channel(); self.spawn( @@ -468,13 +461,13 @@ where connection_id, PendingConnection { peer_id: peer, - handler, endpoint, abort_notifier: Some(abort_notifier), accepted_at: Instant::now(), }, ); - Ok(connection_id) + + Ok(()) } /// Adds a pending incoming connection to the pool in the form of a @@ -485,17 +478,14 @@ where pub fn add_incoming( &mut self, future: TFut, - handler: THandler, info: IncomingInfo<'_>, - ) -> Result + ) -> Result where TFut: Future> + Send + 'static, { let endpoint = info.create_connected_point(); - if let Err(limit) = self.counters.check_max_pending_incoming() { - return Err((limit, handler)); - } + self.counters.check_max_pending_incoming()?; let connection_id = ConnectionId::next(); @@ -516,7 +506,6 @@ where connection_id, PendingConnection { peer_id: None, - handler, endpoint: endpoint.into(), abort_notifier: Some(abort_notifier), accepted_at: Instant::now(), @@ -526,7 +515,11 @@ where } /// Polls the connection pool for events. - pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> + pub fn poll( + &mut self, + cx: &mut Context<'_>, + mut new_handler_fn: impl FnMut() -> THandler, + ) -> Poll> where THandler: IntoConnectionHandler + 'static, THandler::Handler: ConnectionHandler + Send, @@ -610,7 +603,6 @@ where } => { let PendingConnection { peer_id: expected_peer_id, - handler, endpoint, abort_notifier: _, accepted_at, @@ -713,7 +705,6 @@ where id, error: error .map(|t| vec![(endpoint.get_remote_address().clone(), t)]), - handler, peer: expected_peer_id.or(Some(obtained_peer_id)), }) } @@ -724,7 +715,6 @@ where return Poll::Ready(PoolEvent::PendingInboundConnectionError { id, error, - handler, send_back_addr, local_addr, }) @@ -749,7 +739,7 @@ where let connection = Connection::new( muxer, - handler.into_handler(&obtained_peer_id, &endpoint), + new_handler_fn().into_handler(&obtained_peer_id, &endpoint), self.substream_upgrade_protocol_override, self.max_negotiating_inbound_streams, ); @@ -776,7 +766,6 @@ where task::PendingConnectionEvent::PendingFailed { id, error } => { if let Some(PendingConnection { peer_id, - handler, endpoint, abort_notifier: _, accepted_at: _, // Ignoring the time it took for the connection to fail. @@ -789,7 +778,6 @@ where return Poll::Ready(PoolEvent::PendingOutboundConnectionError { id, error, - handler, peer: peer_id, }); } @@ -803,7 +791,6 @@ where return Poll::Ready(PoolEvent::PendingInboundConnectionError { id, error, - handler, send_back_addr, local_addr, }); diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 4ec58581c2e..2a9ec75bccb 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -2,7 +2,9 @@ use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, Poll use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; -use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol}; +use crate::{ + ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandlerInEvent, +}; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::PeerId; @@ -29,7 +31,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { Poll::Pending } diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index bd1ed812b8b..7e2c822fb31 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -3,6 +3,7 @@ use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, SubstreamProtocol, }; +use crate::THandlerInEvent; use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::PeerId; @@ -34,7 +35,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { Poll::Pending } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index cf0b4c3b08a..522c911bbb2 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -91,6 +91,7 @@ pub mod derive_prelude { pub use crate::NetworkBehaviour; pub use crate::NetworkBehaviourAction; pub use crate::PollParameters; + pub use crate::THandlerInEvent; pub use futures::prelude as futures; pub use libp2p_core::connection::ConnectionId; pub use libp2p_core::either::EitherOutput; @@ -163,11 +164,11 @@ type THandler = ::ConnectionHandler; /// Custom event that can be received by the [`ConnectionHandler`] of the /// [`NetworkBehaviour`]. -type THandlerInEvent = +pub type THandlerInEvent = < as IntoConnectionHandler>::Handler as ConnectionHandler>::InEvent; /// Custom event that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -type THandlerOutEvent = +pub type THandlerOutEvent = < as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent; /// Custom error that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. @@ -503,14 +504,13 @@ where /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); /// ``` pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { - let handler = self.behaviour.new_handler(); - self.dial_with_handler(opts.into(), handler) + self.dial_with_id(opts.into(), ConnectionId::next()) } - fn dial_with_handler( + fn dial_with_id( &mut self, dial_opts: DialOpts, - handler: ::ConnectionHandler, + connection_id: ConnectionId, ) -> Result<(), DialError> { let peer_id = dial_opts .get_or_parse_peer_id() @@ -531,8 +531,8 @@ where self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, - handler, error: &e, + connection_id, })); return Err(e); @@ -545,8 +545,8 @@ where self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id: Some(peer_id), - handler, error: &error, + connection_id, })); return Err(error); @@ -573,8 +573,8 @@ where self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, - handler, error: &error, + connection_id, })); return Err(error); }; @@ -608,18 +608,18 @@ where match self.pool.add_outgoing( dials, peer_id, - handler, dial_opts.role_override(), dial_opts.dial_concurrency_override(), + connection_id, ) { - Ok(_connection_id) => Ok(()), - Err((connection_limit, handler)) => { + Ok(()) => Ok(()), + Err(connection_limit) => { let error = DialError::ConnectionLimit(connection_limit); self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, - handler, error: &error, + connection_id, })); Err(error) @@ -819,9 +819,8 @@ where } } PoolEvent::PendingOutboundConnectionError { - id: _, + id: connection_id, error, - handler, peer, } => { let error = error.into(); @@ -829,8 +828,8 @@ where self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id: peer, - handler, error: &error, + connection_id, })); if let Some(peer) = peer { @@ -849,14 +848,12 @@ where send_back_addr, local_addr, error, - handler, } => { log::debug!("Incoming connection failed: {:?}", error); self.behaviour .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr: &local_addr, send_back_addr: &send_back_addr, - handler, })); return Some(SwarmEvent::IncomingConnectionError { local_addr, @@ -955,10 +952,8 @@ where local_addr, send_back_addr, } => { - let handler = self.behaviour.new_handler(); match self.pool.add_incoming( upgrade, - handler, IncomingInfo { local_addr: &local_addr, send_back_addr: &send_back_addr, @@ -970,12 +965,11 @@ where send_back_addr, }); } - Err((connection_limit, handler)) => { + Err(connection_limit) => { self.behaviour .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr: &local_addr, send_back_addr: &send_back_addr, - handler, })); log::warn!("Incoming connection rejected: {:?}", connection_limit); } @@ -1058,15 +1052,18 @@ where fn handle_behaviour_event( &mut self, - event: NetworkBehaviourAction, + event: NetworkBehaviourAction>, ) -> Option>> { match event { NetworkBehaviourAction::GenerateEvent(event) => { return Some(SwarmEvent::Behaviour(event)) } - NetworkBehaviourAction::Dial { opts, handler } => { + NetworkBehaviourAction::Dial { + opts, + connection_id, + } => { let peer_id = opts.get_or_parse_peer_id(); - if let Ok(()) = self.dial_with_handler(opts, handler) { + if let Ok(()) = self.dial_with_id(opts, connection_id) { if let Ok(Some(peer_id)) = peer_id { return Some(SwarmEvent::Dialing(peer_id)); } @@ -1212,7 +1209,7 @@ where } // Poll the known peers. - match this.pool.poll(cx) { + match this.pool.poll(cx, || this.behaviour.new_handler()) { Poll::Pending => {} Poll::Ready(pool_event) => { if let Some(swarm_event) = this.handle_pool_event(pool_event) { diff --git a/swarm/src/test.rs b/swarm/src/test.rs index d850a174bdd..87a7907bf03 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -24,7 +24,7 @@ use crate::behaviour::{ }; use crate::{ ConnectionHandler, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, + PollParameters, THandlerInEvent, }; use libp2p_core::{ connection::ConnectionId, multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId, @@ -47,7 +47,7 @@ where /// The next action to return from `poll`. /// /// An action is only returned once. - pub next_action: Option>, + pub next_action: Option>, } impl MockBehaviour @@ -84,7 +84,7 @@ where &mut self, _: &mut Context, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { self.next_action.take().map_or(Poll::Pending, Poll::Ready) } @@ -390,14 +390,14 @@ where } FromSwarm::DialFailure(DialFailure { peer_id, - handler, + connection_id, error, }) => { self.on_dial_failure.push(peer_id); self.inner .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, - handler, + connection_id, error, })); } @@ -481,7 +481,7 @@ where &mut self, cx: &mut Context, args: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { self.poll += 1; self.inner.poll(cx, args) } diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 08f04081297..118b279bfc5 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::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent}; +use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent, THandlerInEvent}; use std::fmt::Debug; /// Small utility to check that a type implements `NetworkBehaviour`. @@ -401,7 +401,7 @@ fn custom_out_event_no_type_parameters() { &mut self, _ctx: &mut Context, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { Poll::Pending } From f6cf7514772e991f77f38af414d9f6e6d92c9903 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Jan 2023 14:20:49 +1100 Subject: [PATCH 064/177] Port dcutr protocol --- protocols/dcutr/src/behaviour_impl.rs | 148 +++++++++++++++---------- protocols/dcutr/src/handler.rs | 52 ++------- protocols/dcutr/src/handler/direct.rs | 18 +-- protocols/dcutr/src/handler/relayed.rs | 10 +- 4 files changed, 106 insertions(+), 122 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index d4cae973da3..52e05d3c352 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -29,11 +29,12 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailu use libp2p_swarm::dial_opts::{self, DialOpts}; use libp2p_swarm::{ ConnectionHandler, ConnectionHandlerUpgrErr, ExternalAddresses, IntoConnectionHandler, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; use thiserror::Error; +use void::Void; const MAX_NUMBER_OF_UPGRADE_ATTEMPTS: u8 = 3; @@ -67,7 +68,7 @@ pub enum Error { pub struct Behaviour { /// Queue of actions to return when polled. - queued_events: VecDeque>, + queued_events: VecDeque>>, /// All direct (non-relayed) connections. direct_connections: HashMap>, @@ -75,6 +76,10 @@ pub struct Behaviour { external_addresses: ExternalAddresses, local_peer_id: PeerId, + + direct_to_relayed_connections: HashMap, + + outgoing_direct_connection_attempts: HashMap<(ConnectionId, PeerId), u8>, } impl Behaviour { @@ -84,6 +89,8 @@ impl Behaviour { direct_connections: Default::default(), external_addresses: Default::default(), local_peer_id, + direct_to_relayed_connections: Default::default(), + outgoing_direct_connection_attempts: Default::default(), } } @@ -147,40 +154,57 @@ impl Behaviour { fn on_dial_failure( &mut self, DialFailure { - peer_id, handler, .. - }: DialFailure<::ConnectionHandler>, + peer_id, + connection_id: failed_direct_connection, + .. + }: DialFailure, ) { - if let handler::Prototype::DirectConnection { - relayed_connection_id, - role: handler::Role::Initiator { attempt }, - } = handler + let peer_id = if let Some(peer_id) = peer_id { + peer_id + } else { + return; + }; + + let relayed_connection_id = if let Some(relayed_connection_id) = self + .direct_to_relayed_connections + .get(&failed_direct_connection) { - let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); - if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - self.queued_events - .push_back(NetworkBehaviourAction::NotifyHandler { - handler: NotifyHandler::One(relayed_connection_id), - peer_id, - event: Either::Left(handler::relayed::Command::Connect { - attempt: attempt + 1, - obs_addrs: self.observed_addreses(), - }), - }) - } else { - self.queued_events.extend([ - NetworkBehaviourAction::NotifyHandler { - peer_id, - handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left( - handler::relayed::Command::UpgradeFinishedDontKeepAlive, - ), - }, - NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { - remote_peer_id: peer_id, - error: Error::Dial, + *relayed_connection_id + } else { + return; + }; + + let attempt = if let Some(attempt) = self + .outgoing_direct_connection_attempts + .get(&(relayed_connection_id, peer_id)) + { + *attempt + } else { + return; + }; + + if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { + self.queued_events + .push_back(NetworkBehaviourAction::NotifyHandler { + handler: NotifyHandler::One(relayed_connection_id), + peer_id, + event: Either::Left(handler::relayed::Command::Connect { + attempt: attempt + 1, + obs_addrs: self.observed_addreses(), }), - ]); - } + }) + } else { + self.queued_events.extend([ + NetworkBehaviourAction::NotifyHandler { + peer_id, + handler: NotifyHandler::One(relayed_connection_id), + event: Either::Left(handler::relayed::Command::UpgradeFinishedDontKeepAlive), + }, + NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { + remote_peer_id: peer_id, + error: Error::Dial, + }), + ]); } } @@ -214,16 +238,26 @@ impl NetworkBehaviour for Behaviour { type OutEvent = Event; fn new_handler(&mut self) -> Self::ConnectionHandler { - handler::Prototype::UnknownConnection + handler::Prototype } fn on_connection_handler_event( &mut self, event_source: PeerId, - connection: ConnectionId, - handler_event: <::Handler as - ConnectionHandler>::OutEvent, + connection_id: ConnectionId, + handler_event: <::Handler as ConnectionHandler>::OutEvent, ) { + let relayed_connection_id = match handler_event.as_ref() { + Either::Left(_) => connection_id, + Either::Right(_) => match self.direct_to_relayed_connections.get(&connection_id) { + None => { + // If the connection ID is unknown to us, it means we didn't create it so ignore any event coming from it. + return; + } + Some(relayed_connection_id) => *relayed_connection_id, + }, + }; + match handler_event { Either::Left(handler::relayed::Event::InboundConnectRequest { inbound_connect, @@ -231,7 +265,7 @@ impl NetworkBehaviour for Behaviour { }) => { self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { - handler: NotifyHandler::One(connection), + handler: NotifyHandler::One(relayed_connection_id), peer_id: event_source, event: Either::Left(handler::relayed::Command::AcceptInboundConnect { inbound_connect, @@ -256,15 +290,17 @@ impl NetworkBehaviour for Behaviour { )); } Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => { + let maybe_direct_connection_id = ConnectionId::next(); + + self.direct_to_relayed_connections + .insert(maybe_direct_connection_id, relayed_connection_id); + self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(event_source) .addresses(remote_addrs) .condition(dial_opts::PeerCondition::Always) .build(), - handler: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Listener, - }, + connection_id: maybe_direct_connection_id, }); } Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { @@ -276,27 +312,26 @@ impl NetworkBehaviour for Behaviour { }, )); } - Either::Left(handler::relayed::Event::OutboundConnectNegotiated { - remote_addrs, - attempt, - }) => { + Either::Left(handler::relayed::Event::OutboundConnectNegotiated { remote_addrs }) => { + let maybe_direct_connection_id = ConnectionId::next(); + + self.direct_to_relayed_connections + .insert(maybe_direct_connection_id, relayed_connection_id); + *self + .outgoing_direct_connection_attempts + .entry((maybe_direct_connection_id, event_source)) + .or_default() += 1; + self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(event_source) .condition(dial_opts::PeerCondition::Always) .addresses(remote_addrs) .override_role() .build(), - handler: handler::Prototype::DirectConnection { - relayed_connection_id: connection, - role: handler::Role::Initiator { attempt }, - }, + connection_id: maybe_direct_connection_id, }); } - Either::Right(Either::Left( - handler::direct::Event::DirectConnectionUpgradeSucceeded { - relayed_connection_id, - }, - )) => { + Either::Right(handler::direct::Event::DirectConnectionEstablished) => { self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id: event_source, @@ -312,7 +347,6 @@ impl NetworkBehaviour for Behaviour { ), ]); } - Either::Right(Either::Right(event)) => void::unreachable(event), }; } @@ -320,7 +354,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(event) = self.queued_events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/dcutr/src/handler.rs b/protocols/dcutr/src/handler.rs index e854b395308..34392bde182 100644 --- a/protocols/dcutr/src/handler.rs +++ b/protocols/dcutr/src/handler.rs @@ -20,62 +20,30 @@ use crate::protocol; use either::Either; -use libp2p_core::connection::ConnectionId; -use libp2p_core::upgrade::{self, DeniedUpgrade}; +use libp2p_core::upgrade; use libp2p_core::{ConnectedPoint, PeerId}; -use libp2p_swarm::dummy; use libp2p_swarm::handler::SendWrapper; use libp2p_swarm::{ConnectionHandler, IntoConnectionHandler}; pub mod direct; pub mod relayed; -pub enum Prototype { - DirectConnection { - role: Role, - relayed_connection_id: ConnectionId, - }, - UnknownConnection, -} - -pub enum Role { - Initiator { attempt: u8 }, - Listener, -} +pub struct Prototype; impl IntoConnectionHandler for Prototype { - type Handler = Either>; + type Handler = Either; fn into_handler(self, _remote_peer_id: &PeerId, endpoint: &ConnectedPoint) -> Self::Handler { - match self { - Self::UnknownConnection => { - if endpoint.is_relayed() { - Either::Left(relayed::Handler::new(endpoint.clone())) - } else { - Either::Right(Either::Right(dummy::ConnectionHandler)) - } - } - Self::DirectConnection { - relayed_connection_id, - .. - } => { - assert!( - !endpoint.is_relayed(), - "`Prototype::DirectConnection` is never created for relayed connection." - ); - Either::Right(Either::Left(direct::Handler::new(relayed_connection_id))) - } + if endpoint.is_relayed() { + Either::Left(relayed::Handler::new(endpoint.clone())) + } else { + Either::Right(direct::Handler::default()) // This is a direct connection. What we don't know is whether it is the one we created or another one that happened accidentally. } } fn inbound_protocol(&self) -> ::InboundProtocol { - match self { - Prototype::UnknownConnection => upgrade::EitherUpgrade::A(SendWrapper( - upgrade::EitherUpgrade::A(protocol::inbound::Upgrade {}), - )), - Prototype::DirectConnection { .. } => { - upgrade::EitherUpgrade::A(SendWrapper(upgrade::EitherUpgrade::B(DeniedUpgrade))) - } - } + upgrade::EitherUpgrade::A(SendWrapper(upgrade::EitherUpgrade::A( + protocol::inbound::Upgrade {}, + ))) } } diff --git a/protocols/dcutr/src/handler/direct.rs b/protocols/dcutr/src/handler/direct.rs index 9e6759977ad..aab212483eb 100644 --- a/protocols/dcutr/src/handler/direct.rs +++ b/protocols/dcutr/src/handler/direct.rs @@ -20,7 +20,6 @@ //! [`ConnectionHandler`] handling direct connection upgraded through a relayed connection. -use libp2p_core::connection::ConnectionId; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_swarm::handler::ConnectionEvent; use libp2p_swarm::{ @@ -32,23 +31,14 @@ use void::Void; #[derive(Debug)] pub enum Event { - DirectConnectionUpgradeSucceeded { relayed_connection_id: ConnectionId }, + DirectConnectionEstablished, } +#[derive(Default)] pub struct Handler { - relayed_connection_id: ConnectionId, reported: bool, } -impl Handler { - pub(crate) fn new(relayed_connection_id: ConnectionId) -> Self { - Self { - reported: false, - relayed_connection_id, - } - } -} - impl ConnectionHandler for Handler { type InEvent = void::Void; type OutEvent = Event; @@ -82,9 +72,7 @@ impl ConnectionHandler for Handler { if !self.reported { self.reported = true; return Poll::Ready(ConnectionHandlerEvent::Custom( - Event::DirectConnectionUpgradeSucceeded { - relayed_connection_id: self.relayed_connection_id, - }, + Event::DirectConnectionEstablished, )); } Poll::Pending diff --git a/protocols/dcutr/src/handler/relayed.rs b/protocols/dcutr/src/handler/relayed.rs index 301f2ee3d82..bb4732ee81a 100644 --- a/protocols/dcutr/src/handler/relayed.rs +++ b/protocols/dcutr/src/handler/relayed.rs @@ -91,7 +91,6 @@ pub enum Event { }, OutboundConnectNegotiated { remote_addrs: Vec, - attempt: u8, }, } @@ -117,13 +116,9 @@ impl fmt::Debug for Event { .debug_struct("Event::OutboundNegotiationFailed") .field("error", error) .finish(), - Event::OutboundConnectNegotiated { - remote_addrs, - attempt, - } => f + Event::OutboundConnectNegotiated { remote_addrs } => f .debug_struct("Event::OutboundConnectNegotiated") .field("remote_addrs", remote_addrs) - .field("attempt", attempt) .finish(), } } @@ -194,7 +189,7 @@ impl Handler { &mut self, FullyNegotiatedOutbound { protocol: protocol::outbound::Connect { obs_addrs }, - info: attempt, + .. }: FullyNegotiatedOutbound< ::OutboundProtocol, ::OutboundOpenInfo, @@ -207,7 +202,6 @@ impl Handler { self.queued_events.push_back(ConnectionHandlerEvent::Custom( Event::OutboundConnectNegotiated { remote_addrs: obs_addrs, - attempt, }, )); } From 08c51608ddcef1a9201a4fdad3ae85859d31f435 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Jan 2023 14:20:55 +1100 Subject: [PATCH 065/177] Port relay protocol --- protocols/relay/src/behaviour.rs | 13 ++-- protocols/relay/src/priv_client.rs | 110 ++++++++++++++++------------- 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/protocols/relay/src/behaviour.rs b/protocols/relay/src/behaviour.rs index b478de2e70b..22d45b38608 100644 --- a/protocols/relay/src/behaviour.rs +++ b/protocols/relay/src/behaviour.rs @@ -33,13 +33,14 @@ use libp2p_core::PeerId; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{hash_map, HashMap, HashSet, VecDeque}; use std::num::NonZeroU32; use std::ops::Add; use std::task::{Context, Poll}; use std::time::Duration; +use void::Void; /// Configuration for the relay [`Behaviour`]. /// @@ -643,7 +644,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action.build(self.local_peer_id, &self.external_addresses)); } @@ -746,7 +747,7 @@ impl Add for CircuitId { /// before being returned in [`Behaviour::poll`]. #[allow(clippy::large_enum_variant)] enum Action { - Done(NetworkBehaviourAction), + Done(NetworkBehaviourAction>), AcceptReservationPrototype { inbound_reservation_req: inbound_hop::ReservationReq, handler: NotifyHandler, @@ -754,8 +755,8 @@ enum Action { }, } -impl From> for Action { - fn from(action: NetworkBehaviourAction) -> Self { +impl From>> for Action { + fn from(action: NetworkBehaviourAction>) -> Self { Self::Done(action) } } @@ -765,7 +766,7 @@ impl Action { self, local_peer_id: PeerId, external_addresses: &ExternalAddresses, - ) -> NetworkBehaviourAction { + ) -> NetworkBehaviourAction> { match self { Action::Done(action) => action, Action::AcceptReservationPrototype { diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 7bb79f5d246..e0e9e512426 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -38,7 +38,7 @@ use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ ConnectionHandlerUpgrErr, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, + NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{hash_map, HashMap, VecDeque}; use std::io::{Error, ErrorKind, IoSlice}; @@ -46,6 +46,7 @@ use std::ops::DerefMut; use std::pin::Pin; use std::task::{Context, Poll}; use transport::Transport; +use void::Void; /// The events produced by the client `Behaviour`. #[derive(Debug)] @@ -100,7 +101,9 @@ pub struct Behaviour { directly_connected_peers: HashMap>, /// Queue of actions to return when polled. - queued_actions: VecDeque, + queued_actions: VecDeque>>, + + pending_handler_commands: HashMap, } /// Create a new client relay [`Behaviour`] with it's corresponding [`Transport`]. @@ -111,6 +114,7 @@ pub fn new(local_peer_id: PeerId) -> (Transport, Behaviour) { from_transport, directly_connected_peers: Default::default(), queued_actions: Default::default(), + pending_handler_commands: Default::default(), }; (transport, behaviour) } @@ -174,6 +178,15 @@ impl NetworkBehaviour for Behaviour { .or_default() .push(connection_id); } + + if let Some(event) = self.pending_handler_commands.remove(&connection_id) { + self.queued_actions + .push_back(NetworkBehaviourAction::NotifyHandler { + peer_id, + handler: NotifyHandler::One(connection_id), + event: Either::Left(event), + }) + } } FromSwarm::ConnectionClosed(connection_closed) => { self.on_connection_closed(connection_closed) @@ -202,61 +215,57 @@ impl NetworkBehaviour for Behaviour { Either::Right(v) => void::unreachable(v), }; - match handler_event { - handler::Event::ReservationReqAccepted { renewal, limit } => self - .queued_actions - .push_back(Event::ReservationReqAccepted { + let event = match handler_event { + handler::Event::ReservationReqAccepted { renewal, limit } => { + Event::ReservationReqAccepted { relay_peer_id: event_source, renewal, limit, - }), + } + } handler::Event::ReservationReqFailed { renewal, error } => { - self.queued_actions.push_back(Event::ReservationReqFailed { + Event::ReservationReqFailed { relay_peer_id: event_source, renewal, error, - }) + } } handler::Event::OutboundCircuitEstablished { limit } => { - self.queued_actions - .push_back(Event::OutboundCircuitEstablished { - relay_peer_id: event_source, - limit, - }) + Event::OutboundCircuitEstablished { + relay_peer_id: event_source, + limit, + } } - handler::Event::OutboundCircuitReqFailed { error } => { - self.queued_actions - .push_back(Event::OutboundCircuitReqFailed { - relay_peer_id: event_source, - error, - }) + handler::Event::OutboundCircuitReqFailed { error } => Event::OutboundCircuitReqFailed { + relay_peer_id: event_source, + error, + }, + handler::Event::InboundCircuitEstablished { src_peer_id, limit } => { + Event::InboundCircuitEstablished { src_peer_id, limit } } - handler::Event::InboundCircuitEstablished { src_peer_id, limit } => self - .queued_actions - .push_back(Event::InboundCircuitEstablished { src_peer_id, limit }), - handler::Event::InboundCircuitReqFailed { error } => { - self.queued_actions - .push_back(Event::InboundCircuitReqFailed { - relay_peer_id: event_source, - error, - }) + handler::Event::InboundCircuitReqFailed { error } => Event::InboundCircuitReqFailed { + relay_peer_id: event_source, + error, + }, + handler::Event::InboundCircuitReqDenied { src_peer_id } => { + Event::InboundCircuitReqDenied { src_peer_id } } - handler::Event::InboundCircuitReqDenied { src_peer_id } => self - .queued_actions - .push_back(Event::InboundCircuitReqDenied { src_peer_id }), - handler::Event::InboundCircuitReqDenyFailed { src_peer_id, error } => self - .queued_actions - .push_back(Event::InboundCircuitReqDenyFailed { src_peer_id, error }), - } + handler::Event::InboundCircuitReqDenyFailed { src_peer_id, error } => { + Event::InboundCircuitReqDenyFailed { src_peer_id, error } + } + }; + + self.queued_actions + .push_back(NetworkBehaviourAction::GenerateEvent(event)) } fn poll( &mut self, cx: &mut Context<'_>, _poll_parameters: &mut impl PollParameters, - ) -> Poll> { - if let Some(event) = self.queued_actions.pop_front() { - return Poll::Ready(NetworkBehaviourAction::GenerateEvent(event)); + ) -> Poll>> { + if let Some(action) = self.queued_actions.pop_front() { + return Poll::Ready(action); } let action = match ready!(self.from_transport.poll_next_unpin(cx)) { @@ -276,16 +285,16 @@ impl NetworkBehaviour for Behaviour { event: Either::Left(handler::In::Reserve { to_listener }), }, None => { - let handler = handler::Prototype::new( - self.local_peer_id, - Some(handler::In::Reserve { to_listener }), - ); + let relayed_connection_id = ConnectionId::next(); + + self.pending_handler_commands + .insert(relayed_connection_id, handler::In::Reserve { to_listener }); NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(relay_peer_id) .addresses(vec![relay_addr]) .extend_addresses_through_behaviour() .build(), - handler, + connection_id: relayed_connection_id, } } } @@ -311,19 +320,22 @@ impl NetworkBehaviour for Behaviour { }), }, None => { - let handler = handler::Prototype::new( - self.local_peer_id, - Some(handler::In::EstablishCircuit { + let connection_id = ConnectionId::next(); + + self.pending_handler_commands.insert( + connection_id, + handler::In::EstablishCircuit { send_back, dst_peer_id, - }), + }, ); + NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(relay_peer_id) .addresses(vec![relay_addr]) .extend_addresses_through_behaviour() .build(), - handler, + connection_id, } } } From 8e0d7d844ef859d69b522562c6491375d50dd7b5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Jan 2023 14:26:10 +1100 Subject: [PATCH 066/177] Add changelog entry to swarm --- swarm/CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 25969d67052..904c442ad72 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -15,11 +15,18 @@ - Remove type parameter from `PendingOutboundConnectionError` and `PendingInboundConnectionError`. These two types are always used with `std::io::Error`. See [PR 3272]. +- Remove `handler` field from `NetworkBehaviourAction::Dial`. + Instead of constructing the handler early, you now get to pass a `ConnectionId`. + `ConnectionId` are `Copy` and will be used throughout the entire lifetime of the connection to report events. + This allows you to send events to a very specific connection, much like you previously could directly set state in the handler. + See [PR 3328]. + [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 [PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153 [PR 3264]: https://github.com/libp2p/rust-libp2p/pull/3264 [PR 3272]: https://github.com/libp2p/rust-libp2p/pull/3272 +[PR 3328]: https://github.com/libp2p/rust-libp2p/pull/3328 # 0.41.1 From 1beec8cb3755932f26e02434aa712cb74ae2467f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:05:09 +1100 Subject: [PATCH 067/177] Remove ordering functionality from `ConnectionId` --- core/src/connection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/connection.rs b/core/src/connection.rs index 3949921c3e1..3496848aa2e 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -24,7 +24,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; static NEXT_CONNECTION_ID: AtomicUsize = AtomicUsize::new(0); /// Connection identifier. -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct ConnectionId(usize); impl ConnectionId { From de9f152c65eaa750ddc25d1b97957e63a94993b8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:09:57 +1100 Subject: [PATCH 068/177] Remove unnecessary visibility qualifiers --- swarm/src/dial_opts.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/swarm/src/dial_opts.rs b/swarm/src/dial_opts.rs index acc1b69a617..4137a4a4d67 100644 --- a/swarm/src/dial_opts.rs +++ b/swarm/src/dial_opts.rs @@ -36,7 +36,7 @@ use std::num::NonZeroU8; /// /// - [`DialOpts::unknown_peer_id`] dialing an unknown peer #[derive(Debug)] -pub struct DialOpts(pub(super) Opts); +pub struct DialOpts(Opts); impl DialOpts { /// Dial a known peer. @@ -200,7 +200,7 @@ impl From for DialOpts { /// - [`DialOpts::peer_id`] dialing a known peer /// - [`DialOpts::unknown_peer_id`] dialing an unknown peer #[derive(Debug)] -pub(super) enum Opts { +enum Opts { WithPeerId(WithPeerId), WithPeerIdWithAddresses(WithPeerIdWithAddresses), WithoutPeerIdWithAddress(WithoutPeerIdWithAddress), @@ -208,10 +208,10 @@ pub(super) enum Opts { #[derive(Debug)] pub struct WithPeerId { - pub(crate) peer_id: PeerId, - pub(crate) condition: PeerCondition, - pub(crate) role_override: Endpoint, - pub(crate) dial_concurrency_factor_override: Option, + peer_id: PeerId, + condition: PeerCondition, + role_override: Endpoint, + dial_concurrency_factor_override: Option, } impl WithPeerId { @@ -262,12 +262,12 @@ impl WithPeerId { #[derive(Debug)] pub struct WithPeerIdWithAddresses { - pub(crate) peer_id: PeerId, - pub(crate) condition: PeerCondition, - pub(crate) addresses: Vec, - pub(crate) extend_addresses_through_behaviour: bool, - pub(crate) role_override: Endpoint, - pub(crate) dial_concurrency_factor_override: Option, + peer_id: PeerId, + condition: PeerCondition, + addresses: Vec, + extend_addresses_through_behaviour: bool, + role_override: Endpoint, + dial_concurrency_factor_override: Option, } impl WithPeerIdWithAddresses { @@ -323,8 +323,8 @@ impl WithoutPeerId { #[derive(Debug)] pub struct WithoutPeerIdWithAddress { - pub(crate) address: Multiaddr, - pub(crate) role_override: Endpoint, + address: Multiaddr, + role_override: Endpoint, } impl WithoutPeerIdWithAddress { From 7692c770a84e5eed08ba7b69fa743369e3b5a943 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:11:32 +1100 Subject: [PATCH 069/177] Convert `DialOpts` to struct variant --- swarm/src/dial_opts.rs | 141 +++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 54 deletions(-) diff --git a/swarm/src/dial_opts.rs b/swarm/src/dial_opts.rs index 4137a4a4d67..1fb49ca1bd4 100644 --- a/swarm/src/dial_opts.rs +++ b/swarm/src/dial_opts.rs @@ -36,7 +36,9 @@ use std::num::NonZeroU8; /// /// - [`DialOpts::unknown_peer_id`] dialing an unknown peer #[derive(Debug)] -pub struct DialOpts(Opts); +pub struct DialOpts { + inner: Opts, +} impl DialOpts { /// Dial a known peer. @@ -74,11 +76,15 @@ impl DialOpts { /// Get the [`PeerId`] specified in a [`DialOpts`] if any. pub fn get_peer_id(&self) -> Option { match self { - DialOpts(Opts::WithPeerId(WithPeerId { peer_id, .. })) => Some(*peer_id), - DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - peer_id, .. - })) => Some(*peer_id), - DialOpts(Opts::WithoutPeerIdWithAddress(_)) => None, + DialOpts { + inner: Opts::WithPeerId(WithPeerId { peer_id, .. }), + } => Some(*peer_id), + DialOpts { + inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { peer_id, .. }), + } => Some(*peer_id), + DialOpts { + inner: Opts::WithoutPeerIdWithAddress(_), + } => None, } } @@ -93,13 +99,15 @@ impl DialOpts { /// See . pub(crate) fn get_or_parse_peer_id(&self) -> Result, Multihash> { match self { - DialOpts(Opts::WithPeerId(WithPeerId { peer_id, .. })) => Ok(Some(*peer_id)), - DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - peer_id, .. - })) => Ok(Some(*peer_id)), - DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { - address, .. - })) => { + DialOpts { + inner: Opts::WithPeerId(WithPeerId { peer_id, .. }), + } => Ok(Some(*peer_id)), + DialOpts { + inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { peer_id, .. }), + } => Ok(Some(*peer_id)), + DialOpts { + inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { address, .. }), + } => { let peer_id = address .iter() .last() @@ -119,64 +127,83 @@ impl DialOpts { pub(crate) fn get_addresses(&self) -> Vec { match self { - DialOpts(Opts::WithPeerId(WithPeerId { .. })) => vec![], - DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - addresses, .. - })) => addresses.clone(), - DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { - address, .. - })) => vec![address.clone()], + DialOpts { + inner: Opts::WithPeerId(WithPeerId { .. }), + } => vec![], + DialOpts { + inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { addresses, .. }), + } => addresses.clone(), + DialOpts { + inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { address, .. }), + } => vec![address.clone()], } } pub(crate) fn extend_addresses_through_behaviour(&self) -> bool { match self { - DialOpts(Opts::WithPeerId(WithPeerId { .. })) => true, - DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - extend_addresses_through_behaviour, - .. - })) => *extend_addresses_through_behaviour, - DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. })) => true, + DialOpts { + inner: Opts::WithPeerId(WithPeerId { .. }), + } => true, + DialOpts { + inner: + Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { + extend_addresses_through_behaviour, + .. + }), + } => *extend_addresses_through_behaviour, + DialOpts { + inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. }), + } => true, } } pub(crate) fn peer_condition(&self) -> PeerCondition { match self { - DialOpts( - Opts::WithPeerId(WithPeerId { condition, .. }) - | Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { condition, .. }), - ) => *condition, - DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. })) => { - PeerCondition::Always - } + DialOpts { + inner: + Opts::WithPeerId(WithPeerId { condition, .. }) + | Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { condition, .. }), + } => *condition, + DialOpts { + inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. }), + } => PeerCondition::Always, } } pub(crate) fn dial_concurrency_override(&self) -> Option { match self { - DialOpts(Opts::WithPeerId(WithPeerId { - dial_concurrency_factor_override, - .. - })) => *dial_concurrency_factor_override, - DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - dial_concurrency_factor_override, - .. - })) => *dial_concurrency_factor_override, - DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. })) => None, + DialOpts { + inner: + Opts::WithPeerId(WithPeerId { + dial_concurrency_factor_override, + .. + }), + } => *dial_concurrency_factor_override, + DialOpts { + inner: + Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { + dial_concurrency_factor_override, + .. + }), + } => *dial_concurrency_factor_override, + DialOpts { + inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. }), + } => None, } } pub(crate) fn role_override(&self) -> Endpoint { match self { - DialOpts(Opts::WithPeerId(WithPeerId { role_override, .. })) => *role_override, - DialOpts(Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - role_override, - .. - })) => *role_override, - DialOpts(Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { - role_override, - .. - })) => *role_override, + DialOpts { + inner: Opts::WithPeerId(WithPeerId { role_override, .. }), + } => *role_override, + DialOpts { + inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { role_override, .. }), + } => *role_override, + DialOpts { + inner: + Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { role_override, .. }), + } => *role_override, } } } @@ -256,7 +283,9 @@ impl WithPeerId { /// Addresses to dial the peer are retrieved via /// [`NetworkBehaviour::addresses_of_peer`](crate::behaviour::NetworkBehaviour::addresses_of_peer). pub fn build(self) -> DialOpts { - DialOpts(Opts::WithPeerId(self)) + DialOpts { + inner: Opts::WithPeerId(self), + } } } @@ -304,7 +333,9 @@ impl WithPeerIdWithAddresses { /// Build the final [`DialOpts`]. pub fn build(self) -> DialOpts { - DialOpts(Opts::WithPeerIdWithAddresses(self)) + DialOpts { + inner: Opts::WithPeerIdWithAddresses(self), + } } } @@ -340,7 +371,9 @@ impl WithoutPeerIdWithAddress { } /// Build the final [`DialOpts`]. pub fn build(self) -> DialOpts { - DialOpts(Opts::WithoutPeerIdWithAddress(self)) + DialOpts { + inner: Opts::WithoutPeerIdWithAddress(self), + } } } From b492236f8cdeb6a0bc82326b454777b9b8fb6321 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:25:27 +1100 Subject: [PATCH 070/177] Eagerly set defaults in `DialOpts` Instead of carrying around an enum and parsing its contents later, directly set the correct values as we construct the final `DialOpts`. --- swarm/src/dial_opts.rs | 170 +++++++++++++---------------------------- 1 file changed, 51 insertions(+), 119 deletions(-) diff --git a/swarm/src/dial_opts.rs b/swarm/src/dial_opts.rs index 1fb49ca1bd4..5362ad99e91 100644 --- a/swarm/src/dial_opts.rs +++ b/swarm/src/dial_opts.rs @@ -37,7 +37,12 @@ use std::num::NonZeroU8; /// - [`DialOpts::unknown_peer_id`] dialing an unknown peer #[derive(Debug)] pub struct DialOpts { - inner: Opts, + peer_id: Option, + condition: PeerCondition, + addresses: Vec, + extend_addresses_through_behaviour: bool, + role_override: Endpoint, + dial_concurrency_factor_override: Option, } impl DialOpts { @@ -75,17 +80,7 @@ impl DialOpts { /// Get the [`PeerId`] specified in a [`DialOpts`] if any. pub fn get_peer_id(&self) -> Option { - match self { - DialOpts { - inner: Opts::WithPeerId(WithPeerId { peer_id, .. }), - } => Some(*peer_id), - DialOpts { - inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { peer_id, .. }), - } => Some(*peer_id), - DialOpts { - inner: Opts::WithoutPeerIdWithAddress(_), - } => None, - } + self.peer_id } /// Retrieves the [`PeerId`] from the [`DialOpts`] if specified or otherwise tries to parse it @@ -98,113 +93,48 @@ impl DialOpts { /// /// See . pub(crate) fn get_or_parse_peer_id(&self) -> Result, Multihash> { - match self { - DialOpts { - inner: Opts::WithPeerId(WithPeerId { peer_id, .. }), - } => Ok(Some(*peer_id)), - DialOpts { - inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { peer_id, .. }), - } => Ok(Some(*peer_id)), - DialOpts { - inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { address, .. }), - } => { - let peer_id = address - .iter() - .last() - .and_then(|p| { - if let Protocol::P2p(ma) = p { - Some(PeerId::try_from(ma)) - } else { - None - } - }) - .transpose()?; - - Ok(peer_id) - } + if let Some(peer_id) = self.peer_id { + return Ok(Some(peer_id)) } + + let first_address = match self.addresses.first() { + Some(first_address) => first_address, + None => return Ok(None) + }; + + let maybe_peer_id = first_address + .iter() + .last() + .and_then(|p| { + if let Protocol::P2p(ma) = p { + Some(PeerId::try_from(ma)) + } else { + None + } + }) + .transpose()?; + + Ok(maybe_peer_id) } pub(crate) fn get_addresses(&self) -> Vec { - match self { - DialOpts { - inner: Opts::WithPeerId(WithPeerId { .. }), - } => vec![], - DialOpts { - inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { addresses, .. }), - } => addresses.clone(), - DialOpts { - inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { address, .. }), - } => vec![address.clone()], - } + self.addresses.clone() } pub(crate) fn extend_addresses_through_behaviour(&self) -> bool { - match self { - DialOpts { - inner: Opts::WithPeerId(WithPeerId { .. }), - } => true, - DialOpts { - inner: - Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - extend_addresses_through_behaviour, - .. - }), - } => *extend_addresses_through_behaviour, - DialOpts { - inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. }), - } => true, - } + self.extend_addresses_through_behaviour } pub(crate) fn peer_condition(&self) -> PeerCondition { - match self { - DialOpts { - inner: - Opts::WithPeerId(WithPeerId { condition, .. }) - | Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { condition, .. }), - } => *condition, - DialOpts { - inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. }), - } => PeerCondition::Always, - } + self.condition } pub(crate) fn dial_concurrency_override(&self) -> Option { - match self { - DialOpts { - inner: - Opts::WithPeerId(WithPeerId { - dial_concurrency_factor_override, - .. - }), - } => *dial_concurrency_factor_override, - DialOpts { - inner: - Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { - dial_concurrency_factor_override, - .. - }), - } => *dial_concurrency_factor_override, - DialOpts { - inner: Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { .. }), - } => None, - } + self.dial_concurrency_factor_override } pub(crate) fn role_override(&self) -> Endpoint { - match self { - DialOpts { - inner: Opts::WithPeerId(WithPeerId { role_override, .. }), - } => *role_override, - DialOpts { - inner: Opts::WithPeerIdWithAddresses(WithPeerIdWithAddresses { role_override, .. }), - } => *role_override, - DialOpts { - inner: - Opts::WithoutPeerIdWithAddress(WithoutPeerIdWithAddress { role_override, .. }), - } => *role_override, - } + self.role_override } } @@ -220,19 +150,6 @@ impl From for DialOpts { } } -/// Internal options type. -/// -/// Not to be constructed manually. Use either of the below instead: -/// -/// - [`DialOpts::peer_id`] dialing a known peer -/// - [`DialOpts::unknown_peer_id`] dialing an unknown peer -#[derive(Debug)] -enum Opts { - WithPeerId(WithPeerId), - WithPeerIdWithAddresses(WithPeerIdWithAddresses), - WithoutPeerIdWithAddress(WithoutPeerIdWithAddress), -} - #[derive(Debug)] pub struct WithPeerId { peer_id: PeerId, @@ -284,7 +201,12 @@ impl WithPeerId { /// [`NetworkBehaviour::addresses_of_peer`](crate::behaviour::NetworkBehaviour::addresses_of_peer). pub fn build(self) -> DialOpts { DialOpts { - inner: Opts::WithPeerId(self), + peer_id: Some(self.peer_id), + condition: self.condition, + addresses: vec![], + extend_addresses_through_behaviour: false, + role_override: self.role_override, + dial_concurrency_factor_override: self.dial_concurrency_factor_override, } } } @@ -334,7 +256,12 @@ impl WithPeerIdWithAddresses { /// Build the final [`DialOpts`]. pub fn build(self) -> DialOpts { DialOpts { - inner: Opts::WithPeerIdWithAddresses(self), + peer_id: Some(self.peer_id), + condition: self.condition, + addresses: self.addresses, + extend_addresses_through_behaviour: self.extend_addresses_through_behaviour, + role_override: self.role_override, + dial_concurrency_factor_override: self.dial_concurrency_factor_override, } } } @@ -372,7 +299,12 @@ impl WithoutPeerIdWithAddress { /// Build the final [`DialOpts`]. pub fn build(self) -> DialOpts { DialOpts { - inner: Opts::WithoutPeerIdWithAddress(self), + peer_id: None, + condition: PeerCondition::Always, + addresses: vec![self.address], + extend_addresses_through_behaviour: false, + role_override: self.role_override, + dial_concurrency_factor_override: None, } } } From 951a0dcca78c134a6045f4b45ace81db148ac747 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:39:57 +1100 Subject: [PATCH 071/177] Make `ConnectionId` part of `DialOpts` --- protocols/autonat/src/behaviour/as_server.rs | 1 - protocols/dcutr/src/behaviour_impl.rs | 36 +++++++++----------- protocols/floodsub/src/layer.rs | 2 -- protocols/gossipsub/src/behaviour.rs | 2 -- protocols/identify/src/behaviour.rs | 1 - protocols/kad/src/behaviour.rs | 3 -- protocols/relay/src/priv_client.rs | 28 +++++++-------- protocols/request-response/src/lib.rs | 1 - swarm-derive/src/lib.rs | 4 +-- swarm/src/behaviour.rs | 27 ++++----------- swarm/src/dial_opts.rs | 18 ++++++++-- swarm/src/lib.rs | 16 +++------ 12 files changed, 57 insertions(+), 82 deletions(-) diff --git a/protocols/autonat/src/behaviour/as_server.rs b/protocols/autonat/src/behaviour/as_server.rs index ea1e59821d4..f250fc855be 100644 --- a/protocols/autonat/src/behaviour/as_server.rs +++ b/protocols/autonat/src/behaviour/as_server.rs @@ -138,7 +138,6 @@ impl<'a> HandleInnerEvent for AsServer<'a> { ) .addresses(addrs) .build(), - connection_id: ConnectionId::next(), }, ]) } diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 52e05d3c352..1f77bbb67fb 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -290,18 +290,17 @@ impl NetworkBehaviour for Behaviour { )); } Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => { - let maybe_direct_connection_id = ConnectionId::next(); + let opts = DialOpts::peer_id(event_source) + .addresses(remote_addrs) + .condition(dial_opts::PeerCondition::Always) + .build(); + + let maybe_direct_connection_id = opts.connection_id(); self.direct_to_relayed_connections .insert(maybe_direct_connection_id, relayed_connection_id); - - self.queued_events.push_back(NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(event_source) - .addresses(remote_addrs) - .condition(dial_opts::PeerCondition::Always) - .build(), - connection_id: maybe_direct_connection_id, - }); + self.queued_events + .push_back(NetworkBehaviourAction::Dial { opts }); } Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { self.queued_events @@ -313,7 +312,13 @@ impl NetworkBehaviour for Behaviour { )); } Either::Left(handler::relayed::Event::OutboundConnectNegotiated { remote_addrs }) => { - let maybe_direct_connection_id = ConnectionId::next(); + let opts = DialOpts::peer_id(event_source) + .condition(dial_opts::PeerCondition::Always) + .addresses(remote_addrs) + .override_role() + .build(); + + let maybe_direct_connection_id = opts.connection_id(); self.direct_to_relayed_connections .insert(maybe_direct_connection_id, relayed_connection_id); @@ -321,15 +326,8 @@ impl NetworkBehaviour for Behaviour { .outgoing_direct_connection_attempts .entry((maybe_direct_connection_id, event_source)) .or_default() += 1; - - self.queued_events.push_back(NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(event_source) - .condition(dial_opts::PeerCondition::Always) - .addresses(remote_addrs) - .override_role() - .build(), - connection_id: maybe_direct_connection_id, - }); + self.queued_events + .push_back(NetworkBehaviourAction::Dial { opts }); } Either::Right(handler::direct::Event::DirectConnectionEstablished) => { self.queued_events.extend([ diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 109ebdca84a..e82557ae2a6 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -105,7 +105,6 @@ impl Floodsub { if self.target_peers.insert(peer_id) { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - connection_id: ConnectionId::next(), }); } } @@ -327,7 +326,6 @@ impl Floodsub { if self.target_peers.contains(&peer_id) { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - connection_id: ConnectionId::next(), }); } } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 3962433f56b..12692348281 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -1136,7 +1136,6 @@ where debug!("Connecting to explicit peer {:?}", peer_id); self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer_id).build(), - connection_id: ConnectionId::next(), }); } } @@ -1636,7 +1635,6 @@ where // dial peer self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - connection_id: ConnectionId::next(), }); } } diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 64e765f6e22..7cb9e7d6226 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -201,7 +201,6 @@ impl Behaviour { self.events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(p).build(), - connection_id: ConnectionId::next(), }); } } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 48cf8dd9695..acf77ddda58 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -573,7 +573,6 @@ where kbucket::InsertResult::Pending { disconnected } => { self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()).build(), - connection_id: ConnectionId::next(), }); RoutingUpdate::Pending } @@ -1223,7 +1222,6 @@ where self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(disconnected.into_preimage()) .build(), - connection_id: ConnectionId::next(), }) } } @@ -2387,7 +2385,6 @@ where query.inner.pending_rpcs.push((peer_id, event)); self.queued_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id).build(), - connection_id: ConnectionId::next(), }); } } diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index e0e9e512426..bc1a19d94e7 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -285,17 +285,15 @@ impl NetworkBehaviour for Behaviour { event: Either::Left(handler::In::Reserve { to_listener }), }, None => { - let relayed_connection_id = ConnectionId::next(); + let opts = DialOpts::peer_id(relay_peer_id) + .addresses(vec![relay_addr]) + .extend_addresses_through_behaviour() + .build(); + let relayed_connection_id = opts.connection_id(); self.pending_handler_commands .insert(relayed_connection_id, handler::In::Reserve { to_listener }); - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) - .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() - .build(), - connection_id: relayed_connection_id, - } + NetworkBehaviourAction::Dial { opts } } } } @@ -320,7 +318,11 @@ impl NetworkBehaviour for Behaviour { }), }, None => { - let connection_id = ConnectionId::next(); + let opts = DialOpts::peer_id(relay_peer_id) + .addresses(vec![relay_addr]) + .extend_addresses_through_behaviour() + .build(); + let connection_id = opts.connection_id(); self.pending_handler_commands.insert( connection_id, @@ -330,13 +332,7 @@ impl NetworkBehaviour for Behaviour { }, ); - NetworkBehaviourAction::Dial { - opts: DialOpts::peer_id(relay_peer_id) - .addresses(vec![relay_addr]) - .extend_addresses_through_behaviour() - .build(), - connection_id, - } + NetworkBehaviourAction::Dial { opts } } } } diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index a5e3ae95b82..8861e74175f 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -420,7 +420,6 @@ where if let Some(request) = self.try_send_request(peer, request) { self.pending_events.push_back(NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(*peer).build(), - connection_id: ConnectionId::next(), }); self.pending_outbound_requests .entry(*peer) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 9ff690b323b..0072bbb7dce 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -612,8 +612,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { loop { match #trait_to_impl::poll(&mut self.#field, cx, poll_params) { #generate_event_match_arm - std::task::Poll::Ready(#network_behaviour_action::Dial { opts, connection_id }) => { - return std::task::Poll::Ready(#network_behaviour_action::Dial { opts, connection_id }); + std::task::Poll::Ready(#network_behaviour_action::Dial { opts }) => { + return std::task::Poll::Ready(#network_behaviour_action::Dial { opts }); } std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { peer_id, handler, event }) => { return std::task::Poll::Ready(#network_behaviour_action::NotifyHandler { diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index d964e2a103f..e9bcb69e386 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -233,13 +233,10 @@ pub enum NetworkBehaviourAction { /// On success, [`NetworkBehaviour::on_swarm_event`] with `ConnectionEstablished` is invoked. /// On failure, [`NetworkBehaviour::on_swarm_event`] with `DialFailure` is invoked. /// - /// The provided [`ConnectionId`] will be used throughout the connection's lifecycle to associate - /// events with it. This allows a [`NetworkBehaviour`] to identify a connection that resulted out - /// of its own dial request. - Dial { - opts: DialOpts, - connection_id: ConnectionId, - }, + /// [`DialOpts`] provides access to the [`ConnectionId`] via [`DialOpts::connection_id`]. + /// This [`ConnectionId`] will be used throughout the connection's lifecycle to associate events with it. + /// This allows a [`NetworkBehaviour`] to identify a connection that resulted out of its own dial request. + Dial { opts: DialOpts }, /// Instructs the `Swarm` to send an event to the handler dedicated to a /// connection with a peer. @@ -307,13 +304,7 @@ impl NetworkBehaviourAction { ) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e), - NetworkBehaviourAction::Dial { - opts, - connection_id, - } => NetworkBehaviourAction::Dial { - opts, - connection_id, - }, + NetworkBehaviourAction::Dial { opts } => NetworkBehaviourAction::Dial { opts }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, @@ -345,13 +336,7 @@ impl NetworkBehaviourAction { ) -> NetworkBehaviourAction { match self { NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)), - NetworkBehaviourAction::Dial { - opts, - connection_id, - } => NetworkBehaviourAction::Dial { - opts, - connection_id, - }, + NetworkBehaviourAction::Dial { opts } => NetworkBehaviourAction::Dial { opts }, NetworkBehaviourAction::NotifyHandler { peer_id, handler, diff --git a/swarm/src/dial_opts.rs b/swarm/src/dial_opts.rs index 5362ad99e91..591ef157b41 100644 --- a/swarm/src/dial_opts.rs +++ b/swarm/src/dial_opts.rs @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use libp2p_core::connection::Endpoint; +use libp2p_core::connection::{ConnectionId, Endpoint}; use libp2p_core::multiaddr::Protocol; use libp2p_core::multihash::Multihash; use libp2p_core::{Multiaddr, PeerId}; @@ -43,6 +43,7 @@ pub struct DialOpts { extend_addresses_through_behaviour: bool, role_override: Endpoint, dial_concurrency_factor_override: Option, + connection_id: ConnectionId, } impl DialOpts { @@ -83,6 +84,14 @@ impl DialOpts { self.peer_id } + /// Get the [`ConnectionId`] of this dial attempt. + /// + /// All future events of this dial will be associated with this ID. + /// See [`DialFailure`](crate::DialFailure) and [`ConnectionEstablished`](crate::behaviour::ConnectionEstablished). + pub fn connection_id(&self) -> ConnectionId { + self.connection_id + } + /// Retrieves the [`PeerId`] from the [`DialOpts`] if specified or otherwise tries to parse it /// from the multihash in the `/p2p` part of the address, if present. /// @@ -94,12 +103,12 @@ impl DialOpts { /// See . pub(crate) fn get_or_parse_peer_id(&self) -> Result, Multihash> { if let Some(peer_id) = self.peer_id { - return Ok(Some(peer_id)) + return Ok(Some(peer_id)); } let first_address = match self.addresses.first() { Some(first_address) => first_address, - None => return Ok(None) + None => return Ok(None), }; let maybe_peer_id = first_address @@ -207,6 +216,7 @@ impl WithPeerId { extend_addresses_through_behaviour: false, role_override: self.role_override, dial_concurrency_factor_override: self.dial_concurrency_factor_override, + connection_id: ConnectionId::next(), } } } @@ -262,6 +272,7 @@ impl WithPeerIdWithAddresses { extend_addresses_through_behaviour: self.extend_addresses_through_behaviour, role_override: self.role_override, dial_concurrency_factor_override: self.dial_concurrency_factor_override, + connection_id: ConnectionId::next(), } } } @@ -305,6 +316,7 @@ impl WithoutPeerIdWithAddress { extend_addresses_through_behaviour: false, role_override: self.role_override, dial_concurrency_factor_override: None, + connection_id: ConnectionId::next(), } } } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 522c911bbb2..4c47ec757b9 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -504,18 +504,15 @@ where /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); /// ``` pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { - self.dial_with_id(opts.into(), ConnectionId::next()) + self._dial(opts.into()) } - fn dial_with_id( - &mut self, - dial_opts: DialOpts, - connection_id: ConnectionId, - ) -> Result<(), DialError> { + fn _dial(&mut self, dial_opts: DialOpts) -> Result<(), DialError> { let peer_id = dial_opts .get_or_parse_peer_id() .map_err(DialError::InvalidPeerId)?; let condition = dial_opts.peer_condition(); + let connection_id = dial_opts.connection_id(); let should_dial = match (condition, peer_id) { (PeerCondition::Always, _) => true, @@ -1058,12 +1055,9 @@ where NetworkBehaviourAction::GenerateEvent(event) => { return Some(SwarmEvent::Behaviour(event)) } - NetworkBehaviourAction::Dial { - opts, - connection_id, - } => { + NetworkBehaviourAction::Dial { opts } => { let peer_id = opts.get_or_parse_peer_id(); - if let Ok(()) = self.dial_with_id(opts, connection_id) { + if let Ok(()) = self._dial(opts) { if let Ok(Some(peer_id)) = peer_id { return Some(SwarmEvent::Dialing(peer_id)); } From 41e49a5fedaeeec4d19068095d99da06f6b5759d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:40:52 +1100 Subject: [PATCH 072/177] Inline `_dial` --- swarm/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 4c47ec757b9..fb7bc647eca 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -504,10 +504,8 @@ where /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); /// ``` pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { - self._dial(opts.into()) - } + let dial_opts = opts.into(); - fn _dial(&mut self, dial_opts: DialOpts) -> Result<(), DialError> { let peer_id = dial_opts .get_or_parse_peer_id() .map_err(DialError::InvalidPeerId)?; @@ -1057,7 +1055,7 @@ where } NetworkBehaviourAction::Dial { opts } => { let peer_id = opts.get_or_parse_peer_id(); - if let Ok(()) = self._dial(opts) { + if let Ok(()) = self.dial(opts) { if let Ok(Some(peer_id)) = peer_id { return Some(SwarmEvent::Dialing(peer_id)); } From 3547b53dd5a7c5ad883aaa89a9fc55025cf4b3a5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:42:26 +1100 Subject: [PATCH 073/177] Rustfmt --- swarm/src/dial_opts.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/src/dial_opts.rs b/swarm/src/dial_opts.rs index 5362ad99e91..5cbb5370d18 100644 --- a/swarm/src/dial_opts.rs +++ b/swarm/src/dial_opts.rs @@ -94,12 +94,12 @@ impl DialOpts { /// See . pub(crate) fn get_or_parse_peer_id(&self) -> Result, Multihash> { if let Some(peer_id) = self.peer_id { - return Ok(Some(peer_id)) + return Ok(Some(peer_id)); } let first_address = match self.addresses.first() { Some(first_address) => first_address, - None => return Ok(None) + None => return Ok(None), }; let maybe_peer_id = first_address From 75b30ac00315468dfa884524fdd46e1739b2be5b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Jan 2023 15:44:14 +1100 Subject: [PATCH 074/177] Fix wrong default --- swarm/src/dial_opts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/dial_opts.rs b/swarm/src/dial_opts.rs index 5cbb5370d18..eb375c6ce74 100644 --- a/swarm/src/dial_opts.rs +++ b/swarm/src/dial_opts.rs @@ -204,7 +204,7 @@ impl WithPeerId { peer_id: Some(self.peer_id), condition: self.condition, addresses: vec![], - extend_addresses_through_behaviour: false, + extend_addresses_through_behaviour: true, role_override: self.role_override, dial_concurrency_factor_override: self.dial_concurrency_factor_override, } From 42c9758c6c12e922a6c380b323b07ba07e0de83a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Jan 2023 22:11:29 +1100 Subject: [PATCH 075/177] Expand changelog entry --- swarm/CHANGELOG.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 0000e6263e8..681cdeb204b 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -18,9 +18,33 @@ - Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. - Remove `handler` field from `NetworkBehaviourAction::Dial`. - Instead of constructing the handler early, you now get to pass a `ConnectionId`. - `ConnectionId` are `Copy` and will be used throughout the entire lifetime of the connection to report events. + Instead of constructing the handler early, you can now access the `ConnectionId` of the future connection on `DialOpts`. + `ConnectionId`s are `Copy` and will be used throughout the entire lifetime of the connection to report events. This allows you to send events to a very specific connection, much like you previously could directly set state in the handler. + + Removing the `handler` field also reduces the type parameters of `NetworkBehaviourAction` from three to two. + The third one used to be defaulted to the `InEvent` of the `ConnectionHandler`. + You now have to manually specify that where you previously had to specify the `ConnectionHandler`. + This very likely will trigger **convoluted compile errors** about traits not being implemented. + + Within `NetworkBehaviourAction::poll`, the easiest way to migrate is to do this (in the example of `libp2p-floodsub`): + ```diff + --- a/protocols/floodsub/src/layer.rs + +++ b/protocols/floodsub/src/layer.rs + @@ -472,7 +465,7 @@ impl NetworkBehaviour for Floodsub { + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + - ) -> Poll> { + + ) -> Poll>> { + ``` + + In other words: + + |Search|Replace| + |---|---| + |`NetworkBehaviourAction`|`NetworkBehaviourAction>`| + See [PR 3328]. [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 From 14b9841902685ff8c92686749b34f6bf8a779b46 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Jan 2023 22:11:48 +1100 Subject: [PATCH 076/177] Move most important changelog entry to the top --- swarm/CHANGELOG.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 681cdeb204b..a8fbfd1723d 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,22 +1,5 @@ # 0.42.0 [unreleased] -- Update to `libp2p-core` `v0.39.0`. - -- Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170]. -- Deprecate functions on `PollParameters` in preparation for `PollParameters` to be removed entirely eventually. See [PR 3153]. - -- Add `estblished_in` to `SwarmEvent::ConnectionEstablished`. See [PR 3134]. - -- Remove deprecated `inject_*` methods from `NetworkBehaviour` and `ConnectionHandler`. - see [PR 3264]. - -- Update to `libp2p-swarm-derive` `v0.32.0`. - -- Remove type parameter from `PendingOutboundConnectionError` and `PendingInboundConnectionError`. - These two types are always used with `std::io::Error`. See [PR 3272]. - -- Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. - - Remove `handler` field from `NetworkBehaviourAction::Dial`. Instead of constructing the handler early, you can now access the `ConnectionId` of the future connection on `DialOpts`. `ConnectionId`s are `Copy` and will be used throughout the entire lifetime of the connection to report events. @@ -26,7 +9,7 @@ The third one used to be defaulted to the `InEvent` of the `ConnectionHandler`. You now have to manually specify that where you previously had to specify the `ConnectionHandler`. This very likely will trigger **convoluted compile errors** about traits not being implemented. - + Within `NetworkBehaviourAction::poll`, the easiest way to migrate is to do this (in the example of `libp2p-floodsub`): ```diff --- a/protocols/floodsub/src/layer.rs @@ -38,15 +21,32 @@ - ) -> Poll> { + ) -> Poll>> { ``` - + In other words: |Search|Replace| - |---|---| + |---|---| |`NetworkBehaviourAction`|`NetworkBehaviourAction>`| See [PR 3328]. +- Update to `libp2p-core` `v0.39.0`. + +- Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170]. +- Deprecate functions on `PollParameters` in preparation for `PollParameters` to be removed entirely eventually. See [PR 3153]. + +- Add `estblished_in` to `SwarmEvent::ConnectionEstablished`. See [PR 3134]. + +- Remove deprecated `inject_*` methods from `NetworkBehaviour` and `ConnectionHandler`. + see [PR 3264]. + +- Update to `libp2p-swarm-derive` `v0.32.0`. + +- Remove type parameter from `PendingOutboundConnectionError` and `PendingInboundConnectionError`. + These two types are always used with `std::io::Error`. See [PR 3272]. + +- Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. + [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 [PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153 From 1a3a1009fd2b0854cf88c087fe96606c2d7ab2b3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Jan 2023 22:13:59 +1100 Subject: [PATCH 077/177] Add more text to changelog entry --- swarm/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index a8fbfd1723d..b8e3f9d1a74 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -28,6 +28,9 @@ |---|---| |`NetworkBehaviourAction`|`NetworkBehaviourAction>`| + If you reference `NetworkBehaviourAction` somewhere else as well, + you may have to fill in the type of `ConnectionHandler::InEvent` manually as the 2nd parameter. + See [PR 3328]. - Update to `libp2p-core` `v0.39.0`. From 5535395ec51a7998c3fcf137f458127882ddbfa6 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 18 Jan 2023 22:15:21 +1100 Subject: [PATCH 078/177] Fix formatting --- protocols/ping/src/lib.rs | 3 ++- protocols/rendezvous/src/server.rs | 3 +-- protocols/request-response/src/lib.rs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 8f575e29a95..d675eb9c89b 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -49,7 +49,8 @@ use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::PeerId; use libp2p_swarm::{ - behaviour::FromSwarm, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + behaviour::FromSwarm, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, }; use std::{ collections::VecDeque, diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 14781a929f0..099b5979da9 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -31,8 +31,7 @@ use libp2p_core::PeerId; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, - THandlerInEvent, + PollParameters, THandlerInEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::iter::FromIterator; diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 4f92acde52a..97513d6a145 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -75,8 +75,7 @@ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, ConnectionId, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, - THandlerInEvent, + PollParameters, THandlerInEvent, }; use smallvec::SmallVec; use std::{ From 70690dac8af03ad03d9fdb04a6c789ad823c30a5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 23 Jan 2023 17:24:49 +1100 Subject: [PATCH 079/177] Fix most errors --- core/src/connection.rs | 1 - protocols/autonat/src/behaviour.rs | 4 +- protocols/dcutr/src/behaviour_impl.rs | 143 +++++++++++---------- protocols/floodsub/src/layer.rs | 4 +- protocols/gossipsub/src/behaviour.rs | 7 +- protocols/identify/src/behaviour.rs | 8 +- protocols/kad/src/behaviour.rs | 3 +- protocols/mdns/src/behaviour.rs | 7 +- protocols/ping/src/lib.rs | 4 +- protocols/relay/src/behaviour.rs | 7 +- protocols/relay/src/behaviour/handler.rs | 5 +- protocols/relay/src/priv_client.rs | 17 +-- protocols/relay/src/priv_client/handler.rs | 1 + protocols/rendezvous/src/client.rs | 2 +- protocols/rendezvous/src/server.rs | 2 +- protocols/request-response/src/lib.rs | 4 +- swarm/src/behaviour.rs | 4 +- swarm/src/behaviour/toggle.rs | 7 +- swarm/src/connection/pool.rs | 5 +- swarm/src/dummy.rs | 7 +- swarm/src/handler/select.rs | 17 +-- swarm/src/lib.rs | 6 +- swarm/src/test.rs | 4 +- swarm/tests/swarm_derive.rs | 9 +- 24 files changed, 144 insertions(+), 134 deletions(-) diff --git a/core/src/connection.rs b/core/src/connection.rs index 1613dd7c925..7a339b0661b 100644 --- a/core/src/connection.rs +++ b/core/src/connection.rs @@ -19,7 +19,6 @@ // DEALINGS IN THE SOFTWARE. use crate::multiaddr::{Multiaddr, Protocol}; -use std::fmt::Debug; /// The endpoint roles associated with a peer-to-peer communication channel. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 61d4313f5d5..2f01a8eb19e 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -37,8 +37,8 @@ use libp2p_swarm::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, FromSwarm, }, - ConnectionHandler, ConnectionId, ExternalAddresses, IntoConnectionHandler, ListenAddresses, - NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandlerInEvent, + ConnectionId, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use std::error::Error; use std::{ diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index af4995783f2..0755c36c137 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -20,19 +20,17 @@ //! [`NetworkBehaviour`] to act as a direct connection upgrade through relay node. -use crate::handler; use crate::handler::{direct, relayed, Role}; -use crate::protocol; use either::Either; use libp2p_core::connection::ConnectedPoint; use libp2p_core::multiaddr::Protocol; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::dial_opts::{self, DialOpts}; -use libp2p_swarm::ConnectionId; +use libp2p_swarm::{dummy, ConnectionId, THandler, THandlerOutEvent}; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerUpgrErr, ExternalAddresses, IntoConnectionHandler, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, + NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::task::{Context, Poll}; @@ -66,14 +64,15 @@ pub enum Error { #[error("Failed to dial peer.")] Dial, #[error("Failed to establish substream: {0}.")] - Handler(ConnectionHandlerUpgrErr), + Handler(ConnectionHandlerUpgrErr), } pub struct Behaviour { /// Queue of actions to return when polled. - queued_events: VecDeque>>, + queued_actions: + VecDeque>>>, - direct_outgoing_connection_attempts: HashMap, + direct_outgoing_connection_attempts: HashMap, /// All direct (non-relayed) connections. direct_connections: HashMap>, @@ -90,7 +89,7 @@ pub struct Behaviour { impl Behaviour { pub fn new(local_peer_id: PeerId) -> Self { Behaviour { - queued_events: Default::default(), + queued_actions: Default::default(), direct_outgoing_connection_attempts: Default::default(), direct_connections: Default::default(), external_addresses: Default::default(), @@ -129,11 +128,11 @@ impl Behaviour { // connection upgrade by initiating a direct connection to A. // // https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol - self.queued_events.extend([ + self.queued_actions.extend([ NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(connection_id), - event: Either::Left(handler::relayed::Command::Connect { + event: Either::Left(relayed::Command::Connect { obs_addrs: self.observed_addreses(), attempt: 1, }), @@ -157,12 +156,21 @@ impl Behaviour { } } - fn on_dial_failure(&mut self, DialFailure { peer_id, id, .. }: DialFailure) { - let (relayed_connection_id, role) = - match self.direct_outgoing_connection_attempts.remove(&id) { - None => return, - Some((relayed_connection_id, role)) => (relayed_connection_id, role), - }; + fn on_dial_failure( + &mut self, + DialFailure { + peer_id, + connection_id: failed_direct_connection, + .. + }: DialFailure, + ) { + let (relayed_connection_id, role) = match self + .direct_outgoing_connection_attempts + .remove(&failed_direct_connection) + { + None => return, + Some((relayed_connection_id, role)) => (relayed_connection_id, role), + }; let attempt = match role { Role::Listener => return, Role::Initiator { attempt } => attempt, @@ -170,24 +178,26 @@ impl Behaviour { let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - self.queued_actions.push_back(ActionBuilder::Connect { - peer_id, - handler: NotifyHandler::One(relayed_connection_id), - attempt: attempt + 1, - }); + self.queued_actions + .push_back(NetworkBehaviourAction::NotifyHandler { + peer_id, + handler: NotifyHandler::One(relayed_connection_id), + event: Either::Left(relayed::Command::Connect { + obs_addrs: self.observed_addreses(), + attempt: attempt + 1, + }), + }); } else { self.queued_actions.extend([ NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left(handler::relayed::Command::UpgradeFinishedDontKeepAlive), - } - .into(), + event: Either::Left(relayed::Command::UpgradeFinishedDontKeepAlive), + }, NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { remote_peer_id: peer_id, error: Error::Dial, - }) - .into(), + }), ]); } } @@ -231,7 +241,7 @@ impl NetworkBehaviour for Behaviour { ) -> Result, Box> { let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - let relayed_connection_id = match self + match self .direct_outgoing_connection_attempts .remove(&connection_id) { @@ -245,20 +255,18 @@ impl NetworkBehaviour for Behaviour { Either::Right(Either::Right(dummy::ConnectionHandler)) }; - return Ok(handler); + Ok(handler) } // TODO: Why are we ignoring `Role`? - Some((relayed_connection_id, _)) => relayed_connection_id, - }; - - assert!( - !is_relayed, - "`Prototype::DirectConnection` is never created for relayed connection." - ); + Some((_, _)) => { + assert!( + !is_relayed, + "`Prototype::DirectConnection` is never created for relayed connection." + ); - Ok(Either::Right(Either::Left(direct::Handler::new( - relayed_connection_id, - )))) + Ok(Either::Right(Either::Left(direct::Handler::default()))) + } + } } fn handle_established_outbound_connection( @@ -270,7 +278,7 @@ impl NetworkBehaviour for Behaviour { ) -> Result, Box> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - let relayed_connection_id = match self + match self .direct_outgoing_connection_attempts .remove(&connection_id) { @@ -284,27 +292,25 @@ impl NetworkBehaviour for Behaviour { Either::Right(Either::Right(dummy::ConnectionHandler)) }; - return Ok(handler); + Ok(handler) } // TODO: Why are we ignoring `Role`? - Some((relayed_connection_id, _)) => relayed_connection_id, - }; - - assert!( - !is_relayed, - "`Prototype::DirectConnection` is never created for relayed connection." - ); + Some((_, _)) => { + assert!( + !is_relayed, + "`Prototype::DirectConnection` is never created for relayed connection." + ); - Ok(Either::Right(Either::Left(direct::Handler::new( - relayed_connection_id, - )))) + Ok(Either::Right(Either::Left(direct::Handler::default()))) + } + } } fn on_connection_handler_event( &mut self, event_source: PeerId, connection_id: ConnectionId, - handler_event: <::Handler as ConnectionHandler>::OutEvent, + handler_event: THandlerOutEvent, ) { let relayed_connection_id = match handler_event.as_ref() { Either::Left(_) => connection_id, @@ -318,15 +324,15 @@ impl NetworkBehaviour for Behaviour { }; match handler_event { - Either::Left(handler::relayed::Event::InboundConnectRequest { + Either::Left(relayed::Event::InboundConnectRequest { inbound_connect, remote_addr, }) => { - self.queued_events.extend([ + self.queued_actions.extend([ NetworkBehaviourAction::NotifyHandler { handler: NotifyHandler::One(relayed_connection_id), peer_id: event_source, - event: Either::Left(handler::relayed::Command::AcceptInboundConnect { + event: Either::Left(relayed::Command::AcceptInboundConnect { inbound_connect, obs_addrs: self.observed_addreses(), }), @@ -339,8 +345,8 @@ impl NetworkBehaviour for Behaviour { ), ]); } - Either::Left(handler::relayed::Event::InboundNegotiationFailed { error }) => { - self.queued_events + Either::Left(relayed::Event::InboundNegotiationFailed { error }) => { + self.queued_actions .push_back(NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeFailed { remote_peer_id: event_source, @@ -348,7 +354,7 @@ impl NetworkBehaviour for Behaviour { }, )); } - Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => { + Either::Left(relayed::Event::InboundConnectNegotiated(remote_addrs)) => { let opts = DialOpts::peer_id(event_source) .addresses(remote_addrs) .condition(dial_opts::PeerCondition::Always) @@ -358,11 +364,11 @@ impl NetworkBehaviour for Behaviour { self.direct_to_relayed_connections .insert(maybe_direct_connection_id, relayed_connection_id); - self.queued_events + self.queued_actions .push_back(NetworkBehaviourAction::Dial { opts }); } - Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { - self.queued_events + Either::Left(relayed::Event::OutboundNegotiationFailed { error }) => { + self.queued_actions .push_back(NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeFailed { remote_peer_id: event_source, @@ -370,7 +376,7 @@ impl NetworkBehaviour for Behaviour { }, )); } - Either::Left(handler::relayed::Event::OutboundConnectNegotiated { remote_addrs }) => { + Either::Left(relayed::Event::OutboundConnectNegotiated { remote_addrs }) => { let opts = DialOpts::peer_id(event_source) .condition(dial_opts::PeerCondition::Always) .addresses(remote_addrs) @@ -385,17 +391,15 @@ impl NetworkBehaviour for Behaviour { .outgoing_direct_connection_attempts .entry((maybe_direct_connection_id, event_source)) .or_default() += 1; - self.queued_events + self.queued_actions .push_back(NetworkBehaviourAction::Dial { opts }); } - Either::Right(handler::direct::Event::DirectConnectionEstablished) => { - self.queued_events.extend([ + Either::Right(Either::Left(direct::Event::DirectConnectionEstablished)) => { + self.queued_actions.extend([ NetworkBehaviourAction::NotifyHandler { peer_id: event_source, handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left( - handler::relayed::Command::UpgradeFinishedDontKeepAlive, - ), + event: Either::Left(relayed::Command::UpgradeFinishedDontKeepAlive), }, NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeSucceeded { @@ -404,6 +408,7 @@ impl NetworkBehaviour for Behaviour { ), ]); } + Either::Right(Either::Right(never)) => void::unreachable(never), }; } @@ -412,7 +417,7 @@ impl NetworkBehaviour for Behaviour { _cx: &mut Context<'_>, _: &mut impl PollParameters, ) -> Poll>> { - if let Some(event) = self.queued_events.pop_front() { + if let Some(event) = self.queued_actions.pop_front() { return Poll::Ready(event); } diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index ddb5fa05c53..4e0e3ea182f 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -26,11 +26,11 @@ use crate::topic::Topic; use crate::FloodsubConfig; use cuckoofilter::{CuckooError, CuckooFilter}; use fnv::FnvHashSet; -use libp2p_core::PeerId; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::{ dial_opts::DialOpts, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - OneShotHandler, PollParameters, THandlerInEvent, + OneShotHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use log::warn; use smallvec::SmallVec; diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 0e03e880ec2..4448b520652 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -36,13 +36,14 @@ use prost::Message; use rand::{seq::SliceRandom, thread_rng}; use libp2p_core::{ - identity::Keypair, multiaddr::Protocol::Ip4, multiaddr::Protocol::Ip6, Endpoint, Multiaddr, PeerId, + identity::Keypair, multiaddr::Protocol::Ip4, multiaddr::Protocol::Ip6, Endpoint, Multiaddr, + PeerId, }; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, dial_opts::DialOpts, - ConnectionHandler, ConnectionId, IntoConnectionHandler, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandler, THandlerInEvent, THandlerOutEvent, }; use wasm_timer::Instant; diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 51aa02a89bf..f6ecd0ab7fc 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -22,12 +22,12 @@ use crate::handler::{self, Handler, InEvent}; use crate::protocol::{Info, Protocol, UpgradeError}; use libp2p_core::{multiaddr, ConnectedPoint, Endpoint, Multiaddr, PeerId, PublicKey}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; -use libp2p_swarm::ConnectionId; use libp2p_swarm::{ - dial_opts::DialOpts, AddressScore, ConnectionHandler, ConnectionHandlerUpgrErr, DialError, - ExternalAddresses, IntoConnectionHandler, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + dial_opts::DialOpts, AddressScore, ConnectionHandlerUpgrErr, DialError, ExternalAddresses, + ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandlerInEvent, }; +use libp2p_swarm::{ConnectionId, THandler, THandlerOutEvent}; use lru::LruCache; use std::error::Error; use std::num::NonZeroUsize; diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index e310713919f..e9580d6e7db 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -46,7 +46,8 @@ use libp2p_swarm::behaviour::{ use libp2p_swarm::{ dial_opts::{self, DialOpts}, ConnectionId, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, THandlerInEvent, + THandlerOutEvent, }; use log::{debug, info, warn}; use smallvec::SmallVec; diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index ce259663624..da3c508a7a3 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -27,12 +27,11 @@ use crate::behaviour::{socket::AsyncSocket, timer::Builder}; use crate::Config; use futures::Stream; use if_watch::IfEvent; -use libp2p_core::connection::ConnectionId; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - dummy, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, - THandlerInEvent, THandlerOutEvent, + dummy, ConnectionId, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandler, THandlerOutEvent, }; use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; @@ -252,7 +251,7 @@ where fn on_connection_handler_event( &mut self, _: PeerId, - _: libp2p_core::connection::ConnectionId, + _: ConnectionId, ev: THandlerOutEvent, ) { void::unreachable(ev) diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 436eadc0a42..b2824e4233c 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -47,10 +47,10 @@ mod protocol; use handler::Handler; pub use handler::{Config, Failure, Success}; -use libp2p_core::PeerId; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::{ behaviour::FromSwarm, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerInEvent, + THandler, THandlerInEvent, THandlerOutEvent, }; use std::error::Error; use std::{ diff --git a/protocols/relay/src/behaviour.rs b/protocols/relay/src/behaviour.rs index d14144d7ebe..5e1092a8ecc 100644 --- a/protocols/relay/src/behaviour.rs +++ b/protocols/relay/src/behaviour.rs @@ -23,17 +23,18 @@ mod handler; pub mod rate_limiter; +use crate::behaviour::handler::Handler; use crate::message_proto; use crate::protocol::{inbound_hop, outbound_stop}; -use crate::v2::relay::handler::Handler; use either::Either; use instant::Instant; use libp2p_core::multiaddr::Protocol; use libp2p_core::{ConnectedPoint, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - ConnectionHandlerUpgrErr, ConnectionId, ExternalAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + dummy, ConnectionHandlerUpgrErr, ConnectionId, ExternalAddresses, NetworkBehaviour, + NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, THandlerInEvent, + THandlerOutEvent, }; use std::collections::{hash_map, HashMap, HashSet, VecDeque}; use std::error::Error; diff --git a/protocols/relay/src/behaviour/handler.rs b/protocols/relay/src/behaviour/handler.rs index e50b3e4875e..b75ade9834d 100644 --- a/protocols/relay/src/behaviour/handler.rs +++ b/protocols/relay/src/behaviour/handler.rs @@ -23,6 +23,7 @@ use crate::copy_future::CopyFuture; use crate::message_proto::Status; use crate::protocol::{inbound_hop, outbound_stop}; use bytes::Bytes; +use either::Either; use futures::channel::oneshot::{self, Canceled}; use futures::future::{BoxFuture, FutureExt, TryFutureExt}; use futures::io::AsyncWriteExt; @@ -35,8 +36,8 @@ use libp2p_swarm::handler::{ ListenUpgradeError, }; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, ConnectionId, - IntoConnectionHandler, KeepAlive, NegotiatedSubstream, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, ConnectionId, KeepAlive, + NegotiatedSubstream, SubstreamProtocol, }; use std::collections::VecDeque; use std::fmt; diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 70aa5ae32e5..0b106717b46 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -23,6 +23,7 @@ mod handler; pub(crate) mod transport; +use crate::priv_client::handler::Handler; use crate::protocol::{self, inbound_stop, outbound_hop}; use bytes::Bytes; use either::Either; @@ -32,12 +33,14 @@ use futures::future::{BoxFuture, FutureExt}; use futures::io::{AsyncRead, AsyncWrite}; use futures::ready; use futures::stream::StreamExt; -use libp2p_core::PeerId; +use libp2p_core::multiaddr::Protocol; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ - ConnectionHandlerUpgrErr, ConnectionId, NegotiatedSubstream, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, + dummy, ConnectionHandler, ConnectionHandlerUpgrErr, ConnectionId, NegotiatedSubstream, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, + THandlerInEvent, THandlerOutEvent, }; use std::collections::{hash_map, HashMap, VecDeque}; use std::io::{Error, ErrorKind, IoSlice}; @@ -103,8 +106,6 @@ pub struct Behaviour { queued_actions: VecDeque>>, pending_handler_commands: HashMap, - - pending_events: HashMap, } /// Create a new client relay [`Behaviour`] with it's corresponding [`Transport`]. @@ -115,7 +116,7 @@ pub fn new(local_peer_id: PeerId) -> (Transport, Behaviour) { from_transport, directly_connected_peers: Default::default(), queued_actions: Default::default(), - pending_events: Default::default(), + pending_handler_commands: Default::default(), }; (transport, behaviour) } @@ -176,7 +177,7 @@ impl NetworkBehaviour for Behaviour { let mut handler = Handler::new(self.local_peer_id, peer, remote_addr.clone()); - if let Some(event) = self.pending_events.remove(&connection_id) { + if let Some(event) = self.pending_handler_commands.remove(&connection_id) { handler.on_behaviour_event(event) } @@ -198,7 +199,7 @@ impl NetworkBehaviour for Behaviour { let mut handler = Handler::new(self.local_peer_id, peer, addr.clone()); - if let Some(event) = self.pending_events.remove(&connection_id) { + if let Some(event) = self.pending_handler_commands.remove(&connection_id) { handler.on_behaviour_event(event) } diff --git a/protocols/relay/src/priv_client/handler.rs b/protocols/relay/src/priv_client/handler.rs index 5f3489869ba..1891813d489 100644 --- a/protocols/relay/src/priv_client/handler.rs +++ b/protocols/relay/src/priv_client/handler.rs @@ -21,6 +21,7 @@ use crate::message_proto::Status; use crate::priv_client::transport; use crate::protocol::{self, inbound_stop, outbound_hop}; +use either::Either; use futures::channel::{mpsc, oneshot}; use futures::future::{BoxFuture, FutureExt}; use futures::sink::SinkExt; diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index b815c04f6e2..23e0e75695a 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -34,7 +34,7 @@ use libp2p_core::{Endpoint, Multiaddr, PeerId, PeerRecord}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, ConnectionId, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandlerInEvent, + NotifyHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, VecDeque}; use std::error::Error; diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index bf56ee2a40d..0d3ebad4110 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -31,7 +31,7 @@ use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ CloseConnection, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, THandlerInEvent, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::iter::FromIterator; diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index c75ff5574df..6a96cf2ce5d 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -74,8 +74,8 @@ use libp2p_core::{ConnectedPoint, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, - ConnectionId, IntoConnectionHandler, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, THandlerInEvent, + ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandler, THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::{ diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 8a78d7ad096..e403c0cbf4d 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -31,9 +31,7 @@ use crate::dial_opts::DialOpts; #[allow(deprecated)] use crate::handler::IntoConnectionHandler; use crate::{AddressRecord, AddressScore, DialError, THandler, THandlerInEvent, THandlerOutEvent}; -use libp2p_core::{ - transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId, -}; +use libp2p_core::{transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId}; use std::{task::Context, task::Poll}; /// A [`NetworkBehaviour`] defines the behaviour of the local node on the network. diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 14d0a0b12fd..2152ae6a193 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -26,9 +26,12 @@ use crate::handler::{ KeepAlive, ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; -use crate::{NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, THandlerOutEvent}; +use crate::{ + NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, + THandlerOutEvent, +}; use either::Either; -use libp2p_core::{either::EitherOutput, upgrade::DeniedUpgrade, Multiaddr, PeerId, Endpoint}; +use libp2p_core::{either::EitherOutput, upgrade::DeniedUpgrade, Endpoint, Multiaddr, PeerId}; use std::error::Error; use std::{task::Context, task::Poll}; diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 5f155f10c17..7beefd64834 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -41,10 +41,10 @@ use futures::{ use instant::Instant; use libp2p_core::connection::Endpoint; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerExt}; -use std::task::Waker; use libp2p_core::ProtocolName; use smallvec::SmallVec; use std::error::Error; +use std::task::Waker; use std::{ collections::{hash_map, HashMap}, convert::TryFrom as _, @@ -131,7 +131,8 @@ where no_established_connections_waker: Option, /// Receivers for events reported from established connections. - established_connection_events: SelectAll>>, + established_connection_events: + SelectAll>>, } #[derive(Debug)] diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 98c5459ffa4..0112cb650d7 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,10 +1,13 @@ use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; -use crate::derive_prelude::Multiaddr; use crate::connection::ConnectionId; +use crate::derive_prelude::Multiaddr; use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; -use crate::{ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandler, THandlerInEvent, THandlerOutEvent}; +use crate::{ + ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandler, + THandlerInEvent, THandlerOutEvent, +}; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::UpgradeError; use libp2p_core::{Endpoint, PeerId}; diff --git a/swarm/src/handler/select.rs b/swarm/src/handler/select.rs index ed7467d60d1..056723d285d 100644 --- a/swarm/src/handler/select.rs +++ b/swarm/src/handler/select.rs @@ -102,7 +102,7 @@ impl ConnectionHandlerSelect { } impl - FullyNegotiatedOutbound, SendWrapper>, Either> + FullyNegotiatedOutbound, SendWrapper>, Either> where S1OP: OutboundUpgradeSend, S2OP: OutboundUpgradeSend, @@ -127,10 +127,7 @@ where } impl - FullyNegotiatedInbound< - Either, SendWrapper>, - Either, - > + FullyNegotiatedInbound, SendWrapper>, Either> where S1OP: InboundUpgradeSend, S2OP: InboundUpgradeSend, @@ -142,11 +139,11 @@ where ) -> Either, FullyNegotiatedInbound> { match self { FullyNegotiatedInbound { - protocol: Either::Left(protocol), + protocol: EitherOutput::First(protocol), info: Either::Left(info), } => Either::Left(FullyNegotiatedInbound { protocol, info }), FullyNegotiatedInbound { - protocol: Either::Right(protocol), + protocol: EitherOutput::Second(protocol), info: Either::Right(info), } => Either::Right(FullyNegotiatedInbound { protocol, info }), _ => panic!("wrong API usage: the protocol doesn't match the upgrade info"), @@ -448,7 +445,7 @@ where >; type OutboundProtocol = Either, SendWrapper>; - type OutboundOpenInfo = EitherOutput; + type OutboundOpenInfo = Either; type InboundOpenInfo = (TProto1::InboundOpenInfo, TProto2::InboundOpenInfo); fn listen_protocol(&self) -> SubstreamProtocol { @@ -497,7 +494,7 @@ where return Poll::Ready(ConnectionHandlerEvent::OutboundSubstreamRequest { protocol: protocol .map_upgrade(|u| Either::Left(SendWrapper(u))) - .map_info(EitherOutput::First), + .map_info(Either::Left), }); } Poll::Pending => (), @@ -514,7 +511,7 @@ where return Poll::Ready(ConnectionHandlerEvent::OutboundSubstreamRequest { protocol: protocol .map_upgrade(|u| Either::Right(SendWrapper(u))) - .map_info(EitherOutput::Second), + .map_info(Either::Right), }); } Poll::Pending => (), diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 19ba13b18c7..c1b1ec2391f 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -577,7 +577,7 @@ where let num_addresses = addresses.len(); if num_addresses > 0 { - log::debug!("discarding {num_addresses} addresses from `NetworkBehaviour` because `DialOpts::extend_addresses_through_behaviour is `false` for connection {connection_id}") + log::debug!("discarding {num_addresses} addresses from `NetworkBehaviour` because `DialOpts::extend_addresses_through_behaviour is `false` for connection {connection_id:?}") } } } @@ -588,7 +588,7 @@ where .on_swarm_event(FromSwarm::DialFailure(DialFailure { peer_id, error: &error, - id: connection_id, + connection_id, })); return Err(error); @@ -954,7 +954,7 @@ where let dial_error = DialError::Denied { cause }; self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { - id, + connection_id: id, error: &dial_error, peer_id: Some(peer_id), })); diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 0f669f4b55f..c665c2cf62e 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -23,8 +23,8 @@ use crate::behaviour::{ FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, }; use crate::{ - ConnectionHandler, ConnectionId, IntoConnectionHandler, NetworkBehaviour, - NetworkBehaviourAction, PollParameters, THandlerInEvent, + ConnectionHandler, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + THandlerInEvent, THandlerOutEvent, }; use libp2p_core::{multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId}; use std::collections::HashMap; diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 5c56f6c87e6..f04cf4d2f6c 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -21,7 +21,9 @@ use futures::StreamExt; use libp2p_identify as identify; use libp2p_ping as ping; -use libp2p_swarm::{behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent, THandlerInEvent}; +use libp2p_swarm::{ + behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent, THandlerInEvent, THandlerOutEvent, +}; use std::fmt::Debug; /// Small utility to check that a type implements `NetworkBehaviour`. @@ -369,10 +371,7 @@ fn generated_out_event_derive_debug() { #[test] fn custom_out_event_no_type_parameters() { use libp2p_core::PeerId; - use libp2p_swarm::{ - ConnectionHandler, ConnectionId, IntoConnectionHandler, NetworkBehaviourAction, - PollParameters, - }; + use libp2p_swarm::{ConnectionId, NetworkBehaviourAction, PollParameters}; use std::task::Context; use std::task::Poll; From 649745ca09bd3ac6c4980776cdc4b5f4010f6c1b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 00:11:19 +1100 Subject: [PATCH 080/177] Fix implementation of dcutr --- protocols/dcutr/src/behaviour_impl.rs | 45 ++++++++++++++------------- protocols/dcutr/src/handler.rs | 5 --- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 0755c36c137..80baf517801 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -20,7 +20,7 @@ //! [`NetworkBehaviour`] to act as a direct connection upgrade through relay node. -use crate::handler::{direct, relayed, Role}; +use crate::handler::{direct, relayed}; use either::Either; use libp2p_core::connection::ConnectedPoint; use libp2p_core::multiaddr::Protocol; @@ -72,8 +72,6 @@ pub struct Behaviour { queued_actions: VecDeque>>>, - direct_outgoing_connection_attempts: HashMap, - /// All direct (non-relayed) connections. direct_connections: HashMap>, @@ -90,7 +88,6 @@ impl Behaviour { pub fn new(local_peer_id: PeerId) -> Self { Behaviour { queued_actions: Default::default(), - direct_outgoing_connection_attempts: Default::default(), direct_connections: Default::default(), external_addresses: Default::default(), local_peer_id, @@ -164,19 +161,25 @@ impl Behaviour { .. }: DialFailure, ) { - let (relayed_connection_id, role) = match self - .direct_outgoing_connection_attempts - .remove(&failed_direct_connection) + let peer_id = match peer_id { + None => return, + Some(peer_id) => peer_id, + }; + let attempt = match self + .outgoing_direct_connection_attempts + .remove(&(failed_direct_connection, peer_id)) { None => return, - Some((relayed_connection_id, role)) => (relayed_connection_id, role), + Some(attempt) => attempt, }; - let attempt = match role { - Role::Listener => return, - Role::Initiator { attempt } => attempt, + let relayed_connection_id = match self + .direct_to_relayed_connections + .get(&failed_direct_connection) + { + None => return, + Some(relayed_connection_id) => *relayed_connection_id, }; - let peer_id = peer_id.expect("Peer of `Prototype::DirectConnection` is always known."); if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { self.queued_actions .push_back(NetworkBehaviourAction::NotifyHandler { @@ -234,7 +237,7 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _peer: PeerId, + peer: PeerId, connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, @@ -242,8 +245,8 @@ impl NetworkBehaviour for Behaviour { let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. match self - .direct_outgoing_connection_attempts - .remove(&connection_id) + .outgoing_direct_connection_attempts + .remove(&(connection_id, peer)) { None => { let handler = if is_relayed { @@ -257,8 +260,7 @@ impl NetworkBehaviour for Behaviour { Ok(handler) } - // TODO: Why are we ignoring `Role`? - Some((_, _)) => { + Some(_) => { assert!( !is_relayed, "`Prototype::DirectConnection` is never created for relayed connection." @@ -271,7 +273,7 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, - _peer: PeerId, + peer: PeerId, addr: &Multiaddr, role_override: Endpoint, connection_id: ConnectionId, @@ -279,8 +281,8 @@ impl NetworkBehaviour for Behaviour { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. match self - .direct_outgoing_connection_attempts - .remove(&connection_id) + .outgoing_direct_connection_attempts + .remove(&(connection_id, peer)) { None => { let handler = if is_relayed { @@ -294,8 +296,7 @@ impl NetworkBehaviour for Behaviour { Ok(handler) } - // TODO: Why are we ignoring `Role`? - Some((_, _)) => { + Some(_) => { assert!( !is_relayed, "`Prototype::DirectConnection` is never created for relayed connection." diff --git a/protocols/dcutr/src/handler.rs b/protocols/dcutr/src/handler.rs index ca4fcafc5f4..cc59e3ab4ce 100644 --- a/protocols/dcutr/src/handler.rs +++ b/protocols/dcutr/src/handler.rs @@ -20,8 +20,3 @@ pub mod direct; pub mod relayed; - -pub enum Role { - Initiator { attempt: u8 }, - Listener, -} From 7216a1a5d0c79322be0d8bd210533f7573639e2a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 00:15:30 +1100 Subject: [PATCH 081/177] Reduce diff --- protocols/relay/src/behaviour.rs | 16 ++++++++-------- protocols/relay/src/behaviour/handler.rs | 4 ++-- protocols/relay/src/priv_client/handler.rs | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/protocols/relay/src/behaviour.rs b/protocols/relay/src/behaviour.rs index 5e1092a8ecc..b6d4316ef10 100644 --- a/protocols/relay/src/behaviour.rs +++ b/protocols/relay/src/behaviour.rs @@ -271,15 +271,15 @@ impl NetworkBehaviour for Behaviour { } Ok(Either::Left(Handler::new( - ConnectedPoint::Listener { - local_addr: local_addr.clone(), - send_back_addr: remote_addr.clone(), - }, handler::Config { reservation_duration: self.config.reservation_duration, max_circuit_duration: self.config.max_circuit_duration, max_circuit_bytes: self.config.max_circuit_bytes, }, + ConnectedPoint::Listener { + local_addr: local_addr.clone(), + send_back_addr: remote_addr.clone(), + }, ))) } @@ -298,15 +298,15 @@ impl NetworkBehaviour for Behaviour { } Ok(Either::Left(Handler::new( - ConnectedPoint::Dialer { - address: addr.clone(), - role_override, - }, handler::Config { reservation_duration: self.config.reservation_duration, max_circuit_duration: self.config.max_circuit_duration, max_circuit_bytes: self.config.max_circuit_bytes, }, + ConnectedPoint::Dialer { + address: addr.clone(), + role_override, + }, ))) } diff --git a/protocols/relay/src/behaviour/handler.rs b/protocols/relay/src/behaviour/handler.rs index b75ade9834d..adba9d738e5 100644 --- a/protocols/relay/src/behaviour/handler.rs +++ b/protocols/relay/src/behaviour/handler.rs @@ -393,8 +393,8 @@ pub struct Handler { } impl Handler { - pub fn new(endpoint: ConnectedPoint, config: Config) -> Self { - Self { + pub fn new(config: Config, endpoint: ConnectedPoint) -> Handler { + Handler { endpoint, config, queued_events: Default::default(), diff --git a/protocols/relay/src/priv_client/handler.rs b/protocols/relay/src/priv_client/handler.rs index 1891813d489..cae7db78322 100644 --- a/protocols/relay/src/priv_client/handler.rs +++ b/protocols/relay/src/priv_client/handler.rs @@ -160,13 +160,13 @@ impl Handler { local_peer_id, remote_peer_id, remote_addr, - pending_error: Default::default(), - keep_alive: KeepAlive::Yes, queued_events: Default::default(), + pending_error: Default::default(), reservation: Reservation::None, alive_lend_out_substreams: Default::default(), circuit_deny_futs: Default::default(), send_error_futs: Default::default(), + keep_alive: KeepAlive::Yes, } } From eb8f8b5d4ca52227a04515fceee4e34df80b794e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 00:17:36 +1100 Subject: [PATCH 082/177] Undo accidential change --- swarm/src/handler/one_shot.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/swarm/src/handler/one_shot.rs b/swarm/src/handler/one_shot.rs index c0abbae0b49..e8cd03ebed8 100644 --- a/swarm/src/handler/one_shot.rs +++ b/swarm/src/handler/one_shot.rs @@ -212,8 +212,9 @@ where self.events_out.push(out.into()); } ConnectionEvent::DialUpgradeError(DialUpgradeError { error, .. }) => { - log::debug!("failed to open stream: {}", error); - self.keep_alive = KeepAlive::No; + if self.pending_error.is_none() { + self.pending_error = Some(error); + } } ConnectionEvent::AddressChange(_) | ConnectionEvent::ListenUpgradeError(_) => {} } From 05337d5c50223db7f1f2b562c1041b063db4ca65 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 00:22:49 +1100 Subject: [PATCH 083/177] Reduce diff --- protocols/dcutr/src/behaviour_impl.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 80baf517801..f34fcb634fe 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -69,7 +69,7 @@ pub enum Error { pub struct Behaviour { /// Queue of actions to return when polled. - queued_actions: + queued_events: VecDeque>>>, /// All direct (non-relayed) connections. @@ -87,7 +87,7 @@ pub struct Behaviour { impl Behaviour { pub fn new(local_peer_id: PeerId) -> Self { Behaviour { - queued_actions: Default::default(), + queued_events: Default::default(), direct_connections: Default::default(), external_addresses: Default::default(), local_peer_id, @@ -125,7 +125,7 @@ impl Behaviour { // connection upgrade by initiating a direct connection to A. // // https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol - self.queued_actions.extend([ + self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(connection_id), @@ -181,7 +181,7 @@ impl Behaviour { }; if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { - self.queued_actions + self.queued_events .push_back(NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(relayed_connection_id), @@ -191,7 +191,7 @@ impl Behaviour { }), }); } else { - self.queued_actions.extend([ + self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(relayed_connection_id), @@ -329,7 +329,7 @@ impl NetworkBehaviour for Behaviour { inbound_connect, remote_addr, }) => { - self.queued_actions.extend([ + self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { handler: NotifyHandler::One(relayed_connection_id), peer_id: event_source, @@ -347,7 +347,7 @@ impl NetworkBehaviour for Behaviour { ]); } Either::Left(relayed::Event::InboundNegotiationFailed { error }) => { - self.queued_actions + self.queued_events .push_back(NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeFailed { remote_peer_id: event_source, @@ -365,11 +365,11 @@ impl NetworkBehaviour for Behaviour { self.direct_to_relayed_connections .insert(maybe_direct_connection_id, relayed_connection_id); - self.queued_actions + self.queued_events .push_back(NetworkBehaviourAction::Dial { opts }); } Either::Left(relayed::Event::OutboundNegotiationFailed { error }) => { - self.queued_actions + self.queued_events .push_back(NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeFailed { remote_peer_id: event_source, @@ -392,11 +392,11 @@ impl NetworkBehaviour for Behaviour { .outgoing_direct_connection_attempts .entry((maybe_direct_connection_id, event_source)) .or_default() += 1; - self.queued_actions + self.queued_events .push_back(NetworkBehaviourAction::Dial { opts }); } Either::Right(Either::Left(direct::Event::DirectConnectionEstablished)) => { - self.queued_actions.extend([ + self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id: event_source, handler: NotifyHandler::One(relayed_connection_id), @@ -418,7 +418,7 @@ impl NetworkBehaviour for Behaviour { _cx: &mut Context<'_>, _: &mut impl PollParameters, ) -> Poll>> { - if let Some(event) = self.queued_actions.pop_front() { + if let Some(event) = self.queued_events.pop_front() { return Poll::Ready(event); } From 338c35adc0d21b900d7f99facfb7723faecdfddb Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 00:30:59 +1100 Subject: [PATCH 084/177] Attempt to reduce diff --- protocols/dcutr/src/behaviour_impl.rs | 57 +++++++++++-------- .../gossipsub/src/subscription_filter.rs | 4 +- protocols/gossipsub/src/transform.rs | 2 +- protocols/kad/src/behaviour.rs | 5 +- protocols/relay/src/behaviour/handler.rs | 4 +- swarm/src/connection/pool.rs | 10 +--- 6 files changed, 41 insertions(+), 41 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index f34fcb634fe..58a54006b63 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -20,7 +20,7 @@ //! [`NetworkBehaviour`] to act as a direct connection upgrade through relay node. -use crate::handler::{direct, relayed}; +use crate::handler; use either::Either; use libp2p_core::connection::ConnectedPoint; use libp2p_core::multiaddr::Protocol; @@ -69,8 +69,9 @@ pub enum Error { pub struct Behaviour { /// Queue of actions to return when polled. - queued_events: - VecDeque>>>, + queued_events: VecDeque< + NetworkBehaviourAction>>, + >, /// All direct (non-relayed) connections. direct_connections: HashMap>, @@ -129,7 +130,7 @@ impl Behaviour { NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(connection_id), - event: Either::Left(relayed::Command::Connect { + event: Either::Left(handler::relayed::Command::Connect { obs_addrs: self.observed_addreses(), attempt: 1, }), @@ -183,11 +184,11 @@ impl Behaviour { if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { self.queued_events .push_back(NetworkBehaviourAction::NotifyHandler { - peer_id, handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left(relayed::Command::Connect { - obs_addrs: self.observed_addreses(), + peer_id, + event: Either::Left(handler::relayed::Command::Connect { attempt: attempt + 1, + obs_addrs: self.observed_addreses(), }), }); } else { @@ -195,7 +196,7 @@ impl Behaviour { NetworkBehaviourAction::NotifyHandler { peer_id, handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left(relayed::Command::UpgradeFinishedDontKeepAlive), + event: Either::Left(handler::relayed::Command::UpgradeFinishedDontKeepAlive), }, NetworkBehaviourAction::GenerateEvent(Event::DirectConnectionUpgradeFailed { remote_peer_id: peer_id, @@ -231,8 +232,10 @@ impl Behaviour { } impl NetworkBehaviour for Behaviour { - type ConnectionHandler = - Either>; + type ConnectionHandler = Either< + handler::relayed::Handler, + Either, + >; type OutEvent = Event; fn handle_established_inbound_connection( @@ -250,10 +253,10 @@ impl NetworkBehaviour for Behaviour { { None => { let handler = if is_relayed { - Either::Left(relayed::Handler::new(ConnectedPoint::Listener { + Either::Left(handler::relayed::Handler::new(ConnectedPoint::Listener { local_addr: local_addr.clone(), send_back_addr: remote_addr.clone(), - })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. + })) // TODO: We could make two `handler::relayed::Handler` here, one inbound one outbound. } else { Either::Right(Either::Right(dummy::ConnectionHandler)) }; @@ -266,7 +269,9 @@ impl NetworkBehaviour for Behaviour { "`Prototype::DirectConnection` is never created for relayed connection." ); - Ok(Either::Right(Either::Left(direct::Handler::default()))) + Ok(Either::Right(Either::Left( + handler::direct::Handler::default(), + ))) } } } @@ -286,10 +291,10 @@ impl NetworkBehaviour for Behaviour { { None => { let handler = if is_relayed { - Either::Left(relayed::Handler::new(ConnectedPoint::Dialer { + Either::Left(handler::relayed::Handler::new(ConnectedPoint::Dialer { address: addr.clone(), role_override, - })) // TODO: We could make two `relayed::Handler` here, one inbound one outbound. + })) // TODO: We could make two `handler::relayed::Handler` here, one inbound one outbound. } else { Either::Right(Either::Right(dummy::ConnectionHandler)) }; @@ -302,7 +307,9 @@ impl NetworkBehaviour for Behaviour { "`Prototype::DirectConnection` is never created for relayed connection." ); - Ok(Either::Right(Either::Left(direct::Handler::default()))) + Ok(Either::Right(Either::Left( + handler::direct::Handler::default(), + ))) } } } @@ -325,7 +332,7 @@ impl NetworkBehaviour for Behaviour { }; match handler_event { - Either::Left(relayed::Event::InboundConnectRequest { + Either::Left(handler::relayed::Event::InboundConnectRequest { inbound_connect, remote_addr, }) => { @@ -333,7 +340,7 @@ impl NetworkBehaviour for Behaviour { NetworkBehaviourAction::NotifyHandler { handler: NotifyHandler::One(relayed_connection_id), peer_id: event_source, - event: Either::Left(relayed::Command::AcceptInboundConnect { + event: Either::Left(handler::relayed::Command::AcceptInboundConnect { inbound_connect, obs_addrs: self.observed_addreses(), }), @@ -346,7 +353,7 @@ impl NetworkBehaviour for Behaviour { ), ]); } - Either::Left(relayed::Event::InboundNegotiationFailed { error }) => { + Either::Left(handler::relayed::Event::InboundNegotiationFailed { error }) => { self.queued_events .push_back(NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeFailed { @@ -355,7 +362,7 @@ impl NetworkBehaviour for Behaviour { }, )); } - Either::Left(relayed::Event::InboundConnectNegotiated(remote_addrs)) => { + Either::Left(handler::relayed::Event::InboundConnectNegotiated(remote_addrs)) => { let opts = DialOpts::peer_id(event_source) .addresses(remote_addrs) .condition(dial_opts::PeerCondition::Always) @@ -368,7 +375,7 @@ impl NetworkBehaviour for Behaviour { self.queued_events .push_back(NetworkBehaviourAction::Dial { opts }); } - Either::Left(relayed::Event::OutboundNegotiationFailed { error }) => { + Either::Left(handler::relayed::Event::OutboundNegotiationFailed { error }) => { self.queued_events .push_back(NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeFailed { @@ -377,7 +384,7 @@ impl NetworkBehaviour for Behaviour { }, )); } - Either::Left(relayed::Event::OutboundConnectNegotiated { remote_addrs }) => { + Either::Left(handler::relayed::Event::OutboundConnectNegotiated { remote_addrs }) => { let opts = DialOpts::peer_id(event_source) .condition(dial_opts::PeerCondition::Always) .addresses(remote_addrs) @@ -395,12 +402,14 @@ impl NetworkBehaviour for Behaviour { self.queued_events .push_back(NetworkBehaviourAction::Dial { opts }); } - Either::Right(Either::Left(direct::Event::DirectConnectionEstablished)) => { + Either::Right(Either::Left(handler::direct::Event::DirectConnectionEstablished)) => { self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id: event_source, handler: NotifyHandler::One(relayed_connection_id), - event: Either::Left(relayed::Command::UpgradeFinishedDontKeepAlive), + event: Either::Left( + handler::relayed::Command::UpgradeFinishedDontKeepAlive, + ), }, NetworkBehaviourAction::GenerateEvent( Event::DirectConnectionUpgradeSucceeded { diff --git a/protocols/gossipsub/src/subscription_filter.rs b/protocols/gossipsub/src/subscription_filter.rs index 63e1b6a598e..ec6cb6756ba 100644 --- a/protocols/gossipsub/src/subscription_filter.rs +++ b/protocols/gossipsub/src/subscription_filter.rs @@ -23,7 +23,7 @@ use crate::TopicHash; use log::debug; use std::collections::{BTreeSet, HashMap, HashSet}; -pub trait TopicSubscriptionFilter: Send + 'static { +pub trait TopicSubscriptionFilter { /// Returns true iff the topic is of interest and we can subscribe to it. fn can_subscribe(&mut self, topic_hash: &TopicHash) -> bool; @@ -193,7 +193,7 @@ where impl TopicSubscriptionFilter for CallbackSubscriptionFilter where - T: FnMut(&TopicHash) -> bool + Send + 'static, + T: FnMut(&TopicHash) -> bool, { fn can_subscribe(&mut self, topic_hash: &TopicHash) -> bool { (self.0)(topic_hash) diff --git a/protocols/gossipsub/src/transform.rs b/protocols/gossipsub/src/transform.rs index fc4a44d62c9..ed11c78e5e0 100644 --- a/protocols/gossipsub/src/transform.rs +++ b/protocols/gossipsub/src/transform.rs @@ -35,7 +35,7 @@ use crate::{GossipsubMessage, RawGossipsubMessage, TopicHash}; /// outbound transform MUST leave the underlying data un-modified. /// /// By default, this is the identity transform for all fields in [`GossipsubMessage`]. -pub trait DataTransform: Send + 'static { +pub trait DataTransform { /// Takes a [`RawGossipsubMessage`] received and converts it to a [`GossipsubMessage`]. fn inbound_transform( &self, diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index e9580d6e7db..b907a4cef92 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -64,10 +64,7 @@ pub use crate::query::QueryStats; /// `Kademlia` is a `NetworkBehaviour` that implements the libp2p /// Kademlia protocol. -pub struct Kademlia -where - TStore: RecordStore + Send + 'static, -{ +pub struct Kademlia { /// The Kademlia routing table. kbuckets: KBucketsTable, Addresses>, diff --git a/protocols/relay/src/behaviour/handler.rs b/protocols/relay/src/behaviour/handler.rs index adba9d738e5..4ed521d57c1 100644 --- a/protocols/relay/src/behaviour/handler.rs +++ b/protocols/relay/src/behaviour/handler.rs @@ -399,13 +399,13 @@ impl Handler { config, queued_events: Default::default(), pending_error: Default::default(), - keep_alive: KeepAlive::Yes, reservation_request_future: Default::default(), - active_reservation: Default::default(), circuit_accept_futures: Default::default(), circuit_deny_futures: Default::default(), alive_lend_out_substreams: Default::default(), circuits: Default::default(), + active_reservation: Default::default(), + keep_alive: KeepAlive::Yes, } } diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 7beefd64834..a291ae2e648 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -207,10 +207,7 @@ impl PendingConnection { } } -impl fmt::Debug for Pool -where - THandler: ConnectionHandler, -{ +impl fmt::Debug for Pool { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { f.debug_struct("Pool") .field("counters", &self.counters) @@ -221,10 +218,7 @@ where /// Event that can happen on the `Pool`. #[derive(Debug)] #[allow(clippy::large_enum_variant)] -pub enum PoolEvent -where - THandler: ConnectionHandler, -{ +pub enum PoolEvent { /// A new connection has been established. ConnectionEstablished { id: ConnectionId, From c0a7d2a22b67fd42937339f8c1aa31e10b2fe375 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 12:31:42 +1100 Subject: [PATCH 085/177] Remove unnecessary `..` --- protocols/gossipsub/src/behaviour/tests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 5329ab5a1e1..948867e0a1a 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -1392,7 +1392,7 @@ fn test_explicit_peer_gets_connected() { .events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(peer), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id() == Some(peer), _ => false, }) .count(); @@ -1433,7 +1433,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id() == Some(*peer), _ => false, }) .count(), @@ -1448,7 +1448,7 @@ fn test_explicit_peer_reconnects() { gs.events .iter() .filter(|e| match e { - NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id() == Some(*peer), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id() == Some(*peer), _ => false, }) .count() @@ -1828,7 +1828,7 @@ fn test_connect_to_px_peers_on_handle_prune() { .events .iter() .filter_map(|e| match e { - NetworkBehaviourAction::Dial { opts, .. } => opts.get_peer_id(), + NetworkBehaviourAction::Dial { opts } => opts.get_peer_id(), _ => None, }) .collect(); From 04da3b468f40e54223919c9307f83641907b22aa Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 13:13:19 +1100 Subject: [PATCH 086/177] WIP --- swarm/src/behaviour.rs | 6 ++++-- swarm/src/connection.rs | 2 +- swarm/src/lib.rs | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 12a3122212b..059687e40eb 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -29,7 +29,7 @@ pub use listen_addresses::ListenAddresses; use crate::connection::ConnectionId; use crate::dial_opts::DialOpts; use crate::handler::{ConnectionHandler, IntoConnectionHandler}; -use crate::{AddressRecord, AddressScore, DialError}; +use crate::{AddressRecord, AddressScore, DialError, ListenError}; use libp2p_core::{transport::ListenerId, ConnectedPoint, Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -746,6 +746,7 @@ pub struct DialFailure<'a, Handler> { pub struct ListenFailure<'a, Handler> { pub local_addr: &'a Multiaddr, pub send_back_addr: &'a Multiaddr, + pub error: &'a ListenError, pub handler: Handler, } @@ -874,10 +875,11 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, - handler, + error, handler, }) => Some(FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, + error, handler: map_into_handler(handler)?, })), FromSwarm::NewListener(NewListener { listener_id }) => { diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index cfa54bf57ac..baa3896462c 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -376,7 +376,7 @@ impl<'a> IncomingInfo<'a> { } /// Information about a connection limit. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct ConnectionLimit { /// The maximum number of connections. pub limit: u32, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ee8a28081ab..709ce331544 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -233,7 +233,7 @@ pub enum SwarmEvent { /// Address used to send back data to the remote. send_back_addr: Multiaddr, /// The error that happened. - error: PendingInboundConnectionError, + error: ListenError, }, /// Outgoing connection attempt failed. OutgoingConnectionError { @@ -850,11 +850,14 @@ where error, handler, } => { + let error = error.into(); + log::debug!("Incoming connection failed: {:?}", error); self.behaviour .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr: &local_addr, send_back_addr: &send_back_addr, + error: &error, handler, })); return Some(SwarmEvent::IncomingConnectionError { @@ -970,10 +973,13 @@ where }); } Err((connection_limit, handler)) => { + let error = ListenError::ConnectionLimit(connection_limit); + self.behaviour .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr: &local_addr, send_back_addr: &send_back_addr, + error: &error, handler, })); log::warn!("Incoming connection rejected: {:?}", connection_limit); @@ -1685,6 +1691,34 @@ impl error::Error for DialError { } } +#[derive(Debug)] +pub enum ListenError { + /// The peer is currently banned. + Banned, + /// The configured limit for simultaneous outgoing connections + /// has been reached. + ConnectionLimit(ConnectionLimit), + /// Pending connection attempt has been aborted. + Aborted, + /// The peer identity obtained on the connection did not match the one that was expected. + WrongPeerId { + obtained: PeerId, + endpoint: ConnectedPoint, + }, + /// An I/O error occurred on the connection. + ConnectionIo(io::Error), + /// An error occurred while negotiating the transport protocol(s) on a connection. + Transport(Vec<(Multiaddr, TransportError)>), +} + +impl From for ListenError { + fn from(error: PendingInboundConnectionError) -> Self { + match error { + + } + } +} + /// Information about the connections obtained by [`Swarm::network_info()`]. #[derive(Clone, Debug)] pub struct NetworkInfo { From 2384c7292e501af7de0d79e58991885660c72e45 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 13:33:14 +1100 Subject: [PATCH 087/177] Remove unused error variant --- misc/metrics/src/swarm.rs | 2 -- swarm/CHANGELOG.md | 5 +++++ swarm/src/connection/error.rs | 7 ------- swarm/src/lib.rs | 1 - 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index 354f05366cb..cb376cbaeb2 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -364,7 +364,6 @@ enum PendingInboundConnectionError { TransportErrorMultiaddrNotSupported, TransportErrorOther, Aborted, - Io, ConnectionLimit, } @@ -386,7 +385,6 @@ impl From<&libp2p_swarm::PendingInboundConnectionError> for PendingInboundConnec libp2p_swarm::PendingInboundConnectionError::Aborted => { PendingInboundConnectionError::Aborted } - libp2p_swarm::PendingInboundConnectionError::IO(_) => PendingInboundConnectionError::Io, } } } diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 0d2a38d65f6..143f68f2f4e 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -23,6 +23,10 @@ If you have previously set `connection_event_buffer_size` you should re-evaluate what a good size for a _per connection_ buffer is. See [PR 3188]. +- Remove `PendingConnectionError:::IO` variant. + This was never constructed. + See [PR XXXX]. + [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 @@ -31,6 +35,7 @@ [PR 3272]: https://github.com/libp2p/rust-libp2p/pull/3272 [PR 3327]: https://github.com/libp2p/rust-libp2p/pull/3327 [PR 3188]: https://github.com/libp2p/rust-libp2p/pull/3188 +[PR XXXX]: https://github.com/libp2p/rust-libp2p/pull/XXXX # 0.41.1 diff --git a/swarm/src/connection/error.rs b/swarm/src/connection/error.rs index 9226035968c..7b9217ad352 100644 --- a/swarm/src/connection/error.rs +++ b/swarm/src/connection/error.rs @@ -101,10 +101,6 @@ pub enum PendingConnectionError { obtained: PeerId, endpoint: ConnectedPoint, }, - - /// An I/O error occurred on the connection. - // TODO: Eventually this should also be a custom error? - IO(io::Error), } impl PendingConnectionError { @@ -118,7 +114,6 @@ impl PendingConnectionError { PendingConnectionError::WrongPeerId { obtained, endpoint } => { PendingConnectionError::WrongPeerId { obtained, endpoint } } - PendingConnectionError::IO(e) => PendingConnectionError::IO(e), } } } @@ -129,7 +124,6 @@ where { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - PendingConnectionError::IO(err) => write!(f, "Pending connection: I/O error: {err}"), PendingConnectionError::Aborted => write!(f, "Pending connection: Aborted."), PendingConnectionError::Transport(err) => { write!( @@ -156,7 +150,6 @@ where { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { - PendingConnectionError::IO(err) => Some(err), PendingConnectionError::Transport(_) => None, PendingConnectionError::WrongPeerId { .. } => None, PendingConnectionError::Aborted => None, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ee8a28081ab..6026d8d3eb3 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1611,7 +1611,6 @@ impl From for DialError { PendingConnectionError::WrongPeerId { obtained, endpoint } => { DialError::WrongPeerId { obtained, endpoint } } - PendingConnectionError::IO(e) => DialError::ConnectionIo(e), PendingConnectionError::Transport(e) => DialError::Transport(e), } } From 49d2326f11633e55ce89ef4a267703b6f748742a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 13:35:38 +1100 Subject: [PATCH 088/177] Apply suggestions from code review --- swarm/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 143f68f2f4e..b05af853d39 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -25,7 +25,7 @@ - Remove `PendingConnectionError:::IO` variant. This was never constructed. - See [PR XXXX]. + See [PR 3373]. [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 @@ -35,7 +35,7 @@ [PR 3272]: https://github.com/libp2p/rust-libp2p/pull/3272 [PR 3327]: https://github.com/libp2p/rust-libp2p/pull/3327 [PR 3188]: https://github.com/libp2p/rust-libp2p/pull/3188 -[PR XXXX]: https://github.com/libp2p/rust-libp2p/pull/XXXX +[PR 3373]: https://github.com/libp2p/rust-libp2p/pull/3373 # 0.41.1 From 439628fd3a9ed962ca78056757de495a69de20ce Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 13:52:46 +1100 Subject: [PATCH 089/177] WIP --- misc/metrics/src/swarm.rs | 62 ++++++++++++++++++--------------------- swarm-derive/src/lib.rs | 4 ++- swarm/src/behaviour.rs | 3 +- swarm/src/lib.rs | 47 ++++++++++++++++++++++++++--- 4 files changed, 77 insertions(+), 39 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index cb376cbaeb2..63438be0f50 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -214,40 +214,38 @@ impl super::Recorder record( - OutgoingConnectionErrorError::TransportMultiaddrNotSupported, - ), + ) => { + record(OutgoingConnectionError::TransportMultiaddrNotSupported) + } libp2p_core::transport::TransportError::Other(_) => { - record(OutgoingConnectionErrorError::TransportOther) + record(OutgoingConnectionError::TransportOther) } }; } } - libp2p_swarm::DialError::Banned => record(OutgoingConnectionErrorError::Banned), + libp2p_swarm::DialError::Banned => record(OutgoingConnectionError::Banned), libp2p_swarm::DialError::ConnectionLimit(_) => { - record(OutgoingConnectionErrorError::ConnectionLimit) + record(OutgoingConnectionError::ConnectionLimit) } libp2p_swarm::DialError::LocalPeerId => { - record(OutgoingConnectionErrorError::LocalPeerId) + record(OutgoingConnectionError::LocalPeerId) } libp2p_swarm::DialError::NoAddresses => { - record(OutgoingConnectionErrorError::NoAddresses) + record(OutgoingConnectionError::NoAddresses) } libp2p_swarm::DialError::DialPeerConditionFalse(_) => { - record(OutgoingConnectionErrorError::DialPeerConditionFalse) - } - libp2p_swarm::DialError::Aborted => { - record(OutgoingConnectionErrorError::Aborted) + record(OutgoingConnectionError::DialPeerConditionFalse) } + libp2p_swarm::DialError::Aborted => record(OutgoingConnectionError::Aborted), libp2p_swarm::DialError::InvalidPeerId { .. } => { - record(OutgoingConnectionErrorError::InvalidPeerId) + record(OutgoingConnectionError::InvalidPeerId) } libp2p_swarm::DialError::WrongPeerId { .. } => { - record(OutgoingConnectionErrorError::WrongPeerId) + record(OutgoingConnectionError::WrongPeerId) } libp2p_swarm::DialError::ConnectionIo(_) => { - record(OutgoingConnectionErrorError::ConnectionIo) + record(OutgoingConnectionError::ConnectionIo) } }; } @@ -328,7 +326,7 @@ impl From<&libp2p_core::ConnectedPoint> for Role { #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] struct OutgoingConnectionErrorLabels { peer: PeerStatus, - error: OutgoingConnectionErrorError, + error: OutgoingConnectionError, } #[derive(EncodeLabelValue, Hash, Clone, Eq, PartialEq, Copy, Debug)] @@ -338,7 +336,7 @@ enum PeerStatus { } #[derive(EncodeLabelValue, Hash, Clone, Eq, PartialEq, Debug)] -enum OutgoingConnectionErrorError { +enum OutgoingConnectionError { Banned, ConnectionLimit, LocalPeerId, @@ -354,37 +352,35 @@ enum OutgoingConnectionErrorError { #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] struct IncomingConnectionErrorLabels { - error: PendingInboundConnectionError, + error: IncomingConnectionError, protocols: String, } #[derive(EncodeLabelValue, Hash, Clone, Eq, PartialEq, Debug)] -enum PendingInboundConnectionError { +enum IncomingConnectionError { WrongPeerId, TransportErrorMultiaddrNotSupported, TransportErrorOther, Aborted, ConnectionLimit, + ConnectionIo, } -impl From<&libp2p_swarm::PendingInboundConnectionError> for PendingInboundConnectionError { - fn from(error: &libp2p_swarm::PendingInboundConnectionError) -> Self { +impl From<&libp2p_swarm::ListenError> for IncomingConnectionError { + fn from(error: &libp2p_swarm::ListenError) -> Self { match error { - libp2p_swarm::PendingInboundConnectionError::WrongPeerId { .. } => { - PendingInboundConnectionError::WrongPeerId + libp2p_swarm::ListenError::WrongPeerId { .. } => IncomingConnectionError::WrongPeerId, + libp2p_swarm::ListenError::ConnectionLimit(_) => { + IncomingConnectionError::ConnectionLimit } - libp2p_swarm::PendingInboundConnectionError::ConnectionLimit(_) => { - PendingInboundConnectionError::ConnectionLimit - } - libp2p_swarm::PendingInboundConnectionError::Transport( + libp2p_swarm::ListenError::Transport( libp2p_core::transport::TransportError::MultiaddrNotSupported(_), - ) => PendingInboundConnectionError::TransportErrorMultiaddrNotSupported, - libp2p_swarm::PendingInboundConnectionError::Transport( + ) => IncomingConnectionError::TransportErrorMultiaddrNotSupported, + libp2p_swarm::ListenError::Transport( libp2p_core::transport::TransportError::Other(_), - ) => PendingInboundConnectionError::TransportErrorOther, - libp2p_swarm::PendingInboundConnectionError::Aborted => { - PendingInboundConnectionError::Aborted - } + ) => IncomingConnectionError::TransportErrorOther, + libp2p_swarm::ListenError::Aborted => IncomingConnectionError::Aborted, + libp2p_swarm::ListenError::ConnectionIo(_) => IncomingConnectionError::ConnectionIo, } } } diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index a95d99a37cb..aa2a141c764 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -344,6 +344,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { self.#i.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { local_addr, send_back_addr, + error, handler, })); }, @@ -351,6 +352,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { self.#enum_n.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { local_addr, send_back_addr, + error, handler, })); }, @@ -747,7 +749,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #dial_failure { peer_id, handler: handlers, error }) => { #(#on_dial_failure_stmts)* } #from_swarm::ListenFailure( - #listen_failure { local_addr, send_back_addr, handler: handlers }) + #listen_failure { local_addr, send_back_addr, handler: handlers, error }) => { #(#on_listen_failure_stmts)* } #from_swarm::NewListener( #new_listener { listener_id }) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 059687e40eb..b696efa8986 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -875,7 +875,8 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, - error, handler, + error, + handler, }) => Some(FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index b4c0011e8fa..589a467a9af 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1692,8 +1692,6 @@ impl error::Error for DialError { #[derive(Debug)] pub enum ListenError { - /// The peer is currently banned. - Banned, /// The configured limit for simultaneous outgoing connections /// has been reached. ConnectionLimit(ConnectionLimit), @@ -1707,13 +1705,54 @@ pub enum ListenError { /// An I/O error occurred on the connection. ConnectionIo(io::Error), /// An error occurred while negotiating the transport protocol(s) on a connection. - Transport(Vec<(Multiaddr, TransportError)>), + Transport(TransportError), } impl From for ListenError { fn from(error: PendingInboundConnectionError) -> Self { match error { + PendingInboundConnectionError::Transport(inner) => ListenError::Transport(inner), + PendingInboundConnectionError::ConnectionLimit(inner) => { + ListenError::ConnectionLimit(inner) + } + PendingInboundConnectionError::Aborted => ListenError::Aborted, + PendingInboundConnectionError::WrongPeerId { obtained, endpoint } => { + ListenError::WrongPeerId { obtained, endpoint } + } + } + } +} + +impl fmt::Display for ListenError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ListenError::ConnectionLimit(_) => write!(f, "Listen error"), + ListenError::Aborted => write!( + f, + "Listen error: Pending connection attempt has been aborted." + ), + ListenError::WrongPeerId { obtained, endpoint } => write!( + f, + "Listen error: Unexpected peer ID {obtained} at {endpoint:?}." + ), + ListenError::ConnectionIo(_) => { + write!(f, "Listen error: An I/O error occurred on the connection") + } + ListenError::Transport(_) => { + write!(f, "Listen error: Failed to negotiate transport protocol(s)") + } + } + } +} +impl error::Error for ListenError { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self { + ListenError::ConnectionLimit(err) => Some(err), + ListenError::WrongPeerId { .. } => None, + ListenError::ConnectionIo(err) => Some(err), + ListenError::Transport(err) => Some(err), + ListenError::Aborted => None, } } } @@ -2364,7 +2403,7 @@ mod tests { network_1_established = true; } Poll::Ready(Some(SwarmEvent::IncomingConnectionError { - error: PendingConnectionError::ConnectionLimit(err), + error: ListenError::ConnectionLimit(err), .. })) => { assert_eq!(err.limit, limit); From 494d1314d65a282e2b8db71c73cd8b16ab66c5dd Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 13:55:03 +1100 Subject: [PATCH 090/177] Remove unused `DialError::ConnectionIo` variant --- misc/metrics/src/swarm.rs | 4 ---- protocols/kad/src/behaviour.rs | 1 - swarm/src/lib.rs | 7 ------- 3 files changed, 12 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index cb376cbaeb2..09950bc7956 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -246,9 +246,6 @@ impl super::Recorder { record(OutgoingConnectionErrorError::WrongPeerId) } - libp2p_swarm::DialError::ConnectionIo(_) => { - record(OutgoingConnectionErrorError::ConnectionIo) - } }; } libp2p_swarm::SwarmEvent::BannedPeer { endpoint, .. } => { @@ -347,7 +344,6 @@ enum OutgoingConnectionErrorError { Aborted, InvalidPeerId, WrongPeerId, - ConnectionIo, TransportMultiaddrNotSupported, TransportOther, } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 66e1b426ad7..7f4c147aebe 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1936,7 +1936,6 @@ where | DialError::InvalidPeerId { .. } | DialError::WrongPeerId { .. } | DialError::Aborted - | DialError::ConnectionIo(_) | DialError::Transport(_) | DialError::NoAddresses => { if let DialError::Transport(addresses) = error { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 6026d8d3eb3..6e478d9dca5 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1597,8 +1597,6 @@ pub enum DialError { obtained: PeerId, endpoint: ConnectedPoint, }, - /// An I/O error occurred on the connection. - ConnectionIo(io::Error), /// An error occurred while negotiating the transport protocol(s) on a connection. Transport(Vec<(Multiaddr, TransportError)>), } @@ -1637,10 +1635,6 @@ impl fmt::Display for DialError { f, "Dial error: Unexpected peer ID {obtained} at {endpoint:?}." ), - DialError::ConnectionIo(e) => write!( - f, - "Dial error: An I/O error occurred on the connection: {e:?}." - ), DialError::Transport(errors) => { write!(f, "Failed to negotiate transport protocol(s): [")?; @@ -1678,7 +1672,6 @@ impl error::Error for DialError { DialError::Aborted => None, DialError::InvalidPeerId { .. } => None, DialError::WrongPeerId { .. } => None, - DialError::ConnectionIo(_) => None, DialError::Transport(_) => None, } } From e389876bb0dcfd503bdceca31b35af7352ed9f80 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 13:56:55 +1100 Subject: [PATCH 091/177] add changelog entry --- swarm/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index b05af853d39..281f2b77da2 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -27,6 +27,10 @@ This was never constructed. See [PR 3373]. +- Remove `DialError:ConnectionIo` variant. + This was never constructed. + See [PR 3374]. + [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 @@ -36,6 +40,7 @@ [PR 3327]: https://github.com/libp2p/rust-libp2p/pull/3327 [PR 3188]: https://github.com/libp2p/rust-libp2p/pull/3188 [PR 3373]: https://github.com/libp2p/rust-libp2p/pull/3373 +[PR 3374]: https://github.com/libp2p/rust-libp2p/pull/3374 # 0.41.1 From f5c2a0e39d744951b4e648d7009a33447601aaf6 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 13:57:10 +1100 Subject: [PATCH 092/177] Fix missing colon --- swarm/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 281f2b77da2..1378832e7af 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -27,7 +27,7 @@ This was never constructed. See [PR 3373]. -- Remove `DialError:ConnectionIo` variant. +- Remove `DialError::ConnectionIo` variant. This was never constructed. See [PR 3374]. From a553ab7ca3f4dbbc934bd3d20dfd873352de210e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 15:06:56 +1100 Subject: [PATCH 093/177] Remove unused `ConnectionIo` variant from `ListenError` --- misc/metrics/src/swarm.rs | 2 -- swarm/src/lib.rs | 6 ------ 2 files changed, 8 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index 38e33ddebbb..97241f67447 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -359,7 +359,6 @@ enum IncomingConnectionError { TransportErrorOther, Aborted, ConnectionLimit, - ConnectionIo, } impl From<&libp2p_swarm::ListenError> for IncomingConnectionError { @@ -376,7 +375,6 @@ impl From<&libp2p_swarm::ListenError> for IncomingConnectionError { libp2p_core::transport::TransportError::Other(_), ) => IncomingConnectionError::TransportErrorOther, libp2p_swarm::ListenError::Aborted => IncomingConnectionError::Aborted, - libp2p_swarm::ListenError::ConnectionIo(_) => IncomingConnectionError::ConnectionIo, } } } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index c3dc4fe76d7..65e9ab18fa6 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1695,8 +1695,6 @@ pub enum ListenError { obtained: PeerId, endpoint: ConnectedPoint, }, - /// An I/O error occurred on the connection. - ConnectionIo(io::Error), /// An error occurred while negotiating the transport protocol(s) on a connection. Transport(TransportError), } @@ -1728,9 +1726,6 @@ impl fmt::Display for ListenError { f, "Listen error: Unexpected peer ID {obtained} at {endpoint:?}." ), - ListenError::ConnectionIo(_) => { - write!(f, "Listen error: An I/O error occurred on the connection") - } ListenError::Transport(_) => { write!(f, "Listen error: Failed to negotiate transport protocol(s)") } @@ -1743,7 +1738,6 @@ impl error::Error for ListenError { match self { ListenError::ConnectionLimit(err) => Some(err), ListenError::WrongPeerId { .. } => None, - ListenError::ConnectionIo(err) => Some(err), ListenError::Transport(err) => Some(err), ListenError::Aborted => None, } From 717e2d76a4b7bd5eacba4dfd9061566c746ea97d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 15:13:16 +1100 Subject: [PATCH 094/177] Update docs --- swarm/src/lib.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 65e9ab18fa6..ce77853d6fa 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -221,7 +221,7 @@ pub enum SwarmEvent { /// Address used to send back data to the remote. send_back_addr: Multiaddr, }, - /// An error happened on a connection during its initial handshake. + /// An error happened on an inbound connection during its initial handshake. /// /// This can include, for example, an error during the handshake of the encryption layer, or /// the connection unexpectedly closed. @@ -235,7 +235,7 @@ pub enum SwarmEvent { /// The error that happened. error: ListenError, }, - /// Outgoing connection attempt failed. + /// An error happened on an outbound connection. OutgoingConnectionError { /// If known, [`PeerId`] of the peer we tried to reach. peer_id: Option, @@ -1578,7 +1578,7 @@ where } } -/// The possible failures of dialing. +/// Possible errors when trying to establish or upgrade an outbound connection. #[derive(Debug)] pub enum DialError { /// The peer is currently banned. @@ -1683,6 +1683,7 @@ impl error::Error for DialError { } } +/// Possible errors when upgrading an inbound connection. #[derive(Debug)] pub enum ListenError { /// The configured limit for simultaneous outgoing connections From be9bb13d6472ecb5a4bf96d6d3692fdadd8cf96f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 15:18:24 +1100 Subject: [PATCH 095/177] Add changelog entry --- swarm/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 1378832e7af..90670f0348a 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -31,6 +31,9 @@ This was never constructed. See [PR 3374]. +- Introduce `ListenError` and use it within `SwarmEvent::IncomingConnectionError`. + See [PR XXXX]. + [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 @@ -41,6 +44,7 @@ [PR 3188]: https://github.com/libp2p/rust-libp2p/pull/3188 [PR 3373]: https://github.com/libp2p/rust-libp2p/pull/3373 [PR 3374]: https://github.com/libp2p/rust-libp2p/pull/3374 +[PR XXXX]: https://github.com/libp2p/rust-libp2p/pull/XXXX # 0.41.1 From e2476a322914e5dc43201e7c86ca57d229b38ddf Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 24 Jan 2023 15:19:22 +1100 Subject: [PATCH 096/177] Update changelog --- swarm/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 90670f0348a..59fb0fbed1d 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -32,7 +32,7 @@ See [PR 3374]. - Introduce `ListenError` and use it within `SwarmEvent::IncomingConnectionError`. - See [PR XXXX]. + See [PR 3375]. [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 @@ -44,7 +44,7 @@ [PR 3188]: https://github.com/libp2p/rust-libp2p/pull/3188 [PR 3373]: https://github.com/libp2p/rust-libp2p/pull/3373 [PR 3374]: https://github.com/libp2p/rust-libp2p/pull/3374 -[PR XXXX]: https://github.com/libp2p/rust-libp2p/pull/XXXX +[PR 3375]: https://github.com/libp2p/rust-libp2p/pull/3375 # 0.41.1 From 130ef666dc5ed01d78e390785af3960a1437f05b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 10:11:05 +1100 Subject: [PATCH 097/177] Report cause of denied connection --- misc/metrics/src/swarm.rs | 2 ++ swarm/src/lib.rs | 42 ++++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index e77276e0edd..e865caee942 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -362,6 +362,7 @@ enum IncomingConnectionError { TransportErrorOther, Aborted, ConnectionLimit, + Denied, } impl From<&libp2p_swarm::ListenError> for IncomingConnectionError { @@ -378,6 +379,7 @@ impl From<&libp2p_swarm::ListenError> for IncomingConnectionError { libp2p_core::transport::TransportError::Other(_), ) => IncomingConnectionError::TransportErrorOther, libp2p_swarm::ListenError::Aborted => IncomingConnectionError::Aborted, + libp2p_swarm::ListenError::Denied { .. } => IncomingConnectionError::Denied, } } } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index b9e4c6478f2..7d913edc372 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -879,7 +879,7 @@ where }); } PoolEvent::PendingInboundConnectionError { - id, + id: _, send_back_addr, local_addr, error, @@ -971,13 +971,19 @@ where local_addr, send_back_addr, } => { + let listen_error = ListenError::Denied { cause }; + self.behaviour + .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { + local_addr: &local_addr, + send_back_addr: &send_back_addr, + error: &listen_error, + })); + return Some(SwarmEvent::IncomingConnectionError { send_back_addr, local_addr, - error: todo!( - "Got a 'pending' error here but we have an established connection ..." - ), - }) + error: listen_error, + }); } }, PoolEvent::ConnectionEvent { peer_id, id, event } => { @@ -1031,10 +1037,21 @@ where &send_back_addr, ) { Ok(()) => {} - Err(error) => { - // TODO: self.behaviour.on_swarm_event(FromSwarm::ListenFailure()) + Err(cause) => { + let listen_error = ListenError::Denied { cause }; + + self.behaviour + .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { + local_addr: &local_addr, + send_back_addr: &send_back_addr, + error: &listen_error, + })); - return Some(todo!("Report connection error event, these are currently modeled in a weird way where we split them by incoming/outgoing on the `SwarmEvent` level but everywhere else by established/pending")); + return Some(SwarmEvent::IncomingConnectionError { + local_addr, + send_back_addr, + error: listen_error, + }); } } @@ -1753,7 +1770,7 @@ impl fmt::Display for DialError { Ok(()) } DialError::Denied { .. } => { - write!(f, "Dial was denied") + write!(f, "Outbound connection was denied") } } } @@ -1799,6 +1816,9 @@ pub enum ListenError { obtained: PeerId, endpoint: ConnectedPoint, }, + Denied { + cause: Box, + }, /// An error occurred while negotiating the transport protocol(s) on a connection. Transport(TransportError), } @@ -1833,6 +1853,9 @@ impl fmt::Display for ListenError { ListenError::Transport(_) => { write!(f, "Listen error: Failed to negotiate transport protocol(s)") } + ListenError::Denied { .. } => { + write!(f, "Inbound connection was denied") + } } } } @@ -1844,6 +1867,7 @@ impl error::Error for ListenError { ListenError::WrongPeerId { .. } => None, ListenError::Transport(err) => Some(err), ListenError::Aborted => None, + ListenError::Denied { cause } => Some(cause.as_ref()), } } } From dbebfd0b5a45f3882f5e792d85be4be74ebe100d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 10:22:48 +1100 Subject: [PATCH 098/177] Introduce dedicated error type --- protocols/autonat/src/behaviour.rs | 13 +++++---- protocols/dcutr/src/behaviour_impl.rs | 6 ++--- protocols/floodsub/src/layer.rs | 8 +++--- protocols/gossipsub/src/behaviour.rs | 8 +++--- protocols/identify/src/behaviour.rs | 11 ++++---- protocols/kad/src/behaviour.rs | 11 ++++---- protocols/mdns/src/behaviour.rs | 11 ++++---- protocols/ping/src/lib.rs | 9 +++---- protocols/relay/src/behaviour.rs | 11 ++++---- protocols/relay/src/priv_client.rs | 10 +++---- protocols/rendezvous/src/client.rs | 12 ++++----- protocols/rendezvous/src/server.rs | 8 +++--- protocols/request-response/src/lib.rs | 10 +++---- swarm-derive/src/lib.rs | 9 ++++--- swarm/src/behaviour.rs | 12 ++++----- swarm/src/behaviour/either.rs | 11 ++++---- swarm/src/behaviour/toggle.rs | 13 +++++---- swarm/src/connection/pool.rs | 7 +++-- swarm/src/dummy.rs | 9 +++---- swarm/src/keep_alive.rs | 7 +++-- swarm/src/lib.rs | 39 ++++++++++++++++++++++----- 21 files changed, 125 insertions(+), 110 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 2f01a8eb19e..65a3d0391bc 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -37,10 +37,9 @@ use libp2p_swarm::{ AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, FromSwarm, }, - ConnectionId, ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, - PollParameters, THandler, THandlerInEvent, THandlerOutEvent, + ConnectionDenied, ConnectionId, ExternalAddresses, ListenAddresses, NetworkBehaviour, + NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; -use std::error::Error; use std::{ collections::{HashMap, VecDeque}, iter, @@ -491,7 +490,7 @@ impl NetworkBehaviour for Behaviour { connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result<(), Box> { + ) -> Result<(), ConnectionDenied> { self.inner .handle_pending_inbound_connection(connection_id, local_addr, remote_addr) } @@ -502,7 +501,7 @@ impl NetworkBehaviour for Behaviour { connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { self.inner.handle_established_inbound_connection( peer, connection_id, @@ -517,7 +516,7 @@ impl NetworkBehaviour for Behaviour { addresses: &[Multiaddr], effective_role: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { self.inner.handle_pending_outbound_connection( maybe_peer, addresses, @@ -532,7 +531,7 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, role_override: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { self.inner .handle_established_outbound_connection(peer, addr, role_override, connection_id) } diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 58a54006b63..6443f07f51e 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -27,7 +27,7 @@ use libp2p_core::multiaddr::Protocol; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::dial_opts::{self, DialOpts}; -use libp2p_swarm::{dummy, ConnectionId, THandler, THandlerOutEvent}; +use libp2p_swarm::{dummy, ConnectionDenied, ConnectionId, THandler, THandlerOutEvent}; use libp2p_swarm::{ ConnectionHandlerUpgrErr, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, @@ -244,7 +244,7 @@ impl NetworkBehaviour for Behaviour { connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. match self @@ -282,7 +282,7 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, role_override: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. match self diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 4e0e3ea182f..697549fad3b 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -29,8 +29,8 @@ use fnv::FnvHashSet; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::{ - dial_opts::DialOpts, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - OneShotHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, + dial_opts::DialOpts, ConnectionDenied, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, + NotifyHandler, OneShotHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use log::warn; use smallvec::SmallVec; @@ -340,7 +340,7 @@ impl NetworkBehaviour for Floodsub { _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(Default::default()) } @@ -350,7 +350,7 @@ impl NetworkBehaviour for Floodsub { _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(Default::default()) } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 4448b520652..886fb14ba94 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -42,8 +42,8 @@ use libp2p_core::{ use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, FromSwarm}, dial_opts::DialOpts, - ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandler, THandlerInEvent, THandlerOutEvent, + ConnectionDenied, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use wasm_timer::Instant; @@ -3300,7 +3300,7 @@ where _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), @@ -3321,7 +3321,7 @@ where _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let protocol_config = ProtocolConfig::new( self.config.protocol_id().clone(), self.config.custom_id_version().clone(), diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index f6ecd0ab7fc..450ee154e6f 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -23,13 +23,12 @@ use crate::protocol::{Info, Protocol, UpgradeError}; use libp2p_core::{multiaddr, ConnectedPoint, Endpoint, Multiaddr, PeerId, PublicKey}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}; use libp2p_swarm::{ - dial_opts::DialOpts, AddressScore, ConnectionHandlerUpgrErr, DialError, ExternalAddresses, - ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandlerInEvent, + dial_opts::DialOpts, AddressScore, ConnectionDenied, ConnectionHandlerUpgrErr, DialError, + ExternalAddresses, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, + PollParameters, THandlerInEvent, }; use libp2p_swarm::{ConnectionId, THandler, THandlerOutEvent}; use lru::LruCache; -use std::error::Error; use std::num::NonZeroUsize; use std::{ collections::{HashMap, HashSet, VecDeque}, @@ -424,7 +423,7 @@ impl NetworkBehaviour for Behaviour { _: ConnectionId, _: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(Handler::new( self.config.initial_delay, self.config.interval, @@ -442,7 +441,7 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(Handler::new( self.config.initial_delay, self.config.interval, diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index db5a1e72ef1..9ec8d2a1119 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -45,14 +45,13 @@ use libp2p_swarm::behaviour::{ }; use libp2p_swarm::{ dial_opts::{self, DialOpts}, - ConnectionId, DialError, ExternalAddresses, ListenAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, THandlerInEvent, - THandlerOutEvent, + ConnectionDenied, ConnectionId, DialError, ExternalAddresses, ListenAddresses, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, + THandlerInEvent, THandlerOutEvent, }; use log::{debug, info, warn}; use smallvec::SmallVec; use std::collections::{BTreeMap, HashSet, VecDeque}; -use std::error::Error; use std::fmt; use std::num::NonZeroUsize; use std::task::{Context, Poll}; @@ -1990,7 +1989,7 @@ where _: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(KademliaHandler::new( KademliaHandlerConfig { protocol_config: self.protocol_config.clone(), @@ -2011,7 +2010,7 @@ where addr: &Multiaddr, role_override: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(KademliaHandler::new( KademliaHandlerConfig { protocol_config: self.protocol_config.clone(), diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index da3c508a7a3..0328e84dd11 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -30,12 +30,11 @@ use if_watch::IfEvent; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - dummy, ConnectionId, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandler, THandlerOutEvent, + dummy, ConnectionDenied, ConnectionId, ListenAddresses, NetworkBehaviour, + NetworkBehaviourAction, PollParameters, THandler, THandlerOutEvent, }; use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; -use std::error::Error; use std::{cmp, fmt, io, net::IpAddr, pin::Pin, task::Context, task::Poll, time::Instant}; use void::Void; @@ -182,7 +181,7 @@ where _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(dummy::ConnectionHandler) } @@ -192,7 +191,7 @@ where _addresses: &[Multiaddr], _effective_role: Endpoint, _connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let peer_id = match maybe_peer { None => return Ok(vec![]), Some(peer) => peer, @@ -212,7 +211,7 @@ where _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(dummy::ConnectionHandler) } diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index b2824e4233c..705f4059d5d 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -49,10 +49,9 @@ use handler::Handler; pub use handler::{Config, Failure, Success}; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::{ - behaviour::FromSwarm, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandler, THandlerInEvent, THandlerOutEvent, + behaviour::FromSwarm, ConnectionDenied, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; -use std::error::Error; use std::{ collections::VecDeque, task::{Context, Poll}, @@ -127,7 +126,7 @@ impl NetworkBehaviour for Behaviour { _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> std::result::Result, Box> { + ) -> std::result::Result, ConnectionDenied> { Ok(Handler::new(self.config.clone())) } @@ -137,7 +136,7 @@ impl NetworkBehaviour for Behaviour { _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> std::result::Result, Box> { + ) -> std::result::Result, ConnectionDenied> { Ok(Handler::new(self.config.clone())) } diff --git a/protocols/relay/src/behaviour.rs b/protocols/relay/src/behaviour.rs index b6d4316ef10..82b44903583 100644 --- a/protocols/relay/src/behaviour.rs +++ b/protocols/relay/src/behaviour.rs @@ -32,12 +32,11 @@ use libp2p_core::multiaddr::Protocol; use libp2p_core::{ConnectedPoint, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ - dummy, ConnectionHandlerUpgrErr, ConnectionId, ExternalAddresses, NetworkBehaviour, - NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, THandlerInEvent, - THandlerOutEvent, + dummy, ConnectionDenied, ConnectionHandlerUpgrErr, ConnectionId, ExternalAddresses, + NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, + THandlerInEvent, THandlerOutEvent, }; use std::collections::{hash_map, HashMap, HashSet, VecDeque}; -use std::error::Error; use std::num::NonZeroU32; use std::ops::Add; use std::task::{Context, Poll}; @@ -262,7 +261,7 @@ impl NetworkBehaviour for Behaviour { _connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. if is_relayed { @@ -289,7 +288,7 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, role_override: Endpoint, _connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. if is_relayed { diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 0b106717b46..bdc4061c462 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -38,9 +38,9 @@ use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ - dummy, ConnectionHandler, ConnectionHandlerUpgrErr, ConnectionId, NegotiatedSubstream, - NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, - THandlerInEvent, THandlerOutEvent, + dummy, ConnectionDenied, ConnectionHandler, ConnectionHandlerUpgrErr, ConnectionId, + NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, + THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{hash_map, HashMap, VecDeque}; use std::io::{Error, ErrorKind, IoSlice}; @@ -168,7 +168,7 @@ impl NetworkBehaviour for Behaviour { connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. if is_relayed { @@ -190,7 +190,7 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, _role_override: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. if is_relayed { diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 23e0e75695a..3b9dd16bea1 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -33,11 +33,11 @@ use libp2p_core::identity::Keypair; use libp2p_core::{Endpoint, Multiaddr, PeerId, PeerRecord}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ - CloseConnection, ConnectionId, ExternalAddresses, NetworkBehaviour, NetworkBehaviourAction, - NotifyHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, + CloseConnection, ConnectionDenied, ConnectionId, ExternalAddresses, NetworkBehaviour, + NetworkBehaviourAction, NotifyHandler, PollParameters, THandler, THandlerInEvent, + THandlerOutEvent, }; use std::collections::{HashMap, VecDeque}; -use std::error::Error; use std::iter::FromIterator; use std::task::{Context, Poll}; use void::Void; @@ -175,7 +175,7 @@ impl NetworkBehaviour for Behaviour { _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(SubstreamConnectionHandler::new_outbound_only( Duration::from_secs(30), )) @@ -187,7 +187,7 @@ impl NetworkBehaviour for Behaviour { _addresses: &[Multiaddr], _effective_role: Endpoint, _connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let peer = match maybe_peer { None => return Ok(vec![]), Some(peer) => peer, @@ -210,7 +210,7 @@ impl NetworkBehaviour for Behaviour { _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(SubstreamConnectionHandler::new_outbound_only( Duration::from_secs(30), )) diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 0d3ebad4110..c43bd66bbec 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -30,8 +30,8 @@ use futures::{FutureExt, StreamExt}; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::FromSwarm; use libp2p_swarm::{ - CloseConnection, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, - PollParameters, THandler, THandlerInEvent, THandlerOutEvent, + CloseConnection, ConnectionDenied, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, + NotifyHandler, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use std::collections::{HashMap, HashSet, VecDeque}; use std::iter::FromIterator; @@ -117,7 +117,7 @@ impl NetworkBehaviour for Behaviour { _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(SubstreamConnectionHandler::new_inbound_only( Duration::from_secs(30), )) @@ -129,7 +129,7 @@ impl NetworkBehaviour for Behaviour { _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(SubstreamConnectionHandler::new_inbound_only( Duration::from_secs(30), )) diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 6a96cf2ce5d..281f28848ba 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -74,8 +74,8 @@ use libp2p_core::{ConnectedPoint, Endpoint, Multiaddr, PeerId}; use libp2p_swarm::{ behaviour::{AddressChange, ConnectionClosed, ConnectionEstablished, DialFailure, FromSwarm}, dial_opts::DialOpts, - ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, - THandler, THandlerInEvent, THandlerOutEvent, + ConnectionDenied, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::{ @@ -732,7 +732,7 @@ where _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(Handler::new( self.inbound_protocols.clone(), self.codec.clone(), @@ -748,7 +748,7 @@ where _addresses: &[Multiaddr], _effective_role: Endpoint, _connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let peer = match maybe_peer { None => return Ok(vec![]), Some(peer) => peer, @@ -771,7 +771,7 @@ where _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(Handler::new( self.inbound_protocols.clone(), self.codec.clone(), diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 3355895db58..1f422245d43 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -77,6 +77,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let t_handler_in_event = quote! { #prelude_path::THandlerInEvent }; let t_handler_out_event = quote! { #prelude_path::THandlerOutEvent }; let endpoint = quote! { #prelude_path::Endpoint }; + let connection_denied = quote! { #prelude_path::ConnectionDenied }; // Build the generics. let impl_generics = { @@ -712,7 +713,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { connection_id: #connection_id, local_addr: &#multiaddr, remote_addr: &#multiaddr, - ) -> Result<(), Box> { + ) -> Result<(), #connection_denied> { #(#handle_pending_inbound_connection_stmts)* Ok(()) @@ -725,7 +726,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { connection_id: #connection_id, local_addr: &#multiaddr, remote_addr: &#multiaddr, - ) -> Result<#t_handler, Box> { + ) -> Result<#t_handler, #connection_denied> { Ok(#handle_established_inbound_connection) } @@ -736,7 +737,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { addresses: &[#multiaddr], effective_role: #endpoint, connection_id: #connection_id, - ) -> Result<::std::vec::Vec<#multiaddr>, Box> { + ) -> Result<::std::vec::Vec<#multiaddr>, #connection_denied> { #handle_pending_outbound_connection } @@ -747,7 +748,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { addr: &#multiaddr, role_override: #endpoint, connection_id: #connection_id, - ) -> Result<#t_handler, Box> { + ) -> Result<#t_handler, #connection_denied> { Ok(#handle_established_outbound_connection) } diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 11b79896dd7..aaa38f76065 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -31,8 +31,8 @@ use crate::dial_opts::DialOpts; #[allow(deprecated)] use crate::handler::IntoConnectionHandler; use crate::{ - AddressRecord, AddressScore, DialError, ListenError, THandler, THandlerInEvent, - THandlerOutEvent, + AddressRecord, AddressScore, ConnectionDenied, DialError, ListenError, THandler, + THandlerInEvent, THandlerOutEvent, }; use libp2p_core::{transport::ListenerId, ConnectedPoint, Endpoint, Multiaddr, PeerId}; use std::{task::Context, task::Poll}; @@ -162,7 +162,7 @@ pub trait NetworkBehaviour: 'static { _connection_id: ConnectionId, _local_addr: &Multiaddr, _remote_addr: &Multiaddr, - ) -> Result<(), Box> { + ) -> Result<(), ConnectionDenied> { Ok(()) } @@ -179,7 +179,7 @@ pub trait NetworkBehaviour: 'static { _connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { #[allow(deprecated)] Ok(self.new_handler().into_handler( &peer, @@ -206,7 +206,7 @@ pub trait NetworkBehaviour: 'static { _addresses: &[Multiaddr], _effective_role: Endpoint, _connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { #[allow(deprecated)] if let Some(peer_id) = maybe_peer { Ok(self.addresses_of_peer(&peer_id)) @@ -227,7 +227,7 @@ pub trait NetworkBehaviour: 'static { addr: &Multiaddr, role_override: Endpoint, _connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { #[allow(deprecated)] Ok(self.new_handler().into_handler( &peer, diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 3e0cf984c59..5032b14f044 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -20,10 +20,9 @@ use crate::behaviour::{self, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use crate::connection::ConnectionId; -use crate::{THandler, THandlerInEvent, THandlerOutEvent}; +use crate::{ConnectionDenied, THandler, THandlerInEvent, THandlerOutEvent}; use either::Either; use libp2p_core::{Endpoint, Multiaddr, PeerId}; -use std::error::Error; use std::{task::Context, task::Poll}; /// Implementation of [`NetworkBehaviour`] that can be either of two implementations. @@ -40,7 +39,7 @@ where connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result<(), Box> { + ) -> Result<(), ConnectionDenied> { match self { Either::Left(inner) => { inner.handle_pending_inbound_connection(connection_id, local_addr, remote_addr)? @@ -59,7 +58,7 @@ where connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { match self { Either::Left(inner) => Ok(Either::Left(inner.handle_established_inbound_connection( peer, @@ -84,7 +83,7 @@ where addresses: &[Multiaddr], effective_role: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let addresses = match self { Either::Left(inner) => inner.handle_pending_outbound_connection( maybe_peer, @@ -109,7 +108,7 @@ where addr: &Multiaddr, role_override: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { match self { Either::Left(inner) => Ok(Either::Left(inner.handle_established_outbound_connection( peer, diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 8050b8f43c0..d79c45066fe 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -27,13 +27,12 @@ use crate::handler::{ }; use crate::upgrade::SendWrapper; use crate::{ - NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, - THandlerOutEvent, + ConnectionDenied, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, + THandlerInEvent, THandlerOutEvent, }; use either::Either; use futures::future; use libp2p_core::{upgrade::DeniedUpgrade, Endpoint, Multiaddr, PeerId}; -use std::error::Error; use std::{task::Context, task::Poll}; /// Implementation of `NetworkBehaviour` that can be either in the disabled or enabled state. @@ -78,7 +77,7 @@ where connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result<(), Box> { + ) -> Result<(), ConnectionDenied> { let inner = match self.inner.as_mut() { None => return Ok(()), Some(inner) => inner, @@ -95,7 +94,7 @@ where connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let inner = match self.inner.as_mut() { None => return Ok(ToggleConnectionHandler { inner: None }), Some(inner) => inner, @@ -119,7 +118,7 @@ where addresses: &[Multiaddr], effective_role: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let inner = match self.inner.as_mut() { None => return Ok(vec![]), Some(inner) => inner, @@ -141,7 +140,7 @@ where addr: &Multiaddr, role_override: Endpoint, connection_id: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { let inner = match self.inner.as_mut() { None => return Ok(ToggleConnectionHandler { inner: None }), Some(inner) => inner, diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index a291ae2e648..d34737c9917 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -26,7 +26,7 @@ use crate::{ PendingInboundConnectionError, PendingOutboundConnectionError, }, transport::TransportError, - ConnectedPoint, ConnectionHandler, Executor, Multiaddr, PeerId, + ConnectedPoint, ConnectionDenied, ConnectionHandler, Executor, Multiaddr, PeerId, }; use concurrent_dial::ConcurrentDial; use fnv::FnvHashMap; @@ -43,7 +43,6 @@ use libp2p_core::connection::Endpoint; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerExt}; use libp2p_core::ProtocolName; use smallvec::SmallVec; -use std::error::Error; use std::task::Waker; use std::{ collections::{hash_map, HashMap}, @@ -269,7 +268,7 @@ pub enum PoolEvent { id: ConnectionId, peer_id: PeerId, endpoint: ConnectedPoint, - cause: Box, + cause: ConnectionDenied, }, /// An outbound connection attempt failed. @@ -531,7 +530,7 @@ where PeerId, &ConnectedPoint, ConnectionId, - ) -> Result>, + ) -> Result, cx: &mut Context<'_>, ) -> Poll> where diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 0112cb650d7..07af0668bef 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -5,13 +5,12 @@ use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; use crate::{ - ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, SubstreamProtocol, THandler, - THandlerInEvent, THandlerOutEvent, + ConnectionDenied, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, + SubstreamProtocol, THandler, THandlerInEvent, THandlerOutEvent, }; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::UpgradeError; use libp2p_core::{Endpoint, PeerId}; -use std::error::Error; use std::task::{Context, Poll}; use void::Void; @@ -28,7 +27,7 @@ impl NetworkBehaviour for Behaviour { _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(ConnectionHandler) } @@ -38,7 +37,7 @@ impl NetworkBehaviour for Behaviour { _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(ConnectionHandler) } diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index 688964620a0..b5546cfa68d 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -4,10 +4,9 @@ use crate::handler::{ ConnectionEvent, ConnectionHandlerEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, SubstreamProtocol, }; -use crate::{THandler, THandlerInEvent, THandlerOutEvent}; +use crate::{ConnectionDenied, THandler, THandlerInEvent, THandlerOutEvent}; use libp2p_core::upgrade::DeniedUpgrade; use libp2p_core::{Endpoint, Multiaddr, PeerId}; -use std::error::Error; use std::task::{Context, Poll}; use void::Void; @@ -30,7 +29,7 @@ impl NetworkBehaviour for Behaviour { _: ConnectionId, _: &Multiaddr, _: &Multiaddr, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(ConnectionHandler) } @@ -40,7 +39,7 @@ impl NetworkBehaviour for Behaviour { _: &Multiaddr, _: Endpoint, _: ConnectionId, - ) -> Result, Box> { + ) -> Result, ConnectionDenied> { Ok(ConnectionHandler) } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 7d913edc372..52f8cf5ee3e 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -85,6 +85,7 @@ pub mod derive_prelude { pub use crate::behaviour::NewListenAddr; pub use crate::behaviour::NewListener; pub use crate::connection::ConnectionId; + pub use crate::ConnectionDenied; pub use crate::ConnectionHandler; pub use crate::ConnectionHandlerSelect; pub use crate::DialError; @@ -1710,9 +1711,8 @@ pub enum DialError { obtained: PeerId, endpoint: ConnectedPoint, }, - // TODO: Should this include the role_override? Denied { - cause: Box, + cause: ConnectionDenied, }, /// An error occurred while negotiating the transport protocol(s) on a connection. Transport(Vec<(Multiaddr, TransportError)>), @@ -1770,7 +1770,7 @@ impl fmt::Display for DialError { Ok(()) } DialError::Denied { .. } => { - write!(f, "Outbound connection was denied") + write!(f, "Dial error") } } } @@ -1798,7 +1798,7 @@ impl error::Error for DialError { DialError::InvalidPeerId { .. } => None, DialError::WrongPeerId { .. } => None, DialError::Transport(_) => None, - DialError::Denied { cause } => Some(cause.as_ref()), + DialError::Denied { cause } => Some(cause), } } } @@ -1817,7 +1817,7 @@ pub enum ListenError { endpoint: ConnectedPoint, }, Denied { - cause: Box, + cause: ConnectionDenied, }, /// An error occurred while negotiating the transport protocol(s) on a connection. Transport(TransportError), @@ -1854,7 +1854,7 @@ impl fmt::Display for ListenError { write!(f, "Listen error: Failed to negotiate transport protocol(s)") } ListenError::Denied { .. } => { - write!(f, "Inbound connection was denied") + write!(f, "Listen error") } } } @@ -1867,11 +1867,36 @@ impl error::Error for ListenError { ListenError::WrongPeerId { .. } => None, ListenError::Transport(err) => Some(err), ListenError::Aborted => None, - ListenError::Denied { cause } => Some(cause.as_ref()), + ListenError::Denied { cause } => Some(cause), } } } +#[derive(Debug)] +pub struct ConnectionDenied { + inner: Box, +} + +impl ConnectionDenied { + pub fn new(cause: impl error::Error + Send + Sync + 'static) -> Self { + Self { + inner: Box::new(cause), + } + } +} + +impl fmt::Display for ConnectionDenied { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "connection denied") + } +} + +impl error::Error for ConnectionDenied { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + Some(self.inner.as_ref()) + } +} + /// Information about the connections obtained by [`Swarm::network_info()`]. #[derive(Clone, Debug)] pub struct NetworkInfo { From f54559411d9967476662839aad30a195a1be9309 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 10:29:03 +1100 Subject: [PATCH 099/177] Don't comment docs --- swarm/src/behaviour.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index aaa38f76065..dc8552c4780 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -127,22 +127,22 @@ pub trait NetworkBehaviour: 'static { /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; - // /// Creates a new [`ConnectionHandler`] for a connection with a peer. - // /// - // /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] - // /// emitted a dial request, this method is called. - // /// - // /// The returned object is a handler for that specific connection, and will be moved to a - // /// background task dedicated to that connection. - // /// - // /// The network behaviour (ie. the implementation of this trait) and the handlers it has spawned - // /// (ie. the objects returned by `new_handler`) can communicate by passing messages. Messages - // /// sent from the handler to the behaviour are injected with [`NetworkBehaviour::inject_event`], - // /// and the behaviour can send a message to the handler by making [`NetworkBehaviour::poll`] - // /// return [`NetworkBehaviourAction::NotifyHandler`]. - // /// - // /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and - // /// connection closing. + /// Creates a new [`ConnectionHandler`] for a connection with a peer. + /// + /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] + /// emitted a dial request, this method is called. + /// + /// The returned object is a handler for that specific connection, and will be moved to a + /// background task dedicated to that connection. + /// + /// The network behaviour (ie. the implementation of this trait) and the handlers it has spawned + /// (ie. the objects returned by `new_handler`) can communicate by passing messages. Messages + /// sent from the handler to the behaviour are injected with [`NetworkBehaviour::inject_event`], + /// and the behaviour can send a message to the handler by making [`NetworkBehaviour::poll`] + /// return [`NetworkBehaviourAction::NotifyHandler`]. + /// + /// Note that the handler is returned to the [`NetworkBehaviour`] on connection failure and + /// connection closing. #[deprecated( since = "0.42.0", note = "Use one or more of `NetworkBehaviour::{handle_pending_inbound_connection,handle_established_inbound_connection,handle_pending_outbound_connection,handle_established_outbound_connection}` instead." From 1c99ff1450598edc1a67cca03232cf54e62e4fc5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 10:31:17 +1100 Subject: [PATCH 100/177] Fix docs --- swarm/src/behaviour.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index dc8552c4780..91e27186ed5 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -195,10 +195,12 @@ pub trait NetworkBehaviour: 'static { /// We have access to: /// /// - The [`PeerId`], if known. Remember that we can dial without a [`PeerId`]. - /// - All addresses passes to [`DialOpts`] are passed in here too. + /// - All addresses passed to [`DialOpts`] are passed in here too. /// - The effective [`Role`](Endpoint) of this peer in the dial attempt. Typically, this is set to [`Endpoint::Dialer`] except if we are attempting a hole-punch. /// - The [`ConnectionId`] identifying the future connection resulting from this dial, if successful. /// + /// Note that the addresses returned from this function are only used for dialing if [`DialOpts::extend_addresses_through_behaviour`] is set. + /// /// Any error returned from this function will immediately abort the dial attempt. fn handle_pending_outbound_connection( &mut self, From d9f85678f694ff2728debe43f6afe11ca0e915c0 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 10:40:23 +1100 Subject: [PATCH 101/177] Migrate `CallTraceBehaviour` --- swarm/src/test.rs | 97 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/swarm/src/test.rs b/swarm/src/test.rs index c665c2cf62e..ffb0f09d9b4 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -23,10 +23,10 @@ use crate::behaviour::{ FromSwarm, ListenerClosed, ListenerError, NewExternalAddr, NewListenAddr, NewListener, }; use crate::{ - ConnectionHandler, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerInEvent, THandlerOutEvent, + ConnectionDenied, ConnectionHandler, ConnectionId, NetworkBehaviour, NetworkBehaviourAction, + PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; -use libp2p_core::{multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, PeerId}; +use libp2p_core::{multiaddr::Multiaddr, transport::ListenerId, ConnectedPoint, Endpoint, PeerId}; use std::collections::HashMap; use std::task::{Context, Poll}; @@ -125,7 +125,11 @@ where { inner: TInner, - pub addresses_of_peer: Vec, + pub handle_pending_inbound_connection: Vec<(ConnectionId, Multiaddr, Multiaddr)>, + pub handle_pending_outbound_connection: + Vec<(Option, Vec, Endpoint, ConnectionId)>, + pub handle_established_inbound_connection: Vec<(PeerId, ConnectionId, Multiaddr, Multiaddr)>, + pub handle_established_outbound_connection: Vec<(PeerId, Multiaddr, Endpoint, ConnectionId)>, pub on_connection_established: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>, pub on_connection_closed: Vec<(PeerId, ConnectionId, ConnectedPoint, usize)>, pub on_connection_handler_event: Vec<(PeerId, ConnectionId, THandlerOutEvent)>, @@ -148,7 +152,10 @@ where pub fn new(inner: TInner) -> Self { Self { inner, - addresses_of_peer: Vec::new(), + handle_pending_inbound_connection: Vec::new(), + handle_pending_outbound_connection: Vec::new(), + handle_established_inbound_connection: Vec::new(), + handle_established_outbound_connection: Vec::new(), on_connection_established: Vec::new(), on_connection_closed: Vec::new(), on_connection_handler_event: Vec::new(), @@ -166,7 +173,10 @@ where #[allow(dead_code)] pub fn reset(&mut self) { - self.addresses_of_peer = Vec::new(); + self.handle_pending_inbound_connection = Vec::new(); + self.handle_pending_outbound_connection = Vec::new(); + self.handle_established_inbound_connection = Vec::new(); + self.handle_established_outbound_connection = Vec::new(); self.on_connection_established = Vec::new(); self.on_connection_closed = Vec::new(); self.on_connection_handler_event = Vec::new(); @@ -366,13 +376,78 @@ where type ConnectionHandler = TInner::ConnectionHandler; type OutEvent = TInner::OutEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { - self.inner.new_handler() + fn handle_pending_inbound_connection( + &mut self, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result<(), ConnectionDenied> { + self.handle_pending_inbound_connection.push(( + connection_id, + local_addr.clone(), + remote_addr.clone(), + )); + self.inner + .handle_pending_inbound_connection(connection_id, local_addr, remote_addr) } - fn addresses_of_peer(&mut self, p: &PeerId) -> Vec { - self.addresses_of_peer.push(*p); - self.inner.addresses_of_peer(p) + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + connection_id: ConnectionId, + local_addr: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, ConnectionDenied> { + self.handle_established_inbound_connection.push(( + peer, + connection_id, + local_addr.clone(), + remote_addr.clone(), + )); + self.inner.handle_established_inbound_connection( + peer, + connection_id, + local_addr, + remote_addr, + ) + } + + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + addresses: &[Multiaddr], + effective_role: Endpoint, + connection_id: ConnectionId, + ) -> Result, ConnectionDenied> { + self.handle_pending_outbound_connection.push(( + maybe_peer, + addresses.to_vec(), + effective_role, + connection_id, + )); + self.inner.handle_pending_outbound_connection( + maybe_peer, + addresses, + effective_role, + connection_id, + ) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + role_override: Endpoint, + connection_id: ConnectionId, + ) -> Result, ConnectionDenied> { + self.handle_established_outbound_connection.push(( + peer, + addr.clone(), + role_override, + connection_id, + )); + self.inner + .handle_established_outbound_connection(peer, addr, role_override, connection_id) } fn on_swarm_event(&mut self, event: FromSwarm) { From 478854ee14485f0b0bcee54221c4f2eae66bcd1e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 10:43:20 +1100 Subject: [PATCH 102/177] Temporarily allow usage of `new_handler` --- protocols/gossipsub/src/behaviour/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index 948867e0a1a..dc4547f60a9 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -267,6 +267,7 @@ where // peer_connections.connections should never be empty. let mut active_connections = peer_connections.connections.len(); for connection_id in peer_connections.connections.clone() { + #[allow(deprecated)] // To be fixed with https://github.com/libp2p/rust-libp2p/issues/3371. let handler = gs.new_handler(); active_connections = active_connections.checked_sub(1).unwrap(); gs.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { From 5da8dce9f4a21455e349b8b6843ce564a3191861 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 10:49:44 +1100 Subject: [PATCH 103/177] Refactor gossipsub config handler to avoid calls to trait functions --- protocols/gossipsub/src/behaviour.rs | 20 +-------- protocols/gossipsub/src/behaviour/tests.rs | 3 +- protocols/gossipsub/src/config.rs | 15 ++----- protocols/gossipsub/src/protocol.rs | 48 ++++++++++++---------- 4 files changed, 34 insertions(+), 52 deletions(-) diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 886fb14ba94..886205c2f9f 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -3301,16 +3301,8 @@ where _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { - 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(), - ); - Ok(GossipsubHandler::new( - protocol_config, + ProtocolConfig::new(&self.config), self.config.idle_timeout(), )) } @@ -3322,16 +3314,8 @@ where _: Endpoint, _: ConnectionId, ) -> Result, ConnectionDenied> { - 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(), - ); - Ok(GossipsubHandler::new( - protocol_config, + ProtocolConfig::new(&self.config), self.config.idle_timeout(), )) } diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index dc4547f60a9..def0de0825c 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -267,7 +267,8 @@ where // peer_connections.connections should never be empty. let mut active_connections = peer_connections.connections.len(); for connection_id in peer_connections.connections.clone() { - #[allow(deprecated)] // To be fixed with https://github.com/libp2p/rust-libp2p/issues/3371. + #[allow(deprecated)] + // To be fixed with https://github.com/libp2p/rust-libp2p/issues/3371. let handler = gs.new_handler(); active_connections = active_connections.checked_sub(1).unwrap(); gs.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { diff --git a/protocols/gossipsub/src/config.rs b/protocols/gossipsub/src/config.rs index 34956fe614c..0b31dd74724 100644 --- a/protocols/gossipsub/src/config.rs +++ b/protocols/gossipsub/src/config.rs @@ -885,12 +885,11 @@ impl std::fmt::Debug for GossipsubConfig { #[cfg(test)] mod test { use super::*; + use crate::protocol::ProtocolConfig; use crate::topic::IdentityHash; use crate::types::PeerKind; use crate::Topic; - use crate::{Gossipsub, MessageAuthenticity}; use libp2p_core::UpgradeInfo; - use libp2p_swarm::{ConnectionHandler, NetworkBehaviour}; use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; @@ -992,11 +991,7 @@ mod test { assert_eq!(builder.protocol_id(), "purple"); assert_eq!(builder.custom_id_version(), &None); - let mut gossipsub: Gossipsub = - Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - - let handler = gossipsub.new_handler(); - let (protocol_config, _) = handler.listen_protocol().into_upgrade(); + let protocol_config = ProtocolConfig::new(&builder); let protocol_ids = protocol_config.protocol_info(); assert_eq!(protocol_ids.len(), 2); @@ -1020,11 +1015,7 @@ mod test { assert_eq!(builder.protocol_id(), "purple"); assert_eq!(builder.custom_id_version(), &Some(GossipsubVersion::V1_0)); - let mut gossipsub: Gossipsub = - Gossipsub::new(MessageAuthenticity::Anonymous, builder).expect("Correct configuration"); - - let handler = gossipsub.new_handler(); - let (protocol_config, _) = handler.listen_protocol().into_upgrade(); + let protocol_config = ProtocolConfig::new(&builder); let protocol_ids = protocol_config.protocol_info(); assert_eq!(protocol_ids.len(), 1); diff --git a/protocols/gossipsub/src/protocol.rs b/protocols/gossipsub/src/protocol.rs index 07610d9121d..659400ba53c 100644 --- a/protocols/gossipsub/src/protocol.rs +++ b/protocols/gossipsub/src/protocol.rs @@ -21,12 +21,12 @@ use crate::config::{GossipsubVersion, ValidationMode}; use crate::error::{GossipsubHandlerError, ValidationError}; use crate::handler::HandlerEvent; -use crate::rpc_proto; use crate::topic::TopicHash; use crate::types::{ GossipsubControlAction, GossipsubRpc, GossipsubSubscription, GossipsubSubscriptionAction, MessageId, PeerInfo, PeerKind, RawGossipsubMessage, }; +use crate::{rpc_proto, GossipsubConfig}; use asynchronous_codec::{Decoder, Encoder, Framed}; use byteorder::{BigEndian, ByteOrder}; use bytes::BytesMut; @@ -37,7 +37,7 @@ use libp2p_core::{ }; use log::{debug, warn}; use prost::Message as ProtobufMessage; -use std::{borrow::Cow, pin::Pin}; +use std::pin::Pin; use unsigned_varint::codec; pub(crate) const SIGNING_PREFIX: &[u8] = b"libp2p-pubsub:"; @@ -57,27 +57,33 @@ impl ProtocolConfig { /// Builds a new [`ProtocolConfig`]. /// /// Sets the maximum gossip transmission size. - pub fn new( - id: Cow<'static, str>, - custom_id_peer_kind: Option, - max_transmit_size: usize, - validation_mode: ValidationMode, - support_floodsub: bool, - ) -> ProtocolConfig { - let protocol_ids = match custom_id_peer_kind { + pub fn new(gossipsub_config: &GossipsubConfig) -> ProtocolConfig { + let protocol_ids = match gossipsub_config.custom_id_version() { Some(v) => match v { - GossipsubVersion::V1_0 => vec![ProtocolId::new(id, PeerKind::Gossipsub, false)], - GossipsubVersion::V1_1 => vec![ProtocolId::new(id, PeerKind::Gossipsubv1_1, false)], + GossipsubVersion::V1_0 => vec![ProtocolId::new( + gossipsub_config.protocol_id(), + PeerKind::Gossipsub, + false, + )], + GossipsubVersion::V1_1 => vec![ProtocolId::new( + gossipsub_config.protocol_id(), + PeerKind::Gossipsubv1_1, + false, + )], }, None => { let mut protocol_ids = vec![ - ProtocolId::new(id.clone(), PeerKind::Gossipsubv1_1, true), - ProtocolId::new(id, PeerKind::Gossipsub, true), + ProtocolId::new( + gossipsub_config.protocol_id(), + PeerKind::Gossipsubv1_1, + true, + ), + ProtocolId::new(gossipsub_config.protocol_id(), PeerKind::Gossipsub, true), ]; // add floodsub support if enabled. - if support_floodsub { - protocol_ids.push(ProtocolId::new(Cow::from(""), PeerKind::Floodsub, false)); + if gossipsub_config.support_floodsub() { + protocol_ids.push(ProtocolId::new("", PeerKind::Floodsub, false)); } protocol_ids @@ -86,8 +92,8 @@ impl ProtocolConfig { ProtocolConfig { protocol_ids, - max_transmit_size, - validation_mode, + max_transmit_size: gossipsub_config.max_transmit_size(), + validation_mode: gossipsub_config.validation_mode().clone(), } } } @@ -103,15 +109,15 @@ pub struct ProtocolId { /// An RPC protocol ID. impl ProtocolId { - pub fn new(id: Cow<'static, str>, kind: PeerKind, prefix: bool) -> Self { + pub fn new(id: &str, kind: PeerKind, prefix: bool) -> Self { let protocol_id = match kind { PeerKind::Gossipsubv1_1 => match prefix { true => format!("/{}/{}", id, "1.1.0"), - false => format!("{id}"), + false => id.to_string(), }, PeerKind::Gossipsub => match prefix { true => format!("/{}/{}", id, "1.0.0"), - false => format!("{id}"), + false => id.to_string(), }, PeerKind::Floodsub => format!("/{}/{}", "floodsub", "1.0.0"), // NOTE: This is used for informing the behaviour of unsupported peers. We do not From 2a12efe96c9e57278684af12248b6b7b5fdd4b45 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 11:00:16 +1100 Subject: [PATCH 104/177] Undo bad doc comment change --- swarm/src/behaviour.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 91e27186ed5..f50c3c0aa22 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -137,7 +137,8 @@ pub trait NetworkBehaviour: 'static { /// /// The network behaviour (ie. the implementation of this trait) and the handlers it has spawned /// (ie. the objects returned by `new_handler`) can communicate by passing messages. Messages - /// sent from the handler to the behaviour are injected with [`NetworkBehaviour::inject_event`], + /// sent from the handler to the behaviour are invoked with + /// [`NetworkBehaviour::on_connection_handler_event`], /// and the behaviour can send a message to the handler by making [`NetworkBehaviour::poll`] /// return [`NetworkBehaviourAction::NotifyHandler`]. /// From da9c92628bf1751ebeb298fd3b610443d5cfb389 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 13:21:04 +1100 Subject: [PATCH 105/177] Fix rustdocs --- swarm/src/behaviour.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index f50c3c0aa22..53cfb308f1f 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -127,7 +127,7 @@ pub trait NetworkBehaviour: 'static { /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; - /// Creates a new [`ConnectionHandler`] for a connection with a peer. + /// Creates a new [`ConnectionHandler`](crate::ConnectionHandler) for a connection with a peer. /// /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] /// emitted a dial request, this method is called. @@ -172,7 +172,7 @@ pub trait NetworkBehaviour: 'static { /// This is invoked once another peer has successfully dialed us. /// /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial. - /// In order to actually use this connection, this function must return a [`ConnectionHandler`]. + /// In order to actually use this connection, this function must return a [`ConnectionHandler`](crate::ConnectionHandler). /// Returning an error will immediately close the connection. fn handle_established_inbound_connection( &mut self, @@ -200,7 +200,7 @@ pub trait NetworkBehaviour: 'static { /// - The effective [`Role`](Endpoint) of this peer in the dial attempt. Typically, this is set to [`Endpoint::Dialer`] except if we are attempting a hole-punch. /// - The [`ConnectionId`] identifying the future connection resulting from this dial, if successful. /// - /// Note that the addresses returned from this function are only used for dialing if [`DialOpts::extend_addresses_through_behaviour`] is set. + /// Note that the addresses returned from this function are only used for dialing if [`DialOpts::extend_addresses_through_behaviour`](crate::DialOpts::extend_addresses_through_behaviour) is set. /// /// Any error returned from this function will immediately abort the dial attempt. fn handle_pending_outbound_connection( @@ -222,7 +222,7 @@ pub trait NetworkBehaviour: 'static { /// /// This is invoked once we have successfully dialed a peer. /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial. - /// In order to actually use this connection, this function must return a [`ConnectionHandler`]. + /// In order to actually use this connection, this function must return a [`ConnectionHandler`](crate::ConnectionHandler). /// Returning an error will immediately close the connection. fn handle_established_outbound_connection( &mut self, @@ -340,19 +340,19 @@ pub enum NetworkBehaviourAction { /// connection with a peer. /// /// If the `Swarm` is connected to the peer, the message is delivered to the - /// [`ConnectionHandler`] instance identified by the peer ID and connection ID. + /// [`ConnectionHandler`](crate::ConnectionHandler) instance identified by the peer ID and connection ID. /// /// If the specified connection no longer exists, the event is silently dropped. /// /// Typically the connection ID given is the same as the one passed to /// [`NetworkBehaviour::on_connection_handler_event`], i.e. whenever the behaviour wishes to /// respond to a request on the same connection (and possibly the same - /// substream, as per the implementation of [`ConnectionHandler`]). + /// substream, as per the implementation of [`ConnectionHandler`](crate::ConnectionHandler)). /// /// Note that even if the peer is currently connected, connections can get closed /// at any time and thus the event may not reach a handler. NotifyHandler { - /// The peer for whom a [`ConnectionHandler`] should be notified. + /// The peer for whom a [`ConnectionHandler`](crate::ConnectionHandler) should be notified. peer_id: PeerId, /// The options w.r.t. which connection handler to notify of the event. handler: NotifyHandler, @@ -381,10 +381,10 @@ pub enum NetworkBehaviourAction { /// /// Note: Closing a connection via /// [`NetworkBehaviourAction::CloseConnection`] does not inform the - /// corresponding [`ConnectionHandler`]. - /// Closing a connection via a [`ConnectionHandler`] can be done - /// either in a collaborative manner across [`ConnectionHandler`]s - /// with [`ConnectionHandler::connection_keep_alive`] or directly with + /// corresponding [`ConnectionHandler`](crate::ConnectionHandler). + /// Closing a connection via a [`ConnectionHandler`](crate::ConnectionHandler) can be done + /// either in a collaborative manner across [`ConnectionHandler`](crate::ConnectionHandler)s + /// with [`ConnectionHandler::connection_keep_alive`](crate::ConnectionHandler::connection_keep_alive) or directly with /// [`ConnectionHandlerEvent::Close`](crate::ConnectionHandlerEvent::Close). CloseConnection { /// The peer to disconnect. From 7651d4aad30931abd62f52ebae0f3db9c813f325 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 13:24:11 +1100 Subject: [PATCH 106/177] Fix deprecation warnings --- protocols/kad/src/behaviour/test.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index ba65902ee6e..5a1c669cf30 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -1318,7 +1318,15 @@ fn network_behaviour_on_address_change() { // At this point the remote is not yet known to support the // configured protocol name, so the peer is not yet in the // local routing table and hence no addresses are known. - assert!(kademlia.addresses_of_peer(&remote_peer_id).is_empty()); + assert!(kademlia + .handle_pending_outbound_connection( + Some(remote_peer_id), + &[], + Endpoint::Dialer, + connection_id + ) + .unwrap() + .is_empty()); // Mimick the connection handler confirming the protocol for // the test connection, so that the peer is added to the routing table. @@ -1330,7 +1338,14 @@ fn network_behaviour_on_address_change() { assert_eq!( vec![old_address.clone()], - kademlia.addresses_of_peer(&remote_peer_id), + kademlia + .handle_pending_outbound_connection( + Some(remote_peer_id), + &[], + Endpoint::Dialer, + connection_id + ) + .unwrap(), ); kademlia.on_swarm_event(FromSwarm::AddressChange(AddressChange { @@ -1348,7 +1363,14 @@ fn network_behaviour_on_address_change() { assert_eq!( vec![new_address], - kademlia.addresses_of_peer(&remote_peer_id), + kademlia + .handle_pending_outbound_connection( + Some(remote_peer_id), + &[], + Endpoint::Dialer, + connection_id + ) + .unwrap(), ); } From 096a30358b542524e83760e9790763139a364230 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 13:27:37 +1100 Subject: [PATCH 107/177] Fix failing gossipsub test --- protocols/gossipsub/src/behaviour/tests.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/protocols/gossipsub/src/behaviour/tests.rs b/protocols/gossipsub/src/behaviour/tests.rs index def0de0825c..4c4ce218257 100644 --- a/protocols/gossipsub/src/behaviour/tests.rs +++ b/protocols/gossipsub/src/behaviour/tests.rs @@ -265,17 +265,21 @@ where role_override: Endpoint::Dialer, }; // this is not relevant // peer_connections.connections should never be empty. + let mut active_connections = peer_connections.connections.len(); for connection_id in peer_connections.connections.clone() { - #[allow(deprecated)] - // To be fixed with https://github.com/libp2p/rust-libp2p/issues/3371. - let handler = gs.new_handler(); active_connections = active_connections.checked_sub(1).unwrap(); + + let dummy_handler = GossipsubHandler::new( + ProtocolConfig::new(&GossipsubConfig::default()), + Duration::ZERO, + ); + gs.on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { peer_id: *peer_id, connection_id, endpoint: &fake_endpoint, - handler, + handler: dummy_handler, remaining_established: active_connections, })); } From 0dcee3ea4027e31583358ca135d401fd34b403b2 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 13:35:29 +1100 Subject: [PATCH 108/177] Fix more docs --- swarm/src/behaviour.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 53cfb308f1f..8d9ed073dfe 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -200,7 +200,7 @@ pub trait NetworkBehaviour: 'static { /// - The effective [`Role`](Endpoint) of this peer in the dial attempt. Typically, this is set to [`Endpoint::Dialer`] except if we are attempting a hole-punch. /// - The [`ConnectionId`] identifying the future connection resulting from this dial, if successful. /// - /// Note that the addresses returned from this function are only used for dialing if [`DialOpts::extend_addresses_through_behaviour`](crate::DialOpts::extend_addresses_through_behaviour) is set. + /// Note that the addresses returned from this function are only used for dialing if [`WithPeerIdWithAddresses::extend_addresses_through_behaviour`](crate::dial_opts::WithPeerIdWithAddresses::extend_addresses_through_behaviour) is set. /// /// Any error returned from this function will immediately abort the dial attempt. fn handle_pending_outbound_connection( @@ -255,8 +255,8 @@ pub trait NetworkBehaviour: 'static { /// 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. + /// Informs the behaviour about an event generated by the [`ConnectionHandler`](crate::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`]. From 0c706d590f5e6fc871b887dfbb30fd370dfb1f97 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 13:36:38 +1100 Subject: [PATCH 109/177] Fix beta clippy --- swarm/src/lib.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 52f8cf5ee3e..151cbc703cd 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1734,28 +1734,23 @@ impl From for DialError { impl fmt::Display for DialError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - DialError::ConnectionLimit(err) => write!(f, "Dial error: {}", err), + DialError::ConnectionLimit(err) => write!(f, "Dial error: {err}"), DialError::NoAddresses => write!(f, "Dial error: no addresses for peer."), DialError::LocalPeerId => write!(f, "Dial error: tried to dial local peer id."), DialError::Banned => write!(f, "Dial error: peer is banned."), DialError::DialPeerConditionFalse(c) => { - write!( - f, - "Dial error: condition {:?} for dialing peer was false.", - c - ) + write!(f, "Dial error: condition {c:?} for dialing peer was false.",) } DialError::Aborted => write!( f, "Dial error: Pending connection attempt has been aborted." ), DialError::InvalidPeerId(multihash) => { - write!(f, "Dial error: multihash {:?} is not a PeerId", multihash) + write!(f, "Dial error: multihash {multihash:?} is not a PeerId") } DialError::WrongPeerId { obtained, endpoint } => write!( f, - "Dial error: Unexpected peer ID {} at {:?}.", - obtained, endpoint + "Dial error: Unexpected peer ID {obtained} at {endpoint:?}.", ), DialError::Transport(errors) => { write!(f, "Failed to negotiate transport protocol(s): [")?; From c5f3320db0e395ea037c805fc2ae0dd28e7b8edd Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 16:14:25 +1100 Subject: [PATCH 110/177] Actually fix beta clippy --- swarm/src/lib.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 151cbc703cd..efaa89b64d4 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -2425,7 +2425,7 @@ mod tests { panic!("Unexpected transport event.") } future::Either::Right((e, _)) => { - panic!("Expect swarm to not emit any event {:?}", e) + panic!("Expect swarm to not emit any event {e:?}") } } } @@ -2433,7 +2433,7 @@ mod tests { match swarm.next().await.unwrap() { SwarmEvent::OutgoingConnectionError { .. } => {} - e => panic!("Unexpected swarm event {:?}", e), + e => panic!("Unexpected swarm event {e:?}"), } }) } @@ -2473,7 +2473,7 @@ mod tests { assert_eq!(limit.current, outgoing_limit); assert_eq!(limit.limit, outgoing_limit); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } let info = network.network_info(); @@ -2513,7 +2513,7 @@ mod tests { let listen_addr = async_std::task::block_on(poll_fn(|cx| { match ready!(network1.poll_next_unpin(cx)).unwrap() { SwarmEvent::NewListenAddr { address, .. } => Poll::Ready(address), - e => panic!("Unexpected network event: {:?}", e), + e => panic!("Unexpected network event: {e:?}"), } })); @@ -2552,7 +2552,7 @@ mod tests { Poll::Pending => { network_1_pending = true; } - e => panic!("Unexpected network event: {:?}", e), + e => panic!("Unexpected network event: {e:?}"), } match network2.poll_next_unpin(cx) { @@ -2570,7 +2570,7 @@ mod tests { Poll::Pending => { network_2_pending = true; } - e => panic!("Unexpected network event: {:?}", e), + e => panic!("Unexpected network event: {e:?}"), } if network_1_pending && network_2_pending { @@ -2640,7 +2640,7 @@ mod tests { Poll::Ready(Some(SwarmEvent::OutgoingConnectionError { peer_id, error, .. })) => Poll::Ready((peer_id, error)), - Poll::Ready(x) => panic!("unexpected {:?}", x), + Poll::Ready(x) => panic!("unexpected {x:?}"), Poll::Pending => Poll::Pending, } })); @@ -2656,7 +2656,7 @@ mod tests { } ); } - x => panic!("wrong error {:?}", x), + x => panic!("wrong error {x:?}"), } } @@ -2719,7 +2719,7 @@ mod tests { assert_eq!(local_addr, local_address); } Poll::Ready(ev) => { - panic!("Unexpected event: {:?}", ev) + panic!("Unexpected event: {ev:?}") } Poll::Pending => break Poll::Pending, } @@ -2795,7 +2795,7 @@ mod tests { listener.listen_on(multiaddr![Memory(0u64)]).unwrap(); let listener_address = match block_on(listener.next()).unwrap() { SwarmEvent::NewListenAddr { address, .. } => address, - e => panic!("Unexpected network event: {:?}", e), + e => panic!("Unexpected network event: {e:?}"), }; dialer @@ -2815,7 +2815,7 @@ mod tests { error: DialError::Aborted, .. } => {} - e => panic!("Unexpected swarm event {:?}.", e), + e => panic!("Unexpected swarm event {e:?}."), } } From ab35c119c0157ebf39a09cdfaf423b6a43b17d91 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 16:29:44 +1100 Subject: [PATCH 111/177] Resolve remaining todos --- misc/metrics/src/swarm.rs | 3 ++- protocols/kad/src/behaviour.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index e865caee942..ed3a98fa58a 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -245,7 +245,7 @@ impl super::Recorder { - todo!() + record(OutgoingConnectionError::Denied) } }; } @@ -347,6 +347,7 @@ enum OutgoingConnectionError { WrongPeerId, TransportMultiaddrNotSupported, TransportOther, + Denied, } #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 9ec8d2a1119..42d5951b073 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1928,6 +1928,7 @@ where | DialError::InvalidPeerId { .. } | DialError::WrongPeerId { .. } | DialError::Aborted + | DialError::Denied { .. } | DialError::Transport(_) | DialError::NoAddresses => { if let DialError::Transport(addresses) = error { @@ -1949,7 +1950,6 @@ where DialError::DialPeerConditionFalse(dial_opts::PeerCondition::Always) => { unreachable!("DialPeerCondition::Always can not trigger DialPeerConditionFalse."); } - DialError::Denied { .. } => todo!(), } } From 53ff65720f15388e959b9d3771d198c40309edaf Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 17:04:56 +1100 Subject: [PATCH 112/177] Implement connections limits using `NetworkBehaviour` --- swarm/src/connection/pool.rs | 12 +- swarm/src/connection_limits.rs | 193 +++++++++++++++++++++++++++++++++ swarm/src/lib.rs | 2 + 3 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 swarm/src/connection_limits.rs diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index d34737c9917..6dd9d2c0b4e 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -1021,12 +1021,12 @@ fn num_peer_established( /// By default no connection limits apply. #[derive(Debug, Clone, Default)] pub struct ConnectionLimits { - max_pending_incoming: Option, - max_pending_outgoing: Option, - max_established_incoming: Option, - max_established_outgoing: Option, - max_established_per_peer: Option, - max_established_total: Option, + pub(crate) max_pending_incoming: Option, + pub(crate) max_pending_outgoing: Option, + pub(crate) max_established_incoming: Option, + pub(crate) max_established_outgoing: Option, + pub(crate) max_established_per_peer: Option, + pub(crate) max_established_total: Option, } impl ConnectionLimits { diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs new file mode 100644 index 00000000000..d3a45b09c0d --- /dev/null +++ b/swarm/src/connection_limits.rs @@ -0,0 +1,193 @@ +use crate::{ + dummy, ConnectionClosed, ConnectionDenied, ConnectionId, ConnectionLimit, ConnectionLimits, + FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, + THandlerOutEvent, +}; +use libp2p_core::{Endpoint, Multiaddr, PeerId}; +use std::collections::{HashMap, HashSet}; +use std::task::{Context, Poll}; +use void::Void; + +pub struct Behaviour { + limits: ConnectionLimits, + + pending_inbound_connections: HashSet, + pending_outbound_connections: HashSet, + established_inbound_connections: HashSet, + established_outbound_connections: HashSet, + established_per_peer: HashMap>, +} + +impl Behaviour { + pub fn new(limits: ConnectionLimits) -> Self { + Self { + limits, + pending_inbound_connections: Default::default(), + pending_outbound_connections: Default::default(), + established_inbound_connections: Default::default(), + established_outbound_connections: Default::default(), + established_per_peer: Default::default(), + } + } + + fn check_limit(&mut self, limit: Option, current: usize) -> Result<(), ConnectionDenied> { + let limit = limit.unwrap_or(u32::MAX); + let current = current as u32; + + if current > limit { + return Err(ConnectionDenied::new(ConnectionLimit { limit, current })); + } + + Ok(()) + } +} + +impl NetworkBehaviour for Behaviour { + type ConnectionHandler = dummy::ConnectionHandler; + type OutEvent = Void; + + fn handle_pending_inbound_connection( + &mut self, + connection_id: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result<(), ConnectionDenied> { + self.check_limit( + self.limits.max_pending_incoming, + self.pending_inbound_connections.len(), + )?; + + self.pending_inbound_connections.insert(connection_id); + + Ok(()) + } + + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + connection_id: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, ConnectionDenied> { + self.check_limit( + self.limits.max_established_incoming, + self.established_inbound_connections.len(), + )?; + self.check_limit( + self.limits.max_established_per_peer, + self.established_per_peer + .get(&peer) + .map(|connections| connections.len()) + .unwrap_or(0), + )?; + self.check_limit( + self.limits.max_established_total, + self.established_inbound_connections.len() + + self.established_outbound_connections.len(), + )?; + + self.pending_inbound_connections.remove(&connection_id); + self.established_inbound_connections.insert(connection_id); + self.established_per_peer + .entry(peer) + .or_default() + .insert(connection_id); + + Ok(dummy::ConnectionHandler) + } + + fn handle_pending_outbound_connection( + &mut self, + _: Option, + _: &[Multiaddr], + _: Endpoint, + connection_id: ConnectionId, + ) -> Result, ConnectionDenied> { + self.check_limit( + self.limits.max_pending_outgoing, + self.pending_outbound_connections.len(), + )?; + + self.pending_outbound_connections.insert(connection_id); + + Ok(vec![]) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + _: &Multiaddr, + _: Endpoint, + connection_id: ConnectionId, + ) -> Result, ConnectionDenied> { + self.check_limit( + self.limits.max_established_outgoing, + self.established_outbound_connections.len(), + )?; + self.check_limit( + self.limits.max_established_per_peer, + self.established_per_peer + .get(&peer) + .map(|connections| connections.len()) + .unwrap_or(0), + )?; + self.check_limit( + self.limits.max_established_total, + self.established_inbound_connections.len() + + self.established_outbound_connections.len(), + )?; + + self.pending_outbound_connections.remove(&connection_id); + self.established_outbound_connections.insert(connection_id); + self.established_per_peer + .entry(peer) + .or_default() + .insert(connection_id); + + Ok(dummy::ConnectionHandler) + } + + fn on_swarm_event(&mut self, event: FromSwarm) { + match event { + FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + connection_id, + .. + }) => { + self.established_inbound_connections.remove(&connection_id); + self.established_outbound_connections.remove(&connection_id); + self.established_per_peer + .entry(peer_id) + .or_default() + .remove(&connection_id); + } + FromSwarm::ConnectionEstablished(_) => {} + 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: THandlerOutEvent, + ) { + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll>> { + Poll::Pending + } +} diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index efaa89b64d4..5d0e38edf86 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -62,6 +62,7 @@ mod test; mod upgrade; pub mod behaviour; +pub mod connection_limits; pub mod dial_opts; pub mod dummy; mod executor; @@ -1635,6 +1636,7 @@ where } /// Configures the connection limits. + #[deprecated(note = "Use the `connection_limits::Behaviour` instead.")] pub fn connection_limits(mut self, limits: ConnectionLimits) -> Self { self.connection_limits = limits; self From 54591976e0e06b60d88d571336f11cb540b05fdf Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 17:09:16 +1100 Subject: [PATCH 113/177] Always remove connections from pending after successful upgrade --- swarm/src/connection_limits.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index d3a45b09c0d..f3f9ab79bf2 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -69,6 +69,8 @@ impl NetworkBehaviour for Behaviour { _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { + self.pending_inbound_connections.remove(&connection_id); + self.check_limit( self.limits.max_established_incoming, self.established_inbound_connections.len(), @@ -86,7 +88,6 @@ impl NetworkBehaviour for Behaviour { + self.established_outbound_connections.len(), )?; - self.pending_inbound_connections.remove(&connection_id); self.established_inbound_connections.insert(connection_id); self.established_per_peer .entry(peer) @@ -120,6 +121,8 @@ impl NetworkBehaviour for Behaviour { _: Endpoint, connection_id: ConnectionId, ) -> Result, ConnectionDenied> { + self.pending_outbound_connections.remove(&connection_id); + self.check_limit( self.limits.max_established_outgoing, self.established_outbound_connections.len(), @@ -137,7 +140,6 @@ impl NetworkBehaviour for Behaviour { + self.established_outbound_connections.len(), )?; - self.pending_outbound_connections.remove(&connection_id); self.established_outbound_connections.insert(connection_id); self.established_per_peer .entry(peer) From b4dfd38ae87c6b4c020bdff910e1c0bb3cc34062 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Jan 2023 17:10:18 +1100 Subject: [PATCH 114/177] Assert that handler never sends events --- swarm/src/connection_limits.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index f3f9ab79bf2..839867eec38 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -179,10 +179,11 @@ impl NetworkBehaviour for Behaviour { fn on_connection_handler_event( &mut self, - _peer_id: PeerId, - _connection_id: ConnectionId, - _event: THandlerOutEvent, + _id: PeerId, + _: ConnectionId, + event: THandlerOutEvent, ) { + void::unreachable(event) } fn poll( From 9a420e4b94ff50b3ed38a8f7382036f4b712c6f5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 26 Jan 2023 17:04:47 +1100 Subject: [PATCH 115/177] Don't use else block if we return in the previous one --- swarm/src/lib.rs | 74 ++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 6a64b4c10ab..9979f7c569c 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -767,50 +767,50 @@ where self.banned_peer_connections.insert(id); self.pool.disconnect(peer_id); return Some(SwarmEvent::BannedPeer { peer_id, endpoint }); - } else { - let num_established = NonZeroU32::new( - u32::try_from(other_established_connection_ids.len() + 1).unwrap(), - ) - .expect("n + 1 is always non-zero; qed"); - let non_banned_established = other_established_connection_ids - .into_iter() - .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) - .count(); + } - log::debug!( + let num_established = NonZeroU32::new( + u32::try_from(other_established_connection_ids.len() + 1).unwrap(), + ) + .expect("n + 1 is always non-zero; qed"); + let non_banned_established = other_established_connection_ids + .into_iter() + .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) + .count(); + + log::debug!( "Connection established: {:?} {:?}; Total (peer): {}. Total non-banned (peer): {}", peer_id, endpoint, num_established, non_banned_established + 1, ); - let failed_addresses = concurrent_dial_errors - .as_ref() - .map(|es| { - es.iter() - .map(|(a, _)| a) - .cloned() - .collect::>() - }) - .unwrap_or_default(); - self.behaviour - .on_swarm_event(FromSwarm::ConnectionEstablished( - behaviour::ConnectionEstablished { - peer_id, - connection_id: id, - endpoint: &endpoint, - failed_addresses: &failed_addresses, - other_established: non_banned_established, - }, - )); - return Some(SwarmEvent::ConnectionEstablished { - peer_id, - num_established, - endpoint, - concurrent_dial_errors, - established_in, - }); - } + let failed_addresses = concurrent_dial_errors + .as_ref() + .map(|es| { + es.iter() + .map(|(a, _)| a) + .cloned() + .collect::>() + }) + .unwrap_or_default(); + self.behaviour + .on_swarm_event(FromSwarm::ConnectionEstablished( + behaviour::ConnectionEstablished { + peer_id, + connection_id: id, + endpoint: &endpoint, + failed_addresses: &failed_addresses, + other_established: non_banned_established, + }, + )); + return Some(SwarmEvent::ConnectionEstablished { + peer_id, + num_established, + endpoint, + concurrent_dial_errors, + established_in, + }); } PoolEvent::PendingOutboundConnectionError { id: connection_id, From f5f37ab3a2f78a25bf9ecc41cea92d2e41f629bb Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 26 Jan 2023 17:12:38 +1100 Subject: [PATCH 116/177] Remove closure in favor of spawning connection from the outside --- core/src/muxing/boxed.rs | 6 +++ swarm/src/connection/pool.rs | 98 ++++++++++++++++++------------------ swarm/src/lib.rs | 15 +++++- 3 files changed, 68 insertions(+), 51 deletions(-) diff --git a/core/src/muxing/boxed.rs b/core/src/muxing/boxed.rs index 99f7a87c6a5..e909fb9fbf1 100644 --- a/core/src/muxing/boxed.rs +++ b/core/src/muxing/boxed.rs @@ -13,6 +13,12 @@ pub struct StreamMuxerBox { inner: Pin + Send>>, } +impl fmt::Debug for StreamMuxerBox { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("StreamMuxerBox").finish_non_exhaustive() + } +} + /// Abstract type for asynchronous reading and writing. /// /// A [`SubstreamBox`] erases the concrete type it is given and only retains its `AsyncRead` diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index b12a2d3985f..dd8eda322f7 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -225,10 +225,7 @@ pub enum PoolEvent { id: ConnectionId, peer_id: PeerId, endpoint: ConnectedPoint, - /// List of other connections to the same peer. - /// - /// Note: Does not include the connection reported through this event. - other_established_connection_ids: Vec, + connection: StreamMuxerBox, /// [`Some`] when the new connection is an outgoing connection. /// Addresses are dialed in parallel. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. @@ -516,12 +513,53 @@ where Ok(connection_id) } - /// Polls the connection pool for events. - pub fn poll( + pub fn spawn_connection( &mut self, - cx: &mut Context<'_>, - mut new_handler_fn: impl FnMut() -> THandler, - ) -> Poll> + id: ConnectionId, + obtained_peer_id: PeerId, + endpoint: &ConnectedPoint, + muxer: StreamMuxerBox, + handler: ::Handler, + ) { + let conns = self.established.entry(obtained_peer_id).or_default(); + self.counters.inc_established(endpoint); + + let (command_sender, command_receiver) = mpsc::channel(self.task_command_buffer_size); + let (event_sender, event_receiver) = mpsc::channel(self.per_connection_event_buffer_size); + + conns.insert( + id, + EstablishedConnection { + endpoint: endpoint.clone(), + sender: command_sender, + }, + ); + self.established_connection_events.push(event_receiver); + if let Some(waker) = self.no_established_connections_waker.take() { + waker.wake(); + } + + let connection = Connection::new( + muxer, + handler, + self.substream_upgrade_protocol_override, + self.max_negotiating_inbound_streams, + ); + + self.spawn( + task::new_for_established_connection( + id, + obtained_peer_id, + connection, + command_receiver, + event_sender, + ) + .boxed(), + ); + } + + /// Polls the connection pool for events. + pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> where THandler: IntoConnectionHandler + 'static, THandler::Handler: ConnectionHandler + Send, @@ -726,51 +764,13 @@ where }; } - // Add the connection to the pool. - let conns = self.established.entry(obtained_peer_id).or_default(); - let other_established_connection_ids = conns.keys().cloned().collect(); - self.counters.inc_established(&endpoint); - - let (command_sender, command_receiver) = - mpsc::channel(self.task_command_buffer_size); - let (event_sender, event_receiver) = - mpsc::channel(self.per_connection_event_buffer_size); - - conns.insert( - id, - EstablishedConnection { - endpoint: endpoint.clone(), - sender: command_sender, - }, - ); - self.established_connection_events.push(event_receiver); - if let Some(waker) = self.no_established_connections_waker.take() { - waker.wake(); - } - - let connection = Connection::new( - muxer, - new_handler_fn().into_handler(&obtained_peer_id, &endpoint), - self.substream_upgrade_protocol_override, - self.max_negotiating_inbound_streams, - ); - - self.spawn( - task::new_for_established_connection( - id, - obtained_peer_id, - connection, - command_receiver, - event_sender, - ) - .boxed(), - ); let established_in = accepted_at.elapsed(); + return Poll::Ready(PoolEvent::ConnectionEstablished { peer_id: obtained_peer_id, endpoint, id, - other_established_connection_ids, + connection: muxer, concurrent_dial_errors, established_in, }); diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 9979f7c569c..dea4b4e5f36 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -757,7 +757,7 @@ where peer_id, id, endpoint, - other_established_connection_ids, + connection, concurrent_dial_errors, established_in, } => { @@ -769,6 +769,17 @@ where return Some(SwarmEvent::BannedPeer { peer_id, endpoint }); } + let handler = self + .behaviour + .new_handler() + .into_handler(&peer_id, &endpoint); + self.pool + .spawn_connection(id, peer_id, &endpoint, connection, handler); + + let other_established_connection_ids = self + .pool + .iter_established_connections_of_peer(&peer_id) + .collect::>(); let num_established = NonZeroU32::new( u32::try_from(other_established_connection_ids.len() + 1).unwrap(), ) @@ -1200,7 +1211,7 @@ where } // Poll the known peers. - match this.pool.poll(cx, || this.behaviour.new_handler()) { + match this.pool.poll(cx) { Poll::Pending => {} Poll::Ready(pool_event) => { if let Some(swarm_event) = this.handle_pool_event(pool_event) { From dd1eb8c7b0ab08b6bfab6e240c2efb10e49db297 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 26 Jan 2023 17:23:44 +1100 Subject: [PATCH 117/177] Add `ConnectionId` to `ListenFailure` --- swarm-derive/src/lib.rs | 4 +++- swarm/src/behaviour.rs | 3 +++ swarm/src/connection/pool.rs | 7 +++---- swarm/src/lib.rs | 9 +++++++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index f929b771f04..9055546da5f 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -326,12 +326,14 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { self.#i.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { local_addr, send_back_addr, + connection_id })); }, None => quote! { self.#enum_n.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { local_addr, send_back_addr, + connection_id })); }, }; @@ -693,7 +695,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #dial_failure { peer_id, connection_id, error }) => { #(#on_dial_failure_stmts)* } #from_swarm::ListenFailure( - #listen_failure { local_addr, send_back_addr }) + #listen_failure { local_addr, send_back_addr, connection_id }) => { #(#on_listen_failure_stmts)* } #from_swarm::NewListener( #new_listener { listener_id }) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 92cea23f1ee..419eebf463b 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -474,6 +474,7 @@ pub struct DialFailure<'a> { pub struct ListenFailure<'a> { pub local_addr: &'a Multiaddr, pub send_back_addr: &'a Multiaddr, + pub connection_id: ConnectionId, } /// [`FromSwarm`] variant that informs the behaviour that a new listener was created. @@ -599,9 +600,11 @@ impl<'a, Handler: IntoConnectionHandler> FromSwarm<'a, Handler> { FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, + connection_id, }) => Some(FromSwarm::ListenFailure(ListenFailure { local_addr, send_back_addr, + connection_id, })), FromSwarm::NewListener(NewListener { listener_id }) => { Some(FromSwarm::NewListener(NewListener { listener_id })) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index dd8eda322f7..45dfc5dda84 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -478,7 +478,8 @@ where &mut self, future: TFut, info: IncomingInfo<'_>, - ) -> Result + connection_id: ConnectionId, + ) -> Result<(), ConnectionLimit> where TFut: Future> + Send + 'static, { @@ -486,8 +487,6 @@ where self.counters.check_max_pending_incoming()?; - let connection_id = ConnectionId::next(); - let (abort_notifier, abort_receiver) = oneshot::channel(); self.spawn( @@ -510,7 +509,7 @@ where accepted_at: Instant::now(), }, ); - Ok(connection_id) + Ok(()) } pub fn spawn_connection( diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 1be4b1c427f..babb4f3226f 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -849,7 +849,7 @@ where }); } PoolEvent::PendingInboundConnectionError { - id: _, + id, send_back_addr, local_addr, error, @@ -859,6 +859,7 @@ where .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr: &local_addr, send_back_addr: &send_back_addr, + connection_id: id, })); return Some(SwarmEvent::IncomingConnectionError { local_addr, @@ -957,14 +958,17 @@ where local_addr, send_back_addr, } => { + let connection_id = ConnectionId::next(); + match self.pool.add_incoming( upgrade, IncomingInfo { local_addr: &local_addr, send_back_addr: &send_back_addr, }, + connection_id, ) { - Ok(_connection_id) => { + Ok(()) => { return Some(SwarmEvent::IncomingConnection { local_addr, send_back_addr, @@ -975,6 +979,7 @@ where .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { local_addr: &local_addr, send_back_addr: &send_back_addr, + connection_id, })); log::warn!("Incoming connection rejected: {:?}", connection_limit); } From 32a465be2b23bf91a5bfb93c41b2d7e74fc1cdff Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 26 Jan 2023 17:29:22 +1100 Subject: [PATCH 118/177] Clean up pending commands on failure --- protocols/relay/src/priv_client.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 4915efb6f55..c3bc617b202 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -36,7 +36,7 @@ use libp2p_core::PeerId; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ - ConnectionHandlerUpgrErr, ConnectionId, NegotiatedSubstream, NetworkBehaviour, + ConnectionHandlerUpgrErr, ConnectionId, DialFailure, NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, NotifyHandler, PollParameters, THandlerInEvent, }; use std::collections::{hash_map, HashMap, VecDeque}; @@ -190,8 +190,10 @@ impl NetworkBehaviour for Behaviour { FromSwarm::ConnectionClosed(connection_closed) => { self.on_connection_closed(connection_closed) } + FromSwarm::DialFailure(DialFailure { connection_id, .. }) => { + self.pending_handler_commands.remove(&connection_id); + } FromSwarm::AddressChange(_) - | FromSwarm::DialFailure(_) | FromSwarm::ListenFailure(_) | FromSwarm::NewListener(_) | FromSwarm::NewListenAddr(_) From 91f942fb5f54759fc579c571ee6efc6010959673 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 26 Jan 2023 17:32:50 +1100 Subject: [PATCH 119/177] Add docs and fix bug --- protocols/dcutr/src/behaviour_impl.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index c658dd705ae..a8f73f55ebc 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -80,6 +80,8 @@ pub struct Behaviour { direct_to_relayed_connections: HashMap, + /// Indexed by the [`ConnectionId`] of the relayed connection and + /// the [`PeerId`] we are trying to establish a direct connection to. outgoing_direct_connection_attempts: HashMap<(ConnectionId, PeerId), u8>, } @@ -325,7 +327,7 @@ impl NetworkBehaviour for Behaviour { .insert(maybe_direct_connection_id, relayed_connection_id); *self .outgoing_direct_connection_attempts - .entry((maybe_direct_connection_id, event_source)) + .entry((relayed_connection_id, event_source)) .or_default() += 1; self.queued_events .push_back(NetworkBehaviourAction::Dial { opts }); From d704e89162436e402df130fb33c5acb5c973076d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 10:37:52 +1100 Subject: [PATCH 120/177] Consistently use `THandlerInEvent` --- protocols/mdns/src/behaviour.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 629bae53371..7333530bd0f 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -31,12 +31,11 @@ use libp2p_core::{Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, FromSwarm}; use libp2p_swarm::{ dummy, ListenAddresses, NetworkBehaviour, NetworkBehaviourAction, PollParameters, - THandlerOutEvent, + THandlerInEvent, THandlerOutEvent, }; use smallvec::SmallVec; use std::collections::hash_map::{Entry, HashMap}; use std::{cmp, fmt, io, net::IpAddr, pin::Pin, task::Context, task::Poll, time::Instant}; -use void::Void; /// An abstraction to allow for compatibility with various async runtimes. pub trait Provider: 'static { @@ -232,7 +231,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll> { + ) -> Poll>> { // Poll ifwatch. while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) { match event { From 55baab174051abfd69ca41d1793878d41b65a1cb Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 10:42:07 +1100 Subject: [PATCH 121/177] Use type alias --- protocols/rendezvous/src/client.rs | 2 +- protocols/rendezvous/src/server.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index d3fd7546a00..ea722e7a7d7 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -289,7 +289,7 @@ fn handle_outbound_event( peer_id: PeerId, discovered_peers: &mut HashMap<(PeerId, Namespace), Vec>, expiring_registrations: &mut FuturesUnordered>, -) -> Vec>> { +) -> Vec>> { match event { outbound::OutEvent::Registered { namespace, ttl } => { vec![NetworkBehaviourAction::GenerateEvent(Event::Registered { diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 5db364ea93e..c38b8e760f3 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -184,7 +184,7 @@ fn handle_inbound_event( connection: ConnectionId, id: InboundSubstreamId, registrations: &mut Registrations, -) -> Vec>> { +) -> Vec>> { match event { // bad registration inbound::OutEvent::RegistrationRequested(registration) From 2c84f28d75616391b60fe5f0cdcb27a5a782e860 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 10:42:18 +1100 Subject: [PATCH 122/177] Remove unnecessary indentation and "quote"-ing --- swarm-derive/src/lib.rs | 99 +++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 57 deletions(-) diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 5628f157736..4bf1eaa357c 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -285,66 +285,51 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { // 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() - .enumerate() - .map(|(enum_n, field)| { - let inject = match field.ident { - Some(ref i) => quote! { - self.#i.on_swarm_event(#from_swarm::DialFailure(#dial_failure { - peer_id, - connection_id, - error, - })); - }, - None => quote! { - self.#enum_n.on_swarm_event(#from_swarm::DialFailure(#dial_failure { - peer_id, - connection_id, - error, - })); - }, - }; - quote! { - #inject; - } - }) - }; + let on_dial_failure_stmts = data_struct + .fields + .iter() + .enumerate() + .map(|(enum_n, field)| match field.ident { + Some(ref i) => quote! { + self.#i.on_swarm_event(#from_swarm::DialFailure(#dial_failure { + peer_id, + connection_id, + error, + })); + }, + None => quote! { + self.#enum_n.on_swarm_event(#from_swarm::DialFailure(#dial_failure { + peer_id, + connection_id, + error, + })); + }, + }); // 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() - .map(|(enum_n, field)| { - let inject = match field.ident { - Some(ref i) => quote! { - self.#i.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { - local_addr, - send_back_addr, - connection_id, - error - })); - }, - None => quote! { - self.#enum_n.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { - local_addr, - send_back_addr, - connection_id, - error - })); - }, - }; - - quote! { - #inject; - } - }) - }; + let on_listen_failure_stmts = data_struct + .fields + .iter() + .enumerate() + .map(|(enum_n, field)| match field.ident { + Some(ref i) => quote! { + self.#i.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { + local_addr, + send_back_addr, + connection_id, + error + })); + }, + None => quote! { + self.#enum_n.on_swarm_event(#from_swarm::ListenFailure(#listen_failure { + local_addr, + send_back_addr, + connection_id, + error + })); + }, + }); // Build the list of statements to put in the body of `on_swarm_event()` // for the `FromSwarm::NewListener` variant. From cf772461f7385a4f91fad3980a48e4e8d6723e78 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 10:44:32 +1100 Subject: [PATCH 123/177] Fix bad changelog entry --- swarm/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 53ccd7e3b10..2c6f116571e 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -69,9 +69,9 @@ - Introduce `ListenError` and use it within `SwarmEvent::IncomingConnectionError`. See [PR 3375]. -[PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 - Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. +[PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 [PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153 From 55f922d135ad182c4b383502acb3c1023ca2b859 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 11:03:20 +1100 Subject: [PATCH 124/177] Spawn connection at right point in time --- swarm/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index eae10e3c044..9242df692e3 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -877,9 +877,6 @@ where .protocol_info() .map(|p| p.protocol_name().to_owned()) .collect(); - self.pool - .spawn_connection(id, peer_id, &endpoint, connection, handler); - let other_established_connection_ids = self .pool .iter_established_connections_of_peer(&peer_id) @@ -893,6 +890,9 @@ where .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) .count(); + self.pool + .spawn_connection(id, peer_id, &endpoint, connection, handler); + log::debug!( "Connection established: {:?} {:?}; Total (peer): {}. Total non-banned (peer): {}", peer_id, From a2dfc395e2d8bec94ea18f559cd3ca6a26cb895c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 11:22:37 +1100 Subject: [PATCH 125/177] Attempt to reduce diff --- protocols/dcutr/src/behaviour_impl.rs | 33 ++++--- protocols/gossipsub/src/behaviour.rs | 8 +- protocols/mdns/src/behaviour.rs | 18 ++-- protocols/ping/src/lib.rs | 18 ++-- swarm/CHANGELOG.md | 11 --- swarm/src/behaviour/external_addresses.rs | 5 +- swarm/src/behaviour/listen_addresses.rs | 5 +- swarm/src/connection/pool.rs | 4 +- swarm/src/connection/pool/task.rs | 5 +- swarm/src/dummy.rs | 37 ++++---- swarm/src/handler/either.rs | 103 ++++++++++++++++++++- swarm/src/handler/select.rs | 108 +--------------------- swarm/src/lib.rs | 19 +--- 13 files changed, 179 insertions(+), 195 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index a3ee37ea64c..c8e7e625df0 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -164,23 +164,28 @@ impl Behaviour { .. }: DialFailure, ) { - let peer_id = match peer_id { - None => return, - Some(peer_id) => peer_id, - }; - let attempt = match self - .outgoing_direct_connection_attempts - .remove(&(failed_direct_connection, peer_id)) - { - None => return, - Some(attempt) => attempt, + let peer_id = if let Some(peer_id) = peer_id { + peer_id + } else { + return; }; - let relayed_connection_id = match self + + let relayed_connection_id = if let Some(relayed_connection_id) = self .direct_to_relayed_connections .get(&failed_direct_connection) { - None => return, - Some(relayed_connection_id) => *relayed_connection_id, + *relayed_connection_id + } else { + return; + }; + + let attempt = if let Some(attempt) = self + .outgoing_direct_connection_attempts + .get(&(relayed_connection_id, peer_id)) + { + *attempt + } else { + return; }; if attempt < MAX_NUMBER_OF_UPGRADE_ATTEMPTS { @@ -192,7 +197,7 @@ impl Behaviour { attempt: attempt + 1, obs_addrs: self.observed_addreses(), }), - }); + }) } else { self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 886205c2f9f..2b083b83d3b 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -19,7 +19,7 @@ // DEALINGS IN THE SOFTWARE. use std::{ - cmp::max, + cmp::{max, Ordering}, collections::HashSet, collections::VecDeque, collections::{BTreeSet, HashMap}, @@ -2223,7 +2223,7 @@ where let score_p1 = *scores.get(p1).unwrap_or(&0.0); let score_p2 = *scores.get(p2).unwrap_or(&0.0); - score_p1.partial_cmp(&score_p2).unwrap_or(Equal) + score_p1.partial_cmp(&score_p2).unwrap_or(Ordering::Equal) }); // shuffle everything except the last retain_scores many peers (the best ones) shuffled[..peers.len() - self.config.retain_scores()].shuffle(&mut rng); @@ -3657,7 +3657,7 @@ fn validate_config( Ok(()) } -impl Debug for Gossipsub { +impl fmt::Debug for Gossipsub { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Gossipsub") .field("config", &self.config) @@ -3675,7 +3675,7 @@ impl Debug for Gossipsub { } } -impl Debug for PublishConfig { +impl fmt::Debug for PublishConfig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { PublishConfig::Signing { author, .. } => { diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index b14d63790ee..5030ae3a1d7 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -214,6 +214,15 @@ where Ok(dummy::ConnectionHandler) } + fn on_connection_handler_event( + &mut self, + _: PeerId, + _: ConnectionId, + ev: THandlerOutEvent, + ) { + void::unreachable(ev) + } + fn on_swarm_event(&mut self, event: FromSwarm) { self.listen_addresses.on_swarm_event(&event); @@ -246,15 +255,6 @@ where } } - fn on_connection_handler_event( - &mut self, - _: PeerId, - _: ConnectionId, - ev: THandlerOutEvent, - ) { - void::unreachable(ev) - } - fn poll( &mut self, cx: &mut Context<'_>, diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 705f4059d5d..317d13e51a5 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -140,6 +140,15 @@ impl NetworkBehaviour for Behaviour { Ok(Handler::new(self.config.clone())) } + fn on_connection_handler_event( + &mut self, + peer: PeerId, + _: ConnectionId, + result: THandlerOutEvent, + ) { + self.events.push_front(Event { peer, result }) + } + fn on_swarm_event( &mut self, event: libp2p_swarm::behaviour::FromSwarm, @@ -160,15 +169,6 @@ impl NetworkBehaviour for Behaviour { } } - fn on_connection_handler_event( - &mut self, - peer: PeerId, - _: ConnectionId, - result: THandlerOutEvent, - ) { - self.events.push_front(Event { peer, result }) - } - fn poll( &mut self, _: &mut Context<'_>, diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index eb4e40e3e17..411a27e7509 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -71,17 +71,6 @@ - Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. -- Remove `PendingConnectionError:::IO` variant. - This was never constructed. - See [PR 3373]. - -- Remove `DialError::ConnectionIo` variant. - This was never constructed. - See [PR 3374]. - -- Introduce `ListenError` and use it within `SwarmEvent::IncomingConnectionError`. - See [PR 3375]. - [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 diff --git a/swarm/src/behaviour/external_addresses.rs b/swarm/src/behaviour/external_addresses.rs index efba03796e5..27a25c1c7f5 100644 --- a/swarm/src/behaviour/external_addresses.rs +++ b/swarm/src/behaviour/external_addresses.rs @@ -1,4 +1,6 @@ use crate::behaviour::{ExpiredExternalAddr, FromSwarm, NewExternalAddr}; +#[allow(deprecated)] +use crate::IntoConnectionHandler; use libp2p_core::Multiaddr; use std::collections::HashSet; @@ -30,10 +32,9 @@ impl ExternalAddresses { } /// Feed a [`FromSwarm`] event to this struct. - #[allow(deprecated)] pub fn on_swarm_event(&mut self, event: &FromSwarm) where - THandler: crate::IntoConnectionHandler, + THandler: IntoConnectionHandler, { match event { FromSwarm::NewExternalAddr(NewExternalAddr { addr, .. }) => { diff --git a/swarm/src/behaviour/listen_addresses.rs b/swarm/src/behaviour/listen_addresses.rs index 4d6254a72c0..badd5689f9f 100644 --- a/swarm/src/behaviour/listen_addresses.rs +++ b/swarm/src/behaviour/listen_addresses.rs @@ -1,4 +1,6 @@ use crate::behaviour::{ExpiredListenAddr, FromSwarm, NewListenAddr}; +#[allow(deprecated)] +use crate::IntoConnectionHandler; use libp2p_core::Multiaddr; use std::collections::HashSet; @@ -15,10 +17,9 @@ impl ListenAddresses { } /// Feed a [`FromSwarm`] event to this struct. - #[allow(deprecated)] pub fn on_swarm_event(&mut self, event: &FromSwarm) where - THandler: crate::IntoConnectionHandler, + THandler: IntoConnectionHandler, { match event { FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => { diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 64ee160a1d7..4d7e3290416 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -19,6 +19,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. use crate::connection::{Connection, ConnectionId, PendingPoint}; +#[allow(deprecated)] +use crate::IntoConnectionHandler; use crate::{ connection::{ Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError, @@ -511,7 +513,7 @@ where obtained_peer_id: PeerId, endpoint: &ConnectedPoint, muxer: StreamMuxerBox, - handler: ::Handler, + handler: ::Handler, ) { let conns = self.established.entry(obtained_peer_id).or_default(); self.counters.inc_established(endpoint); diff --git a/swarm/src/connection/pool/task.rs b/swarm/src/connection/pool/task.rs index 30a02c9bcc7..27a2a4780a3 100644 --- a/swarm/src/connection/pool/task.rs +++ b/swarm/src/connection/pool/task.rs @@ -66,10 +66,7 @@ pub enum PendingConnectionEvent { } #[derive(Debug)] -pub enum EstablishedConnectionEvent -where - THandler: ConnectionHandler, -{ +pub enum EstablishedConnectionEvent { /// A node we are connected to has changed its address. AddressChange { id: ConnectionId, diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 07af0668bef..c28f7c43778 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -1,6 +1,5 @@ use crate::behaviour::{FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters}; use crate::connection::ConnectionId; -use crate::derive_prelude::Multiaddr; use crate::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; @@ -9,8 +8,8 @@ use crate::{ SubstreamProtocol, THandler, THandlerInEvent, THandlerOutEvent, }; use libp2p_core::upgrade::DeniedUpgrade; -use libp2p_core::UpgradeError; use libp2p_core::{Endpoint, PeerId}; +use libp2p_core::{Multiaddr, UpgradeError}; use std::task::{Context, Poll}; use void::Void; @@ -41,23 +40,6 @@ impl NetworkBehaviour for Behaviour { Ok(ConnectionHandler) } - fn on_swarm_event(&mut self, event: FromSwarm) { - match event { - FromSwarm::ConnectionEstablished(_) - | FromSwarm::ConnectionClosed(_) - | FromSwarm::AddressChange(_) - | FromSwarm::DialFailure(_) - | FromSwarm::ListenFailure(_) - | FromSwarm::NewListener(_) - | FromSwarm::NewListenAddr(_) - | FromSwarm::ExpiredListenAddr(_) - | FromSwarm::ListenerError(_) - | FromSwarm::ListenerClosed(_) - | FromSwarm::NewExternalAddr(_) - | FromSwarm::ExpiredExternalAddr(_) => {} - } - } - fn on_connection_handler_event( &mut self, _: PeerId, @@ -74,6 +56,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 53e940fa814..896a544e2bc 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -19,12 +19,113 @@ // DEALINGS IN THE SOFTWARE. use crate::handler::{ - ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, KeepAlive, SubstreamProtocol, + ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, FullyNegotiatedInbound, + InboundUpgradeSend, KeepAlive, ListenUpgradeError, SubstreamProtocol, }; use crate::upgrade::SendWrapper; +use crate::ConnectionHandlerUpgrErr; use either::Either; +use libp2p_core::UpgradeError; use std::task::{Context, Poll}; +impl + FullyNegotiatedInbound, SendWrapper>, Either> +where + S1OP: InboundUpgradeSend, + S2OP: InboundUpgradeSend, + S1OOI: Send + 'static, + S2OOI: Send + 'static, +{ + pub(crate) fn transpose( + self, + ) -> Either, FullyNegotiatedInbound> { + match self { + FullyNegotiatedInbound { + protocol: future::Either::Left(protocol), + info: Either::Left(info), + } => Either::Left(FullyNegotiatedInbound { protocol, info }), + FullyNegotiatedInbound { + protocol: future::Either::Right(protocol), + info: Either::Right(info), + } => Either::Right(FullyNegotiatedInbound { protocol, info }), + _ => panic!("wrong API usage: the protocol doesn't match the upgrade info"), + } + } +} + +impl + ListenUpgradeError, Either, SendWrapper>> +where + S1OP: InboundUpgradeSend, + S2OP: InboundUpgradeSend, + S1OOI: Send + 'static, + S2OOI: Send + 'static, +{ + pub(crate) fn transpose( + self, + ) -> Either, ListenUpgradeError> { + match self { + ListenUpgradeError { + info: Either::Left(info), + error: ConnectionHandlerUpgrErr::Timer, + } => Either::Left(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Timer, + }), + ListenUpgradeError { + info: Either::Left(info), + error: ConnectionHandlerUpgrErr::Timeout, + } => Either::Left(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Timeout, + }), + ListenUpgradeError { + info: Either::Left(info), + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), + } => Either::Left(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), + }), + ListenUpgradeError { + info: Either::Left(info), + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Left(err))), + } => Either::Left(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)), + }), + ListenUpgradeError { + info: Either::Right(info), + error: ConnectionHandlerUpgrErr::Timer, + } => Either::Right(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Timer, + }), + ListenUpgradeError { + info: Either::Right(info), + error: ConnectionHandlerUpgrErr::Timeout, + } => Either::Right(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Timeout, + }), + ListenUpgradeError { + info: Either::Right(info), + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), + } => Either::Right(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), + }), + ListenUpgradeError { + info: Either::Right(info), + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Right(err))), + } => Either::Right(ListenUpgradeError { + info, + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)), + }), + _ => panic!("Wrong API usage; the upgrade error doesn't match the outbound open info"), + } + } +} + /// Implementation of a [`ConnectionHandler`] that represents either of two [`ConnectionHandler`] /// implementations. impl ConnectionHandler for Either diff --git a/swarm/src/handler/select.rs b/swarm/src/handler/select.rs index 73e5fd535a6..a1dd844c019 100644 --- a/swarm/src/handler/select.rs +++ b/swarm/src/handler/select.rs @@ -18,13 +18,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#[allow(deprecated)] +use crate::handler::IntoConnectionHandler; use crate::handler::{ AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, InboundUpgradeSend, KeepAlive, ListenUpgradeError, OutboundUpgradeSend, SubstreamProtocol, }; use crate::upgrade::SendWrapper; - use either::Either; use futures::future; use libp2p_core::{ @@ -54,11 +55,10 @@ impl IntoConnectionHandlerSelect { } #[allow(deprecated)] -impl crate::handler::IntoConnectionHandler - for IntoConnectionHandlerSelect +impl IntoConnectionHandler for IntoConnectionHandlerSelect where - TProto1: crate::handler::IntoConnectionHandler, - TProto2: crate::handler::IntoConnectionHandler, + TProto1: IntoConnectionHandler, + TProto2: IntoConnectionHandler, { type Handler = ConnectionHandlerSelect; @@ -126,31 +126,6 @@ where } } -impl - FullyNegotiatedInbound, SendWrapper>, Either> -where - S1OP: InboundUpgradeSend, - S2OP: InboundUpgradeSend, - S1OOI: Send + 'static, - S2OOI: Send + 'static, -{ - pub(crate) fn transpose( - self, - ) -> Either, FullyNegotiatedInbound> { - match self { - FullyNegotiatedInbound { - protocol: future::Either::Left(protocol), - info: Either::Left(info), - } => Either::Left(FullyNegotiatedInbound { protocol, info }), - FullyNegotiatedInbound { - protocol: future::Either::Right(protocol), - info: Either::Right(info), - } => Either::Right(FullyNegotiatedInbound { protocol, info }), - _ => panic!("wrong API usage: the protocol doesn't match the upgrade info"), - } - } -} - impl FullyNegotiatedInbound, SendWrapper>, (S1IOI, S2IOI)> where @@ -246,79 +221,6 @@ where } } -impl - ListenUpgradeError, Either, SendWrapper>> -where - S1OP: InboundUpgradeSend, - S2OP: InboundUpgradeSend, - S1OOI: Send + 'static, - S2OOI: Send + 'static, -{ - pub(crate) fn transpose( - self, - ) -> Either, ListenUpgradeError> { - match self { - ListenUpgradeError { - info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Timer, - } => Either::Left(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Timer, - }), - ListenUpgradeError { - info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Timeout, - } => Either::Left(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Timeout, - }), - ListenUpgradeError { - info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), - } => Either::Left(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), - }), - ListenUpgradeError { - info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Left(err))), - } => Either::Left(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)), - }), - ListenUpgradeError { - info: Either::Right(info), - error: ConnectionHandlerUpgrErr::Timer, - } => Either::Right(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Timer, - }), - ListenUpgradeError { - info: Either::Right(info), - error: ConnectionHandlerUpgrErr::Timeout, - } => Either::Right(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Timeout, - }), - ListenUpgradeError { - info: Either::Right(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), - } => Either::Right(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), - }), - ListenUpgradeError { - info: Either::Right(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Right(err))), - } => Either::Right(ListenUpgradeError { - info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)), - }), - _ => panic!("Wrong API usage; the upgrade error doesn't match the outbound open info"), - } - } -} - impl ConnectionHandlerSelect where TProto1: ConnectionHandler, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 9242df692e3..58bb5adab0b 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -348,19 +348,6 @@ impl Swarm where TBehaviour: NetworkBehaviour, { - /// Builds a new `Swarm`. - #[deprecated( - since = "0.41.0", - note = "This constructor is considered ambiguous regarding the executor. Use one of the new, executor-specific constructors or `Swarm::with_threadpool_executor` for the same behaviour." - )] - pub fn new( - transport: transport::Boxed<(PeerId, StreamMuxerBox)>, - behaviour: TBehaviour, - local_peer_id: PeerId, - ) -> Self { - Self::with_threadpool_executor(transport, behaviour, local_peer_id) - } - /// Builds a new `Swarm` with a provided executor. pub fn with_executor( transport: transport::Boxed<(PeerId, StreamMuxerBox)>, @@ -506,7 +493,7 @@ where /// # use libp2p_core::transport::dummy::DummyTransport; /// # use libp2p_swarm::dummy; /// # - /// let mut swarm = Swarm::new( + /// let mut swarm = Swarm::without_executor( /// DummyTransport::new().boxed(), /// dummy::Behaviour, /// PeerId::random(), @@ -1761,7 +1748,7 @@ impl fmt::Display for DialError { ), DialError::Banned => write!(f, "Dial error: peer is banned."), DialError::DialPeerConditionFalse(c) => { - write!(f, "Dial error: condition {c:?} for dialing peer was false.",) + write!(f, "Dial error: condition {c:?} for dialing peer was false.") } DialError::Aborted => write!( f, @@ -1772,7 +1759,7 @@ impl fmt::Display for DialError { } DialError::WrongPeerId { obtained, endpoint } => write!( f, - "Dial error: Unexpected peer ID {obtained} at {endpoint:?}.", + "Dial error: Unexpected peer ID {obtained} at {endpoint:?}." ), DialError::Transport(errors) => { write!(f, "Failed to negotiate transport protocol(s): [")?; From e38002eb097bf0b6db04295b9ede1ad69cd75a8f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 11:30:27 +1100 Subject: [PATCH 126/177] Reduce diff further --- protocols/ping/src/lib.rs | 40 ++++++------ swarm/CHANGELOG.md | 1 - swarm/src/behaviour/external_addresses.rs | 1 + swarm/src/behaviour/listen_addresses.rs | 1 + swarm/src/handler/either.rs | 77 +++++++++++------------ 5 files changed, 58 insertions(+), 62 deletions(-) diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 317d13e51a5..a48c4dadb6e 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -149,26 +149,6 @@ impl NetworkBehaviour for Behaviour { self.events.push_front(Event { peer, result }) } - 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(_) => {} - } - } - fn poll( &mut self, _: &mut Context<'_>, @@ -188,4 +168,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/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 411a27e7509..2c6f116571e 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -71,7 +71,6 @@ - Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. -[PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 diff --git a/swarm/src/behaviour/external_addresses.rs b/swarm/src/behaviour/external_addresses.rs index 27a25c1c7f5..2090d4b3481 100644 --- a/swarm/src/behaviour/external_addresses.rs +++ b/swarm/src/behaviour/external_addresses.rs @@ -32,6 +32,7 @@ impl ExternalAddresses { } /// Feed a [`FromSwarm`] event to this struct. + #[allow(deprecated)] pub fn on_swarm_event(&mut self, event: &FromSwarm) where THandler: IntoConnectionHandler, diff --git a/swarm/src/behaviour/listen_addresses.rs b/swarm/src/behaviour/listen_addresses.rs index badd5689f9f..07bd003bc8d 100644 --- a/swarm/src/behaviour/listen_addresses.rs +++ b/swarm/src/behaviour/listen_addresses.rs @@ -17,6 +17,7 @@ impl ListenAddresses { } /// Feed a [`FromSwarm`] event to this struct. + #[allow(deprecated)] pub fn on_swarm_event(&mut self, event: &FromSwarm) where THandler: IntoConnectionHandler, diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index 896a544e2bc..e66c3549824 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -25,20 +25,19 @@ use crate::handler::{ use crate::upgrade::SendWrapper; use crate::ConnectionHandlerUpgrErr; use either::Either; +use futures::future; use libp2p_core::UpgradeError; use std::task::{Context, Poll}; -impl - FullyNegotiatedInbound, SendWrapper>, Either> +impl + FullyNegotiatedInbound, SendWrapper>, Either> where - S1OP: InboundUpgradeSend, - S2OP: InboundUpgradeSend, - S1OOI: Send + 'static, - S2OOI: Send + 'static, + RIP: InboundUpgradeSend, + LIP: InboundUpgradeSend, { pub(crate) fn transpose( self, - ) -> Either, FullyNegotiatedInbound> { + ) -> Either, FullyNegotiatedInbound> { match self { FullyNegotiatedInbound { protocol: future::Either::Left(protocol), @@ -48,80 +47,76 @@ where protocol: future::Either::Right(protocol), info: Either::Right(info), } => Either::Right(FullyNegotiatedInbound { protocol, info }), - _ => panic!("wrong API usage: the protocol doesn't match the upgrade info"), + _ => unreachable!(), } } } -impl - ListenUpgradeError, Either, SendWrapper>> +impl + ListenUpgradeError, Either, SendWrapper>> where - S1OP: InboundUpgradeSend, - S2OP: InboundUpgradeSend, - S1OOI: Send + 'static, - S2OOI: Send + 'static, + RIP: InboundUpgradeSend, + LIP: InboundUpgradeSend, { - pub(crate) fn transpose( - self, - ) -> Either, ListenUpgradeError> { + fn transpose(self) -> Either, ListenUpgradeError> { match self { ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Left(error))), info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Timer, } => Either::Left(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(error)), info, - error: ConnectionHandlerUpgrErr::Timer, }), ListenUpgradeError { - info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Timeout, - } => Either::Left(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Right(error))), + info: Either::Right(info), + } => Either::Right(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(error)), info, - error: ConnectionHandlerUpgrErr::Timeout, }), ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)), info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), } => Either::Left(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)), info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), }), ListenUpgradeError { - info: Either::Left(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Left(err))), - } => Either::Left(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)), + info: Either::Right(info), + } => Either::Right(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)), info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)), }), ListenUpgradeError { - info: Either::Right(info), error: ConnectionHandlerUpgrErr::Timer, - } => Either::Right(ListenUpgradeError { - info, + info: Either::Left(info), + } => Either::Left(ListenUpgradeError { error: ConnectionHandlerUpgrErr::Timer, + info, }), ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Timer, info: Either::Right(info), - error: ConnectionHandlerUpgrErr::Timeout, } => Either::Right(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Timer, info, - error: ConnectionHandlerUpgrErr::Timeout, }), ListenUpgradeError { - info: Either::Right(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), - } => Either::Right(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Timeout, + info: Either::Left(info), + } => Either::Left(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Timeout, info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(err)), }), ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Timeout, info: Either::Right(info), - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Right(err))), } => Either::Right(ListenUpgradeError { + error: ConnectionHandlerUpgrErr::Timeout, info, - error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)), }), - _ => panic!("Wrong API usage; the upgrade error doesn't match the outbound open info"), + _ => unreachable!(), } } } From 57980817cf881f0e1f216a8b1db4d0779ff1d1c8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 11:38:11 +1100 Subject: [PATCH 127/177] Less diff ... --- swarm/src/behaviour/either.rs | 62 ++++++++++++++++------------------- swarm/src/connection/pool.rs | 1 - 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 5032b14f044..7c706ea3eb0 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -36,20 +36,14 @@ where fn handle_pending_inbound_connection( &mut self, - connection_id: ConnectionId, + id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result<(), ConnectionDenied> { match self { - Either::Left(inner) => { - inner.handle_pending_inbound_connection(connection_id, local_addr, remote_addr)? - } - Either::Right(inner) => { - inner.handle_pending_inbound_connection(connection_id, local_addr, remote_addr)? - } - }; - - Ok(()) + Either::Left(a) => a.handle_pending_inbound_connection(id, local_addr, remote_addr), + Either::Right(b) => b.handle_pending_inbound_connection(id, local_addr, remote_addr), + } } fn handle_established_inbound_connection( @@ -59,22 +53,22 @@ where local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { - match self { - Either::Left(inner) => Ok(Either::Left(inner.handle_established_inbound_connection( + let handler = match self { + Either::Left(inner) => Either::Left(inner.handle_established_inbound_connection( peer, connection_id, local_addr, remote_addr, - )?)), - Either::Right(inner) => { - Ok(Either::Right(inner.handle_established_inbound_connection( - peer, - connection_id, - local_addr, - remote_addr, - )?)) - } - } + )?), + Either::Right(inner) => Either::Right(inner.handle_established_inbound_connection( + peer, + connection_id, + local_addr, + remote_addr, + )?), + }; + + Ok(handler) } fn handle_pending_outbound_connection( @@ -109,22 +103,22 @@ where role_override: Endpoint, connection_id: ConnectionId, ) -> Result, ConnectionDenied> { - match self { - Either::Left(inner) => Ok(Either::Left(inner.handle_established_outbound_connection( + let handler = match self { + Either::Left(inner) => Either::Left(inner.handle_established_outbound_connection( peer, addr, role_override, connection_id, - )?)), - Either::Right(inner) => Ok(Either::Right( - inner.handle_established_outbound_connection( - peer, - addr, - role_override, - connection_id, - )?, - )), - } + )?), + Either::Right(inner) => Either::Right(inner.handle_established_outbound_connection( + peer, + addr, + role_override, + connection_id, + )?), + }; + + Ok(handler) } fn on_swarm_event(&mut self, event: behaviour::FromSwarm) { diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 4d7e3290416..6ac28271c18 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -215,7 +215,6 @@ impl fmt::Debug for Pool { /// Event that can happen on the `Pool`. #[derive(Debug)] -#[allow(clippy::large_enum_variant)] pub enum PoolEvent { /// A new connection has been established. ConnectionEstablished { From 67577a77107cfbed86c1b616718302a4147dcb2f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 11:47:18 +1100 Subject: [PATCH 128/177] Don't override deprecated callbacks anywhere --- protocols/identify/src/behaviour.rs | 87 ++++++++++++++++------------- protocols/kad/src/behaviour.rs | 19 +++++-- swarm/src/test.rs | 35 ++++++++++-- swarm/tests/swarm_derive.rs | 24 +++++++- 4 files changed, 116 insertions(+), 49 deletions(-) diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 450ee154e6f..f6d78dc205c 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -237,6 +237,42 @@ impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; type OutEvent = Event; + fn handle_established_inbound_connection( + &mut self, + peer: PeerId, + _: ConnectionId, + _: &Multiaddr, + remote_addr: &Multiaddr, + ) -> Result, ConnectionDenied> { + Ok(Handler::new( + self.config.initial_delay, + self.config.interval, + peer, + self.config.local_public_key.clone(), + self.config.protocol_version.clone(), + self.config.agent_version.clone(), + remote_addr.clone(), + )) + } + + fn handle_established_outbound_connection( + &mut self, + peer: PeerId, + addr: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, ConnectionDenied> { + Ok(Handler::new( + self.config.initial_delay, + self.config.interval, + peer, + self.config.local_public_key.clone(), + self.config.protocol_version.clone(), + self.config.agent_version.clone(), + addr.clone(), // TODO: This is weird? That is the public address we dialed, shouldn't need to tell the other party? + )) + } + fn on_connection_handler_event( &mut self, peer_id: PeerId, @@ -342,8 +378,19 @@ impl NetworkBehaviour for Behaviour { } } - fn addresses_of_peer(&mut self, peer: &PeerId) -> Vec { - self.discovered_peers.get(peer) + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + _: &[Multiaddr], + _: Endpoint, + _: ConnectionId, + ) -> Result, ConnectionDenied> { + let peer = match maybe_peer { + None => return Ok(vec![]), + Some(peer) => peer, + }; + + Ok(self.discovered_peers.get(&peer)) } fn on_swarm_event(&mut self, event: FromSwarm) { @@ -416,42 +463,6 @@ impl NetworkBehaviour for Behaviour { | FromSwarm::ExpiredExternalAddr(_) => {} } } - - fn handle_established_inbound_connection( - &mut self, - peer: PeerId, - _: ConnectionId, - _: &Multiaddr, - remote_addr: &Multiaddr, - ) -> Result, ConnectionDenied> { - Ok(Handler::new( - self.config.initial_delay, - self.config.interval, - peer, - self.config.local_public_key.clone(), - self.config.protocol_version.clone(), - self.config.agent_version.clone(), - remote_addr.clone(), - )) - } - - fn handle_established_outbound_connection( - &mut self, - peer: PeerId, - addr: &Multiaddr, - _: Endpoint, - _: ConnectionId, - ) -> Result, ConnectionDenied> { - Ok(Handler::new( - self.config.initial_delay, - self.config.interval, - peer, - self.config.local_public_key.clone(), - self.config.protocol_version.clone(), - self.config.agent_version.clone(), - addr.clone(), // TODO: This is weird? That is the public address we dialed, shouldn't need to tell the other party? - )) - } } /// Event emitted by the `Identify` behaviour. diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 3d95cac2fce..f562a968181 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -2025,10 +2025,21 @@ where )) } - fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + _: &[Multiaddr], + _: Endpoint, + _: ConnectionId, + ) -> Result, ConnectionDenied> { + let peer_id = match maybe_peer { + None => return Ok(vec![]), + Some(peer) => peer, + }; + // 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 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::>(); @@ -2040,12 +2051,12 @@ where // 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) { + if let Some(addrs) = query.inner.addresses.get(&peer_id) { peer_addrs.extend(addrs.iter().cloned()) } } - peer_addrs + Ok(peer_addrs) } fn on_connection_handler_event( diff --git a/swarm/src/test.rs b/swarm/src/test.rs index ffb0f09d9b4..b6a540196e4 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -74,12 +74,39 @@ where type ConnectionHandler = THandler; type OutEvent = TOutEvent; - fn new_handler(&mut self) -> Self::ConnectionHandler { - self.handler_proto.clone() + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result { + Ok(self.handler_proto.clone()) } - fn addresses_of_peer(&mut self, p: &PeerId) -> Vec { - self.addresses.get(p).map_or(Vec::new(), |v| v.clone()) + fn handle_pending_outbound_connection( + &mut self, + maybe_peer: Option, + _: &[Multiaddr], + _: Endpoint, + _: ConnectionId, + ) -> Result, ConnectionDenied> { + let p = match maybe_peer { + None => return Ok(vec![]), + Some(peer) => peer, + }; + + Ok(self.addresses.get(&p).map_or(Vec::new(), |v| v.clone())) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result { + Ok(self.handler_proto.clone()) } fn poll( diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index f04cf4d2f6c..4d146a96ab0 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -19,10 +19,12 @@ // DEALINGS IN THE SOFTWARE. use futures::StreamExt; +use libp2p_core::{Endpoint, Multiaddr}; use libp2p_identify as identify; use libp2p_ping as ping; use libp2p_swarm::{ - behaviour::FromSwarm, dummy, NetworkBehaviour, SwarmEvent, THandlerInEvent, THandlerOutEvent, + behaviour::FromSwarm, dummy, ConnectionDenied, NetworkBehaviour, SwarmEvent, THandler, + THandlerInEvent, THandlerOutEvent, }; use std::fmt::Debug; @@ -383,8 +385,24 @@ fn custom_out_event_no_type_parameters() { type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = void::Void; - fn new_handler(&mut self) -> Self::ConnectionHandler { - dummy::ConnectionHandler + fn handle_established_inbound_connection( + &mut self, + _: PeerId, + _: ConnectionId, + _: &Multiaddr, + _: &Multiaddr, + ) -> Result, ConnectionDenied> { + Ok(dummy::ConnectionHandler) + } + + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result, ConnectionDenied> { + Ok(dummy::ConnectionHandler) } fn on_connection_handler_event( From 91a7a70de2b064ee94e479a33c639b4dfe7a8f6e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 11:50:10 +1100 Subject: [PATCH 129/177] Better order of callbacks --- swarm/src/test.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/swarm/src/test.rs b/swarm/src/test.rs index b6a540196e4..867e1c389ea 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -84,6 +84,16 @@ where Ok(self.handler_proto.clone()) } + fn handle_established_outbound_connection( + &mut self, + _: PeerId, + _: &Multiaddr, + _: Endpoint, + _: ConnectionId, + ) -> Result { + Ok(self.handler_proto.clone()) + } + fn handle_pending_outbound_connection( &mut self, maybe_peer: Option, @@ -99,16 +109,6 @@ where Ok(self.addresses.get(&p).map_or(Vec::new(), |v| v.clone())) } - fn handle_established_outbound_connection( - &mut self, - _: PeerId, - _: &Multiaddr, - _: Endpoint, - _: ConnectionId, - ) -> Result { - Ok(self.handler_proto.clone()) - } - fn poll( &mut self, _: &mut Context, From 92a96255868ba07fba97747d585b12e1ee93e548 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 11:51:17 +1100 Subject: [PATCH 130/177] Spawn connection at right point in time Otherwise the num-established counter is wrong. --- swarm/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 7fee4b001ec..641f2a9cf4d 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -773,8 +773,6 @@ where .behaviour .new_handler() .into_handler(&peer_id, &endpoint); - self.pool - .spawn_connection(id, peer_id, &endpoint, connection, handler); let other_established_connection_ids = self .pool @@ -789,6 +787,9 @@ where .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) .count(); + self.pool + .spawn_connection(id, peer_id, &endpoint, connection, handler); + log::debug!( "Connection established: {:?} {:?}; Total (peer): {}. Total non-banned (peer): {}", peer_id, From 6df1c9a75c5f5eeba517810f42f03452b6959708 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 12:00:13 +1100 Subject: [PATCH 131/177] Be consistent in order of parameters --- protocols/autonat/src/behaviour.rs | 20 +++++++------- protocols/dcutr/src/behaviour_impl.rs | 8 +++--- protocols/floodsub/src/layer.rs | 4 +-- protocols/gossipsub/src/behaviour.rs | 4 +-- protocols/identify/src/behaviour.rs | 10 +++---- protocols/kad/src/behaviour.rs | 10 +++---- protocols/kad/src/behaviour/test.rs | 12 ++++---- protocols/mdns/src/behaviour.rs | 6 ++-- protocols/ping/src/lib.rs | 4 +-- protocols/relay/src/behaviour.rs | 8 +++--- protocols/relay/src/priv_client.rs | 8 +++--- protocols/rendezvous/src/client.rs | 6 ++-- protocols/rendezvous/src/server.rs | 4 +-- protocols/request-response/src/lib.rs | 6 ++-- swarm-derive/src/lib.rs | 14 +++++----- swarm/src/behaviour.rs | 6 ++-- swarm/src/behaviour/either.rs | 30 ++++++++++---------- swarm/src/behaviour/toggle.rs | 20 +++++++------- swarm/src/dummy.rs | 4 +-- swarm/src/keep_alive.rs | 4 +-- swarm/src/lib.rs | 6 ++-- swarm/src/test.rs | 40 +++++++++++++-------------- swarm/tests/swarm_derive.rs | 4 +-- 23 files changed, 119 insertions(+), 119 deletions(-) diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index 65a3d0391bc..7e83992ae64 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -497,14 +497,14 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, - connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { self.inner.handle_established_inbound_connection( + _connection_id, peer, - connection_id, local_addr, remote_addr, ) @@ -512,28 +512,28 @@ impl NetworkBehaviour for Behaviour { fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, - addresses: &[Multiaddr], - effective_role: Endpoint, - connection_id: ConnectionId, + _addresses: &[Multiaddr], + _effective_role: Endpoint, ) -> Result, ConnectionDenied> { self.inner.handle_pending_outbound_connection( + _connection_id, maybe_peer, - addresses, - effective_role, - connection_id, + _addresses, + _effective_role, ) } fn handle_established_outbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - connection_id: ConnectionId, ) -> Result, ConnectionDenied> { self.inner - .handle_established_outbound_connection(peer, addr, role_override, connection_id) + .handle_established_outbound_connection(_connection_id, peer, addr, role_override) } fn on_swarm_event(&mut self, event: FromSwarm) { diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index c8e7e625df0..090bd5dc444 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -247,8 +247,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, - connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -256,7 +256,7 @@ impl NetworkBehaviour for Behaviour { match self .outgoing_direct_connection_attempts - .remove(&(connection_id, peer)) + .remove(&(_connection_id, peer)) { None => { let handler = if is_relayed { @@ -285,16 +285,16 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - connection_id: ConnectionId, ) -> Result, ConnectionDenied> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. match self .outgoing_direct_connection_attempts - .remove(&(connection_id, peer)) + .remove(&(_connection_id, peer)) { None => { let handler = if is_relayed { diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 697549fad3b..769bf7dfcef 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -336,8 +336,8 @@ impl NetworkBehaviour for Floodsub { fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -346,10 +346,10 @@ impl NetworkBehaviour for Floodsub { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(Default::default()) } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 2b083b83d3b..82c99c699f6 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -3296,8 +3296,8 @@ where fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -3309,10 +3309,10 @@ where fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(GossipsubHandler::new( ProtocolConfig::new(&self.config), diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index f6d78dc205c..22e50d1d3f5 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -239,8 +239,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - peer: PeerId, _: ConnectionId, + peer: PeerId, _: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -257,10 +257,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, peer: PeerId, addr: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(Handler::new( self.config.initial_delay, @@ -380,10 +380,10 @@ impl NetworkBehaviour for Behaviour { fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, - _: &[Multiaddr], - _: Endpoint, - _: ConnectionId, + _addresses: &[Multiaddr], + _effective_role: Endpoint, ) -> Result, ConnectionDenied> { let peer = match maybe_peer { None => return Ok(vec![]), diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index f562a968181..9d3d9014538 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1985,8 +1985,8 @@ where fn handle_established_inbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, - _: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -2006,10 +2006,10 @@ where fn handle_established_outbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(KademliaHandler::new( KademliaHandlerConfig { @@ -2027,10 +2027,10 @@ where fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, - _: &[Multiaddr], - _: Endpoint, - _: ConnectionId, + _addresses: &[Multiaddr], + _effective_role: Endpoint, ) -> Result, ConnectionDenied> { let peer_id = match maybe_peer { None => return Ok(vec![]), diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index 5a1c669cf30..2f51eaef52d 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -1320,10 +1320,10 @@ fn network_behaviour_on_address_change() { // local routing table and hence no addresses are known. assert!(kademlia .handle_pending_outbound_connection( + connection_id, Some(remote_peer_id), &[], - Endpoint::Dialer, - connection_id + Endpoint::Dialer ) .unwrap() .is_empty()); @@ -1340,10 +1340,10 @@ fn network_behaviour_on_address_change() { vec![old_address.clone()], kademlia .handle_pending_outbound_connection( + connection_id, Some(remote_peer_id), &[], - Endpoint::Dialer, - connection_id + Endpoint::Dialer ) .unwrap(), ); @@ -1365,10 +1365,10 @@ fn network_behaviour_on_address_change() { vec![new_address], kademlia .handle_pending_outbound_connection( + connection_id, Some(remote_peer_id), &[], - Endpoint::Dialer, - connection_id + Endpoint::Dialer ) .unwrap(), ); diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 5030ae3a1d7..44b968c12a3 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -176,8 +176,8 @@ where fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -186,10 +186,10 @@ where fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, _addresses: &[Multiaddr], _effective_role: Endpoint, - _connection_id: ConnectionId, ) -> Result, ConnectionDenied> { let peer_id = match maybe_peer { None => return Ok(vec![]), @@ -206,10 +206,10 @@ where fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(dummy::ConnectionHandler) } diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index a48c4dadb6e..b9016f34aa7 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -122,8 +122,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> std::result::Result, ConnectionDenied> { @@ -132,10 +132,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> std::result::Result, ConnectionDenied> { Ok(Handler::new(self.config.clone())) } diff --git a/protocols/relay/src/behaviour.rs b/protocols/relay/src/behaviour.rs index 82b44903583..86a0cd10b29 100644 --- a/protocols/relay/src/behaviour.rs +++ b/protocols/relay/src/behaviour.rs @@ -257,8 +257,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _peer: PeerId, - _connection_id: ConnectionId, + _: ConnectionId, + _: PeerId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -284,10 +284,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, - _peer: PeerId, + _: ConnectionId, + _: PeerId, addr: &Multiaddr, role_override: Endpoint, - _connection_id: ConnectionId, ) -> Result, ConnectionDenied> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index ae3c1b6fef4..dce1e5a4a9c 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -164,8 +164,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, - connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -177,7 +177,7 @@ impl NetworkBehaviour for Behaviour { let mut handler = Handler::new(self.local_peer_id, peer, remote_addr.clone()); - if let Some(event) = self.pending_handler_commands.remove(&connection_id) { + if let Some(event) = self.pending_handler_commands.remove(&_connection_id) { handler.on_behaviour_event(event) } @@ -186,10 +186,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, - _role_override: Endpoint, - connection_id: ConnectionId, + _: Endpoint, ) -> Result, ConnectionDenied> { let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index 50e3e75f017..8cb91a71f11 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -171,8 +171,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -183,10 +183,10 @@ impl NetworkBehaviour for Behaviour { fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, _addresses: &[Multiaddr], _effective_role: Endpoint, - _connection_id: ConnectionId, ) -> Result, ConnectionDenied> { let peer = match maybe_peer { None => return Ok(vec![]), @@ -206,10 +206,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(SubstreamConnectionHandler::new_outbound_only( Duration::from_secs(30), diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index f552a2a0df2..2d38d201497 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -113,8 +113,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -125,10 +125,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(SubstreamConnectionHandler::new_inbound_only( Duration::from_secs(30), diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 281f28848ba..008a6aa38e9 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -728,8 +728,8 @@ where fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -744,10 +744,10 @@ where fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, _addresses: &[Multiaddr], _effective_role: Endpoint, - _connection_id: ConnectionId, ) -> Result, ConnectionDenied> { let peer = match maybe_peer { None => return Ok(vec![]), @@ -767,10 +767,10 @@ where fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(Handler::new( self.inbound_protocols.clone(), diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 9c85806d36b..6b5524e719c 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -549,7 +549,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }; let builder = quote! { - #field_name.handle_established_inbound_connection(peer, connection_id, local_addr, remote_addr)? + #field_name.handle_established_inbound_connection(connection_id, peer, local_addr, remote_addr)? }; match out_handler { @@ -571,10 +571,10 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .map(|(field_n, field)| { match field.ident { Some(ref i) => quote! { - combined_addresses.extend(#trait_to_impl::handle_pending_outbound_connection(&mut self.#i, maybe_peer, addresses, effective_role, connection_id)?); + combined_addresses.extend(#trait_to_impl::handle_pending_outbound_connection(&mut self.#i, connection_id, maybe_peer, addresses, effective_role)?); }, None => quote! { - combined_addresses.extend(#trait_to_impl::handle_pending_outbound_connection(&mut self.#field_n, maybe_peer, addresses, effective_role, connection_id)?); + combined_addresses.extend(#trait_to_impl::handle_pending_outbound_connection(&mut self.#field_n, connection_id, maybe_peer, addresses, effective_role)?); } } }); @@ -599,7 +599,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }; let builder = quote! { - #field_name.handle_established_outbound_connection(peer, addr, role_override, connection_id)? + #field_name.handle_established_outbound_connection(connection_id, peer, addr, role_override)? }; match out_handler { @@ -709,8 +709,8 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #[allow(clippy::needless_question_mark)] fn handle_established_inbound_connection( &mut self, - peer: #peer_id, connection_id: #connection_id, + peer: #peer_id, local_addr: &#multiaddr, remote_addr: &#multiaddr, ) -> Result<#t_handler, #connection_denied> { @@ -720,10 +720,10 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #[allow(clippy::needless_question_mark)] fn handle_pending_outbound_connection( &mut self, + connection_id: #connection_id, maybe_peer: Option<#peer_id>, addresses: &[#multiaddr], effective_role: #endpoint, - connection_id: #connection_id, ) -> Result<::std::vec::Vec<#multiaddr>, #connection_denied> { #handle_pending_outbound_connection } @@ -731,10 +731,10 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #[allow(clippy::needless_question_mark)] fn handle_established_outbound_connection( &mut self, + connection_id: #connection_id, peer: #peer_id, addr: &#multiaddr, role_override: #endpoint, - connection_id: #connection_id, ) -> Result<#t_handler, #connection_denied> { Ok(#handle_established_outbound_connection) } diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 0e76dbfef05..37b570376ac 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -176,8 +176,8 @@ pub trait NetworkBehaviour: 'static { /// Returning an error will immediately close the connection. fn handle_established_inbound_connection( &mut self, - peer: PeerId, _connection_id: ConnectionId, + peer: PeerId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -205,10 +205,10 @@ pub trait NetworkBehaviour: 'static { /// Any error returned from this function will immediately abort the dial attempt. fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, _addresses: &[Multiaddr], _effective_role: Endpoint, - _connection_id: ConnectionId, ) -> Result, ConnectionDenied> { #[allow(deprecated)] if let Some(peer_id) = maybe_peer { @@ -226,10 +226,10 @@ pub trait NetworkBehaviour: 'static { /// Returning an error will immediately close the connection. fn handle_established_outbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - _connection_id: ConnectionId, ) -> Result, ConnectionDenied> { #[allow(deprecated)] Ok(self.new_handler().into_handler( diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index 7c706ea3eb0..ef62b51f7b9 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -48,21 +48,21 @@ where fn handle_established_inbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, - connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { let handler = match self { Either::Left(inner) => Either::Left(inner.handle_established_inbound_connection( + _connection_id, peer, - connection_id, local_addr, remote_addr, )?), Either::Right(inner) => Either::Right(inner.handle_established_inbound_connection( + _connection_id, peer, - connection_id, local_addr, remote_addr, )?), @@ -73,23 +73,23 @@ where fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, - addresses: &[Multiaddr], - effective_role: Endpoint, - connection_id: ConnectionId, + _addresses: &[Multiaddr], + _effective_role: Endpoint, ) -> Result, ConnectionDenied> { let addresses = match self { Either::Left(inner) => inner.handle_pending_outbound_connection( + _connection_id, maybe_peer, - addresses, - effective_role, - connection_id, + _addresses, + _effective_role, )?, Either::Right(inner) => inner.handle_pending_outbound_connection( + _connection_id, maybe_peer, - addresses, - effective_role, - connection_id, + _addresses, + _effective_role, )?, }; @@ -98,23 +98,23 @@ where fn handle_established_outbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - connection_id: ConnectionId, ) -> Result, ConnectionDenied> { let handler = match self { Either::Left(inner) => Either::Left(inner.handle_established_outbound_connection( + _connection_id, peer, addr, role_override, - connection_id, )?), Either::Right(inner) => Either::Right(inner.handle_established_outbound_connection( + _connection_id, peer, addr, role_override, - connection_id, )?), }; diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index d79c45066fe..0566eafbd68 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -90,8 +90,8 @@ where fn handle_established_inbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, - connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -101,8 +101,8 @@ where }; let handler = inner.handle_established_inbound_connection( + _connection_id, peer, - connection_id, local_addr, remote_addr, )?; @@ -114,10 +114,10 @@ where fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, - addresses: &[Multiaddr], - effective_role: Endpoint, - connection_id: ConnectionId, + _addresses: &[Multiaddr], + _effective_role: Endpoint, ) -> Result, ConnectionDenied> { let inner = match self.inner.as_mut() { None => return Ok(vec![]), @@ -125,10 +125,10 @@ where }; let addresses = inner.handle_pending_outbound_connection( + _connection_id, maybe_peer, - addresses, - effective_role, - connection_id, + _addresses, + _effective_role, )?; Ok(addresses) @@ -136,10 +136,10 @@ where fn handle_established_outbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - connection_id: ConnectionId, ) -> Result, ConnectionDenied> { let inner = match self.inner.as_mut() { None => return Ok(ToggleConnectionHandler { inner: None }), @@ -147,10 +147,10 @@ where }; let handler = inner.handle_established_outbound_connection( + _connection_id, peer, addr, role_override, - connection_id, )?; Ok(ToggleConnectionHandler { diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index c28f7c43778..8d9fa74c7ab 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -22,8 +22,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -32,10 +32,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(ConnectionHandler) } diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index b5546cfa68d..cbc778cfc0a 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -25,8 +25,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -35,10 +35,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(ConnectionHandler) } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 58bb5adab0b..f254c17d9b1 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -554,10 +554,10 @@ where let mut addresses_from_opts = dial_opts.get_addresses(); match self.behaviour.handle_pending_outbound_connection( + connection_id, peer_id, addresses_from_opts.as_slice(), dial_opts.role_override(), - connection_id, ) { Ok(addresses) => { if dial_opts.extend_addresses_through_behaviour() { @@ -803,10 +803,10 @@ where role_override, } => { match self.behaviour.handle_established_outbound_connection( + id, peer_id, &address, role_override, - id, ) { Ok(handler) => handler, Err(cause) => { @@ -831,8 +831,8 @@ where send_back_addr, } => { match self.behaviour.handle_established_inbound_connection( - peer_id, id, + peer_id, &local_addr, &send_back_addr, ) { diff --git a/swarm/src/test.rs b/swarm/src/test.rs index 867e1c389ea..aac5b600a2c 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -76,8 +76,8 @@ where fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result { @@ -86,20 +86,20 @@ where fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result { Ok(self.handler_proto.clone()) } fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, - _: &[Multiaddr], - _: Endpoint, - _: ConnectionId, + _addresses: &[Multiaddr], + _effective_role: Endpoint, ) -> Result, ConnectionDenied> { let p = match maybe_peer { None => return Ok(vec![]), @@ -420,20 +420,20 @@ where fn handle_established_inbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, - connection_id: ConnectionId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { self.handle_established_inbound_connection.push(( peer, - connection_id, + _connection_id, local_addr.clone(), remote_addr.clone(), )); self.inner.handle_established_inbound_connection( + _connection_id, peer, - connection_id, local_addr, remote_addr, ) @@ -441,40 +441,40 @@ where fn handle_pending_outbound_connection( &mut self, + _connection_id: ConnectionId, maybe_peer: Option, - addresses: &[Multiaddr], - effective_role: Endpoint, - connection_id: ConnectionId, + _addresses: &[Multiaddr], + _effective_role: Endpoint, ) -> Result, ConnectionDenied> { self.handle_pending_outbound_connection.push(( maybe_peer, - addresses.to_vec(), - effective_role, - connection_id, + _addresses.to_vec(), + _effective_role, + _connection_id, )); self.inner.handle_pending_outbound_connection( + _connection_id, maybe_peer, - addresses, - effective_role, - connection_id, + _addresses, + _effective_role, ) } fn handle_established_outbound_connection( &mut self, + _connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, - connection_id: ConnectionId, ) -> Result, ConnectionDenied> { self.handle_established_outbound_connection.push(( peer, addr.clone(), role_override, - connection_id, + _connection_id, )); self.inner - .handle_established_outbound_connection(peer, addr, role_override, connection_id) + .handle_established_outbound_connection(_connection_id, peer, addr, role_override) } fn on_swarm_event(&mut self, event: FromSwarm) { diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 4d146a96ab0..4d378bc5641 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -387,8 +387,8 @@ fn custom_out_event_no_type_parameters() { fn handle_established_inbound_connection( &mut self, - _: PeerId, _: ConnectionId, + _: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -397,10 +397,10 @@ fn custom_out_event_no_type_parameters() { fn handle_established_outbound_connection( &mut self, + _: ConnectionId, _: PeerId, _: &Multiaddr, _: Endpoint, - _: ConnectionId, ) -> Result, ConnectionDenied> { Ok(dummy::ConnectionHandler) } From 17db8b47dffcc75af14c6237866d995e92d721fe Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 12:06:36 +1100 Subject: [PATCH 132/177] Reduce diff --- examples/file-sharing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/file-sharing.rs b/examples/file-sharing.rs index ceebd39dad8..6cae1f492a5 100644 --- a/examples/file-sharing.rs +++ b/examples/file-sharing.rs @@ -547,7 +547,7 @@ mod network { .swarm .dial(peer_addr.with(Protocol::P2p(peer_id.into()))) { - Ok(_) => { + Ok(()) => { e.insert(sender); } Err(e) => { From d90ac81fb9fa05824fe7b5f0d27b0bbfd33ba4ea Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 12:12:13 +1100 Subject: [PATCH 133/177] Fix rustdoc --- swarm/src/behaviour.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 19b55883ea6..06b9a906c45 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -124,7 +124,7 @@ pub trait NetworkBehaviour: 'static { /// Event generated by the `NetworkBehaviour` and that the swarm will report back. type OutEvent: Send + 'static; - /// Creates a new [`ConnectionHandler`] for a connection with a peer. + /// Creates a new [`ConnectionHandler`](crate::ConnectionHandler) for a connection with a peer. /// /// Every time an incoming connection is opened, and every time another [`NetworkBehaviour`] /// emitted a dial request, this method is called. @@ -156,8 +156,8 @@ pub trait NetworkBehaviour: 'static { /// 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. + /// Informs the behaviour about an event generated by the [`ConnectionHandler`](crate::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`]. @@ -241,19 +241,19 @@ pub enum NetworkBehaviourAction { /// connection with a peer. /// /// If the `Swarm` is connected to the peer, the message is delivered to the - /// [`ConnectionHandler`] instance identified by the peer ID and connection ID. + /// [`ConnectionHandler`](crate::ConnectionHandler) instance identified by the peer ID and connection ID. /// /// If the specified connection no longer exists, the event is silently dropped. /// /// Typically the connection ID given is the same as the one passed to /// [`NetworkBehaviour::on_connection_handler_event`], i.e. whenever the behaviour wishes to /// respond to a request on the same connection (and possibly the same - /// substream, as per the implementation of [`ConnectionHandler`]). + /// substream, as per the implementation of [`ConnectionHandler`](crate::ConnectionHandler)). /// /// Note that even if the peer is currently connected, connections can get closed /// at any time and thus the event may not reach a handler. NotifyHandler { - /// The peer for whom a [`ConnectionHandler`] should be notified. + /// The peer for whom a [`ConnectionHandler`](crate::ConnectionHandler) should be notified. peer_id: PeerId, /// The options w.r.t. which connection handler to notify of the event. handler: NotifyHandler, @@ -282,9 +282,9 @@ pub enum NetworkBehaviourAction { /// /// Note: Closing a connection via /// [`NetworkBehaviourAction::CloseConnection`] does not inform the - /// corresponding [`ConnectionHandler`]. - /// Closing a connection via a [`ConnectionHandler`] can be done - /// either in a collaborative manner across [`ConnectionHandler`]s + /// corresponding [`ConnectionHandler`](crate::ConnectionHandler). + /// Closing a connection via a [`ConnectionHandler`](crate::ConnectionHandler) can be done + /// either in a collaborative manner across [`ConnectionHandler`](crate::ConnectionHandler)s /// with [`ConnectionHandler::connection_keep_alive`] or directly with /// [`ConnectionHandlerEvent::Close`](crate::ConnectionHandlerEvent::Close). CloseConnection { From cfe9f958cba987efde2a5b1ddbf0a665e352c563 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 12:22:43 +1100 Subject: [PATCH 134/177] One more missing rustdoc link --- swarm/src/behaviour.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 06b9a906c45..44d69fed654 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -285,7 +285,7 @@ pub enum NetworkBehaviourAction { /// corresponding [`ConnectionHandler`](crate::ConnectionHandler). /// Closing a connection via a [`ConnectionHandler`](crate::ConnectionHandler) can be done /// either in a collaborative manner across [`ConnectionHandler`](crate::ConnectionHandler)s - /// with [`ConnectionHandler::connection_keep_alive`] or directly with + /// with [`ConnectionHandler::connection_keep_alive`](crate::ConnectionHandler::connection_keep_alive) or directly with /// [`ConnectionHandlerEvent::Close`](crate::ConnectionHandlerEvent::Close). CloseConnection { /// The peer to disconnect. From 3f8f73c7bed55d8b662e2de37054de7a7ce0e10c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 15:18:23 +1100 Subject: [PATCH 135/177] Remove `banned_peer_connections` We no longer add connections for banned peers to the pool so we don't have to filter them later. --- swarm/src/lib.rs | 76 +++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 641f2a9cf4d..d950927fd05 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -327,12 +327,6 @@ where /// List of nodes for which we deny any incoming connection. banned_peers: HashSet, - /// Connections for which we withhold any reporting. These belong to banned peers. - /// - /// Note: Connections to a peer that are established at the time of banning that peer - /// are not added here. Instead they are simply closed. - banned_peer_connections: HashSet, - /// Pending event to be delivered to connection handlers /// (or dropped if the peer disconnected) before the `behaviour` /// can be polled again. @@ -762,9 +756,6 @@ where established_in, } => { if self.banned_peers.contains(&peer_id) { - // Mark the connection for the banned peer as banned, thus withholding any - // future events from the connection to the behaviour. - self.banned_peer_connections.insert(id); self.pool.disconnect(peer_id); return Some(SwarmEvent::BannedPeer { peer_id, endpoint }); } @@ -782,21 +773,16 @@ where u32::try_from(other_established_connection_ids.len() + 1).unwrap(), ) .expect("n + 1 is always non-zero; qed"); - let non_banned_established = other_established_connection_ids - .into_iter() - .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) - .count(); self.pool .spawn_connection(id, peer_id, &endpoint, connection, handler); log::debug!( - "Connection established: {:?} {:?}; Total (peer): {}. Total non-banned (peer): {}", - peer_id, - endpoint, - num_established, - non_banned_established + 1, - ); + "Connection established: {:?} {:?}; Total (peer): {}.", + peer_id, + endpoint, + num_established, + ); let failed_addresses = concurrent_dial_errors .as_ref() .map(|es| { @@ -813,7 +799,7 @@ where connection_id: id, endpoint: &endpoint, failed_addresses: &failed_addresses, - other_established: non_banned_established, + other_established: other_established_connection_ids.len(), }, )); return Some(SwarmEvent::ConnectionEstablished { @@ -897,21 +883,15 @@ where let endpoint = connected.endpoint; let num_established = u32::try_from(remaining_established_connection_ids.len()).unwrap(); - let conn_was_reported = !self.banned_peer_connections.remove(&id); - if conn_was_reported { - let remaining_non_banned = remaining_established_connection_ids - .into_iter() - .filter(|conn_id| !self.banned_peer_connections.contains(conn_id)) - .count(); - self.behaviour - .on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { - peer_id, - connection_id: id, - endpoint: &endpoint, - handler, - remaining_established: remaining_non_banned, - })); - } + + self.behaviour + .on_swarm_event(FromSwarm::ConnectionClosed(ConnectionClosed { + peer_id, + connection_id: id, + endpoint: &endpoint, + handler, + remaining_established: num_established as usize, + })); return Some(SwarmEvent::ConnectionClosed { peer_id, endpoint, @@ -920,12 +900,8 @@ where }); } PoolEvent::ConnectionEvent { peer_id, id, event } => { - if self.banned_peer_connections.contains(&id) { - log::debug!("Ignoring event from banned peer: {} {:?}.", peer_id, id); - } else { - self.behaviour - .on_connection_handler_event(peer_id, id, event); - } + self.behaviour + .on_connection_handler_event(peer_id, id, event); } PoolEvent::AddressChange { peer_id, @@ -933,15 +909,13 @@ where new_endpoint, old_endpoint, } => { - if !self.banned_peer_connections.contains(&id) { - self.behaviour - .on_swarm_event(FromSwarm::AddressChange(AddressChange { - peer_id, - connection_id: id, - old: &old_endpoint, - new: &new_endpoint, - })); - } + self.behaviour + .on_swarm_event(FromSwarm::AddressChange(AddressChange { + peer_id, + connection_id: id, + old: &old_endpoint, + new: &new_endpoint, + })); } } @@ -1577,7 +1551,6 @@ where listened_addrs: HashMap::new(), external_addrs: Addresses::default(), banned_peers: HashSet::new(), - banned_peer_connections: HashSet::new(), pending_event: None, } } @@ -2004,7 +1977,6 @@ mod tests { 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()); // Setup to test that a ban lifted does not affect future connections. for _ in 0..num_connections { From 063ef5c2a0835f42c46c97e5e4ce694724193838 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 15:22:26 +1100 Subject: [PATCH 136/177] Fix test Now that we no longer add connections to banned peers, we need to: - Reduce the number of expected connections by 1 (i.e. delete line 1954) - Act in `Stage::BannedDial` earlier (i.e. remove the `if`) --- swarm/src/lib.rs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index d950927fd05..45c389932f3 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1951,24 +1951,22 @@ mod tests { { // Setup to test that new connections of banned peers are not reported. swarm1.dial(addr2.clone()).unwrap(); - s1_expected_conns += 1; stage = Stage::BannedDial; } } Stage::BannedDial => { - if swarm2.network_info().num_peers() == 1 { - // The banned connection was established. Check that it was not reported to - // the behaviour of the banning swarm. - assert_eq!( - swarm2.behaviour.on_connection_established.len(), s2_expected_conns, - "No additional closed connections should be reported for the banned peer" - ); + // The banned connection was established. Check that it was not reported to + // the behaviour of the banning swarm. + assert_eq!( + swarm2.behaviour.on_connection_established.len(), + s2_expected_conns, + "No additional closed connections should be reported for the banned peer" + ); - // Setup to test that the banned connection is not reported upon closing - // even if the peer is unbanned. - swarm2.unban_peer_id(swarm1_id); - stage = Stage::Unbanned; - } + // Setup to test that the banned connection is not reported upon closing + // even if the peer is unbanned. + swarm2.unban_peer_id(swarm1_id); + stage = Stage::Unbanned; } Stage::Unbanned => { if swarm2.network_info().num_peers() == 0 { From 751cad4691600c84946f54a0c47d4d7163372ac3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 15:47:19 +1100 Subject: [PATCH 137/177] Remove duplication around detecting relayed addresses in `libp2p-relay` --- protocols/relay/src/behaviour.rs | 9 +++------ protocols/relay/src/lib.rs | 1 + protocols/relay/src/multiaddr_ext.rs | 12 ++++++++++++ protocols/relay/src/priv_client.rs | 9 +++------ protocols/relay/src/priv_client/transport.rs | 3 ++- 5 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 protocols/relay/src/multiaddr_ext.rs diff --git a/protocols/relay/src/behaviour.rs b/protocols/relay/src/behaviour.rs index 86a0cd10b29..96c99697a7a 100644 --- a/protocols/relay/src/behaviour.rs +++ b/protocols/relay/src/behaviour.rs @@ -25,6 +25,7 @@ pub mod rate_limiter; use crate::behaviour::handler::Handler; use crate::message_proto; +use crate::multiaddr_ext::MultiaddrExt; use crate::protocol::{inbound_hop, outbound_stop}; use either::Either; use instant::Instant; @@ -262,9 +263,7 @@ impl NetworkBehaviour for Behaviour { local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { - let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - - if is_relayed { + if local_addr.is_relayed() { // Deny all substreams on relayed connection. return Ok(Either::Right(dummy::ConnectionHandler)); } @@ -289,9 +288,7 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, role_override: Endpoint, ) -> Result, ConnectionDenied> { - let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - - if is_relayed { + if addr.is_relayed() { // Deny all substreams on relayed connection. return Ok(Either::Right(dummy::ConnectionHandler)); } diff --git a/protocols/relay/src/lib.rs b/protocols/relay/src/lib.rs index aa5a82043f5..87f3cee0e82 100644 --- a/protocols/relay/src/lib.rs +++ b/protocols/relay/src/lib.rs @@ -25,6 +25,7 @@ mod behaviour; mod copy_future; +mod multiaddr_ext; mod priv_client; mod protocol; pub mod v2; diff --git a/protocols/relay/src/multiaddr_ext.rs b/protocols/relay/src/multiaddr_ext.rs new file mode 100644 index 00000000000..6991a8b9ded --- /dev/null +++ b/protocols/relay/src/multiaddr_ext.rs @@ -0,0 +1,12 @@ +use libp2p_core::multiaddr::Protocol; +use libp2p_core::Multiaddr; + +pub(crate) trait MultiaddrExt { + fn is_relayed(&self) -> bool; +} + +impl MultiaddrExt for Multiaddr { + fn is_relayed(&self) -> bool { + self.iter().any(|p| p == Protocol::P2pCircuit) + } +} diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index dce1e5a4a9c..435c2059ca0 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -23,6 +23,7 @@ mod handler; pub(crate) mod transport; +use crate::multiaddr_ext::MultiaddrExt; use crate::priv_client::handler::Handler; use crate::protocol::{self, inbound_stop, outbound_hop}; use bytes::Bytes; @@ -169,9 +170,7 @@ impl NetworkBehaviour for Behaviour { local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { - let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - - if is_relayed { + if local_addr.is_relayed() { return Ok(Either::Right(dummy::ConnectionHandler)); } @@ -191,9 +190,7 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, _: Endpoint, ) -> Result, ConnectionDenied> { - let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - - if is_relayed { + if addr.is_relayed() { return Ok(Either::Right(dummy::ConnectionHandler)); } diff --git a/protocols/relay/src/priv_client/transport.rs b/protocols/relay/src/priv_client/transport.rs index 264eb3abcd5..6dfc46710f8 100644 --- a/protocols/relay/src/priv_client/transport.rs +++ b/protocols/relay/src/priv_client/transport.rs @@ -19,6 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use crate::multiaddr_ext::MultiaddrExt; use crate::priv_client::Connection; use crate::RequestId; use futures::channel::mpsc; @@ -247,7 +248,7 @@ struct RelayedMultiaddr { /// Parse a [`Multiaddr`] containing a [`Protocol::P2pCircuit`]. fn parse_relayed_multiaddr(addr: Multiaddr) -> Result> { - if !addr.iter().any(|p| matches!(p, Protocol::P2pCircuit)) { + if !addr.is_relayed() { return Err(TransportError::MultiaddrNotSupported(addr)); } From 9462dbeddc8b2e751ef8ca37d2004bb35ab720c9 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 15:49:07 +1100 Subject: [PATCH 138/177] Extract utility fn for dcutr protocol --- protocols/dcutr/src/behaviour_impl.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 090bd5dc444..9dde9d965ef 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -252,14 +252,12 @@ impl NetworkBehaviour for Behaviour { local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { - let is_relayed = local_addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - match self .outgoing_direct_connection_attempts .remove(&(_connection_id, peer)) { None => { - let handler = if is_relayed { + let handler = if is_relayed(local_addr) { Either::Left(handler::relayed::Handler::new(ConnectedPoint::Listener { local_addr: local_addr.clone(), send_back_addr: remote_addr.clone(), @@ -272,7 +270,7 @@ impl NetworkBehaviour for Behaviour { } Some(_) => { assert!( - !is_relayed, + !is_relayed(local_addr), "`Prototype::DirectConnection` is never created for relayed connection." ); @@ -290,14 +288,12 @@ impl NetworkBehaviour for Behaviour { addr: &Multiaddr, role_override: Endpoint, ) -> Result, ConnectionDenied> { - let is_relayed = addr.iter().any(|p| p == Protocol::P2pCircuit); // TODO: Make this an extension on `Multiaddr`. - match self .outgoing_direct_connection_attempts .remove(&(_connection_id, peer)) { None => { - let handler = if is_relayed { + let handler = if is_relayed(addr) { Either::Left(handler::relayed::Handler::new(ConnectedPoint::Dialer { address: addr.clone(), role_override, @@ -310,7 +306,7 @@ impl NetworkBehaviour for Behaviour { } Some(_) => { assert!( - !is_relayed, + !is_relayed(addr), "`Prototype::DirectConnection` is never created for relayed connection." ); @@ -464,3 +460,7 @@ impl NetworkBehaviour for Behaviour { } } } + +fn is_relayed(addr: &Multiaddr) -> bool { + addr.iter().any(|p| p == Protocol::P2pCircuit) +} From 639b9dad77dedeeb917016698e2c42a7a1c97a49 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 15:49:39 +1100 Subject: [PATCH 139/177] Remove unused import --- protocols/relay/src/priv_client.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 435c2059ca0..fc3c760a2f8 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -34,7 +34,6 @@ use futures::future::{BoxFuture, FutureExt}; use futures::io::{AsyncRead, AsyncWrite}; use futures::ready; use futures::stream::StreamExt; -use libp2p_core::multiaddr::Protocol; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; From 0bcfe8108bfc7904400cbc249cdb866a93c7d488 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 27 Jan 2023 15:50:45 +1100 Subject: [PATCH 140/177] Remove underscore from used variable --- protocols/relay/src/priv_client.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index fc3c760a2f8..f9869832ae7 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -164,7 +164,7 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _connection_id: ConnectionId, + connection_id: ConnectionId, peer: PeerId, local_addr: &Multiaddr, remote_addr: &Multiaddr, @@ -175,7 +175,7 @@ impl NetworkBehaviour for Behaviour { let mut handler = Handler::new(self.local_peer_id, peer, remote_addr.clone()); - if let Some(event) = self.pending_handler_commands.remove(&_connection_id) { + if let Some(event) = self.pending_handler_commands.remove(&connection_id) { handler.on_behaviour_event(event) } From 95cde920760a046af1452bacb42168002bbe49f6 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 31 Jan 2023 14:47:03 +1100 Subject: [PATCH 141/177] Add changelog entry --- swarm/CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 2c6f116571e..67e07c80c8f 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -33,6 +33,24 @@ See [PR 3328]. +- Allow `NetworkBehaviour`s to manage connections. + We deprecate `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` in favor of four new callbacks: + + - `NetworkBehaviour::handle_pending_inbound_connection` + - `NetworkBehaviour::handle_pending_outbound_connection` + - `NetworkBehaviour::handle_established_inbound_connection` + - `NetworkBehaviour::handle_established_outbound_connection` + + All four are fallible and returning an error from any of them will abort the given connection. + This allows you to create dedicated `NetworkBehaviour`s that only concern themselves with managing connections. + For example: + - checking the `PeerId` of a newly established connection against an allow/block list + - only allowing X connection upgrades at any one time + - denying incoming or outgoing connections from a certain IP range + - only allowing N connections to or from the same peer + + See [PR 3254]. + - Update to `libp2p-core` `v0.39.0`. - Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170]. @@ -84,6 +102,7 @@ [PR 3373]: https://github.com/libp2p/rust-libp2p/pull/3373 [PR 3374]: https://github.com/libp2p/rust-libp2p/pull/3374 [PR 3375]: https://github.com/libp2p/rust-libp2p/pull/3375 +[PR 3254]: https://github.com/libp2p/rust-libp2p/pull/3254 # 0.41.1 From 2efe07360a86e814651df6f9758e203d86d29fa4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 31 Jan 2023 14:49:16 +1100 Subject: [PATCH 142/177] Add footnote --- swarm/CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 67e07c80c8f..5b367bf99e6 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -34,7 +34,7 @@ See [PR 3328]. - Allow `NetworkBehaviour`s to manage connections. - We deprecate `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` in favor of four new callbacks: + We deprecate[^1] `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` in favor of four new callbacks: - `NetworkBehaviour::handle_pending_inbound_connection` - `NetworkBehaviour::handle_pending_outbound_connection` @@ -51,6 +51,10 @@ See [PR 3254]. + [^1]: Please note that due to limitations in the Rust compiler, + _implementations_ of `new_handler` and `addresses_of_peer` are not flagged as deprecated. + Nevertheless, they will be removed in the future. + - Update to `libp2p-core` `v0.39.0`. - Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170]. From 916fe574c21bb8c7b869430664a6d977af4a9403 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 31 Jan 2023 14:50:57 +1100 Subject: [PATCH 143/177] Don't use footnotes --- swarm/CHANGELOG.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 5b367bf99e6..2fe8758b9c1 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -34,13 +34,16 @@ See [PR 3328]. - Allow `NetworkBehaviour`s to manage connections. - We deprecate[^1] `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` in favor of four new callbacks: + We deprecate `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` in favor of four new callbacks: - `NetworkBehaviour::handle_pending_inbound_connection` - `NetworkBehaviour::handle_pending_outbound_connection` - `NetworkBehaviour::handle_established_inbound_connection` - `NetworkBehaviour::handle_established_outbound_connection` - + + Please note that due to limitations in the Rust compiler, _implementations_ of `new_handler` and `addresses_of_peer` are not flagged as deprecated. + Nevertheless, they will be removed in the future. + All four are fallible and returning an error from any of them will abort the given connection. This allows you to create dedicated `NetworkBehaviour`s that only concern themselves with managing connections. For example: @@ -51,10 +54,6 @@ See [PR 3254]. - [^1]: Please note that due to limitations in the Rust compiler, - _implementations_ of `new_handler` and `addresses_of_peer` are not flagged as deprecated. - Nevertheless, they will be removed in the future. - - Update to `libp2p-core` `v0.39.0`. - Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170]. From 3ecd62359a366d8d310286a97d228e84fd8d484e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 10 Feb 2023 19:16:17 +1300 Subject: [PATCH 144/177] Inline `spawn` function --- swarm/src/connection/pool.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 3e04b058165..36b26860e3b 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -403,10 +403,6 @@ where pub fn iter_connected(&self) -> impl Iterator { self.established.keys() } - - fn spawn(&mut self, task: BoxFuture<'static, ()>) { - self.executor.spawn(task) - } } impl Pool @@ -443,7 +439,7 @@ where let (abort_notifier, abort_receiver) = oneshot::channel(); - self.spawn( + self.executor.spawn( task::new_for_pending_outgoing_connection( connection_id, dial, @@ -489,7 +485,7 @@ where let (abort_notifier, abort_receiver) = oneshot::channel(); - self.spawn( + self.executor.spawn( task::new_for_pending_incoming_connection( connection_id, future, @@ -545,7 +541,7 @@ where self.max_negotiating_inbound_streams, ); - self.spawn( + self.executor.spawn( task::new_for_established_connection( id, obtained_peer_id, @@ -554,7 +550,7 @@ where event_sender, ) .boxed(), - ); + ) } /// Polls the connection pool for events. @@ -724,7 +720,7 @@ where }); if let Err(error) = error { - self.spawn( + self.executor.spawn( poll_fn(move |cx| { if let Err(e) = ready!(muxer.poll_close_unpin(cx)) { log::debug!( From 02cbf4288d4c7d32ecd3507cc53eab7f1703a4db Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 10 Feb 2023 19:19:50 +1300 Subject: [PATCH 145/177] Box future inside `spawn` --- swarm/src/connection/pool.rs | 62 ++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 36b26860e3b..0c482a3ac12 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -71,7 +71,9 @@ impl ExecSwitch { } } - fn spawn(&mut self, task: BoxFuture<'static, ()>) { + fn spawn(&mut self, task: impl Future + Send + 'static) { + let task = task.boxed(); + match self { Self::Executor(executor) => executor.exec(task), Self::LocalSpawn(local) => local.push(task), @@ -439,15 +441,13 @@ where let (abort_notifier, abort_receiver) = oneshot::channel(); - self.executor.spawn( - task::new_for_pending_outgoing_connection( + self.executor + .spawn(task::new_for_pending_outgoing_connection( connection_id, dial, abort_receiver, self.pending_connection_events_tx.clone(), - ) - .boxed(), - ); + )); let endpoint = PendingPoint::Dialer { role_override }; @@ -485,15 +485,13 @@ where let (abort_notifier, abort_receiver) = oneshot::channel(); - self.executor.spawn( - task::new_for_pending_incoming_connection( + self.executor + .spawn(task::new_for_pending_incoming_connection( connection_id, future, abort_receiver, self.pending_connection_events_tx.clone(), - ) - .boxed(), - ); + )); self.counters.inc_pending_incoming(); self.pending.insert( @@ -541,16 +539,13 @@ where self.max_negotiating_inbound_streams, ); - self.executor.spawn( - task::new_for_established_connection( - id, - obtained_peer_id, - connection, - command_receiver, - event_sender, - ) - .boxed(), - ) + self.executor.spawn(task::new_for_established_connection( + id, + obtained_peer_id, + connection, + command_receiver, + event_sender, + )) } /// Polls the connection pool for events. @@ -720,20 +715,17 @@ where }); if let Err(error) = error { - self.executor.spawn( - poll_fn(move |cx| { - if let Err(e) = ready!(muxer.poll_close_unpin(cx)) { - log::debug!( - "Failed to close connection {:?} to peer {}: {:?}", - id, - obtained_peer_id, - e - ); - } - Poll::Ready(()) - }) - .boxed(), - ); + self.executor.spawn(poll_fn(move |cx| { + if let Err(e) = ready!(muxer.poll_close_unpin(cx)) { + log::debug!( + "Failed to close connection {:?} to peer {}: {:?}", + id, + obtained_peer_id, + e + ); + } + Poll::Ready(()) + })); match endpoint { ConnectedPoint::Dialer { .. } => { From 1c906db93c28577ef9762fe0a6aa01f0cc543963 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 10 Feb 2023 19:20:59 +1300 Subject: [PATCH 146/177] Merge impl blocks --- swarm/src/connection/pool.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 0c482a3ac12..74f0eab557f 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -405,12 +405,7 @@ where pub fn iter_connected(&self) -> impl Iterator { self.established.keys() } -} -impl Pool -where - THandler: IntoConnectionHandler, -{ /// Adds a pending outgoing connection to the pool in the form of a `Future` /// that establishes and negotiates the connection. /// From 87cf5fd5481c5f444411dba77b0f22b132ff5c3a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 10 Feb 2023 19:22:53 +1300 Subject: [PATCH 147/177] Gracefully close connection to banned peer --- swarm/src/connection/pool.rs | 4 ++++ swarm/src/lib.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 74f0eab557f..28e98968e20 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -543,6 +543,10 @@ where )) } + pub fn close_connection(&mut self, muxer: StreamMuxerBox) { + self.executor.spawn(muxer.close()); + } + /// Polls the connection pool for events. pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> where diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ec8e27a9196..f2cacec67ff 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -756,7 +756,7 @@ where established_in, } => { if self.banned_peers.contains(&peer_id) { - self.pool.disconnect(peer_id); + self.pool.close_connection(connection); return Some(SwarmEvent::BannedPeer { peer_id, endpoint }); } From e74ea6747fbd8e95d1c71c60da04ed86fa2c793e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 10 Feb 2023 20:34:04 +1300 Subject: [PATCH 148/177] Ensure new connections are either spawned or gracefully closed --- swarm/src/connection/pool.rs | 74 ++++++++++++++++++++++++++++++++---- swarm/src/lib.rs | 1 - 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 259b8ad3bff..8d80a8f7870 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -133,6 +133,9 @@ where /// Receivers for events reported from established connections. established_connection_events: SelectAll>>, + + /// Receivers for [`NewConnection`] objects that are dropped. + new_connection_dropped_listeners: FuturesUnordered>, } #[derive(Debug)] @@ -223,7 +226,7 @@ pub enum PoolEvent { id: ConnectionId, peer_id: PeerId, endpoint: ConnectedPoint, - connection: StreamMuxerBox, + connection: NewConnection, /// [`Some`] when the new connection is an outgoing connection. /// Addresses are dialed in parallel. Contains the addresses and errors /// of dial attempts that failed before the one successful dial. @@ -322,6 +325,7 @@ where pending_connection_events_rx, no_established_connections_waker: None, established_connection_events: Default::default(), + new_connection_dropped_listeners: Default::default(), } } @@ -500,9 +504,11 @@ where id: ConnectionId, obtained_peer_id: PeerId, endpoint: &ConnectedPoint, - muxer: StreamMuxerBox, + connection: NewConnection, handler: ::Handler, ) { + let connection = connection.extract(); + let conns = self.established.entry(obtained_peer_id).or_default(); self.counters.inc_established(endpoint); @@ -522,7 +528,7 @@ where } let connection = Connection::new( - muxer, + connection, handler, self.substream_upgrade_protocol_override, self.max_negotiating_inbound_streams, @@ -537,10 +543,6 @@ where )) } - pub fn close_connection(&mut self, muxer: StreamMuxerBox) { - self.executor.spawn(muxer.close()); - } - /// Polls the connection pool for events. pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll> where @@ -613,6 +615,17 @@ where // Poll for events of pending connections. loop { + if let Poll::Ready(Some(result)) = + self.new_connection_dropped_listeners.poll_next_unpin(cx) + { + if let Ok(dropped_connection) = result { + self.executor.spawn(async move { + let _ = dropped_connection.close().await; + }); + } + continue; + } + let event = match self.pending_connection_events_rx.poll_next_unpin(cx) { Poll::Ready(Some(event)) => event, Poll::Pending => break, @@ -744,11 +757,14 @@ where let established_in = accepted_at.elapsed(); + let (connection, drop_listener) = NewConnection::new(muxer); + self.new_connection_dropped_listeners.push(drop_listener); + return Poll::Ready(PoolEvent::ConnectionEstablished { peer_id: obtained_peer_id, endpoint, id, - connection: muxer, + connection, concurrent_dial_errors, established_in, }); @@ -803,6 +819,48 @@ where } } +/// Opaque type for a new connection. +/// +/// This connection has just been established but isn't part of the [`Pool`] yet. +/// It either needs to be spawned via [`Pool::spawn_connection`] or dropped if undesired. +/// +/// On drop, this type send the connection back to the [`Pool`] where it will be gracefully closed. +#[derive(Debug)] +pub struct NewConnection { + connection: Option, + drop_sender: Option>, +} + +impl NewConnection { + fn new(conn: StreamMuxerBox) -> (Self, oneshot::Receiver) { + let (sender, receiver) = oneshot::channel(); + + ( + Self { + connection: Some(conn), + drop_sender: Some(sender), + }, + receiver, + ) + } + + fn extract(mut self) -> StreamMuxerBox { + self.connection.take().unwrap() + } +} + +impl Drop for NewConnection { + fn drop(&mut self) { + if let Some(connection) = self.connection.take() { + let _ = self + .drop_sender + .take() + .expect("`drop_sender` to always be `Some`") + .send(connection); + } + } +} + /// Network connection information. #[derive(Debug, Clone)] pub struct ConnectionCounters { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 185da6db87f..27dba808606 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -784,7 +784,6 @@ where established_in, } => { if self.banned_peers.contains(&peer_id) { - self.pool.close_connection(connection); return Some(SwarmEvent::BannedPeer { peer_id, endpoint }); } From f20485908d38da288b193e0b4f0fde08b4648339 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 10 Feb 2023 20:40:11 +1300 Subject: [PATCH 149/177] Ignore error when closing connection --- swarm/src/connection/pool.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 28e98968e20..ed132accc3e 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -544,7 +544,9 @@ where } pub fn close_connection(&mut self, muxer: StreamMuxerBox) { - self.executor.spawn(muxer.close()); + self.executor.spawn(async move { + let _ = muxer.close().await; + }); } /// Polls the connection pool for events. From fb93cd654e7d769832f2c650b04b66053d90f363 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 16 Feb 2023 18:44:35 +1300 Subject: [PATCH 150/177] Fix compile error --- protocols/dcutr/src/behaviour_impl.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index d0ca3331052..9dde9d965ef 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -405,7 +405,7 @@ impl NetworkBehaviour for Behaviour { self.queued_events .push_back(NetworkBehaviourAction::Dial { opts }); } - Either::Right(handler::direct::Event::DirectConnectionEstablished) => { + Either::Right(Either::Left(handler::direct::Event::DirectConnectionEstablished)) => { self.queued_events.extend([ NetworkBehaviourAction::NotifyHandler { peer_id: event_source, From 82e3acaf6e9fd5610876095d77ad21f718899496 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 21 Feb 2023 12:48:28 +1300 Subject: [PATCH 151/177] Restore `IntoEitherHandler` --- swarm/src/handler/either.rs | 65 ++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index e66c3549824..a10dbc0313d 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -18,6 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#[allow(deprecated)] +use crate::handler::IntoConnectionHandler; use crate::handler::{ ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, FullyNegotiatedInbound, InboundUpgradeSend, KeepAlive, ListenUpgradeError, SubstreamProtocol, @@ -26,9 +28,70 @@ use crate::upgrade::SendWrapper; use crate::ConnectionHandlerUpgrErr; use either::Either; use futures::future; -use libp2p_core::UpgradeError; +use libp2p_core::{ConnectedPoint, PeerId, UpgradeError}; 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), +} + +/// Implementation of a [`IntoConnectionHandler`] that represents either of two [`IntoConnectionHandler`] +/// implementations. +#[allow(deprecated)] +impl IntoConnectionHandler for IntoEitherHandler +where + L: IntoConnectionHandler, + R: IntoConnectionHandler, +{ + type Handler = Either; + + fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler { + match self { + IntoEitherHandler::Left(into_handler) => Either::Left(into_handler.into_handler(p, c)), + IntoEitherHandler::Right(into_handler) => { + Either::Right(into_handler.into_handler(p, c)) + } + } + } + + fn inbound_protocol(&self) -> ::InboundProtocol { + match self { + IntoEitherHandler::Left(into_handler) => { + Either::Left(SendWrapper(into_handler.inbound_protocol())) + } + IntoEitherHandler::Right(into_handler) => { + Either::Right(SendWrapper(into_handler.inbound_protocol())) + } + } + } +} + +// 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.",) + } + } + } +} + impl FullyNegotiatedInbound, SendWrapper>, Either> where From 2a44198dbc00e9cda3555ff75625bf76dea9fe87 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 21 Feb 2023 12:49:30 +1300 Subject: [PATCH 152/177] Don't underscore used variable --- protocols/dcutr/src/behaviour_impl.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 9dde9d965ef..f8edc5930f3 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -247,14 +247,14 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - _connection_id: ConnectionId, + connection_id: ConnectionId, peer: PeerId, local_addr: &Multiaddr, remote_addr: &Multiaddr, ) -> Result, ConnectionDenied> { match self .outgoing_direct_connection_attempts - .remove(&(_connection_id, peer)) + .remove(&(connection_id, peer)) { None => { let handler = if is_relayed(local_addr) { @@ -283,14 +283,14 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, - _connection_id: ConnectionId, + connection_id: ConnectionId, peer: PeerId, addr: &Multiaddr, role_override: Endpoint, ) -> Result, ConnectionDenied> { match self .outgoing_direct_connection_attempts - .remove(&(_connection_id, peer)) + .remove(&(connection_id, peer)) { None => { let handler = if is_relayed(addr) { From 7bae092be0c1944e73099e710c7b8422727f1f17 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 21 Feb 2023 13:08:34 +1300 Subject: [PATCH 153/177] Undo merge conflicts with #3465 --- swarm/src/lib.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 27dba808606..1a39625ad29 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -2037,8 +2037,10 @@ mod tests { /// calls should be registered. #[test] fn test_connect_disconnect_ban() { + let _ = env_logger::try_init(); + // Since the test does not try to open any substreams, we can - // use the dummy protocols handler. + // use keep alive protocols handler. let handler_proto = keep_alive::ConnectionHandler; let mut swarm1 = new_test_swarm::<_, ()>(handler_proto.clone()).build(); @@ -2052,6 +2054,7 @@ mod tests { let swarm1_id = *swarm1.local_peer_id(); + #[derive(Debug)] enum Stage { /// Waiting for the peers to connect. Banning has not occurred. Connecting, @@ -2096,12 +2099,15 @@ mod tests { { // Setup to test that new connections of banned peers are not reported. swarm1.dial(addr2.clone()).unwrap(); + s1_expected_conns += 1; stage = Stage::BannedDial; } } Stage::BannedDial => { - // The banned connection was established. Check that it was not reported to - // the behaviour of the banning swarm. + if swarm1.behaviour.assert_disconnected(s1_expected_conns, 2) { + // The banned connection was established. Given the ban, swarm2 closed the + // connection. Check that it was not reported to the behaviour of the + // banning swarm. assert_eq!( swarm2.behaviour.on_connection_established.len(), s2_expected_conns, @@ -2113,8 +2119,11 @@ mod tests { swarm2.unban_peer_id(swarm1_id); stage = Stage::Unbanned; } + } Stage::Unbanned => { - if swarm2.network_info().num_peers() == 0 { + if swarm1.network_info().num_peers() == 0 + && swarm2.network_info().num_peers() == 0 + { // The banned connection has closed. Check that it was not reported. assert_eq!( swarm2.behaviour.on_connection_closed.len(), s2_expected_conns, From 0ca08c19f868cebeafa691bae199f5682308a470 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 21 Feb 2023 13:23:08 +1300 Subject: [PATCH 154/177] Call out limitations in Rust compiler --- CHANGELOG.md | 5 +++++ swarm/CHANGELOG.md | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20fe3de71af..81da8bb3861 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,11 @@ # 0.51.0 [unreleased] +- Enable `NetworkBehaviour`s to manage connections. + This deprecates `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer`. + Due to limitations in the Rust compiler, these deprecations may not show up for you, nevertheless they will be removed in a future release. + See [`libp2p-swarm`'s CHANGELOG](swarm/CHANGELOG.md#0420) for details. + - Count bandwidth at the application level. Previously `BandwidthLogging` would implement `Transport` and now implements `StreamMuxer` ([PR 3180](https://github.com/libp2p/rust-libp2p/pull/3180)). - `BandwidthLogging::new` now requires a 2nd argument: `Arc` - Remove `BandwidthFuture` diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 2fe8758b9c1..20c4e10598d 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -41,7 +41,7 @@ - `NetworkBehaviour::handle_established_inbound_connection` - `NetworkBehaviour::handle_established_outbound_connection` - Please note that due to limitations in the Rust compiler, _implementations_ of `new_handler` and `addresses_of_peer` are not flagged as deprecated. + Please note that due to [limitations](https://github.com/rust-lang/rust/issues/98990) in the Rust compiler, _implementations_ of `new_handler` and `addresses_of_peer` are not flagged as deprecated. Nevertheless, they will be removed in the future. All four are fallible and returning an error from any of them will abort the given connection. From dd4e374e3ea523afa9a4374e579f1ae60bed3ddd Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 21 Feb 2023 13:23:28 +1300 Subject: [PATCH 155/177] Move manage conn entry to top of changelog This one is more important. --- swarm/CHANGELOG.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 20c4e10598d..ffab8811cbd 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,5 +1,26 @@ # 0.42.0 [unreleased] +- Allow `NetworkBehaviour`s to manage connections. + We deprecate `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` in favor of four new callbacks: + + - `NetworkBehaviour::handle_pending_inbound_connection` + - `NetworkBehaviour::handle_pending_outbound_connection` + - `NetworkBehaviour::handle_established_inbound_connection` + - `NetworkBehaviour::handle_established_outbound_connection` + + Please note that due to [limitations](https://github.com/rust-lang/rust/issues/98990) in the Rust compiler, _implementations_ of `new_handler` and `addresses_of_peer` are not flagged as deprecated. + Nevertheless, they will be removed in the future. + + All four are fallible and returning an error from any of them will abort the given connection. + This allows you to create dedicated `NetworkBehaviour`s that only concern themselves with managing connections. + For example: + - checking the `PeerId` of a newly established connection against an allow/block list + - only allowing X connection upgrades at any one time + - denying incoming or outgoing connections from a certain IP range + - only allowing N connections to or from the same peer + + See [PR 3254]. + - Remove `handler` field from `NetworkBehaviourAction::Dial`. Instead of constructing the handler early, you can now access the `ConnectionId` of the future connection on `DialOpts`. `ConnectionId`s are `Copy` and will be used throughout the entire lifetime of the connection to report events. @@ -33,27 +54,6 @@ See [PR 3328]. -- Allow `NetworkBehaviour`s to manage connections. - We deprecate `NetworkBehaviour::new_handler` and `NetworkBehaviour::addresses_of_peer` in favor of four new callbacks: - - - `NetworkBehaviour::handle_pending_inbound_connection` - - `NetworkBehaviour::handle_pending_outbound_connection` - - `NetworkBehaviour::handle_established_inbound_connection` - - `NetworkBehaviour::handle_established_outbound_connection` - - Please note that due to [limitations](https://github.com/rust-lang/rust/issues/98990) in the Rust compiler, _implementations_ of `new_handler` and `addresses_of_peer` are not flagged as deprecated. - Nevertheless, they will be removed in the future. - - All four are fallible and returning an error from any of them will abort the given connection. - This allows you to create dedicated `NetworkBehaviour`s that only concern themselves with managing connections. - For example: - - checking the `PeerId` of a newly established connection against an allow/block list - - only allowing X connection upgrades at any one time - - denying incoming or outgoing connections from a certain IP range - - only allowing N connections to or from the same peer - - See [PR 3254]. - - Update to `libp2p-core` `v0.39.0`. - Removed deprecated Swarm constructors. For transition notes see [0.41.0](#0.41.0). See [PR 3170]. From 392b0d2110873a97e9906259591815981887a4ec Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 21 Feb 2023 14:09:57 +1300 Subject: [PATCH 156/177] Fix fmt --- swarm/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 1a39625ad29..c9f6bd64257 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -2108,17 +2108,17 @@ mod tests { // The banned connection was established. Given the ban, swarm2 closed the // connection. Check that it was not reported to the behaviour of the // banning swarm. - assert_eq!( + assert_eq!( swarm2.behaviour.on_connection_established.len(), s2_expected_conns, "No additional closed connections should be reported for the banned peer" ); - // Setup to test that the banned connection is not reported upon closing - // even if the peer is unbanned. - swarm2.unban_peer_id(swarm1_id); - stage = Stage::Unbanned; - } + // Setup to test that the banned connection is not reported upon closing + // even if the peer is unbanned. + swarm2.unban_peer_id(swarm1_id); + stage = Stage::Unbanned; + } } Stage::Unbanned => { if swarm1.network_info().num_peers() == 0 From 891005632588f03fd34978bce66ba4046c440672 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 23 Feb 2023 10:20:07 +1100 Subject: [PATCH 157/177] Add license header --- swarm/src/connection_limits.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index 839867eec38..c6df1c76bbc 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -1,3 +1,23 @@ +// Copyright 2023 Protocol Labs. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + use crate::{ dummy, ConnectionClosed, ConnectionDenied, ConnectionId, ConnectionLimit, ConnectionLimits, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, From 01026accfac9a86cfd89164a044602117fc9d4ad Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 23 Feb 2023 10:20:57 +1100 Subject: [PATCH 158/177] Fix compile errors --- swarm/src/connection_limits.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index c6df1c76bbc..ec7e4044db5 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -84,8 +84,8 @@ impl NetworkBehaviour for Behaviour { fn handle_established_inbound_connection( &mut self, - peer: PeerId, connection_id: ConnectionId, + peer: PeerId, _: &Multiaddr, _: &Multiaddr, ) -> Result, ConnectionDenied> { @@ -119,10 +119,10 @@ impl NetworkBehaviour for Behaviour { fn handle_pending_outbound_connection( &mut self, + connection_id: ConnectionId, _: Option, _: &[Multiaddr], _: Endpoint, - connection_id: ConnectionId, ) -> Result, ConnectionDenied> { self.check_limit( self.limits.max_pending_outgoing, @@ -136,10 +136,10 @@ impl NetworkBehaviour for Behaviour { fn handle_established_outbound_connection( &mut self, + connection_id: ConnectionId, peer: PeerId, _: &Multiaddr, _: Endpoint, - connection_id: ConnectionId, ) -> Result, ConnectionDenied> { self.pending_outbound_connections.remove(&connection_id); From 2bc8d85ff3e077be31f1c61832a09896e1c01d22 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 23 Feb 2023 10:44:49 +1100 Subject: [PATCH 159/177] Port tests --- swarm/src/connection/pool.rs | 1 + swarm/src/connection_limits.rs | 208 ++++++++++++++++++++++++++++++++- swarm/src/lib.rs | 188 ++++------------------------- 3 files changed, 228 insertions(+), 169 deletions(-) diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index f36f813e1f9..155b35fcdb0 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -888,6 +888,7 @@ impl ConnectionCounters { } /// The effective connection limits. + #[deprecated(note = "Use the `connection_limits::Behaviour` instead.")] pub fn limits(&self) -> &ConnectionLimits { &self.limits } diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index ec7e4044db5..3d9d68d4505 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -54,7 +54,7 @@ impl Behaviour { let limit = limit.unwrap_or(u32::MAX); let current = current as u32; - if current > limit { + if current >= limit { return Err(ConnectionDenied::new(ConnectionLimit { limit, current })); } @@ -214,3 +214,209 @@ impl NetworkBehaviour for Behaviour { Poll::Pending } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{DialError, DialOpts, ListenError, Swarm, SwarmEvent}; + use futures::ready; + use futures::future; + use futures::StreamExt; + use libp2p_core::{identity, multiaddr::multiaddr, transport, upgrade, Transport}; + use libp2p_plaintext as plaintext; + use libp2p_yamux as yamux; + use quickcheck::*; + + #[test] + fn max_outgoing() { + use rand::Rng; + + let outgoing_limit = rand::thread_rng().gen_range(1..10); + + let mut network = + new_swarm(ConnectionLimits::default().with_max_pending_outgoing(Some(outgoing_limit))); + + let addr: Multiaddr = "/memory/1234".parse().unwrap(); + + let target = PeerId::random(); + for _ in 0..outgoing_limit { + network + .dial( + DialOpts::peer_id(target) + .addresses(vec![addr.clone()]) + .build(), + ) + .expect("Unexpected connection limit."); + } + + match network + .dial(DialOpts::peer_id(target).addresses(vec![addr]).build()) + .expect_err("Unexpected dialing success.") + { + DialError::Denied { cause } => { + let limit = cause + .downcast::() + .expect("connection denied because of limit"); + + assert_eq!(limit.current, outgoing_limit); + assert_eq!(limit.limit, outgoing_limit); + } + e => panic!("Unexpected error: {e:?}"), + } + + let info = network.network_info(); + assert_eq!(info.num_peers(), 0); + assert_eq!( + info.connection_counters().num_pending_outgoing(), + outgoing_limit + ); + } + + #[test] + fn max_established_incoming() { + #[derive(Debug, Clone)] + struct Limit(u32); + + impl Arbitrary for Limit { + fn arbitrary(g: &mut Gen) -> Self { + Self(g.gen_range(1..10)) + } + } + + fn limits(limit: u32) -> ConnectionLimits { + ConnectionLimits::default().with_max_established_incoming(Some(limit)) + } + + fn prop(limit: Limit) { + let limit = limit.0; + + let mut network1 = new_swarm(limits(limit)); + let mut network2 = new_swarm(limits(limit)); + + let _ = network1.listen_on(multiaddr![Memory(0u64)]).unwrap(); + let listen_addr = async_std::task::block_on(future::poll_fn(|cx| { + match ready!(network1.poll_next_unpin(cx)).unwrap() { + SwarmEvent::NewListenAddr { address, .. } => Poll::Ready(address), + e => panic!("Unexpected network event: {e:?}"), + } + })); + + // Spawn and block on the dialer. + async_std::task::block_on({ + let mut n = 0; + network2.dial(listen_addr.clone()).unwrap(); + + let mut expected_closed = false; + let mut network_1_established = false; + let mut network_2_established = false; + let mut network_1_limit_reached = false; + let mut network_2_limit_reached = false; + future::poll_fn(move |cx| { + loop { + let mut network_1_pending = false; + let mut network_2_pending = false; + + match network1.poll_next_unpin(cx) { + Poll::Ready(Some(SwarmEvent::IncomingConnection { .. })) => {} + Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { + network_1_established = true; + } + Poll::Ready(Some(SwarmEvent::IncomingConnectionError { + error: ListenError::Denied { cause }, + .. + })) => { + let err = cause + .downcast::() + .expect("connection denied because of limit"); + + assert_eq!(err.limit, limit); + assert_eq!(err.limit, err.current); + let info = network1.network_info(); + let counters = info.connection_counters(); + assert_eq!(counters.num_established_incoming(), limit); + assert_eq!(counters.num_established(), limit); + network_1_limit_reached = true; + } + Poll::Pending => { + network_1_pending = true; + } + e => panic!("Unexpected network event: {e:?}"), + } + + match network2.poll_next_unpin(cx) { + Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { + network_2_established = true; + } + Poll::Ready(Some(SwarmEvent::ConnectionClosed { .. })) => { + assert!(expected_closed); + let info = network2.network_info(); + let counters = info.connection_counters(); + assert_eq!(counters.num_established_outgoing(), limit); + assert_eq!(counters.num_established(), limit); + network_2_limit_reached = true; + } + Poll::Pending => { + network_2_pending = true; + } + e => panic!("Unexpected network event: {e:?}"), + } + + if network_1_pending && network_2_pending { + return Poll::Pending; + } + + if network_1_established && network_2_established { + network_1_established = false; + network_2_established = false; + + if n <= limit { + // Dial again until the limit is exceeded. + n += 1; + network2.dial(listen_addr.clone()).unwrap(); + + if n == limit { + // The the next dialing attempt exceeds the limit, this + // is the connection we expected to get closed. + expected_closed = true; + } + } else { + panic!("Expect networks not to establish connections beyond the limit.") + } + } + + if network_1_limit_reached && network_2_limit_reached { + return Poll::Ready(()); + } + } + }) + }); + } + + quickcheck(prop as fn(_)); + } + + fn new_swarm(limits: ConnectionLimits) -> Swarm { + let id_keys = identity::Keypair::generate_ed25519(); + let local_public_key = id_keys.public(); + let transport = transport::MemoryTransport::default() + .upgrade(upgrade::Version::V1) + .authenticate(plaintext::PlainText2Config { + local_public_key: local_public_key.clone(), + }) + .multiplex(yamux::YamuxConfig::default()) + .boxed(); + let behaviour = Behaviour { + limits: super::Behaviour::new(limits), + keep_alive: crate::keep_alive::Behaviour, + }; + + Swarm::without_executor(transport, behaviour, local_public_key.to_peer_id()) + } + + #[derive(libp2p_swarm_derive::NetworkBehaviour)] + #[behaviour(prelude = "crate::derive_prelude")] + struct Behaviour { + limits: crate::connection_limits::Behaviour, + keep_alive: crate::keep_alive::Behaviour, + } +} diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index e589535175d..bf92d37cff1 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1872,6 +1872,25 @@ impl ConnectionDenied { inner: Box::new(cause), } } + + /// Checks if the connection was denied for the specified (typed) reason. + pub fn is(&self) -> bool + where + T: error::Error + 'static, + { + ::is::(self) + } + + /// Downcast to the specified type `T`. + pub fn downcast(self) -> Result + where + T: error::Error + 'static, + { + let inner = ::downcast::(self.inner) + .map_err(|inner| ConnectionDenied { inner })?; + + Ok(*inner) + } } impl fmt::Display for ConnectionDenied { @@ -1941,8 +1960,7 @@ mod tests { use either::Either; use futures::executor::block_on; use futures::executor::ThreadPool; - use futures::future::poll_fn; - use futures::{executor, future, ready}; + use futures::{executor, future}; use libp2p_core::multiaddr::multiaddr; use libp2p_core::transport::memory::MemoryTransportError; use libp2p_core::transport::TransportEvent; @@ -2441,172 +2459,6 @@ mod tests { QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _); } - #[test] - fn max_outgoing() { - use rand::Rng; - - let outgoing_limit = rand::thread_rng().gen_range(1..10); - - let limits = ConnectionLimits::default().with_max_pending_outgoing(Some(outgoing_limit)); - let mut network = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) - .connection_limits(limits) - .build(); - - let addr: Multiaddr = "/memory/1234".parse().unwrap(); - - let target = PeerId::random(); - for _ in 0..outgoing_limit { - network - .dial( - DialOpts::peer_id(target) - .addresses(vec![addr.clone()]) - .build(), - ) - .expect("Unexpected connection limit."); - } - - match network - .dial(DialOpts::peer_id(target).addresses(vec![addr]).build()) - .expect_err("Unexpected dialing success.") - { - DialError::ConnectionLimit(limit) => { - assert_eq!(limit.current, outgoing_limit); - assert_eq!(limit.limit, outgoing_limit); - } - e => panic!("Unexpected error: {e:?}"), - } - - let info = network.network_info(); - assert_eq!(info.num_peers(), 0); - assert_eq!( - info.connection_counters().num_pending_outgoing(), - outgoing_limit - ); - } - - #[test] - fn max_established_incoming() { - #[derive(Debug, Clone)] - struct Limit(u32); - - impl Arbitrary for Limit { - fn arbitrary(g: &mut Gen) -> Self { - Self(g.gen_range(1..10)) - } - } - - fn limits(limit: u32) -> ConnectionLimits { - ConnectionLimits::default().with_max_established_incoming(Some(limit)) - } - - fn prop(limit: Limit) { - let limit = limit.0; - - let mut network1 = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) - .connection_limits(limits(limit)) - .build(); - let mut network2 = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) - .connection_limits(limits(limit)) - .build(); - - let _ = network1.listen_on(multiaddr![Memory(0u64)]).unwrap(); - let listen_addr = async_std::task::block_on(poll_fn(|cx| { - match ready!(network1.poll_next_unpin(cx)).unwrap() { - SwarmEvent::NewListenAddr { address, .. } => Poll::Ready(address), - e => panic!("Unexpected network event: {e:?}"), - } - })); - - // Spawn and block on the dialer. - async_std::task::block_on({ - let mut n = 0; - network2.dial(listen_addr.clone()).unwrap(); - - let mut expected_closed = false; - let mut network_1_established = false; - let mut network_2_established = false; - let mut network_1_limit_reached = false; - let mut network_2_limit_reached = false; - poll_fn(move |cx| { - loop { - let mut network_1_pending = false; - let mut network_2_pending = false; - - match network1.poll_next_unpin(cx) { - Poll::Ready(Some(SwarmEvent::IncomingConnection { .. })) => {} - Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { - network_1_established = true; - } - Poll::Ready(Some(SwarmEvent::IncomingConnectionError { - error: ListenError::ConnectionLimit(err), - .. - })) => { - assert_eq!(err.limit, limit); - assert_eq!(err.limit, err.current); - let info = network1.network_info(); - let counters = info.connection_counters(); - assert_eq!(counters.num_established_incoming(), limit); - assert_eq!(counters.num_established(), limit); - network_1_limit_reached = true; - } - Poll::Pending => { - network_1_pending = true; - } - e => panic!("Unexpected network event: {e:?}"), - } - - match network2.poll_next_unpin(cx) { - Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { - network_2_established = true; - } - Poll::Ready(Some(SwarmEvent::ConnectionClosed { .. })) => { - assert!(expected_closed); - let info = network2.network_info(); - let counters = info.connection_counters(); - assert_eq!(counters.num_established_outgoing(), limit); - assert_eq!(counters.num_established(), limit); - network_2_limit_reached = true; - } - Poll::Pending => { - network_2_pending = true; - } - e => panic!("Unexpected network event: {e:?}"), - } - - if network_1_pending && network_2_pending { - return Poll::Pending; - } - - if network_1_established && network_2_established { - network_1_established = false; - network_2_established = false; - - if n <= limit { - // Dial again until the limit is exceeded. - n += 1; - network2.dial(listen_addr.clone()).unwrap(); - - if n == limit { - // The the next dialing attempt exceeds the limit, this - // is the connection we expected to get closed. - expected_closed = true; - } - } else { - panic!("Expect networks not to establish connections beyond the limit.") - } - } - - if network_1_limit_reached && network_2_limit_reached { - return Poll::Ready(()); - } - } - }) - }); - } - - quickcheck(prop as fn(_)); - } - #[test] fn invalid_peer_id() { // Checks whether dialing an address containing the wrong peer id raises an error From 56e9484c9be70c80e4d649cac5fca86c7d47292b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 23 Feb 2023 10:59:12 +1100 Subject: [PATCH 160/177] Restore old tests and deprecate more things --- misc/metrics/src/swarm.rs | 2 + protocols/kad/src/behaviour.rs | 3 +- swarm/src/connection/error.rs | 6 ++ swarm/src/connection/pool.rs | 2 + swarm/src/connection_limits.rs | 2 +- swarm/src/lib.rs | 188 ++++++++++++++++++++++++++++++++- 6 files changed, 200 insertions(+), 3 deletions(-) diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index ff19c650cd9..8f80c74d6ec 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -225,6 +225,7 @@ impl super::Recorder record(OutgoingConnectionError::Banned), + #[allow(deprecated)] libp2p_swarm::DialError::ConnectionLimit(_) => { record(OutgoingConnectionError::ConnectionLimit) } @@ -371,6 +372,7 @@ impl From<&libp2p_swarm::ListenError> for IncomingConnectionError { fn from(error: &libp2p_swarm::ListenError) -> Self { match error { libp2p_swarm::ListenError::WrongPeerId { .. } => IncomingConnectionError::WrongPeerId, + #[allow(deprecated)] libp2p_swarm::ListenError::ConnectionLimit(_) => { IncomingConnectionError::ConnectionLimit } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 9d3d9014538..76d089a76ca 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1923,7 +1923,6 @@ where match error { DialError::Banned - | DialError::ConnectionLimit(_) | DialError::LocalPeerId { .. } | DialError::InvalidPeerId { .. } | DialError::WrongPeerId { .. } @@ -1950,6 +1949,8 @@ where DialError::DialPeerConditionFalse(dial_opts::PeerCondition::Always) => { unreachable!("DialPeerCondition::Always can not trigger DialPeerConditionFalse."); } + #[allow(deprecated)] + DialError::ConnectionLimit(_) => {} } } diff --git a/swarm/src/connection/error.rs b/swarm/src/connection/error.rs index a5a6136f0b1..086572505b1 100644 --- a/swarm/src/connection/error.rs +++ b/swarm/src/connection/error.rs @@ -90,6 +90,9 @@ pub enum PendingConnectionError { /// The connection was dropped because the connection limit /// for a peer has been reached. + #[deprecated( + note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `{Dial,Listen}Error::Denied::cause`." + )] ConnectionLimit(ConnectionLimit), /// Pending connection attempt has been aborted. @@ -110,6 +113,7 @@ impl PendingConnectionError { pub fn map(self, f: impl FnOnce(T) -> U) -> PendingConnectionError { match self { PendingConnectionError::Transport(t) => PendingConnectionError::Transport(f(t)), + #[allow(deprecated)] PendingConnectionError::ConnectionLimit(l) => { PendingConnectionError::ConnectionLimit(l) } @@ -137,6 +141,7 @@ where "Pending connection: Transport error on connection: {err}" ) } + #[allow(deprecated)] PendingConnectionError::ConnectionLimit(l) => { write!(f, "Connection error: Connection limit: {l}.") } @@ -163,6 +168,7 @@ where PendingConnectionError::WrongPeerId { .. } => None, PendingConnectionError::LocalPeerId { .. } => None, PendingConnectionError::Aborted => None, + #[allow(deprecated)] PendingConnectionError::ConnectionLimit(..) => None, } } diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 155b35fcdb0..41f7e5155b3 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -679,6 +679,8 @@ where ), }; + #[allow(deprecated)] + // Remove once `PendingConnectionError::ConnectionLimit` is gone. let error = self .counters // Check general established connection limit. diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index 3d9d68d4505..659dfbeecf9 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -219,8 +219,8 @@ impl NetworkBehaviour for Behaviour { mod tests { use super::*; use crate::{DialError, DialOpts, ListenError, Swarm, SwarmEvent}; - use futures::ready; use futures::future; + use futures::ready; use futures::StreamExt; use libp2p_core::{identity, multiaddr::multiaddr, transport, upgrade, Transport}; use libp2p_plaintext as plaintext; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index bf92d37cff1..ee5818e60d0 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -631,6 +631,7 @@ where ) { Ok(()) => Ok(()), Err(connection_limit) => { + #[allow(deprecated)] let error = DialError::ConnectionLimit(connection_limit); self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { @@ -1069,6 +1070,7 @@ where }); } Err(connection_limit) => { + #[allow(deprecated)] let error = ListenError::ConnectionLimit(connection_limit); self.behaviour .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { @@ -1670,6 +1672,9 @@ pub enum DialError { Banned, /// The configured limit for simultaneous outgoing connections /// has been reached. + #[deprecated( + note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `DialError::Denied::cause`." + )] ConnectionLimit(ConnectionLimit), /// The peer identity obtained on the connection matches the local peer. LocalPeerId { @@ -1700,6 +1705,7 @@ pub enum DialError { impl From for DialError { fn from(error: PendingOutboundConnectionError) -> Self { match error { + #[allow(deprecated)] PendingConnectionError::ConnectionLimit(limit) => DialError::ConnectionLimit(limit), PendingConnectionError::Aborted => DialError::Aborted, PendingConnectionError::WrongPeerId { obtained, endpoint } => { @@ -1714,6 +1720,7 @@ impl From for DialError { impl fmt::Display for DialError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + #[allow(deprecated)] DialError::ConnectionLimit(err) => write!(f, "Dial error: {err}"), DialError::NoAddresses => write!(f, "Dial error: no addresses for peer."), DialError::LocalPeerId { endpoint } => write!( @@ -1767,6 +1774,7 @@ fn print_error_chain(f: &mut fmt::Formatter<'_>, e: &dyn error::Error) -> fmt::R impl error::Error for DialError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { + #[allow(deprecated)] DialError::ConnectionLimit(err) => Some(err), DialError::LocalPeerId { .. } => None, DialError::NoAddresses => None, @@ -1786,6 +1794,9 @@ impl error::Error for DialError { pub enum ListenError { /// The configured limit for simultaneous outgoing connections /// has been reached. + #[deprecated( + note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `ListenError::Denied::cause`." + )] ConnectionLimit(ConnectionLimit), /// Pending connection attempt has been aborted. Aborted, @@ -1809,6 +1820,7 @@ impl From for ListenError { fn from(error: PendingInboundConnectionError) -> Self { match error { PendingInboundConnectionError::Transport(inner) => ListenError::Transport(inner), + #[allow(deprecated)] PendingInboundConnectionError::ConnectionLimit(inner) => { ListenError::ConnectionLimit(inner) } @@ -1826,6 +1838,7 @@ impl From for ListenError { impl fmt::Display for ListenError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + #[allow(deprecated)] ListenError::ConnectionLimit(_) => write!(f, "Listen error"), ListenError::Aborted => write!( f, @@ -1851,6 +1864,7 @@ impl fmt::Display for ListenError { impl error::Error for ListenError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { + #[allow(deprecated)] ListenError::ConnectionLimit(err) => Some(err), ListenError::WrongPeerId { .. } => None, ListenError::Transport(err) => Some(err), @@ -1960,7 +1974,8 @@ mod tests { use either::Either; use futures::executor::block_on; use futures::executor::ThreadPool; - use futures::{executor, future}; + use futures::future::poll_fn; + use futures::{executor, future, ready}; use libp2p_core::multiaddr::multiaddr; use libp2p_core::transport::memory::MemoryTransportError; use libp2p_core::transport::TransportEvent; @@ -2459,6 +2474,177 @@ mod tests { QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _); } + #[test] + fn max_outgoing() { + use rand::Rng; + + let outgoing_limit = rand::thread_rng().gen_range(1..10); + + let limits = ConnectionLimits::default().with_max_pending_outgoing(Some(outgoing_limit)); + #[allow(deprecated)] + let mut network = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) + .connection_limits(limits) + .build(); + + let addr: Multiaddr = "/memory/1234".parse().unwrap(); + + let target = PeerId::random(); + for _ in 0..outgoing_limit { + network + .dial( + DialOpts::peer_id(target) + .addresses(vec![addr.clone()]) + .build(), + ) + .expect("Unexpected connection limit."); + } + + match network + .dial(DialOpts::peer_id(target).addresses(vec![addr]).build()) + .expect_err("Unexpected dialing success.") + { + #[allow(deprecated)] + DialError::ConnectionLimit(limit) => { + assert_eq!(limit.current, outgoing_limit); + assert_eq!(limit.limit, outgoing_limit); + } + e => panic!("Unexpected error: {e:?}"), + } + + let info = network.network_info(); + assert_eq!(info.num_peers(), 0); + assert_eq!( + info.connection_counters().num_pending_outgoing(), + outgoing_limit + ); + } + + #[test] + fn max_established_incoming() { + #[derive(Debug, Clone)] + struct Limit(u32); + + impl Arbitrary for Limit { + fn arbitrary(g: &mut Gen) -> Self { + Self(g.gen_range(1..10)) + } + } + + fn limits(limit: u32) -> ConnectionLimits { + ConnectionLimits::default().with_max_established_incoming(Some(limit)) + } + + fn prop(limit: Limit) { + let limit = limit.0; + + #[allow(deprecated)] + let mut network1 = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) + .connection_limits(limits(limit)) + .build(); + #[allow(deprecated)] + let mut network2 = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) + .connection_limits(limits(limit)) + .build(); + + let _ = network1.listen_on(multiaddr![Memory(0u64)]).unwrap(); + let listen_addr = async_std::task::block_on(poll_fn(|cx| { + match ready!(network1.poll_next_unpin(cx)).unwrap() { + SwarmEvent::NewListenAddr { address, .. } => Poll::Ready(address), + e => panic!("Unexpected network event: {e:?}"), + } + })); + + // Spawn and block on the dialer. + async_std::task::block_on({ + let mut n = 0; + network2.dial(listen_addr.clone()).unwrap(); + + let mut expected_closed = false; + let mut network_1_established = false; + let mut network_2_established = false; + let mut network_1_limit_reached = false; + let mut network_2_limit_reached = false; + poll_fn(move |cx| { + loop { + let mut network_1_pending = false; + let mut network_2_pending = false; + + match network1.poll_next_unpin(cx) { + Poll::Ready(Some(SwarmEvent::IncomingConnection { .. })) => {} + Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { + network_1_established = true; + } + #[allow(deprecated)] + Poll::Ready(Some(SwarmEvent::IncomingConnectionError { + error: ListenError::ConnectionLimit(err), + .. + })) => { + assert_eq!(err.limit, limit); + assert_eq!(err.limit, err.current); + let info = network1.network_info(); + let counters = info.connection_counters(); + assert_eq!(counters.num_established_incoming(), limit); + assert_eq!(counters.num_established(), limit); + network_1_limit_reached = true; + } + Poll::Pending => { + network_1_pending = true; + } + e => panic!("Unexpected network event: {e:?}"), + } + + match network2.poll_next_unpin(cx) { + Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { + network_2_established = true; + } + Poll::Ready(Some(SwarmEvent::ConnectionClosed { .. })) => { + assert!(expected_closed); + let info = network2.network_info(); + let counters = info.connection_counters(); + assert_eq!(counters.num_established_outgoing(), limit); + assert_eq!(counters.num_established(), limit); + network_2_limit_reached = true; + } + Poll::Pending => { + network_2_pending = true; + } + e => panic!("Unexpected network event: {e:?}"), + } + + if network_1_pending && network_2_pending { + return Poll::Pending; + } + + if network_1_established && network_2_established { + network_1_established = false; + network_2_established = false; + + if n <= limit { + // Dial again until the limit is exceeded. + n += 1; + network2.dial(listen_addr.clone()).unwrap(); + + if n == limit { + // The the next dialing attempt exceeds the limit, this + // is the connection we expected to get closed. + expected_closed = true; + } + } else { + panic!("Expect networks not to establish connections beyond the limit.") + } + } + + if network_1_limit_reached && network_2_limit_reached { + return Poll::Ready(()); + } + } + }) + }); + } + + quickcheck(prop as fn(_)); + } + #[test] fn invalid_peer_id() { // Checks whether dialing an address containing the wrong peer id raises an error From 1940b07bec897ace475863534046989191332fcb Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 24 Feb 2023 20:57:42 +1100 Subject: [PATCH 161/177] Add changelog entry and deprecation --- swarm/CHANGELOG.md | 3 +++ swarm/src/lib.rs | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 32c3a8c080b..459eedd5cdc 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -87,6 +87,8 @@ - Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. +- Deprecate `SwarmBuilder::connection_limits` in favor of `libp2p::swarm::connection_limits::Behaviour`. See [PR 3386]. + [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 @@ -102,6 +104,7 @@ [PR 3375]: https://github.com/libp2p/rust-libp2p/pull/3375 [PR 3254]: https://github.com/libp2p/rust-libp2p/pull/3254 [PR 3497]: https://github.com/libp2p/rust-libp2p/pull/3497 +[PR 3386]: https://github.com/libp2p/rust-libp2p/pull/3386 # 0.41.1 diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 271246b7535..df43209f53d 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1611,6 +1611,7 @@ where } /// Configures the connection limits. + #[deprecated(note = "Use `libp2p_swarm::connection_limits::Behaviour` instead.")] pub fn connection_limits(mut self, limits: ConnectionLimits) -> Self { self.connection_limits = limits; self @@ -1698,6 +1699,7 @@ pub enum DialError { impl From for DialError { fn from(error: PendingOutboundConnectionError) -> Self { match error { + #[allow(deprecated)] PendingConnectionError::ConnectionLimit(limit) => DialError::ConnectionLimit(limit), PendingConnectionError::Aborted => DialError::Aborted, PendingConnectionError::WrongPeerId { obtained, endpoint } => { @@ -1807,6 +1809,7 @@ impl From for ListenError { fn from(error: PendingInboundConnectionError) -> Self { match error { PendingInboundConnectionError::Transport(inner) => ListenError::Transport(inner), + #[allow(deprecated)] PendingInboundConnectionError::ConnectionLimit(inner) => { ListenError::ConnectionLimit(inner) } @@ -2446,6 +2449,7 @@ mod tests { let outgoing_limit = rand::thread_rng().gen_range(1..10); let limits = ConnectionLimits::default().with_max_pending_outgoing(Some(outgoing_limit)); + #[allow(deprecated)] let mut network = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) .connection_limits(limits) .build(); @@ -2500,9 +2504,11 @@ mod tests { fn prop(limit: Limit) { let limit = limit.0; + #[allow(deprecated)] let mut network1 = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) .connection_limits(limits(limit)) .build(); + #[allow(deprecated)] let mut network2 = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) .connection_limits(limits(limit)) .build(); From c4061f6e80b76fe1500ef8666dc675a3bbf02cc6 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 25 Feb 2023 01:51:32 +1100 Subject: [PATCH 162/177] Update changelog --- swarm/CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 08fab0406ce..5f3b959a1c4 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,3 +1,8 @@ +# 0.42.1 [unreleased] + +- Deprecate `SwarmBuilder::connection_limits` in favor of `libp2p::swarm::connection_limits::Behaviour`. See [PR 3386]. +[PR 3386]: https://github.com/libp2p/rust-libp2p/pull/3386 + # 0.42.0 - Allow `NetworkBehaviour`s to manage connections. @@ -87,8 +92,6 @@ - Remove `ConnectionId::new`. Manually creating `ConnectionId`s is now unsupported. See [PR 3327]. -- Deprecate `SwarmBuilder::connection_limits` in favor of `libp2p::swarm::connection_limits::Behaviour`. See [PR 3386]. - [PR 3364]: https://github.com/libp2p/rust-libp2p/pull/3364 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 @@ -104,7 +107,6 @@ [PR 3375]: https://github.com/libp2p/rust-libp2p/pull/3375 [PR 3254]: https://github.com/libp2p/rust-libp2p/pull/3254 [PR 3497]: https://github.com/libp2p/rust-libp2p/pull/3497 -[PR 3386]: https://github.com/libp2p/rust-libp2p/pull/3386 # 0.41.1 From b511de0dae8bdb2c427421a8d3016234b07a42a1 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 25 Feb 2023 01:51:54 +1100 Subject: [PATCH 163/177] Bump swarm version --- Cargo.lock | 2 +- swarm/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f5e93182a37..84f1ae5d624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2701,7 +2701,7 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.42.0" +version = "0.42.1" dependencies = [ "async-std", "either", diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 34ef423273f..493b07184d7 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-swarm" edition = "2021" rust-version = "1.62.0" description = "The libp2p swarm" -version = "0.42.0" +version = "0.42.1" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" From e952ac17a1559b50bb11f646f8bc9cca9fa5ab54 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 3 Mar 2023 14:48:31 +1100 Subject: [PATCH 164/177] Add docs to `connection_limits::Behaviour` --- swarm/src/connection_limits.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index 659dfbeecf9..e77ce30060f 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -28,6 +28,33 @@ use std::collections::{HashMap, HashSet}; use std::task::{Context, Poll}; use void::Void; +/// A [`NetworkBehaviour`] that enforces a set of [`ConnectionLimits`]. +/// +/// For these limits to take effect, this needs to be composed into the behaviour tree of your application. +/// +/// If a connection is denied due to a limit, either a [`SwarmEvent::IncomingConnectionError`](crate::SwarmEvent::IncomingConnectionError) +/// or [`SwarmEvent::OutgoingConnectionError`] will be emitted. +/// The [`ListenError::Denied`](crate::ListenError::Denied) and respectively the [`DialError::Denied`](crate::DialError::Denied) variant +/// contain a [`ConnectionDenied`](crate::ConnectionDenied) type that can be downcast to [`ConnectionLimit`] error if (and only if) **this** +/// behaviour denied the connection. +/// +/// If you employ multiple [`NetworkBehaviour`]s that manage connections, it may also be a different error. +/// +/// # Example +/// +/// ```rust +/// # use libp2p_identify as identify; +/// # use libp2p_ping as ping; +/// # use libp2p_swarm_derive::NetworkBehaviour; +/// +/// #[derive(NetworkBehaviour)] +/// # #[behaviour(prelude = "libp2p_swarm::derive_prelude")] +/// struct MyBehaviour { +/// identify: identify::Behaviour, +/// ping: ping::Behaviour, +/// limits: connection_limits::Behaviour +/// } +/// ``` pub struct Behaviour { limits: ConnectionLimits, From 0c615de9e651b7a04ab6f5decd9aaf801338ce93 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 8 Mar 2023 10:47:01 +0100 Subject: [PATCH 165/177] Reorganise code a bit We deprecate the old error and use the opportunity to change the shape of the new `Exceeded` error. --- swarm/src/connection.rs | 3 + swarm/src/connection/error.rs | 5 +- swarm/src/connection/pool.rs | 70 +++------------- swarm/src/connection_limits.rs | 143 ++++++++++++++++++++++++++++++--- swarm/src/lib.rs | 37 ++++++++- 5 files changed, 183 insertions(+), 75 deletions(-) diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index baa3896462c..84eb7baab54 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -376,6 +376,7 @@ impl<'a> IncomingInfo<'a> { } /// Information about a connection limit. +#[deprecated(note = "Use the `connection_limits::Behaviour` to implement connection limits.")] #[derive(Debug, Clone, Copy)] pub struct ConnectionLimit { /// The maximum number of connections. @@ -384,6 +385,7 @@ pub struct ConnectionLimit { pub current: u32, } +#[allow(deprecated)] impl fmt::Display for ConnectionLimit { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -395,6 +397,7 @@ impl fmt::Display for ConnectionLimit { } /// A `ConnectionLimit` can represent an error if it has been exceeded. +#[allow(deprecated)] impl std::error::Error for ConnectionLimit {} struct SubstreamUpgrade { diff --git a/swarm/src/connection/error.rs b/swarm/src/connection/error.rs index 086572505b1..4da15e7138b 100644 --- a/swarm/src/connection/error.rs +++ b/swarm/src/connection/error.rs @@ -18,9 +18,11 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#[allow(deprecated)] +use crate::connection::ConnectionLimit; use crate::transport::TransportError; use crate::Multiaddr; -use crate::{connection::ConnectionLimit, ConnectedPoint, PeerId}; +use crate::{ConnectedPoint, PeerId}; use std::{fmt, io}; /// Errors that can occur in the context of an established `Connection`. @@ -93,6 +95,7 @@ pub enum PendingConnectionError { #[deprecated( note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `{Dial,Listen}Error::Denied::cause`." )] + #[allow(deprecated)] ConnectionLimit(ConnectionLimit), /// Pending connection attempt has been aborted. diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 41f7e5155b3..00e8874cb60 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -18,12 +18,14 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::connection::{Connection, ConnectionId, PendingPoint}; +#[allow(deprecated)] +use crate::connection::{Connection, ConnectionId, ConnectionLimit, PendingPoint}; +use crate::connection_limits::ConnectionLimits; #[allow(deprecated)] use crate::IntoConnectionHandler; use crate::{ connection::{ - Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError, + Connected, ConnectionError, IncomingInfo, PendingConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError, }, transport::TransportError, @@ -407,6 +409,7 @@ where /// /// Returns an error if the limit of pending outgoing connections /// has been reached. + #[allow(deprecated)] pub fn add_outgoing( &mut self, dials: Vec< @@ -461,6 +464,7 @@ where /// /// Returns an error if the limit of pending incoming connections /// has been reached. + #[allow(deprecated)] pub fn add_incoming( &mut self, future: TFut, @@ -978,14 +982,17 @@ impl ConnectionCounters { } } + #[allow(deprecated)] fn check_max_pending_outgoing(&self) -> Result<(), ConnectionLimit> { Self::check(self.pending_outgoing, self.limits.max_pending_outgoing) } + #[allow(deprecated)] fn check_max_pending_incoming(&self) -> Result<(), ConnectionLimit> { Self::check(self.pending_incoming, self.limits.max_pending_incoming) } + #[allow(deprecated)] fn check_max_established(&self, endpoint: &ConnectedPoint) -> Result<(), ConnectionLimit> { // Check total connection limit. Self::check(self.num_established(), self.limits.max_established_total)?; @@ -1002,10 +1009,12 @@ impl ConnectionCounters { } } + #[allow(deprecated)] fn check_max_established_per_peer(&self, current: u32) -> Result<(), ConnectionLimit> { Self::check(current, self.limits.max_established_per_peer) } + #[allow(deprecated)] fn check(current: u32, limit: Option) -> Result<(), ConnectionLimit> { if let Some(limit) = limit { if current >= limit { @@ -1026,63 +1035,6 @@ fn num_peer_established( }) } -/// The configurable connection limits. -/// -/// By default no connection limits apply. -#[derive(Debug, Clone, Default)] -pub struct ConnectionLimits { - pub(crate) max_pending_incoming: Option, - pub(crate) max_pending_outgoing: Option, - pub(crate) max_established_incoming: Option, - pub(crate) max_established_outgoing: Option, - pub(crate) max_established_per_peer: Option, - pub(crate) max_established_total: Option, -} - -impl ConnectionLimits { - /// Configures the maximum number of concurrently incoming connections being established. - pub fn with_max_pending_incoming(mut self, limit: Option) -> Self { - self.max_pending_incoming = limit; - self - } - - /// Configures the maximum number of concurrently outgoing connections being established. - pub fn with_max_pending_outgoing(mut self, limit: Option) -> Self { - self.max_pending_outgoing = limit; - self - } - - /// Configures the maximum number of concurrent established inbound connections. - pub fn with_max_established_incoming(mut self, limit: Option) -> Self { - self.max_established_incoming = limit; - self - } - - /// Configures the maximum number of concurrent established outbound connections. - pub fn with_max_established_outgoing(mut self, limit: Option) -> Self { - self.max_established_outgoing = limit; - self - } - - /// Configures the maximum number of concurrent established connections (both - /// inbound and outbound). - /// - /// Note: This should be used in conjunction with - /// [`ConnectionLimits::with_max_established_incoming`] to prevent possible - /// eclipse attacks (all connections being inbound). - pub fn with_max_established(mut self, limit: Option) -> Self { - self.max_established_total = limit; - self - } - - /// Configures the maximum number of concurrent established connections per peer, - /// regardless of direction (incoming or outgoing). - pub fn with_max_established_per_peer(mut self, limit: Option) -> Self { - self.max_established_per_peer = limit; - self - } -} - /// Configuration options when creating a [`Pool`]. /// /// The default configuration specifies no dedicated task executor, a diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index e77ce30060f..1b7656e5f68 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -19,12 +19,12 @@ // DEALINGS IN THE SOFTWARE. use crate::{ - dummy, ConnectionClosed, ConnectionDenied, ConnectionId, ConnectionLimit, ConnectionLimits, - FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, - THandlerOutEvent, + dummy, ConnectionClosed, ConnectionDenied, ConnectionId, FromSwarm, NetworkBehaviour, + NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; use libp2p_core::{Endpoint, Multiaddr, PeerId}; use std::collections::{HashMap, HashSet}; +use std::fmt; use std::task::{Context, Poll}; use void::Void; @@ -35,7 +35,7 @@ use void::Void; /// If a connection is denied due to a limit, either a [`SwarmEvent::IncomingConnectionError`](crate::SwarmEvent::IncomingConnectionError) /// or [`SwarmEvent::OutgoingConnectionError`] will be emitted. /// The [`ListenError::Denied`](crate::ListenError::Denied) and respectively the [`DialError::Denied`](crate::DialError::Denied) variant -/// contain a [`ConnectionDenied`](crate::ConnectionDenied) type that can be downcast to [`ConnectionLimit`] error if (and only if) **this** +/// contain a [`ConnectionDenied`](crate::ConnectionDenied) type that can be downcast to [`Exceeded`] error if (and only if) **this** /// behaviour denied the connection. /// /// If you employ multiple [`NetworkBehaviour`]s that manage connections, it may also be a different error. @@ -46,6 +46,7 @@ use void::Void; /// # use libp2p_identify as identify; /// # use libp2p_ping as ping; /// # use libp2p_swarm_derive::NetworkBehaviour; +/// # use libp2p_swarm::connection_limits; /// /// #[derive(NetworkBehaviour)] /// # #[behaviour(prelude = "libp2p_swarm::derive_prelude")] @@ -77,18 +78,128 @@ impl Behaviour { } } - fn check_limit(&mut self, limit: Option, current: usize) -> Result<(), ConnectionDenied> { + fn check_limit( + &mut self, + limit: Option, + current: usize, + kind: Kind, + ) -> Result<(), ConnectionDenied> { let limit = limit.unwrap_or(u32::MAX); let current = current as u32; if current >= limit { - return Err(ConnectionDenied::new(ConnectionLimit { limit, current })); + return Err(ConnectionDenied::new(Exceeded { limit, kind })); } Ok(()) } } +/// A connection limit has been exceeded. +#[derive(Debug, Clone, Copy)] +pub struct Exceeded { + limit: u32, + kind: Kind, +} + +impl Exceeded { + pub fn limit(&self) -> u32 { + self.limit + } +} + +impl fmt::Display for Exceeded { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "connection limit exceeded: at most {} {} are allowed", + self.limit, self.kind + ) + } +} + +#[derive(Debug, Clone, Copy)] +enum Kind { + PendingIncoming, + PendingOutgoing, + EstablishedIncoming, + EstablishedOutgoing, + EstablishedPerPeer, + EstablishedTotal, +} + +impl fmt::Display for Kind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Kind::PendingIncoming => write!(f, "pending incoming connections"), + Kind::PendingOutgoing => write!(f, "pending outgoing connections"), + Kind::EstablishedIncoming => write!(f, "established incoming connections"), + Kind::EstablishedOutgoing => write!(f, "established outgoing connections"), + Kind::EstablishedPerPeer => write!(f, "established connections per peer"), + Kind::EstablishedTotal => write!(f, "established connections"), + } + } +} + +impl std::error::Error for Exceeded {} + +/// The configurable connection limits. +/// +/// By default no connection limits apply. +#[derive(Debug, Clone, Default)] +pub struct ConnectionLimits { + pub(crate) max_pending_incoming: Option, + pub(crate) max_pending_outgoing: Option, + pub(crate) max_established_incoming: Option, + pub(crate) max_established_outgoing: Option, + pub(crate) max_established_per_peer: Option, + pub(crate) max_established_total: Option, +} + +impl ConnectionLimits { + /// Configures the maximum number of concurrently incoming connections being established. + pub fn with_max_pending_incoming(mut self, limit: Option) -> Self { + self.max_pending_incoming = limit; + self + } + + /// Configures the maximum number of concurrently outgoing connections being established. + pub fn with_max_pending_outgoing(mut self, limit: Option) -> Self { + self.max_pending_outgoing = limit; + self + } + + /// Configures the maximum number of concurrent established inbound connections. + pub fn with_max_established_incoming(mut self, limit: Option) -> Self { + self.max_established_incoming = limit; + self + } + + /// Configures the maximum number of concurrent established outbound connections. + pub fn with_max_established_outgoing(mut self, limit: Option) -> Self { + self.max_established_outgoing = limit; + self + } + + /// Configures the maximum number of concurrent established connections (both + /// inbound and outbound). + /// + /// Note: This should be used in conjunction with + /// [`ConnectionLimits::with_max_established_incoming`] to prevent possible + /// eclipse attacks (all connections being inbound). + pub fn with_max_established(mut self, limit: Option) -> Self { + self.max_established_total = limit; + self + } + + /// Configures the maximum number of concurrent established connections per peer, + /// regardless of direction (incoming or outgoing). + pub fn with_max_established_per_peer(mut self, limit: Option) -> Self { + self.max_established_per_peer = limit; + self + } +} + impl NetworkBehaviour for Behaviour { type ConnectionHandler = dummy::ConnectionHandler; type OutEvent = Void; @@ -102,6 +213,7 @@ impl NetworkBehaviour for Behaviour { self.check_limit( self.limits.max_pending_incoming, self.pending_inbound_connections.len(), + Kind::PendingIncoming, )?; self.pending_inbound_connections.insert(connection_id); @@ -121,6 +233,7 @@ impl NetworkBehaviour for Behaviour { self.check_limit( self.limits.max_established_incoming, self.established_inbound_connections.len(), + Kind::EstablishedIncoming, )?; self.check_limit( self.limits.max_established_per_peer, @@ -128,11 +241,13 @@ impl NetworkBehaviour for Behaviour { .get(&peer) .map(|connections| connections.len()) .unwrap_or(0), + Kind::EstablishedPerPeer, )?; self.check_limit( self.limits.max_established_total, self.established_inbound_connections.len() + self.established_outbound_connections.len(), + Kind::EstablishedTotal, )?; self.established_inbound_connections.insert(connection_id); @@ -154,6 +269,7 @@ impl NetworkBehaviour for Behaviour { self.check_limit( self.limits.max_pending_outgoing, self.pending_outbound_connections.len(), + Kind::PendingOutgoing, )?; self.pending_outbound_connections.insert(connection_id); @@ -173,6 +289,7 @@ impl NetworkBehaviour for Behaviour { self.check_limit( self.limits.max_established_outgoing, self.established_outbound_connections.len(), + Kind::EstablishedOutgoing, )?; self.check_limit( self.limits.max_established_per_peer, @@ -180,11 +297,13 @@ impl NetworkBehaviour for Behaviour { .get(&peer) .map(|connections| connections.len()) .unwrap_or(0), + Kind::EstablishedPerPeer, )?; self.check_limit( self.limits.max_established_total, self.established_inbound_connections.len() + self.established_outbound_connections.len(), + Kind::EstablishedTotal, )?; self.established_outbound_connections.insert(connection_id); @@ -281,12 +400,11 @@ mod tests { .expect_err("Unexpected dialing success.") { DialError::Denied { cause } => { - let limit = cause - .downcast::() + let exceeded = cause + .downcast::() .expect("connection denied because of limit"); - assert_eq!(limit.current, outgoing_limit); - assert_eq!(limit.limit, outgoing_limit); + assert_eq!(exceeded.limit(), outgoing_limit); } e => panic!("Unexpected error: {e:?}"), } @@ -353,11 +471,10 @@ mod tests { .. })) => { let err = cause - .downcast::() + .downcast::() .expect("connection denied because of limit"); - assert_eq!(err.limit, limit); - assert_eq!(err.limit, err.current); + assert_eq!(err.limit(), limit); let info = network1.network_info(); let counters = info.connection_counters(); assert_eq!(counters.num_established_incoming(), limit); diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index df43209f53d..a7f0e764a8e 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -62,6 +62,7 @@ mod test; mod upgrade; pub mod behaviour; +pub mod connection_limits; pub mod dial_opts; pub mod dummy; mod executor; @@ -104,14 +105,17 @@ pub mod derive_prelude { pub use libp2p_core::PeerId; } +#[allow(deprecated)] +pub use crate::connection::ConnectionLimit; +pub use crate::connection_limits::ConnectionLimits; pub use behaviour::{ AddressChange, CloseConnection, ConnectionClosed, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, ExternalAddresses, FromSwarm, ListenAddresses, ListenFailure, ListenerClosed, ListenerError, NetworkBehaviour, NetworkBehaviourAction, NewExternalAddr, NewListenAddr, NotifyHandler, PollParameters, }; -pub use connection::pool::{ConnectionCounters, ConnectionLimits}; -pub use connection::{ConnectionError, ConnectionId, ConnectionLimit}; +pub use connection::pool::ConnectionCounters; +pub use connection::{ConnectionError, ConnectionId}; pub use executor::Executor; #[allow(deprecated)] pub use handler::IntoConnectionHandler; @@ -630,6 +634,7 @@ where ) { Ok(()) => Ok(()), Err(connection_limit) => { + #[allow(deprecated)] let error = DialError::ConnectionLimit(connection_limit); self.behaviour .on_swarm_event(FromSwarm::DialFailure(DialFailure { @@ -1068,6 +1073,7 @@ where }); } Err(connection_limit) => { + #[allow(deprecated)] let error = ListenError::ConnectionLimit(connection_limit); self.behaviour .on_swarm_event(FromSwarm::ListenFailure(ListenFailure { @@ -1669,6 +1675,10 @@ pub enum DialError { Banned, /// The configured limit for simultaneous outgoing connections /// has been reached. + #[deprecated( + note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `{Dial,Listen}Error::Denied::cause`." + )] + #[allow(deprecated)] ConnectionLimit(ConnectionLimit), /// The peer identity obtained on the connection matches the local peer. LocalPeerId { @@ -1714,6 +1724,7 @@ impl From for DialError { impl fmt::Display for DialError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + #[allow(deprecated)] DialError::ConnectionLimit(err) => write!(f, "Dial error: {err}"), DialError::NoAddresses => write!(f, "Dial error: no addresses for peer."), DialError::LocalPeerId { endpoint } => write!( @@ -1767,6 +1778,7 @@ fn print_error_chain(f: &mut fmt::Formatter<'_>, e: &dyn error::Error) -> fmt::R impl error::Error for DialError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { + #[allow(deprecated)] DialError::ConnectionLimit(err) => Some(err), DialError::LocalPeerId { .. } => None, DialError::NoAddresses => None, @@ -1786,6 +1798,10 @@ impl error::Error for DialError { pub enum ListenError { /// The configured limit for simultaneous outgoing connections /// has been reached. + #[deprecated( + note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `{Dial,Listen}Error::Denied::cause`." + )] + #[allow(deprecated)] ConnectionLimit(ConnectionLimit), /// Pending connection attempt has been aborted. Aborted, @@ -1827,6 +1843,7 @@ impl From for ListenError { impl fmt::Display for ListenError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + #[allow(deprecated)] ListenError::ConnectionLimit(_) => write!(f, "Listen error"), ListenError::Aborted => write!( f, @@ -1852,6 +1869,7 @@ impl fmt::Display for ListenError { impl error::Error for ListenError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { + #[allow(deprecated)] ListenError::ConnectionLimit(err) => Some(err), ListenError::WrongPeerId { .. } => None, ListenError::Transport(err) => Some(err), @@ -1873,6 +1891,19 @@ impl ConnectionDenied { inner: Box::new(cause), } } + + /// Attempt to downcast to a particular reason for why the connection was denied. + pub fn downcast(self) -> Result + where + E: error::Error + Send + Sync + 'static, + { + let inner = self + .inner + .downcast::() + .map_err(|inner| ConnectionDenied { inner })?; + + Ok(*inner) + } } impl fmt::Display for ConnectionDenied { @@ -2471,6 +2502,7 @@ mod tests { .dial(DialOpts::peer_id(target).addresses(vec![addr]).build()) .expect_err("Unexpected dialing success.") { + #[allow(deprecated)] DialError::ConnectionLimit(limit) => { assert_eq!(limit.current, outgoing_limit); assert_eq!(limit.limit, outgoing_limit); @@ -2541,6 +2573,7 @@ mod tests { Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { network_1_established = true; } + #[allow(deprecated)] Poll::Ready(Some(SwarmEvent::IncomingConnectionError { error: ListenError::ConnectionLimit(err), .. From 0f8a232d2f864f6a33df0581ccfebc7b82f6fa34 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 8 Mar 2023 10:52:48 +0100 Subject: [PATCH 166/177] Fix doc comments --- swarm/src/connection_limits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/connection_limits.rs b/swarm/src/connection_limits.rs index 1b7656e5f68..ac5ed614134 100644 --- a/swarm/src/connection_limits.rs +++ b/swarm/src/connection_limits.rs @@ -33,7 +33,7 @@ use void::Void; /// For these limits to take effect, this needs to be composed into the behaviour tree of your application. /// /// If a connection is denied due to a limit, either a [`SwarmEvent::IncomingConnectionError`](crate::SwarmEvent::IncomingConnectionError) -/// or [`SwarmEvent::OutgoingConnectionError`] will be emitted. +/// or [`SwarmEvent::OutgoingConnectionError`](crate::SwarmEvent::OutgoingConnectionError) will be emitted. /// The [`ListenError::Denied`](crate::ListenError::Denied) and respectively the [`DialError::Denied`](crate::DialError::Denied) variant /// contain a [`ConnectionDenied`](crate::ConnectionDenied) type that can be downcast to [`Exceeded`] error if (and only if) **this** /// behaviour denied the connection. From b7d5e5cb43da62d40d441a5a2cf978d8c43bd828 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 14:20:43 +0100 Subject: [PATCH 167/177] Move connection limits into separate crate --- Cargo.lock | 18 ++ Cargo.toml | 18 +- libp2p/Cargo.toml | 1 + libp2p/src/lib.rs | 2 + misc/connection-limits/CHANGELOG.md | 3 + misc/connection-limits/Cargo.toml | 23 ++ .../connection-limits/src/lib.rs | 216 ++++++------------ swarm-test/src/lib.rs | 2 + swarm/CHANGELOG.md | 4 +- swarm/Cargo.toml | 1 + swarm/src/connection/pool.rs | 66 +++++- swarm/src/lib.rs | 10 +- 12 files changed, 198 insertions(+), 166 deletions(-) create mode 100644 misc/connection-limits/CHANGELOG.md create mode 100644 misc/connection-limits/Cargo.toml rename swarm/src/connection_limits.rs => misc/connection-limits/src/lib.rs (66%) diff --git a/Cargo.lock b/Cargo.lock index ceacda29458..7d8abdd4208 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2149,6 +2149,7 @@ dependencies = [ "getrandom 0.2.8", "instant", "libp2p-autonat", + "libp2p-connection-limits", "libp2p-core", "libp2p-dcutr", "libp2p-deflate", @@ -2205,6 +2206,22 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "libp2p-connection-limits" +version = "0.1.0" +dependencies = [ + "async-std", + "env_logger 0.10.0", + "futures", + "libp2p-core", + "libp2p-swarm", + "libp2p-swarm-derive", + "libp2p-swarm-test", + "quickcheck-ext", + "rand 0.8.5", + "void", +] + [[package]] name = "libp2p-core" version = "0.39.1" @@ -2699,6 +2716,7 @@ dependencies = [ "libp2p-ping", "libp2p-plaintext", "libp2p-swarm-derive", + "libp2p-swarm-test", "libp2p-yamux", "log", "quickcheck-ext", diff --git a/Cargo.toml b/Cargo.toml index c32c8c42d1b..27013f3b1b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,42 +10,42 @@ members = [ "examples/ipfs-private", "examples/ping-example", "examples/rendezvous", + "interop-tests", + "misc/connection-limits", + "misc/keygen", "misc/metrics", "misc/multistream-select", - "misc/rw-stream-sink", - "misc/keygen", "misc/quick-protobuf-codec", "misc/quickcheck-ext", + "misc/rw-stream-sink", "muxers/mplex", - "muxers/yamux", "muxers/test-harness", - "protocols/dcutr", + "muxers/yamux", "protocols/autonat", + "protocols/dcutr", "protocols/floodsub", "protocols/gossipsub", - "protocols/rendezvous", "protocols/identify", "protocols/kad", "protocols/mdns", "protocols/ping", "protocols/relay", + "protocols/rendezvous", "protocols/request-response", "swarm", "swarm-derive", - "interop-tests", "swarm-test", "transports/deflate", "transports/dns", "transports/noise", - "transports/tls", "transports/plaintext", "transports/pnet", "transports/quic", "transports/tcp", + "transports/tls", "transports/uds", - "transports/websocket", "transports/wasm-ext", "transports/webrtc", - "interop-tests" + "transports/websocket", ] resolver = "2" diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index af21df20860..96a602def5b 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -93,6 +93,7 @@ getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature instant = "0.1.11" # Explicit dependency to be used in `wasm-bindgen` feature libp2p-autonat = { version = "0.10.0", path = "../protocols/autonat", optional = true } +libp2p-connection-limits = { version = "0.1.0", path = "../misc/connection-limits" } libp2p-core = { version = "0.39.0", path = "../core" } libp2p-dcutr = { version = "0.9.0", path = "../protocols/dcutr", optional = true } libp2p-floodsub = { version = "0.42.0", path = "../protocols/floodsub", optional = true } diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 1055a726cea..4098e706720 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -44,6 +44,8 @@ pub use multiaddr; #[doc(inline)] pub use libp2p_autonat as autonat; #[doc(inline)] +pub use libp2p_connection_limits as connection_limits; +#[doc(inline)] pub use libp2p_core as core; #[cfg(feature = "dcutr")] #[doc(inline)] diff --git a/misc/connection-limits/CHANGELOG.md b/misc/connection-limits/CHANGELOG.md new file mode 100644 index 00000000000..d1e4ec5a44e --- /dev/null +++ b/misc/connection-limits/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.1.0 - unreleased + +- Initial release. diff --git a/misc/connection-limits/Cargo.toml b/misc/connection-limits/Cargo.toml new file mode 100644 index 00000000000..467e32d9d16 --- /dev/null +++ b/misc/connection-limits/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "libp2p-connection-limits" +edition = "2021" +rust-version = "1.62.0" +description = "Connection limits for libp2p." +version = "0.1.0" +license = "MIT" +repository = "https://github.com/libp2p/rust-libp2p" +keywords = ["peer-to-peer", "libp2p", "networking"] +categories = ["network-programming", "asynchronous"] + +[dependencies] +libp2p-core = { version = "0.39.0", path = "../../core" } +libp2p-swarm = { version = "0.42.0", path = "../../swarm" } +void = "1" + +[dev-dependencies] +libp2p-swarm-test = { path = "../../swarm-test" } +libp2p-swarm-derive = { path = "../../swarm-derive" } +quickcheck-ext = { path = "../quickcheck-ext" } +futures = "0.3.26" +rand = "0.8.5" +async-std = { version = "1.12.0", features = ["attributes"] } diff --git a/swarm/src/connection_limits.rs b/misc/connection-limits/src/lib.rs similarity index 66% rename from swarm/src/connection_limits.rs rename to misc/connection-limits/src/lib.rs index ac5ed614134..81d0e49a165 100644 --- a/swarm/src/connection_limits.rs +++ b/misc/connection-limits/src/lib.rs @@ -18,11 +18,11 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::{ +use libp2p_core::{Endpoint, Multiaddr, PeerId}; +use libp2p_swarm::{ dummy, ConnectionClosed, ConnectionDenied, ConnectionId, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, }; -use libp2p_core::{Endpoint, Multiaddr, PeerId}; use std::collections::{HashMap, HashSet}; use std::fmt; use std::task::{Context, Poll}; @@ -144,16 +144,14 @@ impl fmt::Display for Kind { impl std::error::Error for Exceeded {} /// The configurable connection limits. -/// -/// By default no connection limits apply. #[derive(Debug, Clone, Default)] pub struct ConnectionLimits { - pub(crate) max_pending_incoming: Option, - pub(crate) max_pending_outgoing: Option, - pub(crate) max_established_incoming: Option, - pub(crate) max_established_outgoing: Option, - pub(crate) max_established_per_peer: Option, - pub(crate) max_established_total: Option, + max_pending_incoming: Option, + max_pending_outgoing: Option, + max_established_incoming: Option, + max_established_outgoing: Option, + max_established_per_peer: Option, + max_established_total: Option, } impl ConnectionLimits { @@ -364,14 +362,9 @@ impl NetworkBehaviour for Behaviour { #[cfg(test)] mod tests { use super::*; - use crate::{DialError, DialOpts, ListenError, Swarm, SwarmEvent}; - use futures::future; - use futures::ready; - use futures::StreamExt; - use libp2p_core::{identity, multiaddr::multiaddr, transport, upgrade, Transport}; - use libp2p_plaintext as plaintext; - use libp2p_yamux as yamux; - use quickcheck::*; + use libp2p_swarm::{dial_opts::DialOpts, DialError, ListenError, Swarm, SwarmEvent}; + use libp2p_swarm_test::SwarmExt; + use quickcheck_ext::*; #[test] fn max_outgoing() { @@ -379,12 +372,15 @@ mod tests { let outgoing_limit = rand::thread_rng().gen_range(1..10); - let mut network = - new_swarm(ConnectionLimits::default().with_max_pending_outgoing(Some(outgoing_limit))); + let mut network = Swarm::new_ephemeral(|_| { + Behaviour::new( + ConnectionLimits::default().with_max_pending_outgoing(Some(outgoing_limit)), + ) + }); let addr: Multiaddr = "/memory/1234".parse().unwrap(); - let target = PeerId::random(); + for _ in 0..outgoing_limit { network .dial( @@ -419,6 +415,43 @@ mod tests { #[test] fn max_established_incoming() { + fn prop(Limit(limit): Limit) { + let mut swarm1 = Swarm::new_ephemeral(|_| { + Behaviour::new( + ConnectionLimits::default().with_max_established_incoming(Some(limit)), + ) + }); + let mut swarm2 = Swarm::new_ephemeral(|_| { + Behaviour::new( + ConnectionLimits::default().with_max_established_incoming(Some(limit)), + ) + }); + + async_std::task::block_on(async { + let (listen_addr, _) = swarm1.listen().await; + + for _ in 0..limit { + swarm2.connect(&mut swarm1).await; + } + + swarm2.dial(listen_addr).unwrap(); + + async_std::task::spawn(swarm2.loop_on_next()); + + let cause = swarm1 + .wait(|event| match event { + SwarmEvent::IncomingConnectionError { + error: ListenError::Denied { cause }, + .. + } => Some(cause), + _ => None, + }) + .await; + + assert_eq!(cause.downcast::().unwrap().limit, limit); + }); + } + #[derive(Debug, Clone)] struct Limit(u32); @@ -428,139 +461,22 @@ mod tests { } } - fn limits(limit: u32) -> ConnectionLimits { - ConnectionLimits::default().with_max_established_incoming(Some(limit)) - } - - fn prop(limit: Limit) { - let limit = limit.0; - - let mut network1 = new_swarm(limits(limit)); - let mut network2 = new_swarm(limits(limit)); - - let _ = network1.listen_on(multiaddr![Memory(0u64)]).unwrap(); - let listen_addr = async_std::task::block_on(future::poll_fn(|cx| { - match ready!(network1.poll_next_unpin(cx)).unwrap() { - SwarmEvent::NewListenAddr { address, .. } => Poll::Ready(address), - e => panic!("Unexpected network event: {e:?}"), - } - })); - - // Spawn and block on the dialer. - async_std::task::block_on({ - let mut n = 0; - network2.dial(listen_addr.clone()).unwrap(); - - let mut expected_closed = false; - let mut network_1_established = false; - let mut network_2_established = false; - let mut network_1_limit_reached = false; - let mut network_2_limit_reached = false; - future::poll_fn(move |cx| { - loop { - let mut network_1_pending = false; - let mut network_2_pending = false; - - match network1.poll_next_unpin(cx) { - Poll::Ready(Some(SwarmEvent::IncomingConnection { .. })) => {} - Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { - network_1_established = true; - } - Poll::Ready(Some(SwarmEvent::IncomingConnectionError { - error: ListenError::Denied { cause }, - .. - })) => { - let err = cause - .downcast::() - .expect("connection denied because of limit"); - - assert_eq!(err.limit(), limit); - let info = network1.network_info(); - let counters = info.connection_counters(); - assert_eq!(counters.num_established_incoming(), limit); - assert_eq!(counters.num_established(), limit); - network_1_limit_reached = true; - } - Poll::Pending => { - network_1_pending = true; - } - e => panic!("Unexpected network event: {e:?}"), - } - - match network2.poll_next_unpin(cx) { - Poll::Ready(Some(SwarmEvent::ConnectionEstablished { .. })) => { - network_2_established = true; - } - Poll::Ready(Some(SwarmEvent::ConnectionClosed { .. })) => { - assert!(expected_closed); - let info = network2.network_info(); - let counters = info.connection_counters(); - assert_eq!(counters.num_established_outgoing(), limit); - assert_eq!(counters.num_established(), limit); - network_2_limit_reached = true; - } - Poll::Pending => { - network_2_pending = true; - } - e => panic!("Unexpected network event: {e:?}"), - } - - if network_1_pending && network_2_pending { - return Poll::Pending; - } - - if network_1_established && network_2_established { - network_1_established = false; - network_2_established = false; - - if n <= limit { - // Dial again until the limit is exceeded. - n += 1; - network2.dial(listen_addr.clone()).unwrap(); - - if n == limit { - // The the next dialing attempt exceeds the limit, this - // is the connection we expected to get closed. - expected_closed = true; - } - } else { - panic!("Expect networks not to establish connections beyond the limit.") - } - } - - if network_1_limit_reached && network_2_limit_reached { - return Poll::Ready(()); - } - } - }) - }); - } - quickcheck(prop as fn(_)); } - fn new_swarm(limits: ConnectionLimits) -> Swarm { - let id_keys = identity::Keypair::generate_ed25519(); - let local_public_key = id_keys.public(); - let transport = transport::MemoryTransport::default() - .upgrade(upgrade::Version::V1) - .authenticate(plaintext::PlainText2Config { - local_public_key: local_public_key.clone(), - }) - .multiplex(yamux::YamuxConfig::default()) - .boxed(); - let behaviour = Behaviour { - limits: super::Behaviour::new(limits), - keep_alive: crate::keep_alive::Behaviour, - }; - - Swarm::without_executor(transport, behaviour, local_public_key.to_peer_id()) - } - #[derive(libp2p_swarm_derive::NetworkBehaviour)] - #[behaviour(prelude = "crate::derive_prelude")] + #[behaviour(prelude = "libp2p_swarm::derive_prelude")] struct Behaviour { - limits: crate::connection_limits::Behaviour, - keep_alive: crate::keep_alive::Behaviour, + limits: super::Behaviour, + keep_alive: libp2p_swarm::keep_alive::Behaviour, + } + + impl Behaviour { + fn new(limits: ConnectionLimits) -> Self { + Self { + limits: super::Behaviour::new(limits), + keep_alive: libp2p_swarm::keep_alive::Behaviour, + } + } } } diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index 1acec7ba393..7eb53094f02 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -26,6 +26,7 @@ use libp2p_core::{ Multiaddr, PeerId, Transport, }; use libp2p_plaintext::PlainText2Config; +use libp2p_swarm::dial_opts::PeerCondition; use libp2p_swarm::{ dial_opts::DialOpts, AddressScore, NetworkBehaviour, Swarm, SwarmEvent, THandlerErr, }; @@ -233,6 +234,7 @@ where let dial_opts = DialOpts::peer_id(*other.local_peer_id()) .addresses(external_addresses) + .condition(PeerCondition::Always) .build(); self.dial(dial_opts).unwrap(); diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 5f3b959a1c4..e6cf6064e19 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,6 +1,8 @@ # 0.42.1 [unreleased] -- Deprecate `SwarmBuilder::connection_limits` in favor of `libp2p::swarm::connection_limits::Behaviour`. See [PR 3386]. +- Deprecate `ConnectionLimits` in favor of `libp2p::connection_limits`. + See [PR 3386]. + [PR 3386]: https://github.com/libp2p/rust-libp2p/pull/3386 # 0.42.0 diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index aeab94d0156..7c4a4d04552 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -45,6 +45,7 @@ libp2p-kad = { path = "../protocols/kad" } libp2p-ping = { path = "../protocols/ping" } libp2p-plaintext = { path = "../transports/plaintext" } libp2p-swarm-derive = { path = "../swarm-derive" } +libp2p-swarm-test = { path = "../swarm-test" } libp2p-yamux = { path = "../muxers/yamux" } quickcheck = { package = "quickcheck-ext", path = "../misc/quickcheck-ext" } void = "1" diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 00e8874cb60..1880fbdbc7c 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -20,7 +20,6 @@ // DEALINGS IN THE SOFTWARE. #[allow(deprecated)] use crate::connection::{Connection, ConnectionId, ConnectionLimit, PendingPoint}; -use crate::connection_limits::ConnectionLimits; #[allow(deprecated)] use crate::IntoConnectionHandler; use crate::{ @@ -306,6 +305,7 @@ where THandler: ConnectionHandler, { /// Creates a new empty `Pool`. + #[allow(deprecated)] pub fn new(local_id: PeerId, config: PoolConfig, limits: ConnectionLimits) -> Self { let (pending_connection_events_tx, pending_connection_events_rx) = mpsc::channel(0); let executor = match config.executor { @@ -871,6 +871,7 @@ impl Drop for NewConnection { #[derive(Debug, Clone)] pub struct ConnectionCounters { /// The effective connection limits. + #[allow(deprecated)] limits: ConnectionLimits, /// The current number of incoming connections. pending_incoming: u32, @@ -883,6 +884,7 @@ pub struct ConnectionCounters { } impl ConnectionCounters { + #[allow(deprecated)] fn new(limits: ConnectionLimits) -> Self { Self { limits, @@ -894,7 +896,8 @@ impl ConnectionCounters { } /// The effective connection limits. - #[deprecated(note = "Use the `connection_limits::Behaviour` instead.")] + #[deprecated(note = "Use the `libp2p::connection_limits` instead.")] + #[allow(deprecated)] pub fn limits(&self) -> &ConnectionLimits { &self.limits } @@ -1035,6 +1038,65 @@ fn num_peer_established( }) } +/// The configurable connection limits. +/// +/// By default no connection limits apply. +#[derive(Debug, Clone, Default)] +#[deprecated(note = "Use `libp2p::connectio_limits` instead.")] +pub struct ConnectionLimits { + max_pending_incoming: Option, + max_pending_outgoing: Option, + max_established_incoming: Option, + max_established_outgoing: Option, + max_established_per_peer: Option, + max_established_total: Option, +} + +#[allow(deprecated)] +impl ConnectionLimits { + /// Configures the maximum number of concurrently incoming connections being established. + pub fn with_max_pending_incoming(mut self, limit: Option) -> Self { + self.max_pending_incoming = limit; + self + } + + /// Configures the maximum number of concurrently outgoing connections being established. + pub fn with_max_pending_outgoing(mut self, limit: Option) -> Self { + self.max_pending_outgoing = limit; + self + } + + /// Configures the maximum number of concurrent established inbound connections. + pub fn with_max_established_incoming(mut self, limit: Option) -> Self { + self.max_established_incoming = limit; + self + } + + /// Configures the maximum number of concurrent established outbound connections. + pub fn with_max_established_outgoing(mut self, limit: Option) -> Self { + self.max_established_outgoing = limit; + self + } + + /// Configures the maximum number of concurrent established connections (both + /// inbound and outbound). + /// + /// Note: This should be used in conjunction with + /// [`ConnectionLimits::with_max_established_incoming`] to prevent possible + /// eclipse attacks (all connections being inbound). + pub fn with_max_established(mut self, limit: Option) -> Self { + self.max_established_total = limit; + self + } + + /// Configures the maximum number of concurrent established connections per peer, + /// regardless of direction (incoming or outgoing). + pub fn with_max_established_per_peer(mut self, limit: Option) -> Self { + self.max_established_per_peer = limit; + self + } +} + /// Configuration options when creating a [`Pool`]. /// /// The default configuration specifies no dedicated task executor, a diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 4cf48215233..dc6a2571da2 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -62,7 +62,6 @@ mod test; mod upgrade; pub mod behaviour; -pub mod connection_limits; pub mod dial_opts; pub mod dummy; mod executor; @@ -107,7 +106,6 @@ pub mod derive_prelude { #[allow(deprecated)] pub use crate::connection::ConnectionLimit; -pub use crate::connection_limits::ConnectionLimits; pub use behaviour::{ AddressChange, CloseConnection, ConnectionClosed, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, ExternalAddresses, FromSwarm, ListenAddresses, ListenFailure, @@ -128,6 +126,8 @@ pub use handler::{ pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; +#[allow(deprecated)] +use crate::connection::pool::ConnectionLimits; use crate::handler::UpgradeInfoSend; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; @@ -1507,6 +1507,7 @@ pub struct SwarmBuilder { transport: transport::Boxed<(PeerId, StreamMuxerBox)>, behaviour: TBehaviour, pool_config: PoolConfig, + #[allow(deprecated)] connection_limits: ConnectionLimits, } @@ -1628,7 +1629,7 @@ where } /// Configures the connection limits. - #[deprecated(note = "Use `libp2p_swarm::connection_limits::Behaviour` instead.")] + #[allow(deprecated)] pub fn connection_limits(mut self, limits: ConnectionLimits) -> Self { self.connection_limits = limits; self @@ -2485,13 +2486,13 @@ mod tests { } #[test] + #[allow(deprecated)] fn max_outgoing() { use rand::Rng; let outgoing_limit = rand::thread_rng().gen_range(1..10); let limits = ConnectionLimits::default().with_max_pending_outgoing(Some(outgoing_limit)); - #[allow(deprecated)] let mut network = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) .connection_limits(limits) .build(); @@ -2540,6 +2541,7 @@ mod tests { } } + #[allow(deprecated)] fn limits(limit: u32) -> ConnectionLimits { ConnectionLimits::default().with_max_established_incoming(Some(limit)) } From c6e96f38752da6fcef4f1d339cc7119d85f4e80b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 14:24:05 +0100 Subject: [PATCH 168/177] Unify deprecation warnings --- swarm/src/connection.rs | 2 +- swarm/src/connection/error.rs | 2 +- swarm/src/connection/pool.rs | 2 +- swarm/src/lib.rs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index 84eb7baab54..ccf8aecf354 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -376,7 +376,7 @@ impl<'a> IncomingInfo<'a> { } /// Information about a connection limit. -#[deprecated(note = "Use the `connection_limits::Behaviour` to implement connection limits.")] +#[deprecated(note = "Use `libp2p::connection_limits` instead.")] #[derive(Debug, Clone, Copy)] pub struct ConnectionLimit { /// The maximum number of connections. diff --git a/swarm/src/connection/error.rs b/swarm/src/connection/error.rs index 4da15e7138b..f2c340716fd 100644 --- a/swarm/src/connection/error.rs +++ b/swarm/src/connection/error.rs @@ -93,7 +93,7 @@ pub enum PendingConnectionError { /// The connection was dropped because the connection limit /// for a peer has been reached. #[deprecated( - note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `{Dial,Listen}Error::Denied::cause`." + note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`." )] #[allow(deprecated)] ConnectionLimit(ConnectionLimit), diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 1880fbdbc7c..99ee2014daa 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -1042,7 +1042,7 @@ fn num_peer_established( /// /// By default no connection limits apply. #[derive(Debug, Clone, Default)] -#[deprecated(note = "Use `libp2p::connectio_limits` instead.")] +#[deprecated(note = "Use `libp2p::connection_limits` instead.")] pub struct ConnectionLimits { max_pending_incoming: Option, max_pending_outgoing: Option, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index dc6a2571da2..7cf8ef3de76 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1688,7 +1688,7 @@ pub enum DialError { /// The configured limit for simultaneous outgoing connections /// has been reached. #[deprecated( - note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `{Dial,Listen}Error::Denied::cause`." + note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`." )] #[allow(deprecated)] ConnectionLimit(ConnectionLimit), @@ -1811,7 +1811,7 @@ pub enum ListenError { /// The configured limit for simultaneous outgoing connections /// has been reached. #[deprecated( - note = "Use `libp2p_swarm::connection_limits::Behaviour` instead and handle `{Dial,Listen}Error::Denied::cause`." + note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`." )] #[allow(deprecated)] ConnectionLimit(ConnectionLimit), From 8ef157d98bafdae3d538d8206f35973db553dedc Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 14:25:57 +0100 Subject: [PATCH 169/177] Update lockfile --- Cargo.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 7d8abdd4208..422cd7442f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2211,7 +2211,6 @@ name = "libp2p-connection-limits" version = "0.1.0" dependencies = [ "async-std", - "env_logger 0.10.0", "futures", "libp2p-core", "libp2p-swarm", From 5bbf89f189f0ce5588982e074b45bea818dc17ff Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 14:27:13 +0100 Subject: [PATCH 170/177] Fix rustdoc links --- misc/connection-limits/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/connection-limits/src/lib.rs b/misc/connection-limits/src/lib.rs index 81d0e49a165..3e62c2eaff5 100644 --- a/misc/connection-limits/src/lib.rs +++ b/misc/connection-limits/src/lib.rs @@ -32,10 +32,10 @@ use void::Void; /// /// For these limits to take effect, this needs to be composed into the behaviour tree of your application. /// -/// If a connection is denied due to a limit, either a [`SwarmEvent::IncomingConnectionError`](crate::SwarmEvent::IncomingConnectionError) -/// or [`SwarmEvent::OutgoingConnectionError`](crate::SwarmEvent::OutgoingConnectionError) will be emitted. -/// The [`ListenError::Denied`](crate::ListenError::Denied) and respectively the [`DialError::Denied`](crate::DialError::Denied) variant -/// contain a [`ConnectionDenied`](crate::ConnectionDenied) type that can be downcast to [`Exceeded`] error if (and only if) **this** +/// If a connection is denied due to a limit, either a [`SwarmEvent::IncomingConnectionError`](libp2p_swarm::SwarmEvent::IncomingConnectionError) +/// or [`SwarmEvent::OutgoingConnectionError`](libp2p_swarm::SwarmEvent::OutgoingConnectionError) will be emitted. +/// The [`ListenError::Denied`](libp2p_swarm::ListenError::Denied) and respectively the [`DialError::Denied`](libp2p_swarm::DialError::Denied) variant +/// contain a [`ConnectionDenied`](libp2p_swarm::ConnectionDenied) type that can be downcast to [`Exceeded`] error if (and only if) **this** /// behaviour denied the connection. /// /// If you employ multiple [`NetworkBehaviour`]s that manage connections, it may also be a different error. From 74d92b4e11f5922a297f8b47227a2e2523c8339f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 14:29:34 +0100 Subject: [PATCH 171/177] Add deprecation since version --- swarm/src/connection.rs | 2 +- swarm/src/connection/error.rs | 3 ++- swarm/src/connection/pool.rs | 2 +- swarm/src/lib.rs | 6 ++++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index ccf8aecf354..c45cb7a9140 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -376,7 +376,7 @@ impl<'a> IncomingInfo<'a> { } /// Information about a connection limit. -#[deprecated(note = "Use `libp2p::connection_limits` instead.")] +#[deprecated(note = "Use `libp2p::connection_limits` instead.", since = "0.42.1")] #[derive(Debug, Clone, Copy)] pub struct ConnectionLimit { /// The maximum number of connections. diff --git a/swarm/src/connection/error.rs b/swarm/src/connection/error.rs index f2c340716fd..49a3ee65f12 100644 --- a/swarm/src/connection/error.rs +++ b/swarm/src/connection/error.rs @@ -93,7 +93,8 @@ pub enum PendingConnectionError { /// The connection was dropped because the connection limit /// for a peer has been reached. #[deprecated( - note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`." + note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`.", + since = "0.42.1" )] #[allow(deprecated)] ConnectionLimit(ConnectionLimit), diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 99ee2014daa..5cb70173a92 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -1042,7 +1042,7 @@ fn num_peer_established( /// /// By default no connection limits apply. #[derive(Debug, Clone, Default)] -#[deprecated(note = "Use `libp2p::connection_limits` instead.")] +#[deprecated(note = "Use `libp2p::connection_limits` instead.", since = "0.42.1")] pub struct ConnectionLimits { max_pending_incoming: Option, max_pending_outgoing: Option, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 7cf8ef3de76..678700e788c 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1688,7 +1688,8 @@ pub enum DialError { /// The configured limit for simultaneous outgoing connections /// has been reached. #[deprecated( - note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`." + note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`.", + since = "0.42.1" )] #[allow(deprecated)] ConnectionLimit(ConnectionLimit), @@ -1811,7 +1812,8 @@ pub enum ListenError { /// The configured limit for simultaneous outgoing connections /// has been reached. #[deprecated( - note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`." + note = "Use `libp2p::connection_limits` instead and handle `{Dial,Listen}Error::Denied::cause`.", + since = "0.42.1" )] #[allow(deprecated)] ConnectionLimit(ConnectionLimit), From a122529c46c68ae8dc28fc420332b3f9995670ff Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 14:35:03 +0100 Subject: [PATCH 172/177] Fix doc tests --- Cargo.lock | 3 ++- misc/connection-limits/Cargo.toml | 7 ++++--- misc/connection-limits/src/lib.rs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 422cd7442f3..ff36f3121fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2211,8 +2211,9 @@ name = "libp2p-connection-limits" version = "0.1.0" dependencies = [ "async-std", - "futures", "libp2p-core", + "libp2p-identify", + "libp2p-ping", "libp2p-swarm", "libp2p-swarm-derive", "libp2p-swarm-test", diff --git a/misc/connection-limits/Cargo.toml b/misc/connection-limits/Cargo.toml index 467e32d9d16..7d9feb275de 100644 --- a/misc/connection-limits/Cargo.toml +++ b/misc/connection-limits/Cargo.toml @@ -15,9 +15,10 @@ libp2p-swarm = { version = "0.42.0", path = "../../swarm" } void = "1" [dev-dependencies] -libp2p-swarm-test = { path = "../../swarm-test" } +async-std = { version = "1.12.0", features = ["attributes"] } +libp2p-identify = { path = "../../protocols/identify" } +libp2p-ping = { path = "../../protocols/ping" } libp2p-swarm-derive = { path = "../../swarm-derive" } +libp2p-swarm-test = { path = "../../swarm-test" } quickcheck-ext = { path = "../quickcheck-ext" } -futures = "0.3.26" rand = "0.8.5" -async-std = { version = "1.12.0", features = ["attributes"] } diff --git a/misc/connection-limits/src/lib.rs b/misc/connection-limits/src/lib.rs index 3e62c2eaff5..69e2e1ba6fe 100644 --- a/misc/connection-limits/src/lib.rs +++ b/misc/connection-limits/src/lib.rs @@ -46,7 +46,7 @@ use void::Void; /// # use libp2p_identify as identify; /// # use libp2p_ping as ping; /// # use libp2p_swarm_derive::NetworkBehaviour; -/// # use libp2p_swarm::connection_limits; +/// # use libp2p_connection_limits as connection_limits; /// /// #[derive(NetworkBehaviour)] /// # #[behaviour(prelude = "libp2p_swarm::derive_prelude")] From c7450bf865b7fcf8efd7b2569858af42fa93f525 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 16:57:39 +0100 Subject: [PATCH 173/177] Undo breaking change Thanks `cargo semver-checks`! --- swarm/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 678700e788c..366403b0da1 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -112,7 +112,8 @@ pub use behaviour::{ ListenerClosed, ListenerError, NetworkBehaviour, NetworkBehaviourAction, NewExternalAddr, NewListenAddr, NotifyHandler, PollParameters, }; -pub use connection::pool::ConnectionCounters; +#[allow(deprecated)] +pub use connection::pool::{ConnectionCounters, ConnectionLimits}; pub use connection::{ConnectionError, ConnectionId}; pub use executor::Executor; #[allow(deprecated)] From 6100cace0481d35a7dfb3b877d408d025eb78c3b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 11 Mar 2023 16:58:09 +0100 Subject: [PATCH 174/177] Remove duplicated import --- swarm/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 366403b0da1..e972d132276 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -127,8 +127,6 @@ pub use handler::{ pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; -#[allow(deprecated)] -use crate::connection::pool::ConnectionLimits; use crate::handler::UpgradeInfoSend; use connection::pool::{EstablishedConnection, Pool, PoolConfig, PoolEvent}; use connection::IncomingInfo; From fb330dcdb1d6b717d4f801200c2cb094f47d6454 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sun, 12 Mar 2023 21:49:15 +0100 Subject: [PATCH 175/177] Don't use deprecated APIs --- Cargo.lock | 1 + misc/connection-limits/Cargo.toml | 1 + misc/connection-limits/src/lib.rs | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b7254640398..a492d1be7b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2222,6 +2222,7 @@ dependencies = [ "async-std", "libp2p-core", "libp2p-identify", + "libp2p-identity", "libp2p-ping", "libp2p-swarm", "libp2p-swarm-derive", diff --git a/misc/connection-limits/Cargo.toml b/misc/connection-limits/Cargo.toml index 7d9feb275de..3bf2675beb4 100644 --- a/misc/connection-limits/Cargo.toml +++ b/misc/connection-limits/Cargo.toml @@ -12,6 +12,7 @@ categories = ["network-programming", "asynchronous"] [dependencies] libp2p-core = { version = "0.39.0", path = "../../core" } libp2p-swarm = { version = "0.42.0", path = "../../swarm" } +libp2p-identity = { version = "0.1.0", path = "../../identity", features = ["peerid"] } void = "1" [dev-dependencies] diff --git a/misc/connection-limits/src/lib.rs b/misc/connection-limits/src/lib.rs index 69e2e1ba6fe..1f6927b3bd2 100644 --- a/misc/connection-limits/src/lib.rs +++ b/misc/connection-limits/src/lib.rs @@ -18,7 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use libp2p_core::{Endpoint, Multiaddr, PeerId}; +use libp2p_core::{Endpoint, Multiaddr}; +use libp2p_identity::PeerId; use libp2p_swarm::{ dummy, ConnectionClosed, ConnectionDenied, ConnectionId, FromSwarm, NetworkBehaviour, NetworkBehaviourAction, PollParameters, THandler, THandlerInEvent, THandlerOutEvent, From 14cc858ee3cc3f0ce7ef2174048458dd10ba3f4d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 15 Mar 2023 22:34:21 +0100 Subject: [PATCH 176/177] Add changelog entry and bump version --- libp2p/CHANGELOG.md | 7 +++++++ libp2p/Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 64423ea46ee..36e4204ca88 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -1,3 +1,10 @@ +# 0.52.2 - unreleased + +- Introduce `libp2p::connection_limits` module. + See [PR 3386]. + +[PR 3386]: https://github.com/libp2p/rust-libp2p/pull/3386 + # 0.51.1 - Depend on `libp2p-tls` `v0.1.0`. diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 8a5fcd2378b..d165f991ec9 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p" edition = "2021" rust-version = "1.65.0" description = "Peer-to-peer networking library" -version = "0.51.1" +version = "0.51.2" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" From 0bad79cb6ac6cef9873f3bad9cc367a4515f0ca2 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 18 Mar 2023 11:53:46 +0100 Subject: [PATCH 177/177] Update Cargo.lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index a492d1be7b6..15e09b906d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2143,7 +2143,7 @@ checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" [[package]] name = "libp2p" -version = "0.51.1" +version = "0.51.2" dependencies = [ "async-std", "async-trait",