mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-07-02 19:21:37 +00:00
swarm/src/lib: Refactor trait usage (#2182)
- Removes the `Swarm` type alias, renaming `ExpandedSwarm` to `Swarm`. - Remove `TInEvent`, `TOutEvent` and `THandler` trait parameters on `Swarm`, instead deriving them through `TBehaviour`. Move derive logic to separate type aliases. - Simplify trait bounds on `Swarm` main `impl` and `Stream` `impl`.
This commit is contained in:
122
swarm/src/lib.rs
122
swarm/src/lib.rs
@ -120,25 +120,34 @@ use std::collections::HashSet;
|
||||
use std::num::{NonZeroU32, NonZeroUsize};
|
||||
use upgrade::UpgradeInfoSend as _;
|
||||
|
||||
/// Contains the state of the network, plus the way it should behave.
|
||||
pub type Swarm<TBehaviour> = ExpandedSwarm<
|
||||
TBehaviour,
|
||||
<<<TBehaviour as NetworkBehaviour>::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::InEvent,
|
||||
<<<TBehaviour as NetworkBehaviour>::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent,
|
||||
<TBehaviour as NetworkBehaviour>::ProtocolsHandler,
|
||||
>;
|
||||
|
||||
/// Substream for which a protocol has been chosen.
|
||||
///
|
||||
/// Implements the [`AsyncRead`](futures::io::AsyncRead) and
|
||||
/// [`AsyncWrite`](futures::io::AsyncWrite) traits.
|
||||
pub type NegotiatedSubstream = Negotiated<Substream<StreamMuxerBox>>;
|
||||
|
||||
/// Event generated by the [`NetworkBehaviour`] that the swarm will report back.
|
||||
type TBehaviourOutEvent<TBehaviour> = <TBehaviour as NetworkBehaviour>::OutEvent;
|
||||
|
||||
/// [`ProtocolsHandler`] of the [`NetworkBehaviour`] for all the protocols the [`NetworkBehaviour`]
|
||||
/// supports.
|
||||
type THandler<TBehaviour> = <TBehaviour as NetworkBehaviour>::ProtocolsHandler;
|
||||
|
||||
/// Custom event that can be received by the [`ProtocolsHandler`] of the
|
||||
/// [`NetworkBehaviour`].
|
||||
type THandlerInEvent<TBehaviour> = <<THandler<TBehaviour> as IntoProtocolsHandler>::Handler as ProtocolsHandler>::InEvent;
|
||||
|
||||
/// Custom event that can be produced by the [`ProtocolsHandler`] of the [`NetworkBehaviour`].
|
||||
type THandlerOutEvent<TBehaviour> = <<THandler<TBehaviour> as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent;
|
||||
|
||||
/// Custom error that can be produced by the [`ProtocolsHandler`] of the [`NetworkBehaviour`].
|
||||
type THandlerErr<TBehaviour> = <<THandler<TBehaviour> as IntoProtocolsHandler>::Handler as ProtocolsHandler>::Error;
|
||||
|
||||
/// Event generated by the `Swarm`.
|
||||
#[derive(Debug)]
|
||||
pub enum SwarmEvent<TBvEv, THandleErr> {
|
||||
pub enum SwarmEvent<TBehaviourOutEvent, THandlerErr> {
|
||||
/// Event generated by the `NetworkBehaviour`.
|
||||
Behaviour(TBvEv),
|
||||
Behaviour(TBehaviourOutEvent),
|
||||
/// A connection to the given peer has been opened.
|
||||
ConnectionEstablished {
|
||||
/// Identity of the peer that we have connected to.
|
||||
@ -160,7 +169,7 @@ pub enum SwarmEvent<TBvEv, THandleErr> {
|
||||
num_established: u32,
|
||||
/// Reason for the disconnection, if it was not a successful
|
||||
/// active close.
|
||||
cause: Option<ConnectionError<NodeHandlerWrapperError<THandleErr>>>,
|
||||
cause: Option<ConnectionError<NodeHandlerWrapperError<THandlerErr>>>,
|
||||
},
|
||||
/// A new connection arrived on a listener and is in the process of protocol negotiation.
|
||||
///
|
||||
@ -261,17 +270,17 @@ pub enum SwarmEvent<TBvEv, THandleErr> {
|
||||
|
||||
/// Contains the state of the network, plus the way it should behave.
|
||||
///
|
||||
/// Note: Needs to be polled via `<ExpandedSwarm as Stream>` in order to make
|
||||
/// Note: Needs to be polled via `<Swarm as Stream>` in order to make
|
||||
/// progress.
|
||||
pub struct ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
||||
pub struct Swarm<TBehaviour>
|
||||
where
|
||||
THandler: IntoProtocolsHandler,
|
||||
TBehaviour: NetworkBehaviour,
|
||||
{
|
||||
network: Network<
|
||||
transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||
TInEvent,
|
||||
TOutEvent,
|
||||
NodeHandlerWrapperBuilder<THandler>,
|
||||
THandlerInEvent<TBehaviour>,
|
||||
THandlerOutEvent<TBehaviour>,
|
||||
NodeHandlerWrapperBuilder<THandler<TBehaviour>>,
|
||||
>,
|
||||
|
||||
/// Handles which nodes to connect to and how to handle the events sent back by the protocol
|
||||
@ -294,27 +303,21 @@ where
|
||||
/// Pending event to be delivered to connection handlers
|
||||
/// (or dropped if the peer disconnected) before the `behaviour`
|
||||
/// can be polled again.
|
||||
pending_event: Option<(PeerId, PendingNotifyHandler, TInEvent)>,
|
||||
pending_event: Option<(PeerId, PendingNotifyHandler, THandlerInEvent<TBehaviour>)>,
|
||||
|
||||
/// The configured override for substream protocol upgrades, if any.
|
||||
substream_upgrade_protocol_override: Option<libp2p_core::upgrade::Version>,
|
||||
}
|
||||
|
||||
impl<TBehaviour, TInEvent, TOutEvent, THandler> Unpin for
|
||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
||||
impl<TBehaviour> Unpin for Swarm<TBehaviour>
|
||||
where
|
||||
THandler: IntoProtocolsHandler,
|
||||
TBehaviour: NetworkBehaviour,
|
||||
{
|
||||
}
|
||||
|
||||
impl<TBehaviour, TInEvent, TOutEvent, THandler, THandleErr>
|
||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
||||
where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
TInEvent: Send + 'static,
|
||||
TOutEvent: Send + 'static,
|
||||
THandler: IntoProtocolsHandler + Send + 'static,
|
||||
THandler::Handler: ProtocolsHandler<InEvent = TInEvent, OutEvent = TOutEvent, Error = THandleErr>,
|
||||
THandleErr: error::Error + Send + 'static,
|
||||
impl<TBehaviour> Swarm<TBehaviour>
|
||||
where
|
||||
TBehaviour: NetworkBehaviour,
|
||||
{
|
||||
/// Builds a new `Swarm`.
|
||||
pub fn new(
|
||||
@ -438,7 +441,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
}
|
||||
|
||||
/// Removes an external address of the local node, regardless of
|
||||
/// its current score. See [`ExpandedSwarm::add_external_address`]
|
||||
/// its current score. See [`Swarm::add_external_address`]
|
||||
/// for details.
|
||||
///
|
||||
/// Returns `true` if the address existed and was removed, `false`
|
||||
@ -473,7 +476,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
///
|
||||
/// Returns `Ok(())` if there was one or more established connections to the peer.
|
||||
///
|
||||
/// Note: Closing a connection via [`ExpandedSwarm::disconnect_peer_id`] does
|
||||
/// Note: Closing a connection via [`Swarm::disconnect_peer_id`] does
|
||||
/// not inform the corresponding [`ProtocolsHandler`].
|
||||
/// Closing a connection via a [`ProtocolsHandler`] can be done either in a
|
||||
/// collaborative manner across [`ProtocolsHandler`]s
|
||||
@ -507,7 +510,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
///
|
||||
/// Polls the `Swarm` for the next event.
|
||||
fn poll_next_event(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
|
||||
-> Poll<SwarmEvent<TBehaviour::OutEvent, THandleErr>>
|
||||
-> Poll<SwarmEvent<TBehaviour::OutEvent, THandlerErr<TBehaviour>>>
|
||||
{
|
||||
// We use a `this` variable because the compiler can't mutably borrow multiple times
|
||||
// across a `Deref`.
|
||||
@ -708,7 +711,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
return Poll::Ready(SwarmEvent::Behaviour(event))
|
||||
},
|
||||
Poll::Ready(NetworkBehaviourAction::DialAddress { address }) => {
|
||||
let _ = ExpandedSwarm::dial_addr(&mut *this, address);
|
||||
let _ = Swarm::dial_addr(&mut *this, address);
|
||||
},
|
||||
Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }) => {
|
||||
if this.banned_peers.contains(&peer_id) {
|
||||
@ -720,7 +723,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
DialPeerCondition::Always => true,
|
||||
};
|
||||
if condition_matched {
|
||||
if ExpandedSwarm::dial(this, &peer_id).is_ok() {
|
||||
if Swarm::dial(this, &peer_id).is_ok() {
|
||||
return Poll::Ready(SwarmEvent::Dialing(peer_id))
|
||||
}
|
||||
} else {
|
||||
@ -808,11 +811,11 @@ enum PendingNotifyHandler {
|
||||
///
|
||||
/// Returns `None` if the connection is closing or the event has been
|
||||
/// successfully sent, in either case the event is consumed.
|
||||
fn notify_one<'a, TInEvent>(
|
||||
conn: &mut EstablishedConnection<'a, TInEvent>,
|
||||
event: TInEvent,
|
||||
fn notify_one<'a, THandlerInEvent>(
|
||||
conn: &mut EstablishedConnection<'a, THandlerInEvent>,
|
||||
event: THandlerInEvent,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Option<TInEvent>
|
||||
) -> Option<THandlerInEvent>
|
||||
{
|
||||
match conn.poll_ready_notify_handler(cx) {
|
||||
Poll::Pending => Some(event),
|
||||
@ -835,12 +838,12 @@ fn notify_one<'a, TInEvent>(
|
||||
///
|
||||
/// 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<'a, TTrans, TInEvent, TOutEvent, THandler>(
|
||||
fn notify_any<'a, TTrans, THandlerInEvent, THandlerOutEvent, THandler>(
|
||||
ids: SmallVec<[ConnectionId; 10]>,
|
||||
peer: &mut ConnectedPeer<'a, TTrans, TInEvent, TOutEvent, THandler>,
|
||||
event: TInEvent,
|
||||
peer: &mut ConnectedPeer<'a, TTrans, THandlerInEvent, THandlerOutEvent, THandler>,
|
||||
event: THandlerInEvent,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Option<(TInEvent, SmallVec<[ConnectionId; 10]>)>
|
||||
) -> Option<(THandlerInEvent, SmallVec<[ConnectionId; 10]>)>
|
||||
where
|
||||
TTrans: Transport,
|
||||
THandler: IntoConnectionHandler,
|
||||
@ -872,24 +875,18 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
/// Stream of events returned by [`ExpandedSwarm`].
|
||||
/// Stream of events returned by [`Swarm`].
|
||||
///
|
||||
/// Includes events from the [`NetworkBehaviour`] as well as events about
|
||||
/// connection and listener status. See [`SwarmEvent`] for details.
|
||||
///
|
||||
/// Note: This stream is infinite and it is guaranteed that
|
||||
/// [`Stream::poll_next`] will never return `Poll::Ready(None)`.
|
||||
impl<TBehaviour, TInEvent, TOutEvent, THandler, THandleErr> Stream for
|
||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
||||
where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
THandler: IntoProtocolsHandler + Send + 'static,
|
||||
TInEvent: Send + 'static,
|
||||
TOutEvent: Send + 'static,
|
||||
THandler::Handler:
|
||||
ProtocolsHandler<InEvent = TInEvent, OutEvent = TOutEvent, Error = THandleErr>,
|
||||
THandleErr: error::Error + Send + 'static,
|
||||
impl<TBehaviour> Stream for Swarm<TBehaviour>
|
||||
where
|
||||
TBehaviour: NetworkBehaviour,
|
||||
{
|
||||
type Item = SwarmEvent<TBehaviour::OutEvent, THandleErr>;
|
||||
type Item = SwarmEvent<TBehaviourOutEvent<TBehaviour>, THandlerErr<TBehaviour>>;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
self.as_mut()
|
||||
@ -899,13 +896,9 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
}
|
||||
|
||||
/// The stream of swarm events never terminates, so we can implement fused for it.
|
||||
impl<TBehaviour, TInEvent, TOutEvent, THandler> FusedStream for
|
||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
||||
where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
||||
THandler: IntoProtocolsHandler + Send + 'static,
|
||||
TInEvent: Send + 'static,
|
||||
TOutEvent: Send + 'static,
|
||||
THandler::Handler: ProtocolsHandler<InEvent = TInEvent, OutEvent = TOutEvent>,
|
||||
impl<TBehaviour> FusedStream for Swarm<TBehaviour>
|
||||
where
|
||||
TBehaviour: NetworkBehaviour,
|
||||
{
|
||||
fn is_terminated(&self) -> bool {
|
||||
false
|
||||
@ -954,7 +947,8 @@ pub struct SwarmBuilder<TBehaviour> {
|
||||
}
|
||||
|
||||
impl<TBehaviour> SwarmBuilder<TBehaviour>
|
||||
where TBehaviour: NetworkBehaviour,
|
||||
where
|
||||
TBehaviour: NetworkBehaviour,
|
||||
{
|
||||
/// Creates a new `SwarmBuilder` from the given transport, behaviour and
|
||||
/// local peer ID. The `Swarm` with its underlying `Network` is obtained
|
||||
@ -1073,7 +1067,7 @@ where TBehaviour: NetworkBehaviour,
|
||||
|
||||
let network = Network::new(self.transport, self.local_peer_id, network_cfg);
|
||||
|
||||
ExpandedSwarm {
|
||||
Swarm {
|
||||
network,
|
||||
behaviour: self.behaviour,
|
||||
supported_protocols,
|
||||
@ -1086,7 +1080,7 @@ where TBehaviour: NetworkBehaviour,
|
||||
}
|
||||
}
|
||||
|
||||
/// The possible failures of [`ExpandedSwarm::dial`].
|
||||
/// The possible failures of [`Swarm::dial`].
|
||||
#[derive(Debug)]
|
||||
pub enum DialError {
|
||||
/// The peer is currently banned.
|
||||
@ -1346,7 +1340,7 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Establishes multiple connections between two peers,
|
||||
/// after which one peer disconnects the other using [`ExpandedSwarm::disconnect_peer_id`].
|
||||
/// after which one peer disconnects the other using [`Swarm::disconnect_peer_id`].
|
||||
///
|
||||
/// The test expects both behaviours to be notified via pairs of
|
||||
/// inject_connected / inject_disconnected as well as
|
||||
|
Reference in New Issue
Block a user