mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-07-03 11:41:34 +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:
@ -6,7 +6,12 @@
|
|||||||
except for `new_handler`, `inject_event` and `poll`.
|
except for `new_handler`, `inject_event` and `poll`.
|
||||||
This should make it easier to create new implementations. See [PR 2150].
|
This should make it easier to create new implementations. See [PR 2150].
|
||||||
|
|
||||||
|
- Remove `Swarm` type alias and rename `ExpandedSwarm` to `Swarm`. Reduce direct
|
||||||
|
trait parameters on `Swarm` (previously `ExpandedSwarm`), deriving parameters
|
||||||
|
through associated types on `TBehaviour`. See [PR 2182].
|
||||||
|
|
||||||
[PR 2150]: https://github.com/libp2p/rust-libp2p/pull/2150/
|
[PR 2150]: https://github.com/libp2p/rust-libp2p/pull/2150/
|
||||||
|
[PR 2182]: https://github.com/libp2p/rust-libp2p/pull/2182
|
||||||
|
|
||||||
# 0.30.0 [2021-07-12]
|
# 0.30.0 [2021-07-12]
|
||||||
|
|
||||||
|
122
swarm/src/lib.rs
122
swarm/src/lib.rs
@ -120,25 +120,34 @@ use std::collections::HashSet;
|
|||||||
use std::num::{NonZeroU32, NonZeroUsize};
|
use std::num::{NonZeroU32, NonZeroUsize};
|
||||||
use upgrade::UpgradeInfoSend as _;
|
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.
|
/// Substream for which a protocol has been chosen.
|
||||||
///
|
///
|
||||||
/// Implements the [`AsyncRead`](futures::io::AsyncRead) and
|
/// Implements the [`AsyncRead`](futures::io::AsyncRead) and
|
||||||
/// [`AsyncWrite`](futures::io::AsyncWrite) traits.
|
/// [`AsyncWrite`](futures::io::AsyncWrite) traits.
|
||||||
pub type NegotiatedSubstream = Negotiated<Substream<StreamMuxerBox>>;
|
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`.
|
/// Event generated by the `Swarm`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SwarmEvent<TBvEv, THandleErr> {
|
pub enum SwarmEvent<TBehaviourOutEvent, THandlerErr> {
|
||||||
/// Event generated by the `NetworkBehaviour`.
|
/// Event generated by the `NetworkBehaviour`.
|
||||||
Behaviour(TBvEv),
|
Behaviour(TBehaviourOutEvent),
|
||||||
/// A connection to the given peer has been opened.
|
/// A connection to the given peer has been opened.
|
||||||
ConnectionEstablished {
|
ConnectionEstablished {
|
||||||
/// Identity of the peer that we have connected to.
|
/// Identity of the peer that we have connected to.
|
||||||
@ -160,7 +169,7 @@ pub enum SwarmEvent<TBvEv, THandleErr> {
|
|||||||
num_established: u32,
|
num_established: u32,
|
||||||
/// Reason for the disconnection, if it was not a successful
|
/// Reason for the disconnection, if it was not a successful
|
||||||
/// active close.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// progress.
|
||||||
pub struct ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
pub struct Swarm<TBehaviour>
|
||||||
where
|
where
|
||||||
THandler: IntoProtocolsHandler,
|
TBehaviour: NetworkBehaviour,
|
||||||
{
|
{
|
||||||
network: Network<
|
network: Network<
|
||||||
transport::Boxed<(PeerId, StreamMuxerBox)>,
|
transport::Boxed<(PeerId, StreamMuxerBox)>,
|
||||||
TInEvent,
|
THandlerInEvent<TBehaviour>,
|
||||||
TOutEvent,
|
THandlerOutEvent<TBehaviour>,
|
||||||
NodeHandlerWrapperBuilder<THandler>,
|
NodeHandlerWrapperBuilder<THandler<TBehaviour>>,
|
||||||
>,
|
>,
|
||||||
|
|
||||||
/// Handles which nodes to connect to and how to handle the events sent back by the protocol
|
/// 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
|
/// Pending event to be delivered to connection handlers
|
||||||
/// (or dropped if the peer disconnected) before the `behaviour`
|
/// (or dropped if the peer disconnected) before the `behaviour`
|
||||||
/// can be polled again.
|
/// 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.
|
/// The configured override for substream protocol upgrades, if any.
|
||||||
substream_upgrade_protocol_override: Option<libp2p_core::upgrade::Version>,
|
substream_upgrade_protocol_override: Option<libp2p_core::upgrade::Version>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TBehaviour, TInEvent, TOutEvent, THandler> Unpin for
|
impl<TBehaviour> Unpin for Swarm<TBehaviour>
|
||||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
|
||||||
where
|
where
|
||||||
THandler: IntoProtocolsHandler,
|
TBehaviour: NetworkBehaviour,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TBehaviour, TInEvent, TOutEvent, THandler, THandleErr>
|
impl<TBehaviour> Swarm<TBehaviour>
|
||||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
where
|
||||||
where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
TBehaviour: NetworkBehaviour,
|
||||||
TInEvent: Send + 'static,
|
|
||||||
TOutEvent: Send + 'static,
|
|
||||||
THandler: IntoProtocolsHandler + Send + 'static,
|
|
||||||
THandler::Handler: ProtocolsHandler<InEvent = TInEvent, OutEvent = TOutEvent, Error = THandleErr>,
|
|
||||||
THandleErr: error::Error + Send + 'static,
|
|
||||||
{
|
{
|
||||||
/// Builds a new `Swarm`.
|
/// Builds a new `Swarm`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@ -438,7 +441,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Removes an external address of the local node, regardless of
|
/// 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.
|
/// for details.
|
||||||
///
|
///
|
||||||
/// Returns `true` if the address existed and was removed, `false`
|
/// 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.
|
/// 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`].
|
/// not inform the corresponding [`ProtocolsHandler`].
|
||||||
/// Closing a connection via a [`ProtocolsHandler`] can be done either in a
|
/// Closing a connection via a [`ProtocolsHandler`] can be done either in a
|
||||||
/// collaborative manner across [`ProtocolsHandler`]s
|
/// collaborative manner across [`ProtocolsHandler`]s
|
||||||
@ -507,7 +510,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
|||||||
///
|
///
|
||||||
/// Polls the `Swarm` for the next event.
|
/// Polls the `Swarm` for the next event.
|
||||||
fn poll_next_event(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
|
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
|
// We use a `this` variable because the compiler can't mutably borrow multiple times
|
||||||
// across a `Deref`.
|
// across a `Deref`.
|
||||||
@ -708,7 +711,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
|||||||
return Poll::Ready(SwarmEvent::Behaviour(event))
|
return Poll::Ready(SwarmEvent::Behaviour(event))
|
||||||
},
|
},
|
||||||
Poll::Ready(NetworkBehaviourAction::DialAddress { address }) => {
|
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 }) => {
|
Poll::Ready(NetworkBehaviourAction::DialPeer { peer_id, condition }) => {
|
||||||
if this.banned_peers.contains(&peer_id) {
|
if this.banned_peers.contains(&peer_id) {
|
||||||
@ -720,7 +723,7 @@ where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
|||||||
DialPeerCondition::Always => true,
|
DialPeerCondition::Always => true,
|
||||||
};
|
};
|
||||||
if condition_matched {
|
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))
|
return Poll::Ready(SwarmEvent::Dialing(peer_id))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -808,11 +811,11 @@ enum PendingNotifyHandler {
|
|||||||
///
|
///
|
||||||
/// Returns `None` if the connection is closing or the event has been
|
/// Returns `None` if the connection is closing or the event has been
|
||||||
/// successfully sent, in either case the event is consumed.
|
/// successfully sent, in either case the event is consumed.
|
||||||
fn notify_one<'a, TInEvent>(
|
fn notify_one<'a, THandlerInEvent>(
|
||||||
conn: &mut EstablishedConnection<'a, TInEvent>,
|
conn: &mut EstablishedConnection<'a, THandlerInEvent>,
|
||||||
event: TInEvent,
|
event: THandlerInEvent,
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
) -> Option<TInEvent>
|
) -> Option<THandlerInEvent>
|
||||||
{
|
{
|
||||||
match conn.poll_ready_notify_handler(cx) {
|
match conn.poll_ready_notify_handler(cx) {
|
||||||
Poll::Pending => Some(event),
|
Poll::Pending => Some(event),
|
||||||
@ -835,12 +838,12 @@ fn notify_one<'a, TInEvent>(
|
|||||||
///
|
///
|
||||||
/// 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<'a, TTrans, TInEvent, TOutEvent, THandler>(
|
fn notify_any<'a, TTrans, THandlerInEvent, THandlerOutEvent, THandler>(
|
||||||
ids: SmallVec<[ConnectionId; 10]>,
|
ids: SmallVec<[ConnectionId; 10]>,
|
||||||
peer: &mut ConnectedPeer<'a, TTrans, TInEvent, TOutEvent, THandler>,
|
peer: &mut ConnectedPeer<'a, TTrans, THandlerInEvent, THandlerOutEvent, THandler>,
|
||||||
event: TInEvent,
|
event: THandlerInEvent,
|
||||||
cx: &mut Context<'_>,
|
cx: &mut Context<'_>,
|
||||||
) -> Option<(TInEvent, SmallVec<[ConnectionId; 10]>)>
|
) -> Option<(THandlerInEvent, SmallVec<[ConnectionId; 10]>)>
|
||||||
where
|
where
|
||||||
TTrans: Transport,
|
TTrans: Transport,
|
||||||
THandler: IntoConnectionHandler,
|
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
|
/// Includes events from the [`NetworkBehaviour`] as well as events about
|
||||||
/// connection and listener status. See [`SwarmEvent`] for details.
|
/// connection and listener status. See [`SwarmEvent`] for details.
|
||||||
///
|
///
|
||||||
/// Note: This stream is infinite and it is guaranteed that
|
/// Note: This stream is infinite and it is guaranteed that
|
||||||
/// [`Stream::poll_next`] will never return `Poll::Ready(None)`.
|
/// [`Stream::poll_next`] will never return `Poll::Ready(None)`.
|
||||||
impl<TBehaviour, TInEvent, TOutEvent, THandler, THandleErr> Stream for
|
impl<TBehaviour> Stream for Swarm<TBehaviour>
|
||||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
where
|
||||||
where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
TBehaviour: NetworkBehaviour,
|
||||||
THandler: IntoProtocolsHandler + Send + 'static,
|
|
||||||
TInEvent: Send + 'static,
|
|
||||||
TOutEvent: Send + 'static,
|
|
||||||
THandler::Handler:
|
|
||||||
ProtocolsHandler<InEvent = TInEvent, OutEvent = TOutEvent, Error = THandleErr>,
|
|
||||||
THandleErr: error::Error + Send + 'static,
|
|
||||||
{
|
{
|
||||||
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>> {
|
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||||
self.as_mut()
|
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.
|
/// The stream of swarm events never terminates, so we can implement fused for it.
|
||||||
impl<TBehaviour, TInEvent, TOutEvent, THandler> FusedStream for
|
impl<TBehaviour> FusedStream for Swarm<TBehaviour>
|
||||||
ExpandedSwarm<TBehaviour, TInEvent, TOutEvent, THandler>
|
where
|
||||||
where TBehaviour: NetworkBehaviour<ProtocolsHandler = THandler>,
|
TBehaviour: NetworkBehaviour,
|
||||||
THandler: IntoProtocolsHandler + Send + 'static,
|
|
||||||
TInEvent: Send + 'static,
|
|
||||||
TOutEvent: Send + 'static,
|
|
||||||
THandler::Handler: ProtocolsHandler<InEvent = TInEvent, OutEvent = TOutEvent>,
|
|
||||||
{
|
{
|
||||||
fn is_terminated(&self) -> bool {
|
fn is_terminated(&self) -> bool {
|
||||||
false
|
false
|
||||||
@ -954,7 +947,8 @@ pub struct SwarmBuilder<TBehaviour> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<TBehaviour> SwarmBuilder<TBehaviour>
|
impl<TBehaviour> SwarmBuilder<TBehaviour>
|
||||||
where TBehaviour: NetworkBehaviour,
|
where
|
||||||
|
TBehaviour: NetworkBehaviour,
|
||||||
{
|
{
|
||||||
/// Creates a new `SwarmBuilder` from the given transport, behaviour and
|
/// Creates a new `SwarmBuilder` from the given transport, behaviour and
|
||||||
/// local peer ID. The `Swarm` with its underlying `Network` is obtained
|
/// 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);
|
let network = Network::new(self.transport, self.local_peer_id, network_cfg);
|
||||||
|
|
||||||
ExpandedSwarm {
|
Swarm {
|
||||||
network,
|
network,
|
||||||
behaviour: self.behaviour,
|
behaviour: self.behaviour,
|
||||||
supported_protocols,
|
supported_protocols,
|
||||||
@ -1086,7 +1080,7 @@ where TBehaviour: NetworkBehaviour,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The possible failures of [`ExpandedSwarm::dial`].
|
/// The possible failures of [`Swarm::dial`].
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum DialError {
|
pub enum DialError {
|
||||||
/// The peer is currently banned.
|
/// The peer is currently banned.
|
||||||
@ -1346,7 +1340,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Establishes multiple connections between two peers,
|
/// 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
|
/// The test expects both behaviours to be notified via pairs of
|
||||||
/// inject_connected / inject_disconnected as well as
|
/// inject_connected / inject_disconnected as well as
|
||||||
|
Reference in New Issue
Block a user