refactor(swarm)!: don't be generic over Transport (#3272)

Ever since we moved `Pool` into `libp2p-swarm`, we always use it with the same `Transport`: `Boxed`. It is thus unnecessary for us to be overly generic over what kind of `Transport` we are using. This allows us to remove a few type parameters from the implementation which overall simplifies things.

This is technically a breaking change because I am removing a type parameter from two exported type aliases:

- `PendingInboundConnectionError`
- `PendingOutboundConnectionError`

Those have always only be used with `std::io::Error` in our API but it is still a breaking change.
This commit is contained in:
Thomas Eizinger
2022-12-23 11:13:34 +11:00
committed by GitHub
parent aca3454c91
commit 5782a96af2
7 changed files with 62 additions and 98 deletions

View File

@ -370,10 +370,8 @@ enum PendingInboundConnectionError {
ConnectionLimit, ConnectionLimit,
} }
impl<TTransErr> From<&libp2p_swarm::PendingInboundConnectionError<TTransErr>> impl From<&libp2p_swarm::PendingInboundConnectionError> for PendingInboundConnectionError {
for PendingInboundConnectionError fn from(error: &libp2p_swarm::PendingInboundConnectionError) -> Self {
{
fn from(error: &libp2p_swarm::PendingInboundConnectionError<TTransErr>) -> Self {
match error { match error {
libp2p_swarm::PendingInboundConnectionError::WrongPeerId { .. } => { libp2p_swarm::PendingInboundConnectionError::WrongPeerId { .. } => {
PendingInboundConnectionError::WrongPeerId PendingInboundConnectionError::WrongPeerId

View File

@ -7,9 +7,13 @@
- Add `estblished_in` to `SwarmEvent::ConnectionEstablished`. See [PR 3134]. - 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 3272].
[PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170 [PR 3170]: https://github.com/libp2p/rust-libp2p/pull/3170
[PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134 [PR 3134]: https://github.com/libp2p/rust-libp2p/pull/3134
[PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153 [PR 3153]: https://github.com/libp2p/rust-libp2p/pull/3153
[PR 3272]: https://github.com/libp2p/rust-libp2p/pull/3272
# 0.41.1 # 0.41.1

View File

@ -76,12 +76,11 @@ impl<THandlerErr> From<io::Error> for ConnectionError<THandlerErr> {
/// Note: Addresses for an outbound connection are dialed in parallel. Thus, compared to /// Note: Addresses for an outbound connection are dialed in parallel. Thus, compared to
/// [`PendingInboundConnectionError`], one or more [`TransportError`]s can occur for a single /// [`PendingInboundConnectionError`], one or more [`TransportError`]s can occur for a single
/// connection. /// connection.
pub type PendingOutboundConnectionError<TTransErr> = pub type PendingOutboundConnectionError =
PendingConnectionError<Vec<(Multiaddr, TransportError<TTransErr>)>>; PendingConnectionError<Vec<(Multiaddr, TransportError<io::Error>)>>;
/// Errors that can occur in the context of a pending incoming `Connection`. /// Errors that can occur in the context of a pending incoming `Connection`.
pub type PendingInboundConnectionError<TTransErr> = pub type PendingInboundConnectionError = PendingConnectionError<TransportError<io::Error>>;
PendingConnectionError<TransportError<TTransErr>>;
/// Errors that can occur in the context of a pending `Connection`. /// Errors that can occur in the context of a pending `Connection`.
#[derive(Debug)] #[derive(Debug)]

View File

@ -26,7 +26,7 @@ use crate::{
Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError, Connected, ConnectionError, ConnectionLimit, IncomingInfo, PendingConnectionError,
PendingInboundConnectionError, PendingOutboundConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError,
}, },
transport::{Transport, TransportError}, transport::TransportError,
ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, PeerId, ConnectedPoint, ConnectionHandler, Executor, IntoConnectionHandler, Multiaddr, PeerId,
}; };
use concurrent_dial::ConcurrentDial; use concurrent_dial::ConcurrentDial;
@ -79,9 +79,8 @@ impl ExecSwitch {
} }
/// A connection `Pool` manages a set of connections for each peer. /// A connection `Pool` manages a set of connections for each peer.
pub struct Pool<THandler, TTrans> pub struct Pool<THandler>
where where
TTrans: Transport,
THandler: IntoConnectionHandler, THandler: IntoConnectionHandler,
{ {
local_id: PeerId, local_id: PeerId,
@ -124,10 +123,10 @@ where
/// Sender distributed to pending tasks for reporting events back /// Sender distributed to pending tasks for reporting events back
/// to the pool. /// to the pool.
pending_connection_events_tx: mpsc::Sender<task::PendingConnectionEvent<TTrans>>, pending_connection_events_tx: mpsc::Sender<task::PendingConnectionEvent>,
/// Receiver for events reported from pending tasks. /// Receiver for events reported from pending tasks.
pending_connection_events_rx: mpsc::Receiver<task::PendingConnectionEvent<TTrans>>, pending_connection_events_rx: mpsc::Receiver<task::PendingConnectionEvent>,
/// Sender distributed to established tasks for reporting events back /// Sender distributed to established tasks for reporting events back
/// to the pool. /// to the pool.
@ -213,7 +212,7 @@ impl<THandler> PendingConnection<THandler> {
} }
} }
impl<THandler: IntoConnectionHandler, TTrans: Transport> fmt::Debug for Pool<THandler, TTrans> { impl<THandler: IntoConnectionHandler> fmt::Debug for Pool<THandler> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("Pool") f.debug_struct("Pool")
.field("counters", &self.counters) .field("counters", &self.counters)
@ -223,10 +222,7 @@ impl<THandler: IntoConnectionHandler, TTrans: Transport> fmt::Debug for Pool<THa
/// Event that can happen on the `Pool`. /// Event that can happen on the `Pool`.
#[derive(Debug)] #[derive(Debug)]
pub enum PoolEvent<THandler: IntoConnectionHandler, TTrans> pub enum PoolEvent<THandler: IntoConnectionHandler> {
where
TTrans: Transport,
{
/// A new connection has been established. /// A new connection has been established.
ConnectionEstablished { ConnectionEstablished {
id: ConnectionId, id: ConnectionId,
@ -239,7 +235,7 @@ where
/// [`Some`] when the new connection is an outgoing connection. /// [`Some`] when the new connection is an outgoing connection.
/// Addresses are dialed in parallel. Contains the addresses and errors /// Addresses are dialed in parallel. Contains the addresses and errors
/// of dial attempts that failed before the one successful dial. /// of dial attempts that failed before the one successful dial.
concurrent_dial_errors: Option<Vec<(Multiaddr, TransportError<TTrans::Error>)>>, concurrent_dial_errors: Option<Vec<(Multiaddr, TransportError<std::io::Error>)>>,
/// How long it took to establish this connection. /// How long it took to establish this connection.
established_in: std::time::Duration, established_in: std::time::Duration,
}, },
@ -272,7 +268,7 @@ where
/// The ID of the failed connection. /// The ID of the failed connection.
id: ConnectionId, id: ConnectionId,
/// The error that occurred. /// The error that occurred.
error: PendingOutboundConnectionError<TTrans::Error>, error: PendingOutboundConnectionError,
/// The handler that was supposed to handle the connection. /// The handler that was supposed to handle the connection.
handler: THandler, handler: THandler,
/// The (expected) peer of the failed connection. /// The (expected) peer of the failed connection.
@ -288,7 +284,7 @@ where
/// Local connection address. /// Local connection address.
local_addr: Multiaddr, local_addr: Multiaddr,
/// The error that occurred. /// The error that occurred.
error: PendingInboundConnectionError<TTrans::Error>, error: PendingInboundConnectionError,
/// The handler that was supposed to handle the connection. /// The handler that was supposed to handle the connection.
handler: THandler, handler: THandler,
}, },
@ -312,10 +308,9 @@ where
}, },
} }
impl<THandler, TTrans> Pool<THandler, TTrans> impl<THandler> Pool<THandler>
where where
THandler: IntoConnectionHandler, THandler: IntoConnectionHandler,
TTrans: Transport,
{ {
/// Creates a new empty `Pool`. /// Creates a new empty `Pool`.
pub fn new(local_id: PeerId, config: PoolConfig, limits: ConnectionLimits) -> Self { pub fn new(local_id: PeerId, config: PoolConfig, limits: ConnectionLimits) -> Self {
@ -429,12 +424,9 @@ where
} }
} }
impl<THandler, TTrans> Pool<THandler, TTrans> impl<THandler> Pool<THandler>
where where
THandler: IntoConnectionHandler, 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` /// Adds a pending outgoing connection to the pool in the form of a `Future`
/// that establishes and negotiates the connection. /// that establishes and negotiates the connection.
@ -448,10 +440,7 @@ where
'static, 'static,
( (
Multiaddr, Multiaddr,
Result< Result<(PeerId, StreamMuxerBox), TransportError<std::io::Error>>,
<TTrans as Transport>::Output,
TransportError<<TTrans as Transport>::Error>,
>,
), ),
>, >,
>, >,
@ -459,11 +448,7 @@ where
handler: THandler, handler: THandler,
role_override: Endpoint, role_override: Endpoint,
dial_concurrency_factor_override: Option<NonZeroU8>, dial_concurrency_factor_override: Option<NonZeroU8>,
) -> Result<ConnectionId, (ConnectionLimit, THandler)> ) -> Result<ConnectionId, (ConnectionLimit, THandler)> {
where
TTrans: Send,
TTrans::Dial: Send + 'static,
{
if let Err(limit) = self.counters.check_max_pending_outgoing() { if let Err(limit) = self.counters.check_max_pending_outgoing() {
return Err((limit, handler)); return Err((limit, handler));
}; };
@ -515,7 +500,7 @@ where
info: IncomingInfo<'_>, info: IncomingInfo<'_>,
) -> Result<ConnectionId, (ConnectionLimit, THandler)> ) -> Result<ConnectionId, (ConnectionLimit, THandler)>
where where
TFut: Future<Output = Result<TTrans::Output, TTrans::Error>> + Send + 'static, TFut: Future<Output = Result<(PeerId, StreamMuxerBox), std::io::Error>> + Send + 'static,
{ {
let endpoint = info.create_connected_point(); let endpoint = info.create_connected_point();
@ -552,9 +537,8 @@ where
} }
/// Polls the connection pool for events. /// Polls the connection pool for events.
pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll<PoolEvent<THandler, TTrans>> pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll<PoolEvent<THandler>>
where where
TTrans: Transport<Output = (PeerId, StreamMuxerBox)>,
THandler: IntoConnectionHandler + 'static, THandler: IntoConnectionHandler + 'static,
THandler::Handler: ConnectionHandler + Send, THandler::Handler: ConnectionHandler + Send,
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send, <THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send,
@ -677,7 +661,7 @@ where
), ),
}; };
let error: Result<(), PendingInboundConnectionError<_>> = self let error = self
.counters .counters
// Check general established connection limit. // Check general established connection limit.
.check_max_established(&endpoint) .check_max_established(&endpoint)

View File

@ -18,45 +18,38 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
use crate::{ use crate::{transport::TransportError, Multiaddr};
transport::{Transport, TransportError},
Multiaddr,
};
use futures::{ use futures::{
future::{BoxFuture, Future}, future::{BoxFuture, Future},
ready, ready,
stream::{FuturesUnordered, StreamExt}, stream::{FuturesUnordered, StreamExt},
}; };
use libp2p_core::muxing::StreamMuxerBox;
use libp2p_core::PeerId;
use std::{ use std::{
num::NonZeroU8, num::NonZeroU8,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
type Dial<TTrans> = BoxFuture< type Dial = BoxFuture<
'static, 'static,
( (
Multiaddr, Multiaddr,
Result<<TTrans as Transport>::Output, TransportError<<TTrans as Transport>::Error>>, Result<(PeerId, StreamMuxerBox), TransportError<std::io::Error>>,
), ),
>; >;
pub struct ConcurrentDial<TTrans: Transport> { pub struct ConcurrentDial {
dials: FuturesUnordered<Dial<TTrans>>, dials: FuturesUnordered<Dial>,
pending_dials: Box<dyn Iterator<Item = Dial<TTrans>> + Send>, pending_dials: Box<dyn Iterator<Item = Dial> + Send>,
errors: Vec<(Multiaddr, TransportError<TTrans::Error>)>, errors: Vec<(Multiaddr, TransportError<std::io::Error>)>,
} }
impl<TTrans: Transport> Unpin for ConcurrentDial<TTrans> {} impl Unpin for ConcurrentDial {}
impl<TTrans> ConcurrentDial<TTrans> impl ConcurrentDial {
where pub(crate) fn new(pending_dials: Vec<Dial>, concurrency_factor: NonZeroU8) -> Self {
TTrans: Transport + Send + 'static,
TTrans::Output: Send,
TTrans::Error: Send,
TTrans::Dial: Send + 'static,
{
pub(crate) fn new(pending_dials: Vec<Dial<TTrans>>, concurrency_factor: NonZeroU8) -> Self {
let mut pending_dials = pending_dials.into_iter(); let mut pending_dials = pending_dials.into_iter();
let dials = FuturesUnordered::new(); let dials = FuturesUnordered::new();
@ -75,20 +68,17 @@ where
} }
} }
impl<TTrans> Future for ConcurrentDial<TTrans> impl Future for ConcurrentDial {
where
TTrans: Transport,
{
type Output = Result< type Output = Result<
// Either one dial succeeded, returning the negotiated [`PeerId`], the address, the // Either one dial succeeded, returning the negotiated [`PeerId`], the address, the
// muxer and the addresses and errors of the dials that failed before. // muxer and the addresses and errors of the dials that failed before.
( (
Multiaddr, Multiaddr,
TTrans::Output, (PeerId, StreamMuxerBox),
Vec<(Multiaddr, TransportError<TTrans::Error>)>, Vec<(Multiaddr, TransportError<std::io::Error>)>,
), ),
// Or all dials failed, thus returning the address and error for each dial. // Or all dials failed, thus returning the address and error for each dial.
Vec<(Multiaddr, TransportError<TTrans::Error>)>, Vec<(Multiaddr, TransportError<std::io::Error>)>,
>; >;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {

View File

@ -26,7 +26,7 @@ use crate::{
connection::{ connection::{
self, ConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError, self, ConnectionError, PendingInboundConnectionError, PendingOutboundConnectionError,
}, },
transport::{Transport, TransportError}, transport::TransportError,
ConnectionHandler, Multiaddr, PeerId, ConnectionHandler, Multiaddr, PeerId,
}; };
use futures::{ use futures::{
@ -35,6 +35,7 @@ use futures::{
SinkExt, StreamExt, SinkExt, StreamExt,
}; };
use libp2p_core::connection::ConnectionId; use libp2p_core::connection::ConnectionId;
use libp2p_core::muxing::StreamMuxerBox;
use std::pin::Pin; use std::pin::Pin;
use void::Void; use void::Void;
@ -48,26 +49,19 @@ pub enum Command<T> {
Close, Close,
} }
#[derive(Debug)] pub enum PendingConnectionEvent {
pub enum PendingConnectionEvent<TTrans>
where
TTrans: Transport,
{
ConnectionEstablished { ConnectionEstablished {
id: ConnectionId, id: ConnectionId,
output: TTrans::Output, output: (PeerId, StreamMuxerBox),
/// [`Some`] when the new connection is an outgoing connection. /// [`Some`] when the new connection is an outgoing connection.
/// Addresses are dialed in parallel. Contains the addresses and errors /// Addresses are dialed in parallel. Contains the addresses and errors
/// of dial attempts that failed before the one successful dial. /// of dial attempts that failed before the one successful dial.
outgoing: Option<(Multiaddr, Vec<(Multiaddr, TransportError<TTrans::Error>)>)>, outgoing: Option<(Multiaddr, Vec<(Multiaddr, TransportError<std::io::Error>)>)>,
}, },
/// A pending connection failed. /// A pending connection failed.
PendingFailed { PendingFailed {
id: ConnectionId, id: ConnectionId,
error: Either< error: Either<PendingOutboundConnectionError, PendingInboundConnectionError>,
PendingOutboundConnectionError<TTrans::Error>,
PendingInboundConnectionError<TTrans::Error>,
>,
}, },
} }
@ -97,14 +91,12 @@ pub enum EstablishedConnectionEvent<THandler: ConnectionHandler> {
}, },
} }
pub async fn new_for_pending_outgoing_connection<TTrans>( pub async fn new_for_pending_outgoing_connection(
connection_id: ConnectionId, connection_id: ConnectionId,
dial: ConcurrentDial<TTrans>, dial: ConcurrentDial,
abort_receiver: oneshot::Receiver<Void>, abort_receiver: oneshot::Receiver<Void>,
mut events: mpsc::Sender<PendingConnectionEvent<TTrans>>, mut events: mpsc::Sender<PendingConnectionEvent>,
) where ) {
TTrans: Transport,
{
match futures::future::select(abort_receiver, Box::pin(dial)).await { match futures::future::select(abort_receiver, Box::pin(dial)).await {
Either::Left((Err(oneshot::Canceled), _)) => { Either::Left((Err(oneshot::Canceled), _)) => {
let _ = events let _ = events
@ -135,14 +127,13 @@ pub async fn new_for_pending_outgoing_connection<TTrans>(
} }
} }
pub async fn new_for_pending_incoming_connection<TFut, TTrans>( pub async fn new_for_pending_incoming_connection<TFut>(
connection_id: ConnectionId, connection_id: ConnectionId,
future: TFut, future: TFut,
abort_receiver: oneshot::Receiver<Void>, abort_receiver: oneshot::Receiver<Void>,
mut events: mpsc::Sender<PendingConnectionEvent<TTrans>>, mut events: mpsc::Sender<PendingConnectionEvent>,
) where ) where
TTrans: Transport, TFut: Future<Output = Result<(PeerId, StreamMuxerBox), std::io::Error>> + Send + 'static,
TFut: Future<Output = Result<TTrans::Output, TTrans::Error>> + Send + 'static,
{ {
match futures::future::select(abort_receiver, Box::pin(future)).await { match futures::future::select(abort_receiver, Box::pin(future)).await {
Either::Left((Err(oneshot::Canceled), _)) => { Either::Left((Err(oneshot::Canceled), _)) => {

View File

@ -232,7 +232,7 @@ pub enum SwarmEvent<TBehaviourOutEvent, THandlerErr> {
/// Address used to send back data to the remote. /// Address used to send back data to the remote.
send_back_addr: Multiaddr, send_back_addr: Multiaddr,
/// The error that happened. /// The error that happened.
error: PendingInboundConnectionError<io::Error>, error: PendingInboundConnectionError,
}, },
/// Outgoing connection attempt failed. /// Outgoing connection attempt failed.
OutgoingConnectionError { OutgoingConnectionError {
@ -303,7 +303,7 @@ where
transport: transport::Boxed<(PeerId, StreamMuxerBox)>, transport: transport::Boxed<(PeerId, StreamMuxerBox)>,
/// The nodes currently active. /// The nodes currently active.
pool: Pool<THandler<TBehaviour>, transport::Boxed<(PeerId, StreamMuxerBox)>>, pool: Pool<THandler<TBehaviour>>,
/// The local peer ID. /// The local peer ID.
local_peer_id: PeerId, local_peer_id: PeerId,
@ -733,7 +733,7 @@ where
fn handle_pool_event( fn handle_pool_event(
&mut self, &mut self,
event: PoolEvent<THandler<TBehaviour>, transport::Boxed<(PeerId, StreamMuxerBox)>>, event: PoolEvent<THandler<TBehaviour>>,
) -> Option<SwarmEvent<TBehaviour::OutEvent, THandlerErr<TBehaviour>>> { ) -> Option<SwarmEvent<TBehaviour::OutEvent, THandlerErr<TBehaviour>>> {
match event { match event {
PoolEvent::ConnectionEstablished { PoolEvent::ConnectionEstablished {
@ -1130,7 +1130,7 @@ where
} }
} }
PendingNotifyHandler::Any(ids) => { 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, None => continue,
Some((event, ids)) => { Some((event, ids)) => {
let handler = PendingNotifyHandler::Any(ids); let handler = PendingNotifyHandler::Any(ids);
@ -1239,15 +1239,13 @@ fn notify_one<THandlerInEvent>(
/// ///
/// Returns `None` if either all connections are closing or the event /// Returns `None` if either all connections are closing or the event
/// was successfully sent to a handler, in either case the event is consumed. /// was successfully sent to a handler, in either case the event is consumed.
fn notify_any<TTrans, THandler, TBehaviour>( fn notify_any<THandler, TBehaviour>(
ids: SmallVec<[ConnectionId; 10]>, ids: SmallVec<[ConnectionId; 10]>,
pool: &mut Pool<THandler, TTrans>, pool: &mut Pool<THandler>,
event: THandlerInEvent<TBehaviour>, event: THandlerInEvent<TBehaviour>,
cx: &mut Context<'_>, cx: &mut Context<'_>,
) -> Option<(THandlerInEvent<TBehaviour>, SmallVec<[ConnectionId; 10]>)> ) -> Option<(THandlerInEvent<TBehaviour>, SmallVec<[ConnectionId; 10]>)>
where where
TTrans: Transport,
TTrans::Error: Send + 'static,
TBehaviour: NetworkBehaviour, TBehaviour: NetworkBehaviour,
THandler: IntoConnectionHandler, THandler: IntoConnectionHandler,
THandler::Handler: ConnectionHandler< THandler::Handler: ConnectionHandler<
@ -1572,8 +1570,8 @@ pub enum DialError {
Transport(Vec<(Multiaddr, TransportError<io::Error>)>), Transport(Vec<(Multiaddr, TransportError<io::Error>)>),
} }
impl From<PendingOutboundConnectionError<io::Error>> for DialError { impl From<PendingOutboundConnectionError> for DialError {
fn from(error: PendingOutboundConnectionError<io::Error>) -> Self { fn from(error: PendingOutboundConnectionError) -> Self {
match error { match error {
PendingConnectionError::ConnectionLimit(limit) => DialError::ConnectionLimit(limit), PendingConnectionError::ConnectionLimit(limit) => DialError::ConnectionLimit(limit),
PendingConnectionError::Aborted => DialError::Aborted, PendingConnectionError::Aborted => DialError::Aborted,