mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-27 16:51:34 +00:00
feat(libp2p): add SwarmBuilder
Introduce the new `libp2p::SwarmBuilder`. Users should use the new `libp2p::SwarmBuilder` instead of the now deprecated `libp2p::swarm::SwarmBuilder`. See `libp2p::SwarmBuilder` docs on how to use the new builder. Fixes #3657. Fixes #3563. Fixes #3179. Pull-Request: #4120.
This commit is contained in:
@ -23,40 +23,17 @@
|
||||
use either::Either;
|
||||
use futures::prelude::*;
|
||||
use libp2p::{
|
||||
core::{muxing::StreamMuxerBox, transport, transport::upgrade::Version},
|
||||
gossipsub, identify, identity,
|
||||
core::transport::upgrade::Version,
|
||||
gossipsub, identify,
|
||||
multiaddr::Protocol,
|
||||
noise, ping,
|
||||
pnet::{PnetConfig, PreSharedKey},
|
||||
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
|
||||
tcp, yamux, Multiaddr, PeerId, Transport,
|
||||
swarm::{NetworkBehaviour, SwarmEvent},
|
||||
tcp, yamux, Multiaddr, Transport,
|
||||
};
|
||||
use std::{env, error::Error, fs, path::Path, str::FromStr, time::Duration};
|
||||
use std::{env, error::Error, fs, path::Path, str::FromStr};
|
||||
use tokio::{io, io::AsyncBufReadExt, select};
|
||||
|
||||
/// Builds the transport that serves as a common ground for all connections.
|
||||
pub fn build_transport(
|
||||
key_pair: identity::Keypair,
|
||||
psk: Option<PreSharedKey>,
|
||||
) -> transport::Boxed<(PeerId, StreamMuxerBox)> {
|
||||
let noise_config = noise::Config::new(&key_pair).unwrap();
|
||||
let yamux_config = yamux::Config::default();
|
||||
|
||||
let base_transport = tcp::tokio::Transport::new(tcp::Config::default().nodelay(true));
|
||||
let maybe_encrypted = match psk {
|
||||
Some(psk) => Either::Left(
|
||||
base_transport.and_then(move |socket, _| PnetConfig::new(psk).handshake(socket)),
|
||||
),
|
||||
None => Either::Right(base_transport),
|
||||
};
|
||||
maybe_encrypted
|
||||
.upgrade(Version::V1Lazy)
|
||||
.authenticate(noise_config)
|
||||
.multiplex(yamux_config)
|
||||
.timeout(Duration::from_secs(20))
|
||||
.boxed()
|
||||
}
|
||||
|
||||
/// Get the current ipfs repo path, either from the IPFS_PATH environment variable or
|
||||
/// from the default $HOME/.ipfs
|
||||
fn get_ipfs_path() -> Box<Path> {
|
||||
@ -118,76 +95,67 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
.map(|text| PreSharedKey::from_str(&text))
|
||||
.transpose()?;
|
||||
|
||||
// Create a random PeerId
|
||||
let local_key = identity::Keypair::generate_ed25519();
|
||||
let local_peer_id = PeerId::from(local_key.public());
|
||||
println!("using random peer id: {local_peer_id:?}");
|
||||
if let Some(psk) = psk {
|
||||
println!("using swarm key with fingerprint: {}", psk.fingerprint());
|
||||
}
|
||||
|
||||
// Set up a an encrypted DNS-enabled TCP Transport over and Yamux protocol
|
||||
let transport = build_transport(local_key.clone(), psk);
|
||||
|
||||
// Create a Gosspipsub topic
|
||||
let gossipsub_topic = gossipsub::IdentTopic::new("chat");
|
||||
|
||||
// We create a custom network behaviour that combines gossipsub, ping and identify.
|
||||
#[derive(NetworkBehaviour)]
|
||||
#[behaviour(to_swarm = "MyBehaviourEvent")]
|
||||
struct MyBehaviour {
|
||||
gossipsub: gossipsub::Behaviour,
|
||||
identify: identify::Behaviour,
|
||||
ping: ping::Behaviour,
|
||||
}
|
||||
|
||||
enum MyBehaviourEvent {
|
||||
Gossipsub(gossipsub::Event),
|
||||
Identify(identify::Event),
|
||||
Ping(ping::Event),
|
||||
}
|
||||
let mut swarm = libp2p::SwarmBuilder::with_new_identity()
|
||||
.with_tokio()
|
||||
.with_other_transport(|key| {
|
||||
let noise_config = noise::Config::new(key).unwrap();
|
||||
let yamux_config = yamux::Config::default();
|
||||
|
||||
impl From<gossipsub::Event> for MyBehaviourEvent {
|
||||
fn from(event: gossipsub::Event) -> Self {
|
||||
MyBehaviourEvent::Gossipsub(event)
|
||||
}
|
||||
}
|
||||
let base_transport = tcp::tokio::Transport::new(tcp::Config::default().nodelay(true));
|
||||
let maybe_encrypted = match psk {
|
||||
Some(psk) => Either::Left(
|
||||
base_transport
|
||||
.and_then(move |socket, _| PnetConfig::new(psk).handshake(socket)),
|
||||
),
|
||||
None => Either::Right(base_transport),
|
||||
};
|
||||
maybe_encrypted
|
||||
.upgrade(Version::V1Lazy)
|
||||
.authenticate(noise_config)
|
||||
.multiplex(yamux_config)
|
||||
})?
|
||||
.with_dns()?
|
||||
.with_behaviour(|key| {
|
||||
let gossipsub_config = gossipsub::ConfigBuilder::default()
|
||||
.max_transmit_size(262144)
|
||||
.build()
|
||||
.map_err(|msg| io::Error::new(io::ErrorKind::Other, msg))?; // Temporary hack because `build` does not return a proper `std::error::Error`.
|
||||
Ok(MyBehaviour {
|
||||
gossipsub: gossipsub::Behaviour::new(
|
||||
gossipsub::MessageAuthenticity::Signed(key.clone()),
|
||||
gossipsub_config,
|
||||
)
|
||||
.expect("Valid configuration"),
|
||||
identify: identify::Behaviour::new(identify::Config::new(
|
||||
"/ipfs/0.1.0".into(),
|
||||
key.public(),
|
||||
)),
|
||||
ping: ping::Behaviour::new(ping::Config::new()),
|
||||
})
|
||||
})?
|
||||
.build();
|
||||
|
||||
impl From<identify::Event> for MyBehaviourEvent {
|
||||
fn from(event: identify::Event) -> Self {
|
||||
MyBehaviourEvent::Identify(event)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ping::Event> for MyBehaviourEvent {
|
||||
fn from(event: ping::Event) -> Self {
|
||||
MyBehaviourEvent::Ping(event)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a Swarm to manage peers and events
|
||||
let mut swarm = {
|
||||
let gossipsub_config = gossipsub::ConfigBuilder::default()
|
||||
.max_transmit_size(262144)
|
||||
.build()
|
||||
.expect("valid config");
|
||||
let mut behaviour = MyBehaviour {
|
||||
gossipsub: gossipsub::Behaviour::new(
|
||||
gossipsub::MessageAuthenticity::Signed(local_key.clone()),
|
||||
gossipsub_config,
|
||||
)
|
||||
.expect("Valid configuration"),
|
||||
identify: identify::Behaviour::new(identify::Config::new(
|
||||
"/ipfs/0.1.0".into(),
|
||||
local_key.public(),
|
||||
)),
|
||||
ping: ping::Behaviour::new(ping::Config::new()),
|
||||
};
|
||||
|
||||
println!("Subscribing to {gossipsub_topic:?}");
|
||||
behaviour.gossipsub.subscribe(&gossipsub_topic).unwrap();
|
||||
SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id).build()
|
||||
};
|
||||
println!("Subscribing to {gossipsub_topic:?}");
|
||||
swarm
|
||||
.behaviour_mut()
|
||||
.gossipsub
|
||||
.subscribe(&gossipsub_topic)
|
||||
.unwrap();
|
||||
|
||||
// Reach out to other nodes if specified
|
||||
for to_dial in std::env::args().skip(1) {
|
||||
|
Reference in New Issue
Block a user