mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-21 22:01:34 +00:00
swarm/: Enable advanced dialing requests (#2317)
Enable advanced dialing requests both on `Swarm` and via `NetworkBehaviourAction`. Users can now trigger a dial with a specific set of addresses, optionally extended via `NetworkBehaviour::addresses_of_peer`. In addition the whole process is now modelled in a type safe way via the builder pattern. Example of a `NetworkBehaviour` requesting a dial to a specific peer with a set of addresses additionally extended through `NetworkBehaviour::addresses_of_peer`: ```rust NetworkBehaviourAction::Dial { opts: DialOpts::peer_id(peer_id) .condition(PeerCondition::Always) .addresses(addresses) .extend_addresses_through_behaviour() .build(), handler, } ``` Example of a user requesting a dial to an unknown peer with a single address via `Swarm`: ```rust swarm1.dial( DialOpts::unknown_peer_id() .address(addr2.clone()) .build() ) ```
This commit is contained in:
@ -18,6 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::dial_opts::DialOpts;
|
||||
use crate::protocols_handler::{IntoProtocolsHandler, ProtocolsHandler};
|
||||
use crate::{AddressRecord, AddressScore, DialError};
|
||||
use libp2p_core::{
|
||||
@ -265,31 +266,7 @@ pub enum NetworkBehaviourAction<
|
||||
/// Instructs the `Swarm` to return an event when it is being polled.
|
||||
GenerateEvent(TOutEvent),
|
||||
|
||||
/// Instructs the swarm to dial the given multiaddress optionally including a [`PeerId`].
|
||||
///
|
||||
/// 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. See [`NetworkBehaviourAction::DialPeer`] for
|
||||
/// example.
|
||||
DialAddress {
|
||||
/// The address to dial.
|
||||
address: Multiaddr,
|
||||
/// The handler to be used to handle the connection to the peer.
|
||||
handler: THandler,
|
||||
},
|
||||
|
||||
/// Instructs the swarm to dial a known `PeerId`.
|
||||
///
|
||||
/// The [`NetworkBehaviour::addresses_of_peer`] method is called to determine which addresses to
|
||||
/// attempt to reach.
|
||||
///
|
||||
/// If we were already trying to dial this node, the addresses that are not yet in the queue of
|
||||
/// addresses to try are added back to this queue.
|
||||
/// Instructs the swarm to start a dial.
|
||||
///
|
||||
/// On success, [`NetworkBehaviour::inject_connection_established`] is invoked.
|
||||
/// On failure, [`NetworkBehaviour::inject_dial_failure`] is invoked.
|
||||
@ -300,7 +277,7 @@ pub enum NetworkBehaviourAction<
|
||||
/// can be included in the handler, and thus directly send on connection success or extracted by
|
||||
/// the [`NetworkBehaviour`] on connection failure.
|
||||
///
|
||||
/// # Example
|
||||
/// # Example carrying state in the handler
|
||||
///
|
||||
/// ```rust
|
||||
/// # use futures::executor::block_on;
|
||||
@ -312,10 +289,11 @@ pub enum NetworkBehaviourAction<
|
||||
/// # use libp2p::core::PeerId;
|
||||
/// # use libp2p::plaintext::PlainText2Config;
|
||||
/// # use libp2p::swarm::{
|
||||
/// # DialError, DialPeerCondition, IntoProtocolsHandler, KeepAlive, NegotiatedSubstream,
|
||||
/// # DialError, IntoProtocolsHandler, KeepAlive, NegotiatedSubstream,
|
||||
/// # NetworkBehaviour, NetworkBehaviourAction, PollParameters, ProtocolsHandler,
|
||||
/// # ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol, Swarm, SwarmEvent,
|
||||
/// # };
|
||||
/// # use libp2p::swarm::dial_opts::{DialOpts, PeerCondition};
|
||||
/// # use libp2p::yamux;
|
||||
/// # use std::collections::VecDeque;
|
||||
/// # use std::task::{Context, Poll};
|
||||
@ -350,21 +328,22 @@ pub enum NetworkBehaviourAction<
|
||||
/// );
|
||||
/// });
|
||||
///
|
||||
/// # #[derive(Default)]
|
||||
/// # struct MyBehaviour {
|
||||
/// # outbox_to_swarm: VecDeque<NetworkBehaviourAction<PreciousMessage, MyHandler>>,
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl MyBehaviour {
|
||||
/// # fn send(&mut self, peer_id: PeerId, msg: PreciousMessage) {
|
||||
/// # self.outbox_to_swarm
|
||||
/// # .push_back(NetworkBehaviourAction::DialPeer {
|
||||
/// # peer_id,
|
||||
/// # condition: DialPeerCondition::Always,
|
||||
/// # handler: MyHandler { message: Some(msg) },
|
||||
/// # });
|
||||
/// # }
|
||||
/// # }
|
||||
/// #[derive(Default)]
|
||||
/// struct MyBehaviour {
|
||||
/// outbox_to_swarm: VecDeque<NetworkBehaviourAction<PreciousMessage, MyHandler>>,
|
||||
/// }
|
||||
///
|
||||
/// 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 ProtocolsHandler = MyHandler;
|
||||
@ -472,14 +451,7 @@ pub enum NetworkBehaviourAction<
|
||||
/// # #[derive(Debug, PartialEq, Eq)]
|
||||
/// # struct PreciousMessage(String);
|
||||
/// ```
|
||||
DialPeer {
|
||||
/// The peer to try reach.
|
||||
peer_id: PeerId,
|
||||
/// The condition for initiating a new dialing attempt.
|
||||
condition: DialPeerCondition,
|
||||
/// The handler to be used to handle the connection to the peer.
|
||||
handler: THandler,
|
||||
},
|
||||
Dial { opts: DialOpts, handler: THandler },
|
||||
|
||||
/// Instructs the `Swarm` to send an event to the handler dedicated to a
|
||||
/// connection with a peer.
|
||||
@ -549,18 +521,9 @@ impl<TOutEvent, THandler: IntoProtocolsHandler, TInEventOld>
|
||||
) -> NetworkBehaviourAction<TOutEvent, THandler, TInEventNew> {
|
||||
match self {
|
||||
NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e),
|
||||
NetworkBehaviourAction::DialAddress { address, handler } => {
|
||||
NetworkBehaviourAction::DialAddress { address, handler }
|
||||
NetworkBehaviourAction::Dial { opts, handler } => {
|
||||
NetworkBehaviourAction::Dial { opts, handler }
|
||||
}
|
||||
NetworkBehaviourAction::DialPeer {
|
||||
peer_id,
|
||||
condition,
|
||||
handler,
|
||||
} => NetworkBehaviourAction::DialPeer {
|
||||
peer_id,
|
||||
condition,
|
||||
handler,
|
||||
},
|
||||
NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
handler,
|
||||
@ -589,18 +552,9 @@ impl<TOutEvent, THandler: IntoProtocolsHandler> NetworkBehaviourAction<TOutEvent
|
||||
pub fn map_out<E>(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction<E, THandler> {
|
||||
match self {
|
||||
NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)),
|
||||
NetworkBehaviourAction::DialAddress { address, handler } => {
|
||||
NetworkBehaviourAction::DialAddress { address, handler }
|
||||
NetworkBehaviourAction::Dial { opts, handler } => {
|
||||
NetworkBehaviourAction::Dial { opts, handler }
|
||||
}
|
||||
NetworkBehaviourAction::DialPeer {
|
||||
peer_id,
|
||||
condition,
|
||||
handler,
|
||||
} => NetworkBehaviourAction::DialPeer {
|
||||
peer_id,
|
||||
condition,
|
||||
handler,
|
||||
},
|
||||
NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
handler,
|
||||
@ -640,19 +594,8 @@ where
|
||||
{
|
||||
match self {
|
||||
NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e),
|
||||
NetworkBehaviourAction::DialAddress { address, handler } => {
|
||||
NetworkBehaviourAction::DialAddress {
|
||||
address,
|
||||
handler: f(handler),
|
||||
}
|
||||
}
|
||||
NetworkBehaviourAction::DialPeer {
|
||||
peer_id,
|
||||
condition,
|
||||
handler,
|
||||
} => NetworkBehaviourAction::DialPeer {
|
||||
peer_id,
|
||||
condition,
|
||||
NetworkBehaviourAction::Dial { opts, handler } => NetworkBehaviourAction::Dial {
|
||||
opts,
|
||||
handler: f(handler),
|
||||
},
|
||||
NetworkBehaviourAction::NotifyHandler {
|
||||
@ -687,29 +630,6 @@ pub enum NotifyHandler {
|
||||
Any,
|
||||
}
|
||||
|
||||
/// The available conditions under which a new dialing attempt to
|
||||
/// a peer is initiated when requested by [`NetworkBehaviourAction::DialPeer`].
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum DialPeerCondition {
|
||||
/// A new dialing attempt is initiated _only if_ the peer is currently
|
||||
/// considered disconnected, i.e. there is no established connection
|
||||
/// and no ongoing dialing attempt.
|
||||
Disconnected,
|
||||
/// A new dialing attempt is initiated _only if_ there is currently
|
||||
/// no ongoing dialing attempt, i.e. the peer is either considered
|
||||
/// disconnected or connected but without an ongoing dialing attempt.
|
||||
NotDialing,
|
||||
/// A new dialing attempt is always initiated, only subject to the
|
||||
/// configured connection limits.
|
||||
Always,
|
||||
}
|
||||
|
||||
impl Default for DialPeerCondition {
|
||||
fn default() -> Self {
|
||||
DialPeerCondition::Disconnected
|
||||
}
|
||||
}
|
||||
|
||||
/// The options which connections to close.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CloseConnection {
|
||||
|
Reference in New Issue
Block a user