From 557d05220bd38d8bee3048ff0f9bb68b90e4c868 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 26 Jun 2023 21:46:16 +0900 Subject: [PATCH 001/171] feat(libp2p): add `TransportBuilder` --- libp2p/src/builder.rs | 115 ++++++++++++++++++++++++++++++++++++++++++ libp2p/src/lib.rs | 1 + 2 files changed, 116 insertions(+) create mode 100644 libp2p/src/builder.rs diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs new file mode 100644 index 00000000000..45a0f339cfb --- /dev/null +++ b/libp2p/src/builder.rs @@ -0,0 +1,115 @@ +use libp2p_core::{muxing::StreamMuxerBox, Transport}; +use std::marker::PhantomData; + +pub struct TransportBuilder { + keypair: libp2p_identity::Keypair, +} + +impl TransportBuilder { + pub fn new(keypair: libp2p_identity::Keypair) -> Self { + Self { keypair } + } + + pub fn with_async_std(self) -> TcpBuilder { + TcpBuilder { + keypair: self.keypair, + phantom: PhantomData, + } + } + + pub fn with_tokio(self) -> TcpBuilder { + TcpBuilder { + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub enum AsyncStd {} +pub enum Tokio {} + +pub struct TcpBuilder

{ + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +impl TcpBuilder { + pub fn with_tcp(self) -> DnsBuilder { + DnsBuilder { + tcp: libp2p_tcp::async_io::Transport::new(libp2p_tcp::Config::new().nodelay(true)) + .upgrade(libp2p_core::upgrade::Version::V1) + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct DnsBuilder { + tcp: Tcp, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +impl DnsBuilder +where + T: Transport + Send + Unpin + 'static, +{ + pub async fn with_dns(self) -> RelayBuilder> { + RelayBuilder { + transport: libp2p_dns::DnsConfig::system(self.tcp) + .await + .expect("TODO: Handle"), + keypair: self.keypair, + phantom: PhantomData, + } + } + + pub fn without_dns(self) -> RelayBuilder { + RelayBuilder { + transport: self.tcp, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct RelayBuilder { + transport: T, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +impl RelayBuilder +where + T: Transport + Send + Unpin + 'static, + ::Error: Send + 'static, + ::Dial: Send, +{ + pub fn with_relay( + self, + relay_transport: libp2p_relay::client::Transport, + ) -> Builder { + Builder { + transport: self.transport.or_transport(relay_transport), + } + } +} + +pub struct Builder { + transport: T, +} + +impl Builder +where + T: Transport + Send + Unpin + 'static, + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, +{ + pub fn build(self) -> libp2p_core::transport::Boxed<::Output> { + self.transport.boxed() + } +} diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 059857d3b8a..64e68c97e21 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -135,6 +135,7 @@ pub use libp2p_webtransport_websys as webtransport_websys; #[doc(inline)] pub use libp2p_yamux as yamux; +mod builder; mod transport_ext; pub mod bandwidth; From 90e53c00860c59b0094bc0a3b23bcf8de03b3b4b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 30 Jun 2023 19:24:28 +0900 Subject: [PATCH 002/171] Introduce BuildableTransport abstraction --- libp2p/src/builder.rs | 99 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 9 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 45a0f339cfb..cccbc5cec18 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -33,8 +33,35 @@ pub struct TcpBuilder

{ phantom: PhantomData

, } +pub trait BuildableTransport: + Transport< + Error = Self::E, + Dial = Self::D, + ListenerUpgrade = Self::U, + Output = (libp2p_identity::PeerId, StreamMuxerBox), + > + Send + + Unpin + + 'static +{ + type E: Send + Sync + 'static; + type D: Send; + type U: Send; +} + +impl BuildableTransport for T +where + T: Transport + Send + Unpin + 'static, + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, +{ + type E = T::Error; + type D = T::Dial; + type U = T::ListenerUpgrade; +} + impl TcpBuilder { - pub fn with_tcp(self) -> DnsBuilder { + pub fn with_tcp(self) -> DnsBuilder { DnsBuilder { tcp: libp2p_tcp::async_io::Transport::new(libp2p_tcp::Config::new().nodelay(true)) .upgrade(libp2p_core::upgrade::Version::V1) @@ -47,6 +74,20 @@ impl TcpBuilder { } } +impl TcpBuilder { + pub fn with_tcp(self) -> DnsBuilder { + DnsBuilder { + tcp: libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::new().nodelay(true)) + .upgrade(libp2p_core::upgrade::Version::V1) + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + pub struct DnsBuilder { tcp: Tcp, keypair: libp2p_identity::Keypair, @@ -56,6 +97,9 @@ pub struct DnsBuilder { impl DnsBuilder where T: Transport + Send + Unpin + 'static, + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, { pub async fn with_dns(self) -> RelayBuilder> { RelayBuilder { @@ -66,8 +110,26 @@ where phantom: PhantomData, } } +} - pub fn without_dns(self) -> RelayBuilder { +impl DnsBuilder +where + T: Transport + Send + Unpin + 'static, + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, +{ + pub fn with_dns(self) -> RelayBuilder> { + RelayBuilder { + transport: libp2p_dns::TokioDnsConfig::system(self.tcp).expect("TODO: Handle"), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +impl DnsBuilder { + pub fn without_dns(self) -> RelayBuilder { RelayBuilder { transport: self.tcp, keypair: self.keypair, @@ -98,18 +160,37 @@ where } } +impl RelayBuilder { + pub fn without_relay(self) -> Builder { + Builder { + transport: self.transport, + } + } +} + pub struct Builder { transport: T, } -impl Builder -where - T: Transport + Send + Unpin + 'static, - ::Error: Send + Sync + 'static, - ::Dial: Send, - ::ListenerUpgrade: Send, -{ +impl Builder { pub fn build(self) -> libp2p_core::transport::Boxed<::Output> { self.transport.boxed() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn tcp() { + let key = libp2p_identity::Keypair::generate_ed25519(); + let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = + TransportBuilder::new(key) + .with_tokio() + .with_tcp() + .without_dns() + .without_relay() + .build(); + } +} From fe1f3d35a5d405b6f667c96a038a364a95942bc8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 30 Jun 2023 20:21:54 +0900 Subject: [PATCH 003/171] Feature flag --- libp2p/src/builder.rs | 209 ++++++++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 88 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index cccbc5cec18..db6b66d9a5d 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -10,6 +10,7 @@ impl TransportBuilder { Self { keypair } } + #[cfg(feature = "async-std")] pub fn with_async_std(self) -> TcpBuilder { TcpBuilder { keypair: self.keypair, @@ -17,6 +18,7 @@ impl TransportBuilder { } } + #[cfg(feature = "tokio")] pub fn with_tokio(self) -> TcpBuilder { TcpBuilder { keypair: self.keypair, @@ -25,59 +27,33 @@ impl TransportBuilder { } } -pub enum AsyncStd {} -pub enum Tokio {} - pub struct TcpBuilder

{ keypair: libp2p_identity::Keypair, phantom: PhantomData

, } -pub trait BuildableTransport: - Transport< - Error = Self::E, - Dial = Self::D, - ListenerUpgrade = Self::U, - Output = (libp2p_identity::PeerId, StreamMuxerBox), - > + Send - + Unpin - + 'static -{ - type E: Send + Sync + 'static; - type D: Send; - type U: Send; -} - -impl BuildableTransport for T -where - T: Transport + Send + Unpin + 'static, - ::Error: Send + Sync + 'static, - ::Dial: Send, - ::ListenerUpgrade: Send, -{ - type E = T::Error; - type D = T::Dial; - type U = T::ListenerUpgrade; -} - +#[cfg(all(feature = "async-std", feature = "tcp"))] impl TcpBuilder { - pub fn with_tcp(self) -> DnsBuilder { - DnsBuilder { - tcp: libp2p_tcp::async_io::Transport::new(libp2p_tcp::Config::new().nodelay(true)) - .upgrade(libp2p_core::upgrade::Version::V1) - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + pub fn with_tcp(self) -> RelayBuilder { + RelayBuilder { + transport: libp2p_tcp::async_io::Transport::new( + libp2p_tcp::Config::new().nodelay(true), + ) + .upgrade(libp2p_core::upgrade::Version::V1) + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), keypair: self.keypair, phantom: PhantomData, } } } +#[cfg(all(feature = "tokio", feature = "tcp"))] impl TcpBuilder { - pub fn with_tcp(self) -> DnsBuilder { - DnsBuilder { - tcp: libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::new().nodelay(true)) + pub fn with_tcp(self) -> RelayBuilder { + RelayBuilder { + transport: libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::new().nodelay(true)) .upgrade(libp2p_core::upgrade::Version::V1) .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) @@ -88,80 +64,75 @@ impl TcpBuilder { } } -pub struct DnsBuilder { - tcp: Tcp, +// TODO: without_tcp + +pub struct RelayBuilder { + transport: T, keypair: libp2p_identity::Keypair, phantom: PhantomData

, } -impl DnsBuilder -where - T: Transport + Send + Unpin + 'static, - ::Error: Send + Sync + 'static, - ::Dial: Send, - ::ListenerUpgrade: Send, -{ - pub async fn with_dns(self) -> RelayBuilder> { - RelayBuilder { - transport: libp2p_dns::DnsConfig::system(self.tcp) - .await - .expect("TODO: Handle"), - keypair: self.keypair, - phantom: PhantomData, - } - } -} - -impl DnsBuilder -where - T: Transport + Send + Unpin + 'static, - ::Error: Send + Sync + 'static, - ::Dial: Send, - ::ListenerUpgrade: Send, -{ - pub fn with_dns(self) -> RelayBuilder> { - RelayBuilder { - transport: libp2p_dns::TokioDnsConfig::system(self.tcp).expect("TODO: Handle"), +#[cfg(feature = "relay")] +impl RelayBuilder { + pub fn with_relay( + self, + relay_transport: libp2p_relay::client::Transport, + ) -> DnsBuilder { + DnsBuilder { + transport: self + .transport + .or_transport( + relay_transport + .upgrade(libp2p_core::upgrade::Version::V1) + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + ) + .map(|either, _| either.into_inner()), keypair: self.keypair, phantom: PhantomData, } } } -impl DnsBuilder { - pub fn without_dns(self) -> RelayBuilder { - RelayBuilder { - transport: self.tcp, +impl RelayBuilder { + pub fn without_relay(self) -> DnsBuilder { + DnsBuilder { + transport: self.transport, keypair: self.keypair, phantom: PhantomData, } } } -pub struct RelayBuilder { +pub struct DnsBuilder { transport: T, keypair: libp2p_identity::Keypair, phantom: PhantomData

, } -impl RelayBuilder -where - T: Transport + Send + Unpin + 'static, - ::Error: Send + 'static, - ::Dial: Send, -{ - pub fn with_relay( - self, - relay_transport: libp2p_relay::client::Transport, - ) -> Builder { +#[cfg(all(feature = "async-std", feature = "dns"))] +impl DnsBuilder { + pub async fn with_dns(self) -> Builder> { + Builder { + transport: libp2p_dns::DnsConfig::system(self.transport) + .await + .expect("TODO: Handle"), + } + } +} + +#[cfg(all(feature = "tokio", feature = "dns"))] +impl DnsBuilder { + pub fn with_dns(self) -> Builder> { Builder { - transport: self.transport.or_transport(relay_transport), + transport: libp2p_dns::TokioDnsConfig::system(self.transport).expect("TODO: Handle"), } } } -impl RelayBuilder { - pub fn without_relay(self) -> Builder { +impl DnsBuilder { + pub fn without_dns(self) -> Builder { Builder { transport: self.transport, } @@ -178,19 +149,81 @@ impl Builder { } } +#[cfg(feature = "async-std")] +pub enum AsyncStd {} + +#[cfg(feature = "tokio")] +pub enum Tokio {} + +pub trait BuildableTransport: + Transport< + Error = Self::E, + Dial = Self::D, + ListenerUpgrade = Self::U, + Output = (libp2p_identity::PeerId, StreamMuxerBox), + > + Send + + Unpin + + 'static +{ + type E: Send + Sync + 'static; + type D: Send; + type U: Send; +} + +impl BuildableTransport for T +where + T: Transport + Send + Unpin + 'static, + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, +{ + type E = T::Error; + type D = T::Dial; + type U = T::ListenerUpgrade; +} + #[cfg(test)] mod tests { use super::*; #[test] + #[cfg(all(feature = "tokio", feature = "tcp"))] fn tcp() { let key = libp2p_identity::Keypair::generate_ed25519(); let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = TransportBuilder::new(key) .with_tokio() .with_tcp() + .without_relay() + .without_dns() + .build(); + } + + #[test] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "relay"))] + fn tcp_relay() { + let key = libp2p_identity::Keypair::generate_ed25519(); + let (relay_transport, _) = libp2p_relay::client::new(key.public().to_peer_id()); + + let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = + TransportBuilder::new(key) + .with_tokio() + .with_tcp() + .with_relay(relay_transport) .without_dns() + .build(); + } + + #[test] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "dns"))] + fn tcp_dns() { + let key = libp2p_identity::Keypair::generate_ed25519(); + let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = + TransportBuilder::new(key) + .with_tokio() + .with_tcp() .without_relay() + .with_dns() .build(); } } From a42f09a667e0562a1451c091aee008f6e15f5383 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 30 Jun 2023 20:30:25 +0900 Subject: [PATCH 004/171] Add OtherTransportBuilder --- libp2p/src/builder.rs | 52 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index db6b66d9a5d..d6ade2e815e 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -113,8 +113,8 @@ pub struct DnsBuilder { #[cfg(all(feature = "async-std", feature = "dns"))] impl DnsBuilder { - pub async fn with_dns(self) -> Builder> { - Builder { + pub async fn with_dns(self) -> OtherTransportBuilder> { + OtherTransportBuilder { transport: libp2p_dns::DnsConfig::system(self.transport) .await .expect("TODO: Handle"), @@ -124,18 +124,43 @@ impl DnsBuilder { #[cfg(all(feature = "tokio", feature = "dns"))] impl DnsBuilder { - pub fn with_dns(self) -> Builder> { - Builder { + pub fn with_dns(self) -> OtherTransportBuilder> { + OtherTransportBuilder { transport: libp2p_dns::TokioDnsConfig::system(self.transport).expect("TODO: Handle"), } } } impl DnsBuilder { - pub fn without_dns(self) -> Builder { + pub fn without_dns(self) -> OtherTransportBuilder { + OtherTransportBuilder { + transport: self.transport, + } + } +} + +pub struct OtherTransportBuilder { + transport: T, +} + +impl OtherTransportBuilder { + pub fn with_other_transport( + self, + transport: impl BuildableTransport, + ) -> OtherTransportBuilder { + OtherTransportBuilder { + transport: self + .transport + .or_transport(transport) + .map(|either, _| either.into_inner()), + } + } + + pub fn build(self) -> libp2p_core::transport::Boxed<::Output> { Builder { transport: self.transport, } + .build() } } @@ -226,4 +251,21 @@ mod tests { .with_dns() .build(); } + + /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. QUIC or WebRTC. + #[test] + #[cfg(all(feature = "tokio", feature = "tcp"))] + fn tcp_other_transport_other_transport() { + let key = libp2p_identity::Keypair::generate_ed25519(); + let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = + TransportBuilder::new(key) + .with_tokio() + .with_tcp() + .without_relay() + .without_dns() + .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .build(); + } } From 321f5886a09b346f9c9ecda7883ba79ebee03088 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 30 Jun 2023 20:39:36 +0900 Subject: [PATCH 005/171] Fix order --- libp2p/src/builder.rs | 79 ++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index d6ade2e815e..09864de6c5e 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -77,8 +77,8 @@ impl RelayBuilder { pub fn with_relay( self, relay_transport: libp2p_relay::client::Transport, - ) -> DnsBuilder { - DnsBuilder { + ) -> OtherTransportBuilder { + OtherTransportBuilder { transport: self .transport .or_transport( @@ -96,7 +96,39 @@ impl RelayBuilder { } impl RelayBuilder { - pub fn without_relay(self) -> DnsBuilder { + pub fn without_relay(self) -> OtherTransportBuilder { + OtherTransportBuilder { + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct OtherTransportBuilder { + transport: T, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +impl OtherTransportBuilder { + pub fn with_other_transport( + self, + // TODO: could as well be a closure that takes keypair and maybe provider? + transport: impl BuildableTransport, + ) -> OtherTransportBuilder { + OtherTransportBuilder { + transport: self + .transport + .or_transport(transport) + .map(|either, _| either.into_inner()), + keypair: self.keypair, + phantom: PhantomData, + } + } + + // TODO: Not the ideal name. + pub fn no_more_other_transports(self) -> DnsBuilder { DnsBuilder { transport: self.transport, keypair: self.keypair, @@ -113,8 +145,8 @@ pub struct DnsBuilder { #[cfg(all(feature = "async-std", feature = "dns"))] impl DnsBuilder { - pub async fn with_dns(self) -> OtherTransportBuilder> { - OtherTransportBuilder { + pub async fn with_dns(self) -> Builder> { + Builder { transport: libp2p_dns::DnsConfig::system(self.transport) .await .expect("TODO: Handle"), @@ -124,43 +156,18 @@ impl DnsBuilder { #[cfg(all(feature = "tokio", feature = "dns"))] impl DnsBuilder { - pub fn with_dns(self) -> OtherTransportBuilder> { - OtherTransportBuilder { + pub fn with_dns(self) -> Builder> { + Builder { transport: libp2p_dns::TokioDnsConfig::system(self.transport).expect("TODO: Handle"), } } } impl DnsBuilder { - pub fn without_dns(self) -> OtherTransportBuilder { - OtherTransportBuilder { - transport: self.transport, - } - } -} - -pub struct OtherTransportBuilder { - transport: T, -} - -impl OtherTransportBuilder { - pub fn with_other_transport( - self, - transport: impl BuildableTransport, - ) -> OtherTransportBuilder { - OtherTransportBuilder { - transport: self - .transport - .or_transport(transport) - .map(|either, _| either.into_inner()), - } - } - - pub fn build(self) -> libp2p_core::transport::Boxed<::Output> { + pub fn without_dns(self) -> Builder { Builder { transport: self.transport, } - .build() } } @@ -220,6 +227,7 @@ mod tests { .with_tokio() .with_tcp() .without_relay() + .no_more_other_transports() .without_dns() .build(); } @@ -235,6 +243,7 @@ mod tests { .with_tokio() .with_tcp() .with_relay(relay_transport) + .no_more_other_transports() .without_dns() .build(); } @@ -248,6 +257,7 @@ mod tests { .with_tokio() .with_tcp() .without_relay() + .no_more_other_transports() .with_dns() .build(); } @@ -262,10 +272,11 @@ mod tests { .with_tokio() .with_tcp() .without_relay() - .without_dns() .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .no_more_other_transports() + .without_dns() .build(); } } From 4c11afc2dea8dcd8418b5d135e2a51d27b375f3d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 1 Jul 2023 21:34:35 +0900 Subject: [PATCH 006/171] Introduce SwarmBuilder - Allow providing or generating identity - Use V1Lazy - Make NetworkBehaviour constructor take relay Behaviour in case with_relay was called - Rename to AuthenticatedMultiplexedTransport --- libp2p/src/builder.rs | 273 ++++++++++++++++++++++++++++++------------ 1 file changed, 195 insertions(+), 78 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 09864de6c5e..f1d460ab0ba 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,15 +1,28 @@ use libp2p_core::{muxing::StreamMuxerBox, Transport}; +use libp2p_swarm::NetworkBehaviour; use std::marker::PhantomData; -pub struct TransportBuilder { - keypair: libp2p_identity::Keypair, -} +pub struct SwarmBuilder {} + +impl SwarmBuilder { + pub fn new() -> SwarmBuilder { + Self {} + } -impl TransportBuilder { - pub fn new(keypair: libp2p_identity::Keypair) -> Self { - Self { keypair } + pub fn with_new_identity(self) -> ProviderBuilder { + self.with_existing_identity(libp2p_identity::Keypair::generate_ed25519()) } + pub fn with_existing_identity(self, keypair: libp2p_identity::Keypair) -> ProviderBuilder { + ProviderBuilder { keypair } + } +} + +pub struct ProviderBuilder { + keypair: libp2p_identity::Keypair, +} + +impl ProviderBuilder { #[cfg(feature = "async-std")] pub fn with_async_std(self) -> TcpBuilder { TcpBuilder { @@ -34,12 +47,12 @@ pub struct TcpBuilder

{ #[cfg(all(feature = "async-std", feature = "tcp"))] impl TcpBuilder { - pub fn with_tcp(self) -> RelayBuilder { + pub fn with_tcp(self) -> RelayBuilder { RelayBuilder { transport: libp2p_tcp::async_io::Transport::new( libp2p_tcp::Config::new().nodelay(true), ) - .upgrade(libp2p_core::upgrade::Version::V1) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), @@ -51,10 +64,10 @@ impl TcpBuilder { #[cfg(all(feature = "tokio", feature = "tcp"))] impl TcpBuilder { - pub fn with_tcp(self) -> RelayBuilder { + pub fn with_tcp(self) -> RelayBuilder { RelayBuilder { transport: libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::new().nodelay(true)) - .upgrade(libp2p_core::upgrade::Version::V1) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), @@ -73,111 +86,207 @@ pub struct RelayBuilder { } #[cfg(feature = "relay")] -impl RelayBuilder { +impl RelayBuilder { + // TODO: This should be with_relay_client. + // TODO: Ideally one can configure it. pub fn with_relay( self, - relay_transport: libp2p_relay::client::Transport, - ) -> OtherTransportBuilder { + ) -> OtherTransportBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + > { + let (relay_transport, relay_behaviour) = + libp2p_relay::client::new(self.keypair.public().to_peer_id()); + OtherTransportBuilder { transport: self .transport .or_transport( relay_transport - .upgrade(libp2p_core::upgrade::Version::V1) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), ) .map(|either, _| either.into_inner()), keypair: self.keypair, + relay_behaviour, phantom: PhantomData, } } } +pub struct NoRelayBehaviour; + impl RelayBuilder { - pub fn without_relay(self) -> OtherTransportBuilder { + pub fn without_relay(self) -> OtherTransportBuilder { OtherTransportBuilder { transport: self.transport, + relay_behaviour: NoRelayBehaviour, keypair: self.keypair, phantom: PhantomData, } } } -pub struct OtherTransportBuilder { +pub struct OtherTransportBuilder { transport: T, + relay_behaviour: R, keypair: libp2p_identity::Keypair, phantom: PhantomData

, } -impl OtherTransportBuilder { +impl OtherTransportBuilder { pub fn with_other_transport( self, // TODO: could as well be a closure that takes keypair and maybe provider? - transport: impl BuildableTransport, - ) -> OtherTransportBuilder { + transport: impl AuthenticatedMultiplexedTransport, + ) -> OtherTransportBuilder { OtherTransportBuilder { transport: self .transport .or_transport(transport) .map(|either, _| either.into_inner()), + relay_behaviour: self.relay_behaviour, keypair: self.keypair, phantom: PhantomData, } } // TODO: Not the ideal name. - pub fn no_more_other_transports(self) -> DnsBuilder { + pub fn no_more_other_transports( + self, + ) -> DnsBuilder { DnsBuilder { transport: self.transport, + relay_behaviour: self.relay_behaviour, keypair: self.keypair, phantom: PhantomData, } } } -pub struct DnsBuilder { +pub struct DnsBuilder { transport: T, + relay_behaviour: R, keypair: libp2p_identity::Keypair, phantom: PhantomData

, } #[cfg(all(feature = "async-std", feature = "dns"))] -impl DnsBuilder { - pub async fn with_dns(self) -> Builder> { - Builder { +impl DnsBuilder { + pub async fn with_dns(self) -> BehaviourBuilder { + BehaviourBuilder { + keypair: self.keypair, + relay_behaviour: self.relay_behaviour, + // TODO: Timeout needed? transport: libp2p_dns::DnsConfig::system(self.transport) .await - .expect("TODO: Handle"), + .expect("TODO: Handle") + .boxed(), + phantom: PhantomData, } } } #[cfg(all(feature = "tokio", feature = "dns"))] -impl DnsBuilder { - pub fn with_dns(self) -> Builder> { +impl DnsBuilder { + pub fn with_dns(self) -> BehaviourBuilder { + BehaviourBuilder { + keypair: self.keypair, + relay_behaviour: self.relay_behaviour, + // TODO: Timeout needed? + transport: libp2p_dns::TokioDnsConfig::system(self.transport) + .expect("TODO: Handle") + .boxed(), + phantom: PhantomData, + } + } +} + +impl DnsBuilder { + pub fn without_dns(self) -> BehaviourBuilder { + BehaviourBuilder { + keypair: self.keypair, + relay_behaviour: self.relay_behaviour, + // TODO: Timeout needed? + transport: self.transport.boxed(), + phantom: PhantomData, + } + } +} + +pub struct BehaviourBuilder { + keypair: libp2p_identity::Keypair, + relay_behaviour: R, + transport: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)>, + phantom: PhantomData

, +} + +#[cfg(feature = "relay")] +impl

BehaviourBuilder { + // TODO: The close should provide the relay transport in case the user used with_relay. + pub fn with_behaviour( + self, + mut constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, + ) -> Builder { Builder { - transport: libp2p_dns::TokioDnsConfig::system(self.transport).expect("TODO: Handle"), + behaviour: constructor(&self.keypair, self.relay_behaviour), + keypair: self.keypair, + transport: self.transport, + phantom: PhantomData, } } } -impl DnsBuilder { - pub fn without_dns(self) -> Builder { +impl

BehaviourBuilder { + // TODO: The close should provide the relay transport in case the user used with_relay. + pub fn with_behaviour( + self, + mut constructor: impl FnMut(&libp2p_identity::Keypair) -> B, + ) -> Builder { Builder { + behaviour: constructor(&self.keypair), + keypair: self.keypair, transport: self.transport, + phantom: PhantomData, } } } -pub struct Builder { - transport: T, +pub struct Builder { + keypair: libp2p_identity::Keypair, + behaviour: B, + transport: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)>, + phantom: PhantomData

, +} + +#[cfg(feature = "async-std")] +impl Builder { + // TODO: The close should provide the relay transport in case the user used with_relay. + pub fn build(self) -> libp2p_swarm::Swarm { + // TODO: Generic over the runtime! + libp2p_swarm::SwarmBuilder::with_async_std_executor( + self.transport, + self.behaviour, + self.keypair.public().to_peer_id(), + ) + .build() + } } -impl Builder { - pub fn build(self) -> libp2p_core::transport::Boxed<::Output> { - self.transport.boxed() +#[cfg(feature = "tokio")] +impl Builder { + // TODO: The close should provide the relay transport in case the user used with_relay. + pub fn build(self) -> libp2p_swarm::Swarm { + // TODO: Generic over the runtime! + libp2p_swarm::SwarmBuilder::with_tokio_executor( + self.transport, + self.behaviour, + self.keypair.public().to_peer_id(), + ) + .build() } } @@ -187,7 +296,7 @@ pub enum AsyncStd {} #[cfg(feature = "tokio")] pub enum Tokio {} -pub trait BuildableTransport: +pub trait AuthenticatedMultiplexedTransport: Transport< Error = Self::E, Dial = Self::D, @@ -202,7 +311,7 @@ pub trait BuildableTransport: type U: Send; } -impl BuildableTransport for T +impl AuthenticatedMultiplexedTransport for T where T: Transport + Send + Unpin + 'static, ::Error: Send + Sync + 'static, @@ -221,62 +330,70 @@ mod tests { #[test] #[cfg(all(feature = "tokio", feature = "tcp"))] fn tcp() { - let key = libp2p_identity::Keypair::generate_ed25519(); - let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = - TransportBuilder::new(key) - .with_tokio() - .with_tcp() - .without_relay() - .no_more_other_transports() - .without_dns() - .build(); + let _: libp2p_swarm::Swarm = SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .without_relay() + .no_more_other_transports() + .without_dns() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .build(); } #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "relay"))] fn tcp_relay() { - let key = libp2p_identity::Keypair::generate_ed25519(); - let (relay_transport, _) = libp2p_relay::client::new(key.public().to_peer_id()); - - let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = - TransportBuilder::new(key) - .with_tokio() - .with_tcp() - .with_relay(relay_transport) - .no_more_other_transports() - .without_dns() - .build(); + #[derive(NetworkBehaviour)] + #[behaviour(prelude = "libp2p_swarm::derive_prelude")] + struct Behaviour { + dummy: libp2p_swarm::dummy::Behaviour, + relay: libp2p_relay::client::Behaviour, + } + + let _: libp2p_swarm::Swarm = SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .with_relay() + .no_more_other_transports() + .without_dns() + .with_behaviour(|_, relay| Behaviour { + dummy: libp2p_swarm::dummy::Behaviour, + relay, + }) + .build(); } #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "dns"))] fn tcp_dns() { - let key = libp2p_identity::Keypair::generate_ed25519(); - let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = - TransportBuilder::new(key) - .with_tokio() - .with_tcp() - .without_relay() - .no_more_other_transports() - .with_dns() - .build(); + let _: libp2p_swarm::Swarm = SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .without_relay() + .no_more_other_transports() + .with_dns() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .build(); } /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. QUIC or WebRTC. #[test] #[cfg(all(feature = "tokio", feature = "tcp"))] fn tcp_other_transport_other_transport() { - let key = libp2p_identity::Keypair::generate_ed25519(); - let _: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)> = - TransportBuilder::new(key) - .with_tokio() - .with_tcp() - .without_relay() - .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) - .no_more_other_transports() - .without_dns() - .build(); + let _: libp2p_swarm::Swarm = SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .without_relay() + .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .no_more_other_transports() + .without_dns() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .build(); } } From f8e0fe7be130d01f78702383eac095f879e28588 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 8 Jul 2023 12:06:59 +0900 Subject: [PATCH 007/171] Add with_custom_tcp --- libp2p/src/builder.rs | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index f1d460ab0ba..2a8df773457 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -47,15 +47,22 @@ pub struct TcpBuilder

{ #[cfg(all(feature = "async-std", feature = "tcp"))] impl TcpBuilder { - pub fn with_tcp(self) -> RelayBuilder { + pub fn with_default_tcp( + self, + ) -> RelayBuilder { + self.with_custom_tcp(libp2p_tcp::Config::default()) + } + + pub fn with_custom_tcp( + self, + config: libp2p_tcp::Config, + ) -> RelayBuilder { RelayBuilder { - transport: libp2p_tcp::async_io::Transport::new( - libp2p_tcp::Config::new().nodelay(true), - ) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + transport: libp2p_tcp::async_io::Transport::new(config) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), keypair: self.keypair, phantom: PhantomData, } @@ -64,9 +71,16 @@ impl TcpBuilder { #[cfg(all(feature = "tokio", feature = "tcp"))] impl TcpBuilder { - pub fn with_tcp(self) -> RelayBuilder { + pub fn with_default_tcp(self) -> RelayBuilder { + self.with_custom_tcp(libp2p_tcp::Config::default()) + } + + pub fn with_custom_tcp( + self, + config: libp2p_tcp::Config, + ) -> RelayBuilder { RelayBuilder { - transport: libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::new().nodelay(true)) + transport: libp2p_tcp::tokio::Transport::new(config) .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) @@ -333,7 +347,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_tcp() + .with_default_tcp() .without_relay() .no_more_other_transports() .without_dns() @@ -354,7 +368,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_tcp() + .with_default_tcp() .with_relay() .no_more_other_transports() .without_dns() @@ -371,7 +385,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_tcp() + .with_default_tcp() .without_relay() .no_more_other_transports() .with_dns() @@ -386,7 +400,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_tcp() + .with_default_tcp() .without_relay() .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) From 343ba2d2729c4349544c4b027f8a2d6cc29e398b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 8 Jul 2023 12:07:40 +0900 Subject: [PATCH 008/171] Have with_other_transport take keypair closure --- libp2p/src/builder.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 2a8df773457..9a819f99da0 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -152,15 +152,14 @@ pub struct OtherTransportBuilder { } impl OtherTransportBuilder { - pub fn with_other_transport( + pub fn with_other_transport( self, - // TODO: could as well be a closure that takes keypair and maybe provider? - transport: impl AuthenticatedMultiplexedTransport, + mut constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, ) -> OtherTransportBuilder { OtherTransportBuilder { transport: self .transport - .or_transport(transport) + .or_transport(constructor(&self.keypair)) .map(|either, _| either.into_inner()), relay_behaviour: self.relay_behaviour, keypair: self.keypair, @@ -402,9 +401,9 @@ mod tests { .with_tokio() .with_default_tcp() .without_relay() - .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .no_more_other_transports() .without_dns() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) From be220083e3e24d20b3d776ea770855d1e979adaf Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 8 Jul 2023 12:08:10 +0900 Subject: [PATCH 009/171] Fully qualify libp2p_swarm::NetworkBehaviour --- libp2p/src/builder.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 9a819f99da0..ba6bd5b9a1e 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,5 +1,4 @@ use libp2p_core::{muxing::StreamMuxerBox, Transport}; -use libp2p_swarm::NetworkBehaviour; use std::marker::PhantomData; pub struct SwarmBuilder {} @@ -276,7 +275,7 @@ pub struct Builder { } #[cfg(feature = "async-std")] -impl Builder { +impl Builder { // TODO: The close should provide the relay transport in case the user used with_relay. pub fn build(self) -> libp2p_swarm::Swarm { // TODO: Generic over the runtime! @@ -290,7 +289,7 @@ impl Builder { } #[cfg(feature = "tokio")] -impl Builder { +impl Builder { // TODO: The close should provide the relay transport in case the user used with_relay. pub fn build(self) -> libp2p_swarm::Swarm { // TODO: Generic over the runtime! @@ -357,7 +356,7 @@ mod tests { #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "relay"))] fn tcp_relay() { - #[derive(NetworkBehaviour)] + #[derive(libp2p_swarm::NetworkBehaviour)] #[behaviour(prelude = "libp2p_swarm::derive_prelude")] struct Behaviour { dummy: libp2p_swarm::dummy::Behaviour, From 44b9ac427b2e83be246ebb13203d66d0fe426103 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 8 Jul 2023 12:21:24 +0900 Subject: [PATCH 010/171] Use SwwarmBuilder in DCUtR example --- Cargo.lock | 1 + examples/dcutr/Cargo.toml | 1 + examples/dcutr/src/main.rs | 82 ++++++++++++++------------------------ libp2p/src/lib.rs | 2 +- 4 files changed, 32 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a98c360c2a1..4a80e0690b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1251,6 +1251,7 @@ dependencies = [ name = "dcutr" version = "0.1.0" dependencies = [ + "async-std", "clap", "env_logger 0.10.0", "futures", diff --git a/examples/dcutr/Cargo.toml b/examples/dcutr/Cargo.toml index fd04b73585d..2349e5a921c 100644 --- a/examples/dcutr/Cargo.toml +++ b/examples/dcutr/Cargo.toml @@ -6,6 +6,7 @@ publish = false license = "MIT" [dependencies] +async-std = { version = "1.12.0", features = ["attributes"] } clap = { version = "4.3.8", features = ["derive"] } env_logger = "0.10.0" futures = "0.3.28" diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 8359bb1902a..e9490408ea1 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -21,23 +21,16 @@ #![doc = include_str!("../README.md")] use clap::Parser; -use futures::{ - executor::{block_on, ThreadPool}, - future::{Either, FutureExt}, - stream::StreamExt, -}; +use futures::{executor::block_on, future::FutureExt, stream::StreamExt}; use libp2p::{ core::{ multiaddr::{Multiaddr, Protocol}, muxing::StreamMuxerBox, transport::Transport, - upgrade, }, - dcutr, - dns::DnsConfig, - identify, identity, noise, ping, relay, - swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, yamux, PeerId, + dcutr, identify, identity, ping, relay, + swarm::{NetworkBehaviour, SwarmEvent}, + tcp, PeerId, }; use libp2p_quic as quic; use log::info; @@ -81,38 +74,12 @@ impl FromStr for Mode { } } -fn main() -> Result<(), Box> { +#[async_std::main] +async fn main() -> Result<(), Box> { env_logger::init(); let opts = Opts::parse(); - let local_key = generate_ed25519(opts.secret_key_seed); - let local_peer_id = PeerId::from(local_key.public()); - info!("Local peer id: {:?}", local_peer_id); - - let (relay_transport, client) = relay::client::new(local_peer_id); - - let transport = { - let relay_tcp_quic_transport = relay_transport - .or_transport(tcp::async_io::Transport::new( - tcp::Config::default().port_reuse(true), - )) - .upgrade(upgrade::Version::V1) - .authenticate(noise::Config::new(&local_key).unwrap()) - .multiplex(yamux::Config::default()) - .or_transport(quic::async_std::Transport::new(quic::Config::new( - &local_key, - ))); - - block_on(DnsConfig::system(relay_tcp_quic_transport)) - .unwrap() - .map(|either_output, _| match either_output { - Either::Left((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), - Either::Right((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), - }) - .boxed() - }; - #[derive(NetworkBehaviour)] #[behaviour(to_swarm = "Event")] struct Behaviour { @@ -155,21 +122,30 @@ fn main() -> Result<(), Box> { } } - let behaviour = Behaviour { - relay_client: client, - ping: ping::Behaviour::new(ping::Config::new()), - identify: identify::Behaviour::new(identify::Config::new( - "/TODO/0.0.1".to_string(), - local_key.public(), - )), - dcutr: dcutr::Behaviour::new(local_peer_id), - }; + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_existing_identity(generate_ed25519(opts.secret_key_seed)) + .with_async_std() + .with_custom_tcp(tcp::Config::default().port_reuse(true).nodelay(true)) + .with_relay() + .with_other_transport(|keypair| { + quic::async_std::Transport::new(quic::Config::new(&keypair)) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) + }) + .no_more_other_transports() + .with_dns() + .await + .with_behaviour(|keypair, relay_behaviour| Behaviour { + relay_client: relay_behaviour, + ping: ping::Behaviour::new(ping::Config::new()), + identify: identify::Behaviour::new(identify::Config::new( + "/TODO/0.0.1".to_string(), + keypair.public(), + )), + dcutr: dcutr::Behaviour::new(keypair.public().to_peer_id()), + }) + .build(); - let mut swarm = match ThreadPool::new() { - Ok(tp) => SwarmBuilder::with_executor(transport, behaviour, local_peer_id, tp), - Err(_) => SwarmBuilder::without_executor(transport, behaviour, local_peer_id), - } - .build(); + info!("Local peer id: {:?}", swarm.local_peer_id()); swarm .listen_on("/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap()) diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 64e68c97e21..7783920feee 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -135,7 +135,7 @@ pub use libp2p_webtransport_websys as webtransport_websys; #[doc(inline)] pub use libp2p_yamux as yamux; -mod builder; +pub mod builder; mod transport_ext; pub mod bandwidth; From eba4607d4735c578663c49d85f8d730bf58057a9 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 29 Jul 2023 12:56:03 +0200 Subject: [PATCH 011/171] Remove resolved TODO --- libp2p/src/builder.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index ba6bd5b9a1e..563fac757f1 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -238,7 +238,6 @@ pub struct BehaviourBuilder { #[cfg(feature = "relay")] impl

BehaviourBuilder { - // TODO: The close should provide the relay transport in case the user used with_relay. pub fn with_behaviour( self, mut constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, @@ -253,7 +252,6 @@ impl

BehaviourBuilder { } impl

BehaviourBuilder { - // TODO: The close should provide the relay transport in case the user used with_relay. pub fn with_behaviour( self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> B, From 5c0593f5aac1f30eafdf34c279efc3cef9b36835 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 29 Jul 2023 21:15:03 +0200 Subject: [PATCH 012/171] Remove custom TCP option I suggest shipping a minimal Builder at first. Users that need advanced features can use the `with_other_transport` method or build a `Transport` without the builder. --- libp2p/src/builder.rs | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 563fac757f1..7ba96fc352c 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -46,18 +46,9 @@ pub struct TcpBuilder

{ #[cfg(all(feature = "async-std", feature = "tcp"))] impl TcpBuilder { - pub fn with_default_tcp( - self, - ) -> RelayBuilder { - self.with_custom_tcp(libp2p_tcp::Config::default()) - } - - pub fn with_custom_tcp( - self, - config: libp2p_tcp::Config, - ) -> RelayBuilder { + pub fn with_tcp(self) -> RelayBuilder { RelayBuilder { - transport: libp2p_tcp::async_io::Transport::new(config) + transport: libp2p_tcp::async_io::Transport::new(Default::default()) .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) @@ -70,16 +61,9 @@ impl TcpBuilder { #[cfg(all(feature = "tokio", feature = "tcp"))] impl TcpBuilder { - pub fn with_default_tcp(self) -> RelayBuilder { - self.with_custom_tcp(libp2p_tcp::Config::default()) - } - - pub fn with_custom_tcp( - self, - config: libp2p_tcp::Config, - ) -> RelayBuilder { + pub fn with_tcp(self) -> RelayBuilder { RelayBuilder { - transport: libp2p_tcp::tokio::Transport::new(config) + transport: libp2p_tcp::tokio::Transport::new(Default::default()) .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) @@ -101,7 +85,6 @@ pub struct RelayBuilder { #[cfg(feature = "relay")] impl RelayBuilder { // TODO: This should be with_relay_client. - // TODO: Ideally one can configure it. pub fn with_relay( self, ) -> OtherTransportBuilder< @@ -343,7 +326,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_default_tcp() + .with_tcp() .without_relay() .no_more_other_transports() .without_dns() @@ -364,7 +347,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_default_tcp() + .with_tcp() .with_relay() .no_more_other_transports() .without_dns() @@ -381,7 +364,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_default_tcp() + .with_tcp() .without_relay() .no_more_other_transports() .with_dns() @@ -396,7 +379,7 @@ mod tests { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() - .with_default_tcp() + .with_tcp() .without_relay() .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) From 777542dae6acc95309bc02dd8b5e619796e42c28 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 29 Jul 2023 21:26:54 +0200 Subject: [PATCH 013/171] Add without_tcp option --- libp2p/src/builder.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 7ba96fc352c..4e53526c1a3 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -74,6 +74,20 @@ impl TcpBuilder { } } +impl

TcpBuilder

{ + // TODO: This would allow one to build a faulty transport. + pub fn without_tcp(self) -> RelayBuilder { + RelayBuilder { + // TODO: Is this a good idea in a production environment? Unfortunately I don't know a + // way around it. One can not define two `with_relay` methods, one with a real transport + // using OrTransport, one with a fake transport discarding it right away. + transport: libp2p_core::transport::dummy::DummyTransport::new(), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + // TODO: without_tcp pub struct RelayBuilder { From bcf36aed1f464dff494150bc7487b9799551252b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 31 Jul 2023 09:50:14 +0200 Subject: [PATCH 014/171] feat(core): add upgrade::Map --- core/src/upgrade.rs | 2 ++ core/src/upgrade/map.rs | 77 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 core/src/upgrade/map.rs diff --git a/core/src/upgrade.rs b/core/src/upgrade.rs index f6bf72d1f4a..3219474f390 100644 --- a/core/src/upgrade.rs +++ b/core/src/upgrade.rs @@ -61,6 +61,7 @@ mod apply; mod denied; mod either; mod error; +mod map; mod pending; mod ready; mod select; @@ -74,6 +75,7 @@ use futures::future::Future; pub use self::{ denied::DeniedUpgrade, + map::Map, pending::PendingUpgrade, ready::ReadyUpgrade, select::SelectUpgrade, diff --git a/core/src/upgrade/map.rs b/core/src/upgrade/map.rs new file mode 100644 index 00000000000..ad8a593dd11 --- /dev/null +++ b/core/src/upgrade/map.rs @@ -0,0 +1,77 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use crate::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; +use futures::future::{self, TryFutureExt}; + +// TODO: Rename to MapUpgrade? +/// Upgrade applying a function to an inner upgrade. +#[derive(Debug, Clone)] +pub struct Map { + upgrade: U, + fun: F, +} + +impl Map { + /// Applies the function on the result of the upgrade. + pub fn new(upgrade: U, fun: F) -> Self { + Map { upgrade, fun } + } +} + +impl UpgradeInfo for Map +where + U: UpgradeInfo, +{ + type Info = U::Info; + type InfoIter = U::InfoIter; + + fn protocol_info(&self) -> Self::InfoIter { + self.upgrade.protocol_info() + } +} + +impl InboundUpgrade for Map +where + U: InboundUpgrade, + F: FnOnce(U::Output) -> D, +{ + type Output = D; + type Error = U::Error; + type Future = future::MapOk; + + fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future { + self.upgrade.upgrade_inbound(sock, info).map_ok(self.fun) + } +} + +impl OutboundUpgrade for Map +where + U: OutboundUpgrade, + F: FnOnce(U::Output) -> D, +{ + type Output = D; + type Error = U::Error; + type Future = future::MapOk; + + fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future { + self.upgrade.upgrade_outbound(sock, info).map_ok(self.fun) + } +} From b301850398276fdc923df60900d429ff5dd8c14f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 31 Jul 2023 09:50:50 +0200 Subject: [PATCH 015/171] feat(swarm/builder): make authentication configurable - Make tls and noise configurable. - Prevent accidental behavior change through feature change. E.g. enabling "noise" feature should not make ones transport automatically offer noise. Instead one needs to explicitly call `with_noise` and `without_noise`. --- libp2p/src/builder.rs | 318 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 291 insertions(+), 27 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 4e53526c1a3..c2974f39213 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -44,12 +44,106 @@ pub struct TcpBuilder

{ phantom: PhantomData

, } -#[cfg(all(feature = "async-std", feature = "tcp"))] -impl TcpBuilder { - pub fn with_tcp(self) -> RelayBuilder { +impl

TcpBuilder

{ + pub fn with_tcp(self) -> TcpTlsBuilder

{ + TcpTlsBuilder { + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +impl

TcpBuilder

{ + // TODO: This would allow one to build a faulty transport. + pub fn without_tcp(self) -> RelayBuilder { + RelayBuilder { + // TODO: Is this a good idea in a production environment? Unfortunately I don't know a + // way around it. One can not define two `with_relay` methods, one with a real transport + // using OrTransport, one with a fake transport discarding it right away. + transport: libp2p_core::transport::dummy::DummyTransport::new(), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct TcpTlsBuilder

{ + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +impl

TcpTlsBuilder

{ + #[cfg(feature = "tls")] + pub fn with_tls(self) -> TcpNoiseBuilder { + TcpNoiseBuilder { + keypair: self.keypair, + phantom: PhantomData, + } + } + + pub fn without_tls(self) -> TcpNoiseBuilder { + TcpNoiseBuilder { + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct TcpNoiseBuilder { + keypair: libp2p_identity::Keypair, + phantom: PhantomData<(P, A)>, +} + +#[cfg(feature = "async-std")] +impl TcpNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise(self) -> RelayBuilder { + RelayBuilder { + transport: libp2p_tcp::async_io::Transport::new(Default::default()) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + // TODO: Handle unwrap? + .authenticate(libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + )) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + keypair: self.keypair, + phantom: PhantomData, + } + } + pub fn without_noise(self) -> RelayBuilder { RelayBuilder { transport: libp2p_tcp::async_io::Transport::new(Default::default()) .upgrade(libp2p_core::upgrade::Version::V1Lazy) + // TODO: Handle unwrap? + .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +#[cfg(feature = "async-std")] +impl TcpNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise(self) -> RelayBuilder { + RelayBuilder { + transport: libp2p_tcp::async_io::Transport::new(Default::default()) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + // TODO: Handle unwrap? .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), @@ -59,13 +153,40 @@ impl TcpBuilder { } } -#[cfg(all(feature = "tokio", feature = "tcp"))] -impl TcpBuilder { - pub fn with_tcp(self) -> RelayBuilder { +#[cfg(feature = "tokio")] +impl TcpNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise(self) -> RelayBuilder { RelayBuilder { transport: libp2p_tcp::tokio::Transport::new(Default::default()) .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + // TODO: Handle unwrap? + .authenticate(libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + )) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + keypair: self.keypair, + phantom: PhantomData, + } + } + pub fn without_noise(self) -> RelayBuilder { + RelayBuilder { + transport: libp2p_tcp::tokio::Transport::new(Default::default()) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + // TODO: Handle unwrap? + .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), keypair: self.keypair, @@ -74,21 +195,25 @@ impl TcpBuilder { } } -impl

TcpBuilder

{ - // TODO: This would allow one to build a faulty transport. - pub fn without_tcp(self) -> RelayBuilder { +#[cfg(feature = "tokio")] +impl TcpNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise(self) -> RelayBuilder { RelayBuilder { - // TODO: Is this a good idea in a production environment? Unfortunately I don't know a - // way around it. One can not define two `with_relay` methods, one with a real transport - // using OrTransport, one with a fake transport discarding it right away. - transport: libp2p_core::transport::dummy::DummyTransport::new(), + transport: libp2p_tcp::tokio::Transport::new(Default::default()) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + // TODO: Handle unwrap? + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), keypair: self.keypair, phantom: PhantomData, } } } -// TODO: without_tcp +pub enum Tls {} +pub enum WithoutTls {} pub struct RelayBuilder { transport: T, @@ -96,10 +221,67 @@ pub struct RelayBuilder { phantom: PhantomData

, } +// TODO: Noise feature #[cfg(feature = "relay")] -impl RelayBuilder { +impl RelayBuilder { // TODO: This should be with_relay_client. - pub fn with_relay( + pub fn with_relay(self) -> RelayTlsBuilder { + RelayTlsBuilder { + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct NoRelayBehaviour; + +impl RelayBuilder { + pub fn without_relay(self) -> OtherTransportBuilder { + OtherTransportBuilder { + transport: self.transport, + relay_behaviour: NoRelayBehaviour, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct RelayTlsBuilder { + transport: T, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +impl RelayTlsBuilder { + #[cfg(feature = "tls")] + pub fn with_tls(self) -> RelayNoiseBuilder { + RelayNoiseBuilder { + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } + + pub fn without_tls(self) -> RelayNoiseBuilder { + RelayNoiseBuilder { + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct RelayNoiseBuilder { + transport: T, + keypair: libp2p_identity::Keypair, + phantom: PhantomData<(P, A)>, +} + +#[cfg(feature = "async-std")] +impl RelayNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( self, ) -> OtherTransportBuilder< P, @@ -115,7 +297,48 @@ impl RelayBuilder { .or_transport( relay_transport .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + // TODO: Handle unwrap? + .authenticate(libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + )) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + ) + .map(|either, _| either.into_inner()), + keypair: self.keypair, + relay_behaviour, + phantom: PhantomData, + } + } + pub fn without_noise( + self, + ) -> OtherTransportBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + > { + let (relay_transport, relay_behaviour) = + libp2p_relay::client::new(self.keypair.public().to_peer_id()); + + OtherTransportBuilder { + transport: self + .transport + .or_transport( + relay_transport + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + // TODO: Handle unwrap? + .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), ) @@ -127,14 +350,33 @@ impl RelayBuilder { } } -pub struct NoRelayBehaviour; +#[cfg(feature = "async-std")] +impl RelayNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> OtherTransportBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + > { + let (relay_transport, relay_behaviour) = + libp2p_relay::client::new(self.keypair.public().to_peer_id()); -impl RelayBuilder { - pub fn without_relay(self) -> OtherTransportBuilder { OtherTransportBuilder { - transport: self.transport, - relay_behaviour: NoRelayBehaviour, + transport: self + .transport + .or_transport( + relay_transport + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + // TODO: Handle unwrap? + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + ) + .map(|either, _| either.into_inner()), keypair: self.keypair, + relay_behaviour, phantom: PhantomData, } } @@ -335,12 +577,14 @@ mod tests { use super::*; #[test] - #[cfg(all(feature = "tokio", feature = "tcp"))] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] fn tcp() { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() + .with_tls() + .with_noise() .without_relay() .no_more_other_transports() .without_dns() @@ -349,7 +593,13 @@ mod tests { } #[test] - #[cfg(all(feature = "tokio", feature = "tcp", feature = "relay"))] + #[cfg(all( + feature = "tokio", + feature = "tcp", + feature = "tls", + feature = "noise", + feature = "relay" + ))] fn tcp_relay() { #[derive(libp2p_swarm::NetworkBehaviour)] #[behaviour(prelude = "libp2p_swarm::derive_prelude")] @@ -362,7 +612,11 @@ mod tests { .with_new_identity() .with_tokio() .with_tcp() + .with_tls() + .with_noise() .with_relay() + .with_tls() + .with_noise() .no_more_other_transports() .without_dns() .with_behaviour(|_, relay| Behaviour { @@ -373,12 +627,20 @@ mod tests { } #[test] - #[cfg(all(feature = "tokio", feature = "tcp", feature = "dns"))] + #[cfg(all( + feature = "tokio", + feature = "tcp", + feature = "tls", + feature = "noise", + feature = "dns" + ))] fn tcp_dns() { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() + .with_tls() + .with_noise() .without_relay() .no_more_other_transports() .with_dns() @@ -388,12 +650,14 @@ mod tests { /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. QUIC or WebRTC. #[test] - #[cfg(all(feature = "tokio", feature = "tcp"))] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] fn tcp_other_transport_other_transport() { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() + .with_tls() + .with_noise() .without_relay() .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) From 7acc531cb2923d132c755c27589b1c5506e90e95 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 31 Jul 2023 10:02:53 +0200 Subject: [PATCH 016/171] Feature flag for relay --- libp2p/src/builder.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index c2974f39213..a9d6c21f8fd 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -94,7 +94,7 @@ pub struct TcpNoiseBuilder { phantom: PhantomData<(P, A)>, } -#[cfg(feature = "async-std")] +#[cfg(all(feature = "async-std", feature = "tls"))] impl TcpNoiseBuilder { #[cfg(feature = "noise")] pub fn with_noise(self) -> RelayBuilder { @@ -247,12 +247,14 @@ impl RelayBuilder { } } +#[cfg(feature = "relay")] pub struct RelayTlsBuilder { transport: T, keypair: libp2p_identity::Keypair, phantom: PhantomData

, } +#[cfg(feature = "relay")] impl RelayTlsBuilder { #[cfg(feature = "tls")] pub fn with_tls(self) -> RelayNoiseBuilder { @@ -272,13 +274,14 @@ impl RelayTlsBuilder { } } +#[cfg(feature = "relay")] pub struct RelayNoiseBuilder { transport: T, keypair: libp2p_identity::Keypair, phantom: PhantomData<(P, A)>, } -#[cfg(feature = "async-std")] +#[cfg(all(feature = "relay", feature = "tls"))] impl RelayNoiseBuilder { #[cfg(feature = "noise")] pub fn with_noise( @@ -350,7 +353,7 @@ impl RelayNoiseBuilder { } } -#[cfg(feature = "async-std")] +#[cfg(feature = "relay")] impl RelayNoiseBuilder { #[cfg(feature = "noise")] pub fn with_noise( From 493bc8db078004ba370a07c9d335f6c84b95ec60 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 31 Jul 2023 10:03:06 +0200 Subject: [PATCH 017/171] refactor(examples/ping): use `SwarmBuilder` --- examples/ping-example/src/main.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index 6b993bcb6e3..af80ca6c0d2 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -21,29 +21,28 @@ #![doc = include_str!("../README.md")] use futures::prelude::*; -use libp2p::core::upgrade::Version; use libp2p::{ - identity, noise, ping, - swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, yamux, Multiaddr, PeerId, Transport, + ping, + swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, + Multiaddr, }; use std::error::Error; #[async_std::main] async fn main() -> Result<(), Box> { - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - println!("Local peer id: {local_peer_id:?}"); + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .without_tls() + .with_noise() + .without_relay() + .no_more_other_transports() + .without_dns() + .with_behaviour(|_| Behaviour::default()) + .build(); - let transport = tcp::async_io::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&local_key)?) - .multiplex(yamux::Config::default()) - .boxed(); - - let mut swarm = - SwarmBuilder::with_async_std_executor(transport, Behaviour::default(), local_peer_id) - .build(); + println!("Local peer id: {:?}", swarm.local_peer_id()); // Tell the swarm to listen on all interfaces and a random, OS-assigned // port. From b5ed4edcaf1bb2198cde06272d8af19b4df58b1c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 31 Jul 2023 10:12:33 +0200 Subject: [PATCH 018/171] Rename to without_any_other_transports --- examples/ping-example/src/main.rs | 2 +- libp2p/src/builder.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index af80ca6c0d2..6145cf8cf3b 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -37,7 +37,7 @@ async fn main() -> Result<(), Box> { .without_tls() .with_noise() .without_relay() - .no_more_other_transports() + .without_any_other_transports() .without_dns() .with_behaviour(|_| Behaviour::default()) .build(); diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index a9d6c21f8fd..758292cb796 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -409,7 +409,7 @@ impl OtherTransportBuilder } // TODO: Not the ideal name. - pub fn no_more_other_transports( + pub fn without_any_other_transports( self, ) -> DnsBuilder { DnsBuilder { @@ -589,7 +589,7 @@ mod tests { .with_tls() .with_noise() .without_relay() - .no_more_other_transports() + .without_any_other_transports() .without_dns() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); @@ -620,7 +620,7 @@ mod tests { .with_relay() .with_tls() .with_noise() - .no_more_other_transports() + .without_any_other_transports() .without_dns() .with_behaviour(|_, relay| Behaviour { dummy: libp2p_swarm::dummy::Behaviour, @@ -645,7 +645,7 @@ mod tests { .with_tls() .with_noise() .without_relay() - .no_more_other_transports() + .without_any_other_transports() .with_dns() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); @@ -665,7 +665,7 @@ mod tests { .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .no_more_other_transports() + .without_any_other_transports() .without_dns() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); From 43c9b366205ad250802b947f8db0a2bff266fd6e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 09:33:16 +0200 Subject: [PATCH 019/171] feat: websocket support --- libp2p/src/builder.rs | 185 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 6 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 758292cb796..824685406db 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -430,8 +430,8 @@ pub struct DnsBuilder { #[cfg(all(feature = "async-std", feature = "dns"))] impl DnsBuilder { - pub async fn with_dns(self) -> BehaviourBuilder { - BehaviourBuilder { + pub async fn with_dns(self) -> WebsocketBuilder { + WebsocketBuilder { keypair: self.keypair, relay_behaviour: self.relay_behaviour, // TODO: Timeout needed? @@ -446,8 +446,8 @@ impl DnsBuilder { #[cfg(all(feature = "tokio", feature = "dns"))] impl DnsBuilder { - pub fn with_dns(self) -> BehaviourBuilder { - BehaviourBuilder { + pub fn with_dns(self) -> WebsocketBuilder { + WebsocketBuilder { keypair: self.keypair, relay_behaviour: self.relay_behaviour, // TODO: Timeout needed? @@ -459,8 +459,39 @@ impl DnsBuilder { } } -impl DnsBuilder { - pub fn without_dns(self) -> BehaviourBuilder { +impl DnsBuilder { + pub fn without_dns(self) -> WebsocketBuilder { + WebsocketBuilder { + keypair: self.keypair, + relay_behaviour: self.relay_behaviour, + // TODO: Timeout needed? + transport: self.transport, + phantom: PhantomData, + } + } +} + +pub struct WebsocketBuilder { + transport: T, + relay_behaviour: R, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +impl WebsocketBuilder { + pub fn with_websocket(self) -> WebsocketTlsBuilder { + WebsocketTlsBuilder { + transport: self.transport, + relay_behaviour: self.relay_behaviour, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +impl WebsocketBuilder { + // TODO: This would allow one to build a faulty transport. + pub fn without_websocket(self) -> BehaviourBuilder { BehaviourBuilder { keypair: self.keypair, relay_behaviour: self.relay_behaviour, @@ -471,6 +502,148 @@ impl DnsBuilder { } } +pub struct WebsocketTlsBuilder { + transport: T, + relay_behaviour: R, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +#[cfg(feature = "relay")] +impl WebsocketTlsBuilder { + #[cfg(feature = "tls")] + pub fn with_tls(self) -> WebsocketNoiseBuilder { + WebsocketNoiseBuilder { + relay_behaviour: self.relay_behaviour, + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } + + pub fn without_tls(self) -> WebsocketNoiseBuilder { + WebsocketNoiseBuilder { + relay_behaviour: self.relay_behaviour, + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +pub struct WebsocketNoiseBuilder { + transport: T, + relay_behaviour: R, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +// TODO: This is for asyncstd only thus far. + +#[cfg(all(feature = "websocket", feature = "tls"))] +impl WebsocketNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> BehaviourBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_websocket::client::Behaviour, + > { + let websocket_transport = libp2p_websocket::WsConfig::new( + block_on(libp2p_dns::DnsConfig::system( + libp2p::tcp_async_io::Transport::new(libp2p_tcp::Config::default()), + )) + .unwrap(), + ) + .upgrade(upgrade::Version::V1) + .authenticate(libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + )) + .multiplex(libp2p_yamux::Config::default()) + .timeout(Duration::from_secs(20)); + + BehaviourBuilder { + transport: websocket_transport + .or_transport(self.transport) + .map(|either, _| either.into_inner()), + keypair: self.keypair, + relay_behaviour: self.relay_behaviour, + phantom: PhantomData, + } + } + pub fn without_noise( + self, + ) -> BehaviourBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_websocket::client::Behaviour, + > { + let websocket_transport = libp2p_websocket::WsConfig::new( + block_on(libp2p_dns::DnsConfig::system( + libp2p::tcp_async_io::Transport::new(libp2p_tcp::Config::default()), + )) + .unwrap(), + ) + .upgrade(upgrade::Version::V1) + .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .timeout(Duration::from_secs(20)); + + BehaviourBuilder { + transport: websocket_transport + .or_transport(self.transport) + .map(|either, _| either.into_inner()), + keypair: self.keypair, + relay_behaviour: self.relay_behaviour, + phantom: PhantomData, + } + } +} + +#[cfg(feature = "websocket")] +impl WebsocketNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> BehaviourBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_websocket::client::Behaviour, + > { + let websocket_transport = libp2p_websocket::WsConfig::new( + block_on(libp2p_dns::DnsConfig::system( + libp2p::tcp_async_io::Transport::new(libp2p_tcp::Config::default()), + )) + .unwrap(), + ) + .upgrade(upgrade::Version::V1) + .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) + .multiplex(libp2p_yamux::Config::default()) + .timeout(Duration::from_secs(20)); + + BehaviourBuilder { + transport: websocket_transport + .or_transport(self.transport) + .map(|either, _| either.into_inner()), + keypair: self.keypair, + relay_behaviour: self.relay_behaviour, + phantom: PhantomData, + } + } +} + pub struct BehaviourBuilder { keypair: libp2p_identity::Keypair, relay_behaviour: R, From e694bc994242651785444aeea045e1a9dc90c9c8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 10:06:58 +0200 Subject: [PATCH 020/171] Use macros for de-duplication --- libp2p/src/builder.rs | 411 ++++++++++++++++-------------------------- 1 file changed, 153 insertions(+), 258 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 824685406db..e11a72427ce 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,3 +1,4 @@ +// TODO: Rename runtime to provider use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; @@ -94,123 +95,69 @@ pub struct TcpNoiseBuilder { phantom: PhantomData<(P, A)>, } -#[cfg(all(feature = "async-std", feature = "tls"))] -impl TcpNoiseBuilder { - #[cfg(feature = "noise")] - pub fn with_noise(self) -> RelayBuilder { - RelayBuilder { - transport: libp2p_tcp::async_io::Transport::new(Default::default()) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_core::upgrade::Map::new( - libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - )) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - keypair: self.keypair, - phantom: PhantomData, - } - } - pub fn without_noise(self) -> RelayBuilder { +macro_rules! construct_relay_builder { + ($tcp:path, $auth:expr) => { RelayBuilder { - transport: libp2p_tcp::async_io::Transport::new(Default::default()) + transport: $tcp::Transport::new(Default::default()) .upgrade(libp2p_core::upgrade::Version::V1Lazy) // TODO: Handle unwrap? - .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) + .authenticate($auth) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), keypair: self.keypair, phantom: PhantomData, } - } -} + }; +} + +macro_rules! impl_tcp_noise_builder { + ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:path) => { + #[cfg(all(feature = "$runtimeKebabCase", feature = "tls"))] + impl TcpNoiseBuilder<$runtimeCamelCase, Tls> { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { + construct_relay_builder!( + $tcp, + libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + ) + ) + } -#[cfg(feature = "async-std")] -impl TcpNoiseBuilder { - #[cfg(feature = "noise")] - pub fn with_noise(self) -> RelayBuilder { - RelayBuilder { - transport: libp2p_tcp::async_io::Transport::new(Default::default()) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - keypair: self.keypair, - phantom: PhantomData, + pub fn without_noise( + self, + ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { + construct_relay_builder!($tcp, libp2p_tls::Config::new(&self.keypair).unwrap()) + } } - } -} -#[cfg(feature = "tokio")] -impl TcpNoiseBuilder { - #[cfg(feature = "noise")] - pub fn with_noise(self) -> RelayBuilder { - RelayBuilder { - transport: libp2p_tcp::tokio::Transport::new(Default::default()) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_core::upgrade::Map::new( - libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - )) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - keypair: self.keypair, - phantom: PhantomData, - } - } - pub fn without_noise(self) -> RelayBuilder { - RelayBuilder { - transport: libp2p_tcp::tokio::Transport::new(Default::default()) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - keypair: self.keypair, - phantom: PhantomData, + #[cfg(feature = $runtimeKebabCase)] + impl TcpNoiseBuilder<$runtimeCamelCase, WithoutTls> { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { + construct_relay_builder!($tcp, libp2p_noise::Config::new(&self.keypair).unwrap()) + } } - } + }; } -#[cfg(feature = "tokio")] -impl TcpNoiseBuilder { - #[cfg(feature = "noise")] - pub fn with_noise(self) -> RelayBuilder { - RelayBuilder { - transport: libp2p_tcp::tokio::Transport::new(Default::default()) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - keypair: self.keypair, - phantom: PhantomData, - } - } -} +impl_tcp_noise_builder!("async-std", AsyncStd, libp2p_tcp::async_io); +impl_tcp_noise_builder!("tokio", Tokio, libp2p_tcp::tokio); pub enum Tls {} pub enum WithoutTls {} @@ -281,16 +228,8 @@ pub struct RelayNoiseBuilder { phantom: PhantomData<(P, A)>, } -#[cfg(all(feature = "relay", feature = "tls"))] -impl RelayNoiseBuilder { - #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> OtherTransportBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, - > { +macro_rules! construct_other_transport_builder { + ($auth:expr) => { let (relay_transport, relay_behaviour) = libp2p_relay::client::new(self.keypair.public().to_peer_id()); @@ -300,21 +239,7 @@ impl RelayNoiseBuilder { .or_transport( relay_transport .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_core::upgrade::Map::new( - libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - )) + .authenticate($auth) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), ) @@ -323,6 +248,34 @@ impl RelayNoiseBuilder { relay_behaviour, phantom: PhantomData, } + }; +} + +#[cfg(all(feature = "relay", feature = "tls"))] +impl RelayNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> OtherTransportBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + > { + // TODO: Handle unwrap? + construct_other_transport_builder!(libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + )) } pub fn without_noise( self, @@ -331,25 +284,7 @@ impl RelayNoiseBuilder { impl AuthenticatedMultiplexedTransport, libp2p_relay::client::Behaviour, > { - let (relay_transport, relay_behaviour) = - libp2p_relay::client::new(self.keypair.public().to_peer_id()); - - OtherTransportBuilder { - transport: self - .transport - .or_transport( - relay_transport - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - ) - .map(|either, _| either.into_inner()), - keypair: self.keypair, - relay_behaviour, - phantom: PhantomData, - } + construct_other_transport_builder!(libp2p_tls::Config::new(&self.keypair).unwrap()) } } @@ -363,25 +298,7 @@ impl RelayNoiseBuilder { - let (relay_transport, relay_behaviour) = - libp2p_relay::client::new(self.keypair.public().to_peer_id()); - - OtherTransportBuilder { - transport: self - .transport - .or_transport( - relay_transport - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - ) - .map(|either, _| either.into_inner()), - keypair: self.keypair, - relay_behaviour, - phantom: PhantomData, - } + construct_other_transport_builder!(libp2p_noise::Config::new(&self.keypair).unwrap()) } } @@ -490,7 +407,6 @@ impl WebsocketBuilder { } impl WebsocketBuilder { - // TODO: This would allow one to build a faulty transport. pub fn without_websocket(self) -> BehaviourBuilder { BehaviourBuilder { keypair: self.keypair, @@ -538,39 +454,16 @@ pub struct WebsocketNoiseBuilder { phantom: PhantomData

, } -// TODO: This is for asyncstd only thus far. - -#[cfg(all(feature = "websocket", feature = "tls"))] -impl WebsocketNoiseBuilder { - #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> BehaviourBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_websocket::client::Behaviour, - > { +macro_rules! construct_behaviour_builder { + ($tcp:path, $auth:expr) => { let websocket_transport = libp2p_websocket::WsConfig::new( - block_on(libp2p_dns::DnsConfig::system( - libp2p::tcp_async_io::Transport::new(libp2p_tcp::Config::default()), - )) + block_on(libp2p_dns::DnsConfig::system($tcp::Transport::new( + libp2p_tcp::Config::default(), + ))) .unwrap(), ) .upgrade(upgrade::Version::V1) - .authenticate(libp2p_core::upgrade::Map::new( - libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - )) + .authenticate($auth) .multiplex(libp2p_yamux::Config::default()) .timeout(Duration::from_secs(20)); @@ -582,67 +475,73 @@ impl WebsocketNoiseBuilder { relay_behaviour: self.relay_behaviour, phantom: PhantomData, } - } - pub fn without_noise( - self, - ) -> BehaviourBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_websocket::client::Behaviour, - > { - let websocket_transport = libp2p_websocket::WsConfig::new( - block_on(libp2p_dns::DnsConfig::system( - libp2p::tcp_async_io::Transport::new(libp2p_tcp::Config::default()), - )) - .unwrap(), - ) - .upgrade(upgrade::Version::V1) - .authenticate(libp2p_tls::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .timeout(Duration::from_secs(20)); - - BehaviourBuilder { - transport: websocket_transport - .or_transport(self.transport) - .map(|either, _| either.into_inner()), - keypair: self.keypair, - relay_behaviour: self.relay_behaviour, - phantom: PhantomData, + }; +} + +macro_rules! impl_websocket_noise_builder { + ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:path) => { + #[cfg(all(feature = "$runtimeKebabCase", feature = "websocket", feature = "tls"))] + impl + WebsocketNoiseBuilder<$runtimeCamelCase, T, Tls> + { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> BehaviourBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_websocket::client::Behaviour, + > { + construct_behaviour_builder!( + $tcp, + libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + ) + ) + } + pub fn without_noise( + self, + ) -> BehaviourBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_websocket::client::Behaviour, + > { + construct_behaviour_builder!($tcp, libp2p_tls::Config::new(&self.keypair).unwrap()) + } + } + + #[cfg(all(feature = "$runtimeKebabCase", feature = "websocket"))] + impl WebsocketNoiseBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> BehaviourBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_websocket::client::Behaviour, + > { + construct_behaviour_builder!( + $tcp, + libp2p_noise::Config::new(&self.keypair).unwrap(), + ) + } } - } + }; } -#[cfg(feature = "websocket")] -impl WebsocketNoiseBuilder { - #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> BehaviourBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_websocket::client::Behaviour, - > { - let websocket_transport = libp2p_websocket::WsConfig::new( - block_on(libp2p_dns::DnsConfig::system( - libp2p::tcp_async_io::Transport::new(libp2p_tcp::Config::default()), - )) - .unwrap(), - ) - .upgrade(upgrade::Version::V1) - .authenticate(libp2p_noise::Config::new(&self.keypair).unwrap()) - .multiplex(libp2p_yamux::Config::default()) - .timeout(Duration::from_secs(20)); - - BehaviourBuilder { - transport: websocket_transport - .or_transport(self.transport) - .map(|either, _| either.into_inner()), - keypair: self.keypair, - relay_behaviour: self.relay_behaviour, - phantom: PhantomData, - } - } -} +impl_websocket_noise_builder!("async-std", AsyncStd, libp2p_tcp::async_io); +impl_websocket_noise_builder!("tokio", Tokio, libp2p_tcp::tokio); pub struct BehaviourBuilder { keypair: libp2p_identity::Keypair, @@ -689,9 +588,7 @@ pub struct Builder { #[cfg(feature = "async-std")] impl Builder { - // TODO: The close should provide the relay transport in case the user used with_relay. pub fn build(self) -> libp2p_swarm::Swarm { - // TODO: Generic over the runtime! libp2p_swarm::SwarmBuilder::with_async_std_executor( self.transport, self.behaviour, @@ -703,9 +600,7 @@ impl Builder { #[cfg(feature = "tokio")] impl Builder { - // TODO: The close should provide the relay transport in case the user used with_relay. pub fn build(self) -> libp2p_swarm::Swarm { - // TODO: Generic over the runtime! libp2p_swarm::SwarmBuilder::with_tokio_executor( self.transport, self.behaviour, From ffcffaeae6b82d96968752d0ce9b5a05e089e7b0 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 10:56:51 +0200 Subject: [PATCH 021/171] Fix tests --- libp2p/src/builder.rs | 205 +++++++++++++++++++++++++----------------- 1 file changed, 122 insertions(+), 83 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index e11a72427ce..d5a4bd86bd5 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,4 +1,6 @@ // TODO: Rename runtime to provider +// TODO: Should we have a timeout on transport? + use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; @@ -96,29 +98,30 @@ pub struct TcpNoiseBuilder { } macro_rules! construct_relay_builder { - ($tcp:path, $auth:expr) => { + ($self:ident, $tcp:ident, $auth:expr) => { RelayBuilder { - transport: $tcp::Transport::new(Default::default()) + transport: libp2p_tcp::$tcp::Transport::new(Default::default()) .upgrade(libp2p_core::upgrade::Version::V1Lazy) // TODO: Handle unwrap? .authenticate($auth) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - keypair: self.keypair, + keypair: $self.keypair, phantom: PhantomData, } }; } macro_rules! impl_tcp_noise_builder { - ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:path) => { - #[cfg(all(feature = "$runtimeKebabCase", feature = "tls"))] + ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:ident) => { + #[cfg(all(feature = $runtimeKebabCase, feature = "tls"))] impl TcpNoiseBuilder<$runtimeCamelCase, Tls> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { construct_relay_builder!( + self, $tcp, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( @@ -140,7 +143,11 @@ macro_rules! impl_tcp_noise_builder { pub fn without_noise( self, ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { - construct_relay_builder!($tcp, libp2p_tls::Config::new(&self.keypair).unwrap()) + construct_relay_builder!( + self, + $tcp, + libp2p_tls::Config::new(&self.keypair).unwrap() + ) } } @@ -150,14 +157,18 @@ macro_rules! impl_tcp_noise_builder { pub fn with_noise( self, ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { - construct_relay_builder!($tcp, libp2p_noise::Config::new(&self.keypair).unwrap()) + construct_relay_builder!( + self, + $tcp, + libp2p_noise::Config::new(&self.keypair).unwrap() + ) } } }; } -impl_tcp_noise_builder!("async-std", AsyncStd, libp2p_tcp::async_io); -impl_tcp_noise_builder!("tokio", Tokio, libp2p_tcp::tokio); +impl_tcp_noise_builder!("async-std", AsyncStd, async_io); +impl_tcp_noise_builder!("tokio", Tokio, tokio); pub enum Tls {} pub enum WithoutTls {} @@ -229,12 +240,12 @@ pub struct RelayNoiseBuilder { } macro_rules! construct_other_transport_builder { - ($auth:expr) => { + ($self:ident, $auth:expr) => {{ let (relay_transport, relay_behaviour) = - libp2p_relay::client::new(self.keypair.public().to_peer_id()); + libp2p_relay::client::new($self.keypair.public().to_peer_id()); OtherTransportBuilder { - transport: self + transport: $self .transport .or_transport( relay_transport @@ -244,11 +255,11 @@ macro_rules! construct_other_transport_builder { .map(|(p, c), _| (p, StreamMuxerBox::new(c))), ) .map(|either, _| either.into_inner()), - keypair: self.keypair, + keypair: $self.keypair, relay_behaviour, phantom: PhantomData, } - }; + }}; } #[cfg(all(feature = "relay", feature = "tls"))] @@ -262,20 +273,23 @@ impl RelayNoiseBuilder { libp2p_relay::client::Behaviour, > { // TODO: Handle unwrap? - construct_other_transport_builder!(libp2p_core::upgrade::Map::new( - libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - )) + construct_other_transport_builder!( + self, + libp2p_core::upgrade::Map::new( + libp2p_core::upgrade::SelectUpgrade::new( + libp2p_tls::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap(), + ), + |upgrade| match upgrade { + futures::future::Either::Left((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Left(upgrade)) + } + futures::future::Either::Right((peer_id, upgrade)) => { + (peer_id, futures::future::Either::Right(upgrade)) + } + }, + ) + ) } pub fn without_noise( self, @@ -284,7 +298,7 @@ impl RelayNoiseBuilder { impl AuthenticatedMultiplexedTransport, libp2p_relay::client::Behaviour, > { - construct_other_transport_builder!(libp2p_tls::Config::new(&self.keypair).unwrap()) + construct_other_transport_builder!(self, libp2p_tls::Config::new(&self.keypair).unwrap()) } } @@ -298,7 +312,7 @@ impl RelayNoiseBuilder { - construct_other_transport_builder!(libp2p_noise::Config::new(&self.keypair).unwrap()) + construct_other_transport_builder!(self, libp2p_noise::Config::new(&self.keypair).unwrap()) } } @@ -347,15 +361,16 @@ pub struct DnsBuilder { #[cfg(all(feature = "async-std", feature = "dns"))] impl DnsBuilder { - pub async fn with_dns(self) -> WebsocketBuilder { + pub async fn with_dns( + self, + ) -> WebsocketBuilder { WebsocketBuilder { keypair: self.keypair, relay_behaviour: self.relay_behaviour, // TODO: Timeout needed? transport: libp2p_dns::DnsConfig::system(self.transport) .await - .expect("TODO: Handle") - .boxed(), + .expect("TODO: Handle"), phantom: PhantomData, } } @@ -363,14 +378,12 @@ impl DnsBuilder { #[cfg(all(feature = "tokio", feature = "dns"))] impl DnsBuilder { - pub fn with_dns(self) -> WebsocketBuilder { + pub fn with_dns(self) -> WebsocketBuilder { WebsocketBuilder { keypair: self.keypair, relay_behaviour: self.relay_behaviour, // TODO: Timeout needed? - transport: libp2p_dns::TokioDnsConfig::system(self.transport) - .expect("TODO: Handle") - .boxed(), + transport: libp2p_dns::TokioDnsConfig::system(self.transport).expect("TODO: Handle"), phantom: PhantomData, } } @@ -426,9 +439,9 @@ pub struct WebsocketTlsBuilder { } #[cfg(feature = "relay")] -impl WebsocketTlsBuilder { +impl WebsocketTlsBuilder { #[cfg(feature = "tls")] - pub fn with_tls(self) -> WebsocketNoiseBuilder { + pub fn with_tls(self) -> WebsocketNoiseBuilder { WebsocketNoiseBuilder { relay_behaviour: self.relay_behaviour, transport: self.transport, @@ -437,7 +450,7 @@ impl WebsocketTlsBuilder { } } - pub fn without_tls(self) -> WebsocketNoiseBuilder { + pub fn without_tls(self) -> WebsocketNoiseBuilder { WebsocketNoiseBuilder { relay_behaviour: self.relay_behaviour, transport: self.transport, @@ -447,52 +460,53 @@ impl WebsocketTlsBuilder { } } -pub struct WebsocketNoiseBuilder { +pub struct WebsocketNoiseBuilder { transport: T, relay_behaviour: R, keypair: libp2p_identity::Keypair, - phantom: PhantomData

, + phantom: PhantomData<(P, A)>, } macro_rules! construct_behaviour_builder { - ($tcp:path, $auth:expr) => { + ($self:ident, $tcp:ident, $auth:expr) => {{ let websocket_transport = libp2p_websocket::WsConfig::new( - block_on(libp2p_dns::DnsConfig::system($tcp::Transport::new( - libp2p_tcp::Config::default(), - ))) + futures::executor::block_on(libp2p_dns::DnsConfig::system( + libp2p_tcp::$tcp::Transport::new(libp2p_tcp::Config::default()), + )) .unwrap(), ) - .upgrade(upgrade::Version::V1) + .upgrade(libp2p_core::upgrade::Version::V1) .authenticate($auth) .multiplex(libp2p_yamux::Config::default()) - .timeout(Duration::from_secs(20)); + .map(|(p, c), _| (p, StreamMuxerBox::new(c))); BehaviourBuilder { transport: websocket_transport - .or_transport(self.transport) - .map(|either, _| either.into_inner()), - keypair: self.keypair, - relay_behaviour: self.relay_behaviour, + .or_transport($self.transport) + .map(|either, _| either.into_inner()) + .boxed(), + keypair: $self.keypair, + relay_behaviour: $self.relay_behaviour, phantom: PhantomData, } - }; + }}; } macro_rules! impl_websocket_noise_builder { - ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:path) => { - #[cfg(all(feature = "$runtimeKebabCase", feature = "websocket", feature = "tls"))] - impl - WebsocketNoiseBuilder<$runtimeCamelCase, T, Tls> + ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:ident) => { + #[cfg(all( + feature = $runtimeKebabCase, + feature = "dns", + feature = "websocket", + feature = "tls" + ))] + impl + WebsocketNoiseBuilder<$runtimeCamelCase, T, R, Tls> { #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> BehaviourBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_websocket::client::Behaviour, - > { + pub fn with_noise(self) -> BehaviourBuilder<$runtimeCamelCase, R> { construct_behaviour_builder!( + self, $tcp, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( @@ -510,28 +524,23 @@ macro_rules! impl_websocket_noise_builder { ) ) } - pub fn without_noise( - self, - ) -> BehaviourBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_websocket::client::Behaviour, - > { - construct_behaviour_builder!($tcp, libp2p_tls::Config::new(&self.keypair).unwrap()) + pub fn without_noise(self) -> BehaviourBuilder<$runtimeCamelCase, R> { + construct_behaviour_builder!( + self, + $tcp, + libp2p_tls::Config::new(&self.keypair).unwrap() + ) } } - #[cfg(all(feature = "$runtimeKebabCase", feature = "websocket"))] - impl WebsocketNoiseBuilder { + #[cfg(all(feature = "$runtimeKebabCase", feature = "dns", feature = "websocket"))] + impl + WebsocketNoiseBuilder<$runtimeCamelCase, T, R, WithoutTls> + { #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> BehaviourBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_websocket::client::Behaviour, - > { + pub fn with_noise(self) -> BehaviourBuilder<$runtimeCamelCase, R> { construct_behaviour_builder!( + self, $tcp, libp2p_noise::Config::new(&self.keypair).unwrap(), ) @@ -540,8 +549,8 @@ macro_rules! impl_websocket_noise_builder { }; } -impl_websocket_noise_builder!("async-std", AsyncStd, libp2p_tcp::async_io); -impl_websocket_noise_builder!("tokio", Tokio, libp2p_tcp::tokio); +impl_websocket_noise_builder!("async-std", AsyncStd, async_io); +impl_websocket_noise_builder!("tokio", Tokio, tokio); pub struct BehaviourBuilder { keypair: libp2p_identity::Keypair, @@ -659,6 +668,7 @@ mod tests { .without_relay() .without_any_other_transports() .without_dns() + .without_websocket() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); } @@ -690,6 +700,7 @@ mod tests { .with_noise() .without_any_other_transports() .without_dns() + .without_websocket() .with_behaviour(|_, relay| Behaviour { dummy: libp2p_swarm::dummy::Behaviour, relay, @@ -715,6 +726,7 @@ mod tests { .without_relay() .without_any_other_transports() .with_dns() + .without_websocket() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); } @@ -735,6 +747,33 @@ mod tests { .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .without_any_other_transports() .without_dns() + .without_websocket() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .build(); + } + + #[test] + #[cfg(all( + feature = "tokio", + feature = "tcp", + feature = "tls", + feature = "noise", + feature = "dns", + feature = "websocket", + ))] + fn tcp_websocket() { + let _: libp2p_swarm::Swarm = SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .without_relay() + .without_any_other_transports() + .without_dns() + .with_websocket() + .with_tls() + .with_noise() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); } From 225771ff611355a816cfde3eca1abe6d80d9b4fc Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 13:39:40 +0200 Subject: [PATCH 022/171] Allow configuring tcp --- libp2p/src/builder.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index d5a4bd86bd5..53978729d54 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -47,9 +47,15 @@ pub struct TcpBuilder

{ phantom: PhantomData

, } +#[cfg(feature = "tcp")] impl

TcpBuilder

{ pub fn with_tcp(self) -> TcpTlsBuilder

{ + self.with_tcp_config(Default::default()) + } + + pub fn with_tcp_config(self, config: libp2p_tcp::Config) -> TcpTlsBuilder

{ TcpTlsBuilder { + config, keypair: self.keypair, phantom: PhantomData, } @@ -70,15 +76,19 @@ impl

TcpBuilder

{ } } +#[cfg(feature = "tcp")] pub struct TcpTlsBuilder

{ + config: libp2p_tcp::Config, keypair: libp2p_identity::Keypair, phantom: PhantomData

, } +#[cfg(feature = "tcp")] impl

TcpTlsBuilder

{ #[cfg(feature = "tls")] pub fn with_tls(self) -> TcpNoiseBuilder { TcpNoiseBuilder { + config: self.config, keypair: self.keypair, phantom: PhantomData, } @@ -86,13 +96,16 @@ impl

TcpTlsBuilder

{ pub fn without_tls(self) -> TcpNoiseBuilder { TcpNoiseBuilder { + config: self.config, keypair: self.keypair, phantom: PhantomData, } } } +#[cfg(feature = "tcp")] pub struct TcpNoiseBuilder { + config: libp2p_tcp::Config, keypair: libp2p_identity::Keypair, phantom: PhantomData<(P, A)>, } @@ -100,7 +113,7 @@ pub struct TcpNoiseBuilder { macro_rules! construct_relay_builder { ($self:ident, $tcp:ident, $auth:expr) => { RelayBuilder { - transport: libp2p_tcp::$tcp::Transport::new(Default::default()) + transport: libp2p_tcp::$tcp::Transport::new($self.config) .upgrade(libp2p_core::upgrade::Version::V1Lazy) // TODO: Handle unwrap? .authenticate($auth) @@ -114,7 +127,7 @@ macro_rules! construct_relay_builder { macro_rules! impl_tcp_noise_builder { ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:ident) => { - #[cfg(all(feature = $runtimeKebabCase, feature = "tls"))] + #[cfg(all(feature = $runtimeKebabCase, feature = "tcp", feature = "tls"))] impl TcpNoiseBuilder<$runtimeCamelCase, Tls> { #[cfg(feature = "noise")] pub fn with_noise( From bcdaf413eaf7a6c47d7c3f0b9260d8bf9be8db62 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 13:40:45 +0200 Subject: [PATCH 023/171] Add shortcuts --- libp2p/src/builder.rs | 55 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 53978729d54..a53b3ca2304 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -218,6 +218,27 @@ impl RelayBuilder { } } +// Shortcuts +impl RelayBuilder { + pub fn with_other_transport( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, + ) -> OtherTransportBuilder { + self.without_relay().with_other_transport(constructor) + } + + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> B, + ) -> Builder { + self.without_relay() + .without_any_other_transports() + .without_dns() + .without_websocket() + .with_behaviour(constructor) + } +} + #[cfg(feature = "relay")] pub struct RelayTlsBuilder { transport: T, @@ -252,6 +273,7 @@ pub struct RelayNoiseBuilder { phantom: PhantomData<(P, A)>, } +#[cfg(feature = "relay")] macro_rules! construct_other_transport_builder { ($self:ident, $auth:expr) => {{ let (relay_transport, relay_behaviour) = @@ -414,6 +436,29 @@ impl DnsBuilder { } } +// Shortcuts +#[cfg(feature = "relay")] +impl DnsBuilder { + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, + ) -> Builder { + self.without_dns() + .without_websocket() + .with_behaviour(constructor) + } +} +impl DnsBuilder { + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> B, + ) -> Builder { + self.without_dns() + .without_websocket() + .with_behaviour(constructor) + } +} + pub struct WebsocketBuilder { transport: T, relay_behaviour: R, @@ -421,6 +466,7 @@ pub struct WebsocketBuilder { phantom: PhantomData

, } +#[cfg(feature = "websocket")] impl WebsocketBuilder { pub fn with_websocket(self) -> WebsocketTlsBuilder { WebsocketTlsBuilder { @@ -444,6 +490,7 @@ impl WebsocketBuilder { } } +#[cfg(feature = "websocket")] pub struct WebsocketTlsBuilder { transport: T, relay_behaviour: R, @@ -451,7 +498,7 @@ pub struct WebsocketTlsBuilder { phantom: PhantomData

, } -#[cfg(feature = "relay")] +#[cfg(feature = "websocket")] impl WebsocketTlsBuilder { #[cfg(feature = "tls")] pub fn with_tls(self) -> WebsocketNoiseBuilder { @@ -473,6 +520,7 @@ impl WebsocketTlsBuilder { } } +#[cfg(feature = "websocket")] pub struct WebsocketNoiseBuilder { transport: T, relay_behaviour: R, @@ -480,6 +528,7 @@ pub struct WebsocketNoiseBuilder { phantom: PhantomData<(P, A)>, } +#[cfg(feature = "websocket")] macro_rules! construct_behaviour_builder { ($self:ident, $tcp:ident, $auth:expr) => {{ let websocket_transport = libp2p_websocket::WsConfig::new( @@ -509,6 +558,7 @@ macro_rules! impl_websocket_noise_builder { ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:ident) => { #[cfg(all( feature = $runtimeKebabCase, + feature = "websocket", feature = "dns", feature = "websocket", feature = "tls" @@ -592,6 +642,9 @@ impl

BehaviourBuilder { self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> B, ) -> Builder { + // Discard `NoRelayBehaviour`. + let _ = self.relay_behaviour; + Builder { behaviour: constructor(&self.keypair), keypair: self.keypair, From fec404ae6dd94d03cc07515122ce1f7194c36f17 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 13:40:55 +0200 Subject: [PATCH 024/171] Update autonat examples --- examples/autonat/src/bin/autonat_client.rs | 29 ++++++++++------------ examples/autonat/src/bin/autonat_server.rs | 29 ++++++++++------------ 2 files changed, 26 insertions(+), 32 deletions(-) diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index 40db305feef..2af8bf64074 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -21,11 +21,11 @@ #![doc = include_str!("../../README.md")] use clap::Parser; -use futures::prelude::*; +use futures::StreamExt; use libp2p::core::multiaddr::Protocol; -use libp2p::core::{upgrade::Version, Multiaddr, Transport}; -use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; -use libp2p::{autonat, identify, identity, noise, tcp, yamux, PeerId}; +use libp2p::core::Multiaddr; +use libp2p::swarm::{NetworkBehaviour, SwarmEvent}; +use libp2p::{autonat, identify, identity, PeerId}; use std::error::Error; use std::net::Ipv4Addr; use std::time::Duration; @@ -49,20 +49,17 @@ async fn main() -> Result<(), Box> { let opt = Opt::parse(); - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - println!("Local peer id: {local_peer_id:?}"); + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .without_tls() + .with_noise() + .with_behaviour(|key| Behaviour::new(key.public())) + .build(); - let transport = tcp::async_io::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&local_key)?) - .multiplex(yamux::Config::default()) - .boxed(); + println!("Local peer id: {:?}", swarm.local_peer_id()); - let behaviour = Behaviour::new(local_key.public()); - - let mut swarm = - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); swarm.listen_on( Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED)) diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index e0d6ad2f315..23ff8f787f2 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -21,10 +21,10 @@ #![doc = include_str!("../../README.md")] use clap::Parser; -use futures::prelude::*; -use libp2p::core::{multiaddr::Protocol, upgrade::Version, Multiaddr, Transport}; -use libp2p::swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}; -use libp2p::{autonat, identify, identity, noise, tcp, yamux, PeerId}; +use futures::StreamExt; +use libp2p::core::{multiaddr::Protocol, Multiaddr}; +use libp2p::swarm::{NetworkBehaviour, SwarmEvent}; +use libp2p::{autonat, identify, identity}; use std::error::Error; use std::net::Ipv4Addr; @@ -41,20 +41,17 @@ async fn main() -> Result<(), Box> { let opt = Opt::parse(); - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - println!("Local peer id: {local_peer_id:?}"); + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .without_tls() + .with_noise() + .with_behaviour(|key| Behaviour::new(key.public())) + .build(); - let transport = tcp::async_io::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&local_key)?) - .multiplex(yamux::Config::default()) - .boxed(); + println!("Local peer id: {:?}", swarm.local_peer_id()); - let behaviour = Behaviour::new(local_key.public()); - - let mut swarm = - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); swarm.listen_on( Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED)) From 987dc116304204f026c4cf2ceb7139a05d4f5fd0 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 13:41:05 +0200 Subject: [PATCH 025/171] Update chat examples --- examples/chat-example/src/main.rs | 93 ++++++++++++++----------------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 9dc2d92a56f..005508dfc51 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -21,13 +21,10 @@ #![doc = include_str!("../README.md")] use async_std::io; -use futures::{future::Either, prelude::*, select}; +use futures::{prelude::*, select}; use libp2p::{ - core::{muxing::StreamMuxerBox, transport::OrTransport, upgrade}, - gossipsub, identity, mdns, noise, - swarm::NetworkBehaviour, - swarm::{SwarmBuilder, SwarmEvent}, - tcp, yamux, PeerId, Transport, + core::muxing::StreamMuxerBox, gossipsub, mdns, swarm::NetworkBehaviour, swarm::SwarmEvent, + Transport, }; use libp2p_quic as quic; use std::collections::hash_map::DefaultHasher; @@ -44,58 +41,54 @@ struct MyBehaviour { #[async_std::main] async fn main() -> Result<(), Box> { - // Create a random PeerId - let id_keys = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(id_keys.public()); - println!("Local peer id: {local_peer_id}"); - - // Set up an encrypted DNS-enabled TCP Transport over the yamux protocol. - let tcp_transport = tcp::async_io::Transport::new(tcp::Config::default().nodelay(true)) - .upgrade(upgrade::Version::V1Lazy) - .authenticate(noise::Config::new(&id_keys).expect("signing libp2p-noise static keypair")) - .multiplex(yamux::Config::default()) - .timeout(std::time::Duration::from_secs(20)) - .boxed(); - let quic_transport = quic::async_std::Transport::new(quic::Config::new(&id_keys)); - let transport = OrTransport::new(quic_transport, tcp_transport) - .map(|either_output, _| match either_output { - Either::Left((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), - Either::Right((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .without_tls() + .with_noise() + .with_other_transport(|key| { + quic::async_std::Transport::new(quic::Config::new(&key)) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .boxed(); + .without_any_other_transports() + .with_behaviour(|key| { + // To content-address message, we can take the hash of message and use it as an ID. + let message_id_fn = |message: &gossipsub::Message| { + let mut s = DefaultHasher::new(); + message.data.hash(&mut s); + gossipsub::MessageId::from(s.finish().to_string()) + }; + + // Set a custom gossipsub configuration + let gossipsub_config = gossipsub::ConfigBuilder::default() + .heartbeat_interval(Duration::from_secs(10)) // This is set to aid debugging by not cluttering the log space + .validation_mode(gossipsub::ValidationMode::Strict) // This sets the kind of message validation. The default is Strict (enforce message signing) + .message_id_fn(message_id_fn) // content-address messages. No two messages of the same content will be propagated. + .build() + .expect("Valid config"); - // To content-address message, we can take the hash of message and use it as an ID. - let message_id_fn = |message: &gossipsub::Message| { - let mut s = DefaultHasher::new(); - message.data.hash(&mut s); - gossipsub::MessageId::from(s.finish().to_string()) - }; + // build a gossipsub network behaviour + let gossipsub = gossipsub::Behaviour::new( + gossipsub::MessageAuthenticity::Signed(key.clone()), + gossipsub_config, + ) + .expect("Correct configuration"); - // Set a custom gossipsub configuration - let gossipsub_config = gossipsub::ConfigBuilder::default() - .heartbeat_interval(Duration::from_secs(10)) // This is set to aid debugging by not cluttering the log space - .validation_mode(gossipsub::ValidationMode::Strict) // This sets the kind of message validation. The default is Strict (enforce message signing) - .message_id_fn(message_id_fn) // content-address messages. No two messages of the same content will be propagated. - .build() - .expect("Valid config"); + let mdns = + mdns::async_io::Behaviour::new(mdns::Config::default(), key.public().to_peer_id()) + // TODO: How could one handle the unwrap here? The closure does not allow returning an error. + .unwrap(); + MyBehaviour { gossipsub, mdns } + }) + .build(); - // build a gossipsub network behaviour - let mut gossipsub = gossipsub::Behaviour::new( - gossipsub::MessageAuthenticity::Signed(id_keys), - gossipsub_config, - ) - .expect("Correct configuration"); // Create a Gossipsub topic let topic = gossipsub::IdentTopic::new("test-net"); // subscribes to our topic - gossipsub.subscribe(&topic)?; + swarm.behaviour_mut().gossipsub.subscribe(&topic)?; - // Create a Swarm to manage peers and events - let mut swarm = { - let mdns = mdns::async_io::Behaviour::new(mdns::Config::default(), local_peer_id)?; - let behaviour = MyBehaviour { gossipsub, mdns }; - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build() - }; + println!("Local peer id: {:?}", swarm.local_peer_id()); // Read full lines from stdin let mut stdin = io::BufReader::new(io::stdin()).lines().fuse(); From fc7c8f6f85f79728beeaee601d9c10dacb5be069 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 13:47:53 +0200 Subject: [PATCH 026/171] Fix dcutr example --- examples/dcutr/src/main.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index e9490408ea1..9245f5a413d 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -125,15 +125,23 @@ async fn main() -> Result<(), Box> { let mut swarm = libp2p::builder::SwarmBuilder::new() .with_existing_identity(generate_ed25519(opts.secret_key_seed)) .with_async_std() - .with_custom_tcp(tcp::Config::default().port_reuse(true).nodelay(true)) + .with_tcp_config(tcp::Config::default().port_reuse(true).nodelay(true)) + // TODO: shortcut + .without_tls() + .with_noise() .with_relay() + // TODO: shortcut + .without_tls() + .with_noise() .with_other_transport(|keypair| { quic::async_std::Transport::new(quic::Config::new(&keypair)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .no_more_other_transports() + .without_any_other_transports() .with_dns() .await + // TODO: shortcut + .without_websocket() .with_behaviour(|keypair, relay_behaviour| Behaviour { relay_client: relay_behaviour, ping: ping::Behaviour::new(ping::Config::new()), From 499121b87f797f6e61fad2687124109198ea8bf6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 14:06:03 +0200 Subject: [PATCH 027/171] Add shortcuts --- examples/dcutr/src/main.rs | 4 ---- libp2p/src/builder.rs | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 9245f5a413d..f632042316f 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -126,12 +126,8 @@ async fn main() -> Result<(), Box> { .with_existing_identity(generate_ed25519(opts.secret_key_seed)) .with_async_std() .with_tcp_config(tcp::Config::default().port_reuse(true).nodelay(true)) - // TODO: shortcut - .without_tls() .with_noise() .with_relay() - // TODO: shortcut - .without_tls() .with_noise() .with_other_transport(|keypair| { quic::async_std::Transport::new(quic::Config::new(&keypair)) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index a53b3ca2304..996f9d007df 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -103,6 +103,22 @@ impl

TcpTlsBuilder

{ } } +// Shortcuts +#[cfg(all(feature = "tcp", feature = "noise", feature = "async-std"))] +impl TcpTlsBuilder { + #[cfg(feature = "noise")] + pub fn with_noise(self) -> RelayBuilder { + self.without_tls().with_noise() + } +} +#[cfg(all(feature = "tcp", feature = "noise", feature = "tokio"))] +impl TcpTlsBuilder { + #[cfg(feature = "noise")] + pub fn with_noise(self) -> RelayBuilder { + self.without_tls().with_noise() + } +} + #[cfg(feature = "tcp")] pub struct TcpNoiseBuilder { config: libp2p_tcp::Config, @@ -110,6 +126,7 @@ pub struct TcpNoiseBuilder { phantom: PhantomData<(P, A)>, } +#[cfg(feature = "tcp")] macro_rules! construct_relay_builder { ($self:ident, $tcp:ident, $auth:expr) => { RelayBuilder { @@ -266,6 +283,34 @@ impl RelayTlsBuilder { } } +// Shortcuts +#[cfg(all(feature = "relay", feature = "noise", feature = "async-std"))] +impl RelayTlsBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> OtherTransportBuilder< + AsyncStd, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + > { + self.without_tls().with_noise() + } +} +#[cfg(all(feature = "relay", feature = "noise", feature = "tokio"))] +impl RelayTlsBuilder { + #[cfg(feature = "noise")] + pub fn with_noise( + self, + ) -> OtherTransportBuilder< + Tokio, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + > { + self.without_tls().with_noise() + } +} + #[cfg(feature = "relay")] pub struct RelayNoiseBuilder { transport: T, From e1acfa1531b8c144ccee44dd589665489bb1374a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 14:22:45 +0200 Subject: [PATCH 028/171] Update key value store example --- .../distributed-key-value-store/Cargo.toml | 2 +- .../distributed-key-value-store/src/main.rs | 62 ++++++------------- 2 files changed, 21 insertions(+), 43 deletions(-) diff --git a/examples/distributed-key-value-store/Cargo.toml b/examples/distributed-key-value-store/Cargo.toml index f8e0fd2339d..ae9abbdc361 100644 --- a/examples/distributed-key-value-store/Cargo.toml +++ b/examples/distributed-key-value-store/Cargo.toml @@ -10,4 +10,4 @@ async-std = { version = "1.12", features = ["attributes"] } async-trait = "0.1" env_logger = "0.10" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "mdns", "noise", "macros", "tcp", "websocket", "yamux"] } +libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "mdns", "noise", "macros", "tcp", "yamux"] } diff --git a/examples/distributed-key-value-store/src/main.rs b/examples/distributed-key-value-store/src/main.rs index ce0998a9ac5..6fea0dcde86 100644 --- a/examples/distributed-key-value-store/src/main.rs +++ b/examples/distributed-key-value-store/src/main.rs @@ -22,7 +22,6 @@ use async_std::io; use futures::{prelude::*, select}; -use libp2p::core::upgrade::Version; use libp2p::kad::record::store::MemoryStore; use libp2p::kad::Mode; use libp2p::kad::{ @@ -30,9 +29,8 @@ use libp2p::kad::{ PutRecordOk, QueryResult, Quorum, Record, }; use libp2p::{ - identity, mdns, noise, - swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, yamux, PeerId, Transport, + mdns, + swarm::{NetworkBehaviour, SwarmEvent}, }; use std::error::Error; @@ -40,51 +38,31 @@ use std::error::Error; async fn main() -> Result<(), Box> { env_logger::init(); - // Create a random key for ourselves. - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - - let transport = tcp::async_io::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&local_key)?) - .multiplex(yamux::Config::default()) - .boxed(); - // We create a custom network behaviour that combines Kademlia and mDNS. #[derive(NetworkBehaviour)] - #[behaviour(to_swarm = "MyBehaviourEvent")] struct MyBehaviour { kademlia: Kademlia, mdns: mdns::async_io::Behaviour, } - #[allow(clippy::large_enum_variant)] - enum MyBehaviourEvent { - Kademlia(KademliaEvent), - Mdns(mdns::Event), - } - - impl From for MyBehaviourEvent { - fn from(event: KademliaEvent) -> Self { - MyBehaviourEvent::Kademlia(event) - } - } - - impl From for MyBehaviourEvent { - fn from(event: mdns::Event) -> Self { - MyBehaviourEvent::Mdns(event) - } - } - - // Create a swarm to manage peers and events. - let mut swarm = { - // Create a Kademlia behaviour. - let store = MemoryStore::new(local_peer_id); - let kademlia = Kademlia::new(local_peer_id, store); - let mdns = mdns::async_io::Behaviour::new(mdns::Config::default(), local_peer_id)?; - let behaviour = MyBehaviour { kademlia, mdns }; - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build() - }; + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .with_noise() + .with_behaviour(|key| MyBehaviour { + kademlia: Kademlia::new( + key.public().to_peer_id(), + MemoryStore::new(key.public().to_peer_id()), + ), + mdns: mdns::async_io::Behaviour::new( + mdns::Config::default(), + key.public().to_peer_id(), + ) + // TODO: How to handle this error. The closure doesn't allow returning an error. + .unwrap(), + }) + .build(); swarm.behaviour_mut().kademlia.set_mode(Some(Mode::Server)); From eb54dda6a60e9f23af346d272ba04d5cd2e1cfae Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 12 Aug 2023 14:25:36 +0200 Subject: [PATCH 029/171] Update file sharing example --- examples/file-sharing/src/network.rs | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 7ddd0afb0cc..689991e6413 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -45,18 +45,13 @@ pub(crate) async fn new( }; let peer_id = id_keys.public().to_peer_id(); - let transport = tcp::async_io::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&id_keys)?) - .multiplex(yamux::Config::default()) - .boxed(); - - // Build the Swarm, connecting the lower layer transport logic with the - // higher layer network behaviour logic. - let mut swarm = SwarmBuilder::with_async_std_executor( - transport, - ComposedBehaviour { - kademlia: Kademlia::new(peer_id, MemoryStore::new(peer_id)), + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_existing_identity(id_keys) + .with_async_std() + .with_tcp() + .with_noise() + .with_behaviour(|key| ComposedBehaviour { + kademlia: Kademlia::new(peer_id, MemoryStore::new(key.public().to_peer_id())), request_response: request_response::cbor::Behaviour::new( [( StreamProtocol::new("/file-exchange/1"), @@ -64,10 +59,8 @@ pub(crate) async fn new( )], request_response::Config::default(), ), - }, - peer_id, - ) - .build(); + }) + .build(); swarm .behaviour_mut() From 0883641a20020fcf7959aaa0cde1d8bb54bf184a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 15:13:24 +0200 Subject: [PATCH 030/171] Update metrics example --- examples/metrics/src/main.rs | 32 ++++++++++++-------------------- libp2p/src/builder.rs | 1 + 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index 177ff3af09d..01421a030c7 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -21,13 +21,11 @@ #![doc = include_str!("../README.md")] use env_logger::Env; -use futures::executor::block_on; -use futures::stream::StreamExt; -use libp2p::core::{upgrade::Version, Multiaddr, Transport}; -use libp2p::identity::PeerId; +use futures::{executor::block_on, StreamExt}; +use libp2p::core::Multiaddr; use libp2p::metrics::{Metrics, Recorder}; -use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent}; -use libp2p::{identify, identity, noise, ping, tcp, yamux}; +use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmEvent}; +use libp2p::{identify, identity, ping}; use log::info; use prometheus_client::registry::Registry; use std::error::Error; @@ -38,21 +36,15 @@ mod http_service; fn main() -> Result<(), Box> { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - let local_pub_key = local_key.public(); - info!("Local peer id: {local_peer_id:?}"); + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .with_noise() + .with_behaviour(|key| Behaviour::new(key.public())) + .build(); - let mut swarm = SwarmBuilder::without_executor( - tcp::async_io::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&local_key)?) - .multiplex(yamux::Config::default()) - .boxed(), - Behaviour::new(local_pub_key), - local_peer_id, - ) - .build(); + info!("Local peer id: {:?}", swarm.local_peer_id()); swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 996f9d007df..1af805e12db 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,5 +1,6 @@ // TODO: Rename runtime to provider // TODO: Should we have a timeout on transport? +// TODO: Be able to address `SwarmBuilder` configuration methods. use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; From e05ccaf6991c2cd66903b84ede9ff41df599ed0b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 15:18:43 +0200 Subject: [PATCH 031/171] Update libp2p identify example --- Cargo.lock | 1 + examples/identify/Cargo.toml | 1 + examples/identify/src/main.rs | 39 ++++++++++++++--------------------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ebb21f6d578..0dd487b3c4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2226,6 +2226,7 @@ version = "0.1.0" dependencies = [ "async-std", "async-trait", + "env_logger 0.10.0", "futures", "libp2p", ] diff --git a/examples/identify/Cargo.toml b/examples/identify/Cargo.toml index b11ea227c61..0fba5a0b3b8 100644 --- a/examples/identify/Cargo.toml +++ b/examples/identify/Cargo.toml @@ -8,5 +8,6 @@ license = "MIT" [dependencies] async-std = { version = "1.12", features = ["attributes"] } async-trait = "0.1" +env_logger = "0.10" futures = "0.3.28" libp2p = { path = "../../libp2p", features = ["async-std", "dns", "dcutr", "identify", "macros", "noise", "ping", "relay", "rendezvous", "tcp", "tokio", "yamux"] } diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index 7abdd5e9b92..d1621abb5b8 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -20,35 +20,28 @@ #![doc = include_str!("../README.md")] -use futures::prelude::*; -use libp2p::{ - core::{multiaddr::Multiaddr, upgrade::Version}, - identify, identity, noise, - swarm::{SwarmBuilder, SwarmEvent}, - tcp, yamux, PeerId, Transport, -}; +use futures::StreamExt; +use libp2p::{core::multiaddr::Multiaddr, identify, swarm::SwarmEvent}; use std::error::Error; #[async_std::main] async fn main() -> Result<(), Box> { - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - println!("Local peer id: {local_peer_id:?}"); + env_logger::init(); - let transport = tcp::async_io::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&local_key).unwrap()) - .multiplex(yamux::Config::default()) - .boxed(); + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .with_noise() + .with_behaviour(|key| { + identify::Behaviour::new(identify::Config::new( + "/ipfs/id/1.0.0".to_string(), + key.public(), + )) + }) + .build(); - // Create a identify network behaviour. - let behaviour = identify::Behaviour::new(identify::Config::new( - "/ipfs/id/1.0.0".to_string(), - local_key.public(), - )); - - let mut swarm = - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); + println!("Local peer id: {:?}", swarm.local_peer_id()); // Tell the swarm to listen on all interfaces and a random, OS-assigned // port. From e4abd6add1d01321b59a367a53dfaa222d17532b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 15:28:15 +0200 Subject: [PATCH 032/171] Update ipfs-kad example --- examples/ipfs-kad/src/main.rs | 55 +++++++++++++++++------------------ libp2p/src/builder.rs | 7 ++--- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index 1d0ed0a3b00..939612c66b2 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -23,11 +23,7 @@ use futures::StreamExt; use libp2p::kad::record::store::MemoryStore; use libp2p::kad::{GetClosestPeersError, Kademlia, KademliaConfig, KademliaEvent, QueryResult}; -use libp2p::{ - development_transport, identity, - swarm::{SwarmBuilder, SwarmEvent}, - PeerId, -}; +use libp2p::{swarm::SwarmEvent, PeerId}; use std::{env, error::Error, time::Duration}; const BOOTNODES: [&str; 4] = [ @@ -41,30 +37,33 @@ const BOOTNODES: [&str; 4] = [ async fn main() -> Result<(), Box> { env_logger::init(); - // Create a random key for ourselves. - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .with_tcp() + .with_noise() + .without_relay() + .without_any_other_transports() + .with_dns() + .await + .without_websocket() + .with_behaviour(|key| { + // Create a Kademlia behaviour. + let mut cfg = KademliaConfig::default(); + cfg.set_query_timeout(Duration::from_secs(5 * 60)); + let store = MemoryStore::new(key.public().to_peer_id()); + Kademlia::with_config(key.public().to_peer_id(), store, cfg) + }) + .build(); - // Set up a an encrypted DNS-enabled TCP Transport over the yamux protocol - let transport = development_transport(local_key).await?; - - // Create a swarm to manage peers and events. - let mut swarm = { - // Create a Kademlia behaviour. - let mut cfg = KademliaConfig::default(); - cfg.set_query_timeout(Duration::from_secs(5 * 60)); - let store = MemoryStore::new(local_peer_id); - let mut behaviour = Kademlia::with_config(local_peer_id, store, cfg); - - // Add the bootnodes to the local routing table. `libp2p-dns` built - // into the `transport` resolves the `dnsaddr` when Kademlia tries - // to dial these nodes. - for peer in &BOOTNODES { - behaviour.add_address(&peer.parse()?, "/dnsaddr/bootstrap.libp2p.io".parse()?); - } - - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build() - }; + // Add the bootnodes to the local routing table. `libp2p-dns` built + // into the `transport` resolves the `dnsaddr` when Kademlia tries + // to dial these nodes. + for peer in &BOOTNODES { + swarm + .behaviour_mut() + .add_address(&peer.parse()?, "/dnsaddr/bootstrap.libp2p.io".parse()?); + } // Order Kademlia to search for a peer. let to_search = env::args() diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 1af805e12db..57fb82971f9 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,6 +1,7 @@ // TODO: Rename runtime to provider // TODO: Should we have a timeout on transport? // TODO: Be able to address `SwarmBuilder` configuration methods. +// TODO: Shortcut WebsocketBuidler --with_behaviour--> BehaviourBuilder use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; @@ -606,7 +607,6 @@ macro_rules! impl_websocket_noise_builder { feature = $runtimeKebabCase, feature = "websocket", feature = "dns", - feature = "websocket", feature = "tls" ))] impl @@ -642,16 +642,15 @@ macro_rules! impl_websocket_noise_builder { } } - #[cfg(all(feature = "$runtimeKebabCase", feature = "dns", feature = "websocket"))] + #[cfg(all(feature = $runtimeKebabCase, feature = "dns", feature = "websocket", feature = "noise"))] impl WebsocketNoiseBuilder<$runtimeCamelCase, T, R, WithoutTls> { - #[cfg(feature = "noise")] pub fn with_noise(self) -> BehaviourBuilder<$runtimeCamelCase, R> { construct_behaviour_builder!( self, $tcp, - libp2p_noise::Config::new(&self.keypair).unwrap(), + libp2p_noise::Config::new(&self.keypair).unwrap() ) } } From 7aff8eed141abae7f5e7c26822d9c5916c8404a3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 17:53:01 +0200 Subject: [PATCH 033/171] Update ipfs-private example --- examples/ipfs-private/src/main.rs | 138 +++++++++++++----------------- 1 file changed, 58 insertions(+), 80 deletions(-) diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 172131751d7..280ebed5d04 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -24,38 +24,15 @@ use async_std::io; use either::Either; use futures::{prelude::*, select}; use libp2p::{ - core::{muxing::StreamMuxerBox, transport, transport::upgrade::Version}, - gossipsub, identify, identity, + core::{muxing::StreamMuxerBox, 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}; - -/// Builds the transport that serves as a common ground for all connections. -pub fn build_transport( - key_pair: identity::Keypair, - psk: Option, -) -> transport::Boxed<(PeerId, StreamMuxerBox)> { - let noise_config = noise::Config::new(&key_pair).unwrap(); - let yamux_config = yamux::Config::default(); - - let base_transport = tcp::async_io::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() -} +use std::{env, error::Error, fs, path::Path, str::FromStr}; /// Get the current ipfs repo path, either from the IPFS_PATH environment variable or /// from the default $HOME/.ipfs @@ -118,76 +95,77 @@ async fn main() -> Result<(), Box> { .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), - } - - impl From for MyBehaviourEvent { - fn from(event: gossipsub::Event) -> Self { - MyBehaviourEvent::Gossipsub(event) - } - } - - impl From for MyBehaviourEvent { - fn from(event: identify::Event) -> Self { - MyBehaviourEvent::Identify(event) - } - } + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_async_std() + .without_tcp() + .without_relay() + .with_other_transport(|key| { + let noise_config = noise::Config::new(&key).unwrap(); + let yamux_config = yamux::Config::default(); - impl From for MyBehaviourEvent { - fn from(event: ping::Event) -> Self { - MyBehaviourEvent::Ping(event) - } - } + let base_transport = + tcp::async_io::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) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) + }) + .without_any_other_transports() + .with_dns() + .await + .without_websocket() + .with_behaviour(|key| { + let gossipsub_config = gossipsub::ConfigBuilder::default() + .max_transmit_size(262144) + .build() + .expect("valid config"); + 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(); - // 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!("using random peer id: {:?}", swarm.local_peer_id()); - println!("Subscribing to {gossipsub_topic:?}"); - behaviour.gossipsub.subscribe(&gossipsub_topic).unwrap(); - SwarmBuilder::with_async_std_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) { From 7a7e3c4452b73ce296e79524c8be629e55d240cb Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 18:01:49 +0200 Subject: [PATCH 034/171] Update relay server --- examples/dcutr/src/main.rs | 2 -- examples/ipfs-kad/src/main.rs | 1 - examples/ipfs-private/src/main.rs | 1 - examples/relay-server/src/main.rs | 57 +++++++++++++------------------ libp2p/src/builder.rs | 22 +++++++++++- 5 files changed, 44 insertions(+), 39 deletions(-) diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index f632042316f..db22704eac7 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -136,8 +136,6 @@ async fn main() -> Result<(), Box> { .without_any_other_transports() .with_dns() .await - // TODO: shortcut - .without_websocket() .with_behaviour(|keypair, relay_behaviour| Behaviour { relay_client: relay_behaviour, ping: ping::Behaviour::new(ping::Config::new()), diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index 939612c66b2..23b8539a965 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -46,7 +46,6 @@ async fn main() -> Result<(), Box> { .without_any_other_transports() .with_dns() .await - .without_websocket() .with_behaviour(|key| { // Create a Kademlia behaviour. let mut cfg = KademliaConfig::default(); diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 280ebed5d04..7e57afe0310 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -137,7 +137,6 @@ async fn main() -> Result<(), Box> { .without_any_other_transports() .with_dns() .await - .without_websocket() .with_behaviour(|key| { let gossipsub_config = gossipsub::ConfigBuilder::default() .max_transmit_size(262144) diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index 6a1d956b5a5..89c4649fe25 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -22,18 +22,16 @@ #![doc = include_str!("../README.md")] use clap::Parser; +use futures::executor::block_on; use futures::stream::StreamExt; -use futures::{executor::block_on, future::Either}; use libp2p::{ core::multiaddr::Protocol, core::muxing::StreamMuxerBox, - core::upgrade, core::{Multiaddr, Transport}, identify, identity, identity::PeerId, - noise, ping, relay, - swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, + ping, relay, + swarm::{NetworkBehaviour, SwarmEvent}, }; use libp2p_quic as quic; use std::error::Error; @@ -43,42 +41,33 @@ fn main() -> Result<(), Box> { env_logger::init(); let opt = Opt::parse(); - println!("opt: {opt:?}"); // Create a static known PeerId based on given secret let local_key: identity::Keypair = generate_ed25519(opt.secret_key_seed); let local_peer_id = PeerId::from(local_key.public()); println!("Local peer id: {local_peer_id:?}"); - let tcp_transport = tcp::async_io::Transport::default(); - - let tcp_transport = tcp_transport - .upgrade(upgrade::Version::V1Lazy) - .authenticate( - noise::Config::new(&local_key).expect("Signing libp2p-noise static DH keypair failed."), - ) - .multiplex(libp2p::yamux::Config::default()); - - let quic_transport = quic::async_std::Transport::new(quic::Config::new(&local_key)); - - let transport = quic_transport - .or_transport(tcp_transport) - .map(|either_output, _| match either_output { - Either::Left((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), - Either::Right((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_existing_identity(local_key) + .with_async_std() + .with_tcp() + .with_noise() + .without_relay() + .with_other_transport(|keypair| { + quic::async_std::Transport::new(quic::Config::new(&keypair)) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) + }) + .without_any_other_transports() + .without_dns() + .with_behaviour(|key| Behaviour { + relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), + ping: ping::Behaviour::new(ping::Config::new()), + identify: identify::Behaviour::new(identify::Config::new( + "/TODO/0.0.1".to_string(), + key.public(), + )), }) - .boxed(); - - let behaviour = Behaviour { - relay: relay::Behaviour::new(local_peer_id, Default::default()), - ping: ping::Behaviour::new(ping::Config::new()), - identify: identify::Behaviour::new(identify::Config::new( - "/TODO/0.0.1".to_string(), - local_key.public(), - )), - }; - - let mut swarm = SwarmBuilder::without_executor(transport, behaviour, local_peer_id).build(); + .build(); // Listen on all interfaces let listen_addr_tcp = Multiaddr::empty() diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 57fb82971f9..666c1ec4a1b 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,7 +1,6 @@ // TODO: Rename runtime to provider // TODO: Should we have a timeout on transport? // TODO: Be able to address `SwarmBuilder` configuration methods. -// TODO: Shortcut WebsocketBuidler --with_behaviour--> BehaviourBuilder use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; @@ -537,6 +536,27 @@ impl WebsocketBuilder { } } +// Shortcuts +#[cfg(feature = "relay")] +impl + WebsocketBuilder +{ + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, + ) -> Builder { + self.without_websocket().with_behaviour(constructor) + } +} +impl WebsocketBuilder { + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> B, + ) -> Builder { + self.without_websocket().with_behaviour(constructor) + } +} + #[cfg(feature = "websocket")] pub struct WebsocketTlsBuilder { transport: T, From f4a4ca3aaae3aebdd210b96c0af6b51c1e440cc4 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 18:09:11 +0200 Subject: [PATCH 035/171] Update rendezvous examples --- examples/rendezvous/src/bin/rzv-discover.rs | 30 ++++++++------------ examples/rendezvous/src/bin/rzv-identify.rs | 31 +++++++++------------ examples/rendezvous/src/bin/rzv-register.rs | 29 ++++++++----------- examples/rendezvous/src/main.rs | 29 ++++++++----------- 4 files changed, 48 insertions(+), 71 deletions(-) diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index 710b491ff0a..84018e37ed8 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -20,12 +20,10 @@ use futures::StreamExt; use libp2p::{ - core::transport::upgrade::Version, - identity, multiaddr::Protocol, - noise, ping, rendezvous, - swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, yamux, Multiaddr, PeerId, Transport, + ping, rendezvous, + swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, + Multiaddr, }; use std::time::Duration; @@ -35,26 +33,22 @@ const NAMESPACE: &str = "rendezvous"; async fn main() { env_logger::init(); - let key_pair = identity::Keypair::generate_ed25519(); let rendezvous_point_address = "/ip4/127.0.0.1/tcp/62649".parse::().unwrap(); let rendezvous_point = "12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN" .parse() .unwrap(); - let mut swarm = SwarmBuilder::with_tokio_executor( - tcp::tokio::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&key_pair).unwrap()) - .multiplex(yamux::Config::default()) - .boxed(), - MyBehaviour { - rendezvous: rendezvous::client::Behaviour::new(key_pair.clone()), + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .with_noise() + .with_behaviour(|key| MyBehaviour { + rendezvous: rendezvous::client::Behaviour::new(key.clone()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), keep_alive: keep_alive::Behaviour, - }, - PeerId::from(key_pair.public()), - ) - .build(); + }) + .build(); log::info!("Local peer id: {}", swarm.local_peer_id()); diff --git a/examples/rendezvous/src/bin/rzv-identify.rs b/examples/rendezvous/src/bin/rzv-identify.rs index 7c326688231..7f00107ae11 100644 --- a/examples/rendezvous/src/bin/rzv-identify.rs +++ b/examples/rendezvous/src/bin/rzv-identify.rs @@ -20,10 +20,9 @@ use futures::StreamExt; use libp2p::{ - core::transport::upgrade::Version, - identify, identity, noise, ping, rendezvous, - swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, yamux, Multiaddr, PeerId, Transport, + identify, ping, rendezvous, + swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, + Multiaddr, }; use std::time::Duration; @@ -31,30 +30,26 @@ use std::time::Duration; async fn main() { env_logger::init(); - let key_pair = identity::Keypair::generate_ed25519(); let rendezvous_point_address = "/ip4/127.0.0.1/tcp/62649".parse::().unwrap(); let rendezvous_point = "12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN" .parse() .unwrap(); - let mut swarm = SwarmBuilder::with_tokio_executor( - tcp::tokio::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&key_pair).unwrap()) - .multiplex(yamux::Config::default()) - .boxed(), - MyBehaviour { + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .with_noise() + .with_behaviour(|key| MyBehaviour { identify: identify::Behaviour::new(identify::Config::new( "rendezvous-example/1.0.0".to_string(), - key_pair.public(), + key.public(), )), - rendezvous: rendezvous::client::Behaviour::new(key_pair.clone()), + rendezvous: rendezvous::client::Behaviour::new(key.clone()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), keep_alive: keep_alive::Behaviour, - }, - PeerId::from(key_pair.public()), - ) - .build(); + }) + .build(); log::info!("Local peer id: {}", swarm.local_peer_id()); diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index f9fd12b1493..dfe1b55189a 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -20,10 +20,9 @@ use futures::StreamExt; use libp2p::{ - core::transport::upgrade::Version, - identity, noise, ping, rendezvous, - swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, yamux, Multiaddr, PeerId, Transport, + ping, rendezvous, + swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, + Multiaddr, }; use std::time::Duration; @@ -31,26 +30,22 @@ use std::time::Duration; async fn main() { env_logger::init(); - let key_pair = identity::Keypair::generate_ed25519(); let rendezvous_point_address = "/ip4/127.0.0.1/tcp/62649".parse::().unwrap(); let rendezvous_point = "12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN" .parse() .unwrap(); - let mut swarm = SwarmBuilder::with_tokio_executor( - tcp::tokio::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&key_pair).unwrap()) - .multiplex(yamux::Config::default()) - .boxed(), - MyBehaviour { - rendezvous: rendezvous::client::Behaviour::new(key_pair.clone()), + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .with_noise() + .with_behaviour(|key| MyBehaviour { + rendezvous: rendezvous::client::Behaviour::new(key.clone()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), keep_alive: keep_alive::Behaviour, - }, - PeerId::from(key_pair.public()), - ) - .build(); + }) + .build(); // In production the external address should be the publicly facing IP address of the rendezvous point. // This address is recorded in the registration entry by the rendezvous point. diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 4f5aca75e52..5faec5a9275 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -22,10 +22,8 @@ use futures::StreamExt; use libp2p::{ - core::transport::upgrade::Version, - identify, identity, noise, ping, rendezvous, - swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent}, - tcp, yamux, PeerId, Transport, + identify, ping, rendezvous, + swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, }; use std::time::Duration; @@ -33,26 +31,21 @@ use std::time::Duration; async fn main() { env_logger::init(); - let key_pair = identity::Keypair::generate_ed25519(); - - let mut swarm = SwarmBuilder::with_tokio_executor( - tcp::tokio::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&key_pair).unwrap()) - .multiplex(yamux::Config::default()) - .boxed(), - MyBehaviour { + let mut swarm = libp2p::builder::SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .with_noise() + .with_behaviour(|key| MyBehaviour { identify: identify::Behaviour::new(identify::Config::new( "rendezvous-example/1.0.0".to_string(), - key_pair.public(), + key.public(), )), rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), keep_alive: keep_alive::Behaviour, - }, - PeerId::from(key_pair.public()), - ) - .build(); + }) + .build(); log::info!("Local peer id: {}", swarm.local_peer_id()); From cb67678abdb92be7f9f68dbff66968224820a25c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 18:15:50 +0200 Subject: [PATCH 036/171] Export as libp2p::SwarmBuilder --- examples/autonat/src/bin/autonat_client.rs | 2 +- examples/autonat/src/bin/autonat_server.rs | 2 +- examples/chat-example/src/main.rs | 2 +- examples/dcutr/src/main.rs | 2 +- examples/distributed-key-value-store/src/main.rs | 2 +- examples/file-sharing/src/network.rs | 8 +++----- examples/identify/src/main.rs | 2 +- examples/ipfs-kad/src/main.rs | 2 +- examples/ipfs-private/src/main.rs | 2 +- examples/metrics/src/main.rs | 2 +- examples/ping-example/src/main.rs | 2 +- examples/relay-server/src/main.rs | 2 +- examples/rendezvous/src/bin/rzv-discover.rs | 2 +- examples/rendezvous/src/bin/rzv-identify.rs | 2 +- examples/rendezvous/src/bin/rzv-register.rs | 2 +- examples/rendezvous/src/main.rs | 2 +- libp2p/src/builder.rs | 2 ++ libp2p/src/lib.rs | 4 +++- 18 files changed, 23 insertions(+), 21 deletions(-) diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index 2af8bf64074..ddb818dd6a0 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -49,7 +49,7 @@ async fn main() -> Result<(), Box> { let opt = Opt::parse(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index 23ff8f787f2..414751879e2 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -41,7 +41,7 @@ async fn main() -> Result<(), Box> { let opt = Opt::parse(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 005508dfc51..27cdf720ea6 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -41,7 +41,7 @@ struct MyBehaviour { #[async_std::main] async fn main() -> Result<(), Box> { - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index db22704eac7..c4785961249 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -122,7 +122,7 @@ async fn main() -> Result<(), Box> { } } - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_existing_identity(generate_ed25519(opts.secret_key_seed)) .with_async_std() .with_tcp_config(tcp::Config::default().port_reuse(true).nodelay(true)) diff --git a/examples/distributed-key-value-store/src/main.rs b/examples/distributed-key-value-store/src/main.rs index 6fea0dcde86..de7db2a3c80 100644 --- a/examples/distributed-key-value-store/src/main.rs +++ b/examples/distributed-key-value-store/src/main.rs @@ -45,7 +45,7 @@ async fn main() -> Result<(), Box> { mdns: mdns::async_io::Behaviour, } - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 689991e6413..7366092c7d1 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -11,13 +11,11 @@ use libp2p::{ QueryResult, }, multiaddr::Protocol, - noise, request_response::{self, ProtocolSupport, RequestId, ResponseChannel}, - swarm::{NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent}, - tcp, yamux, PeerId, Transport, + swarm::{NetworkBehaviour, Swarm, SwarmEvent}, + PeerId, }; -use libp2p::core::upgrade::Version; use libp2p::StreamProtocol; use serde::{Deserialize, Serialize}; use std::collections::{hash_map, HashMap, HashSet}; @@ -45,7 +43,7 @@ pub(crate) async fn new( }; let peer_id = id_keys.public().to_peer_id(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_existing_identity(id_keys) .with_async_std() .with_tcp() diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index d1621abb5b8..d5022274b27 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -28,7 +28,7 @@ use std::error::Error; async fn main() -> Result<(), Box> { env_logger::init(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index 23b8539a965..a3166d50d0b 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -37,7 +37,7 @@ const BOOTNODES: [&str; 4] = [ async fn main() -> Result<(), Box> { env_logger::init(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 7e57afe0310..e87d4f2e7ad 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -110,7 +110,7 @@ async fn main() -> Result<(), Box> { ping: ping::Behaviour, } - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .without_tcp() diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index 01421a030c7..e411d243d3f 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -36,7 +36,7 @@ mod http_service; fn main() -> Result<(), Box> { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index 6145cf8cf3b..9439eca1da3 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -30,7 +30,7 @@ use std::error::Error; #[async_std::main] async fn main() -> Result<(), Box> { - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_async_std() .with_tcp() diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index 89c4649fe25..b42de9c3182 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -47,7 +47,7 @@ fn main() -> Result<(), Box> { let local_peer_id = PeerId::from(local_key.public()); println!("Local peer id: {local_peer_id:?}"); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_existing_identity(local_key) .with_async_std() .with_tcp() diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index 84018e37ed8..1453933c77e 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -38,7 +38,7 @@ async fn main() { .parse() .unwrap(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() diff --git a/examples/rendezvous/src/bin/rzv-identify.rs b/examples/rendezvous/src/bin/rzv-identify.rs index 7f00107ae11..62621f3980c 100644 --- a/examples/rendezvous/src/bin/rzv-identify.rs +++ b/examples/rendezvous/src/bin/rzv-identify.rs @@ -35,7 +35,7 @@ async fn main() { .parse() .unwrap(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index dfe1b55189a..ec344f15a0d 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -35,7 +35,7 @@ async fn main() { .parse() .unwrap(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 5faec5a9275..6a92ff0a72d 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -31,7 +31,7 @@ use std::time::Duration; async fn main() { env_logger::init(); - let mut swarm = libp2p::builder::SwarmBuilder::new() + let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 666c1ec4a1b..50d4fe05391 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -201,7 +201,9 @@ macro_rules! impl_tcp_noise_builder { impl_tcp_noise_builder!("async-std", AsyncStd, async_io); impl_tcp_noise_builder!("tokio", Tokio, tokio); +#[cfg(feature = "tls")] pub enum Tls {} + pub enum WithoutTls {} pub struct RelayBuilder { diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 58bca37c19c..613bfda09c2 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -139,7 +139,9 @@ pub use libp2p_webtransport_websys as webtransport_websys; #[doc(inline)] pub use libp2p_yamux as yamux; -pub mod builder; +mod builder; +pub use builder::SwarmBuilder; + mod transport_ext; pub mod bandwidth; From a6cf98f50b14a39531bf524eca2d20f535a800c3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 18:36:01 +0200 Subject: [PATCH 037/171] Add shortcuts to skip without_any_other_transports --- examples/chat-example/src/main.rs | 1 - examples/dcutr/src/main.rs | 1 - examples/ipfs-kad/src/main.rs | 2 - examples/ipfs-private/src/main.rs | 1 - examples/ping-example/src/main.rs | 3 -- examples/relay-server/src/main.rs | 2 - libp2p/src/builder.rs | 64 +++++++++++++++++++++++++++++++ 7 files changed, 64 insertions(+), 10 deletions(-) diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 27cdf720ea6..5b33e22fb66 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -51,7 +51,6 @@ async fn main() -> Result<(), Box> { quic::async_std::Transport::new(quic::Config::new(&key)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .without_any_other_transports() .with_behaviour(|key| { // To content-address message, we can take the hash of message and use it as an ID. let message_id_fn = |message: &gossipsub::Message| { diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index c4785961249..1fc8e901779 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -133,7 +133,6 @@ async fn main() -> Result<(), Box> { quic::async_std::Transport::new(quic::Config::new(&keypair)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .without_any_other_transports() .with_dns() .await .with_behaviour(|keypair, relay_behaviour| Behaviour { diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index a3166d50d0b..bd326fb2511 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -42,8 +42,6 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise() - .without_relay() - .without_any_other_transports() .with_dns() .await .with_behaviour(|key| { diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index e87d4f2e7ad..2d59741faca 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -134,7 +134,6 @@ async fn main() -> Result<(), Box> { .multiplex(yamux_config) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .without_any_other_transports() .with_dns() .await .with_behaviour(|key| { diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index 9439eca1da3..0bcea0f92b7 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -36,9 +36,6 @@ async fn main() -> Result<(), Box> { .with_tcp() .without_tls() .with_noise() - .without_relay() - .without_any_other_transports() - .without_dns() .with_behaviour(|_| Behaviour::default()) .build(); diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index b42de9c3182..3125384647a 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -57,8 +57,6 @@ fn main() -> Result<(), Box> { quic::async_std::Transport::new(quic::Config::new(&keypair)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .without_any_other_transports() - .without_dns() .with_behaviour(|key| Behaviour { relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), ping: ping::Behaviour::new(ping::Config::new()), diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 50d4fe05391..384120c656d 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,6 +1,7 @@ // TODO: Rename runtime to provider // TODO: Should we have a timeout on transport? // TODO: Be able to address `SwarmBuilder` configuration methods. +// TODO: Consider moving with_relay after with_other_transport. use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; @@ -258,6 +259,28 @@ impl RelayBuilder { .with_behaviour(constructor) } } +// Shortcuts +#[cfg(all(feature = "async-std", feature = "dns"))] +impl RelayBuilder { + pub async fn with_dns( + self, + ) -> WebsocketBuilder { + self.without_relay() + .without_any_other_transports() + .with_dns() + .await + } +} +#[cfg(all(feature = "tokio", feature = "dns"))] +impl RelayBuilder { + pub fn with_dns( + self, + ) -> WebsocketBuilder { + self.without_relay() + .without_any_other_transports() + .with_dns() + } +} #[cfg(feature = "relay")] pub struct RelayTlsBuilder { @@ -435,6 +458,47 @@ impl OtherTransportBuilder } } +// Shortcuts +#[cfg(all(feature = "async-std", feature = "dns"))] +impl OtherTransportBuilder { + pub async fn with_dns( + self, + ) -> WebsocketBuilder { + self.without_any_other_transports().with_dns().await + } +} +#[cfg(all(feature = "tokio", feature = "dns"))] +impl OtherTransportBuilder { + pub fn with_dns(self) -> WebsocketBuilder { + self.without_any_other_transports().with_dns() + } +} +#[cfg(feature = "relay")] +impl + OtherTransportBuilder +{ + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, + ) -> Builder { + self.without_any_other_transports() + .without_dns() + .without_websocket() + .with_behaviour(constructor) + } +} +impl OtherTransportBuilder { + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> B, + ) -> Builder { + self.without_any_other_transports() + .without_dns() + .without_websocket() + .with_behaviour(constructor) + } +} + pub struct DnsBuilder { transport: T, relay_behaviour: R, From 04a39c0001e285f74ae36c7d5f38daa6302e05bf Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 13 Aug 2023 19:49:28 +0200 Subject: [PATCH 038/171] Error handling --- Cargo.lock | 1 + examples/autonat/src/bin/autonat_client.rs | 2 +- examples/autonat/src/bin/autonat_server.rs | 2 +- examples/chat-example/src/main.rs | 3 +- examples/dcutr/src/main.rs | 6 +- .../distributed-key-value-store/src/main.rs | 2 +- examples/file-sharing/src/network.rs | 2 +- examples/identify/src/main.rs | 2 +- examples/ipfs-kad/src/main.rs | 4 +- examples/ipfs-private/src/main.rs | 2 +- examples/metrics/src/main.rs | 2 +- examples/ping-example/src/main.rs | 3 +- examples/relay-server/src/main.rs | 3 +- examples/rendezvous/src/bin/rzv-discover.rs | 5 +- examples/rendezvous/src/bin/rzv-identify.rs | 1 + examples/rendezvous/src/bin/rzv-register.rs | 1 + examples/rendezvous/src/main.rs | 7 +- libp2p/Cargo.toml | 1 + libp2p/src/builder.rs | 278 +++++++++++------- 19 files changed, 196 insertions(+), 131 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0dd487b3c4f..2f747d8b9e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2558,6 +2558,7 @@ dependencies = [ "libp2p-yamux", "multiaddr", "pin-project", + "thiserror", "tokio", ] diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index ddb818dd6a0..120c67fa395 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -54,7 +54,7 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .without_tls() - .with_noise() + .with_noise()? .with_behaviour(|key| Behaviour::new(key.public())) .build(); diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index 414751879e2..1a1659152f3 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -46,7 +46,7 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .without_tls() - .with_noise() + .with_noise()? .with_behaviour(|key| Behaviour::new(key.public())) .build(); diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 5b33e22fb66..bbcb2865985 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -45,8 +45,7 @@ async fn main() -> Result<(), Box> { .with_new_identity() .with_async_std() .with_tcp() - .without_tls() - .with_noise() + .with_noise()? .with_other_transport(|key| { quic::async_std::Transport::new(quic::Config::new(&key)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 1fc8e901779..0ff8a060eb1 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -126,15 +126,15 @@ async fn main() -> Result<(), Box> { .with_existing_identity(generate_ed25519(opts.secret_key_seed)) .with_async_std() .with_tcp_config(tcp::Config::default().port_reuse(true).nodelay(true)) - .with_noise() + .with_noise()? .with_relay() - .with_noise() + .with_noise()? .with_other_transport(|keypair| { quic::async_std::Transport::new(quic::Config::new(&keypair)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) .with_dns() - .await + .await? .with_behaviour(|keypair, relay_behaviour| Behaviour { relay_client: relay_behaviour, ping: ping::Behaviour::new(ping::Config::new()), diff --git a/examples/distributed-key-value-store/src/main.rs b/examples/distributed-key-value-store/src/main.rs index de7db2a3c80..d6cd4430296 100644 --- a/examples/distributed-key-value-store/src/main.rs +++ b/examples/distributed-key-value-store/src/main.rs @@ -49,7 +49,7 @@ async fn main() -> Result<(), Box> { .with_new_identity() .with_async_std() .with_tcp() - .with_noise() + .with_noise()? .with_behaviour(|key| MyBehaviour { kademlia: Kademlia::new( key.public().to_peer_id(), diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 7366092c7d1..92b55081e1c 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -47,7 +47,7 @@ pub(crate) async fn new( .with_existing_identity(id_keys) .with_async_std() .with_tcp() - .with_noise() + .with_noise()? .with_behaviour(|key| ComposedBehaviour { kademlia: Kademlia::new(peer_id, MemoryStore::new(key.public().to_peer_id())), request_response: request_response::cbor::Behaviour::new( diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index d5022274b27..f63a634341d 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -32,7 +32,7 @@ async fn main() -> Result<(), Box> { .with_new_identity() .with_async_std() .with_tcp() - .with_noise() + .with_noise()? .with_behaviour(|key| { identify::Behaviour::new(identify::Config::new( "/ipfs/id/1.0.0".to_string(), diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index bd326fb2511..cdd2c6667a5 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -41,9 +41,9 @@ async fn main() -> Result<(), Box> { .with_new_identity() .with_async_std() .with_tcp() - .with_noise() + .with_noise()? .with_dns() - .await + .await? .with_behaviour(|key| { // Create a Kademlia behaviour. let mut cfg = KademliaConfig::default(); diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 2d59741faca..a98ce825ccb 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -135,7 +135,7 @@ async fn main() -> Result<(), Box> { .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) .with_dns() - .await + .await? .with_behaviour(|key| { let gossipsub_config = gossipsub::ConfigBuilder::default() .max_transmit_size(262144) diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index e411d243d3f..68deffef6d0 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -40,7 +40,7 @@ fn main() -> Result<(), Box> { .with_new_identity() .with_async_std() .with_tcp() - .with_noise() + .with_noise()? .with_behaviour(|key| Behaviour::new(key.public())) .build(); diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index 0bcea0f92b7..292523c9c56 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -34,8 +34,7 @@ async fn main() -> Result<(), Box> { .with_new_identity() .with_async_std() .with_tcp() - .without_tls() - .with_noise() + .with_noise()? .with_behaviour(|_| Behaviour::default()) .build(); diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index 3125384647a..46db3fa49b7 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -51,8 +51,7 @@ fn main() -> Result<(), Box> { .with_existing_identity(local_key) .with_async_std() .with_tcp() - .with_noise() - .without_relay() + .with_noise()? .with_other_transport(|keypair| { quic::async_std::Transport::new(quic::Config::new(&keypair)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index 1453933c77e..c1988d0bcc9 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -25,12 +25,13 @@ use libp2p::{ swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, Multiaddr, }; +use std::error::Error; use std::time::Duration; const NAMESPACE: &str = "rendezvous"; #[tokio::main] -async fn main() { +async fn main() -> Result<(), Box> { env_logger::init(); let rendezvous_point_address = "/ip4/127.0.0.1/tcp/62649".parse::().unwrap(); @@ -42,7 +43,7 @@ async fn main() { .with_new_identity() .with_tokio() .with_tcp() - .with_noise() + .with_noise()? .with_behaviour(|key| MyBehaviour { rendezvous: rendezvous::client::Behaviour::new(key.clone()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), diff --git a/examples/rendezvous/src/bin/rzv-identify.rs b/examples/rendezvous/src/bin/rzv-identify.rs index 62621f3980c..a912adbef5b 100644 --- a/examples/rendezvous/src/bin/rzv-identify.rs +++ b/examples/rendezvous/src/bin/rzv-identify.rs @@ -40,6 +40,7 @@ async fn main() { .with_tokio() .with_tcp() .with_noise() + .unwrap() .with_behaviour(|key| MyBehaviour { identify: identify::Behaviour::new(identify::Config::new( "rendezvous-example/1.0.0".to_string(), diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index ec344f15a0d..442597ebb55 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -40,6 +40,7 @@ async fn main() { .with_tokio() .with_tcp() .with_noise() + .unwrap() .with_behaviour(|key| MyBehaviour { rendezvous: rendezvous::client::Behaviour::new(key.clone()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 6a92ff0a72d..0d1a56fb0b3 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -25,17 +25,18 @@ use libp2p::{ identify, ping, rendezvous, swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, }; +use std::error::Error; use std::time::Duration; #[tokio::main] -async fn main() { +async fn main() -> Result<(), Box> { env_logger::init(); let mut swarm = libp2p::SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() - .with_noise() + .with_noise()? .with_behaviour(|key| MyBehaviour { identify: identify::Behaviour::new(identify::Config::new( "rendezvous-example/1.0.0".to_string(), @@ -85,6 +86,8 @@ async fn main() { } } } + + Ok(()) } #[derive(NetworkBehaviour)] diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index e057c9e8dd4..27d98b7f32f 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -121,6 +121,7 @@ libp2p-yamux = { workspace = true, optional = true } multiaddr = { workspace = true } pin-project = "1.0.0" +thiserror = "1.0" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] libp2p-deflate = { workspace = true, optional = true } diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 384120c656d..319d114cbd9 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -109,14 +109,20 @@ impl

TcpTlsBuilder

{ #[cfg(all(feature = "tcp", feature = "noise", feature = "async-std"))] impl TcpTlsBuilder { #[cfg(feature = "noise")] - pub fn with_noise(self) -> RelayBuilder { + pub fn with_noise( + self, + ) -> Result, AuthenticationError> + { self.without_tls().with_noise() } } #[cfg(all(feature = "tcp", feature = "noise", feature = "tokio"))] impl TcpTlsBuilder { #[cfg(feature = "noise")] - pub fn with_noise(self) -> RelayBuilder { + pub fn with_noise( + self, + ) -> Result, AuthenticationError> + { self.without_tls().with_noise() } } @@ -131,16 +137,15 @@ pub struct TcpNoiseBuilder { #[cfg(feature = "tcp")] macro_rules! construct_relay_builder { ($self:ident, $tcp:ident, $auth:expr) => { - RelayBuilder { + Ok(RelayBuilder { transport: libp2p_tcp::$tcp::Transport::new($self.config) .upgrade(libp2p_core::upgrade::Version::V1Lazy) - // TODO: Handle unwrap? .authenticate($auth) .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), keypair: $self.keypair, phantom: PhantomData, - } + }) }; } @@ -151,14 +156,17 @@ macro_rules! impl_tcp_noise_builder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { + ) -> Result< + RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + AuthenticationError, + > { construct_relay_builder!( self, $tcp, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), + libp2p_tls::Config::new(&self.keypair)?, + libp2p_noise::Config::new(&self.keypair)?, ), |upgrade| match upgrade { futures::future::Either::Left((peer_id, upgrade)) => { @@ -174,12 +182,11 @@ macro_rules! impl_tcp_noise_builder { pub fn without_noise( self, - ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { - construct_relay_builder!( - self, - $tcp, - libp2p_tls::Config::new(&self.keypair).unwrap() - ) + ) -> Result< + RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + AuthenticationError, + > { + construct_relay_builder!(self, $tcp, libp2p_tls::Config::new(&self.keypair)?) } } @@ -188,12 +195,11 @@ macro_rules! impl_tcp_noise_builder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport> { - construct_relay_builder!( - self, - $tcp, - libp2p_noise::Config::new(&self.keypair).unwrap() - ) + ) -> Result< + RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + AuthenticationError, + > { + construct_relay_builder!(self, $tcp, libp2p_noise::Config::new(&self.keypair)?) } } }; @@ -207,6 +213,16 @@ pub enum Tls {} pub enum WithoutTls {} +#[derive(Debug, thiserror::Error)] +pub enum AuthenticationError { + #[error("Tls")] + #[cfg(feature = "tls")] + Tls(#[from] libp2p_tls::certificate::GenError), + #[error("Noise")] + #[cfg(feature = "noise")] + Noise(#[from] libp2p_noise::Error), +} + pub struct RelayBuilder { transport: T, keypair: libp2p_identity::Keypair, @@ -248,6 +264,16 @@ impl RelayBuilder { self.without_relay().with_other_transport(constructor) } + #[cfg(feature = "websocket")] + pub fn with_websocket( + self, + ) -> WebsocketTlsBuilder { + self.without_relay() + .without_any_other_transports() + .without_dns() + .with_websocket() + } + pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> B, @@ -264,7 +290,10 @@ impl RelayBuilder { impl RelayBuilder { pub async fn with_dns( self, - ) -> WebsocketBuilder { + ) -> Result< + WebsocketBuilder, + std::io::Error, + > { self.without_relay() .without_any_other_transports() .with_dns() @@ -275,7 +304,10 @@ impl RelayBuilder { impl RelayBuilder { pub fn with_dns( self, - ) -> WebsocketBuilder { + ) -> Result< + WebsocketBuilder, + std::io::Error, + > { self.without_relay() .without_any_other_transports() .with_dns() @@ -315,10 +347,13 @@ impl RelayTlsBuilder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> OtherTransportBuilder< - AsyncStd, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + ) -> Result< + OtherTransportBuilder< + AsyncStd, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, + AuthenticationError, > { self.without_tls().with_noise() } @@ -328,10 +363,13 @@ impl RelayTlsBuilder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> OtherTransportBuilder< - Tokio, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + ) -> Result< + OtherTransportBuilder< + Tokio, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, + AuthenticationError, > { self.without_tls().with_noise() } @@ -350,7 +388,7 @@ macro_rules! construct_other_transport_builder { let (relay_transport, relay_behaviour) = libp2p_relay::client::new($self.keypair.public().to_peer_id()); - OtherTransportBuilder { + Ok(OtherTransportBuilder { transport: $self .transport .or_transport( @@ -364,7 +402,7 @@ macro_rules! construct_other_transport_builder { keypair: $self.keypair, relay_behaviour, phantom: PhantomData, - } + }) }}; } @@ -373,18 +411,20 @@ impl RelayNoiseBuilder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> OtherTransportBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + ) -> Result< + OtherTransportBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, + AuthenticationError, > { - // TODO: Handle unwrap? construct_other_transport_builder!( self, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), + libp2p_tls::Config::new(&self.keypair)?, + libp2p_noise::Config::new(&self.keypair)?, ), |upgrade| match upgrade { futures::future::Either::Left((peer_id, upgrade)) => { @@ -399,12 +439,15 @@ impl RelayNoiseBuilder { } pub fn without_noise( self, - ) -> OtherTransportBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + ) -> Result< + OtherTransportBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, + AuthenticationError, > { - construct_other_transport_builder!(self, libp2p_tls::Config::new(&self.keypair).unwrap()) + construct_other_transport_builder!(self, libp2p_tls::Config::new(&self.keypair)?) } } @@ -413,12 +456,15 @@ impl RelayNoiseBuilder OtherTransportBuilder< - P, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + ) -> Result< + OtherTransportBuilder< + P, + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, + AuthenticationError, > { - construct_other_transport_builder!(self, libp2p_noise::Config::new(&self.keypair).unwrap()) + construct_other_transport_builder!(self, libp2p_noise::Config::new(&self.keypair)?) } } @@ -463,13 +509,17 @@ impl OtherTransportBuilder impl OtherTransportBuilder { pub async fn with_dns( self, - ) -> WebsocketBuilder { + ) -> Result, std::io::Error> + { self.without_any_other_transports().with_dns().await } } #[cfg(all(feature = "tokio", feature = "dns"))] impl OtherTransportBuilder { - pub fn with_dns(self) -> WebsocketBuilder { + pub fn with_dns( + self, + ) -> Result, std::io::Error> + { self.without_any_other_transports().with_dns() } } @@ -510,29 +560,29 @@ pub struct DnsBuilder { impl DnsBuilder { pub async fn with_dns( self, - ) -> WebsocketBuilder { - WebsocketBuilder { + ) -> Result, std::io::Error> + { + Ok(WebsocketBuilder { keypair: self.keypair, relay_behaviour: self.relay_behaviour, - // TODO: Timeout needed? - transport: libp2p_dns::DnsConfig::system(self.transport) - .await - .expect("TODO: Handle"), + transport: libp2p_dns::DnsConfig::system(self.transport).await?, phantom: PhantomData, - } + }) } } #[cfg(all(feature = "tokio", feature = "dns"))] impl DnsBuilder { - pub fn with_dns(self) -> WebsocketBuilder { - WebsocketBuilder { + pub fn with_dns( + self, + ) -> Result, std::io::Error> + { + Ok(WebsocketBuilder { keypair: self.keypair, relay_behaviour: self.relay_behaviour, - // TODO: Timeout needed? - transport: libp2p_dns::TokioDnsConfig::system(self.transport).expect("TODO: Handle"), + transport: libp2p_dns::TokioDnsConfig::system(self.transport)?, phantom: PhantomData, - } + }) } } @@ -663,19 +713,14 @@ pub struct WebsocketNoiseBuilder { #[cfg(feature = "websocket")] macro_rules! construct_behaviour_builder { - ($self:ident, $tcp:ident, $auth:expr) => {{ - let websocket_transport = libp2p_websocket::WsConfig::new( - futures::executor::block_on(libp2p_dns::DnsConfig::system( - libp2p_tcp::$tcp::Transport::new(libp2p_tcp::Config::default()), - )) - .unwrap(), - ) - .upgrade(libp2p_core::upgrade::Version::V1) - .authenticate($auth) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))); - - BehaviourBuilder { + ($self:ident, $dnsTcp:expr, $auth:expr) => {{ + let websocket_transport = libp2p_websocket::WsConfig::new($dnsTcp.await?) + .upgrade(libp2p_core::upgrade::Version::V1) + .authenticate($auth) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))); + + Ok(BehaviourBuilder { transport: websocket_transport .or_transport($self.transport) .map(|either, _| either.into_inner()) @@ -683,12 +728,12 @@ macro_rules! construct_behaviour_builder { keypair: $self.keypair, relay_behaviour: $self.relay_behaviour, phantom: PhantomData, - } + }) }}; } macro_rules! impl_websocket_noise_builder { - ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:ident) => { + ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $dnsTcp:expr) => { #[cfg(all( feature = $runtimeKebabCase, feature = "websocket", @@ -699,14 +744,14 @@ macro_rules! impl_websocket_noise_builder { WebsocketNoiseBuilder<$runtimeCamelCase, T, R, Tls> { #[cfg(feature = "noise")] - pub fn with_noise(self) -> BehaviourBuilder<$runtimeCamelCase, R> { + pub async fn with_noise(self) -> Result,WebsocketError> { construct_behaviour_builder!( self, - $tcp, + $dnsTcp, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).unwrap(), - libp2p_noise::Config::new(&self.keypair).unwrap(), + libp2p_tls::Config::new(&self.keypair).map_err(Into::::into)?, + libp2p_noise::Config::new(&self.keypair).map_err(Into::::into)?, ), |upgrade| match upgrade { futures::future::Either::Left((peer_id, upgrade)) => { @@ -719,11 +764,11 @@ macro_rules! impl_websocket_noise_builder { ) ) } - pub fn without_noise(self) -> BehaviourBuilder<$runtimeCamelCase, R> { + pub async fn without_noise(self) -> Result,WebsocketError> { construct_behaviour_builder!( self, - $tcp, - libp2p_tls::Config::new(&self.keypair).unwrap() + $dnsTcp, + libp2p_tls::Config::new(&self.keypair).map_err(Into::::into)? ) } } @@ -732,19 +777,42 @@ macro_rules! impl_websocket_noise_builder { impl WebsocketNoiseBuilder<$runtimeCamelCase, T, R, WithoutTls> { - pub fn with_noise(self) -> BehaviourBuilder<$runtimeCamelCase, R> { + pub async fn with_noise(self) -> Result, WebsocketError> { construct_behaviour_builder!( self, - $tcp, - libp2p_noise::Config::new(&self.keypair).unwrap() + $dnsTcp, + libp2p_noise::Config::new(&self.keypair).map_err(Into::::into)? ) } } }; } -impl_websocket_noise_builder!("async-std", AsyncStd, async_io); -impl_websocket_noise_builder!("tokio", Tokio, tokio); +impl_websocket_noise_builder!( + "async-std", + AsyncStd, + libp2p_dns::DnsConfig::system(libp2p_tcp::async_io::Transport::new( + libp2p_tcp::Config::default(), + )) +); +// TODO: Unnecessary await for Tokio Websocket (i.e. tokio dns). Not ideal but don't know a better way. +impl_websocket_noise_builder!( + "tokio", + Tokio, + futures::future::ready(libp2p_dns::TokioDnsConfig::system( + libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) + )) +); + +#[derive(Debug, thiserror::Error)] +pub enum WebsocketError { + #[error("Dns")] + #[cfg(any(feature = "tls", feature = "noise"))] + Authentication(#[from] AuthenticationError), + #[cfg(feature = "dns")] + #[error("Dns")] + Dns(#[from] std::io::Error), +} pub struct BehaviourBuilder { keypair: libp2p_identity::Keypair, @@ -862,10 +930,7 @@ mod tests { .with_tcp() .with_tls() .with_noise() - .without_relay() - .without_any_other_transports() - .without_dns() - .without_websocket() + .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); } @@ -892,12 +957,11 @@ mod tests { .with_tcp() .with_tls() .with_noise() + .unwrap() .with_relay() .with_tls() .with_noise() - .without_any_other_transports() - .without_dns() - .without_websocket() + .unwrap() .with_behaviour(|_, relay| Behaviour { dummy: libp2p_swarm::dummy::Behaviour, relay, @@ -920,10 +984,9 @@ mod tests { .with_tcp() .with_tls() .with_noise() - .without_relay() - .without_any_other_transports() + .unwrap() .with_dns() - .without_websocket() + .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); } @@ -938,18 +1001,15 @@ mod tests { .with_tcp() .with_tls() .with_noise() - .without_relay() + .unwrap() .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .without_any_other_transports() - .without_dns() - .without_websocket() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); } - #[test] + #[tokio::test] #[cfg(all( feature = "tokio", feature = "tcp", @@ -958,19 +1018,19 @@ mod tests { feature = "dns", feature = "websocket", ))] - fn tcp_websocket() { + async fn tcp_websocket() { let _: libp2p_swarm::Swarm = SwarmBuilder::new() .with_new_identity() .with_tokio() .with_tcp() .with_tls() .with_noise() - .without_relay() - .without_any_other_transports() - .without_dns() + .unwrap() .with_websocket() .with_tls() .with_noise() + .await + .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .build(); } From 1a5418d91aa149a0dcbabbc95aed038feabfc7f0 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 18 Aug 2023 16:45:46 +0200 Subject: [PATCH 039/171] Make with_behaviour fallible --- examples/autonat/src/bin/autonat_client.rs | 2 +- examples/autonat/src/bin/autonat_server.rs | 2 +- examples/chat-example/src/main.rs | 14 ++-- examples/dcutr/src/main.rs | 4 +- .../distributed-key-value-store/src/main.rs | 8 +- examples/file-sharing/src/network.rs | 4 +- examples/identify/src/main.rs | 5 +- examples/ipfs-kad/src/main.rs | 3 +- examples/ipfs-private/src/main.rs | 9 +-- examples/metrics/src/main.rs | 2 +- examples/ping-example/src/main.rs | 3 +- examples/relay-server/src/main.rs | 4 +- examples/rendezvous/src/bin/rzv-discover.rs | 13 ++- examples/rendezvous/src/bin/rzv-identify.rs | 21 +++-- examples/rendezvous/src/bin/rzv-register.rs | 13 ++- examples/rendezvous/src/main.rs | 4 +- libp2p/src/builder.rs | 80 +++++++++++-------- 17 files changed, 109 insertions(+), 82 deletions(-) diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index 120c67fa395..9ac16f76fa8 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -55,7 +55,7 @@ async fn main() -> Result<(), Box> { .with_tcp() .without_tls() .with_noise()? - .with_behaviour(|key| Behaviour::new(key.public())) + .with_behaviour(|key| Ok(Behaviour::new(key.public())))? .build(); println!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index 1a1659152f3..0c6b561ffc5 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -47,7 +47,7 @@ async fn main() -> Result<(), Box> { .with_tcp() .without_tls() .with_noise()? - .with_behaviour(|key| Behaviour::new(key.public())) + .with_behaviour(|key| Ok(Behaviour::new(key.public())))? .build(); println!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index bbcb2865985..4f341b052c3 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -63,22 +63,18 @@ async fn main() -> Result<(), Box> { .heartbeat_interval(Duration::from_secs(10)) // This is set to aid debugging by not cluttering the log space .validation_mode(gossipsub::ValidationMode::Strict) // This sets the kind of message validation. The default is Strict (enforce message signing) .message_id_fn(message_id_fn) // content-address messages. No two messages of the same content will be propagated. - .build() - .expect("Valid config"); + .build()?; // build a gossipsub network behaviour let gossipsub = gossipsub::Behaviour::new( gossipsub::MessageAuthenticity::Signed(key.clone()), gossipsub_config, - ) - .expect("Correct configuration"); + )?; let mdns = - mdns::async_io::Behaviour::new(mdns::Config::default(), key.public().to_peer_id()) - // TODO: How could one handle the unwrap here? The closure does not allow returning an error. - .unwrap(); - MyBehaviour { gossipsub, mdns } - }) + mdns::async_io::Behaviour::new(mdns::Config::default(), key.public().to_peer_id())?; + Ok(MyBehaviour { gossipsub, mdns }) + })? .build(); // Create a Gossipsub topic diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 0ff8a060eb1..32cd54f993c 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -135,7 +135,7 @@ async fn main() -> Result<(), Box> { }) .with_dns() .await? - .with_behaviour(|keypair, relay_behaviour| Behaviour { + .with_behaviour(|keypair, relay_behaviour| Ok(Behaviour { relay_client: relay_behaviour, ping: ping::Behaviour::new(ping::Config::new()), identify: identify::Behaviour::new(identify::Config::new( @@ -143,7 +143,7 @@ async fn main() -> Result<(), Box> { keypair.public(), )), dcutr: dcutr::Behaviour::new(keypair.public().to_peer_id()), - }) + }))? .build(); info!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/distributed-key-value-store/src/main.rs b/examples/distributed-key-value-store/src/main.rs index d6cd4430296..644d04ce412 100644 --- a/examples/distributed-key-value-store/src/main.rs +++ b/examples/distributed-key-value-store/src/main.rs @@ -50,7 +50,7 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| MyBehaviour { + .with_behaviour(|key| Ok(MyBehaviour { kademlia: Kademlia::new( key.public().to_peer_id(), MemoryStore::new(key.public().to_peer_id()), @@ -58,10 +58,8 @@ async fn main() -> Result<(), Box> { mdns: mdns::async_io::Behaviour::new( mdns::Config::default(), key.public().to_peer_id(), - ) - // TODO: How to handle this error. The closure doesn't allow returning an error. - .unwrap(), - }) + )? + }))? .build(); swarm.behaviour_mut().kademlia.set_mode(Some(Mode::Server)); diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 92b55081e1c..07fb778df85 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -48,7 +48,7 @@ pub(crate) async fn new( .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| ComposedBehaviour { + .with_behaviour(|key| Ok(ComposedBehaviour { kademlia: Kademlia::new(peer_id, MemoryStore::new(key.public().to_peer_id())), request_response: request_response::cbor::Behaviour::new( [( @@ -57,7 +57,7 @@ pub(crate) async fn new( )], request_response::Config::default(), ), - }) + }))? .build(); swarm diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index f63a634341d..49fb0f54928 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -34,11 +34,12 @@ async fn main() -> Result<(), Box> { .with_tcp() .with_noise()? .with_behaviour(|key| { - identify::Behaviour::new(identify::Config::new( + Ok(identify::Behaviour::new(identify::Config::new( "/ipfs/id/1.0.0".to_string(), key.public(), - )) + ))) }) + .unwrap() .build(); println!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index cdd2c6667a5..b288141f430 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -49,8 +49,9 @@ async fn main() -> Result<(), Box> { let mut cfg = KademliaConfig::default(); cfg.set_query_timeout(Duration::from_secs(5 * 60)); let store = MemoryStore::new(key.public().to_peer_id()); - Kademlia::with_config(key.public().to_peer_id(), store, cfg) + Ok(Kademlia::with_config(key.public().to_peer_id(), store, cfg)) }) + .unwrap() .build(); // Add the bootnodes to the local routing table. `libp2p-dns` built diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index a98ce825ccb..5a0d582db61 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -139,9 +139,8 @@ async fn main() -> Result<(), Box> { .with_behaviour(|key| { let gossipsub_config = gossipsub::ConfigBuilder::default() .max_transmit_size(262144) - .build() - .expect("valid config"); - MyBehaviour { + .build()?; + Ok(MyBehaviour { gossipsub: gossipsub::Behaviour::new( gossipsub::MessageAuthenticity::Signed(key.clone()), gossipsub_config, @@ -152,8 +151,8 @@ async fn main() -> Result<(), Box> { key.public(), )), ping: ping::Behaviour::new(ping::Config::new()), - } - }) + }) + })? .build(); println!("using random peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index 68deffef6d0..6f1ce3d01a4 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -41,7 +41,7 @@ fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| Behaviour::new(key.public())) + .with_behaviour(|key| Ok(Behaviour::new(key.public())))? .build(); info!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index 292523c9c56..d0e7676b17d 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -35,7 +35,8 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|_| Behaviour::default()) + .with_behaviour(|_| Ok(Behaviour::default())) + .unwrap() .build(); println!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index 46db3fa49b7..5864f94fa25 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -56,14 +56,14 @@ fn main() -> Result<(), Box> { quic::async_std::Transport::new(quic::Config::new(&keypair)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .with_behaviour(|key| Behaviour { + .with_behaviour(|key| Ok(Behaviour { relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), ping: ping::Behaviour::new(ping::Config::new()), identify: identify::Behaviour::new(identify::Config::new( "/TODO/0.0.1".to_string(), key.public(), )), - }) + }))? .build(); // Listen on all interfaces diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index c1988d0bcc9..80486da8ece 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -44,11 +44,16 @@ async fn main() -> Result<(), Box> { .with_tokio() .with_tcp() .with_noise()? - .with_behaviour(|key| MyBehaviour { - rendezvous: rendezvous::client::Behaviour::new(key.clone()), - ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), - keep_alive: keep_alive::Behaviour, + .with_behaviour(|key| { + Ok(MyBehaviour { + rendezvous: rendezvous::client::Behaviour::new(key.clone()), + ping: ping::Behaviour::new( + ping::Config::new().with_interval(Duration::from_secs(1)), + ), + keep_alive: keep_alive::Behaviour, + }) }) + .unwrap() .build(); log::info!("Local peer id: {}", swarm.local_peer_id()); diff --git a/examples/rendezvous/src/bin/rzv-identify.rs b/examples/rendezvous/src/bin/rzv-identify.rs index a912adbef5b..bbbbd4a4755 100644 --- a/examples/rendezvous/src/bin/rzv-identify.rs +++ b/examples/rendezvous/src/bin/rzv-identify.rs @@ -41,15 +41,20 @@ async fn main() { .with_tcp() .with_noise() .unwrap() - .with_behaviour(|key| MyBehaviour { - identify: identify::Behaviour::new(identify::Config::new( - "rendezvous-example/1.0.0".to_string(), - key.public(), - )), - rendezvous: rendezvous::client::Behaviour::new(key.clone()), - ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), - keep_alive: keep_alive::Behaviour, + .with_behaviour(|key| { + Ok(MyBehaviour { + identify: identify::Behaviour::new(identify::Config::new( + "rendezvous-example/1.0.0".to_string(), + key.public(), + )), + rendezvous: rendezvous::client::Behaviour::new(key.clone()), + ping: ping::Behaviour::new( + ping::Config::new().with_interval(Duration::from_secs(1)), + ), + keep_alive: keep_alive::Behaviour, + }) }) + .unwrap() .build(); log::info!("Local peer id: {}", swarm.local_peer_id()); diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index 442597ebb55..f30ec304d40 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -41,11 +41,16 @@ async fn main() { .with_tcp() .with_noise() .unwrap() - .with_behaviour(|key| MyBehaviour { - rendezvous: rendezvous::client::Behaviour::new(key.clone()), - ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), - keep_alive: keep_alive::Behaviour, + .with_behaviour(|key| { + Ok(MyBehaviour { + rendezvous: rendezvous::client::Behaviour::new(key.clone()), + ping: ping::Behaviour::new( + ping::Config::new().with_interval(Duration::from_secs(1)), + ), + keep_alive: keep_alive::Behaviour, + }) }) + .unwrap() .build(); // In production the external address should be the publicly facing IP address of the rendezvous point. diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 0d1a56fb0b3..959c6de4e3f 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -37,7 +37,7 @@ async fn main() -> Result<(), Box> { .with_tokio() .with_tcp() .with_noise()? - .with_behaviour(|key| MyBehaviour { + .with_behaviour(|key| Ok(MyBehaviour { identify: identify::Behaviour::new(identify::Config::new( "rendezvous-example/1.0.0".to_string(), key.public(), @@ -45,7 +45,7 @@ async fn main() -> Result<(), Box> { rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), keep_alive: keep_alive::Behaviour, - }) + }))? .build(); log::info!("Local peer id: {}", swarm.local_peer_id()); diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 319d114cbd9..332f09686ab 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -2,6 +2,8 @@ // TODO: Should we have a timeout on transport? // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider moving with_relay after with_other_transport. +// TODO: Consider making with_other_transport fallible. +// TODO: Add with_quic use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; @@ -276,8 +278,8 @@ impl RelayBuilder { pub fn with_behaviour( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> B, - ) -> Builder { + constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result, Box> { self.without_relay() .without_any_other_transports() .without_dns() @@ -529,8 +531,11 @@ impl { pub fn with_behaviour( self, - constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, - ) -> Builder { + constructor: impl FnMut( + &libp2p_identity::Keypair, + libp2p_relay::client::Behaviour, + ) -> Result>, + ) -> Result, Box> { self.without_any_other_transports() .without_dns() .without_websocket() @@ -540,8 +545,8 @@ impl impl OtherTransportBuilder { pub fn with_behaviour( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> B, - ) -> Builder { + constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result, Box> { self.without_any_other_transports() .without_dns() .without_websocket() @@ -603,8 +608,11 @@ impl DnsBuilder { impl DnsBuilder { pub fn with_behaviour( self, - constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, - ) -> Builder { + constructor: impl FnMut( + &libp2p_identity::Keypair, + libp2p_relay::client::Behaviour, + ) -> Result>, + ) -> Result, Box> { self.without_dns() .without_websocket() .with_behaviour(constructor) @@ -613,8 +621,8 @@ impl DnsBuilder DnsBuilder { pub fn with_behaviour( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> B, - ) -> Builder { + constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result, Box> { self.without_dns() .without_websocket() .with_behaviour(constructor) @@ -659,16 +667,19 @@ impl { pub fn with_behaviour( self, - constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, - ) -> Builder { + constructor: impl FnMut( + &libp2p_identity::Keypair, + libp2p_relay::client::Behaviour, + ) -> Result>, + ) -> Result, Box> { self.without_websocket().with_behaviour(constructor) } } impl WebsocketBuilder { pub fn with_behaviour( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> B, - ) -> Builder { + constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result, Box> { self.without_websocket().with_behaviour(constructor) } } @@ -825,31 +836,34 @@ pub struct BehaviourBuilder { impl

BehaviourBuilder { pub fn with_behaviour( self, - mut constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> B, - ) -> Builder { - Builder { - behaviour: constructor(&self.keypair, self.relay_behaviour), + mut constructor: impl FnMut( + &libp2p_identity::Keypair, + libp2p_relay::client::Behaviour, + ) -> Result>, + ) -> Result, Box> { + Ok(Builder { + behaviour: constructor(&self.keypair, self.relay_behaviour)?, keypair: self.keypair, transport: self.transport, phantom: PhantomData, - } + }) } } impl

BehaviourBuilder { pub fn with_behaviour( self, - mut constructor: impl FnMut(&libp2p_identity::Keypair) -> B, - ) -> Builder { + mut constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result, Box> { // Discard `NoRelayBehaviour`. let _ = self.relay_behaviour; - Builder { - behaviour: constructor(&self.keypair), + Ok(Builder { + behaviour: constructor(&self.keypair)?, keypair: self.keypair, transport: self.transport, phantom: PhantomData, - } + }) } } @@ -931,7 +945,7 @@ mod tests { .with_tls() .with_noise() .unwrap() - .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() .build(); } @@ -962,10 +976,12 @@ mod tests { .with_tls() .with_noise() .unwrap() - .with_behaviour(|_, relay| Behaviour { - dummy: libp2p_swarm::dummy::Behaviour, - relay, - }) + .with_behaviour(|_, relay| { + Ok(Behaviour { + dummy: libp2p_swarm::dummy::Behaviour, + relay, + }) + }).unwrap() .build(); } @@ -987,7 +1003,7 @@ mod tests { .unwrap() .with_dns() .unwrap() - .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() .build(); } @@ -1005,7 +1021,7 @@ mod tests { .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() .build(); } @@ -1031,7 +1047,7 @@ mod tests { .with_noise() .await .unwrap() - .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() .build(); } } From e244c53ccd4195366f4662b71a5677288761561d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 18 Aug 2023 17:02:32 +0200 Subject: [PATCH 040/171] Add with_quic --- libp2p/src/builder.rs | 172 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 157 insertions(+), 15 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 332f09686ab..8cbbfcbbea1 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -113,7 +113,7 @@ impl TcpTlsBuilder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> Result, AuthenticationError> + ) -> Result, AuthenticationError> { self.without_tls().with_noise() } @@ -123,7 +123,7 @@ impl TcpTlsBuilder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> Result, AuthenticationError> + ) -> Result, AuthenticationError> { self.without_tls().with_noise() } @@ -137,9 +137,9 @@ pub struct TcpNoiseBuilder { } #[cfg(feature = "tcp")] -macro_rules! construct_relay_builder { +macro_rules! construct_quic_builder { ($self:ident, $tcp:ident, $auth:expr) => { - Ok(RelayBuilder { + Ok(QuicBuilder { transport: libp2p_tcp::$tcp::Transport::new($self.config) .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate($auth) @@ -159,10 +159,10 @@ macro_rules! impl_tcp_noise_builder { pub fn with_noise( self, ) -> Result< - RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + QuicBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, AuthenticationError, > { - construct_relay_builder!( + construct_quic_builder!( self, $tcp, libp2p_core::upgrade::Map::new( @@ -185,10 +185,10 @@ macro_rules! impl_tcp_noise_builder { pub fn without_noise( self, ) -> Result< - RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + QuicBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, AuthenticationError, > { - construct_relay_builder!(self, $tcp, libp2p_tls::Config::new(&self.keypair)?) + construct_quic_builder!(self, $tcp, libp2p_tls::Config::new(&self.keypair)?) } } @@ -198,10 +198,10 @@ macro_rules! impl_tcp_noise_builder { pub fn with_noise( self, ) -> Result< - RelayBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + QuicBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, AuthenticationError, > { - construct_relay_builder!(self, $tcp, libp2p_noise::Config::new(&self.keypair)?) + construct_quic_builder!(self, $tcp, libp2p_noise::Config::new(&self.keypair)?) } } }; @@ -225,6 +225,127 @@ pub enum AuthenticationError { Noise(#[from] libp2p_noise::Error), } +pub struct QuicBuilder { + transport: T, + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, +} + +#[cfg(all(feature = "quic", feature = "async-std"))] +impl QuicBuilder { + pub fn with_quic(self) -> RelayBuilder { + RelayBuilder { + transport: self + .transport + .or( + quic::async_std::Transport::new(quic::Config::new(&self.keypair)) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), + ), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +#[cfg(all(feature = "quic", feature = "tokio"))] +impl QuicBuilder { + pub fn with_quic(self) -> RelayBuilder { + RelayBuilder { + transport: self + .transport + .or( + quic::tokio::Transport::new(quic::Config::new(&self.keypair)) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), + ), + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +impl QuicBuilder { + pub fn without_quic(self) -> RelayBuilder { + RelayBuilder { + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +// Shortcuts +impl QuicBuilder { + pub fn with_relay(self) -> RelayTlsBuilder { + RelayTlsBuilder { + transport: self.transport, + keypair: self.keypair, + phantom: PhantomData, + } + } + + pub fn with_other_transport( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, + ) -> OtherTransportBuilder { + self.without_quic() + .without_relay() + .with_other_transport(constructor) + } + + #[cfg(feature = "websocket")] + pub fn with_websocket( + self, + ) -> WebsocketTlsBuilder { + self.without_quic() + .without_relay() + .without_any_other_transports() + .without_dns() + .with_websocket() + } + + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result, Box> { + self.without_quic() + .without_relay() + .without_any_other_transports() + .without_dns() + .without_websocket() + .with_behaviour(constructor) + } +} +// Shortcuts +#[cfg(all(feature = "async-std", feature = "dns"))] +impl QuicBuilder { + pub async fn with_dns( + self, + ) -> Result< + WebsocketBuilder, + std::io::Error, + > { + self.without_quic() + .without_relay() + .without_any_other_transports() + .with_dns() + .await + } +} +#[cfg(all(feature = "tokio", feature = "dns"))] +impl QuicBuilder { + pub fn with_dns( + self, + ) -> Result< + WebsocketBuilder, + std::io::Error, + > { + self.without_quic() + .without_relay() + .without_any_other_transports() + .with_dns() + } +} + pub struct RelayBuilder { transport: T, keypair: libp2p_identity::Keypair, @@ -945,7 +1066,24 @@ mod tests { .with_tls() .with_noise() .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() + .build(); + } + + #[test] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise", feature = "quic"))] + fn tcp_quic() { + let _: libp2p_swarm::Swarm = SwarmBuilder::new() + .with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_quic() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() .build(); } @@ -981,7 +1119,8 @@ mod tests { dummy: libp2p_swarm::dummy::Behaviour, relay, }) - }).unwrap() + }) + .unwrap() .build(); } @@ -1003,7 +1142,8 @@ mod tests { .unwrap() .with_dns() .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() .build(); } @@ -1021,7 +1161,8 @@ mod tests { .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() .build(); } @@ -1047,7 +1188,8 @@ mod tests { .with_noise() .await .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)).unwrap() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() .build(); } } From 14606dd6b1c9809851f8c8896d0dc4c00f9b552f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Fri, 18 Aug 2023 17:37:15 +0200 Subject: [PATCH 041/171] Use with_quic --- examples/chat-example/src/main.rs | 10 ++-------- libp2p/src/builder.rs | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 1b75dbad94a..30840c5b0e6 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -22,10 +22,7 @@ use async_std::io; use futures::{prelude::*, select}; -use libp2p::{ - core::muxing::StreamMuxerBox, gossipsub, mdns, swarm::NetworkBehaviour, swarm::SwarmEvent, - Transport, -}; +use libp2p::{gossipsub, mdns, swarm::NetworkBehaviour, swarm::SwarmEvent}; use std::collections::hash_map::DefaultHasher; use std::error::Error; use std::hash::{Hash, Hasher}; @@ -45,10 +42,7 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_other_transport(|key| { - quic::async_std::Transport::new(quic::Config::new(&key)) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) - }) + .with_quic() .with_behaviour(|key| { // To content-address message, we can take the hash of message and use it as an ID. let message_id_fn = |message: &gossipsub::Message| { diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index b33c9647bfc..14d0d4aab4d 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -3,7 +3,6 @@ // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider moving with_relay after with_other_transport. // TODO: Consider making with_other_transport fallible. -// TODO: Add with_quic use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; @@ -277,6 +276,7 @@ impl QuicBuilder { // Shortcuts impl QuicBuilder { + #[cfg(feature = "relay")] pub fn with_relay(self) -> RelayTlsBuilder { RelayTlsBuilder { transport: self.transport, From d3ffdd4d2fd9c7ade80de7fc9b4cf1ccc8518a25 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 20 Aug 2023 15:20:22 +0200 Subject: [PATCH 042/171] Introduce phases --- examples/autonat/src/bin/autonat_client.rs | 3 +- examples/autonat/src/bin/autonat_server.rs | 3 +- examples/chat-example/src/main.rs | 3 +- examples/dcutr/src/main.rs | 48 +- .../distributed-key-value-store/src/main.rs | 25 +- examples/file-sharing/src/network.rs | 25 +- examples/identify/src/main.rs | 3 +- examples/ipfs-kad/src/main.rs | 3 +- examples/ipfs-private/src/main.rs | 3 +- examples/metrics/src/main.rs | 3 +- examples/ping-example/src/main.rs | 3 +- examples/relay-server/src/main.rs | 21 +- examples/rendezvous/src/bin/rzv-discover.rs | 3 +- examples/rendezvous/src/bin/rzv-identify.rs | 3 +- examples/rendezvous/src/bin/rzv-register.rs | 3 +- examples/rendezvous/src/main.rs | 27 +- libp2p/src/builder.rs | 784 ++++++++++-------- 17 files changed, 530 insertions(+), 433 deletions(-) diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index 9ac16f76fa8..67aacad9064 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -49,8 +49,7 @@ async fn main() -> Result<(), Box> { let opt = Opt::parse(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .without_tls() diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index 0c6b561ffc5..7bc61984bdb 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -41,8 +41,7 @@ async fn main() -> Result<(), Box> { let opt = Opt::parse(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .without_tls() diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 30840c5b0e6..27b208bfdb1 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -37,8 +37,7 @@ struct MyBehaviour { #[async_std::main] async fn main() -> Result<(), Box> { - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .with_noise()? diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index ac2afea99db..ebddc54fd12 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -121,29 +121,31 @@ async fn main() -> Result<(), Box> { } } - let mut swarm = libp2p::SwarmBuilder::new() - .with_existing_identity(generate_ed25519(opts.secret_key_seed)) - .with_async_std() - .with_tcp_config(tcp::Config::default().port_reuse(true).nodelay(true)) - .with_noise()? - .with_relay() - .with_noise()? - .with_other_transport(|keypair| { - quic::async_std::Transport::new(quic::Config::new(&keypair)) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) - }) - .with_dns() - .await? - .with_behaviour(|keypair, relay_behaviour| Ok(Behaviour { - relay_client: relay_behaviour, - ping: ping::Behaviour::new(ping::Config::new()), - identify: identify::Behaviour::new(identify::Config::new( - "/TODO/0.0.1".to_string(), - keypair.public(), - )), - dcutr: dcutr::Behaviour::new(keypair.public().to_peer_id()), - }))? - .build(); + let mut swarm = + libp2p::SwarmBuilder::with_existing_identity(generate_ed25519(opts.secret_key_seed)) + .with_async_std() + .with_tcp_config(tcp::Config::default().port_reuse(true).nodelay(true)) + .with_noise()? + .with_relay() + .with_noise()? + .with_other_transport(|keypair| { + quic::async_std::Transport::new(quic::Config::new(&keypair)) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) + }) + .with_dns() + .await? + .with_behaviour(|keypair, relay_behaviour| { + Ok(Behaviour { + relay_client: relay_behaviour, + ping: ping::Behaviour::new(ping::Config::new()), + identify: identify::Behaviour::new(identify::Config::new( + "/TODO/0.0.1".to_string(), + keypair.public(), + )), + dcutr: dcutr::Behaviour::new(keypair.public().to_peer_id()), + }) + })? + .build(); info!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/distributed-key-value-store/src/main.rs b/examples/distributed-key-value-store/src/main.rs index 644d04ce412..6200c857129 100644 --- a/examples/distributed-key-value-store/src/main.rs +++ b/examples/distributed-key-value-store/src/main.rs @@ -45,21 +45,22 @@ async fn main() -> Result<(), Box> { mdns: mdns::async_io::Behaviour, } - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| Ok(MyBehaviour { - kademlia: Kademlia::new( - key.public().to_peer_id(), - MemoryStore::new(key.public().to_peer_id()), - ), - mdns: mdns::async_io::Behaviour::new( - mdns::Config::default(), - key.public().to_peer_id(), - )? - }))? + .with_behaviour(|key| { + Ok(MyBehaviour { + kademlia: Kademlia::new( + key.public().to_peer_id(), + MemoryStore::new(key.public().to_peer_id()), + ), + mdns: mdns::async_io::Behaviour::new( + mdns::Config::default(), + key.public().to_peer_id(), + )?, + }) + })? .build(); swarm.behaviour_mut().kademlia.set_mode(Some(Mode::Server)); diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 07fb778df85..92db1ff9488 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -43,21 +43,22 @@ pub(crate) async fn new( }; let peer_id = id_keys.public().to_peer_id(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_existing_identity(id_keys) + let mut swarm = libp2p::SwarmBuilder::with_existing_identity(id_keys) .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| Ok(ComposedBehaviour { - kademlia: Kademlia::new(peer_id, MemoryStore::new(key.public().to_peer_id())), - request_response: request_response::cbor::Behaviour::new( - [( - StreamProtocol::new("/file-exchange/1"), - ProtocolSupport::Full, - )], - request_response::Config::default(), - ), - }))? + .with_behaviour(|key| { + Ok(ComposedBehaviour { + kademlia: Kademlia::new(peer_id, MemoryStore::new(key.public().to_peer_id())), + request_response: request_response::cbor::Behaviour::new( + [( + StreamProtocol::new("/file-exchange/1"), + ProtocolSupport::Full, + )], + request_response::Config::default(), + ), + }) + })? .build(); swarm diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index 49fb0f54928..e87eeb46a31 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -28,8 +28,7 @@ use std::error::Error; async fn main() -> Result<(), Box> { env_logger::init(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .with_noise()? diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index b288141f430..b6bfc45a05d 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -37,8 +37,7 @@ const BOOTNODES: [&str; 4] = [ async fn main() -> Result<(), Box> { env_logger::init(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .with_noise()? diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 5a0d582db61..05689f69b22 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -110,8 +110,7 @@ async fn main() -> Result<(), Box> { ping: ping::Behaviour, } - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .without_tcp() .without_relay() diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index 6f1ce3d01a4..46a38f8da1d 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -36,8 +36,7 @@ mod http_service; fn main() -> Result<(), Box> { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .with_noise()? diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index d0e7676b17d..853d5e6b673 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -30,8 +30,7 @@ use std::error::Error; #[async_std::main] async fn main() -> Result<(), Box> { - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() .with_noise()? diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index e92d5709c3f..d437f6107c4 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -46,8 +46,7 @@ fn main() -> Result<(), Box> { let local_peer_id = PeerId::from(local_key.public()); println!("Local peer id: {local_peer_id:?}"); - let mut swarm = libp2p::SwarmBuilder::new() - .with_existing_identity(local_key) + let mut swarm = libp2p::SwarmBuilder::with_existing_identity(local_key) .with_async_std() .with_tcp() .with_noise()? @@ -55,14 +54,16 @@ fn main() -> Result<(), Box> { quic::async_std::Transport::new(quic::Config::new(&keypair)) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) }) - .with_behaviour(|key| Ok(Behaviour { - relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), - ping: ping::Behaviour::new(ping::Config::new()), - identify: identify::Behaviour::new(identify::Config::new( - "/TODO/0.0.1".to_string(), - key.public(), - )), - }))? + .with_behaviour(|key| { + Ok(Behaviour { + relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), + ping: ping::Behaviour::new(ping::Config::new()), + identify: identify::Behaviour::new(identify::Config::new( + "/TODO/0.0.1".to_string(), + key.public(), + )), + }) + })? .build(); // Listen on all interfaces diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index 80486da8ece..a2619b22c19 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -39,8 +39,7 @@ async fn main() -> Result<(), Box> { .parse() .unwrap(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() .with_noise()? diff --git a/examples/rendezvous/src/bin/rzv-identify.rs b/examples/rendezvous/src/bin/rzv-identify.rs index bbbbd4a4755..e4b841865bd 100644 --- a/examples/rendezvous/src/bin/rzv-identify.rs +++ b/examples/rendezvous/src/bin/rzv-identify.rs @@ -35,8 +35,7 @@ async fn main() { .parse() .unwrap(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() .with_noise() diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index f30ec304d40..b8bb8c68982 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -35,8 +35,7 @@ async fn main() { .parse() .unwrap(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() .with_noise() diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 959c6de4e3f..1562353b854 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -32,20 +32,25 @@ use std::time::Duration; async fn main() -> Result<(), Box> { env_logger::init(); - let mut swarm = libp2p::SwarmBuilder::new() - .with_new_identity() + let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() .with_noise()? - .with_behaviour(|key| Ok(MyBehaviour { - identify: identify::Behaviour::new(identify::Config::new( - "rendezvous-example/1.0.0".to_string(), - key.public(), - )), - rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()), - ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), - keep_alive: keep_alive::Behaviour, - }))? + .with_behaviour(|key| { + Ok(MyBehaviour { + identify: identify::Behaviour::new(identify::Config::new( + "rendezvous-example/1.0.0".to_string(), + key.public(), + )), + rendezvous: rendezvous::server::Behaviour::new( + rendezvous::server::Config::default(), + ), + ping: ping::Behaviour::new( + ping::Config::new().with_interval(Duration::from_secs(1)), + ), + keep_alive: keep_alive::Behaviour, + }) + })? .build(); log::info!("Local peer id: {}", swarm.local_peer_id()); diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 14d0d4aab4d..efe5499ac5b 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -7,143 +7,161 @@ use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; -pub struct SwarmBuilder {} +pub struct SwarmBuilder { + keypair: libp2p_identity::Keypair, + phantom: PhantomData

, + phase: Phase, +} -impl SwarmBuilder { - pub fn new() -> SwarmBuilder { - Self {} - } +pub struct InitialPhase {} - pub fn with_new_identity(self) -> ProviderBuilder { - self.with_existing_identity(libp2p_identity::Keypair::generate_ed25519()) +impl SwarmBuilder { + pub fn with_new_identity() -> SwarmBuilder { + SwarmBuilder::with_existing_identity(libp2p_identity::Keypair::generate_ed25519()) } - pub fn with_existing_identity(self, keypair: libp2p_identity::Keypair) -> ProviderBuilder { - ProviderBuilder { keypair } + pub fn with_existing_identity( + keypair: libp2p_identity::Keypair, + ) -> SwarmBuilder { + SwarmBuilder { + keypair, + phantom: PhantomData, + phase: ProviderPhase {}, + } } } -pub struct ProviderBuilder { - keypair: libp2p_identity::Keypair, -} +pub struct ProviderPhase {} -impl ProviderBuilder { +impl SwarmBuilder { #[cfg(feature = "async-std")] - pub fn with_async_std(self) -> TcpBuilder { - TcpBuilder { + pub fn with_async_std(self) -> SwarmBuilder { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: TcpPhase {}, } } #[cfg(feature = "tokio")] - pub fn with_tokio(self) -> TcpBuilder { - TcpBuilder { + pub fn with_tokio(self) -> SwarmBuilder { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: TcpPhase {}, } } } -pub struct TcpBuilder

{ - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, -} +pub struct TcpPhase {} #[cfg(feature = "tcp")] -impl

TcpBuilder

{ - pub fn with_tcp(self) -> TcpTlsBuilder

{ +impl

SwarmBuilder { + pub fn with_tcp(self) -> SwarmBuilder { self.with_tcp_config(Default::default()) } - pub fn with_tcp_config(self, config: libp2p_tcp::Config) -> TcpTlsBuilder

{ - TcpTlsBuilder { - config, + pub fn with_tcp_config(self, config: libp2p_tcp::Config) -> SwarmBuilder { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: TcpTlsPhase { config }, } } } -impl

TcpBuilder

{ +impl

SwarmBuilder { // TODO: This would allow one to build a faulty transport. - pub fn without_tcp(self) -> RelayBuilder { - RelayBuilder { + pub fn without_tcp( + self, + ) -> SwarmBuilder> { + SwarmBuilder { // TODO: Is this a good idea in a production environment? Unfortunately I don't know a // way around it. One can not define two `with_relay` methods, one with a real transport // using OrTransport, one with a fake transport discarding it right away. - transport: libp2p_core::transport::dummy::DummyTransport::new(), keypair: self.keypair, phantom: PhantomData, + phase: RelayPhase { + transport: libp2p_core::transport::dummy::DummyTransport::new(), + }, } } } #[cfg(feature = "tcp")] -pub struct TcpTlsBuilder

{ +pub struct TcpTlsPhase { config: libp2p_tcp::Config, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } #[cfg(feature = "tcp")] -impl

TcpTlsBuilder

{ +impl

SwarmBuilder { #[cfg(feature = "tls")] - pub fn with_tls(self) -> TcpNoiseBuilder { - TcpNoiseBuilder { - config: self.config, + pub fn with_tls(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: TcpNoisePhase { + config: self.phase.config, + phantom: PhantomData, + }, } } - pub fn without_tls(self) -> TcpNoiseBuilder { - TcpNoiseBuilder { - config: self.config, + pub fn without_tls(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: TcpNoisePhase { + config: self.phase.config, + phantom: PhantomData, + }, } } } // Shortcuts #[cfg(all(feature = "tcp", feature = "noise", feature = "async-std"))] -impl TcpTlsBuilder { +impl SwarmBuilder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> Result, AuthenticationError> - { + ) -> Result< + SwarmBuilder>, + AuthenticationError, + > { self.without_tls().with_noise() } } #[cfg(all(feature = "tcp", feature = "noise", feature = "tokio"))] -impl TcpTlsBuilder { +impl SwarmBuilder { #[cfg(feature = "noise")] pub fn with_noise( self, - ) -> Result, AuthenticationError> - { + ) -> Result< + SwarmBuilder>, + AuthenticationError, + > { self.without_tls().with_noise() } } #[cfg(feature = "tcp")] -pub struct TcpNoiseBuilder { +pub struct TcpNoisePhase { config: libp2p_tcp::Config, - keypair: libp2p_identity::Keypair, - phantom: PhantomData<(P, A)>, + phantom: PhantomData, } #[cfg(feature = "tcp")] macro_rules! construct_quic_builder { ($self:ident, $tcp:ident, $auth:expr) => { - Ok(QuicBuilder { - transport: libp2p_tcp::$tcp::Transport::new($self.config) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate($auth) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + Ok(SwarmBuilder { + phase: QuicPhase { + transport: libp2p_tcp::$tcp::Transport::new($self.phase.config) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate($auth) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + }, keypair: $self.keypair, phantom: PhantomData, }) @@ -153,12 +171,12 @@ macro_rules! construct_quic_builder { macro_rules! impl_tcp_noise_builder { ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:ident) => { #[cfg(all(feature = $runtimeKebabCase, feature = "tcp", feature = "tls"))] - impl TcpNoiseBuilder<$runtimeCamelCase, Tls> { + impl SwarmBuilder<$runtimeCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - QuicBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + SwarmBuilder<$runtimeCamelCase, QuicPhase>, AuthenticationError, > { construct_quic_builder!( @@ -184,7 +202,7 @@ macro_rules! impl_tcp_noise_builder { pub fn without_noise( self, ) -> Result< - QuicBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + SwarmBuilder<$runtimeCamelCase, QuicPhase>, AuthenticationError, > { construct_quic_builder!(self, $tcp, libp2p_tls::Config::new(&self.keypair)?) @@ -192,12 +210,12 @@ macro_rules! impl_tcp_noise_builder { } #[cfg(feature = $runtimeKebabCase)] - impl TcpNoiseBuilder<$runtimeCamelCase, WithoutTls> { + impl SwarmBuilder<$runtimeCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - QuicBuilder<$runtimeCamelCase, impl AuthenticatedMultiplexedTransport>, + SwarmBuilder<$runtimeCamelCase, QuicPhase>, AuthenticationError, > { construct_quic_builder!(self, $tcp, libp2p_noise::Config::new(&self.keypair)?) @@ -224,23 +242,28 @@ pub enum AuthenticationError { Noise(#[from] libp2p_noise::Error), } -pub struct QuicBuilder { +pub struct QuicPhase { transport: T, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } #[cfg(all(feature = "quic", feature = "async-std"))] -impl QuicBuilder { - pub fn with_quic(self) -> RelayBuilder { - RelayBuilder { - transport: self - .transport - .or_transport( - libp2p_quic::async_std::Transport::new(libp2p_quic::Config::new(&self.keypair)) +impl SwarmBuilder> { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + SwarmBuilder { + phase: RelayPhase { + transport: self + .phase + .transport + .or_transport( + libp2p_quic::async_std::Transport::new(libp2p_quic::Config::new( + &self.keypair, + )) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), - ) - .map(|either, _| either.into_inner()), + ) + .map(|either, _| either.into_inner()), + }, keypair: self.keypair, phantom: PhantomData, } @@ -248,47 +271,59 @@ impl QuicBuilder { } #[cfg(all(feature = "quic", feature = "tokio"))] -impl QuicBuilder { - pub fn with_quic(self) -> RelayBuilder { - RelayBuilder { - transport: self - .transport - .or_transport( - libp2p_quic::tokio::Transport::new(libp2p_quic::Config::new(&self.keypair)) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), - ) - .map(|either, _| either.into_inner()), +impl SwarmBuilder> { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + SwarmBuilder { + phase: RelayPhase { + transport: self + .phase + .transport + .or_transport( + libp2p_quic::tokio::Transport::new(libp2p_quic::Config::new(&self.keypair)) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), + ) + .map(|either, _| either.into_inner()), + }, keypair: self.keypair, phantom: PhantomData, } } } -impl QuicBuilder { - pub fn without_quic(self) -> RelayBuilder { - RelayBuilder { - transport: self.transport, +impl SwarmBuilder> { + pub fn without_quic(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: RelayPhase { + transport: self.phase.transport, + }, } } } // Shortcuts -impl QuicBuilder { +impl SwarmBuilder> { #[cfg(feature = "relay")] - pub fn with_relay(self) -> RelayTlsBuilder { - RelayTlsBuilder { - transport: self.transport, + pub fn with_relay(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: RelayTlsPhase { + transport: self.phase.transport, + }, } } pub fn with_other_transport( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> OtherTransportBuilder { + ) -> SwarmBuilder< + P, + OtherTransportPhase, + > { self.without_quic() .without_relay() .with_other_transport(constructor) @@ -297,7 +332,8 @@ impl QuicBuilder { #[cfg(feature = "websocket")] pub fn with_websocket( self, - ) -> WebsocketTlsBuilder { + ) -> SwarmBuilder> + { self.without_quic() .without_relay() .without_any_other_transports() @@ -308,7 +344,7 @@ impl QuicBuilder { pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_quic() .without_relay() .without_any_other_transports() @@ -319,11 +355,14 @@ impl QuicBuilder { } // Shortcuts #[cfg(all(feature = "async-std", feature = "dns"))] -impl QuicBuilder { +impl SwarmBuilder> { pub async fn with_dns( self, ) -> Result< - WebsocketBuilder, + SwarmBuilder< + AsyncStd, + WebsocketPhase, + >, std::io::Error, > { self.without_quic() @@ -334,11 +373,14 @@ impl QuicBuilder { } } #[cfg(all(feature = "tokio", feature = "dns"))] -impl QuicBuilder { +impl SwarmBuilder> { pub fn with_dns( self, ) -> Result< - WebsocketBuilder, + SwarmBuilder< + Tokio, + WebsocketPhase, + >, std::io::Error, > { self.without_quic() @@ -348,51 +390,57 @@ impl QuicBuilder { } } -pub struct RelayBuilder { +pub struct RelayPhase { transport: T, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } -// TODO: Noise feature +// TODO: Noise feature or tls feature #[cfg(feature = "relay")] -impl RelayBuilder { +impl SwarmBuilder> { // TODO: This should be with_relay_client. - pub fn with_relay(self) -> RelayTlsBuilder { - RelayTlsBuilder { - transport: self.transport, + pub fn with_relay(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: RelayTlsPhase { + transport: self.phase.transport, + }, } } } pub struct NoRelayBehaviour; -impl RelayBuilder { - pub fn without_relay(self) -> OtherTransportBuilder { - OtherTransportBuilder { - transport: self.transport, - relay_behaviour: NoRelayBehaviour, +impl SwarmBuilder> { + pub fn without_relay(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: OtherTransportPhase { + transport: self.phase.transport, + relay_behaviour: NoRelayBehaviour, + }, } } } // Shortcuts -impl RelayBuilder { +impl SwarmBuilder> { pub fn with_other_transport( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> OtherTransportBuilder { + ) -> SwarmBuilder< + P, + OtherTransportPhase, + > { self.without_relay().with_other_transport(constructor) } #[cfg(feature = "websocket")] pub fn with_websocket( self, - ) -> WebsocketTlsBuilder { + ) -> SwarmBuilder> + { self.without_relay() .without_any_other_transports() .without_dns() @@ -402,7 +450,7 @@ impl RelayBuilder { pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_relay() .without_any_other_transports() .without_dns() @@ -410,13 +458,15 @@ impl RelayBuilder { .with_behaviour(constructor) } } -// Shortcuts #[cfg(all(feature = "async-std", feature = "dns"))] -impl RelayBuilder { +impl SwarmBuilder> { pub async fn with_dns( self, ) -> Result< - WebsocketBuilder, + SwarmBuilder< + AsyncStd, + WebsocketPhase, + >, std::io::Error, > { self.without_relay() @@ -426,11 +476,14 @@ impl RelayBuilder { } } #[cfg(all(feature = "tokio", feature = "dns"))] -impl RelayBuilder { +impl SwarmBuilder> { pub fn with_dns( self, ) -> Result< - WebsocketBuilder, + SwarmBuilder< + Tokio, + WebsocketPhase, + >, std::io::Error, > { self.without_relay() @@ -440,43 +493,50 @@ impl RelayBuilder { } #[cfg(feature = "relay")] -pub struct RelayTlsBuilder { +pub struct RelayTlsPhase { transport: T, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } #[cfg(feature = "relay")] -impl RelayTlsBuilder { +impl SwarmBuilder> { #[cfg(feature = "tls")] - pub fn with_tls(self) -> RelayNoiseBuilder { - RelayNoiseBuilder { - transport: self.transport, + pub fn with_tls(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: RelayNoisePhase { + transport: self.phase.transport, + phantom: PhantomData, + }, } } - pub fn without_tls(self) -> RelayNoiseBuilder { - RelayNoiseBuilder { - transport: self.transport, + pub fn without_tls(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: RelayNoisePhase { + transport: self.phase.transport, + + phantom: PhantomData, + }, } } } // Shortcuts #[cfg(all(feature = "relay", feature = "noise", feature = "async-std"))] -impl RelayTlsBuilder { +impl SwarmBuilder> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - OtherTransportBuilder< + SwarmBuilder< AsyncStd, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + OtherTransportPhase< + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, >, AuthenticationError, > { @@ -484,15 +544,17 @@ impl RelayTlsBuilder { } } #[cfg(all(feature = "relay", feature = "noise", feature = "tokio"))] -impl RelayTlsBuilder { +impl SwarmBuilder> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - OtherTransportBuilder< + SwarmBuilder< Tokio, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + OtherTransportPhase< + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, >, AuthenticationError, > { @@ -501,10 +563,9 @@ impl RelayTlsBuilder { } #[cfg(feature = "relay")] -pub struct RelayNoiseBuilder { +pub struct RelayNoisePhase { transport: T, - keypair: libp2p_identity::Keypair, - phantom: PhantomData<(P, A)>, + phantom: PhantomData, } #[cfg(feature = "relay")] @@ -513,34 +574,39 @@ macro_rules! construct_other_transport_builder { let (relay_transport, relay_behaviour) = libp2p_relay::client::new($self.keypair.public().to_peer_id()); - Ok(OtherTransportBuilder { - transport: $self - .transport - .or_transport( - relay_transport - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate($auth) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - ) - .map(|either, _| either.into_inner()), + Ok(SwarmBuilder { + phase: OtherTransportPhase { + relay_behaviour, + transport: $self + .phase + .transport + .or_transport( + relay_transport + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate($auth) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + ) + .map(|either, _| either.into_inner()), + }, keypair: $self.keypair, - relay_behaviour, phantom: PhantomData, }) }}; } #[cfg(all(feature = "relay", feature = "tls"))] -impl RelayNoiseBuilder { +impl SwarmBuilder> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - OtherTransportBuilder< + SwarmBuilder< P, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + OtherTransportPhase< + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, >, AuthenticationError, > { @@ -565,10 +631,12 @@ impl RelayNoiseBuilder { pub fn without_noise( self, ) -> Result< - OtherTransportBuilder< + SwarmBuilder< P, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + OtherTransportPhase< + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, >, AuthenticationError, > { @@ -577,15 +645,17 @@ impl RelayNoiseBuilder { } #[cfg(feature = "relay")] -impl RelayNoiseBuilder { +impl SwarmBuilder> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - OtherTransportBuilder< + SwarmBuilder< P, - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, + OtherTransportPhase< + impl AuthenticatedMultiplexedTransport, + libp2p_relay::client::Behaviour, + >, >, AuthenticationError, > { @@ -593,24 +663,25 @@ impl RelayNoiseBuilder { +pub struct OtherTransportPhase { transport: T, relay_behaviour: R, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } -impl OtherTransportBuilder { +impl SwarmBuilder> { pub fn with_other_transport( self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> OtherTransportBuilder { - OtherTransportBuilder { - transport: self - .transport - .or_transport(constructor(&self.keypair)) - .map(|either, _| either.into_inner()), - relay_behaviour: self.relay_behaviour, + ) -> SwarmBuilder> { + SwarmBuilder { + phase: OtherTransportPhase { + transport: self + .phase + .transport + .or_transport(constructor(&self.keypair)) + .map(|either, _| either.into_inner()), + relay_behaviour: self.phase.relay_behaviour, + }, keypair: self.keypair, phantom: PhantomData, } @@ -619,38 +690,44 @@ impl OtherTransportBuilder // TODO: Not the ideal name. pub fn without_any_other_transports( self, - ) -> DnsBuilder { - DnsBuilder { - transport: self.transport, - relay_behaviour: self.relay_behaviour, + ) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: DnsPhase { + transport: self.phase.transport, + relay_behaviour: self.phase.relay_behaviour, + }, } } } // Shortcuts #[cfg(all(feature = "async-std", feature = "dns"))] -impl OtherTransportBuilder { +impl SwarmBuilder> { pub async fn with_dns( self, - ) -> Result, std::io::Error> - { + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { self.without_any_other_transports().with_dns().await } } #[cfg(all(feature = "tokio", feature = "dns"))] -impl OtherTransportBuilder { +impl SwarmBuilder> { pub fn with_dns( self, - ) -> Result, std::io::Error> - { + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { self.without_any_other_transports().with_dns() } } #[cfg(feature = "relay")] impl - OtherTransportBuilder + SwarmBuilder> { pub fn with_behaviour( self, @@ -658,18 +735,20 @@ impl &libp2p_identity::Keypair, libp2p_relay::client::Behaviour, ) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_any_other_transports() .without_dns() .without_websocket() .with_behaviour(constructor) } } -impl OtherTransportBuilder { +impl + SwarmBuilder> +{ pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_any_other_transports() .without_dns() .without_websocket() @@ -677,108 +756,120 @@ impl OtherTransportBuilder { +pub struct DnsPhase { transport: T, relay_behaviour: R, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } #[cfg(all(feature = "async-std", feature = "dns"))] -impl DnsBuilder { +impl SwarmBuilder> { pub async fn with_dns( self, - ) -> Result, std::io::Error> - { - Ok(WebsocketBuilder { + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { + Ok(SwarmBuilder { keypair: self.keypair, - relay_behaviour: self.relay_behaviour, - transport: libp2p_dns::DnsConfig::system(self.transport).await?, phantom: PhantomData, + phase: WebsocketPhase { + relay_behaviour: self.phase.relay_behaviour, + transport: libp2p_dns::DnsConfig::system(self.phase.transport).await?, + }, }) } } #[cfg(all(feature = "tokio", feature = "dns"))] -impl DnsBuilder { +impl SwarmBuilder> { pub fn with_dns( self, - ) -> Result, std::io::Error> - { - Ok(WebsocketBuilder { + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { + Ok(SwarmBuilder { keypair: self.keypair, - relay_behaviour: self.relay_behaviour, - transport: libp2p_dns::TokioDnsConfig::system(self.transport)?, phantom: PhantomData, + phase: WebsocketPhase { + relay_behaviour: self.phase.relay_behaviour, + transport: libp2p_dns::TokioDnsConfig::system(self.phase.transport)?, + }, }) } } -impl DnsBuilder { - pub fn without_dns(self) -> WebsocketBuilder { - WebsocketBuilder { +impl SwarmBuilder> { + pub fn without_dns(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, - relay_behaviour: self.relay_behaviour, - // TODO: Timeout needed? - transport: self.transport, phantom: PhantomData, + phase: WebsocketPhase { + relay_behaviour: self.phase.relay_behaviour, + // TODO: Timeout needed? + transport: self.phase.transport, + }, } } } // Shortcuts #[cfg(feature = "relay")] -impl DnsBuilder { +impl + SwarmBuilder> +{ pub fn with_behaviour( self, constructor: impl FnMut( &libp2p_identity::Keypair, libp2p_relay::client::Behaviour, ) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_dns() .without_websocket() .with_behaviour(constructor) } } -impl DnsBuilder { +impl SwarmBuilder> { pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_dns() .without_websocket() .with_behaviour(constructor) } } -pub struct WebsocketBuilder { +pub struct WebsocketPhase { transport: T, relay_behaviour: R, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } #[cfg(feature = "websocket")] -impl WebsocketBuilder { - pub fn with_websocket(self) -> WebsocketTlsBuilder { - WebsocketTlsBuilder { - transport: self.transport, - relay_behaviour: self.relay_behaviour, +impl SwarmBuilder> { + pub fn with_websocket(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: WebsocketTlsPhase { + transport: self.phase.transport, + relay_behaviour: self.phase.relay_behaviour, + }, } } } -impl WebsocketBuilder { - pub fn without_websocket(self) -> BehaviourBuilder { - BehaviourBuilder { +impl SwarmBuilder> { + pub fn without_websocket(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, - relay_behaviour: self.relay_behaviour, - // TODO: Timeout needed? - transport: self.transport.boxed(), phantom: PhantomData, + phase: BehaviourPhase { + relay_behaviour: self.phase.relay_behaviour, + // TODO: Timeout needed? + transport: self.phase.transport.boxed(), + }, } } } @@ -786,7 +877,7 @@ impl WebsocketBuilder { // Shortcuts #[cfg(feature = "relay")] impl - WebsocketBuilder + SwarmBuilder> { pub fn with_behaviour( self, @@ -794,55 +885,58 @@ impl &libp2p_identity::Keypair, libp2p_relay::client::Behaviour, ) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_websocket().with_behaviour(constructor) } } -impl WebsocketBuilder { +impl SwarmBuilder> { pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { self.without_websocket().with_behaviour(constructor) } } #[cfg(feature = "websocket")] -pub struct WebsocketTlsBuilder { +pub struct WebsocketTlsPhase { transport: T, relay_behaviour: R, - keypair: libp2p_identity::Keypair, - phantom: PhantomData

, } #[cfg(feature = "websocket")] -impl WebsocketTlsBuilder { +impl SwarmBuilder> { #[cfg(feature = "tls")] - pub fn with_tls(self) -> WebsocketNoiseBuilder { - WebsocketNoiseBuilder { - relay_behaviour: self.relay_behaviour, - transport: self.transport, + pub fn with_tls(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: WebsocketNoisePhase { + relay_behaviour: self.phase.relay_behaviour, + transport: self.phase.transport, + phantom: PhantomData, + }, } } - pub fn without_tls(self) -> WebsocketNoiseBuilder { - WebsocketNoiseBuilder { - relay_behaviour: self.relay_behaviour, - transport: self.transport, + pub fn without_tls(self) -> SwarmBuilder> { + SwarmBuilder { keypair: self.keypair, phantom: PhantomData, + phase: WebsocketNoisePhase { + relay_behaviour: self.phase.relay_behaviour, + transport: self.phase.transport, + phantom: PhantomData, + }, } } } #[cfg(feature = "websocket")] -pub struct WebsocketNoiseBuilder { +pub struct WebsocketNoisePhase { transport: T, relay_behaviour: R, - keypair: libp2p_identity::Keypair, - phantom: PhantomData<(P, A)>, + phantom: PhantomData, } #[cfg(feature = "websocket")] @@ -854,14 +948,16 @@ macro_rules! construct_behaviour_builder { .multiplex(libp2p_yamux::Config::default()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))); - Ok(BehaviourBuilder { - transport: websocket_transport - .or_transport($self.transport) - .map(|either, _| either.into_inner()) - .boxed(), + Ok(SwarmBuilder { keypair: $self.keypair, - relay_behaviour: $self.relay_behaviour, phantom: PhantomData, + phase: BehaviourPhase { + transport: websocket_transport + .or_transport($self.phase.transport) + .map(|either, _| either.into_inner()) + .boxed(), + relay_behaviour: $self.phase.relay_behaviour, + }, }) }}; } @@ -875,10 +971,10 @@ macro_rules! impl_websocket_noise_builder { feature = "tls" ))] impl - WebsocketNoiseBuilder<$runtimeCamelCase, T, R, Tls> + SwarmBuilder<$runtimeCamelCase, WebsocketNoisePhase< T, R, Tls>> { #[cfg(feature = "noise")] - pub async fn with_noise(self) -> Result,WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -898,7 +994,7 @@ macro_rules! impl_websocket_noise_builder { ) ) } - pub async fn without_noise(self) -> Result,WebsocketError> { + pub async fn without_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -909,9 +1005,9 @@ macro_rules! impl_websocket_noise_builder { #[cfg(all(feature = $runtimeKebabCase, feature = "dns", feature = "websocket", feature = "noise"))] impl - WebsocketNoiseBuilder<$runtimeCamelCase, T, R, WithoutTls> + SwarmBuilder<$runtimeCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> { - pub async fn with_noise(self) -> Result, WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -948,61 +1044,61 @@ pub enum WebsocketError { Dns(#[from] std::io::Error), } -pub struct BehaviourBuilder { - keypair: libp2p_identity::Keypair, +pub struct BehaviourPhase { relay_behaviour: R, transport: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)>, - phantom: PhantomData

, } #[cfg(feature = "relay")] -impl

BehaviourBuilder { +impl

SwarmBuilder> { pub fn with_behaviour( self, mut constructor: impl FnMut( &libp2p_identity::Keypair, libp2p_relay::client::Behaviour, ) -> Result>, - ) -> Result, Box> { - Ok(Builder { - behaviour: constructor(&self.keypair, self.relay_behaviour)?, + ) -> Result>, Box> { + Ok(SwarmBuilder { + phase: BuildPhase { + behaviour: constructor(&self.keypair, self.phase.relay_behaviour)?, + transport: self.phase.transport, + }, keypair: self.keypair, - transport: self.transport, phantom: PhantomData, }) } } -impl

BehaviourBuilder { +impl

SwarmBuilder> { pub fn with_behaviour( self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result, Box> { + ) -> Result>, Box> { // Discard `NoRelayBehaviour`. - let _ = self.relay_behaviour; + let _ = self.phase.relay_behaviour; - Ok(Builder { - behaviour: constructor(&self.keypair)?, + Ok(SwarmBuilder { + phase: BuildPhase { + behaviour: constructor(&self.keypair)?, + transport: self.phase.transport, + }, keypair: self.keypair, - transport: self.transport, phantom: PhantomData, }) } } -pub struct Builder { - keypair: libp2p_identity::Keypair, +pub struct BuildPhase { behaviour: B, transport: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)>, - phantom: PhantomData

, } #[cfg(feature = "async-std")] -impl Builder { +impl SwarmBuilder> { pub fn build(self) -> libp2p_swarm::Swarm { libp2p_swarm::SwarmBuilder::with_async_std_executor( - self.transport, - self.behaviour, + self.phase.transport, + self.phase.behaviour, self.keypair.public().to_peer_id(), ) .build() @@ -1010,17 +1106,19 @@ impl Builder { } #[cfg(feature = "tokio")] -impl Builder { +impl SwarmBuilder> { pub fn build(self) -> libp2p_swarm::Swarm { libp2p_swarm::SwarmBuilder::with_tokio_executor( - self.transport, - self.behaviour, + self.phase.transport, + self.phase.behaviour, self.keypair.public().to_peer_id(), ) .build() } } +pub enum NoProviderSpecified {} + #[cfg(feature = "async-std")] pub enum AsyncStd {} @@ -1061,16 +1159,16 @@ mod tests { #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] fn tcp() { - let _: libp2p_swarm::Swarm = SwarmBuilder::new() - .with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _: libp2p_swarm::Swarm = + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() + .build(); } #[test] @@ -1082,17 +1180,17 @@ mod tests { feature = "quic" ))] fn tcp_quic() { - let _: libp2p_swarm::Swarm = SwarmBuilder::new() - .with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_quic() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _: libp2p_swarm::Swarm = + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_quic() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() + .build(); } #[test] @@ -1111,8 +1209,7 @@ mod tests { relay: libp2p_relay::client::Behaviour, } - let _: libp2p_swarm::Swarm = SwarmBuilder::new() - .with_new_identity() + let _: libp2p_swarm::Swarm = SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() .with_tls() @@ -1141,37 +1238,38 @@ mod tests { feature = "dns" ))] fn tcp_dns() { - let _: libp2p_swarm::Swarm = SwarmBuilder::new() - .with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_dns() - .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _: libp2p_swarm::Swarm = futures::executor::block_on( + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_dns(), + ) + .unwrap() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() + .build(); } /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. QUIC or WebRTC. #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] fn tcp_other_transport_other_transport() { - let _: libp2p_swarm::Swarm = SwarmBuilder::new() - .with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _: libp2p_swarm::Swarm = + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() + .build(); } #[tokio::test] @@ -1184,20 +1282,20 @@ mod tests { feature = "websocket", ))] async fn tcp_websocket() { - let _: libp2p_swarm::Swarm = SwarmBuilder::new() - .with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_websocket() - .with_tls() - .with_noise() - .await - .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _: libp2p_swarm::Swarm = + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_websocket() + .with_tls() + .with_noise() + .await + .unwrap() + .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .unwrap() + .build(); } } From faecb8bcc583e3ccc5c203ee3635fea90aac39e2 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 21 Aug 2023 13:57:33 +0200 Subject: [PATCH 043/171] Make without_ methods private whereever possible In the case where the without_ method returns a Result this is not possible. --- libp2p/src/builder.rs | 57 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index efe5499ac5b..529c213fc7a 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -72,22 +72,38 @@ impl

SwarmBuilder { impl

SwarmBuilder { // TODO: This would allow one to build a faulty transport. - pub fn without_tcp( - self, - ) -> SwarmBuilder> { + fn without_tcp(self) -> SwarmBuilder> { SwarmBuilder { // TODO: Is this a good idea in a production environment? Unfortunately I don't know a // way around it. One can not define two `with_relay` methods, one with a real transport // using OrTransport, one with a fake transport discarding it right away. keypair: self.keypair, phantom: PhantomData, - phase: RelayPhase { + phase: QuicPhase { transport: libp2p_core::transport::dummy::DummyTransport::new(), }, } } } +// Shortcuts +#[cfg(all(feature = "quic", feature = "async-std"))] +impl SwarmBuilder { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + self.without_tcp().with_quic() + } +} +#[cfg(all(feature = "quic", feature = "tokio"))] +impl SwarmBuilder { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + self.without_tcp().with_quic() + } +} + #[cfg(feature = "tcp")] pub struct TcpTlsPhase { config: libp2p_tcp::Config, @@ -107,7 +123,7 @@ impl

SwarmBuilder { } } - pub fn without_tls(self) -> SwarmBuilder> { + fn without_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -293,7 +309,7 @@ impl SwarmBuilder> { } impl SwarmBuilder> { - pub fn without_quic(self) -> SwarmBuilder> { + fn without_quic(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -412,7 +428,7 @@ impl SwarmBuilder> { pub struct NoRelayBehaviour; impl SwarmBuilder> { - pub fn without_relay(self) -> SwarmBuilder> { + fn without_relay(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -511,7 +527,7 @@ impl SwarmBuilder> { } } - pub fn without_tls(self) -> SwarmBuilder> { + fn without_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -628,6 +644,7 @@ impl SwarmBuilder Result< @@ -688,7 +705,7 @@ impl SwarmBuilder SwarmBuilder> { SwarmBuilder { @@ -800,7 +817,7 @@ impl SwarmBuilder } impl SwarmBuilder> { - pub fn without_dns(self) -> SwarmBuilder> { + fn without_dns(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -861,7 +878,7 @@ impl SwarmBuilder> { } impl SwarmBuilder> { - pub fn without_websocket(self) -> SwarmBuilder> { + fn without_websocket(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -919,7 +936,7 @@ impl SwarmBuilder> { } } - pub fn without_tls(self) -> SwarmBuilder> { + fn without_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -932,6 +949,22 @@ impl SwarmBuilder> { } } +// Shortcuts +#[cfg(all(feature = "websocket", feature = "noise", feature = "async-std"))] +impl SwarmBuilder> { + #[cfg(feature = "noise")] + pub async fn with_noise(self) -> Result>, WebsocketError> { + self.without_tls().with_noise().await + } +} +#[cfg(all(feature = "websocket", feature = "noise", feature = "tokio"))] +impl SwarmBuilder> { + #[cfg(feature = "noise")] + pub async fn with_noise(self) -> Result>, WebsocketError> { + self.without_tls().with_noise().await + } +} + #[cfg(feature = "websocket")] pub struct WebsocketNoisePhase { transport: T, From bc7291b5a2be6a7d18124d28cb269de400b78c03 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 21 Aug 2023 14:54:12 +0200 Subject: [PATCH 044/171] Change phase order - Move relay to the back. It doesn't need to come that early. Removes the need to drag the relay behaviour through all phases. - Move other transport closer to tcp and quic to benefit from dns. --- examples/autonat/src/bin/autonat_client.rs | 1 - examples/autonat/src/bin/autonat_server.rs | 1 - examples/dcutr/src/main.rs | 15 +- examples/ipfs-private/src/main.rs | 2 - examples/relay-server/src/main.rs | 8 +- libp2p/src/builder.rs | 475 +++++++++------------ 6 files changed, 197 insertions(+), 305 deletions(-) diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index 67aacad9064..3c57ea44934 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -52,7 +52,6 @@ async fn main() -> Result<(), Box> { let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() - .without_tls() .with_noise()? .with_behaviour(|key| Ok(Behaviour::new(key.public())))? .build(); diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index 7bc61984bdb..33b49b64c7e 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -44,7 +44,6 @@ async fn main() -> Result<(), Box> { let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_tcp() - .without_tls() .with_noise()? .with_behaviour(|key| Ok(Behaviour::new(key.public())))? .build(); diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index ebddc54fd12..7687fe63b84 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -23,11 +23,7 @@ use clap::Parser; use futures::{executor::block_on, future::FutureExt, stream::StreamExt}; use libp2p::{ - core::{ - multiaddr::{Multiaddr, Protocol}, - muxing::StreamMuxerBox, - transport::Transport, - }, + core::multiaddr::{Multiaddr, Protocol}, dcutr, identify, identity, ping, relay, swarm::{NetworkBehaviour, SwarmEvent}, tcp, PeerId, @@ -126,14 +122,11 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp_config(tcp::Config::default().port_reuse(true).nodelay(true)) .with_noise()? - .with_relay() - .with_noise()? - .with_other_transport(|keypair| { - quic::async_std::Transport::new(quic::Config::new(&keypair)) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) - }) + .with_quic() .with_dns() .await? + .with_relay() + .with_noise()? .with_behaviour(|keypair, relay_behaviour| { Ok(Behaviour { relay_client: relay_behaviour, diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 05689f69b22..6d2f3d577f8 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -112,8 +112,6 @@ async fn main() -> Result<(), Box> { let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() - .without_tcp() - .without_relay() .with_other_transport(|key| { let noise_config = noise::Config::new(&key).unwrap(); let yamux_config = yamux::Config::default(); diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index d437f6107c4..7edead57d6d 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -26,8 +26,7 @@ use futures::executor::block_on; use futures::stream::StreamExt; use libp2p::{ core::multiaddr::Protocol, - core::muxing::StreamMuxerBox, - core::{Multiaddr, Transport}, + core::Multiaddr, identify, identity, identity::PeerId, ping, relay, @@ -50,10 +49,7 @@ fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_other_transport(|keypair| { - quic::async_std::Transport::new(quic::Config::new(&keypair)) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) - }) + .with_quic() .with_behaviour(|key| { Ok(Behaviour { relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 529c213fc7a..a9bd407acd8 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,7 +1,6 @@ // TODO: Rename runtime to provider // TODO: Should we have a timeout on transport? // TODO: Be able to address `SwarmBuilder` configuration methods. -// TODO: Consider moving with_relay after with_other_transport. // TODO: Consider making with_other_transport fallible. use libp2p_core::{muxing::StreamMuxerBox, Transport}; @@ -91,7 +90,7 @@ impl

SwarmBuilder { impl SwarmBuilder { pub fn with_quic( self, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { self.without_tcp().with_quic() } } @@ -99,10 +98,20 @@ impl SwarmBuilder { impl SwarmBuilder { pub fn with_quic( self, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { self.without_tcp().with_quic() } } +impl

SwarmBuilder { + pub fn with_other_transport( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, + ) -> SwarmBuilder> { + self.without_tcp() + .without_quic() + .with_other_transport(constructor) + } +} #[cfg(feature = "tcp")] pub struct TcpTlsPhase { @@ -266,9 +275,9 @@ pub struct QuicPhase { impl SwarmBuilder> { pub fn with_quic( self, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { SwarmBuilder { - phase: RelayPhase { + phase: OtherTransportPhase { transport: self .phase .transport @@ -290,9 +299,9 @@ impl SwarmBuilder> impl SwarmBuilder> { pub fn with_quic( self, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { SwarmBuilder { - phase: RelayPhase { + phase: OtherTransportPhase { transport: self .phase .transport @@ -309,11 +318,11 @@ impl SwarmBuilder> { } impl SwarmBuilder> { - fn without_quic(self) -> SwarmBuilder> { + fn without_quic(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, - phase: RelayPhase { + phase: OtherTransportPhase { transport: self.phase.transport, }, } @@ -336,13 +345,8 @@ impl SwarmBuilder> { pub fn with_other_transport( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder< - P, - OtherTransportPhase, - > { - self.without_quic() - .without_relay() - .with_other_transport(constructor) + ) -> SwarmBuilder> { + self.without_quic().with_other_transport(constructor) } #[cfg(feature = "websocket")] @@ -351,9 +355,9 @@ impl SwarmBuilder> { ) -> SwarmBuilder> { self.without_quic() - .without_relay() .without_any_other_transports() .without_dns() + .without_relay() .with_websocket() } @@ -362,27 +366,22 @@ impl SwarmBuilder> { constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, ) -> Result>, Box> { self.without_quic() - .without_relay() .without_any_other_transports() .without_dns() + .without_relay() .without_websocket() .with_behaviour(constructor) } } -// Shortcuts #[cfg(all(feature = "async-std", feature = "dns"))] impl SwarmBuilder> { pub async fn with_dns( self, ) -> Result< - SwarmBuilder< - AsyncStd, - WebsocketPhase, - >, + SwarmBuilder>, std::io::Error, > { self.without_quic() - .without_relay() .without_any_other_transports() .with_dns() .await @@ -393,118 +392,214 @@ impl SwarmBuilder> { pub fn with_dns( self, ) -> Result< - SwarmBuilder< - Tokio, - WebsocketPhase, - >, + SwarmBuilder>, std::io::Error, > { self.without_quic() - .without_relay() .without_any_other_transports() .with_dns() } } -pub struct RelayPhase { +pub struct OtherTransportPhase { transport: T, } -// TODO: Noise feature or tls feature -#[cfg(feature = "relay")] -impl SwarmBuilder> { - // TODO: This should be with_relay_client. - pub fn with_relay(self) -> SwarmBuilder> { +impl SwarmBuilder> { + pub fn with_other_transport( + self, + mut constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, + ) -> SwarmBuilder> { SwarmBuilder { + phase: OtherTransportPhase { + transport: self + .phase + .transport + .or_transport(constructor(&self.keypair)) + .map(|either, _| either.into_inner()), + }, keypair: self.keypair, phantom: PhantomData, - phase: RelayTlsPhase { - transport: self.phase.transport, - }, } } -} - -pub struct NoRelayBehaviour; -impl SwarmBuilder> { - fn without_relay(self) -> SwarmBuilder> { + // TODO: Not the ideal name. + fn without_any_other_transports( + self, + ) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, - phase: OtherTransportPhase { + phase: DnsPhase { transport: self.phase.transport, - relay_behaviour: NoRelayBehaviour, }, } } } // Shortcuts -impl SwarmBuilder> { - pub fn with_other_transport( +#[cfg(all(feature = "async-std", feature = "dns"))] +impl SwarmBuilder> { + pub async fn with_dns( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder< - P, - OtherTransportPhase, + ) -> Result< + SwarmBuilder>, + std::io::Error, > { - self.without_relay().with_other_transport(constructor) + self.without_any_other_transports().with_dns().await } - - #[cfg(feature = "websocket")] - pub fn with_websocket( +} +#[cfg(all(feature = "tokio", feature = "dns"))] +impl SwarmBuilder> { + pub fn with_dns( self, - ) -> SwarmBuilder> - { - self.without_relay() - .without_any_other_transports() + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { + self.without_any_other_transports().with_dns() + } +} +#[cfg(feature = "relay")] +impl SwarmBuilder> { + pub fn with_relay( + self, + ) -> SwarmBuilder> { + self.without_any_other_transports() .without_dns() - .with_websocket() + .with_relay() } - +} +impl SwarmBuilder> { pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, ) -> Result>, Box> { - self.without_relay() - .without_any_other_transports() + self.without_any_other_transports() .without_dns() + .without_relay() .without_websocket() .with_behaviour(constructor) } } + +pub struct DnsPhase { + transport: T, +} + #[cfg(all(feature = "async-std", feature = "dns"))] -impl SwarmBuilder> { +impl SwarmBuilder> { pub async fn with_dns( self, ) -> Result< - SwarmBuilder< - AsyncStd, - WebsocketPhase, - >, + SwarmBuilder>, std::io::Error, > { - self.without_relay() - .without_any_other_transports() - .with_dns() - .await + Ok(SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: RelayPhase { + transport: libp2p_dns::DnsConfig::system(self.phase.transport).await?, + }, + }) } } + #[cfg(all(feature = "tokio", feature = "dns"))] -impl SwarmBuilder> { +impl SwarmBuilder> { pub fn with_dns( self, ) -> Result< - SwarmBuilder< - Tokio, - WebsocketPhase, - >, + SwarmBuilder>, std::io::Error, > { + Ok(SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: RelayPhase { + transport: libp2p_dns::TokioDnsConfig::system(self.phase.transport)?, + }, + }) + } +} + +impl SwarmBuilder> { + fn without_dns(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: RelayPhase { + // TODO: Timeout needed? + transport: self.phase.transport, + }, + } + } +} + +// Shortcuts +impl SwarmBuilder> { + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result>, Box> { + self.without_dns() + .without_relay() + .without_websocket() + .with_behaviour(constructor) + } +} + +pub struct RelayPhase { + transport: T, +} + +// TODO: Noise feature or tls feature +#[cfg(feature = "relay")] +impl SwarmBuilder> { + // TODO: This should be with_relay_client. + pub fn with_relay(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: RelayTlsPhase { + transport: self.phase.transport, + }, + } + } +} + +pub struct NoRelayBehaviour; + +impl SwarmBuilder> { + fn without_relay(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: WebsocketPhase { + transport: self.phase.transport, + relay_behaviour: NoRelayBehaviour, + }, + } + } +} + +// Shortcuts +impl SwarmBuilder> { + #[cfg(feature = "websocket")] + pub fn with_websocket( + self, + ) -> SwarmBuilder> + { + self.without_relay().with_websocket() + } + + pub fn with_behaviour( + self, + constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, + ) -> Result>, Box> { self.without_relay() - .without_any_other_transports() - .with_dns() + .without_websocket() + .with_behaviour(constructor) } } @@ -549,10 +644,7 @@ impl SwarmBuilder Result< SwarmBuilder< AsyncStd, - OtherTransportPhase< - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, - >, + WebsocketPhase, >, AuthenticationError, > { @@ -567,10 +659,7 @@ impl SwarmBuilder> ) -> Result< SwarmBuilder< Tokio, - OtherTransportPhase< - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, - >, + WebsocketPhase, >, AuthenticationError, > { @@ -584,14 +673,15 @@ pub struct RelayNoisePhase { phantom: PhantomData, } +// TODO: Rename these macros to phase not builder. All. #[cfg(feature = "relay")] -macro_rules! construct_other_transport_builder { +macro_rules! construct_websocket_builder { ($self:ident, $auth:expr) => {{ let (relay_transport, relay_behaviour) = libp2p_relay::client::new($self.keypair.public().to_peer_id()); Ok(SwarmBuilder { - phase: OtherTransportPhase { + phase: WebsocketPhase { relay_behaviour, transport: $self .phase @@ -619,14 +709,11 @@ impl SwarmBuilder Result< SwarmBuilder< P, - OtherTransportPhase< - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, - >, + WebsocketPhase, >, AuthenticationError, > { - construct_other_transport_builder!( + construct_websocket_builder!( self, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( @@ -650,14 +737,11 @@ impl SwarmBuilder Result< SwarmBuilder< P, - OtherTransportPhase< - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, - >, + WebsocketPhase, >, AuthenticationError, > { - construct_other_transport_builder!(self, libp2p_tls::Config::new(&self.keypair)?) + construct_websocket_builder!(self, libp2p_tls::Config::new(&self.keypair)?) } } @@ -669,192 +753,11 @@ impl SwarmBuilder Result< SwarmBuilder< P, - OtherTransportPhase< - impl AuthenticatedMultiplexedTransport, - libp2p_relay::client::Behaviour, - >, + WebsocketPhase, >, AuthenticationError, > { - construct_other_transport_builder!(self, libp2p_noise::Config::new(&self.keypair)?) - } -} - -pub struct OtherTransportPhase { - transport: T, - relay_behaviour: R, -} - -impl SwarmBuilder> { - pub fn with_other_transport( - self, - mut constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder> { - SwarmBuilder { - phase: OtherTransportPhase { - transport: self - .phase - .transport - .or_transport(constructor(&self.keypair)) - .map(|either, _| either.into_inner()), - relay_behaviour: self.phase.relay_behaviour, - }, - keypair: self.keypair, - phantom: PhantomData, - } - } - - // TODO: Not the ideal name. - fn without_any_other_transports( - self, - ) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: DnsPhase { - transport: self.phase.transport, - relay_behaviour: self.phase.relay_behaviour, - }, - } - } -} - -// Shortcuts -#[cfg(all(feature = "async-std", feature = "dns"))] -impl SwarmBuilder> { - pub async fn with_dns( - self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { - self.without_any_other_transports().with_dns().await - } -} -#[cfg(all(feature = "tokio", feature = "dns"))] -impl SwarmBuilder> { - pub fn with_dns( - self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { - self.without_any_other_transports().with_dns() - } -} -#[cfg(feature = "relay")] -impl - SwarmBuilder> -{ - pub fn with_behaviour( - self, - constructor: impl FnMut( - &libp2p_identity::Keypair, - libp2p_relay::client::Behaviour, - ) -> Result>, - ) -> Result>, Box> { - self.without_any_other_transports() - .without_dns() - .without_websocket() - .with_behaviour(constructor) - } -} -impl - SwarmBuilder> -{ - pub fn with_behaviour( - self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { - self.without_any_other_transports() - .without_dns() - .without_websocket() - .with_behaviour(constructor) - } -} - -pub struct DnsPhase { - transport: T, - relay_behaviour: R, -} - -#[cfg(all(feature = "async-std", feature = "dns"))] -impl SwarmBuilder> { - pub async fn with_dns( - self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { - Ok(SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: WebsocketPhase { - relay_behaviour: self.phase.relay_behaviour, - transport: libp2p_dns::DnsConfig::system(self.phase.transport).await?, - }, - }) - } -} - -#[cfg(all(feature = "tokio", feature = "dns"))] -impl SwarmBuilder> { - pub fn with_dns( - self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { - Ok(SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: WebsocketPhase { - relay_behaviour: self.phase.relay_behaviour, - transport: libp2p_dns::TokioDnsConfig::system(self.phase.transport)?, - }, - }) - } -} - -impl SwarmBuilder> { - fn without_dns(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: WebsocketPhase { - relay_behaviour: self.phase.relay_behaviour, - // TODO: Timeout needed? - transport: self.phase.transport, - }, - } - } -} - -// Shortcuts -#[cfg(feature = "relay")] -impl - SwarmBuilder> -{ - pub fn with_behaviour( - self, - constructor: impl FnMut( - &libp2p_identity::Keypair, - libp2p_relay::client::Behaviour, - ) -> Result>, - ) -> Result>, Box> { - self.without_dns() - .without_websocket() - .with_behaviour(constructor) - } -} -impl SwarmBuilder> { - pub fn with_behaviour( - self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { - self.without_dns() - .without_websocket() - .with_behaviour(constructor) + construct_websocket_builder!(self, libp2p_noise::Config::new(&self.keypair)?) } } @@ -953,14 +856,18 @@ impl SwarmBuilder> { #[cfg(all(feature = "websocket", feature = "noise", feature = "async-std"))] impl SwarmBuilder> { #[cfg(feature = "noise")] - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise( + self, + ) -> Result>, WebsocketError> { self.without_tls().with_noise().await } } #[cfg(all(feature = "websocket", feature = "noise", feature = "tokio"))] impl SwarmBuilder> { #[cfg(feature = "noise")] - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise( + self, + ) -> Result>, WebsocketError> { self.without_tls().with_noise().await } } From 711bfcb3ba7e478c96041d3df5008d147692749b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 21 Aug 2023 18:15:18 +0200 Subject: [PATCH 045/171] Rename runtime to provider --- libp2p/src/builder.rs | 182 +++++++++++++++++++++++------------------- 1 file changed, 102 insertions(+), 80 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index a9bd407acd8..9ad349e2a58 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,4 +1,3 @@ -// TODO: Rename runtime to provider // TODO: Should we have a timeout on transport? // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider making with_other_transport fallible. @@ -6,9 +5,9 @@ use libp2p_core::{muxing::StreamMuxerBox, Transport}; use std::marker::PhantomData; -pub struct SwarmBuilder { +pub struct SwarmBuilder { keypair: libp2p_identity::Keypair, - phantom: PhantomData

, + phantom: PhantomData, phase: Phase, } @@ -55,12 +54,15 @@ impl SwarmBuilder { pub struct TcpPhase {} #[cfg(feature = "tcp")] -impl

SwarmBuilder { - pub fn with_tcp(self) -> SwarmBuilder { +impl SwarmBuilder { + pub fn with_tcp(self) -> SwarmBuilder { self.with_tcp_config(Default::default()) } - pub fn with_tcp_config(self, config: libp2p_tcp::Config) -> SwarmBuilder { + pub fn with_tcp_config( + self, + config: libp2p_tcp::Config, + ) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -69,9 +71,11 @@ impl

SwarmBuilder { } } -impl

SwarmBuilder { +impl SwarmBuilder { // TODO: This would allow one to build a faulty transport. - fn without_tcp(self) -> SwarmBuilder> { + fn without_tcp( + self, + ) -> SwarmBuilder> { SwarmBuilder { // TODO: Is this a good idea in a production environment? Unfortunately I don't know a // way around it. One can not define two `with_relay` methods, one with a real transport @@ -102,11 +106,11 @@ impl SwarmBuilder { self.without_tcp().with_quic() } } -impl

SwarmBuilder { +impl SwarmBuilder { pub fn with_other_transport( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { self.without_tcp() .without_quic() .with_other_transport(constructor) @@ -119,9 +123,9 @@ pub struct TcpTlsPhase { } #[cfg(feature = "tcp")] -impl

SwarmBuilder { +impl SwarmBuilder { #[cfg(feature = "tls")] - pub fn with_tls(self) -> SwarmBuilder> { + pub fn with_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -132,7 +136,7 @@ impl

SwarmBuilder { } } - fn without_tls(self) -> SwarmBuilder> { + fn without_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -194,14 +198,14 @@ macro_rules! construct_quic_builder { } macro_rules! impl_tcp_noise_builder { - ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $tcp:ident) => { - #[cfg(all(feature = $runtimeKebabCase, feature = "tcp", feature = "tls"))] - impl SwarmBuilder<$runtimeCamelCase, TcpNoisePhase> { + ($providerKebabCase:literal, $providerCamelCase:ident, $tcp:ident) => { + #[cfg(all(feature = $providerKebabCase, feature = "tcp", feature = "tls"))] + impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - SwarmBuilder<$runtimeCamelCase, QuicPhase>, + SwarmBuilder<$providerCamelCase, QuicPhase>, AuthenticationError, > { construct_quic_builder!( @@ -227,20 +231,20 @@ macro_rules! impl_tcp_noise_builder { pub fn without_noise( self, ) -> Result< - SwarmBuilder<$runtimeCamelCase, QuicPhase>, + SwarmBuilder<$providerCamelCase, QuicPhase>, AuthenticationError, > { construct_quic_builder!(self, $tcp, libp2p_tls::Config::new(&self.keypair)?) } } - #[cfg(feature = $runtimeKebabCase)] - impl SwarmBuilder<$runtimeCamelCase, TcpNoisePhase> { + #[cfg(feature = $providerKebabCase)] + impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< - SwarmBuilder<$runtimeCamelCase, QuicPhase>, + SwarmBuilder<$providerCamelCase, QuicPhase>, AuthenticationError, > { construct_quic_builder!(self, $tcp, libp2p_noise::Config::new(&self.keypair)?) @@ -317,8 +321,8 @@ impl SwarmBuilder> { } } -impl SwarmBuilder> { - fn without_quic(self) -> SwarmBuilder> { +impl SwarmBuilder> { + fn without_quic(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -330,9 +334,9 @@ impl SwarmBuilder> { } // Shortcuts -impl SwarmBuilder> { +impl SwarmBuilder> { #[cfg(feature = "relay")] - pub fn with_relay(self) -> SwarmBuilder> { + pub fn with_relay(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -345,15 +349,17 @@ impl SwarmBuilder> { pub fn with_other_transport( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { self.without_quic().with_other_transport(constructor) } #[cfg(feature = "websocket")] pub fn with_websocket( self, - ) -> SwarmBuilder> - { + ) -> SwarmBuilder< + Provider, + WebsocketTlsPhase, + > { self.without_quic() .without_any_other_transports() .without_dns() @@ -364,7 +370,7 @@ impl SwarmBuilder> { pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { self.without_quic() .without_any_other_transports() .without_dns() @@ -405,11 +411,13 @@ pub struct OtherTransportPhase { transport: T, } -impl SwarmBuilder> { +impl + SwarmBuilder> +{ pub fn with_other_transport( self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { SwarmBuilder { phase: OtherTransportPhase { transport: self @@ -426,7 +434,7 @@ impl SwarmBuilder SwarmBuilder> { + ) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -461,20 +469,24 @@ impl SwarmBuilder SwarmBuilder> { +impl + SwarmBuilder> +{ pub fn with_relay( self, - ) -> SwarmBuilder> { + ) -> SwarmBuilder> { self.without_any_other_transports() .without_dns() .with_relay() } } -impl SwarmBuilder> { +impl + SwarmBuilder> +{ pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { self.without_any_other_transports() .without_dns() .without_relay() @@ -523,8 +535,8 @@ impl SwarmBuilder> { } } -impl SwarmBuilder> { - fn without_dns(self) -> SwarmBuilder> { +impl SwarmBuilder> { + fn without_dns(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -537,11 +549,11 @@ impl SwarmBuilder> { } // Shortcuts -impl SwarmBuilder> { +impl SwarmBuilder> { pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { self.without_dns() .without_relay() .without_websocket() @@ -555,9 +567,9 @@ pub struct RelayPhase { // TODO: Noise feature or tls feature #[cfg(feature = "relay")] -impl SwarmBuilder> { +impl SwarmBuilder> { // TODO: This should be with_relay_client. - pub fn with_relay(self) -> SwarmBuilder> { + pub fn with_relay(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -570,8 +582,8 @@ impl SwarmBuilder> { pub struct NoRelayBehaviour; -impl SwarmBuilder> { - fn without_relay(self) -> SwarmBuilder> { +impl SwarmBuilder> { + fn without_relay(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -584,19 +596,21 @@ impl SwarmBuilder> { } // Shortcuts -impl SwarmBuilder> { +impl SwarmBuilder> { #[cfg(feature = "websocket")] pub fn with_websocket( self, - ) -> SwarmBuilder> - { + ) -> SwarmBuilder< + Provider, + WebsocketTlsPhase, + > { self.without_relay().with_websocket() } pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { self.without_relay() .without_websocket() .with_behaviour(constructor) @@ -609,9 +623,9 @@ pub struct RelayTlsPhase { } #[cfg(feature = "relay")] -impl SwarmBuilder> { +impl SwarmBuilder> { #[cfg(feature = "tls")] - pub fn with_tls(self) -> SwarmBuilder> { + pub fn with_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -622,7 +636,7 @@ impl SwarmBuilder> { } } - fn without_tls(self) -> SwarmBuilder> { + fn without_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -702,13 +716,15 @@ macro_rules! construct_websocket_builder { } #[cfg(all(feature = "relay", feature = "tls"))] -impl SwarmBuilder> { +impl + SwarmBuilder> +{ #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< SwarmBuilder< - P, + Provider, WebsocketPhase, >, AuthenticationError, @@ -736,7 +752,7 @@ impl SwarmBuilder Result< SwarmBuilder< - P, + Provider, WebsocketPhase, >, AuthenticationError, @@ -746,13 +762,15 @@ impl SwarmBuilder SwarmBuilder> { +impl + SwarmBuilder> +{ #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< SwarmBuilder< - P, + Provider, WebsocketPhase, >, AuthenticationError, @@ -767,8 +785,8 @@ pub struct WebsocketPhase { } #[cfg(feature = "websocket")] -impl SwarmBuilder> { - pub fn with_websocket(self) -> SwarmBuilder> { +impl SwarmBuilder> { + pub fn with_websocket(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -780,8 +798,10 @@ impl SwarmBuilder> { } } -impl SwarmBuilder> { - fn without_websocket(self) -> SwarmBuilder> { +impl + SwarmBuilder> +{ + fn without_websocket(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -796,8 +816,8 @@ impl SwarmBuilder - SwarmBuilder> +impl + SwarmBuilder> { pub fn with_behaviour( self, @@ -805,15 +825,17 @@ impl &libp2p_identity::Keypair, libp2p_relay::client::Behaviour, ) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { self.without_websocket().with_behaviour(constructor) } } -impl SwarmBuilder> { +impl + SwarmBuilder> +{ pub fn with_behaviour( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { self.without_websocket().with_behaviour(constructor) } } @@ -825,9 +847,9 @@ pub struct WebsocketTlsPhase { } #[cfg(feature = "websocket")] -impl SwarmBuilder> { +impl SwarmBuilder> { #[cfg(feature = "tls")] - pub fn with_tls(self) -> SwarmBuilder> { + pub fn with_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -839,7 +861,7 @@ impl SwarmBuilder> { } } - fn without_tls(self) -> SwarmBuilder> { + fn without_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -903,18 +925,18 @@ macro_rules! construct_behaviour_builder { } macro_rules! impl_websocket_noise_builder { - ($runtimeKebabCase:literal, $runtimeCamelCase:ident, $dnsTcp:expr) => { + ($providerKebabCase:literal, $providerCamelCase:ident, $dnsTcp:expr) => { #[cfg(all( - feature = $runtimeKebabCase, + feature = $providerKebabCase, feature = "websocket", feature = "dns", feature = "tls" ))] impl - SwarmBuilder<$runtimeCamelCase, WebsocketNoisePhase< T, R, Tls>> + SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, Tls>> { #[cfg(feature = "noise")] - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -934,7 +956,7 @@ macro_rules! impl_websocket_noise_builder { ) ) } - pub async fn without_noise(self) -> Result>, WebsocketError> { + pub async fn without_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -943,11 +965,11 @@ macro_rules! impl_websocket_noise_builder { } } - #[cfg(all(feature = $runtimeKebabCase, feature = "dns", feature = "websocket", feature = "noise"))] + #[cfg(all(feature = $providerKebabCase, feature = "dns", feature = "websocket", feature = "noise"))] impl - SwarmBuilder<$runtimeCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> + SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> { - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -990,14 +1012,14 @@ pub struct BehaviourPhase { } #[cfg(feature = "relay")] -impl

SwarmBuilder> { +impl SwarmBuilder> { pub fn with_behaviour( self, mut constructor: impl FnMut( &libp2p_identity::Keypair, libp2p_relay::client::Behaviour, ) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { Ok(SwarmBuilder { phase: BuildPhase { behaviour: constructor(&self.keypair, self.phase.relay_behaviour)?, @@ -1009,11 +1031,11 @@ impl

SwarmBuilder> { } } -impl

SwarmBuilder> { +impl SwarmBuilder> { pub fn with_behaviour( self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + ) -> Result>, Box> { // Discard `NoRelayBehaviour`. let _ = self.phase.relay_behaviour; From 1b1f49d8fdad24cae653487e57d47269aeef217d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 24 Aug 2023 09:20:52 +0200 Subject: [PATCH 046/171] Avoid need for `Ok` wrapping behaviour when closure is infallible --- examples/autonat/src/bin/autonat_client.rs | 2 +- examples/autonat/src/bin/autonat_server.rs | 2 +- examples/chat-example/src/main.rs | 3 +- examples/dcutr/src/main.rs | 18 +- examples/file-sharing/src/network.rs | 20 +- examples/identify/src/main.rs | 4 +- examples/ipfs-kad/src/main.rs | 2 +- examples/ipfs-private/src/main.rs | 5 +- examples/metrics/src/main.rs | 2 +- examples/ping-example/src/main.rs | 2 +- examples/relay-server/src/main.rs | 16 +- examples/rendezvous/src/bin/rzv-discover.rs | 12 +- examples/rendezvous/src/bin/rzv-identify.rs | 20 +- examples/rendezvous/src/bin/rzv-register.rs | 12 +- examples/rendezvous/src/main.rs | 22 +- libp2p/src/builder.rs | 238 ++++++++++---------- 16 files changed, 184 insertions(+), 196 deletions(-) diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index 3c57ea44934..8e1f95ce1ce 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -53,7 +53,7 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| Ok(Behaviour::new(key.public())))? + .with_behaviour(|key| Behaviour::new(key.public()))? .build(); println!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index 33b49b64c7e..29869eaa0ba 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -45,7 +45,7 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| Ok(Behaviour::new(key.public())))? + .with_behaviour(|key| Behaviour::new(key.public()))? .build(); println!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 27b208bfdb1..9504c19afce 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -55,7 +55,8 @@ async fn main() -> Result<(), Box> { .heartbeat_interval(Duration::from_secs(10)) // This is set to aid debugging by not cluttering the log space .validation_mode(gossipsub::ValidationMode::Strict) // This sets the kind of message validation. The default is Strict (enforce message signing) .message_id_fn(message_id_fn) // content-address messages. No two messages of the same content will be propagated. - .build()?; + .build() + .map_err(|msg| io::Error::new(io::ErrorKind::Other, msg))?; // Temporary hack because `build` does not return a proper `std::error::Error`. // build a gossipsub network behaviour let gossipsub = gossipsub::Behaviour::new( diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 7687fe63b84..d16c78444fe 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -127,16 +127,14 @@ async fn main() -> Result<(), Box> { .await? .with_relay() .with_noise()? - .with_behaviour(|keypair, relay_behaviour| { - Ok(Behaviour { - relay_client: relay_behaviour, - ping: ping::Behaviour::new(ping::Config::new()), - identify: identify::Behaviour::new(identify::Config::new( - "/TODO/0.0.1".to_string(), - keypair.public(), - )), - dcutr: dcutr::Behaviour::new(keypair.public().to_peer_id()), - }) + .with_behaviour(|keypair, relay_behaviour| Behaviour { + relay_client: relay_behaviour, + ping: ping::Behaviour::new(ping::Config::new()), + identify: identify::Behaviour::new(identify::Config::new( + "/TODO/0.0.1".to_string(), + keypair.public(), + )), + dcutr: dcutr::Behaviour::new(keypair.public().to_peer_id()), })? .build(); diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 92db1ff9488..7d50d757ab1 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -47,17 +47,15 @@ pub(crate) async fn new( .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| { - Ok(ComposedBehaviour { - kademlia: Kademlia::new(peer_id, MemoryStore::new(key.public().to_peer_id())), - request_response: request_response::cbor::Behaviour::new( - [( - StreamProtocol::new("/file-exchange/1"), - ProtocolSupport::Full, - )], - request_response::Config::default(), - ), - }) + .with_behaviour(|key| ComposedBehaviour { + kademlia: Kademlia::new(peer_id, MemoryStore::new(key.public().to_peer_id())), + request_response: request_response::cbor::Behaviour::new( + [( + StreamProtocol::new("/file-exchange/1"), + ProtocolSupport::Full, + )], + request_response::Config::default(), + ), })? .build(); diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index e87eeb46a31..536fc83d6f6 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -33,10 +33,10 @@ async fn main() -> Result<(), Box> { .with_tcp() .with_noise()? .with_behaviour(|key| { - Ok(identify::Behaviour::new(identify::Config::new( + identify::Behaviour::new(identify::Config::new( "/ipfs/id/1.0.0".to_string(), key.public(), - ))) + )) }) .unwrap() .build(); diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index b6bfc45a05d..727ab2209d8 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -48,7 +48,7 @@ async fn main() -> Result<(), Box> { let mut cfg = KademliaConfig::default(); cfg.set_query_timeout(Duration::from_secs(5 * 60)); let store = MemoryStore::new(key.public().to_peer_id()); - Ok(Kademlia::with_config(key.public().to_peer_id(), store, cfg)) + Kademlia::with_config(key.public().to_peer_id(), store, cfg) }) .unwrap() .build(); diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 6d2f3d577f8..34c39dd9313 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -113,7 +113,7 @@ async fn main() -> Result<(), Box> { let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_async_std() .with_other_transport(|key| { - let noise_config = noise::Config::new(&key).unwrap(); + let noise_config = noise::Config::new(key).unwrap(); let yamux_config = yamux::Config::default(); let base_transport = @@ -136,7 +136,8 @@ async fn main() -> Result<(), Box> { .with_behaviour(|key| { let gossipsub_config = gossipsub::ConfigBuilder::default() .max_transmit_size(262144) - .build()?; + .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()), diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index 46a38f8da1d..0ba06862bff 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -40,7 +40,7 @@ fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|key| Ok(Behaviour::new(key.public())))? + .with_behaviour(|key| Behaviour::new(key.public()))? .build(); info!("Local peer id: {:?}", swarm.local_peer_id()); diff --git a/examples/ping-example/src/main.rs b/examples/ping-example/src/main.rs index 853d5e6b673..e388d292a71 100644 --- a/examples/ping-example/src/main.rs +++ b/examples/ping-example/src/main.rs @@ -34,7 +34,7 @@ async fn main() -> Result<(), Box> { .with_async_std() .with_tcp() .with_noise()? - .with_behaviour(|_| Ok(Behaviour::default())) + .with_behaviour(|_| Behaviour::default()) .unwrap() .build(); diff --git a/examples/relay-server/src/main.rs b/examples/relay-server/src/main.rs index 7edead57d6d..7a37fd2ca7f 100644 --- a/examples/relay-server/src/main.rs +++ b/examples/relay-server/src/main.rs @@ -50,15 +50,13 @@ fn main() -> Result<(), Box> { .with_tcp() .with_noise()? .with_quic() - .with_behaviour(|key| { - Ok(Behaviour { - relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), - ping: ping::Behaviour::new(ping::Config::new()), - identify: identify::Behaviour::new(identify::Config::new( - "/TODO/0.0.1".to_string(), - key.public(), - )), - }) + .with_behaviour(|key| Behaviour { + relay: relay::Behaviour::new(key.public().to_peer_id(), Default::default()), + ping: ping::Behaviour::new(ping::Config::new()), + identify: identify::Behaviour::new(identify::Config::new( + "/TODO/0.0.1".to_string(), + key.public(), + )), })? .build(); diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index a2619b22c19..19c5f54658c 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -43,14 +43,10 @@ async fn main() -> Result<(), Box> { .with_tokio() .with_tcp() .with_noise()? - .with_behaviour(|key| { - Ok(MyBehaviour { - rendezvous: rendezvous::client::Behaviour::new(key.clone()), - ping: ping::Behaviour::new( - ping::Config::new().with_interval(Duration::from_secs(1)), - ), - keep_alive: keep_alive::Behaviour, - }) + .with_behaviour(|key| MyBehaviour { + rendezvous: rendezvous::client::Behaviour::new(key.clone()), + ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), + keep_alive: keep_alive::Behaviour, }) .unwrap() .build(); diff --git a/examples/rendezvous/src/bin/rzv-identify.rs b/examples/rendezvous/src/bin/rzv-identify.rs index e4b841865bd..0c4caa89f6b 100644 --- a/examples/rendezvous/src/bin/rzv-identify.rs +++ b/examples/rendezvous/src/bin/rzv-identify.rs @@ -40,18 +40,14 @@ async fn main() { .with_tcp() .with_noise() .unwrap() - .with_behaviour(|key| { - Ok(MyBehaviour { - identify: identify::Behaviour::new(identify::Config::new( - "rendezvous-example/1.0.0".to_string(), - key.public(), - )), - rendezvous: rendezvous::client::Behaviour::new(key.clone()), - ping: ping::Behaviour::new( - ping::Config::new().with_interval(Duration::from_secs(1)), - ), - keep_alive: keep_alive::Behaviour, - }) + .with_behaviour(|key| MyBehaviour { + identify: identify::Behaviour::new(identify::Config::new( + "rendezvous-example/1.0.0".to_string(), + key.public(), + )), + rendezvous: rendezvous::client::Behaviour::new(key.clone()), + ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), + keep_alive: keep_alive::Behaviour, }) .unwrap() .build(); diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index b8bb8c68982..cda0c4aedff 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -40,14 +40,10 @@ async fn main() { .with_tcp() .with_noise() .unwrap() - .with_behaviour(|key| { - Ok(MyBehaviour { - rendezvous: rendezvous::client::Behaviour::new(key.clone()), - ping: ping::Behaviour::new( - ping::Config::new().with_interval(Duration::from_secs(1)), - ), - keep_alive: keep_alive::Behaviour, - }) + .with_behaviour(|key| MyBehaviour { + rendezvous: rendezvous::client::Behaviour::new(key.clone()), + ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), + keep_alive: keep_alive::Behaviour, }) .unwrap() .build(); diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 1562353b854..517991e1f3a 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -36,20 +36,14 @@ async fn main() -> Result<(), Box> { .with_tokio() .with_tcp() .with_noise()? - .with_behaviour(|key| { - Ok(MyBehaviour { - identify: identify::Behaviour::new(identify::Config::new( - "rendezvous-example/1.0.0".to_string(), - key.public(), - )), - rendezvous: rendezvous::server::Behaviour::new( - rendezvous::server::Config::default(), - ), - ping: ping::Behaviour::new( - ping::Config::new().with_interval(Duration::from_secs(1)), - ), - keep_alive: keep_alive::Behaviour, - }) + .with_behaviour(|key| MyBehaviour { + identify: identify::Behaviour::new(identify::Config::new( + "rendezvous-example/1.0.0".to_string(), + key.public(), + )), + rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()), + ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), + keep_alive: keep_alive::Behaviour, })? .build(); diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 9ad349e2a58..382978de144 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -3,6 +3,9 @@ // TODO: Consider making with_other_transport fallible. use libp2p_core::{muxing::StreamMuxerBox, Transport}; +use libp2p_swarm::NetworkBehaviour; +use std::convert::Infallible; +use std::io; use std::marker::PhantomData; pub struct SwarmBuilder { @@ -367,10 +370,10 @@ impl SwarmBuilder( + pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { self.without_quic() .without_any_other_transports() .without_dns() @@ -383,10 +386,8 @@ impl SwarmBuilder SwarmBuilder> { pub async fn with_dns( self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { + ) -> Result>, io::Error> + { self.without_quic() .without_any_other_transports() .with_dns() @@ -397,10 +398,8 @@ impl SwarmBuilder> impl SwarmBuilder> { pub fn with_dns( self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { + ) -> Result>, io::Error> + { self.without_quic() .without_any_other_transports() .with_dns() @@ -450,10 +449,8 @@ impl impl SwarmBuilder> { pub async fn with_dns( self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { + ) -> Result>, io::Error> + { self.without_any_other_transports().with_dns().await } } @@ -461,10 +458,8 @@ impl SwarmBuilder SwarmBuilder> { pub fn with_dns( self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { + ) -> Result>, io::Error> + { self.without_any_other_transports().with_dns() } } @@ -483,10 +478,10 @@ impl impl SwarmBuilder> { - pub fn with_behaviour( + pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { self.without_any_other_transports() .without_dns() .without_relay() @@ -503,10 +498,8 @@ pub struct DnsPhase { impl SwarmBuilder> { pub async fn with_dns( self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { + ) -> Result>, io::Error> + { Ok(SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -521,10 +514,8 @@ impl SwarmBuilder> { impl SwarmBuilder> { pub fn with_dns( self, - ) -> Result< - SwarmBuilder>, - std::io::Error, - > { + ) -> Result>, io::Error> + { Ok(SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -550,10 +541,10 @@ impl SwarmBuilder> { // Shortcuts impl SwarmBuilder> { - pub fn with_behaviour( + pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { self.without_dns() .without_relay() .without_websocket() @@ -607,10 +598,10 @@ impl SwarmBuilder( + pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { self.without_relay() .without_websocket() .with_behaviour(constructor) @@ -819,23 +810,21 @@ impl impl SwarmBuilder> { - pub fn with_behaviour( + pub fn with_behaviour>( self, - constructor: impl FnMut( - &libp2p_identity::Keypair, - libp2p_relay::client::Behaviour, - ) -> Result>, - ) -> Result>, Box> { + constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } } + impl SwarmBuilder> { - pub fn with_behaviour( + pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } } @@ -1003,7 +992,7 @@ pub enum WebsocketError { Authentication(#[from] AuthenticationError), #[cfg(feature = "dns")] #[error("Dns")] - Dns(#[from] std::io::Error), + Dns(#[from] io::Error), } pub struct BehaviourPhase { @@ -1013,16 +1002,14 @@ pub struct BehaviourPhase { #[cfg(feature = "relay")] impl SwarmBuilder> { - pub fn with_behaviour( + pub fn with_behaviour>( self, - mut constructor: impl FnMut( - &libp2p_identity::Keypair, - libp2p_relay::client::Behaviour, - ) -> Result>, - ) -> Result>, Box> { + mut constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + ) -> Result>, R::Error> { Ok(SwarmBuilder { phase: BuildPhase { - behaviour: constructor(&self.keypair, self.phase.relay_behaviour)?, + behaviour: constructor(&self.keypair, self.phase.relay_behaviour) + .try_into_behaviour()?, transport: self.phase.transport, }, keypair: self.keypair, @@ -1032,16 +1019,16 @@ impl SwarmBuilder SwarmBuilder> { - pub fn with_behaviour( + pub fn with_behaviour>( self, - mut constructor: impl FnMut(&libp2p_identity::Keypair) -> Result>, - ) -> Result>, Box> { + mut constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { // Discard `NoRelayBehaviour`. let _ = self.phase.relay_behaviour; Ok(SwarmBuilder { phase: BuildPhase { - behaviour: constructor(&self.keypair)?, + behaviour: constructor(&self.keypair).try_into_behaviour()?, transport: self.phase.transport, }, keypair: self.keypair, @@ -1114,6 +1101,35 @@ where type U = T::ListenerUpgrade; } +// TODO: Seal this. +pub trait TryIntoBehaviour { + type Error; + + fn try_into_behaviour(self) -> Result; +} + +impl TryIntoBehaviour for B +where + B: NetworkBehaviour, +{ + type Error = Infallible; + + fn try_into_behaviour(self) -> Result { + Ok(self) + } +} + +impl TryIntoBehaviour for Result> +where + B: NetworkBehaviour, +{ + type Error = io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? + + fn try_into_behaviour(self) -> Result { + self.map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + } +} + #[cfg(test)] mod tests { use super::*; @@ -1121,16 +1137,15 @@ mod tests { #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] fn tcp() { - let _: libp2p_swarm::Swarm = - SwarmBuilder::with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); } #[test] @@ -1142,17 +1157,16 @@ mod tests { feature = "quic" ))] fn tcp_quic() { - let _: libp2p_swarm::Swarm = - SwarmBuilder::with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_quic() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_quic() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); } #[test] @@ -1171,7 +1185,7 @@ mod tests { relay: libp2p_relay::client::Behaviour, } - let _: libp2p_swarm::Swarm = SwarmBuilder::with_new_identity() + let _ = SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() .with_tls() @@ -1181,11 +1195,9 @@ mod tests { .with_tls() .with_noise() .unwrap() - .with_behaviour(|_, relay| { - Ok(Behaviour { - dummy: libp2p_swarm::dummy::Behaviour, - relay, - }) + .with_behaviour(|_, relay| Behaviour { + dummy: libp2p_swarm::dummy::Behaviour, + relay, }) .unwrap() .build(); @@ -1200,7 +1212,7 @@ mod tests { feature = "dns" ))] fn tcp_dns() { - let _: libp2p_swarm::Swarm = futures::executor::block_on( + let _ = futures::executor::block_on( SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() @@ -1210,7 +1222,7 @@ mod tests { .with_dns(), ) .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .unwrap() .build(); } @@ -1219,19 +1231,18 @@ mod tests { #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] fn tcp_other_transport_other_transport() { - let _: libp2p_swarm::Swarm = - SwarmBuilder::with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); } #[tokio::test] @@ -1244,20 +1255,19 @@ mod tests { feature = "websocket", ))] async fn tcp_websocket() { - let _: libp2p_swarm::Swarm = - SwarmBuilder::with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .with_noise() - .unwrap() - .with_websocket() - .with_tls() - .with_noise() - .await - .unwrap() - .with_behaviour(|_| Ok(libp2p_swarm::dummy::Behaviour)) - .unwrap() - .build(); + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .with_noise() + .unwrap() + .with_websocket() + .with_tls() + .with_noise() + .await + .unwrap() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); } } From 83a55e986eb0b4d0224c3baa8ee9fe6a6ad3d7df Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 26 Aug 2023 10:32:48 +0200 Subject: [PATCH 047/171] Apply global timeout of 10s --- libp2p/src/builder.rs | 80 +++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 382978de144..76cd0c6af1b 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,4 +1,3 @@ -// TODO: Should we have a timeout on transport? // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider making with_other_transport fallible. @@ -373,7 +372,7 @@ impl SwarmBuilder>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_quic() .without_any_other_transports() .without_dns() @@ -431,9 +430,7 @@ impl } // TODO: Not the ideal name. - fn without_any_other_transports( - self, - ) -> SwarmBuilder> { + fn without_any_other_transports(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -481,7 +478,7 @@ impl pub fn with_behaviour>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_any_other_transports() .without_dns() .without_relay() @@ -532,7 +529,6 @@ impl SwarmBuilder> { keypair: self.keypair, phantom: PhantomData, phase: RelayPhase { - // TODO: Timeout needed? transport: self.phase.transport, }, } @@ -544,7 +540,7 @@ impl SwarmBuilder>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_dns() .without_relay() .without_websocket() @@ -601,7 +597,7 @@ impl SwarmBuilder>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_relay() .without_websocket() .with_behaviour(constructor) @@ -792,14 +788,13 @@ impl SwarmBuilder> { impl SwarmBuilder> { - fn without_websocket(self) -> SwarmBuilder> { + fn without_websocket(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, phase: BehaviourPhase { relay_behaviour: self.phase.relay_behaviour, - // TODO: Timeout needed? - transport: self.phase.transport.boxed(), + transport: self.phase.transport, }, } } @@ -813,7 +808,7 @@ impl pub fn with_behaviour>( self, constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } } @@ -824,7 +819,7 @@ impl pub fn with_behaviour>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } } @@ -869,7 +864,10 @@ impl SwarmBuilder Result>, WebsocketError> { + ) -> Result< + SwarmBuilder>, + WebsocketError, + > { self.without_tls().with_noise().await } } @@ -878,7 +876,10 @@ impl SwarmBuilder Result>, WebsocketError> { + ) -> Result< + SwarmBuilder>, + WebsocketError, + > { self.without_tls().with_noise().await } } @@ -905,8 +906,7 @@ macro_rules! construct_behaviour_builder { phase: BehaviourPhase { transport: websocket_transport .or_transport($self.phase.transport) - .map(|either, _| either.into_inner()) - .boxed(), + .map(|either, _| either.into_inner()), relay_behaviour: $self.phase.relay_behaviour, }, }) @@ -925,7 +925,7 @@ macro_rules! impl_websocket_noise_builder { SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, Tls>> { #[cfg(feature = "noise")] - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -945,7 +945,7 @@ macro_rules! impl_websocket_noise_builder { ) ) } - pub async fn without_noise(self) -> Result>, WebsocketError> { + pub async fn without_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -958,7 +958,7 @@ macro_rules! impl_websocket_noise_builder { impl SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> { - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -995,17 +995,17 @@ pub enum WebsocketError { Dns(#[from] io::Error), } -pub struct BehaviourPhase { +pub struct BehaviourPhase { relay_behaviour: R, - transport: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)>, + transport: T, } #[cfg(feature = "relay")] -impl SwarmBuilder> { +impl SwarmBuilder> { pub fn with_behaviour>( self, mut constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { Ok(SwarmBuilder { phase: BuildPhase { behaviour: constructor(&self.keypair, self.phase.relay_behaviour) @@ -1018,11 +1018,11 @@ impl SwarmBuilder SwarmBuilder> { +impl SwarmBuilder> { pub fn with_behaviour>( self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { // Discard `NoRelayBehaviour`. let _ = self.phase.relay_behaviour; @@ -1037,16 +1037,24 @@ impl SwarmBuilder> { } } -pub struct BuildPhase { +pub struct BuildPhase { behaviour: B, - transport: libp2p_core::transport::Boxed<(libp2p_identity::PeerId, StreamMuxerBox)>, + transport: T, } +const CONNECTION_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10); + #[cfg(feature = "async-std")] -impl SwarmBuilder> { +impl + SwarmBuilder> +{ pub fn build(self) -> libp2p_swarm::Swarm { libp2p_swarm::SwarmBuilder::with_async_std_executor( - self.phase.transport, + libp2p_core::transport::timeout::TransportTimeout::new( + self.phase.transport, + CONNECTION_TIMEOUT, + ) + .boxed(), self.phase.behaviour, self.keypair.public().to_peer_id(), ) @@ -1055,10 +1063,16 @@ impl SwarmBuilder> { } #[cfg(feature = "tokio")] -impl SwarmBuilder> { +impl + SwarmBuilder> +{ pub fn build(self) -> libp2p_swarm::Swarm { libp2p_swarm::SwarmBuilder::with_tokio_executor( - self.phase.transport, + libp2p_core::transport::timeout::TransportTimeout::new( + self.phase.transport, + CONNECTION_TIMEOUT, + ) + .boxed(), self.phase.behaviour, self.keypair.public().to_peer_id(), ) From 2b687276f29333719b28f9585354d42c886d91da Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 26 Aug 2023 18:16:57 +0200 Subject: [PATCH 048/171] feat(swarm): add SwarmConfig --- libp2p/src/builder.rs | 98 ++++++++++++++++++-------- swarm/src/lib.rs | 160 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 228 insertions(+), 30 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 76cd0c6af1b..b8783c4582d 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -372,7 +372,7 @@ impl SwarmBuilder>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_quic() .without_any_other_transports() .without_dns() @@ -478,7 +478,7 @@ impl pub fn with_behaviour>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_any_other_transports() .without_dns() .without_relay() @@ -540,7 +540,7 @@ impl SwarmBuilder>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_dns() .without_relay() .without_websocket() @@ -597,7 +597,7 @@ impl SwarmBuilder>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_relay() .without_websocket() .with_behaviour(constructor) @@ -808,7 +808,7 @@ impl pub fn with_behaviour>( self, constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } } @@ -819,7 +819,7 @@ impl pub fn with_behaviour>( self, constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } } @@ -1005,9 +1005,9 @@ impl SwarmBuilder>( self, mut constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { Ok(SwarmBuilder { - phase: BuildPhase { + phase: SwarmPhase { behaviour: constructor(&self.keypair, self.phase.relay_behaviour) .try_into_behaviour()?, transport: self.phase.transport, @@ -1022,12 +1022,12 @@ impl SwarmBuilder> { pub fn with_behaviour>( self, mut constructor: impl FnMut(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { + ) -> Result>, R::Error> { // Discard `NoRelayBehaviour`. let _ = self.phase.relay_behaviour; Ok(SwarmBuilder { - phase: BuildPhase { + phase: SwarmPhase { behaviour: constructor(&self.keypair).try_into_behaviour()?, transport: self.phase.transport, }, @@ -1037,37 +1037,75 @@ impl SwarmBuilder> { } } -pub struct BuildPhase { +pub struct SwarmPhase { behaviour: B, transport: T, } -const CONNECTION_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10); +impl SwarmBuilder> { + pub fn with_swarm_config( + self, + config: libp2p_swarm::SwarmConfig, + ) -> SwarmBuilder> { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: config, + }, + keypair: self.keypair, + phantom: PhantomData, + } + } +} #[cfg(feature = "async-std")] -impl - SwarmBuilder> -{ - pub fn build(self) -> libp2p_swarm::Swarm { - libp2p_swarm::SwarmBuilder::with_async_std_executor( - libp2p_core::transport::timeout::TransportTimeout::new( - self.phase.transport, - CONNECTION_TIMEOUT, - ) - .boxed(), - self.phase.behaviour, - self.keypair.public().to_peer_id(), - ) - .build() +impl SwarmBuilder> { + pub fn build( + self, + ) -> libp2p_swarm::Swarm { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: libp2p_swarm::SwarmConfig::with_async_std_executor(), + }, + keypair: self.keypair, + phantom: PhantomData::, + }.build() } } #[cfg(feature = "tokio")] -impl - SwarmBuilder> +impl SwarmBuilder> { + pub fn build( + self, + ) -> libp2p_swarm::Swarm { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: libp2p_swarm::SwarmConfig::with_tokio_executor(), + }, + keypair: self.keypair, + phantom: PhantomData::, + }.build() + } +} + +pub struct BuildPhase { + behaviour: B, + transport: T, + swarm_config: libp2p_swarm::SwarmConfig, +} + +const CONNECTION_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10); + +impl + SwarmBuilder> { pub fn build(self) -> libp2p_swarm::Swarm { - libp2p_swarm::SwarmBuilder::with_tokio_executor( + libp2p_swarm::Swarm::new_with_config( libp2p_core::transport::timeout::TransportTimeout::new( self.phase.transport, CONNECTION_TIMEOUT, @@ -1075,8 +1113,8 @@ impl .boxed(), self.phase.behaviour, self.keypair.public().to_peer_id(), + self.phase.swarm_config, ) - .build() } } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 867e49410c5..056c254eb54 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -356,6 +356,26 @@ impl Swarm where TBehaviour: NetworkBehaviour, { + /// Creates a new [`Swarm`] from the given [`Transport`], [`NetworkBehaviour`], [`PeerId`] and + /// [`SwarmConfig`]. + pub fn new_with_config( + transport: transport::Boxed<(PeerId, StreamMuxerBox)>, + behaviour: TBehaviour, + local_peer_id: PeerId, + config: SwarmConfig + ) -> Self { + Swarm { + local_peer_id: local_peer_id, + transport: transport, + pool: Pool::new(local_peer_id, config.pool_config), + behaviour: behaviour, + supported_protocols: Default::default(), + confirmed_external_addr: Default::default(), + listened_addrs: HashMap::new(), + pending_event: None, + } + } + /// Returns information about the connections underlying the [`Swarm`]. pub fn network_info(&self) -> NetworkInfo { let num_peers = self.pool.num_peers(); @@ -1343,7 +1363,146 @@ impl<'a> PollParameters for SwarmPollParameters<'a> { } } +pub struct SwarmConfig { + pool_config: PoolConfig, +} + +impl SwarmConfig +{ + /// Creates a new [`SwarmConfig`] from the given executor. The [`Swarm`] is obtained via + /// [`Swarm::new_from_config`]. + pub fn with_executor( + executor: impl Executor + Send + 'static, + ) -> Self { + Self { + pool_config: PoolConfig::new(Some(Box::new(executor))), + } + } + + /// Sets executor to the `wasm` executor. + /// Background tasks will be executed by the browser on the next micro-tick. + /// + /// Spawning a task is similar too: + /// ```typescript + /// function spawn(task: () => Promise) { + /// task() + /// } + /// ``` + #[cfg(feature = "wasm-bindgen")] + pub fn with_wasm_executor( + ) -> Self { + Self::with_executor( + crate::executor::WasmBindgenExecutor, + ) + } + + /// Builds a new [`SwarmConfig`] from the given `tokio` executor. + #[cfg(all( + feature = "tokio", + not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")) + ))] + pub fn with_tokio_executor( + ) -> Self { + Self::with_executor( + crate::executor::TokioExecutor, + ) + } + + /// Builds a new [`SwarmConfig`] from the given `async-std` executor. + #[cfg(all( + feature = "async-std", + not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")) + ))] + pub fn with_async_std_executor( + ) -> Self { + Self::with_executor( + crate::executor::AsyncStdExecutor, + ) + } + + // TODO: Should we remove this from `SwarmConfig`?! + // + /// Creates a new [`SwarmConfig`]. + /// + /// ## ⚠️ Performance warning + /// All connections will be polled on the current task, thus quite bad performance + /// characteristics should be expected. Whenever possible use an executor and + /// [`SwarmConfig::with_executor`]. + pub fn without_executor( + ) -> Self { + Self { + pool_config: PoolConfig::new(None), + } + } + + /// Configures the number of events from the [`NetworkBehaviour`] in + /// destination to the [`ConnectionHandler`] that can be buffered before + /// the [`Swarm`] has to wait. An individual buffer with this number of + /// events exists for each individual connection. + /// + /// The ideal value depends on the executor used, the CPU speed, and the + /// volume of events. If this value is too low, then the [`Swarm`] will + /// be sleeping more often than necessary. Increasing this value increases + /// the overall memory usage. + pub fn notify_handler_buffer_size(mut self, n: NonZeroUsize) -> Self { + self.pool_config = self.pool_config.with_notify_handler_buffer_size(n); + self + } + + /// Configures the size of the buffer for events sent by a [`ConnectionHandler`] to the + /// [`NetworkBehaviour`]. + /// + /// Each connection has its own buffer. + /// + /// The ideal value depends on the executor used, the CPU speed and the volume of events. + /// If this value is too low, then the [`ConnectionHandler`]s will be sleeping more often + /// than necessary. Increasing this value increases the overall memory + /// usage, and more importantly the latency between the moment when an + /// event is emitted and the moment when it is received by the + /// [`NetworkBehaviour`]. + pub fn per_connection_event_buffer_size(mut self, n: usize) -> Self { + self.pool_config = self.pool_config.with_per_connection_event_buffer_size(n); + self + } + + /// Number of addresses concurrently dialed for a single outbound connection attempt. + pub fn dial_concurrency_factor(mut self, factor: NonZeroU8) -> Self { + self.pool_config = self.pool_config.with_dial_concurrency_factor(factor); + self + } + + /// Configures an override for the substream upgrade protocol to use. + /// + /// The subtream upgrade protocol is the multistream-select protocol + /// used for protocol negotiation on substreams. Since a listener + /// supports all existing versions, the choice of upgrade protocol + /// only effects the "dialer", i.e. the peer opening a substream. + /// + /// > **Note**: If configured, specific upgrade protocols for + /// > individual [`SubstreamProtocol`]s emitted by the `NetworkBehaviour` + /// > are ignored. + pub fn substream_upgrade_protocol_override(mut self, v: libp2p_core::upgrade::Version) -> Self { + self.pool_config = self.pool_config.with_substream_upgrade_protocol_override(v); + self + } + + /// The maximum number of inbound streams concurrently negotiating on a + /// connection. New inbound streams exceeding the limit are dropped and thus + /// reset. + /// + /// Note: This only enforces a limit on the number of concurrently + /// negotiating inbound streams. The total number of inbound streams on a + /// connection is the sum of negotiating and negotiated streams. A limit on + /// the total number of streams can be enforced at the + /// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level. + pub fn max_negotiating_inbound_streams(mut self, v: usize) -> Self { + self.pool_config = self.pool_config.with_max_negotiating_inbound_streams(v); + self + } +} + /// A [`SwarmBuilder`] provides an API for configuring and constructing a [`Swarm`]. +#[deprecated(note = "Use the new `libp2p::SwarmBuilder` instead of `libp2p::swarm::SwarmBuilder` or create a `Swarm` directly via `Swarm::new_with_config`.")] pub struct SwarmBuilder { local_peer_id: PeerId, transport: transport::Boxed<(PeerId, StreamMuxerBox)>, @@ -1351,6 +1510,7 @@ pub struct SwarmBuilder { pool_config: PoolConfig, } +#[allow(deprecated)] impl SwarmBuilder where TBehaviour: NetworkBehaviour, From 4ad2a0e427fec8269163fef52e6ed3a480cef8a0 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 13:02:21 +0200 Subject: [PATCH 049/171] Make `without_noise` on `TcpNoisePhase` private --- libp2p/src/builder.rs | 136 +++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 48 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index b8783c4582d..98b35e95603 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -63,12 +63,12 @@ impl SwarmBuilder { pub fn with_tcp_config( self, - config: libp2p_tcp::Config, + tcp_config: libp2p_tcp::Config, ) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, - phase: TcpTlsPhase { config }, + phase: TcpTlsPhase { tcp_config }, } } } @@ -121,21 +121,25 @@ impl SwarmBuilder { #[cfg(feature = "tcp")] pub struct TcpTlsPhase { - config: libp2p_tcp::Config, + tcp_config: libp2p_tcp::Config, } #[cfg(feature = "tcp")] impl SwarmBuilder { #[cfg(feature = "tls")] - pub fn with_tls(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, + pub fn with_tls( + self, + ) -> Result>, AuthenticationError> + { + Ok(SwarmBuilder { phase: TcpNoisePhase { - config: self.phase.config, + tcp_config: self.phase.tcp_config, + tls_config: libp2p_tls::Config::new(&self.keypair)?, phantom: PhantomData, }, - } + keypair: self.keypair, + phantom: PhantomData, + }) } fn without_tls(self) -> SwarmBuilder> { @@ -143,7 +147,8 @@ impl SwarmBuilder { keypair: self.keypair, phantom: PhantomData, phase: TcpNoisePhase { - config: self.phase.config, + tcp_config: self.phase.tcp_config, + tls_config: WithoutTls {}, phantom: PhantomData, }, } @@ -178,16 +183,17 @@ impl SwarmBuilder { #[cfg(feature = "tcp")] pub struct TcpNoisePhase { - config: libp2p_tcp::Config, + tcp_config: libp2p_tcp::Config, + tls_config: A, phantom: PhantomData, } #[cfg(feature = "tcp")] macro_rules! construct_quic_builder { ($self:ident, $tcp:ident, $auth:expr) => { - Ok(SwarmBuilder { + SwarmBuilder { phase: QuicPhase { - transport: libp2p_tcp::$tcp::Transport::new($self.phase.config) + transport: libp2p_tcp::$tcp::Transport::new($self.phase.tcp_config) .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate($auth) .multiplex(libp2p_yamux::Config::default()) @@ -195,14 +201,14 @@ macro_rules! construct_quic_builder { }, keypair: $self.keypair, phantom: PhantomData, - }) + } }; } macro_rules! impl_tcp_noise_builder { ($providerKebabCase:literal, $providerCamelCase:ident, $tcp:ident) => { #[cfg(all(feature = $providerKebabCase, feature = "tcp", feature = "tls"))] - impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { + impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( self, @@ -210,12 +216,12 @@ macro_rules! impl_tcp_noise_builder { SwarmBuilder<$providerCamelCase, QuicPhase>, AuthenticationError, > { - construct_quic_builder!( + Ok(construct_quic_builder!( self, $tcp, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair)?, + self.phase.tls_config, libp2p_noise::Config::new(&self.keypair)?, ), |upgrade| match upgrade { @@ -227,16 +233,14 @@ macro_rules! impl_tcp_noise_builder { } }, ) - ) + )) } - pub fn without_noise( + fn without_noise( self, - ) -> Result< - SwarmBuilder<$providerCamelCase, QuicPhase>, - AuthenticationError, - > { - construct_quic_builder!(self, $tcp, libp2p_tls::Config::new(&self.keypair)?) + ) -> SwarmBuilder<$providerCamelCase, QuicPhase> + { + construct_quic_builder!(self, $tcp, self.phase.tls_config) } } @@ -249,7 +253,11 @@ macro_rules! impl_tcp_noise_builder { SwarmBuilder<$providerCamelCase, QuicPhase>, AuthenticationError, > { - construct_quic_builder!(self, $tcp, libp2p_noise::Config::new(&self.keypair)?) + Ok(construct_quic_builder!( + self, + $tcp, + libp2p_noise::Config::new(&self.keypair)? + )) } } }; @@ -258,10 +266,7 @@ macro_rules! impl_tcp_noise_builder { impl_tcp_noise_builder!("async-std", AsyncStd, async_io); impl_tcp_noise_builder!("tokio", Tokio, tokio); -#[cfg(feature = "tls")] -pub enum Tls {} - -pub enum WithoutTls {} +pub struct WithoutTls {} #[derive(Debug, thiserror::Error)] pub enum AuthenticationError { @@ -273,6 +278,24 @@ pub enum AuthenticationError { Noise(#[from] libp2p_noise::Error), } +// Shortcuts +#[cfg(all(feature = "quic", feature = "async-std"))] +impl SwarmBuilder> { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + self.without_noise().with_quic() + } +} +#[cfg(all(feature = "quic", feature = "tokio"))] +impl SwarmBuilder> { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + self.without_noise().with_quic() + } +} + pub struct QuicPhase { transport: T, } @@ -612,7 +635,7 @@ pub struct RelayTlsPhase { #[cfg(feature = "relay")] impl SwarmBuilder> { #[cfg(feature = "tls")] - pub fn with_tls(self) -> SwarmBuilder> { + pub fn with_tls(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -704,7 +727,7 @@ macro_rules! construct_websocket_builder { #[cfg(all(feature = "relay", feature = "tls"))] impl - SwarmBuilder> + SwarmBuilder> { #[cfg(feature = "noise")] pub fn with_noise( @@ -833,16 +856,22 @@ pub struct WebsocketTlsPhase { #[cfg(feature = "websocket")] impl SwarmBuilder> { #[cfg(feature = "tls")] - pub fn with_tls(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, + pub fn with_tls( + self, + ) -> Result< + SwarmBuilder>, + AuthenticationError, + > { + Ok(SwarmBuilder { phase: WebsocketNoisePhase { + tls_config: libp2p_tls::Config::new(&self.keypair)?, relay_behaviour: self.phase.relay_behaviour, transport: self.phase.transport, phantom: PhantomData, }, - } + keypair: self.keypair, + phantom: PhantomData, + }) } fn without_tls(self) -> SwarmBuilder> { @@ -850,6 +879,7 @@ impl SwarmBuilder> { keypair: self.keypair, phantom: PhantomData, phase: WebsocketNoisePhase { + tls_config: WithoutTls {}, relay_behaviour: self.phase.relay_behaviour, transport: self.phase.transport, phantom: PhantomData, @@ -886,6 +916,7 @@ impl SwarmBuilder { + tls_config: A, transport: T, relay_behaviour: R, phantom: PhantomData, @@ -922,7 +953,7 @@ macro_rules! impl_websocket_noise_builder { feature = "tls" ))] impl - SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, Tls>> + SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, libp2p_tls::Config>> { #[cfg(feature = "noise")] pub async fn with_noise(self) -> Result>, WebsocketError> { @@ -931,7 +962,7 @@ macro_rules! impl_websocket_noise_builder { $dnsTcp, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair).map_err(Into::::into)?, + self.phase.tls_config, libp2p_noise::Config::new(&self.keypair).map_err(Into::::into)?, ), |upgrade| match upgrade { @@ -1060,10 +1091,10 @@ impl SwarmBuilder> { } #[cfg(feature = "async-std")] -impl SwarmBuilder> { - pub fn build( - self, - ) -> libp2p_swarm::Swarm { +impl + SwarmBuilder> +{ + pub fn build(self) -> libp2p_swarm::Swarm { SwarmBuilder { phase: BuildPhase { behaviour: self.phase.behaviour, @@ -1072,15 +1103,16 @@ impl SwarmBuilder, - }.build() + } + .build() } } #[cfg(feature = "tokio")] -impl SwarmBuilder> { - pub fn build( - self, - ) -> libp2p_swarm::Swarm { +impl + SwarmBuilder> +{ + pub fn build(self) -> libp2p_swarm::Swarm { SwarmBuilder { phase: BuildPhase { behaviour: self.phase.behaviour, @@ -1089,7 +1121,8 @@ impl SwarmBuilder, - }.build() + } + .build() } } @@ -1193,6 +1226,7 @@ mod tests { .with_tokio() .with_tcp() .with_tls() + .unwrap() .with_noise() .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) @@ -1213,6 +1247,7 @@ mod tests { .with_tokio() .with_tcp() .with_tls() + .unwrap() .with_noise() .unwrap() .with_quic() @@ -1241,6 +1276,7 @@ mod tests { .with_tokio() .with_tcp() .with_tls() + .unwrap() .with_noise() .unwrap() .with_relay() @@ -1269,6 +1305,7 @@ mod tests { .with_tokio() .with_tcp() .with_tls() + .unwrap() .with_noise() .unwrap() .with_dns(), @@ -1287,6 +1324,7 @@ mod tests { .with_tokio() .with_tcp() .with_tls() + .unwrap() .with_noise() .unwrap() .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) @@ -1311,10 +1349,12 @@ mod tests { .with_tokio() .with_tcp() .with_tls() + .unwrap() .with_noise() .unwrap() .with_websocket() .with_tls() + .unwrap() .with_noise() .await .unwrap() From c289ccc3a61d1f8d4188eb11304da922ce1e6f61 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 13:30:27 +0200 Subject: [PATCH 050/171] Move pub use down --- libp2p/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index a3c41ed3ed6..5b5ced34cd2 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -143,7 +143,6 @@ pub use libp2p_webtransport_websys as webtransport_websys; pub use libp2p_yamux as yamux; mod builder; -pub use builder::SwarmBuilder; mod transport_ext; @@ -157,6 +156,7 @@ pub use self::core::{ upgrade::{InboundUpgrade, OutboundUpgrade}, Transport, }; +pub use self::builder::SwarmBuilder; pub use self::multiaddr::{multiaddr as build_multiaddr, Multiaddr}; pub use self::swarm::Swarm; pub use self::transport_ext::TransportExt; @@ -164,6 +164,7 @@ pub use libp2p_identity as identity; pub use libp2p_identity::PeerId; pub use libp2p_swarm::{Stream, StreamProtocol}; +// TODO: deprecate /// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p: /// /// * DNS resolution. @@ -209,6 +210,7 @@ pub async fn development_transport( .boxed()) } +// TODO: deprecate /// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p: /// /// * DNS resolution. From fb8f4b7f2745a8eb1d35a6127af1012aca912d51 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 13:32:04 +0200 Subject: [PATCH 051/171] Deprecate development_transport --- libp2p/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 5b5ced34cd2..0d2140af7d1 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -164,7 +164,6 @@ pub use libp2p_identity as identity; pub use libp2p_identity::PeerId; pub use libp2p_swarm::{Stream, StreamProtocol}; -// TODO: deprecate /// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p: /// /// * DNS resolution. @@ -176,6 +175,7 @@ pub use libp2p_swarm::{Stream, StreamProtocol}; /// /// > **Note**: This `Transport` is not suitable for production usage, as its implementation /// > reserves the right to support additional protocols or remove deprecated protocols. +#[deprecated(note = "Use `libp2p::SwarmBuilder` instead.")] #[cfg(all( not(target_arch = "wasm32"), feature = "tcp", @@ -210,7 +210,6 @@ pub async fn development_transport( .boxed()) } -// TODO: deprecate /// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p: /// /// * DNS resolution. @@ -222,6 +221,7 @@ pub async fn development_transport( /// /// > **Note**: This `Transport` is not suitable for production usage, as its implementation /// > reserves the right to support additional protocols or remove deprecated protocols. +#[deprecated(note = "Use `libp2p::SwarmBuilder` instead.")] #[cfg(all( not(target_arch = "wasm32"), feature = "tcp", From 46a8bd982a2ea6685eee05310796f4c80845b02d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 13:47:12 +0200 Subject: [PATCH 052/171] Wrap errors --- libp2p/src/builder.rs | 60 +++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 98b35e95603..565e5c96600 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -134,7 +134,8 @@ impl SwarmBuilder { Ok(SwarmBuilder { phase: TcpNoisePhase { tcp_config: self.phase.tcp_config, - tls_config: libp2p_tls::Config::new(&self.keypair)?, + tls_config: libp2p_tls::Config::new(&self.keypair) + .map_err(|e| AuthenticationError(e.into()))?, phantom: PhantomData, }, keypair: self.keypair, @@ -222,7 +223,8 @@ macro_rules! impl_tcp_noise_builder { libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, - libp2p_noise::Config::new(&self.keypair)?, + libp2p_noise::Config::new(&self.keypair) + .map_err(|e| AuthenticationError(e.into()))?, ), |upgrade| match upgrade { futures::future::Either::Left((peer_id, upgrade)) => { @@ -256,7 +258,8 @@ macro_rules! impl_tcp_noise_builder { Ok(construct_quic_builder!( self, $tcp, - libp2p_noise::Config::new(&self.keypair)? + libp2p_noise::Config::new(&self.keypair) + .map_err(|e| AuthenticationError(e.into()))? )) } } @@ -269,7 +272,11 @@ impl_tcp_noise_builder!("tokio", Tokio, tokio); pub struct WithoutTls {} #[derive(Debug, thiserror::Error)] -pub enum AuthenticationError { +#[error(transparent)] +pub struct AuthenticationError(AuthenticationErrorInner); + +#[derive(Debug, thiserror::Error)] +enum AuthenticationErrorInner { #[error("Tls")] #[cfg(feature = "tls")] Tls(#[from] libp2p_tls::certificate::GenError), @@ -743,8 +750,10 @@ impl self, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair)?, - libp2p_noise::Config::new(&self.keypair)?, + libp2p_tls::Config::new(&self.keypair) + .map_err(|e| AuthenticationError(e.into()))?, + libp2p_noise::Config::new(&self.keypair) + .map_err(|e| AuthenticationError(e.into()))?, ), |upgrade| match upgrade { futures::future::Either::Left((peer_id, upgrade)) => { @@ -758,6 +767,7 @@ impl ) } + // TODO: construct tls in previous phase. pub fn without_noise( self, ) -> Result< @@ -767,7 +777,10 @@ impl >, AuthenticationError, > { - construct_websocket_builder!(self, libp2p_tls::Config::new(&self.keypair)?) + construct_websocket_builder!( + self, + libp2p_tls::Config::new(&self.keypair).map_err(|e| AuthenticationError(e.into()))? + ) } } @@ -785,7 +798,10 @@ impl >, AuthenticationError, > { - construct_websocket_builder!(self, libp2p_noise::Config::new(&self.keypair)?) + construct_websocket_builder!( + self, + libp2p_noise::Config::new(&self.keypair).map_err(|e| AuthenticationError(e.into()))? + ) } } @@ -864,7 +880,8 @@ impl SwarmBuilder> { > { Ok(SwarmBuilder { phase: WebsocketNoisePhase { - tls_config: libp2p_tls::Config::new(&self.keypair)?, + tls_config: libp2p_tls::Config::new(&self.keypair) + .map_err(|e| AuthenticationError(e.into()))?, relay_behaviour: self.phase.relay_behaviour, transport: self.phase.transport, phantom: PhantomData, @@ -925,11 +942,12 @@ pub struct WebsocketNoisePhase { #[cfg(feature = "websocket")] macro_rules! construct_behaviour_builder { ($self:ident, $dnsTcp:expr, $auth:expr) => {{ - let websocket_transport = libp2p_websocket::WsConfig::new($dnsTcp.await?) - .upgrade(libp2p_core::upgrade::Version::V1) - .authenticate($auth) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))); + let websocket_transport = + libp2p_websocket::WsConfig::new($dnsTcp.await.map_err(|e| WebsocketError(e.into()))?) + .upgrade(libp2p_core::upgrade::Version::V1) + .authenticate($auth) + .multiplex(libp2p_yamux::Config::default()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))); Ok(SwarmBuilder { keypair: $self.keypair, @@ -963,7 +981,7 @@ macro_rules! impl_websocket_noise_builder { libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, - libp2p_noise::Config::new(&self.keypair).map_err(Into::::into)?, + libp2p_noise::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))?, ), |upgrade| match upgrade { futures::future::Either::Left((peer_id, upgrade)) => { @@ -980,7 +998,7 @@ macro_rules! impl_websocket_noise_builder { construct_behaviour_builder!( self, $dnsTcp, - libp2p_tls::Config::new(&self.keypair).map_err(Into::::into)? + libp2p_tls::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))? ) } } @@ -993,7 +1011,7 @@ macro_rules! impl_websocket_noise_builder { construct_behaviour_builder!( self, $dnsTcp, - libp2p_noise::Config::new(&self.keypair).map_err(Into::::into)? + libp2p_noise::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))? ) } } @@ -1017,10 +1035,14 @@ impl_websocket_noise_builder!( ); #[derive(Debug, thiserror::Error)] -pub enum WebsocketError { +#[error(transparent)] +pub struct WebsocketError(WebsocketErrorInner); + +#[derive(Debug, thiserror::Error)] +enum WebsocketErrorInner { #[error("Dns")] #[cfg(any(feature = "tls", feature = "noise"))] - Authentication(#[from] AuthenticationError), + Authentication(#[from] AuthenticationErrorInner), #[cfg(feature = "dns")] #[error("Dns")] Dns(#[from] io::Error), From 3dfb915e0a84f1c54a4c6dfb269165ff37721397 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 14:04:46 +0200 Subject: [PATCH 053/171] Make RelayNoisePhase without_noise private --- libp2p/src/builder.rs | 80 +++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 29 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 565e5c96600..dfc6f665ad0 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,5 +1,6 @@ // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider making with_other_transport fallible. +// TODO: Are all with_behaviour with Relay behaviour properly set? use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::NetworkBehaviour; @@ -613,6 +614,7 @@ impl SwarmBuilder> { } // Shortcuts +#[cfg(feature = "relay")] impl SwarmBuilder> { #[cfg(feature = "websocket")] pub fn with_websocket( @@ -642,15 +644,19 @@ pub struct RelayTlsPhase { #[cfg(feature = "relay")] impl SwarmBuilder> { #[cfg(feature = "tls")] - pub fn with_tls(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, + pub fn with_tls( + self, + ) -> Result>, AuthenticationError> + { + Ok(SwarmBuilder { phase: RelayNoisePhase { + tls_config: libp2p_tls::Config::new(&self.keypair) + .map_err(|e| AuthenticationError(e.into()))?, transport: self.phase.transport, - phantom: PhantomData, }, - } + keypair: self.keypair, + phantom: PhantomData, + }) } fn without_tls(self) -> SwarmBuilder> { @@ -658,9 +664,8 @@ impl SwarmBuilder> { keypair: self.keypair, phantom: PhantomData, phase: RelayNoisePhase { + tls_config: WithoutTls {}, transport: self.phase.transport, - - phantom: PhantomData, }, } } @@ -700,8 +705,8 @@ impl SwarmBuilder> #[cfg(feature = "relay")] pub struct RelayNoisePhase { + tls_config: A, transport: T, - phantom: PhantomData, } // TODO: Rename these macros to phase not builder. All. @@ -711,7 +716,7 @@ macro_rules! construct_websocket_builder { let (relay_transport, relay_behaviour) = libp2p_relay::client::new($self.keypair.public().to_peer_id()); - Ok(SwarmBuilder { + SwarmBuilder { phase: WebsocketPhase { relay_behaviour, transport: $self @@ -728,7 +733,7 @@ macro_rules! construct_websocket_builder { }, keypair: $self.keypair, phantom: PhantomData, - }) + } }}; } @@ -746,12 +751,11 @@ impl >, AuthenticationError, > { - construct_websocket_builder!( + Ok(construct_websocket_builder!( self, libp2p_core::upgrade::Map::new( libp2p_core::upgrade::SelectUpgrade::new( - libp2p_tls::Config::new(&self.keypair) - .map_err(|e| AuthenticationError(e.into()))?, + self.phase.tls_config, libp2p_noise::Config::new(&self.keypair) .map_err(|e| AuthenticationError(e.into()))?, ), @@ -764,23 +768,16 @@ impl } }, ) - ) + )) } - // TODO: construct tls in previous phase. - pub fn without_noise( + fn without_noise( self, - ) -> Result< - SwarmBuilder< - Provider, - WebsocketPhase, - >, - AuthenticationError, + ) -> SwarmBuilder< + Provider, + WebsocketPhase, > { - construct_websocket_builder!( - self, - libp2p_tls::Config::new(&self.keypair).map_err(|e| AuthenticationError(e.into()))? - ) + construct_websocket_builder!(self, self.phase.tls_config) } } @@ -798,10 +795,34 @@ impl >, AuthenticationError, > { - construct_websocket_builder!( + Ok(construct_websocket_builder!( self, libp2p_noise::Config::new(&self.keypair).map_err(|e| AuthenticationError(e.into()))? - ) + )) + } +} + +// Shortcuts +impl + SwarmBuilder> +{ + #[cfg(feature = "websocket")] + pub fn with_websocket( + self, + ) -> SwarmBuilder< + Provider, + WebsocketTlsPhase, + > { + self.without_noise().with_websocket() + } + + pub fn with_behaviour>( + self, + constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + ) -> Result>, R::Error> { + self.without_noise() + .without_websocket() + .with_behaviour(constructor) } } @@ -1303,6 +1324,7 @@ mod tests { .unwrap() .with_relay() .with_tls() + .unwrap() .with_noise() .unwrap() .with_behaviour(|_, relay| Behaviour { From 9f2aa7f2700c651a0ebe790e816460d66f7b3cf6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 16:37:26 +0200 Subject: [PATCH 054/171] Add example showcasing all features --- libp2p/src/builder.rs | 94 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index dfc6f665ad0..c551c3dfb41 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -8,6 +8,50 @@ use std::convert::Infallible; use std::io; use std::marker::PhantomData; +/// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. +/// +/// ``` +/// # use libp2p::{swarm::NetworkBehaviour, SwarmBuilder}; +/// # use std::error::Error; +/// # +/// # #[cfg(all( +/// # feature = "tokio", +/// # feature = "tcp", +/// # feature = "tls", +/// # feature = "noise", +/// # feature = "quic", +/// # feature = "dns", +/// # feature = "relay", +/// # feature = "websocket", +/// # ))] +/// # async fn build_swarm() -> Result<(), Box> { +/// # #[derive(NetworkBehaviour)] +/// # #[behaviour(prelude = "libp2p_swarm::derive_prelude")] +/// # struct MyBehaviour { +/// # relay: libp2p_relay::client::Behaviour, +/// # } +/// +/// let swarm = SwarmBuilder::with_new_identity() +/// .with_tokio() +/// .with_tcp() +/// .with_tls()? +/// .with_noise()? +/// .with_quic() +/// .with_dns() +/// .await? +/// .with_relay() +/// .with_tls()? +/// .with_noise()? +/// .with_websocket() +/// .with_tls()? +/// .with_noise() +/// .await? +/// .with_behaviour(|_key, relay| MyBehaviour { relay })? +/// .build(); +/// # +/// # Ok(()) +/// # } +/// ``` pub struct SwarmBuilder { keypair: libp2p_identity::Keypair, phantom: PhantomData, @@ -819,7 +863,10 @@ impl pub fn with_behaviour>( self, constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { + ) -> Result< + SwarmBuilder>, + R::Error, + > { self.without_noise() .without_websocket() .with_behaviour(constructor) @@ -1406,4 +1453,49 @@ mod tests { .unwrap() .build(); } + + #[tokio::test] + #[cfg(all( + feature = "tokio", + feature = "tcp", + feature = "tls", + feature = "noise", + feature = "quic", + feature = "dns", + feature = "relay", + feature = "websocket", + ))] + async fn all() { + #[derive(NetworkBehaviour)] + #[behaviour(prelude = "libp2p_swarm::derive_prelude")] + struct MyBehaviour { + relay: libp2p_relay::client::Behaviour, + } + + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .unwrap() + .with_noise() + .unwrap() + .with_quic() + .with_dns() + .await + .unwrap() + .with_relay() + .with_tls() + .unwrap() + .with_noise() + .unwrap() + .with_websocket() + .with_tls() + .unwrap() + .with_noise() + .await + .unwrap() + .with_behaviour(|_key, relay| MyBehaviour { relay }) + .unwrap() + .build(); + } } From e3ec84bb7c48d7095f6134a5fa382aa884d885c2 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 17:05:15 +0200 Subject: [PATCH 055/171] Add with_quic_config --- libp2p/src/builder.rs | 100 +++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index c551c3dfb41..3625d40ea64 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,6 +1,7 @@ // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider making with_other_transport fallible. // TODO: Are all with_behaviour with Relay behaviour properly set? +// TODO: replace FnMut with FnOnce use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::NetworkBehaviour; @@ -89,7 +90,7 @@ impl SwarmBuilder { } #[cfg(feature = "tokio")] - pub fn with_tokio(self) -> SwarmBuilder { + pub fn with_tokio(self) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, @@ -300,6 +301,7 @@ macro_rules! impl_tcp_noise_builder { SwarmBuilder<$providerCamelCase, QuicPhase>, AuthenticationError, > { + let _ = self.phase.tls_config; Ok(construct_quic_builder!( self, $tcp, @@ -331,7 +333,7 @@ enum AuthenticationErrorInner { } // Shortcuts -#[cfg(all(feature = "quic", feature = "async-std"))] +#[cfg(all(feature = "tls", feature = "quic", feature = "async-std"))] impl SwarmBuilder> { pub fn with_quic( self, @@ -339,7 +341,7 @@ impl SwarmBuilder> { self.without_noise().with_quic() } } -#[cfg(all(feature = "quic", feature = "tokio"))] +#[cfg(all(feature = "tls", feature = "quic", feature = "tokio"))] impl SwarmBuilder> { pub fn with_quic( self, @@ -352,52 +354,50 @@ pub struct QuicPhase { transport: T, } -#[cfg(all(feature = "quic", feature = "async-std"))] -impl SwarmBuilder> { - pub fn with_quic( - self, - ) -> SwarmBuilder> { + +#[cfg(feature = "quic")] +macro_rules! construct_other_transport_builder { + ($self:ident, $quic:ident, $config:expr) => { SwarmBuilder { - phase: OtherTransportPhase { - transport: self + phase: OtherTransportPhase{ + transport: $self .phase .transport .or_transport( - libp2p_quic::async_std::Transport::new(libp2p_quic::Config::new( - &self.keypair, - )) + libp2p_quic::$quic::Transport::new($config) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), ) .map(|either, _| either.into_inner()), }, - keypair: self.keypair, + keypair: $self.keypair, phantom: PhantomData, } - } + }; } -#[cfg(all(feature = "quic", feature = "tokio"))] -impl SwarmBuilder> { - pub fn with_quic( - self, - ) -> SwarmBuilder> { - SwarmBuilder { - phase: OtherTransportPhase { - transport: self - .phase - .transport - .or_transport( - libp2p_quic::tokio::Transport::new(libp2p_quic::Config::new(&self.keypair)) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), - ) - .map(|either, _| either.into_inner()), - }, - keypair: self.keypair, - phantom: PhantomData, +macro_rules! impl_quic_builder { + ($providerKebabCase:literal, $providerCamelCase:ident, $quic:ident) => { + #[cfg(all(feature = "quic", feature = $providerKebabCase))] + impl SwarmBuilder<$providerCamelCase, QuicPhase> { + pub fn with_quic( + self, + ) -> SwarmBuilder<$providerCamelCase, OtherTransportPhase> { + self.with_quic_config(|key| libp2p_quic::Config::new(&key)) + } + + pub fn with_quic_config( + self, + mut constructor: impl FnMut(&libp2p_identity::Keypair) -> libp2p_quic::Config, + ) -> SwarmBuilder<$providerCamelCase, OtherTransportPhase> { + construct_other_transport_builder!(self, $quic, constructor(&self.keypair)) + } } } } +impl_quic_builder!("async-std", AsyncStd, async_std); +impl_quic_builder!("tokio", Tokio, tokio); + impl SwarmBuilder> { fn without_quic(self) -> SwarmBuilder> { SwarmBuilder { @@ -839,6 +839,8 @@ impl >, AuthenticationError, > { + let _ = self.phase.tls_config; + Ok(construct_websocket_builder!( self, libp2p_noise::Config::new(&self.keypair).map_err(|e| AuthenticationError(e.into()))? @@ -847,6 +849,7 @@ impl } // Shortcuts +#[cfg(feature = "tls")] impl SwarmBuilder> { @@ -1382,7 +1385,7 @@ mod tests { .build(); } - #[test] + #[tokio::test] #[cfg(all( feature = "tokio", feature = "tcp", @@ -1390,21 +1393,19 @@ mod tests { feature = "noise", feature = "dns" ))] - fn tcp_dns() { - let _ = futures::executor::block_on( - SwarmBuilder::with_new_identity() - .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() - .unwrap() - .with_dns(), - ) - .unwrap() - .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) - .unwrap() - .build(); + async fn tcp_dns() { + SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls() + .unwrap() + .with_noise() + .unwrap() + .with_dns() + .unwrap() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); } /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. QUIC or WebRTC. @@ -1481,7 +1482,6 @@ mod tests { .unwrap() .with_quic() .with_dns() - .await .unwrap() .with_relay() .with_tls() From 4c20f83d62c7993081954c37cf16289bbbdad2ec Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 17:09:02 +0200 Subject: [PATCH 056/171] refactor(misc/server): use new SwarmBuilder --- misc/server/src/main.rs | 54 +++++++++++------------------------------ 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/misc/server/src/main.rs b/misc/server/src/main.rs index c2dff1f9228..f644599cc43 100644 --- a/misc/server/src/main.rs +++ b/misc/server/src/main.rs @@ -1,28 +1,20 @@ use base64::Engine; use clap::Parser; use futures::executor::block_on; -use futures::future::Either; use futures::stream::StreamExt; use futures_timer::Delay; -use libp2p::core::muxing::StreamMuxerBox; -use libp2p::core::upgrade; -use libp2p::dns; use libp2p::identify; use libp2p::identity; use libp2p::identity::PeerId; use libp2p::kad; use libp2p::metrics::{Metrics, Recorder}; -use libp2p::noise; -use libp2p::quic; -use libp2p::swarm::{SwarmBuilder, SwarmEvent}; +use libp2p::swarm::{SwarmEvent}; use libp2p::tcp; -use libp2p::yamux; -use libp2p::Transport; +use libp2p::quic; use log::{debug, info}; use prometheus_client::metrics::info::Info; use prometheus_client::registry::Registry; use std::error::Error; -use std::io; use std::path::PathBuf; use std::str::FromStr; use std::task::Poll; @@ -81,38 +73,20 @@ async fn main() -> Result<(), Box> { }; println!("Local peer id: {local_peer_id}"); - let transport = { - let tcp_transport = - tcp::tokio::Transport::new(tcp::Config::new().port_reuse(true).nodelay(true)) - .upgrade(upgrade::Version::V1) - .authenticate(noise::Config::new(&local_keypair)?) - .multiplex(yamux::Config::default()) - .timeout(Duration::from_secs(20)); - - let quic_transport = { - let mut config = quic::Config::new(&local_keypair); + let mut swarm = libp2p::SwarmBuilder::with_existing_identity(local_keypair) + .with_tokio() + .with_tcp_config(tcp::Config::new().port_reuse(true).nodelay(true)) + .with_noise()? + .with_quic_config(|key| { + let mut config = quic::Config::new(key); config.support_draft_29 = true; - quic::tokio::Transport::new(config) - }; - - dns::TokioDnsConfig::system(libp2p::core::transport::OrTransport::new( - quic_transport, - tcp_transport, - ))? - .map(|either_output, _| match either_output { - Either::Left((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), - Either::Right((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)), + config }) - .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) - .boxed() - }; - - let behaviour = behaviour::Behaviour::new( - local_keypair.public(), - opt.enable_kademlia, - opt.enable_autonat, - ); - let mut swarm = SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id).build(); + .with_dns()? + .with_behaviour(|key| { + behaviour::Behaviour::new(key.public(), opt.enable_kademlia, opt.enable_autonat) + })? + .build(); if config.addresses.swarm.is_empty() { log::warn!("No listen addresses configured."); From 19c401d8be4e2c54609d2582f512a8153b00733d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 17:11:53 +0200 Subject: [PATCH 057/171] Use FnOnce instead of FnMut --- libp2p/src/builder.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 3625d40ea64..b899f69080a 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,7 +1,6 @@ // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider making with_other_transport fallible. // TODO: Are all with_behaviour with Relay behaviour properly set? -// TODO: replace FnMut with FnOnce use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::NetworkBehaviour; @@ -38,8 +37,7 @@ use std::marker::PhantomData; /// .with_tls()? /// .with_noise()? /// .with_quic() -/// .with_dns() -/// .await? +/// .with_dns()? /// .with_relay() /// .with_tls()? /// .with_noise()? @@ -157,7 +155,7 @@ impl SwarmBuilder { impl SwarmBuilder { pub fn with_other_transport( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> OtherTransport, ) -> SwarmBuilder> { self.without_tcp() .without_quic() @@ -387,7 +385,7 @@ macro_rules! impl_quic_builder { pub fn with_quic_config( self, - mut constructor: impl FnMut(&libp2p_identity::Keypair) -> libp2p_quic::Config, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> libp2p_quic::Config, ) -> SwarmBuilder<$providerCamelCase, OtherTransportPhase> { construct_other_transport_builder!(self, $quic, constructor(&self.keypair)) } @@ -425,7 +423,7 @@ impl SwarmBuilder( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> OtherTransport, ) -> SwarmBuilder> { self.without_quic().with_other_transport(constructor) } @@ -446,7 +444,7 @@ impl SwarmBuilder>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { self.without_quic() .without_any_other_transports() @@ -489,7 +487,7 @@ impl { pub fn with_other_transport( self, - mut constructor: impl FnMut(&libp2p_identity::Keypair) -> OtherTransport, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> OtherTransport, ) -> SwarmBuilder> { SwarmBuilder { phase: OtherTransportPhase { @@ -552,7 +550,7 @@ impl { pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { self.without_any_other_transports() .without_dns() @@ -614,7 +612,7 @@ impl SwarmBuilder> { impl SwarmBuilder> { pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { self.without_dns() .without_relay() @@ -672,7 +670,7 @@ impl SwarmBuilder>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { self.without_relay() .without_websocket() @@ -865,7 +863,7 @@ impl pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, ) -> Result< SwarmBuilder>, R::Error, @@ -917,7 +915,7 @@ impl { pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } @@ -928,7 +926,7 @@ impl { pub fn with_behaviour>( self, - constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { self.without_websocket().with_behaviour(constructor) } @@ -1128,7 +1126,7 @@ pub struct BehaviourPhase { impl SwarmBuilder> { pub fn with_behaviour>( self, - mut constructor: impl FnMut(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, ) -> Result>, R::Error> { Ok(SwarmBuilder { phase: SwarmPhase { @@ -1145,7 +1143,7 @@ impl SwarmBuilder SwarmBuilder> { pub fn with_behaviour>( self, - mut constructor: impl FnMut(&libp2p_identity::Keypair) -> R, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { // Discard `NoRelayBehaviour`. let _ = self.phase.relay_behaviour; From 642bae2596b6a2658152a1352996e37d703b3865 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 17:38:42 +0200 Subject: [PATCH 058/171] Feature gate most from wasm32 --- libp2p/src/builder.rs | 130 ++++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 48 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index b899f69080a..7eb65433749 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,6 +1,7 @@ // TODO: Be able to address `SwarmBuilder` configuration methods. // TODO: Consider making with_other_transport fallible. // TODO: Are all with_behaviour with Relay behaviour properly set? +// TODO: WASM executor use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::NetworkBehaviour; @@ -15,6 +16,7 @@ use std::marker::PhantomData; /// # use std::error::Error; /// # /// # #[cfg(all( +/// # not(target_arch = "wasm32"), /// # feature = "tokio", /// # feature = "tcp", /// # feature = "tls", @@ -78,7 +80,7 @@ impl SwarmBuilder { pub struct ProviderPhase {} impl SwarmBuilder { - #[cfg(feature = "async-std")] + #[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] pub fn with_async_std(self) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, @@ -87,7 +89,7 @@ impl SwarmBuilder { } } - #[cfg(feature = "tokio")] + #[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] pub fn with_tokio(self) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, @@ -99,7 +101,7 @@ impl SwarmBuilder { pub struct TcpPhase {} -#[cfg(feature = "tcp")] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] impl SwarmBuilder { pub fn with_tcp(self) -> SwarmBuilder { self.with_tcp_config(Default::default()) @@ -136,7 +138,7 @@ impl SwarmBuilder { } // Shortcuts -#[cfg(all(feature = "quic", feature = "async-std"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = "async-std"))] impl SwarmBuilder { pub fn with_quic( self, @@ -144,7 +146,7 @@ impl SwarmBuilder { self.without_tcp().with_quic() } } -#[cfg(all(feature = "quic", feature = "tokio"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = "tokio"))] impl SwarmBuilder { pub fn with_quic( self, @@ -163,12 +165,12 @@ impl SwarmBuilder { } } -#[cfg(feature = "tcp")] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] pub struct TcpTlsPhase { tcp_config: libp2p_tcp::Config, } -#[cfg(feature = "tcp")] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] impl SwarmBuilder { #[cfg(feature = "tls")] pub fn with_tls( @@ -201,9 +203,13 @@ impl SwarmBuilder { } // Shortcuts -#[cfg(all(feature = "tcp", feature = "noise", feature = "async-std"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + feature = "noise", + feature = "async-std" +))] impl SwarmBuilder { - #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< @@ -213,9 +219,13 @@ impl SwarmBuilder { self.without_tls().with_noise() } } -#[cfg(all(feature = "tcp", feature = "noise", feature = "tokio"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + feature = "noise", + feature = "tokio" +))] impl SwarmBuilder { - #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< @@ -226,14 +236,14 @@ impl SwarmBuilder { } } -#[cfg(feature = "tcp")] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] pub struct TcpNoisePhase { tcp_config: libp2p_tcp::Config, tls_config: A, phantom: PhantomData, } -#[cfg(feature = "tcp")] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] macro_rules! construct_quic_builder { ($self:ident, $tcp:ident, $auth:expr) => { SwarmBuilder { @@ -252,7 +262,7 @@ macro_rules! construct_quic_builder { macro_rules! impl_tcp_noise_builder { ($providerKebabCase:literal, $providerCamelCase:ident, $tcp:ident) => { - #[cfg(all(feature = $providerKebabCase, feature = "tcp", feature = "tls"))] + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "tls"))] impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( @@ -290,7 +300,7 @@ macro_rules! impl_tcp_noise_builder { } } - #[cfg(feature = $providerKebabCase)] + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp"))] impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( @@ -331,7 +341,12 @@ enum AuthenticationErrorInner { } // Shortcuts -#[cfg(all(feature = "tls", feature = "quic", feature = "async-std"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tls", + feature = "quic", + feature = "async-std" +))] impl SwarmBuilder> { pub fn with_quic( self, @@ -339,7 +354,12 @@ impl SwarmBuilder> { self.without_noise().with_quic() } } -#[cfg(all(feature = "tls", feature = "quic", feature = "tokio"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tls", + feature = "quic", + feature = "tokio" +))] impl SwarmBuilder> { pub fn with_quic( self, @@ -352,18 +372,17 @@ pub struct QuicPhase { transport: T, } - -#[cfg(feature = "quic")] +#[cfg(all(not(target_arch = "wasm32"), feature = "quic"))] macro_rules! construct_other_transport_builder { ($self:ident, $quic:ident, $config:expr) => { SwarmBuilder { - phase: OtherTransportPhase{ + phase: OtherTransportPhase { transport: $self .phase .transport .or_transport( libp2p_quic::$quic::Transport::new($config) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), ) .map(|either, _| either.into_inner()), }, @@ -379,18 +398,24 @@ macro_rules! impl_quic_builder { impl SwarmBuilder<$providerCamelCase, QuicPhase> { pub fn with_quic( self, - ) -> SwarmBuilder<$providerCamelCase, OtherTransportPhase> { + ) -> SwarmBuilder< + $providerCamelCase, + OtherTransportPhase, + > { self.with_quic_config(|key| libp2p_quic::Config::new(&key)) } pub fn with_quic_config( self, constructor: impl FnOnce(&libp2p_identity::Keypair) -> libp2p_quic::Config, - ) -> SwarmBuilder<$providerCamelCase, OtherTransportPhase> { + ) -> SwarmBuilder< + $providerCamelCase, + OtherTransportPhase, + > { construct_other_transport_builder!(self, $quic, constructor(&self.keypair)) } } - } + }; } impl_quic_builder!("async-std", AsyncStd, async_std); @@ -428,7 +453,7 @@ impl SwarmBuilder SwarmBuilder< @@ -454,7 +479,7 @@ impl SwarmBuilder SwarmBuilder> { pub async fn with_dns( self, @@ -466,7 +491,7 @@ impl SwarmBuilder> .await } } -#[cfg(all(feature = "tokio", feature = "dns"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] impl SwarmBuilder> { pub fn with_dns( self, @@ -502,7 +527,6 @@ impl } } - // TODO: Not the ideal name. fn without_any_other_transports(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, @@ -515,7 +539,7 @@ impl } // Shortcuts -#[cfg(all(feature = "async-std", feature = "dns"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] impl SwarmBuilder> { pub async fn with_dns( self, @@ -524,7 +548,7 @@ impl SwarmBuilder SwarmBuilder> { pub fn with_dns( self, @@ -564,7 +588,7 @@ pub struct DnsPhase { transport: T, } -#[cfg(all(feature = "async-std", feature = "dns"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] impl SwarmBuilder> { pub async fn with_dns( self, @@ -580,7 +604,7 @@ impl SwarmBuilder> { } } -#[cfg(all(feature = "tokio", feature = "dns"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] impl SwarmBuilder> { pub fn with_dns( self, @@ -658,7 +682,7 @@ impl SwarmBuilder> { // Shortcuts #[cfg(feature = "relay")] impl SwarmBuilder> { - #[cfg(feature = "websocket")] + #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] pub fn with_websocket( self, ) -> SwarmBuilder< @@ -851,7 +875,7 @@ impl impl SwarmBuilder> { - #[cfg(feature = "websocket")] + #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] pub fn with_websocket( self, ) -> SwarmBuilder< @@ -879,7 +903,7 @@ pub struct WebsocketPhase { relay_behaviour: R, } -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] impl SwarmBuilder> { pub fn with_websocket(self) -> SwarmBuilder> { SwarmBuilder { @@ -909,7 +933,6 @@ impl } // Shortcuts -#[cfg(feature = "relay")] impl SwarmBuilder> { @@ -938,7 +961,7 @@ pub struct WebsocketTlsPhase { relay_behaviour: R, } -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] impl SwarmBuilder> { #[cfg(feature = "tls")] pub fn with_tls( @@ -975,7 +998,12 @@ impl SwarmBuilder> { } // Shortcuts -#[cfg(all(feature = "websocket", feature = "noise", feature = "async-std"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "websocket", + feature = "noise", + feature = "async-std" +))] impl SwarmBuilder> { #[cfg(feature = "noise")] pub async fn with_noise( @@ -987,7 +1015,12 @@ impl SwarmBuilder SwarmBuilder> { #[cfg(feature = "noise")] pub async fn with_noise( @@ -1000,7 +1033,7 @@ impl SwarmBuilder { tls_config: A, transport: T, @@ -1008,7 +1041,7 @@ pub struct WebsocketNoisePhase { phantom: PhantomData, } -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] macro_rules! construct_behaviour_builder { ($self:ident, $dnsTcp:expr, $auth:expr) => {{ let websocket_transport = @@ -1034,11 +1067,12 @@ macro_rules! construct_behaviour_builder { macro_rules! impl_websocket_noise_builder { ($providerKebabCase:literal, $providerCamelCase:ident, $dnsTcp:expr) => { #[cfg(all( - feature = $providerKebabCase, - feature = "websocket", - feature = "dns", - feature = "tls" - ))] + not(target_arch = "wasm32"), + feature = $providerKebabCase, + feature = "websocket", + feature = "dns", + feature = "tls" + ))] impl SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, libp2p_tls::Config>> { @@ -1181,7 +1215,7 @@ impl SwarmBuilder> { } } -#[cfg(feature = "async-std")] +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] impl SwarmBuilder> { @@ -1199,7 +1233,7 @@ impl } } -#[cfg(feature = "tokio")] +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] impl SwarmBuilder> { From 55dfaac4aefffbb76eba66a0775877bb633a9d9e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 17:43:10 +0200 Subject: [PATCH 059/171] Fix clippy --- libp2p/src/builder.rs | 3 +++ swarm/src/lib.rs | 43 ++++++++++++++++--------------------------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 7eb65433749..6866dedb777 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -324,6 +324,7 @@ macro_rules! impl_tcp_noise_builder { impl_tcp_noise_builder!("async-std", AsyncStd, async_io); impl_tcp_noise_builder!("tokio", Tokio, tokio); +#[cfg(any(feature = "tls", feature = "noise"))] pub struct WithoutTls {} #[derive(Debug, thiserror::Error)] @@ -1111,6 +1112,8 @@ macro_rules! impl_websocket_noise_builder { SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> { pub async fn with_noise(self) -> Result>, WebsocketError> { + let _ = self.phase.tls_config; + construct_behaviour_builder!( self, $dnsTcp, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 056c254eb54..a8a6400d1c3 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -362,13 +362,13 @@ where transport: transport::Boxed<(PeerId, StreamMuxerBox)>, behaviour: TBehaviour, local_peer_id: PeerId, - config: SwarmConfig + config: SwarmConfig, ) -> Self { Swarm { - local_peer_id: local_peer_id, - transport: transport, + local_peer_id, + transport, pool: Pool::new(local_peer_id, config.pool_config), - behaviour: behaviour, + behaviour, supported_protocols: Default::default(), confirmed_external_addr: Default::default(), listened_addrs: HashMap::new(), @@ -1367,13 +1367,10 @@ pub struct SwarmConfig { pool_config: PoolConfig, } -impl SwarmConfig -{ +impl SwarmConfig { /// Creates a new [`SwarmConfig`] from the given executor. The [`Swarm`] is obtained via /// [`Swarm::new_from_config`]. - pub fn with_executor( - executor: impl Executor + Send + 'static, - ) -> Self { + pub fn with_executor(executor: impl Executor + Send + 'static) -> Self { Self { pool_config: PoolConfig::new(Some(Box::new(executor))), } @@ -1389,11 +1386,8 @@ impl SwarmConfig /// } /// ``` #[cfg(feature = "wasm-bindgen")] - pub fn with_wasm_executor( - ) -> Self { - Self::with_executor( - crate::executor::WasmBindgenExecutor, - ) + pub fn with_wasm_executor() -> Self { + Self::with_executor(crate::executor::WasmBindgenExecutor) } /// Builds a new [`SwarmConfig`] from the given `tokio` executor. @@ -1401,11 +1395,8 @@ impl SwarmConfig feature = "tokio", not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")) ))] - pub fn with_tokio_executor( - ) -> Self { - Self::with_executor( - crate::executor::TokioExecutor, - ) + pub fn with_tokio_executor() -> Self { + Self::with_executor(crate::executor::TokioExecutor) } /// Builds a new [`SwarmConfig`] from the given `async-std` executor. @@ -1413,11 +1404,8 @@ impl SwarmConfig feature = "async-std", not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")) ))] - pub fn with_async_std_executor( - ) -> Self { - Self::with_executor( - crate::executor::AsyncStdExecutor, - ) + pub fn with_async_std_executor() -> Self { + Self::with_executor(crate::executor::AsyncStdExecutor) } // TODO: Should we remove this from `SwarmConfig`?! @@ -1428,8 +1416,7 @@ impl SwarmConfig /// All connections will be polled on the current task, thus quite bad performance /// characteristics should be expected. Whenever possible use an executor and /// [`SwarmConfig::with_executor`]. - pub fn without_executor( - ) -> Self { + pub fn without_executor() -> Self { Self { pool_config: PoolConfig::new(None), } @@ -1502,7 +1489,9 @@ impl SwarmConfig } /// A [`SwarmBuilder`] provides an API for configuring and constructing a [`Swarm`]. -#[deprecated(note = "Use the new `libp2p::SwarmBuilder` instead of `libp2p::swarm::SwarmBuilder` or create a `Swarm` directly via `Swarm::new_with_config`.")] +#[deprecated( + note = "Use the new `libp2p::SwarmBuilder` instead of `libp2p::swarm::SwarmBuilder` or create a `Swarm` directly via `Swarm::new_with_config`." +)] pub struct SwarmBuilder { local_peer_id: PeerId, transport: transport::Boxed<(PeerId, StreamMuxerBox)>, From 5a49887989fa03ece359000dc6ff24a8fcafa611 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 19:05:07 +0200 Subject: [PATCH 060/171] More feature flags --- libp2p/src/builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 6866dedb777..57b0f2bc928 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -872,7 +872,7 @@ impl } // Shortcuts -#[cfg(feature = "tls")] +#[cfg(all(feature = "tls", feature = "relay"))] impl SwarmBuilder> { @@ -934,6 +934,7 @@ impl } // Shortcuts +#[cfg(feature = "relay")] impl SwarmBuilder> { From c6feb018490b02d297b259d3dd76887fadd1436a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 19:12:01 +0200 Subject: [PATCH 061/171] More feature flags --- libp2p/src/builder.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 57b0f2bc928..84bc43d2cf9 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -334,7 +334,7 @@ pub struct AuthenticationError(AuthenticationErrorInner); #[derive(Debug, thiserror::Error)] enum AuthenticationErrorInner { #[error("Tls")] - #[cfg(feature = "tls")] + #[cfg(all(not(target_arch = "wasm32"), feature = "tls"))] Tls(#[from] libp2p_tls::certificate::GenError), #[error("Noise")] #[cfg(feature = "noise")] @@ -395,7 +395,7 @@ macro_rules! construct_other_transport_builder { macro_rules! impl_quic_builder { ($providerKebabCase:literal, $providerCamelCase:ident, $quic:ident) => { - #[cfg(all(feature = "quic", feature = $providerKebabCase))] + #[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = $providerKebabCase))] impl SwarmBuilder<$providerCamelCase, QuicPhase> { pub fn with_quic( self, @@ -710,7 +710,7 @@ pub struct RelayTlsPhase { #[cfg(feature = "relay")] impl SwarmBuilder> { - #[cfg(feature = "tls")] + #[cfg(all(not(target_arch = "wasm32"), feature = "tls"))] pub fn with_tls( self, ) -> Result>, AuthenticationError> @@ -804,7 +804,7 @@ macro_rules! construct_websocket_builder { }}; } -#[cfg(all(feature = "relay", feature = "tls"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "relay", feature = "tls"))] impl SwarmBuilder> { @@ -872,7 +872,7 @@ impl } // Shortcuts -#[cfg(all(feature = "tls", feature = "relay"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "tls", feature = "relay"))] impl SwarmBuilder> { @@ -1108,7 +1108,7 @@ macro_rules! impl_websocket_noise_builder { } } - #[cfg(all(feature = $providerKebabCase, feature = "dns", feature = "websocket", feature = "noise"))] + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "dns", feature = "websocket", feature = "noise"))] impl SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> { From adc3180dd3ad37ef384c8d6f9bd7b0d04a65908e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 19:14:38 +0200 Subject: [PATCH 062/171] More feature flags --- libp2p/src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 84bc43d2cf9..415823d0549 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -957,7 +957,7 @@ impl } } -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] pub struct WebsocketTlsPhase { transport: T, relay_behaviour: R, From 6e760d73848cf8f4e8eefc9751f7519b43e3d0b0 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 19:36:08 +0200 Subject: [PATCH 063/171] Fix feature flag --- libp2p/src/builder.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 415823d0549..3e75af144f0 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -681,7 +681,6 @@ impl SwarmBuilder> { } // Shortcuts -#[cfg(feature = "relay")] impl SwarmBuilder> { #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] pub fn with_websocket( From 87934981337eb98cc05d3ce5c6988202fefe87bb Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 19:36:52 +0200 Subject: [PATCH 064/171] Clippy --- libp2p/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 0d2140af7d1..3368f2e7d39 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -151,12 +151,12 @@ pub mod bandwidth; #[cfg(doc)] pub mod tutorials; +pub use self::builder::SwarmBuilder; pub use self::core::{ transport::TransportError, upgrade::{InboundUpgrade, OutboundUpgrade}, Transport, }; -pub use self::builder::SwarmBuilder; pub use self::multiaddr::{multiaddr as build_multiaddr, Multiaddr}; pub use self::swarm::Swarm; pub use self::transport_ext::TransportExt; From 7393b8a06cb05fba3f8d0e4cf048e248a5ef6cd1 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 27 Aug 2023 19:37:11 +0200 Subject: [PATCH 065/171] Clippy --- misc/server/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/server/src/main.rs b/misc/server/src/main.rs index f644599cc43..63e7fafe523 100644 --- a/misc/server/src/main.rs +++ b/misc/server/src/main.rs @@ -8,9 +8,9 @@ use libp2p::identity; use libp2p::identity::PeerId; use libp2p::kad; use libp2p::metrics::{Metrics, Recorder}; -use libp2p::swarm::{SwarmEvent}; -use libp2p::tcp; use libp2p::quic; +use libp2p::swarm::SwarmEvent; +use libp2p::tcp; use log::{debug, info}; use prometheus_client::metrics::info::Info; use prometheus_client::registry::Registry; From dec90c7445686a8637faac1fe6cc2a1447935cf0 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 2 Sep 2023 17:30:58 +0200 Subject: [PATCH 066/171] Make with_other_transport fallible --- libp2p/src/builder.rs | 101 +++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 25 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 3e75af144f0..a6016cc2159 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,5 +1,3 @@ -// TODO: Be able to address `SwarmBuilder` configuration methods. -// TODO: Consider making with_other_transport fallible. // TODO: Are all with_behaviour with Relay behaviour properly set? // TODO: WASM executor @@ -155,10 +153,16 @@ impl SwarmBuilder { } } impl SwarmBuilder { - pub fn with_other_transport( + pub fn with_other_transport< + OtherTransport: AuthenticatedMultiplexedTransport, + R: TryIntoTransport, + >( self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder> { + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result< + SwarmBuilder>, + R::Error, + > { self.without_tcp() .without_quic() .with_other_transport(constructor) @@ -447,10 +451,16 @@ impl SwarmBuilder( + pub fn with_other_transport< + OtherTransport: AuthenticatedMultiplexedTransport, + R: TryIntoTransport, + >( self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder> { + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result< + SwarmBuilder>, + R::Error, + > { self.without_quic().with_other_transport(constructor) } @@ -511,21 +521,27 @@ pub struct OtherTransportPhase { impl SwarmBuilder> { - pub fn with_other_transport( + pub fn with_other_transport< + OtherTransport: AuthenticatedMultiplexedTransport, + R: TryIntoTransport, + >( self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> OtherTransport, - ) -> SwarmBuilder> { - SwarmBuilder { + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result< + SwarmBuilder>, + R::Error, + > { + Ok(SwarmBuilder { phase: OtherTransportPhase { transport: self .phase .transport - .or_transport(constructor(&self.keypair)) + .or_transport(constructor(&self.keypair).try_into_transport()?) .map(|either, _| either.into_inner()), }, keypair: self.keypair, phantom: PhantomData, - } + }) } fn without_any_other_transports(self) -> SwarmBuilder> { @@ -1336,6 +1352,7 @@ impl TryIntoBehaviour for Result enough? type Error = io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? fn try_into_behaviour(self) -> Result { @@ -1343,6 +1360,36 @@ where } } +// TODO: Seal this. +pub trait TryIntoTransport { + type Error; + + fn try_into_transport(self) -> Result; +} + +impl TryIntoTransport for T +where + T: AuthenticatedMultiplexedTransport, +{ + type Error = Infallible; + + fn try_into_transport(self) -> Result { + Ok(self) + } +} + +impl TryIntoTransport for Result> +where + T: AuthenticatedMultiplexedTransport, +{ + // TODO mxinden: why do we need an io error here? isn't box enough? + type Error = io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? + + fn try_into_transport(self) -> Result { + self.map_err(|e| io::Error::new(io::ErrorKind::Other, e)) + } +} + #[cfg(test)] mod tests { use super::*; @@ -1443,23 +1490,27 @@ mod tests { .build(); } - /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. QUIC or WebRTC. + /// Showcases how to provide custom transports unknown to the libp2p crate, e.g. WebRTC. #[test] - #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] - fn tcp_other_transport_other_transport() { + #[cfg(feature = "tokio")] + fn other_transport() -> Result<(), Box> { let _ = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() - .unwrap() - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new()) + // Closure can either return a Transport directly. + .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new())? + // Or a Result containing a Transport. + .with_other_transport(|_| { + if true { + Ok(libp2p_core::transport::dummy::DummyTransport::new()) + } else { + Err(Box::from("test")) + } + })? .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .unwrap() .build(); + + Ok(()) } #[tokio::test] From 62d2c8ae58f594cec5e3cb8d683eb1dd5226bfa4 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 2 Sep 2023 19:18:08 +0200 Subject: [PATCH 067/171] Use SwarmBuilder in interop-tests --- interop-tests/src/arch.rs | 183 +++++++++++++++++++------------------- interop-tests/src/lib.rs | 39 ++++---- libp2p/src/builder.rs | 60 ++++++++++++- 3 files changed, 169 insertions(+), 113 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 2b2181f2459..ed8602447b3 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -4,11 +4,11 @@ use libp2p::PeerId; // Native re-exports #[cfg(not(target_arch = "wasm32"))] -pub(crate) use native::{build_transport, init_logger, sleep, swarm_builder, Instant, RedisClient}; +pub(crate) use native::{build_swarm, init_logger, sleep, Instant, RedisClient}; // Wasm re-exports #[cfg(target_arch = "wasm32")] -pub(crate) use wasm::{build_transport, init_logger, sleep, swarm_builder, Instant, RedisClient}; +pub(crate) use wasm::{build_swarm, init_logger, sleep, swarm_builder, Instant, RedisClient}; type BoxedTransport = Boxed<(PeerId, StreamMuxerBox)>; @@ -17,17 +17,13 @@ pub(crate) mod native { use std::time::Duration; use anyhow::{bail, Context, Result}; - use either::Either; use env_logger::{Env, Target}; use futures::future::BoxFuture; use futures::FutureExt; use libp2p::core::muxing::StreamMuxerBox; - use libp2p::core::upgrade::Version; use libp2p::identity::Keypair; - use libp2p::swarm::{NetworkBehaviour, SwarmBuilder}; - use libp2p::websocket::WsConfig; - use libp2p::{noise, quic, tcp, tls, yamux, PeerId, Transport as _}; - use libp2p_mplex as mplex; + use libp2p::swarm::{NetworkBehaviour, Swarm}; + use libp2p::Transport as _; use libp2p_webrtc as webrtc; use redis::AsyncCommands; @@ -47,87 +43,89 @@ pub(crate) mod native { tokio::time::sleep(duration).boxed() } - fn muxer_protocol_from_env() -> Result> { - Ok(match from_env("muxer")? { - Muxer::Yamux => Either::Left(yamux::Config::default()), - Muxer::Mplex => Either::Right(mplex::MplexConfig::new()), - }) - } + // TODO: Still need to support mplex? Ideally not. + // fn muxer_protocol_from_env() -> Result> { + // Ok(match from_env("muxer")? { + // Muxer::Yamux => Either::Left(yamux::Config::default()), + // Muxer::Mplex => Either::Right(mplex::MplexConfig::new()), + // }) + // } - pub(crate) fn build_transport( - local_key: Keypair, + pub(crate) async fn build_swarm( ip: &str, transport: Transport, - ) -> Result<(BoxedTransport, String)> { - let (transport, addr) = match (transport, from_env::("security")) { - (Transport::QuicV1, _) => ( - quic::tokio::Transport::new(quic::Config::new(&local_key)) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))) - .boxed(), - format!("/ip4/{ip}/udp/0/quic-v1"), - ), - (Transport::Tcp, Ok(SecProtocol::Tls)) => ( - tcp::tokio::Transport::new(tcp::Config::new()) - .upgrade(Version::V1Lazy) - .authenticate(tls::Config::new(&local_key).context("failed to initialise tls")?) - .multiplex(muxer_protocol_from_env()?) - .timeout(Duration::from_secs(5)) - .boxed(), - format!("/ip4/{ip}/tcp/0"), - ), - (Transport::Tcp, Ok(SecProtocol::Noise)) => ( - tcp::tokio::Transport::new(tcp::Config::new()) - .upgrade(Version::V1Lazy) - .authenticate( - noise::Config::new(&local_key).context("failed to intialise noise")?, - ) - .multiplex(muxer_protocol_from_env()?) - .timeout(Duration::from_secs(5)) - .boxed(), - format!("/ip4/{ip}/tcp/0"), - ), - (Transport::Ws, Ok(SecProtocol::Tls)) => ( - WsConfig::new(tcp::tokio::Transport::new(tcp::Config::new())) - .upgrade(Version::V1Lazy) - .authenticate(tls::Config::new(&local_key).context("failed to initialise tls")?) - .multiplex(muxer_protocol_from_env()?) - .timeout(Duration::from_secs(5)) - .boxed(), - format!("/ip4/{ip}/tcp/0/ws"), - ), - (Transport::Ws, Ok(SecProtocol::Noise)) => ( - WsConfig::new(tcp::tokio::Transport::new(tcp::Config::new())) - .upgrade(Version::V1Lazy) - .authenticate( - noise::Config::new(&local_key).context("failed to intialise noise")?, - ) - .multiplex(muxer_protocol_from_env()?) - .timeout(Duration::from_secs(5)) - .boxed(), - format!("/ip4/{ip}/tcp/0/ws"), - ), - (Transport::WebRtcDirect, _) => ( - webrtc::tokio::Transport::new( - local_key, - webrtc::tokio::Certificate::generate(&mut rand::thread_rng())?, - ) - .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) - .boxed(), - format!("/ip4/{ip}/udp/0/webrtc-direct"), - ), + behaviour_constructor: impl FnOnce(&Keypair) -> B, + ) -> Result<(Swarm, String)> { + let (swarm, addr) = match (transport, from_env::("security")) { + (Transport::QuicV1, _) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_quic() + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/udp/0/quic-v1")) + } + (Transport::Tcp, Ok(SecProtocol::Tls)) => { + // TODO: Note that the timeout of 5 secs is gone now. + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_tls()? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0")) + } + (Transport::Tcp, Ok(SecProtocol::Noise)) => { + // TODO: Note that the timeout of 5 secs is gone now. + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp() + .with_noise()? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0")) + } + (Transport::Ws, Ok(SecProtocol::Tls)) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_websocket() + .with_tls()? + .without_noise() + .await? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0/ws")) + } + (Transport::Ws, Ok(SecProtocol::Noise)) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_websocket() + .with_noise() + .await? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0/ws")) + } + (Transport::WebRtcDirect, _) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_other_transport(|key| { + Ok(webrtc::tokio::Transport::new( + key.clone(), + webrtc::tokio::Certificate::generate(&mut rand::thread_rng())?, + ) + .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn)))) + })? + .with_behaviour(behaviour_constructor)? + .build(); + + (swarm, format!("/ip4/{ip}/udp/0/webrtc-direct")) + } (Transport::Tcp, Err(_)) => bail!("Missing security protocol for TCP transport"), (Transport::Ws, Err(_)) => bail!("Missing security protocol for Websocket transport"), (Transport::Webtransport, _) => bail!("Webtransport can only be used with wasm"), }; - Ok((transport, addr)) - } - - pub(crate) fn swarm_builder( - transport: BoxedTransport, - behaviour: TBehaviour, - peer_id: PeerId, - ) -> SwarmBuilder { - SwarmBuilder::with_tokio_executor(transport, behaviour, peer_id) + Ok((swarm, addr)) } pub(crate) struct RedisClient(redis::Client); @@ -176,19 +174,22 @@ pub(crate) mod wasm { futures_timer::Delay::new(duration).boxed() } - pub(crate) fn build_transport( - local_key: Keypair, + pub(crate) fn build_swarm( ip: &str, transport: Transport, + behaviour_constructor: FnOnce(Keypair) -> B, ) -> Result<(BoxedTransport, String)> { if let Transport::Webtransport = transport { - Ok(( - libp2p::webtransport_websys::Transport::new( - libp2p::webtransport_websys::Config::new(&local_key), - ) - .boxed(), - format!("/ip4/{ip}/udp/0/quic/webtransport"), - )) + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_wasm_executor() + .with_other_transport(|key| { + libp2p::webtransport_websys::Transport::new( + libp2p::webtransport_websys::Config::new(key), + ) + })? + .with_behaviour(behaviour_constructor)? + .build(); + return Ok((swarm, format!("/ip4/{ip}/udp/0/quic/webtransport"))); } else { bail!("Only webtransport supported with wasm") } diff --git a/interop-tests/src/lib.rs b/interop-tests/src/lib.rs index 57ce636367b..f4dd9f67f21 100644 --- a/interop-tests/src/lib.rs +++ b/interop-tests/src/lib.rs @@ -3,14 +3,15 @@ use std::time::Duration; use anyhow::{bail, Context, Result}; use futures::{FutureExt, StreamExt}; +use libp2p::identity::Keypair; use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmEvent}; -use libp2p::{identify, identity, ping, Multiaddr, PeerId}; +use libp2p::{identify, ping, Multiaddr}; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; mod arch; -use arch::{build_transport, init_logger, swarm_builder, Instant, RedisClient}; +use arch::{build_swarm, init_logger, Instant, RedisClient}; pub async fn run_test( transport: &str, @@ -24,26 +25,10 @@ pub async fn run_test( let test_timeout = Duration::from_secs(test_timeout_seconds); let transport = transport.parse().context("Couldn't parse transport")?; - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); let redis_client = RedisClient::new(redis_addr).context("Could not connect to redis")?; // Build the transport from the passed ENV var. - let (boxed_transport, local_addr) = build_transport(local_key.clone(), ip, transport)?; - let mut swarm = swarm_builder( - boxed_transport, - Behaviour { - ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), - keep_alive: keep_alive::Behaviour, - // Need to include identify until https://github.com/status-im/nim-libp2p/issues/924 is resolved. - identify: identify::Behaviour::new(identify::Config::new( - "/interop-tests".to_owned(), - local_key.public(), - )), - }, - local_peer_id, - ) - .build(); + let (mut swarm, local_addr) = build_swarm(ip, transport, build_behaviour).await?; log::info!("Running ping test: {}", swarm.local_peer_id()); @@ -111,7 +96,7 @@ pub async fn run_test( continue; } if listener_id == id { - let ma = format!("{address}/p2p/{local_peer_id}"); + let ma = format!("{address}/p2p/{}", swarm.local_peer_id()); redis_client.rpush("listenerAddr", ma).await?; break; } @@ -239,7 +224,7 @@ impl FromStr for SecProtocol { } #[derive(NetworkBehaviour)] -struct Behaviour { +pub(crate) struct Behaviour { ping: ping::Behaviour, keep_alive: keep_alive::Behaviour, identify: identify::Behaviour, @@ -255,3 +240,15 @@ where .parse() .map_err(Into::into) } + +pub(crate) fn build_behaviour(key: &Keypair) -> Behaviour { + Behaviour { + ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), + keep_alive: keep_alive::Behaviour, + // Need to include identify until https://github.com/status-im/nim-libp2p/issues/924 is resolved. + identify: identify::Behaviour::new(identify::Config::new( + "/interop-tests".to_owned(), + key.public(), + )), + } +} diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index a6016cc2159..cd51b12ab9d 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,4 +1,3 @@ -// TODO: Are all with_behaviour with Relay behaviour properly set? // TODO: WASM executor use libp2p_core::{muxing::StreamMuxerBox, Transport}; @@ -167,6 +166,21 @@ impl SwarmBuilder { .without_quic() .with_other_transport(constructor) } + + #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] + pub fn with_websocket( + self, + ) -> SwarmBuilder< + Provider, + WebsocketTlsPhase, + > { + self.without_tcp() + .without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .with_websocket() + } } #[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] @@ -372,6 +386,50 @@ impl SwarmBuilder> { self.without_noise().with_quic() } } +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tls", + feature = "quic", + feature = "async-std" +))] +impl SwarmBuilder> { + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result< + SwarmBuilder>, + R::Error, + > { + self.without_noise() + .without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .without_websocket() + .with_behaviour(constructor) + } +} +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tls", + feature = "quic", + feature = "tokio" +))] +impl SwarmBuilder> { + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> + { + self.without_noise() + .without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .without_websocket() + .with_behaviour(constructor) + } +} pub struct QuicPhase { transport: T, From 00dca91e4ce44c2564012fba01cd60c8f8aa317a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 2 Sep 2023 19:31:01 +0200 Subject: [PATCH 068/171] Add WASM support --- interop-tests/src/arch.rs | 34 +++++++++------------------------- libp2p/src/builder.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index ed8602447b3..a44ca747634 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -1,16 +1,10 @@ -use libp2p::core::muxing::StreamMuxerBox; -use libp2p::core::transport::Boxed; -use libp2p::PeerId; - // Native re-exports #[cfg(not(target_arch = "wasm32"))] pub(crate) use native::{build_swarm, init_logger, sleep, Instant, RedisClient}; // Wasm re-exports #[cfg(target_arch = "wasm32")] -pub(crate) use wasm::{build_swarm, init_logger, sleep, swarm_builder, Instant, RedisClient}; - -type BoxedTransport = Boxed<(PeerId, StreamMuxerBox)>; +pub(crate) use wasm::{build_swarm, init_logger, sleep, Instant, RedisClient}; #[cfg(not(target_arch = "wasm32"))] pub(crate) mod native { @@ -29,8 +23,6 @@ pub(crate) mod native { use crate::{from_env, Muxer, SecProtocol, Transport}; - use super::BoxedTransport; - pub(crate) type Instant = std::time::Instant; pub(crate) fn init_logger() { @@ -154,15 +146,14 @@ pub(crate) mod native { pub(crate) mod wasm { use anyhow::{bail, Result}; use futures::future::{BoxFuture, FutureExt}; + use libp2p::core::muxing::StreamMuxerBox; use libp2p::identity::Keypair; - use libp2p::swarm::{NetworkBehaviour, SwarmBuilder}; - use libp2p::PeerId; + use libp2p::swarm::{NetworkBehaviour, Swarm}; + use libp2p::Transport as _; use std::time::Duration; use crate::{BlpopRequest, Transport}; - use super::BoxedTransport; - pub(crate) type Instant = instant::Instant; pub(crate) fn init_logger() { @@ -174,18 +165,19 @@ pub(crate) mod wasm { futures_timer::Delay::new(duration).boxed() } - pub(crate) fn build_swarm( + pub(crate) async fn build_swarm( ip: &str, transport: Transport, - behaviour_constructor: FnOnce(Keypair) -> B, - ) -> Result<(BoxedTransport, String)> { + behaviour_constructor: impl FnOnce(&Keypair) -> B, + ) -> Result<(Swarm, String)> { if let Transport::Webtransport = transport { let swarm = libp2p::SwarmBuilder::with_new_identity() - .with_wasm_executor() + .with_wasm_bindgen() .with_other_transport(|key| { libp2p::webtransport_websys::Transport::new( libp2p::webtransport_websys::Config::new(key), ) + .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) })? .with_behaviour(behaviour_constructor)? .build(); @@ -195,14 +187,6 @@ pub(crate) mod wasm { } } - pub(crate) fn swarm_builder( - transport: BoxedTransport, - behaviour: TBehaviour, - peer_id: PeerId, - ) -> SwarmBuilder { - SwarmBuilder::with_wasm_executor(transport, behaviour, peer_id) - } - pub(crate) struct RedisClient(String); impl RedisClient { diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index cd51b12ab9d..0b32bc32828 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -94,6 +94,20 @@ impl SwarmBuilder { phase: TcpPhase {}, } } + + #[cfg(feature = "wasm-bindgen")] + pub fn with_wasm_bindgen( + self, + ) -> SwarmBuilder> + { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: OtherTransportPhase { + transport: libp2p_core::transport::dummy::DummyTransport::new(), + }, + } + } } pub struct TcpPhase {} @@ -1328,6 +1342,24 @@ impl } } +#[cfg(feature = "wasm-bindgen")] +impl + SwarmBuilder> +{ + pub fn build(self) -> libp2p_swarm::Swarm { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: libp2p_swarm::SwarmConfig::with_wasm_executor(), + }, + keypair: self.keypair, + phantom: PhantomData::, + } + .build() + } +} + pub struct BuildPhase { behaviour: B, transport: T, @@ -1361,6 +1393,9 @@ pub enum AsyncStd {} #[cfg(feature = "tokio")] pub enum Tokio {} +#[cfg(feature = "wasm-bindgen")] +pub enum WasmBindgen {} + pub trait AuthenticatedMultiplexedTransport: Transport< Error = Self::E, From 926a6842139c0c7d064501731f9a3b8f2e72e25e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 2 Sep 2023 19:33:31 +0200 Subject: [PATCH 069/171] Simplify with_wasm_bindgen --- libp2p/src/builder.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 0b32bc32828..9e624a1b8a9 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -96,16 +96,11 @@ impl SwarmBuilder { } #[cfg(feature = "wasm-bindgen")] - pub fn with_wasm_bindgen( - self, - ) -> SwarmBuilder> - { + pub fn with_wasm_bindgen(self) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, - phase: OtherTransportPhase { - transport: libp2p_core::transport::dummy::DummyTransport::new(), - }, + phase: TcpPhase {}, } } } From 9e53d1b1aaf9352e4f40f80a2c3fdbd3b02154cd Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 2 Sep 2023 19:34:25 +0200 Subject: [PATCH 070/171] Remove wasm TODO --- libp2p/src/builder.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 9e624a1b8a9..9f26328c3d7 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,5 +1,3 @@ -// TODO: WASM executor - use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::NetworkBehaviour; use std::convert::Infallible; From 9edf25ea873697932b0fd173065d76663bdc7208 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 2 Sep 2023 21:03:57 +0200 Subject: [PATCH 071/171] interop: remove mplex support --- interop-tests/native-ping-version.json | 1 - interop-tests/src/arch.rs | 8 -------- 2 files changed, 9 deletions(-) diff --git a/interop-tests/native-ping-version.json b/interop-tests/native-ping-version.json index c509f72bfd0..eb88d21d9c5 100644 --- a/interop-tests/native-ping-version.json +++ b/interop-tests/native-ping-version.json @@ -12,7 +12,6 @@ "noise" ], "muxers": [ - "mplex", "yamux" ] } diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index a44ca747634..c74ce0545c9 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -35,14 +35,6 @@ pub(crate) mod native { tokio::time::sleep(duration).boxed() } - // TODO: Still need to support mplex? Ideally not. - // fn muxer_protocol_from_env() -> Result> { - // Ok(match from_env("muxer")? { - // Muxer::Yamux => Either::Left(yamux::Config::default()), - // Muxer::Mplex => Either::Right(mplex::MplexConfig::new()), - // }) - // } - pub(crate) async fn build_swarm( ip: &str, transport: Transport, From c0c6e9c93b64faf670b49aefa62e75c391c23ef7 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 2 Sep 2023 21:26:28 +0200 Subject: [PATCH 072/171] Update ping tutorial --- interop-tests/src/arch.rs | 3 +- libp2p/src/builder.rs | 12 +-- libp2p/src/tutorials/hole_punching.rs | 2 + libp2p/src/tutorials/ping.rs | 121 +++++++++++--------------- 4 files changed, 59 insertions(+), 79 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index c74ce0545c9..b21464cedb8 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -21,7 +21,7 @@ pub(crate) mod native { use libp2p_webrtc as webrtc; use redis::AsyncCommands; - use crate::{from_env, Muxer, SecProtocol, Transport}; + use crate::{from_env, SecProtocol, Transport}; pub(crate) type Instant = std::time::Instant; @@ -35,6 +35,7 @@ pub(crate) mod native { tokio::time::sleep(duration).boxed() } + // TODO: Error in case muxer is not yamux. pub(crate) async fn build_swarm( ip: &str, transport: Transport, diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 9f26328c3d7..3dbf2416729 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,5 +1,5 @@ use libp2p_core::{muxing::StreamMuxerBox, Transport}; -use libp2p_swarm::NetworkBehaviour; +use libp2p_swarm::{NetworkBehaviour, Swarm}; use std::convert::Infallible; use std::io; use std::marker::PhantomData; @@ -1303,7 +1303,7 @@ impl SwarmBuilder> { impl SwarmBuilder> { - pub fn build(self) -> libp2p_swarm::Swarm { + pub fn build(self) -> Swarm { SwarmBuilder { phase: BuildPhase { behaviour: self.phase.behaviour, @@ -1321,7 +1321,7 @@ impl impl SwarmBuilder> { - pub fn build(self) -> libp2p_swarm::Swarm { + pub fn build(self) -> Swarm { SwarmBuilder { phase: BuildPhase { behaviour: self.phase.behaviour, @@ -1339,7 +1339,7 @@ impl impl SwarmBuilder> { - pub fn build(self) -> libp2p_swarm::Swarm { + pub fn build(self) -> Swarm { SwarmBuilder { phase: BuildPhase { behaviour: self.phase.behaviour, @@ -1364,8 +1364,8 @@ const CONNECTION_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(1 impl SwarmBuilder> { - pub fn build(self) -> libp2p_swarm::Swarm { - libp2p_swarm::Swarm::new_with_config( + pub fn build(self) -> Swarm { + Swarm::new_with_config( libp2p_core::transport::timeout::TransportTimeout::new( self.phase.transport, CONNECTION_TIMEOUT, diff --git a/libp2p/src/tutorials/hole_punching.rs b/libp2p/src/tutorials/hole_punching.rs index 161a2feeec4..7b0e7656fd0 100644 --- a/libp2p/src/tutorials/hole_punching.rs +++ b/libp2p/src/tutorials/hole_punching.rs @@ -18,6 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +// TODO: Update + //! # Hole Punching Tutorial //! //! This tutorial shows hands-on how to overcome firewalls and NATs with libp2p's hole punching diff --git a/libp2p/src/tutorials/ping.rs b/libp2p/src/tutorials/ping.rs index 976b45e1e22..17377172d57 100644 --- a/libp2p/src/tutorials/ping.rs +++ b/libp2p/src/tutorials/ping.rs @@ -55,9 +55,9 @@ //! edition = "2021" //! //! [dependencies] -//! libp2p = { version = "0.50", features = ["tcp", "dns", "async-std", "noise", "yamux", "websocket", "ping", "macros"] } -//! futures = "0.3.21" -//! async-std = { version = "1.12.0", features = ["attributes"] } +//! libp2p = { version = "0.52", features = ["tcp", "dns", "async-std", "noise", "yamux", "websocket", "ping", "macros"] } +//! futures = "0.3" +//! async-std = { version = "1.12", features = ["attributes"] } //! ``` //! //! ## Network identity @@ -70,38 +70,25 @@ //! derived from their public key. Now, replace the contents of main.rs by: //! //! ```rust -//! use libp2p::{identity, PeerId}; //! use std::error::Error; //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { -//! let local_key = identity::Keypair::generate_ed25519(); -//! let local_peer_id = PeerId::from(local_key.public()); -//! println!("Local peer id: {local_peer_id:?}"); +//! let mut swarm = libp2p::SwarmBuilder::with_new_identity(); //! //! Ok(()) //! } //! ``` //! -//! Go ahead and build and run the above code with: `cargo run`. A unique -//! [`PeerId`](crate::PeerId) should be displayed. +//! Go ahead and build and run the above code with: `cargo run`. Nothing happening thus far. //! //! ## Transport //! -//! Next up we need to construct a transport. A transport in libp2p provides -//! connection-oriented communication channels (e.g. TCP) as well as upgrades -//! on top of those like authentication and encryption protocols. Technically, -//! a libp2p transport is anything that implements the [`Transport`] trait. -//! -//! Instead of constructing a transport ourselves for this tutorial, we use the -//! convenience function [`development_transport`](crate::development_transport) -//! that creates a TCP transport with [`noise`](crate::noise) for authenticated -//! encryption. -//! -//! Furthermore, [`development_transport`] builds a multiplexed transport, -//! whereby multiple logical substreams can coexist on the same underlying (TCP) -//! connection. For further details on substream multiplexing, take a look at -//! [`crate::core::muxing`] and [`yamux`](crate::yamux). +//! Next up we need to construct a transport. Each transport in libp2p provides encrypted streams. +//! E.g. combining TCP to establish connections, TLS to encrypt these connections and Yamux to run +//! one or more streams on a connection. Another libp2p transport is QUIC, providing encrypted +//! streams out-of-the-box. We will stick to TCP for now. Each of these implement the [`Transport`] +//! trait. //! //! ```rust //! use libp2p::{identity, PeerId}; @@ -109,11 +96,10 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { -//! let local_key = identity::Keypair::generate_ed25519(); -//! let local_peer_id = PeerId::from(local_key.public()); -//! println!("Local peer id: {local_peer_id:?}"); -//! -//! let transport = libp2p::development_transport(local_key).await?; +//! let mut swarm = libp2p::SwarmBuilder::with_new_identity() +//! .with_async_std() +//! .with_tcp() +//! .with_tls()?; //! //! Ok(()) //! } @@ -124,20 +110,20 @@ //! Now it is time to look at another core trait of rust-libp2p: the //! [`NetworkBehaviour`]. While the previously introduced trait [`Transport`] //! defines _how_ to send bytes on the network, a [`NetworkBehaviour`] defines -//! _what_ bytes to send on the network. +//! _what_ bytes and to _whom_ to send on the network. //! //! To make this more concrete, let's take a look at a simple implementation of //! the [`NetworkBehaviour`] trait: the [`ping::Behaviour`](crate::ping::Behaviour). -//! As you might have guessed, similar to the good old `ping` network tool, +//! As you might have guessed, similar to the good old ICMP `ping` network tool, //! libp2p [`ping::Behaviour`](crate::ping::Behaviour) sends a ping to a peer and expects //! to receive a pong in turn. The [`ping::Behaviour`](crate::ping::Behaviour) does not care _how_ //! the ping and pong messages are sent on the network, whether they are sent via //! TCP, whether they are encrypted via [noise](crate::noise) or just in -//! [plaintext](crate::plaintext). It only cares about _what_ messages are sent -//! on the network. +//! [plaintext](crate::plaintext). It only cares about _what_ messages and to _whom_ to sent on the +//! network. //! //! The two traits [`Transport`] and [`NetworkBehaviour`] allow us to cleanly -//! separate _how_ to send bytes from _what_ bytes to send. +//! separate _how_ to send bytes from _what_ bytes and to _whom_ to send. //! //! With the above in mind, let's extend our example, creating a [`ping::Behaviour`](crate::ping::Behaviour) at the end: //! @@ -148,13 +134,11 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { -//! let local_key = identity::Keypair::generate_ed25519(); -//! let local_peer_id = PeerId::from(local_key.public()); -//! println!("Local peer id: {local_peer_id:?}"); -//! -//! let transport = libp2p::development_transport(local_key).await?; -//! -//! let behaviour = Behaviour::default(); +//! let mut swarm = libp2p::SwarmBuilder::with_new_identity() +//! .with_async_std() +//! .with_tcp() +//! .with_tls()? +//! .with_behaviour(|_| Behaviour::default())?; //! //! Ok(()) //! } @@ -172,12 +156,10 @@ //! //! ## Swarm //! -//! Now that we have a [`Transport`] and a [`NetworkBehaviour`], we need -//! something that connects the two, allowing both to make progress. This job is -//! carried out by a [`Swarm`]. Put simply, a [`Swarm`] drives both a -//! [`Transport`] and a [`NetworkBehaviour`] forward, passing commands from the -//! [`NetworkBehaviour`] to the [`Transport`] as well as events from the -//! [`Transport`] to the [`NetworkBehaviour`]. +//! Now that we have a [`Transport`] and a [`NetworkBehaviour`], we can build the [`Swarm`] +//! whcihconnects the two, allowing both to make progress. Put simply, a [`Swarm`] drives both a +//! [`Transport`] and a [`NetworkBehaviour`] forward, passing commands from the [`NetworkBehaviour`] +//! to the [`Transport`] as well as events from the [`Transport`] to the [`NetworkBehaviour`]. //! //! ```rust //! use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmBuilder}; @@ -186,15 +168,12 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { -//! let local_key = identity::Keypair::generate_ed25519(); -//! let local_peer_id = PeerId::from(local_key.public()); -//! println!("Local peer id: {local_peer_id:?}"); -//! -//! let transport = libp2p::development_transport(local_key).await?; -//! -//! let behaviour = Behaviour::default(); -//! -//! let mut swarm = SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); +//! let mut swarm = libp2p::SwarmBuilder::with_new_identity() +//! .with_async_std() +//! .with_tcp() +//! .with_tls()?; +//! .with_behaviour(|_| Behaviour::default())? +//! .build(); //! //! Ok(()) //! } @@ -243,15 +222,14 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { -//! let local_key = identity::Keypair::generate_ed25519(); -//! let local_peer_id = PeerId::from(local_key.public()); -//! println!("Local peer id: {local_peer_id:?}"); -//! -//! let transport = libp2p::development_transport(local_key).await?; -//! -//! let behaviour = Behaviour::default(); +//! let mut swarm = libp2p::SwarmBuilder::with_new_identity() +//! .with_async_std() +//! .with_tcp() +//! .with_tls()?; +//! .with_behaviour(|_| Behaviour::default())? +//! .build(); //! -//! let mut swarm = SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); +//! println!("Local peer id: {}", swarm.local_peer_id()); //! //! // Tell the swarm to listen on all interfaces and a random, OS-assigned //! // port. @@ -293,15 +271,14 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { -//! let local_key = identity::Keypair::generate_ed25519(); -//! let local_peer_id = PeerId::from(local_key.public()); -//! println!("Local peer id: {local_peer_id:?}"); -//! -//! let transport = libp2p::development_transport(local_key).await?; -//! -//! let behaviour = Behaviour::default(); -//! -//! let mut swarm = SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); +//! let mut swarm = libp2p::SwarmBuilder::with_new_identity() +//! .with_async_std() +//! .with_tcp() +//! .with_tls()?; +//! .with_behaviour(|_| Behaviour::default())? +//! .build(); +//! +//! println!("Local peer id: {}", swarm.local_peer_id()); //! //! // Tell the swarm to listen on all interfaces and a random, OS-assigned //! // port. From f22a4ff93058ab4f65a7ff994c31175ffb1a0e4c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 11:33:58 +0200 Subject: [PATCH 073/171] Add with_bandwidth_logging --- libp2p/src/builder.rs | 94 +++++++++++++++++++++++---- libp2p/src/tutorials/hole_punching.rs | 2 - 2 files changed, 83 insertions(+), 13 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 3dbf2416729..c6512c5d055 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,8 +1,12 @@ +use crate::TransportExt; use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::{NetworkBehaviour, Swarm}; use std::convert::Infallible; use std::io; use std::marker::PhantomData; +use std::sync::Arc; + +use crate::bandwidth::BandwidthSinks; /// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. /// @@ -1001,11 +1005,11 @@ impl SwarmBuilder> { impl SwarmBuilder> { - fn without_websocket(self) -> SwarmBuilder> { + fn without_websocket(self) -> SwarmBuilder> { SwarmBuilder { keypair: self.keypair, phantom: PhantomData, - phase: BehaviourPhase { + phase: BandwidthLoggingPhase { relay_behaviour: self.phase.relay_behaviour, transport: self.phase.transport, }, @@ -1022,7 +1026,7 @@ impl self, constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, ) -> Result>, R::Error> { - self.without_websocket().with_behaviour(constructor) + self.without_websocket().without_bandwidth_logging().with_behaviour(constructor) } } @@ -1033,7 +1037,7 @@ impl self, constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { - self.without_websocket().with_behaviour(constructor) + self.without_websocket().without_bandwidth_logging().with_behaviour(constructor) } } @@ -1091,7 +1095,7 @@ impl SwarmBuilder Result< - SwarmBuilder>, + SwarmBuilder>, WebsocketError, > { self.without_tls().with_noise().await @@ -1108,7 +1112,7 @@ impl SwarmBuilder Result< - SwarmBuilder>, + SwarmBuilder>, WebsocketError, > { self.without_tls().with_noise().await @@ -1136,7 +1140,7 @@ macro_rules! construct_behaviour_builder { Ok(SwarmBuilder { keypair: $self.keypair, phantom: PhantomData, - phase: BehaviourPhase { + phase: BandwidthLoggingPhase { transport: websocket_transport .or_transport($self.phase.transport) .map(|either, _| either.into_inner()), @@ -1159,7 +1163,7 @@ macro_rules! impl_websocket_noise_builder { SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, libp2p_tls::Config>> { #[cfg(feature = "noise")] - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -1179,7 +1183,7 @@ macro_rules! impl_websocket_noise_builder { ) ) } - pub async fn without_noise(self) -> Result>, WebsocketError> { + pub async fn without_noise(self) -> Result>, WebsocketError> { construct_behaviour_builder!( self, $dnsTcp, @@ -1192,7 +1196,7 @@ macro_rules! impl_websocket_noise_builder { impl SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> { - pub async fn with_noise(self) -> Result>, WebsocketError> { + pub async fn with_noise(self) -> Result>, WebsocketError> { let _ = self.phase.tls_config; construct_behaviour_builder!( @@ -1235,6 +1239,72 @@ enum WebsocketErrorInner { Dns(#[from] io::Error), } +pub struct BandwidthLoggingPhase { + relay_behaviour: R, + transport: T, +} + +impl + SwarmBuilder> +{ + pub fn with_bandwidth_logging( + self, + ) -> ( + SwarmBuilder>, + Arc, + ) { + let (transport, sinks) = self.phase.transport.with_bandwidth_logging(); + ( + SwarmBuilder { + phase: BehaviourPhase { + relay_behaviour: self.phase.relay_behaviour, + transport, + }, + keypair: self.keypair, + phantom: PhantomData, + }, + sinks, + ) + } + + pub fn without_bandwidth_logging( + self, + ) -> SwarmBuilder> { + SwarmBuilder { + phase: BehaviourPhase { + relay_behaviour: self.phase.relay_behaviour, + transport: self.phase.transport, + }, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +// Shortcuts +#[cfg(feature = "relay")] +impl + SwarmBuilder> +{ + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + ) -> Result>, R::Error> { + self.without_bandwidth_logging().with_behaviour(constructor) + } +} + +impl + SwarmBuilder> +{ + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_bandwidth_logging().with_behaviour(constructor) + } +} + pub struct BehaviourPhase { relay_behaviour: R, transport: T, @@ -1645,7 +1715,7 @@ mod tests { relay: libp2p_relay::client::Behaviour, } - let _ = SwarmBuilder::with_new_identity() + let (builder, _bandwidth_sinks) = SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() .with_tls() @@ -1666,6 +1736,8 @@ mod tests { .with_noise() .await .unwrap() + .with_bandwidth_logging(); + let _: Swarm = builder .with_behaviour(|_key, relay| MyBehaviour { relay }) .unwrap() .build(); diff --git a/libp2p/src/tutorials/hole_punching.rs b/libp2p/src/tutorials/hole_punching.rs index 7b0e7656fd0..161a2feeec4 100644 --- a/libp2p/src/tutorials/hole_punching.rs +++ b/libp2p/src/tutorials/hole_punching.rs @@ -18,8 +18,6 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// TODO: Update - //! # Hole Punching Tutorial //! //! This tutorial shows hands-on how to overcome firewalls and NATs with libp2p's hole punching From 01ea8ebb8fa4c4231ac53f04840f8a00d83d0d82 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 11:48:22 +0200 Subject: [PATCH 074/171] Shortcut for with_bandwidth_logging --- libp2p/src/builder.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index c6512c5d055..7bb51d0c220 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -655,6 +655,19 @@ impl .with_relay() } } +impl + SwarmBuilder> +{ + pub fn with_bandwidth_logging( + self, + ) -> (SwarmBuilder>, Arc) { + self.without_any_other_transports() + .without_dns() + .without_relay() + .without_websocket() + .with_bandwidth_logging() + } +} impl SwarmBuilder> { @@ -666,6 +679,7 @@ impl .without_dns() .without_relay() .without_websocket() + .without_bandwidth_logging() .with_behaviour(constructor) } } From 8f2d043905679ae1e441e01b2d9a17eca1de8353 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 13:04:12 +0200 Subject: [PATCH 075/171] Fix minor CI failures --- examples/ipfs-private/src/main.rs | 2 +- libp2p/src/builder.rs | 30 ++++++++++++++++++++---------- libp2p/src/tutorials/ping.rs | 6 +++--- protocols/perf/src/bin/perf.rs | 16 ++++++++++------ swarm-test/src/lib.rs | 9 +++++++-- swarm/src/lib.rs | 10 +++++----- 6 files changed, 46 insertions(+), 27 deletions(-) diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 34c39dd9313..997399db848 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -130,7 +130,7 @@ async fn main() -> Result<(), Box> { .authenticate(noise_config) .multiplex(yamux_config) .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) - }) + })? .with_dns() .await? .with_behaviour(|key| { diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 7bb51d0c220..688e7cb1738 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -272,7 +272,11 @@ pub struct TcpNoisePhase { phantom: PhantomData, } -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + any(feature = "tls", feature = "noise") +))] macro_rules! construct_quic_builder { ($self:ident, $tcp:ident, $auth:expr) => { SwarmBuilder { @@ -329,9 +333,8 @@ macro_rules! impl_tcp_noise_builder { } } - #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp"))] + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "noise"))] impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { - #[cfg(feature = "noise")] pub fn with_noise( self, ) -> Result< @@ -353,7 +356,6 @@ macro_rules! impl_tcp_noise_builder { impl_tcp_noise_builder!("async-std", AsyncStd, async_io); impl_tcp_noise_builder!("tokio", Tokio, tokio); -#[cfg(any(feature = "tls", feature = "noise"))] pub struct WithoutTls {} #[derive(Debug, thiserror::Error)] @@ -660,7 +662,13 @@ impl { pub fn with_bandwidth_logging( self, - ) -> (SwarmBuilder>, Arc) { + ) -> ( + SwarmBuilder< + Provider, + BehaviourPhase, + >, + Arc, + ) { self.without_any_other_transports() .without_dns() .without_relay() @@ -1040,7 +1048,9 @@ impl self, constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, ) -> Result>, R::Error> { - self.without_websocket().without_bandwidth_logging().with_behaviour(constructor) + self.without_websocket() + .without_bandwidth_logging() + .with_behaviour(constructor) } } @@ -1051,7 +1061,9 @@ impl self, constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, ) -> Result>, R::Error> { - self.without_websocket().without_bandwidth_logging().with_behaviour(constructor) + self.without_websocket() + .without_bandwidth_logging() + .with_behaviour(constructor) } } @@ -1281,9 +1293,7 @@ impl ) } - pub fn without_bandwidth_logging( - self, - ) -> SwarmBuilder> { + pub fn without_bandwidth_logging(self) -> SwarmBuilder> { SwarmBuilder { phase: BehaviourPhase { relay_behaviour: self.phase.relay_behaviour, diff --git a/libp2p/src/tutorials/ping.rs b/libp2p/src/tutorials/ping.rs index 17377172d57..0aaf0970cff 100644 --- a/libp2p/src/tutorials/ping.rs +++ b/libp2p/src/tutorials/ping.rs @@ -171,7 +171,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp() -//! .with_tls()?; +//! .with_tls()? //! .with_behaviour(|_| Behaviour::default())? //! .build(); //! @@ -225,7 +225,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp() -//! .with_tls()?; +//! .with_tls()? //! .with_behaviour(|_| Behaviour::default())? //! .build(); //! @@ -274,7 +274,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp() -//! .with_tls()?; +//! .with_tls()? //! .with_behaviour(|_| Behaviour::default())? //! .build(); //! diff --git a/protocols/perf/src/bin/perf.rs b/protocols/perf/src/bin/perf.rs index b6b090608f5..f9c7b2d1d30 100644 --- a/protocols/perf/src/bin/perf.rs +++ b/protocols/perf/src/bin/perf.rs @@ -31,7 +31,7 @@ use libp2p_core::{ }; use libp2p_identity::PeerId; use libp2p_perf::{Run, RunDuration, RunParams}; -use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent}; +use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmEvent, SwarmConfig}; use log::{error, info}; use serde::{Deserialize, Serialize}; @@ -414,11 +414,15 @@ async fn swarm() -> Result> { .boxed() }; - Ok( - SwarmBuilder::with_tokio_executor(transport, Default::default(), local_peer_id) - .substream_upgrade_protocol_override(upgrade::Version::V1Lazy) - .build(), - ) + let swarm = Swarm::new_with_config( + transport, + Default::default(), + local_peer_id, + SwarmConfig::with_tokio_executor() + .with_substream_upgrade_protocol_override(upgrade::Version::V1Lazy), + ); + + Ok(swarm) } async fn connect( diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index 0ed8dbce220..ba8078232a6 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -28,7 +28,7 @@ use libp2p_identity::{Keypair, PeerId}; use libp2p_plaintext::PlainText2Config; use libp2p_swarm::dial_opts::PeerCondition; use libp2p_swarm::{ - dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent, THandlerErr, + dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent, THandlerErr, }; use libp2p_yamux as yamux; use std::fmt::Debug; @@ -218,7 +218,12 @@ where .timeout(Duration::from_secs(20)) .boxed(); - SwarmBuilder::without_executor(transport, behaviour_fn(identity), peer_id).build() + Swarm::new_with_config( + transport, + behaviour_fn(identity), + peer_id, + SwarmConfig::without_executor(), + ) } async fn connect(&mut self, other: &mut Swarm) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index a8a6400d1c3..7af709aa0e0 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1369,7 +1369,7 @@ pub struct SwarmConfig { impl SwarmConfig { /// Creates a new [`SwarmConfig`] from the given executor. The [`Swarm`] is obtained via - /// [`Swarm::new_from_config`]. + /// [`Swarm::new_with_config`]. pub fn with_executor(executor: impl Executor + Send + 'static) -> Self { Self { pool_config: PoolConfig::new(Some(Box::new(executor))), @@ -1431,7 +1431,7 @@ impl SwarmConfig { /// volume of events. If this value is too low, then the [`Swarm`] will /// be sleeping more often than necessary. Increasing this value increases /// the overall memory usage. - pub fn notify_handler_buffer_size(mut self, n: NonZeroUsize) -> Self { + pub fn with_notify_handler_buffer_size(mut self, n: NonZeroUsize) -> Self { self.pool_config = self.pool_config.with_notify_handler_buffer_size(n); self } @@ -1453,7 +1453,7 @@ impl SwarmConfig { } /// Number of addresses concurrently dialed for a single outbound connection attempt. - pub fn dial_concurrency_factor(mut self, factor: NonZeroU8) -> Self { + pub fn with_dial_concurrency_factor(mut self, factor: NonZeroU8) -> Self { self.pool_config = self.pool_config.with_dial_concurrency_factor(factor); self } @@ -1468,7 +1468,7 @@ impl SwarmConfig { /// > **Note**: If configured, specific upgrade protocols for /// > individual [`SubstreamProtocol`]s emitted by the `NetworkBehaviour` /// > are ignored. - pub fn substream_upgrade_protocol_override(mut self, v: libp2p_core::upgrade::Version) -> Self { + pub fn with_substream_upgrade_protocol_override(mut self, v: libp2p_core::upgrade::Version) -> Self { self.pool_config = self.pool_config.with_substream_upgrade_protocol_override(v); self } @@ -1482,7 +1482,7 @@ impl SwarmConfig { /// connection is the sum of negotiating and negotiated streams. A limit on /// the total number of streams can be enforced at the /// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level. - pub fn max_negotiating_inbound_streams(mut self, v: usize) -> Self { + pub fn with_max_negotiating_inbound_streams(mut self, v: usize) -> Self { self.pool_config = self.pool_config.with_max_negotiating_inbound_streams(v); self } From bc9cf5f0a8818c6dd98f06ad60de09e3e7948609 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 13:36:35 +0200 Subject: [PATCH 076/171] Feature flag any(tls, noise) --- libp2p/src/builder.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 688e7cb1738..668cf5c19d7 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,3 +1,5 @@ +// TODO: Feature flag for yamux. + use crate::TransportExt; use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::{NetworkBehaviour, Swarm}; @@ -109,7 +111,7 @@ impl SwarmBuilder { pub struct TcpPhase {} -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] impl SwarmBuilder { pub fn with_tcp(self) -> SwarmBuilder { self.with_tcp_config(Default::default()) @@ -194,12 +196,12 @@ impl SwarmBuilder { } } -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] pub struct TcpTlsPhase { tcp_config: libp2p_tcp::Config, } -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] impl SwarmBuilder { #[cfg(feature = "tls")] pub fn with_tls( @@ -265,7 +267,7 @@ impl SwarmBuilder { } } -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp"))] +#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] pub struct TcpNoisePhase { tcp_config: libp2p_tcp::Config, tls_config: A, @@ -356,6 +358,7 @@ macro_rules! impl_tcp_noise_builder { impl_tcp_noise_builder!("async-std", AsyncStd, async_io); impl_tcp_noise_builder!("tokio", Tokio, tokio); +#[cfg(any(feature = "tls", feature = "noise"))] pub struct WithoutTls {} #[derive(Debug, thiserror::Error)] From 32162a602efb09e733a12325e1b3a52b95c6ccb6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 14:30:43 +0200 Subject: [PATCH 077/171] Use SwarmConfig --- libp2p/src/builder.rs | 31 ++++++++--- protocols/dcutr/tests/lib.rs | 6 +- protocols/kad/src/behaviour/test.rs | 9 ++- protocols/relay/tests/lib.rs | 10 ++-- swarm/src/lib.rs | 67 ++++++++++++++--------- transports/pnet/tests/smoke.rs | 6 +- transports/tls/tests/smoke.rs | 6 +- transports/webrtc/examples/listen_ping.rs | 10 +++- 8 files changed, 93 insertions(+), 52 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 668cf5c19d7..ecb3b754323 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,5 +1,3 @@ -// TODO: Feature flag for yamux. - use crate::TransportExt; use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::{NetworkBehaviour, Swarm}; @@ -111,7 +109,11 @@ impl SwarmBuilder { pub struct TcpPhase {} -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + any(feature = "tls", feature = "noise") +))] impl SwarmBuilder { pub fn with_tcp(self) -> SwarmBuilder { self.with_tcp_config(Default::default()) @@ -196,12 +198,20 @@ impl SwarmBuilder { } } -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + any(feature = "tls", feature = "noise") +))] pub struct TcpTlsPhase { tcp_config: libp2p_tcp::Config, } -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + any(feature = "tls", feature = "noise") +))] impl SwarmBuilder { #[cfg(feature = "tls")] pub fn with_tls( @@ -267,7 +277,11 @@ impl SwarmBuilder { } } -#[cfg(all(not(target_arch = "wasm32"), feature = "tcp", any(feature = "tls", feature = "noise")))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + any(feature = "tls", feature = "noise") +))] pub struct TcpNoisePhase { tcp_config: libp2p_tcp::Config, tls_config: A, @@ -277,6 +291,7 @@ pub struct TcpNoisePhase { #[cfg(all( not(target_arch = "wasm32"), feature = "tcp", + feature = "yamux", any(feature = "tls", feature = "noise") ))] macro_rules! construct_quic_builder { @@ -297,7 +312,7 @@ macro_rules! construct_quic_builder { macro_rules! impl_tcp_noise_builder { ($providerKebabCase:literal, $providerCamelCase:ident, $tcp:ident) => { - #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "tls"))] + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "tls", feature = "yamux"))] impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { #[cfg(feature = "noise")] pub fn with_noise( @@ -335,7 +350,7 @@ macro_rules! impl_tcp_noise_builder { } } - #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "noise"))] + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "noise", feature = "yamux"))] impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { pub fn with_noise( self, diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index 6888e5914a0..46b0bde4b59 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -26,7 +26,7 @@ use libp2p_identity as identity; use libp2p_identity::PeerId; use libp2p_plaintext::PlainText2Config; use libp2p_relay as relay; -use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent}; +use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; use libp2p_swarm_test::SwarmExt as _; use std::time::Duration; @@ -124,15 +124,15 @@ fn build_client() -> Swarm { .multiplex(libp2p_yamux::Config::default()) .boxed(); - SwarmBuilder::without_executor( + Swarm::new_with_config( transport, Client { relay: behaviour, dcutr: dcutr::Behaviour::new(local_peer_id), }, local_peer_id, + SwarmConfig::without_executor(), ) - .build() } #[derive(NetworkBehaviour)] diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index cd4337e9094..249778f45a7 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -37,7 +37,7 @@ use libp2p_core::{ use libp2p_identity as identity; use libp2p_identity::PeerId; use libp2p_noise as noise; -use libp2p_swarm::{ConnectionId, Swarm, SwarmBuilder, SwarmEvent}; +use libp2p_swarm::{ConnectionId, Swarm, SwarmConfig, SwarmEvent}; use libp2p_yamux as yamux; use quickcheck::*; use rand::{random, rngs::StdRng, thread_rng, Rng, SeedableRng}; @@ -67,7 +67,12 @@ fn build_node_with_config(cfg: KademliaConfig) -> (Multiaddr, TestSwarm) { let store = MemoryStore::new(local_id); let behaviour = Kademlia::with_config(local_id, store, cfg); - let mut swarm = SwarmBuilder::without_executor(transport, behaviour, local_id).build(); + let mut swarm = Swarm::new_with_config( + transport, + behaviour, + local_id, + SwarmConfig::without_executor(), + ); let address: Multiaddr = Protocol::Memory(random::()).into(); swarm.listen_on(address.clone()).unwrap(); diff --git a/protocols/relay/tests/lib.rs b/protocols/relay/tests/lib.rs index fa79ab67f4b..e56fddc5974 100644 --- a/protocols/relay/tests/lib.rs +++ b/protocols/relay/tests/lib.rs @@ -34,7 +34,7 @@ use libp2p_identity::PublicKey; use libp2p_ping as ping; use libp2p_plaintext::PlainText2Config; use libp2p_relay as relay; -use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent}; +use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; use std::time::Duration; #[test] @@ -312,7 +312,7 @@ fn build_relay() -> Swarm { let transport = upgrade_transport(MemoryTransport::default().boxed(), local_public_key); - SwarmBuilder::with_async_std_executor( + Swarm::new_with_config( transport, Relay { ping: ping::Behaviour::new(ping::Config::new()), @@ -325,8 +325,8 @@ fn build_relay() -> Swarm { ), }, local_peer_id, + SwarmConfig::with_async_std_executor(), ) - .build() } fn build_client() -> Swarm { @@ -340,15 +340,15 @@ fn build_client() -> Swarm { local_public_key, ); - SwarmBuilder::with_async_std_executor( + Swarm::new_with_config( transport, Client { ping: ping::Behaviour::new(ping::Config::new()), relay: behaviour, }, local_peer_id, + SwarmConfig::without_executor(), ) - .build() } fn upgrade_transport( diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 7af709aa0e0..93d828e4a74 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1468,7 +1468,10 @@ impl SwarmConfig { /// > **Note**: If configured, specific upgrade protocols for /// > individual [`SubstreamProtocol`]s emitted by the `NetworkBehaviour` /// > are ignored. - pub fn with_substream_upgrade_protocol_override(mut self, v: libp2p_core::upgrade::Version) -> Self { + pub fn with_substream_upgrade_protocol_override( + mut self, + v: libp2p_core::upgrade::Version, + ) -> Self { self.pool_config = self.pool_config.with_substream_upgrade_protocol_override(v); self } @@ -1958,7 +1961,6 @@ mod tests { use super::*; use crate::test::{CallTraceBehaviour, MockBehaviour}; use futures::executor::block_on; - use futures::executor::ThreadPool; use futures::{executor, future}; use libp2p_core::multiaddr::multiaddr; use libp2p_core::transport::memory::MemoryTransportError; @@ -1977,9 +1979,19 @@ mod tests { Disconnecting, } - fn new_test_swarm( + fn new_test_swarm(handler_proto: T) -> Swarm>> + where + T: ConnectionHandler + Clone, + T::ToBehaviour: Clone, + O: Send + 'static, + { + new_test_swarm_with_config(handler_proto, SwarmConfig::with_async_std_executor()) + } + + fn new_test_swarm_with_config( handler_proto: T, - ) -> SwarmBuilder>> + config: SwarmConfig, + ) -> Swarm>> where T: ConnectionHandler + Clone, T::ToBehaviour: Clone, @@ -1995,12 +2007,13 @@ mod tests { .multiplex(yamux::Config::default()) .boxed(); let behaviour = CallTraceBehaviour::new(MockBehaviour::new(handler_proto)); - match ThreadPool::new().ok() { - Some(tp) => { - SwarmBuilder::with_executor(transport, behaviour, local_public_key.into(), tp) - } - None => SwarmBuilder::without_executor(transport, behaviour, local_public_key.into()), - } + + Swarm::new_with_config( + transport, + behaviour, + local_public_key.into(), + config, + ) } fn swarms_connected( @@ -2055,8 +2068,8 @@ mod tests { // use the dummy protocols handler. let handler_proto = keep_alive::ConnectionHandler; - let mut swarm1 = new_test_swarm::<_, ()>(handler_proto.clone()).build(); - let mut swarm2 = new_test_swarm::<_, ()>(handler_proto).build(); + let mut swarm1 = new_test_swarm::<_, ()>(handler_proto.clone()); + let mut swarm2 = new_test_swarm::<_, ()>(handler_proto); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2121,8 +2134,8 @@ mod tests { // use the dummy protocols handler. let handler_proto = keep_alive::ConnectionHandler; - let mut swarm1 = new_test_swarm::<_, ()>(handler_proto.clone()).build(); - let mut swarm2 = new_test_swarm::<_, ()>(handler_proto).build(); + let mut swarm1 = new_test_swarm::<_, ()>(handler_proto.clone()); + let mut swarm2 = new_test_swarm::<_, ()>(handler_proto); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2191,8 +2204,8 @@ mod tests { // use the dummy protocols handler. let handler_proto = keep_alive::ConnectionHandler; - let mut swarm1 = new_test_swarm::<_, ()>(handler_proto.clone()).build(); - let mut swarm2 = new_test_swarm::<_, ()>(handler_proto).build(); + let mut swarm1 = new_test_swarm::<_, ()>(handler_proto.clone()); + let mut swarm2 = new_test_swarm::<_, ()>(handler_proto); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2270,9 +2283,11 @@ mod tests { fn prop(concurrency_factor: DialConcurrencyFactor) { block_on(async { - let mut swarm = new_test_swarm::<_, ()>(keep_alive::ConnectionHandler) - .dial_concurrency_factor(concurrency_factor.0) - .build(); + let mut swarm = new_test_swarm_with_config::<_, ()>( + keep_alive::ConnectionHandler, + SwarmConfig::with_async_std_executor() + .with_dial_concurrency_factor(concurrency_factor.0), + ); // Listen on `concurrency_factor + 1` addresses. // @@ -2338,8 +2353,8 @@ mod tests { // Checks whether dialing an address containing the wrong peer id raises an error // for the expected peer id instead of the obtained peer id. - let mut swarm1 = new_test_swarm::<_, ()>(dummy::ConnectionHandler).build(); - let mut swarm2 = new_test_swarm::<_, ()>(dummy::ConnectionHandler).build(); + let mut swarm1 = new_test_swarm::<_, ()>(dummy::ConnectionHandler); + let mut swarm2 = new_test_swarm::<_, ()>(dummy::ConnectionHandler); swarm1.listen_on("/memory/0".parse().unwrap()).unwrap(); @@ -2398,7 +2413,7 @@ mod tests { // // The last two can happen in any order. - let mut swarm = new_test_swarm::<_, ()>(dummy::ConnectionHandler).build(); + let mut swarm = new_test_swarm::<_, ()>(dummy::ConnectionHandler); swarm.listen_on("/memory/0".parse().unwrap()).unwrap(); let local_address = @@ -2458,7 +2473,7 @@ mod tests { fn dial_self_by_id() { // Trying to dial self by passing the same `PeerId` shouldn't even be possible in the first // place. - let swarm = new_test_swarm::<_, ()>(dummy::ConnectionHandler).build(); + let swarm = new_test_swarm::<_, ()>(dummy::ConnectionHandler); let peer_id = *swarm.local_peer_id(); assert!(!swarm.is_connected(&peer_id)); } @@ -2469,7 +2484,7 @@ mod tests { let target = PeerId::random(); - let mut swarm = new_test_swarm::<_, ()>(dummy::ConnectionHandler).build(); + let mut swarm = new_test_swarm::<_, ()>(dummy::ConnectionHandler); let addresses = HashSet::from([ multiaddr![Ip4([0, 0, 0, 0]), Tcp(rand::random::())], @@ -2515,8 +2530,8 @@ mod tests { fn aborting_pending_connection_surfaces_error() { let _ = env_logger::try_init(); - let mut dialer = new_test_swarm::<_, ()>(dummy::ConnectionHandler).build(); - let mut listener = new_test_swarm::<_, ()>(dummy::ConnectionHandler).build(); + let mut dialer = new_test_swarm::<_, ()>(dummy::ConnectionHandler); + let mut listener = new_test_swarm::<_, ()>(dummy::ConnectionHandler); let listener_peer_id = *listener.local_peer_id(); listener.listen_on(multiaddr![Memory(0u64)]).unwrap(); diff --git a/transports/pnet/tests/smoke.rs b/transports/pnet/tests/smoke.rs index a7635c00ca3..ebe5a67aaee 100644 --- a/transports/pnet/tests/smoke.rs +++ b/transports/pnet/tests/smoke.rs @@ -6,7 +6,7 @@ use libp2p_core::upgrade::Version; use libp2p_core::Transport; use libp2p_core::{multiaddr::Protocol, Multiaddr}; use libp2p_pnet::{PnetConfig, PreSharedKey}; -use libp2p_swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent}; +use libp2p_swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; const TIMEOUT: Duration = Duration::from_secs(5); @@ -113,12 +113,12 @@ where .authenticate(libp2p_noise::Config::new(&identity).unwrap()) .multiplex(libp2p_yamux::Config::default()) .boxed(); - SwarmBuilder::with_tokio_executor( + Swarm::new_with_config( transport, keep_alive::Behaviour, identity.public().to_peer_id(), + SwarmConfig::with_tokio_executor(), ) - .build() } async fn listen_on(swarm: &mut Swarm, addr: Multiaddr) -> Multiaddr { diff --git a/transports/tls/tests/smoke.rs b/transports/tls/tests/smoke.rs index 17aa959c4b2..effd97c0d4c 100644 --- a/transports/tls/tests/smoke.rs +++ b/transports/tls/tests/smoke.rs @@ -3,7 +3,7 @@ use libp2p_core::multiaddr::Protocol; use libp2p_core::transport::MemoryTransport; use libp2p_core::upgrade::Version; use libp2p_core::Transport; -use libp2p_swarm::{keep_alive, Swarm, SwarmBuilder, SwarmEvent}; +use libp2p_swarm::{keep_alive, Swarm, SwarmConfig, SwarmEvent}; #[tokio::test] async fn can_establish_connection() { @@ -64,10 +64,10 @@ fn make_swarm() -> Swarm { .multiplex(libp2p_yamux::Config::default()) .boxed(); - SwarmBuilder::without_executor( + Swarm::new_with_config( transport, keep_alive::Behaviour, identity.public().to_peer_id(), + SwarmConfig::without_executor(), ) - .build() } diff --git a/transports/webrtc/examples/listen_ping.rs b/transports/webrtc/examples/listen_ping.rs index 8475195a1ce..1dadd74ebd0 100644 --- a/transports/webrtc/examples/listen_ping.rs +++ b/transports/webrtc/examples/listen_ping.rs @@ -4,7 +4,7 @@ use libp2p_core::muxing::StreamMuxerBox; use libp2p_core::Transport; use libp2p_identity as identity; use libp2p_ping as ping; -use libp2p_swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmBuilder}; +use libp2p_swarm::{keep_alive, NetworkBehaviour, Swarm, SwarmConfig}; use rand::thread_rng; use void::Void; @@ -33,7 +33,13 @@ fn create_swarm() -> Result> { .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) .boxed(); - Ok(SwarmBuilder::with_tokio_executor(transport, Behaviour::default(), peer_id).build()) + Ok(SwarmConfig::new_with_config( + transport, + Behaviour::default(), + peer_id, + SwarmConfig::with_tokio_executor(), + ) + .build()) } #[derive(NetworkBehaviour, Default)] From 054c9d3d2ec27b9938b85a82962206a05157e144 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 14:33:18 +0200 Subject: [PATCH 078/171] Typo --- transports/webrtc/examples/listen_ping.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transports/webrtc/examples/listen_ping.rs b/transports/webrtc/examples/listen_ping.rs index 1dadd74ebd0..7e74bab7d9b 100644 --- a/transports/webrtc/examples/listen_ping.rs +++ b/transports/webrtc/examples/listen_ping.rs @@ -33,7 +33,7 @@ fn create_swarm() -> Result> { .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) .boxed(); - Ok(SwarmConfig::new_with_config( + Ok(Swarm::new_with_config( transport, Behaviour::default(), peer_id, From 4f909c96e8f85383e187a68b24b5df69a0ae74fe Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 14:36:33 +0200 Subject: [PATCH 079/171] Don't build swarm --- transports/webrtc/examples/listen_ping.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/transports/webrtc/examples/listen_ping.rs b/transports/webrtc/examples/listen_ping.rs index 7e74bab7d9b..c36e93fa5ca 100644 --- a/transports/webrtc/examples/listen_ping.rs +++ b/transports/webrtc/examples/listen_ping.rs @@ -38,8 +38,7 @@ fn create_swarm() -> Result> { Behaviour::default(), peer_id, SwarmConfig::with_tokio_executor(), - ) - .build()) + )) } #[derive(NetworkBehaviour, Default)] From 9f640f3cef31faf47654769da880b4b793a51c6e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 14:39:12 +0200 Subject: [PATCH 080/171] fmt --- protocols/perf/src/bin/perf.rs | 2 +- swarm/src/lib.rs | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/protocols/perf/src/bin/perf.rs b/protocols/perf/src/bin/perf.rs index f9c7b2d1d30..6318839573d 100644 --- a/protocols/perf/src/bin/perf.rs +++ b/protocols/perf/src/bin/perf.rs @@ -31,7 +31,7 @@ use libp2p_core::{ }; use libp2p_identity::PeerId; use libp2p_perf::{Run, RunDuration, RunParams}; -use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmEvent, SwarmConfig}; +use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; use log::{error, info}; use serde::{Deserialize, Serialize}; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 93d828e4a74..405daed782c 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -2008,12 +2008,7 @@ mod tests { .boxed(); let behaviour = CallTraceBehaviour::new(MockBehaviour::new(handler_proto)); - Swarm::new_with_config( - transport, - behaviour, - local_public_key.into(), - config, - ) + Swarm::new_with_config(transport, behaviour, local_public_key.into(), config) } fn swarms_connected( From 732072e98c24d2c18d14f9758b9de764b20f4954 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 17:53:31 +0200 Subject: [PATCH 081/171] Bump versions and add changelog entries --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- libp2p/CHANGELOG.md | 9 +++++++++ libp2p/Cargo.toml | 2 +- swarm/CHANGELOG.md | 9 +++++++++ swarm/Cargo.toml | 2 +- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c2be23c4b7..04d9254b9e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2509,7 +2509,7 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libp2p" -version = "0.52.3" +version = "0.52.4" dependencies = [ "async-std", "async-trait", @@ -3188,7 +3188,7 @@ dependencies = [ [[package]] name = "libp2p-swarm" -version = "0.43.3" +version = "0.43.4" dependencies = [ "async-std", "either", diff --git a/Cargo.toml b/Cargo.toml index 97c8c10adfa..8c3d84d0501 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ resolver = "2" rust-version = "1.65.0" [workspace.dependencies] -libp2p = { version = "0.52.3", path = "libp2p" } +libp2p = { version = "0.52.4", path = "libp2p" } libp2p-allow-block-list = { version = "0.2.0", path = "misc/allow-block-list" } libp2p-autonat = { version = "0.11.0", path = "protocols/autonat" } libp2p-connection-limits = { version = "0.2.1", path = "misc/connection-limits" } @@ -92,7 +92,7 @@ libp2p-relay = { version = "0.16.1", path = "protocols/relay" } libp2p-rendezvous = { version = "0.13.0", path = "protocols/rendezvous" } libp2p-request-response = { version = "0.25.1", path = "protocols/request-response" } libp2p-server = { version = "0.12.2", path = "misc/server" } -libp2p-swarm = { version = "0.43.3", path = "swarm" } +libp2p-swarm = { version = "0.43.4", path = "swarm" } libp2p-swarm-derive = { version = "0.33.0", path = "swarm-derive" } libp2p-swarm-test = { version = "0.2.0", path = "swarm-test" } libp2p-tcp = { version = "0.40.0", path = "transports/tcp" } diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 414c11058cb..11075907720 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.52.4 + +- 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. + Also see [PR 4120]. + +[PR 4120]: https://github.com/libp2p/rust-libp2p/pull/4120 + ## 0.52.3 - Add `libp2p-quic` stable release. diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 5c68dc69517..df9f7f64a7b 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p" edition = "2021" rust-version = { workspace = true } description = "Peer-to-peer networking library" -version = "0.52.3" +version = "0.52.4" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 37a5cbc6157..613567980d8 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.43.4 - unreleased + +- Deprecate old `libp2p::swarm::SwarmBuilder`. + Most users should use the new `libp2p::SwarmBuilder`. + In some special cases, users may need to use `Swarm::new_with_config` and `SwarmConfig` instead of the new `libp2p::SwarmBuilder`. + See [PR 4120]. + +[PR 4120]: https://github.com/libp2p/rust-libp2p/pull/4120 + ## 0.43.3 - Implement `Display` for `ConnectionId`. diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index c2b959eea01..b739aa8dabb 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-swarm" edition = "2021" rust-version = { workspace = true } description = "The libp2p swarm" -version = "0.43.3" +version = "0.43.4" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" From 0b74e3fa5484b21569b081a3fb8399be22c9490b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 18:07:07 +0200 Subject: [PATCH 082/171] Fix relay tests --- protocols/relay/tests/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/relay/tests/lib.rs b/protocols/relay/tests/lib.rs index e56fddc5974..c146c5ac77c 100644 --- a/protocols/relay/tests/lib.rs +++ b/protocols/relay/tests/lib.rs @@ -347,7 +347,7 @@ fn build_client() -> Swarm { relay: behaviour, }, local_peer_id, - SwarmConfig::without_executor(), + SwarmConfig::with_async_std_executor(), ) } From a39a1778df8d861d85738e8e2df38cbc9e46a318 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:07:48 +0200 Subject: [PATCH 083/171] Move upgrade::Map into builder/map.rs --- core/src/upgrade.rs | 2 -- libp2p/src/builder.rs | 11 +++++++---- {core/src/upgrade => libp2p/src/builder}/map.rs | 5 ++--- 3 files changed, 9 insertions(+), 9 deletions(-) rename {core/src/upgrade => libp2p/src/builder}/map.rs (95%) diff --git a/core/src/upgrade.rs b/core/src/upgrade.rs index 3219474f390..f6bf72d1f4a 100644 --- a/core/src/upgrade.rs +++ b/core/src/upgrade.rs @@ -61,7 +61,6 @@ mod apply; mod denied; mod either; mod error; -mod map; mod pending; mod ready; mod select; @@ -75,7 +74,6 @@ use futures::future::Future; pub use self::{ denied::DeniedUpgrade, - map::Map, pending::PendingUpgrade, ready::ReadyUpgrade, select::SelectUpgrade, diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index ecb3b754323..44ce6512220 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,4 +1,3 @@ -use crate::TransportExt; use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_swarm::{NetworkBehaviour, Swarm}; use std::convert::Infallible; @@ -6,7 +5,11 @@ use std::io; use std::marker::PhantomData; use std::sync::Arc; +use crate::TransportExt; use crate::bandwidth::BandwidthSinks; +use map::Map as MapUpgrade; + +mod map; /// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. /// @@ -324,7 +327,7 @@ macro_rules! impl_tcp_noise_builder { Ok(construct_quic_builder!( self, $tcp, - libp2p_core::upgrade::Map::new( + MapUpgrade::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, libp2p_noise::Config::new(&self.keypair) @@ -944,7 +947,7 @@ impl > { Ok(construct_websocket_builder!( self, - libp2p_core::upgrade::Map::new( + MapUpgrade::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, libp2p_noise::Config::new(&self.keypair) @@ -1211,7 +1214,7 @@ macro_rules! impl_websocket_noise_builder { construct_behaviour_builder!( self, $dnsTcp, - libp2p_core::upgrade::Map::new( + MapUpgrade::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, libp2p_noise::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))?, diff --git a/core/src/upgrade/map.rs b/libp2p/src/builder/map.rs similarity index 95% rename from core/src/upgrade/map.rs rename to libp2p/src/builder/map.rs index ad8a593dd11..8ba619f27c1 100644 --- a/core/src/upgrade/map.rs +++ b/libp2p/src/builder/map.rs @@ -18,13 +18,12 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; +use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; use futures::future::{self, TryFutureExt}; -// TODO: Rename to MapUpgrade? /// Upgrade applying a function to an inner upgrade. #[derive(Debug, Clone)] -pub struct Map { +pub(crate) struct Map { upgrade: U, fun: F, } From 97bf5356283d54030bd739223ace796a09d6dc06 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:15:33 +0200 Subject: [PATCH 084/171] Bail on mplex --- interop-tests/src/arch.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index b21464cedb8..c14e16cef62 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -21,7 +21,7 @@ pub(crate) mod native { use libp2p_webrtc as webrtc; use redis::AsyncCommands; - use crate::{from_env, SecProtocol, Transport}; + use crate::{from_env, Muxer, SecProtocol, Transport}; pub(crate) type Instant = std::time::Instant; @@ -35,6 +35,15 @@ pub(crate) mod native { tokio::time::sleep(duration).boxed() } + fn expect_muxer_yamux() -> Result<()> { + Ok(match from_env("muxer")? { + Muxer::Yamux => (), + Muxer::Mplex => { + bail!("Only Yamux is supported, not Mplex") + } + }) + } + // TODO: Error in case muxer is not yamux. pub(crate) async fn build_swarm( ip: &str, @@ -51,7 +60,8 @@ pub(crate) mod native { (swarm, format!("/ip4/{ip}/udp/0/quic-v1")) } (Transport::Tcp, Ok(SecProtocol::Tls)) => { - // TODO: Note that the timeout of 5 secs is gone now. + expect_muxer_yamux()?; + let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() @@ -61,7 +71,8 @@ pub(crate) mod native { (swarm, format!("/ip4/{ip}/tcp/0")) } (Transport::Tcp, Ok(SecProtocol::Noise)) => { - // TODO: Note that the timeout of 5 secs is gone now. + expect_muxer_yamux()?; + let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp() @@ -71,6 +82,8 @@ pub(crate) mod native { (swarm, format!("/ip4/{ip}/tcp/0")) } (Transport::Ws, Ok(SecProtocol::Tls)) => { + expect_muxer_yamux()?; + let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_websocket() @@ -82,6 +95,8 @@ pub(crate) mod native { (swarm, format!("/ip4/{ip}/tcp/0/ws")) } (Transport::Ws, Ok(SecProtocol::Noise)) => { + expect_muxer_yamux()?; + let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_websocket() From ce43526748252c0ba70abcdc72f17f9683b8272c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:18:11 +0200 Subject: [PATCH 085/171] Remove obsolete TODO --- interop-tests/src/arch.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index c14e16cef62..11a36de308a 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -44,7 +44,6 @@ pub(crate) mod native { }) } - // TODO: Error in case muxer is not yamux. pub(crate) async fn build_swarm( ip: &str, transport: Transport, From c6d580c2f5fc1e7ef5c624cb33c5ae800e064d6c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:22:47 +0200 Subject: [PATCH 086/171] Feature flag map module --- libp2p/src/builder.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 44ce6512220..7c0a77040f3 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -5,10 +5,11 @@ use std::io; use std::marker::PhantomData; use std::sync::Arc; -use crate::TransportExt; use crate::bandwidth::BandwidthSinks; +use crate::TransportExt; use map::Map as MapUpgrade; +#[cfg(not(target_arch = "wasm32"))] mod map; /// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. From e497cb2ee6f05225013c1a3ba5ef2a4e20a9dc9a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:27:25 +0200 Subject: [PATCH 087/171] More feature flags --- libp2p/src/builder.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 7c0a77040f3..4ad75fa1f9b 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -9,7 +9,12 @@ use crate::bandwidth::BandwidthSinks; use crate::TransportExt; use map::Map as MapUpgrade; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "tls", + feature = "noise", + any(feature = "tcp", feature = "relay", feature = "websocket") +))] mod map; /// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. From a80d72654594b5b6c23930faf250d2acd140fee3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:30:20 +0200 Subject: [PATCH 088/171] Remove use for map --- libp2p/src/builder.rs | 7 +++---- libp2p/src/builder/map.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 4ad75fa1f9b..99137212c7f 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -7,7 +7,6 @@ use std::sync::Arc; use crate::bandwidth::BandwidthSinks; use crate::TransportExt; -use map::Map as MapUpgrade; #[cfg(all( not(target_arch = "wasm32"), @@ -333,7 +332,7 @@ macro_rules! impl_tcp_noise_builder { Ok(construct_quic_builder!( self, $tcp, - MapUpgrade::new( + map::Upgrade::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, libp2p_noise::Config::new(&self.keypair) @@ -953,7 +952,7 @@ impl > { Ok(construct_websocket_builder!( self, - MapUpgrade::new( + map::Upgrade::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, libp2p_noise::Config::new(&self.keypair) @@ -1220,7 +1219,7 @@ macro_rules! impl_websocket_noise_builder { construct_behaviour_builder!( self, $dnsTcp, - MapUpgrade::new( + map::Upgrade::new( libp2p_core::upgrade::SelectUpgrade::new( self.phase.tls_config, libp2p_noise::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))?, diff --git a/libp2p/src/builder/map.rs b/libp2p/src/builder/map.rs index 8ba619f27c1..fdd42ac00a7 100644 --- a/libp2p/src/builder/map.rs +++ b/libp2p/src/builder/map.rs @@ -23,19 +23,19 @@ use futures::future::{self, TryFutureExt}; /// Upgrade applying a function to an inner upgrade. #[derive(Debug, Clone)] -pub(crate) struct Map { +pub(crate) struct Upgrade { upgrade: U, fun: F, } -impl Map { +impl Upgrade { /// Applies the function on the result of the upgrade. pub fn new(upgrade: U, fun: F) -> Self { - Map { upgrade, fun } + Upgrade { upgrade, fun } } } -impl UpgradeInfo for Map +impl UpgradeInfo for Upgrade where U: UpgradeInfo, { @@ -47,7 +47,7 @@ where } } -impl InboundUpgrade for Map +impl InboundUpgrade for Upgrade where U: InboundUpgrade, F: FnOnce(U::Output) -> D, @@ -61,7 +61,7 @@ where } } -impl OutboundUpgrade for Map +impl OutboundUpgrade for Upgrade where U: OutboundUpgrade, F: FnOnce(U::Output) -> D, From 848f36077750791d6ed3ebb21ff258d8655987ef Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:32:51 +0200 Subject: [PATCH 089/171] Make Upgrade::new pub(crate) --- libp2p/src/builder/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/src/builder/map.rs b/libp2p/src/builder/map.rs index fdd42ac00a7..3b37472d934 100644 --- a/libp2p/src/builder/map.rs +++ b/libp2p/src/builder/map.rs @@ -30,7 +30,7 @@ pub(crate) struct Upgrade { impl Upgrade { /// Applies the function on the result of the upgrade. - pub fn new(upgrade: U, fun: F) -> Self { + pub(crate) fn new(upgrade: U, fun: F) -> Self { Upgrade { upgrade, fun } } } From 14954f07d73cd86f6cb810cceff70cb037348ddd Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 3 Sep 2023 20:37:56 +0200 Subject: [PATCH 090/171] Clippy --- interop-tests/src/arch.rs | 5 +++-- libp2p/src/builder/map.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 11a36de308a..0dfc68f282c 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -36,12 +36,13 @@ pub(crate) mod native { } fn expect_muxer_yamux() -> Result<()> { - Ok(match from_env("muxer")? { + match from_env("muxer")? { Muxer::Yamux => (), Muxer::Mplex => { bail!("Only Yamux is supported, not Mplex") } - }) + }; + Ok(()) } pub(crate) async fn build_swarm( diff --git a/libp2p/src/builder/map.rs b/libp2p/src/builder/map.rs index 3b37472d934..d3909c61b7b 100644 --- a/libp2p/src/builder/map.rs +++ b/libp2p/src/builder/map.rs @@ -18,8 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; use futures::future::{self, TryFutureExt}; +use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; /// Upgrade applying a function to an inner upgrade. #[derive(Debug, Clone)] From fa3056116af16f53e6003480844f192212888022 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 5 Sep 2023 09:59:32 +0200 Subject: [PATCH 091/171] Update libp2p/CHANGELOG.md Co-authored-by: Thomas Eizinger --- libp2p/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 11075907720..cbd18f6fe29 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.52.4 +## 0.52.4 - unreleased - Introduce the new `libp2p::SwarmBuilder`. Users should use the new `libp2p::SwarmBuilder` instead of the now deprecated `libp2p::swarm::SwarmBuilder`. From c6c8ca4f9dcf6df5cdadb6cd44c179555785616f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 7 Sep 2023 11:11:48 +0200 Subject: [PATCH 092/171] Update libp2p/src/lib.rs Co-authored-by: Thomas Eizinger --- libp2p/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 3368f2e7d39..b646cecce94 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -143,7 +143,6 @@ pub use libp2p_webtransport_websys as webtransport_websys; pub use libp2p_yamux as yamux; mod builder; - mod transport_ext; pub mod bandwidth; From aa19b1f7c3f938d99ec758326bed497972fe4898 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 16 Sep 2023 14:41:58 +0200 Subject: [PATCH 093/171] [WIP] with_tcp including sec and mux It compiles :tada: --- libp2p/src/builder.rs | 104 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 99137212c7f..d376c45cc27 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,4 +1,6 @@ use libp2p_core::{muxing::StreamMuxerBox, Transport}; +use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, StreamMuxer, UpgradeInfo}; +use libp2p_identity::{Keypair, PeerId}; use libp2p_swarm::{NetworkBehaviour, Swarm}; use std::convert::Infallible; use std::io; @@ -127,6 +129,61 @@ impl SwarmBuilder { self.with_tcp_config(Default::default()) } + pub fn with_tcp_2( + self, + security_upgrade: SecU, + multiplexer_upgrade: MuxU, + ) -> Result< + SwarmBuilder>, + AuthenticationError, + > + where + D: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecU: IntoSecurityUpgrade, + SecU::Upgrade: InboundUpgrade< + Negotiated, + Output = (PeerId, D), + Error = E, + >, + >>::Future: Send, + SecU::Upgrade: OutboundUpgrade< + Negotiated, + Output = (PeerId, D), + Error = E, + > + Clone + + Send + 'static, + + >>::Future: Send, + E: std::error::Error + Send + Sync + 'static, + <<::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <::Upgrade as UpgradeInfo>::Info: Send, + + MuxM: StreamMuxer + Send + 'static, + MuxM::Substream: Send + 'static, + MuxM::Error: Send + Sync + 'static, + + MuxU: IntoMultiplexerUpgrade, + MuxU::Upgrade: InboundUpgrade, Output = MuxM, Error = MuxE>, + >>::Future: Send, + MuxU::Upgrade: OutboundUpgrade, Output = MuxM, Error = MuxE> + Clone + Send + 'static, + >>::Future: Send, + MuxE: std::error::Error + Send + Sync + 'static, + <<::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <::Upgrade as UpgradeInfo>::Info: Send, + { + Ok(SwarmBuilder { + phase: QuicPhase { + transport: libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate(security_upgrade.into_security_upgrade(&self.keypair)) + .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + }, + keypair: self.keypair, + phantom: PhantomData, + }) + } + pub fn with_tcp_config( self, tcp_config: libp2p_tcp::Config, @@ -139,6 +196,37 @@ impl SwarmBuilder { } } +pub trait IntoSecurityUpgrade { + type Upgrade; + + fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade; +} + +impl IntoSecurityUpgrade for F +where + F: for<'a> FnOnce(&'a Keypair) -> T, +{ + type Upgrade = T; + + fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade { + self(keypair) + } +} + +pub trait IntoMultiplexerUpgrade { + type Upgrade; + + fn into_multiplexer_upgrade(self) -> Self::Upgrade; +} + +impl IntoMultiplexerUpgrade for U { + type Upgrade = Self; + + fn into_multiplexer_upgrade(self) -> Self::Upgrade { + self + } +} + impl SwarmBuilder { // TODO: This would allow one to build a faulty transport. fn without_tcp( @@ -1615,6 +1703,22 @@ mod tests { .build(); } + #[test] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] + fn tcp2() { + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp_2( + // TODO: Handle unwrap + |keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(), + libp2p_yamux::Config::default(), + ) + .unwrap() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); + } + #[test] #[cfg(all( feature = "tokio", From 14c199fc1fcfb9c3f4b0eeb3152d00634afaaa31 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 17 Sep 2023 10:43:47 +0200 Subject: [PATCH 094/171] [WIP] add support for tls+noise and yamux+mplex --- Cargo.lock | 1 + libp2p/Cargo.toml | 1 + libp2p/src/builder.rs | 147 ++++++++++++++++++++++++++------------ libp2p/src/builder/map.rs | 2 +- 4 files changed, 106 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04d9254b9e5..553dd42fc91 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2536,6 +2536,7 @@ dependencies = [ "libp2p-mdns", "libp2p-memory-connection-limits", "libp2p-metrics", + "libp2p-mplex", "libp2p-noise", "libp2p-ping", "libp2p-plaintext", diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index df9f7f64a7b..b29d3797b9d 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -144,6 +144,7 @@ env_logger = "0.10.0" clap = { version = "4.1.6", features = ["derive"] } tokio = { version = "1.15", features = ["io-util", "io-std", "macros", "rt", "rt-multi-thread"] } +libp2p-mplex = { workspace = true } libp2p-noise = { workspace = true } libp2p-tcp = { workspace = true, features = ["tokio"] } diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index d376c45cc27..344f5d1833e 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,3 +1,4 @@ +use libp2p_core::upgrade::SelectUpgrade; use libp2p_core::{muxing::StreamMuxerBox, Transport}; use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, StreamMuxer, UpgradeInfo}; use libp2p_identity::{Keypair, PeerId}; @@ -129,47 +130,38 @@ impl SwarmBuilder { self.with_tcp_config(Default::default()) } - pub fn with_tcp_2( + pub fn with_tcp_2( self, - security_upgrade: SecU, - multiplexer_upgrade: MuxU, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, ) -> Result< SwarmBuilder>, AuthenticationError, > where - D: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecU: IntoSecurityUpgrade, - SecU::Upgrade: InboundUpgrade< - Negotiated, - Output = (PeerId, D), - Error = E, - >, - >>::Future: Send, - SecU::Upgrade: OutboundUpgrade< - Negotiated, - Output = (PeerId, D), - Error = E, - > + Clone - + Send + 'static, - - >>::Future: Send, - E: std::error::Error + Send + Sync + 'static, - <<::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <::Upgrade as UpgradeInfo>::Info: Send, - - MuxM: StreamMuxer + Send + 'static, - MuxM::Substream: Send + 'static, - MuxM::Error: Send + Sync + 'static, - - MuxU: IntoMultiplexerUpgrade, - MuxU::Upgrade: InboundUpgrade, Output = MuxM, Error = MuxE>, - >>::Future: Send, - MuxU::Upgrade: OutboundUpgrade, Output = MuxM, Error = MuxE> + Clone + Send + 'static, - >>::Future: Send, - MuxE: std::error::Error + Send + Sync + 'static, - <<::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <::Upgrade as UpgradeInfo>::Info: Send, + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: Clone + Send + 'static, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError>, + >>::Future: Send, + SecUpgrade::Upgrade: OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError>, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError>, + >>::Future: Send, + MuxUpgrade::Upgrade: OutboundUpgrade, Output = MuxStream, Error = MuxError>, + MuxUpgrade::Upgrade: Clone + Send + 'static, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, { Ok(SwarmBuilder { phase: QuicPhase { @@ -196,34 +188,59 @@ impl SwarmBuilder { } } -pub trait IntoSecurityUpgrade { +pub trait IntoSecurityUpgrade { type Upgrade; fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade; } -impl IntoSecurityUpgrade for F +impl IntoSecurityUpgrade for (F,) where F: for<'a> FnOnce(&'a Keypair) -> T, { type Upgrade = T; fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade { - self(keypair) + self.0(keypair) } } -pub trait IntoMultiplexerUpgrade { +impl IntoSecurityUpgrade for (F1, F2) +where + F1: for<'a> FnOnce(&'a Keypair) -> T1, + F2: for<'a> FnOnce(&'a Keypair) -> T2, + T1: InboundUpgrade, Output = (PeerId, O1)>, + T2: InboundUpgrade, Output = (PeerId, O2)>, +{ + type Upgrade = map::Upgrade, fn(futures::future::Either<>>::Output, >>::Output>) -> (PeerId, futures::future::Either)>; + + fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade { + map::Upgrade::new( + SelectUpgrade::new(self.0(keypair), self.1(keypair)), + |either |futures::future::Either::factor_first(either), + ) + } +} + +pub trait IntoMultiplexerUpgrade { type Upgrade; fn into_multiplexer_upgrade(self) -> Self::Upgrade; } -impl IntoMultiplexerUpgrade for U { - type Upgrade = Self; +impl IntoMultiplexerUpgrade for (U,) { + type Upgrade = U; + + fn into_multiplexer_upgrade(self) -> Self::Upgrade { + self.0 + } +} + +impl IntoMultiplexerUpgrade for (U1, U2) { + type Upgrade = SelectUpgrade; fn into_multiplexer_upgrade(self) -> Self::Upgrade { - self + SelectUpgrade::new(self.0, self.1) } } @@ -1710,8 +1727,50 @@ mod tests { .with_tokio() .with_tcp_2( // TODO: Handle unwrap - |keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(), - libp2p_yamux::Config::default(), + (|keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(),), + // TODO: The single tuple is not intuitive. + (libp2p_yamux::Config::default(),), + ) + .unwrap() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); + } + + #[test] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] + fn tcp_yamux_mplex() { + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp_2( + // TODO: Handle unwrap + (|keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(),), + ( + libp2p_yamux::Config::default(), + libp2p_mplex::MplexConfig::default(), + ), + ) + .unwrap() + .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) + .unwrap() + .build(); + } + + #[test] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] + fn tcp_tls_noise() { + let _ = SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp_2( + // TODO: Handle unwrap + ( + |keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(), + |keypair: &Keypair| libp2p_noise::Config::new(keypair).unwrap(), + ), + ( + libp2p_yamux::Config::default(), + libp2p_mplex::MplexConfig::default(), + ), ) .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) diff --git a/libp2p/src/builder/map.rs b/libp2p/src/builder/map.rs index d3909c61b7b..36cb1194269 100644 --- a/libp2p/src/builder/map.rs +++ b/libp2p/src/builder/map.rs @@ -23,7 +23,7 @@ use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; /// Upgrade applying a function to an inner upgrade. #[derive(Debug, Clone)] -pub(crate) struct Upgrade { +pub struct Upgrade { upgrade: U, fun: F, } From 7f6da36c54e013f8f7dde2b5e67c5fbc4af71155 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 25 Sep 2023 13:55:04 +0200 Subject: [PATCH 095/171] Be generic over provider --- libp2p/Cargo.toml | 1 + libp2p/src/builder.rs | 509 +++++++----------------- transports/tcp/src/provider/async_io.rs | 4 +- 3 files changed, 150 insertions(+), 364 deletions(-) diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index b29d3797b9d..869cbe40510 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -93,6 +93,7 @@ yamux = ["dep:libp2p-yamux"] [dependencies] bytes = "1" +either = "1.9.0" futures = "0.3.26" futures-timer = "3.0.2" # Explicit dependency to be used in `wasm-bindgen` feature getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 344f5d1833e..880c3f40efb 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -120,105 +120,114 @@ impl SwarmBuilder { pub struct TcpPhase {} -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - any(feature = "tls", feature = "noise") -))] -impl SwarmBuilder { - pub fn with_tcp(self) -> SwarmBuilder { - self.with_tcp_config(Default::default()) - } - - pub fn with_tcp_2( - self, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder>, - AuthenticationError, - > - where - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade, - SecUpgrade::Upgrade: Clone + Send + 'static, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError>, - >>::Future: Send, - SecUpgrade::Upgrade: OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError>, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError>, - >>::Future: Send, - MuxUpgrade::Upgrade: OutboundUpgrade, Output = MuxStream, Error = MuxError>, - MuxUpgrade::Upgrade: Clone + Send + 'static, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - { - Ok(SwarmBuilder { - phase: QuicPhase { - transport: libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate(security_upgrade.into_security_upgrade(&self.keypair)) - .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } - - pub fn with_tcp_config( - self, - tcp_config: libp2p_tcp::Config, - ) -> SwarmBuilder { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: TcpTlsPhase { tcp_config }, +macro_rules! impl_tcp_builder { + ($providerKebabCase:literal, $providerCamelCase:ident, $path:ident) => { + #[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + feature = $providerKebabCase, + ))] + impl SwarmBuilder<$providerCamelCase, TcpPhase> { + pub fn with_tcp( + self, + tcp_config: libp2p_tcp::Config, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder<$providerCamelCase, QuicPhase>, + Box, + > + where + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + Ok(SwarmBuilder { + phase: QuicPhase { + transport: libp2p_tcp::$path::Transport::new(tcp_config) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate( + security_upgrade + .into_security_upgrade(&self.keypair) + .map_err(Box::new)?, + ) + .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + }, + keypair: self.keypair, + phantom: PhantomData, + }) + } } - } + }; } +impl_tcp_builder!("async-std", AsyncStd, async_io); +impl_tcp_builder!("tokio", Tokio, tokio); + pub trait IntoSecurityUpgrade { type Upgrade; + type Error: std::error::Error + 'static; - fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade; + fn into_security_upgrade(self, keypair: &Keypair) -> Result; } -impl IntoSecurityUpgrade for (F,) +impl IntoSecurityUpgrade for (F,) where - F: for<'a> FnOnce(&'a Keypair) -> T, + F: for<'a> FnOnce(&'a Keypair) -> Result, + E: std::error::Error + 'static, { type Upgrade = T; + type Error = E; - fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade { + fn into_security_upgrade(self, keypair: &Keypair) -> Result { self.0(keypair) } } -impl IntoSecurityUpgrade for (F1, F2) +impl IntoSecurityUpgrade for (F1, F2) where - F1: for<'a> FnOnce(&'a Keypair) -> T1, - F2: for<'a> FnOnce(&'a Keypair) -> T2, + F1: for<'a> FnOnce(&'a Keypair) -> Result, + F2: for<'a> FnOnce(&'a Keypair) -> Result, T1: InboundUpgrade, Output = (PeerId, O1)>, T2: InboundUpgrade, Output = (PeerId, O2)>, + E1: std::error::Error + 'static, + E2: std::error::Error + 'static, { - type Upgrade = map::Upgrade, fn(futures::future::Either<>>::Output, >>::Output>) -> (PeerId, futures::future::Either)>; + type Upgrade = map::Upgrade< + SelectUpgrade, + fn( + futures::future::Either< + >>::Output, + >>::Output, + >, + ) -> (PeerId, futures::future::Either), + >; + type Error = either::Either; - fn into_security_upgrade(self, keypair: &Keypair) -> Self::Upgrade { - map::Upgrade::new( - SelectUpgrade::new(self.0(keypair), self.1(keypair)), - |either |futures::future::Either::factor_first(either), - ) + fn into_security_upgrade(self, keypair: &Keypair) -> Result { + let u1 = self.0(keypair).map_err(either::Either::Left)?; + let u2 = self.1(keypair).map_err(either::Either::Right)?; + + Ok(map::Upgrade::new(SelectUpgrade::new(u1, u2), |either| { + futures::future::Either::factor_first(either) + })) } } @@ -311,181 +320,6 @@ impl SwarmBuilder { } } -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - any(feature = "tls", feature = "noise") -))] -pub struct TcpTlsPhase { - tcp_config: libp2p_tcp::Config, -} - -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - any(feature = "tls", feature = "noise") -))] -impl SwarmBuilder { - #[cfg(feature = "tls")] - pub fn with_tls( - self, - ) -> Result>, AuthenticationError> - { - Ok(SwarmBuilder { - phase: TcpNoisePhase { - tcp_config: self.phase.tcp_config, - tls_config: libp2p_tls::Config::new(&self.keypair) - .map_err(|e| AuthenticationError(e.into()))?, - phantom: PhantomData, - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } - - fn without_tls(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: TcpNoisePhase { - tcp_config: self.phase.tcp_config, - tls_config: WithoutTls {}, - phantom: PhantomData, - }, - } - } -} - -// Shortcuts -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - feature = "noise", - feature = "async-std" -))] -impl SwarmBuilder { - pub fn with_noise( - self, - ) -> Result< - SwarmBuilder>, - AuthenticationError, - > { - self.without_tls().with_noise() - } -} -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - feature = "noise", - feature = "tokio" -))] -impl SwarmBuilder { - pub fn with_noise( - self, - ) -> Result< - SwarmBuilder>, - AuthenticationError, - > { - self.without_tls().with_noise() - } -} - -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - any(feature = "tls", feature = "noise") -))] -pub struct TcpNoisePhase { - tcp_config: libp2p_tcp::Config, - tls_config: A, - phantom: PhantomData, -} - -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - feature = "yamux", - any(feature = "tls", feature = "noise") -))] -macro_rules! construct_quic_builder { - ($self:ident, $tcp:ident, $auth:expr) => { - SwarmBuilder { - phase: QuicPhase { - transport: libp2p_tcp::$tcp::Transport::new($self.phase.tcp_config) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate($auth) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - }, - keypair: $self.keypair, - phantom: PhantomData, - } - }; -} - -macro_rules! impl_tcp_noise_builder { - ($providerKebabCase:literal, $providerCamelCase:ident, $tcp:ident) => { - #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "tls", feature = "yamux"))] - impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { - #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> Result< - SwarmBuilder<$providerCamelCase, QuicPhase>, - AuthenticationError, - > { - Ok(construct_quic_builder!( - self, - $tcp, - map::Upgrade::new( - libp2p_core::upgrade::SelectUpgrade::new( - self.phase.tls_config, - libp2p_noise::Config::new(&self.keypair) - .map_err(|e| AuthenticationError(e.into()))?, - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - ) - )) - } - - fn without_noise( - self, - ) -> SwarmBuilder<$providerCamelCase, QuicPhase> - { - construct_quic_builder!(self, $tcp, self.phase.tls_config) - } - } - - #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "tcp", feature = "noise", feature = "yamux"))] - impl SwarmBuilder<$providerCamelCase, TcpNoisePhase> { - pub fn with_noise( - self, - ) -> Result< - SwarmBuilder<$providerCamelCase, QuicPhase>, - AuthenticationError, - > { - let _ = self.phase.tls_config; - Ok(construct_quic_builder!( - self, - $tcp, - libp2p_noise::Config::new(&self.keypair) - .map_err(|e| AuthenticationError(e.into()))? - )) - } - } - }; -} - -impl_tcp_noise_builder!("async-std", AsyncStd, async_io); -impl_tcp_noise_builder!("tokio", Tokio, tokio); - #[cfg(any(feature = "tls", feature = "noise"))] pub struct WithoutTls {} @@ -503,78 +337,6 @@ enum AuthenticationErrorInner { Noise(#[from] libp2p_noise::Error), } -// Shortcuts -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tls", - feature = "quic", - feature = "async-std" -))] -impl SwarmBuilder> { - pub fn with_quic( - self, - ) -> SwarmBuilder> { - self.without_noise().with_quic() - } -} -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tls", - feature = "quic", - feature = "tokio" -))] -impl SwarmBuilder> { - pub fn with_quic( - self, - ) -> SwarmBuilder> { - self.without_noise().with_quic() - } -} -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tls", - feature = "quic", - feature = "async-std" -))] -impl SwarmBuilder> { - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result< - SwarmBuilder>, - R::Error, - > { - self.without_noise() - .without_quic() - .without_any_other_transports() - .without_dns() - .without_relay() - .without_websocket() - .with_behaviour(constructor) - } -} -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tls", - feature = "quic", - feature = "tokio" -))] -impl SwarmBuilder> { - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> - { - self.without_noise() - .without_quic() - .without_any_other_transports() - .without_dns() - .without_relay() - .without_websocket() - .with_behaviour(constructor) - } -} - pub struct QuicPhase { transport: T, } @@ -1710,10 +1472,12 @@ mod tests { fn tcp() { let _ = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() + .with_tcp( + Default::default(), + (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + // TODO: The single tuple is not intuitive. + (libp2p_yamux::Config::default(),), + ) .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .unwrap() @@ -1721,13 +1485,18 @@ mod tests { } #[test] - #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] - fn tcp2() { + #[cfg(all( + feature = "async-std", + feature = "tcp", + feature = "tls", + feature = "noise" + ))] + fn async_std_tcp() { let _ = SwarmBuilder::with_new_identity() - .with_tokio() - .with_tcp_2( - // TODO: Handle unwrap - (|keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(),), + .with_async_std() + .with_tcp( + Default::default(), + (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), // TODO: The single tuple is not intuitive. (libp2p_yamux::Config::default(),), ) @@ -1738,13 +1507,13 @@ mod tests { } #[test] - #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] + #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "mplex"))] fn tcp_yamux_mplex() { let _ = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp_2( - // TODO: Handle unwrap - (|keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(),), + .with_tcp( + Default::default(), + (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), ( libp2p_yamux::Config::default(), libp2p_mplex::MplexConfig::default(), @@ -1761,11 +1530,11 @@ mod tests { fn tcp_tls_noise() { let _ = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp_2( - // TODO: Handle unwrap + .with_tcp( + Default::default(), ( - |keypair: &Keypair| libp2p_tls::Config::new(keypair).unwrap(), - |keypair: &Keypair| libp2p_noise::Config::new(keypair).unwrap(), + |keypair: &Keypair| libp2p_tls::Config::new(keypair), + |keypair: &Keypair| libp2p_noise::Config::new(keypair), ), ( libp2p_yamux::Config::default(), @@ -1789,10 +1558,14 @@ mod tests { fn tcp_quic() { let _ = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() + .with_tcp( + Default::default(), + ( + |keypair: &Keypair| libp2p_tls::Config::new(keypair), + |keypair: &Keypair| libp2p_noise::Config::new(keypair), + ), + (libp2p_yamux::Config::default(),), + ) .unwrap() .with_quic() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) @@ -1818,10 +1591,11 @@ mod tests { let _ = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() + .with_tcp( + Default::default(), + (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + (libp2p_yamux::Config::default(),), + ) .unwrap() .with_relay() .with_tls() @@ -1847,10 +1621,14 @@ mod tests { async fn tcp_dns() { SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() + .with_tcp( + Default::default(), + ( + |keypair: &Keypair| libp2p_tls::Config::new(keypair), + |keypair: &Keypair| libp2p_noise::Config::new(keypair), + ), + (libp2p_yamux::Config::default(),), + ) .unwrap() .with_dns() .unwrap() @@ -1894,10 +1672,14 @@ mod tests { async fn tcp_websocket() { let _ = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() + .with_tcp( + Default::default(), + ( + |keypair: &Keypair| libp2p_tls::Config::new(keypair), + |keypair: &Keypair| libp2p_noise::Config::new(keypair), + ), + (libp2p_yamux::Config::default(),), + ) .unwrap() .with_websocket() .with_tls() @@ -1930,10 +1712,11 @@ mod tests { let (builder, _bandwidth_sinks) = SwarmBuilder::with_new_identity() .with_tokio() - .with_tcp() - .with_tls() - .unwrap() - .with_noise() + .with_tcp( + Default::default(), + (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + (libp2p_yamux::Config::default(),), + ) .unwrap() .with_quic() .with_dns() diff --git a/transports/tcp/src/provider/async_io.rs b/transports/tcp/src/provider/async_io.rs index 9f43ed23236..fe0abe42d54 100644 --- a/transports/tcp/src/provider/async_io.rs +++ b/transports/tcp/src/provider/async_io.rs @@ -54,7 +54,7 @@ pub type Transport = crate::Transport; pub enum Tcp {} impl Provider for Tcp { - type Stream = Async; + type Stream = TcpStream; type Listener = Async; type IfWatcher = if_watch::smol::IfWatcher; @@ -116,3 +116,5 @@ impl Provider for Tcp { })) } } + +pub type TcpStream = Async; From 10b3bc12c7d0518b0b6b76db03982a1cf8c91f5e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 25 Sep 2023 14:08:43 +0200 Subject: [PATCH 096/171] Simplify tls and noise construction --- libp2p/src/builder.rs | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 880c3f40efb..9ce74cc7746 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1513,7 +1513,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + (libp2p_tls::Config::new,), ( libp2p_yamux::Config::default(), libp2p_mplex::MplexConfig::default(), @@ -1532,10 +1532,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - ( - |keypair: &Keypair| libp2p_tls::Config::new(keypair), - |keypair: &Keypair| libp2p_noise::Config::new(keypair), - ), + (libp2p_tls::Config::new, libp2p_noise::Config::new), ( libp2p_yamux::Config::default(), libp2p_mplex::MplexConfig::default(), @@ -1560,10 +1557,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - ( - |keypair: &Keypair| libp2p_tls::Config::new(keypair), - |keypair: &Keypair| libp2p_noise::Config::new(keypair), - ), + (libp2p_tls::Config::new, libp2p_noise::Config::new), (libp2p_yamux::Config::default(),), ) .unwrap() @@ -1593,7 +1587,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + (libp2p_tls::Config::new,), (libp2p_yamux::Config::default(),), ) .unwrap() @@ -1623,10 +1617,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - ( - |keypair: &Keypair| libp2p_tls::Config::new(keypair), - |keypair: &Keypair| libp2p_noise::Config::new(keypair), - ), + (libp2p_tls::Config::new, libp2p_noise::Config::new), (libp2p_yamux::Config::default(),), ) .unwrap() @@ -1674,10 +1665,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - ( - |keypair: &Keypair| libp2p_tls::Config::new(keypair), - |keypair: &Keypair| libp2p_noise::Config::new(keypair), - ), + (libp2p_tls::Config::new, libp2p_noise::Config::new), (libp2p_yamux::Config::default(),), ) .unwrap() @@ -1714,7 +1702,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + (libp2p_tls::Config::new,), (libp2p_yamux::Config::default(),), ) .unwrap() From 1f310bbd70de7afb5e50eebfc5cd2283c4651b57 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 26 Sep 2023 10:18:17 +1000 Subject: [PATCH 097/171] Remove 1-tuple from security upgrade --- interop-tests/src/arch.rs | 2 +- libp2p/src/builder.rs | 52 ++++++------ libp2p/src/builder/select_security.rs | 112 ++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 30 deletions(-) create mode 100644 libp2p/src/builder/select_security.rs diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 0dfc68f282c..6085653a4a1 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -36,7 +36,7 @@ pub(crate) mod native { } fn expect_muxer_yamux() -> Result<()> { - match from_env("muxer")? { + match from_env("muxer")? { Muxer::Yamux => (), Muxer::Mplex => { bail!("Only Yamux is supported, not Mplex") diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 9ce74cc7746..05d3f01706f 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -9,6 +9,7 @@ use std::marker::PhantomData; use std::sync::Arc; use crate::bandwidth::BandwidthSinks; +use crate::builder::select_security::SelectSecurityUpgrade; use crate::TransportExt; #[cfg(all( @@ -18,6 +19,7 @@ use crate::TransportExt; any(feature = "tcp", feature = "relay", feature = "websocket") ))] mod map; +mod select_security; /// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. /// @@ -188,7 +190,7 @@ pub trait IntoSecurityUpgrade { fn into_security_upgrade(self, keypair: &Keypair) -> Result; } -impl IntoSecurityUpgrade for (F,) +impl IntoSecurityUpgrade for F where F: for<'a> FnOnce(&'a Keypair) -> Result, E: std::error::Error + 'static, @@ -197,37 +199,29 @@ where type Error = E; fn into_security_upgrade(self, keypair: &Keypair) -> Result { - self.0(keypair) + (self)(keypair) } } -impl IntoSecurityUpgrade for (F1, F2) +impl IntoSecurityUpgrade for (F1, F2) where - F1: for<'a> FnOnce(&'a Keypair) -> Result, - F2: for<'a> FnOnce(&'a Keypair) -> Result, - T1: InboundUpgrade, Output = (PeerId, O1)>, - T2: InboundUpgrade, Output = (PeerId, O2)>, - E1: std::error::Error + 'static, - E2: std::error::Error + 'static, + F1: IntoSecurityUpgrade, + F2: IntoSecurityUpgrade, { - type Upgrade = map::Upgrade< - SelectUpgrade, - fn( - futures::future::Either< - >>::Output, - >>::Output, - >, - ) -> (PeerId, futures::future::Either), - >; - type Error = either::Either; + type Upgrade = SelectSecurityUpgrade; + type Error = either::Either; fn into_security_upgrade(self, keypair: &Keypair) -> Result { - let u1 = self.0(keypair).map_err(either::Either::Left)?; - let u2 = self.1(keypair).map_err(either::Either::Right)?; + let (f1, f2) = self; - Ok(map::Upgrade::new(SelectUpgrade::new(u1, u2), |either| { - futures::future::Either::factor_first(either) - })) + let u1 = f1 + .into_security_upgrade(keypair) + .map_err(either::Either::Left)?; + let u2 = f2 + .into_security_upgrade(keypair) + .map_err(either::Either::Right)?; + + Ok(SelectSecurityUpgrade::new(u1, u2)) } } @@ -1474,7 +1468,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + libp2p_tls::Config::new, // TODO: The single tuple is not intuitive. (libp2p_yamux::Config::default(),), ) @@ -1496,7 +1490,7 @@ mod tests { .with_async_std() .with_tcp( Default::default(), - (|keypair: &Keypair| libp2p_tls::Config::new(keypair),), + libp2p_tls::Config::new, // TODO: The single tuple is not intuitive. (libp2p_yamux::Config::default(),), ) @@ -1513,7 +1507,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - (libp2p_tls::Config::new,), + libp2p_tls::Config::new, ( libp2p_yamux::Config::default(), libp2p_mplex::MplexConfig::default(), @@ -1587,7 +1581,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - (libp2p_tls::Config::new,), + libp2p_tls::Config::new, (libp2p_yamux::Config::default(),), ) .unwrap() @@ -1702,7 +1696,7 @@ mod tests { .with_tokio() .with_tcp( Default::default(), - (libp2p_tls::Config::new,), + libp2p_tls::Config::new, (libp2p_yamux::Config::default(),), ) .unwrap() diff --git a/libp2p/src/builder/select_security.rs b/libp2p/src/builder/select_security.rs new file mode 100644 index 00000000000..472d69053f0 --- /dev/null +++ b/libp2p/src/builder/select_security.rs @@ -0,0 +1,112 @@ +// Copyright 2018 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +use either::Either; +use futures::future::MapOk; +use futures::{future, TryFutureExt}; +use libp2p_core::either::EitherFuture; +use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; +use libp2p_identity::PeerId; +use std::iter::{Chain, Map}; + +/// Upgrade that combines two upgrades into one. Supports all the protocols supported by either +/// sub-upgrade. +/// +/// The protocols supported by the first element have a higher priority. +#[derive(Debug, Clone)] +pub struct SelectSecurityUpgrade(A, B); + +impl SelectSecurityUpgrade { + /// Combines two upgrades into an `SelectUpgrade`. + /// + /// The protocols supported by the first element have a higher priority. + pub fn new(a: A, b: B) -> Self { + SelectSecurityUpgrade(a, b) + } +} + +impl UpgradeInfo for SelectSecurityUpgrade +where + A: UpgradeInfo, + B: UpgradeInfo, +{ + type Info = Either; + type InfoIter = Chain< + Map<::IntoIter, fn(A::Info) -> Self::Info>, + Map<::IntoIter, fn(B::Info) -> Self::Info>, + >; + + fn protocol_info(&self) -> Self::InfoIter { + let a = self + .0 + .protocol_info() + .into_iter() + .map(Either::Left as fn(A::Info) -> _); + let b = self + .1 + .protocol_info() + .into_iter() + .map(Either::Right as fn(B::Info) -> _); + + a.chain(b) + } +} + +impl InboundUpgrade for SelectSecurityUpgrade +where + A: InboundUpgrade, + B: InboundUpgrade, +{ + type Output = (PeerId, future::Either); + type Error = Either; + type Future = MapOk< + EitherFuture, + fn(future::Either<(PeerId, TA), (PeerId, TB)>) -> (PeerId, future::Either), + >; + + fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future { + match info { + Either::Left(info) => EitherFuture::First(self.0.upgrade_inbound(sock, info)), + Either::Right(info) => EitherFuture::Second(self.1.upgrade_inbound(sock, info)), + } + .map_ok(future::Either::factor_first) + } +} + +impl OutboundUpgrade for SelectSecurityUpgrade +where + A: OutboundUpgrade, + B: OutboundUpgrade, +{ + type Output = (PeerId, future::Either); + type Error = Either; + type Future = MapOk< + EitherFuture, + fn(future::Either<(PeerId, TA), (PeerId, TB)>) -> (PeerId, future::Either), + >; + + fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future { + match info { + Either::Left(info) => EitherFuture::First(self.0.upgrade_outbound(sock, info)), + Either::Right(info) => EitherFuture::Second(self.1.upgrade_outbound(sock, info)), + } + .map_ok(future::Either::factor_first) + } +} From 729416e2f1472899bbad973a5a42b5302cd4204e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 26 Sep 2023 12:03:25 +1000 Subject: [PATCH 098/171] Resolve single tuple problem for muxer upgrade --- libp2p/src/builder.rs | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 05d3f01706f..2f36f4d99d9 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -231,19 +231,31 @@ pub trait IntoMultiplexerUpgrade { fn into_multiplexer_upgrade(self) -> Self::Upgrade; } -impl IntoMultiplexerUpgrade for (U,) { +impl IntoMultiplexerUpgrade for F +where + F: FnOnce() -> U, +{ type Upgrade = U; fn into_multiplexer_upgrade(self) -> Self::Upgrade { - self.0 + (self)() } } -impl IntoMultiplexerUpgrade for (U1, U2) { - type Upgrade = SelectUpgrade; +impl IntoMultiplexerUpgrade for (U1, U2) +where + U1: IntoMultiplexerUpgrade, + U2: IntoMultiplexerUpgrade, +{ + type Upgrade = SelectUpgrade; fn into_multiplexer_upgrade(self) -> Self::Upgrade { - SelectUpgrade::new(self.0, self.1) + let (f1, f2) = self; + + let u1 = f1.into_multiplexer_upgrade(); + let u2 = f2.into_multiplexer_upgrade(); + + SelectUpgrade::new(u1, u2) } } @@ -1469,8 +1481,7 @@ mod tests { .with_tcp( Default::default(), libp2p_tls::Config::new, - // TODO: The single tuple is not intuitive. - (libp2p_yamux::Config::default(),), + libp2p_yamux::Config::default, ) .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) @@ -1491,8 +1502,7 @@ mod tests { .with_tcp( Default::default(), libp2p_tls::Config::new, - // TODO: The single tuple is not intuitive. - (libp2p_yamux::Config::default(),), + libp2p_yamux::Config::default, ) .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) @@ -1528,8 +1538,8 @@ mod tests { Default::default(), (libp2p_tls::Config::new, libp2p_noise::Config::new), ( - libp2p_yamux::Config::default(), - libp2p_mplex::MplexConfig::default(), + libp2p_yamux::Config::default, + libp2p_mplex::MplexConfig::default, ), ) .unwrap() @@ -1552,7 +1562,7 @@ mod tests { .with_tcp( Default::default(), (libp2p_tls::Config::new, libp2p_noise::Config::new), - (libp2p_yamux::Config::default(),), + libp2p_yamux::Config::default, ) .unwrap() .with_quic() @@ -1582,7 +1592,7 @@ mod tests { .with_tcp( Default::default(), libp2p_tls::Config::new, - (libp2p_yamux::Config::default(),), + libp2p_yamux::Config::default, ) .unwrap() .with_relay() @@ -1612,7 +1622,7 @@ mod tests { .with_tcp( Default::default(), (libp2p_tls::Config::new, libp2p_noise::Config::new), - (libp2p_yamux::Config::default(),), + libp2p_yamux::Config::default, ) .unwrap() .with_dns() @@ -1660,7 +1670,7 @@ mod tests { .with_tcp( Default::default(), (libp2p_tls::Config::new, libp2p_noise::Config::new), - (libp2p_yamux::Config::default(),), + libp2p_yamux::Config::default, ) .unwrap() .with_websocket() @@ -1697,7 +1707,7 @@ mod tests { .with_tcp( Default::default(), libp2p_tls::Config::new, - (libp2p_yamux::Config::default(),), + libp2p_yamux::Config::default, ) .unwrap() .with_quic() From 8dd8f37c60d31362e07d16e3ee20d1f62daa3b01 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 26 Sep 2023 12:06:16 +1000 Subject: [PATCH 099/171] Undo accidental change --- interop-tests/src/arch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 6085653a4a1..0dfc68f282c 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -36,7 +36,7 @@ pub(crate) mod native { } fn expect_muxer_yamux() -> Result<()> { - match from_env("muxer")? { + match from_env("muxer")? { Muxer::Yamux => (), Muxer::Mplex => { bail!("Only Yamux is supported, not Mplex") From 0c1e4efea3b5bfbaeb1ad50456db9f2de675441b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 26 Sep 2023 12:44:11 +1000 Subject: [PATCH 100/171] Resolve some more warnings --- examples/chat/src/main.rs | 10 ++-------- examples/ping/src/main.rs | 18 ++---------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/examples/chat/src/main.rs b/examples/chat/src/main.rs index 0bf7144aeed..073d8e9a7d5 100644 --- a/examples/chat/src/main.rs +++ b/examples/chat/src/main.rs @@ -20,14 +20,8 @@ #![doc = include_str!("../README.md")] -use futures::{future::Either, stream::StreamExt}; -use libp2p::{ - core::{muxing::StreamMuxerBox, transport::OrTransport, upgrade}, - gossipsub, identity, mdns, noise, quic, - swarm::NetworkBehaviour, - swarm::{SwarmBuilder, SwarmEvent}, - tcp, yamux, PeerId, Transport, -}; +use futures::stream::StreamExt; +use libp2p::{gossipsub, mdns, noise, swarm::NetworkBehaviour, swarm::SwarmEvent, tcp, yamux}; use std::collections::hash_map::DefaultHasher; use std::error::Error; use std::hash::{Hash, Hasher}; diff --git a/examples/ping/src/main.rs b/examples/ping/src/main.rs index 0e0e1b0dcfe..d7d3d9a8d7a 100644 --- a/examples/ping/src/main.rs +++ b/examples/ping/src/main.rs @@ -21,11 +21,7 @@ #![doc = include_str!("../README.md")] use futures::prelude::*; -use libp2p::{ - noise, ping, - swarm::{keep_alive, NetworkBehaviour, SwarmEvent}, - tcp, yamux, Multiaddr, -}; +use libp2p::{noise, ping, swarm::SwarmEvent, tcp, yamux, Multiaddr}; use std::error::Error; #[async_std::main] @@ -37,7 +33,7 @@ async fn main() -> Result<(), Box> { noise::Config::new, yamux::Config::default, )? - .with_behaviour(|_| Behaviour::default()) + .with_behaviour(|_| ping::Behaviour::default()) .unwrap() .build(); @@ -63,13 +59,3 @@ async fn main() -> Result<(), Box> { } } } - -/// Our network behaviour. -/// -/// For illustrative purposes, this includes the [`KeepAlive`](keep_alive::Behaviour) behaviour so a continuous sequence of -/// pings can be observed. -#[derive(NetworkBehaviour, Default)] -struct Behaviour { - keep_alive: keep_alive::Behaviour, - ping: ping::Behaviour, -} From 5ef58bb1bd56c2cab82e3645420c9df0fe68db7b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 26 Sep 2023 12:44:28 +1000 Subject: [PATCH 101/171] Undo unnecessary changes --- examples/chat/src/main.rs | 2 +- interop-tests/src/arch.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/chat/src/main.rs b/examples/chat/src/main.rs index 073d8e9a7d5..0a261873f35 100644 --- a/examples/chat/src/main.rs +++ b/examples/chat/src/main.rs @@ -36,7 +36,7 @@ struct MyBehaviour { } #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<(), Box> { let mut swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp( diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index e4b598c828c..ff5fb26f287 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -68,8 +68,7 @@ pub(crate) mod native { tcp::Config::default(), tls::Config::new, yamux::Config::default, - ) - .context("failed to build tcp transport")? + )? .with_behaviour(behaviour_constructor)? .build(); (swarm, format!("/ip4/{ip}/tcp/0")) @@ -83,8 +82,7 @@ pub(crate) mod native { tcp::Config::default(), noise::Config::new, yamux::Config::default, - ) - .context("failed to build tcp transport")? + )? .with_behaviour(behaviour_constructor)? .build(); (swarm, format!("/ip4/{ip}/tcp/0")) From 9d0538fba35ee5bd5072f21dd9acbce9a39e6945 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 28 Sep 2023 09:56:29 +0200 Subject: [PATCH 102/171] Remove unnecessary trait bounds on IntoSecurityUpgrade::Error --- libp2p/src/builder.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 66ee0588368..a80284daade 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -183,7 +183,7 @@ impl_tcp_builder!("tokio", Tokio, tokio); pub trait IntoSecurityUpgrade { type Upgrade; - type Error: std::error::Error + 'static; + type Error; fn into_security_upgrade(self, keypair: &Keypair) -> Result; } @@ -191,7 +191,6 @@ pub trait IntoSecurityUpgrade { impl IntoSecurityUpgrade for F where F: for<'a> FnOnce(&'a Keypair) -> Result, - E: std::error::Error + 'static, { type Upgrade = T; type Error = E; From ca29c391e2bd71b88d7ca2a9f35a1b24a82b6bda Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 28 Sep 2023 10:17:59 +0200 Subject: [PATCH 103/171] Adjust with_relay --- libp2p/src/builder.rs | 343 +++++++++++++++--------------------------- 1 file changed, 120 insertions(+), 223 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index a80284daade..dd1929e6b3e 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -408,14 +408,40 @@ impl SwarmBuilder> { // Shortcuts impl SwarmBuilder> { #[cfg(feature = "relay")] - pub fn with_relay(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: RelayTlsPhase { - transport: self.phase.transport, - }, - } + pub fn with_relay( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + Provider, + WebsocketPhase, + >, + SecUpgrade::Error, + > where + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_quic() + .with_relay(security_upgrade, multiplexer_upgrade) } pub fn with_other_transport< @@ -545,12 +571,41 @@ impl SwarmBuilder SwarmBuilder> { - pub fn with_relay( + pub fn with_relay( self, - ) -> SwarmBuilder> { + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + Provider, + WebsocketPhase, + >, + SecUpgrade::Error, + > where + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { self.without_any_other_transports() .without_dns() - .with_relay() + .with_relay(security_upgrade, multiplexer_upgrade) } } impl @@ -653,249 +708,97 @@ pub struct RelayPhase { transport: T, } -// TODO: Noise feature or tls feature #[cfg(feature = "relay")] -impl SwarmBuilder> { - // TODO: This should be with_relay_client. - pub fn with_relay(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: RelayTlsPhase { - transport: self.phase.transport, - }, - } - } -} - -pub struct NoRelayBehaviour; - -impl SwarmBuilder> { - fn without_relay(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: WebsocketPhase { - transport: self.phase.transport, - relay_behaviour: NoRelayBehaviour, - }, - } - } -} - -// Shortcuts impl SwarmBuilder> { - #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] - pub fn with_websocket( - self, - ) -> SwarmBuilder< - Provider, - WebsocketTlsPhase, - > { - self.without_relay().with_websocket() - } - - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - self.without_relay() - .without_websocket() - .with_behaviour(constructor) - } -} - -#[cfg(feature = "relay")] -pub struct RelayTlsPhase { - transport: T, -} - -#[cfg(feature = "relay")] -impl SwarmBuilder> { - #[cfg(all(not(target_arch = "wasm32"), feature = "tls"))] - pub fn with_tls( - self, - ) -> Result>, AuthenticationError> - { - Ok(SwarmBuilder { - phase: RelayNoisePhase { - tls_config: libp2p_tls::Config::new(&self.keypair) - .map_err(|e| AuthenticationError(e.into()))?, - transport: self.phase.transport, - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } - - fn without_tls(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: RelayNoisePhase { - tls_config: WithoutTls {}, - transport: self.phase.transport, - }, - } - } -} - -// Shortcuts -#[cfg(all(feature = "relay", feature = "noise", feature = "async-std"))] -impl SwarmBuilder> { - #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> Result< - SwarmBuilder< - AsyncStd, - WebsocketPhase, - >, - AuthenticationError, - > { - self.without_tls().with_noise() - } -} -#[cfg(all(feature = "relay", feature = "noise", feature = "tokio"))] -impl SwarmBuilder> { - #[cfg(feature = "noise")] - pub fn with_noise( + // TODO: This should be with_relay_client. + pub fn with_relay( self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, ) -> Result< SwarmBuilder< - Tokio, + Provider, WebsocketPhase, >, - AuthenticationError, - > { - self.without_tls().with_noise() - } -} - -#[cfg(feature = "relay")] -pub struct RelayNoisePhase { - tls_config: A, - transport: T, -} - -// TODO: Rename these macros to phase not builder. All. -#[cfg(feature = "relay")] -macro_rules! construct_websocket_builder { - ($self:ident, $auth:expr) => {{ + SecUpgrade::Error, + > where + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { let (relay_transport, relay_behaviour) = - libp2p_relay::client::new($self.keypair.public().to_peer_id()); + libp2p_relay::client::new(self.keypair.public().to_peer_id()); - SwarmBuilder { + Ok(SwarmBuilder { phase: WebsocketPhase { relay_behaviour, - transport: $self + transport: self .phase .transport .or_transport( relay_transport .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate($auth) - .multiplex(libp2p_yamux::Config::default()) + .authenticate(security_upgrade.into_security_upgrade(&self.keypair)?) + .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) .map(|(p, c), _| (p, StreamMuxerBox::new(c))), ) .map(|either, _| either.into_inner()), }, - keypair: $self.keypair, + keypair: self.keypair, phantom: PhantomData, - } - }}; -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "relay", feature = "tls"))] -impl - SwarmBuilder> -{ - #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> Result< - SwarmBuilder< - Provider, - WebsocketPhase, - >, - AuthenticationError, - > { - Ok(construct_websocket_builder!( - self, - map::Upgrade::new( - libp2p_core::upgrade::SelectUpgrade::new( - self.phase.tls_config, - libp2p_noise::Config::new(&self.keypair) - .map_err(|e| AuthenticationError(e.into()))?, - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - ) - )) - } - - fn without_noise( - self, - ) -> SwarmBuilder< - Provider, - WebsocketPhase, - > { - construct_websocket_builder!(self, self.phase.tls_config) + }) } } -#[cfg(feature = "relay")] -impl - SwarmBuilder> -{ - #[cfg(feature = "noise")] - pub fn with_noise( - self, - ) -> Result< - SwarmBuilder< - Provider, - WebsocketPhase, - >, - AuthenticationError, - > { - let _ = self.phase.tls_config; +pub struct NoRelayBehaviour; - Ok(construct_websocket_builder!( - self, - libp2p_noise::Config::new(&self.keypair).map_err(|e| AuthenticationError(e.into()))? - )) +impl SwarmBuilder> { + fn without_relay(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: WebsocketPhase { + transport: self.phase.transport, + relay_behaviour: NoRelayBehaviour, + }, + } } } // Shortcuts -#[cfg(all(not(target_arch = "wasm32"), feature = "tls", feature = "relay"))] -impl - SwarmBuilder> -{ +impl SwarmBuilder> { #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] pub fn with_websocket( self, ) -> SwarmBuilder< Provider, - WebsocketTlsPhase, + WebsocketTlsPhase, > { - self.without_noise().with_websocket() + self.without_relay().with_websocket() } pub fn with_behaviour>( self, - constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result< - SwarmBuilder>, - R::Error, - > { - self.without_noise() + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_relay() .without_websocket() .with_behaviour(constructor) } @@ -1592,10 +1495,7 @@ mod tests { libp2p_yamux::Config::default, ) .unwrap() - .with_relay() - .with_tls() - .unwrap() - .with_noise() + .with_relay(libp2p_tls::Config::new, libp2p_yamux::Config::default) .unwrap() .with_behaviour(|_, relay| Behaviour { dummy: libp2p_swarm::dummy::Behaviour, @@ -1710,10 +1610,7 @@ mod tests { .with_quic() .with_dns() .unwrap() - .with_relay() - .with_tls() - .unwrap() - .with_noise() + .with_relay(libp2p_tls::Config::new, libp2p_yamux::Config::default) .unwrap() .with_websocket() .with_tls() From 82eb6557e77377edb7c455328916fbb5a924aca8 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 28 Sep 2023 13:16:23 +0200 Subject: [PATCH 104/171] Adjust with_websocket --- Cargo.lock | 1 + libp2p/Cargo.toml | 2 + libp2p/src/builder.rs | 503 ++++++++++++++++++++---------------------- 3 files changed, 245 insertions(+), 261 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 21bfd9cba8b..482f69efa61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2405,6 +2405,7 @@ dependencies = [ "libp2p-yamux", "multiaddr", "pin-project", + "rw-stream-sink", "thiserror", "tokio", ] diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 38792c52b34..33d334206ea 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -100,6 +100,8 @@ futures = "0.3.26" futures-timer = "3.0.2" # Explicit dependency to be used in `wasm-bindgen` feature getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature instant = "0.1.12" # Explicit dependency to be used in `wasm-bindgen` feature +# TODO feature flag? +rw-stream-sink = { workspace = true } libp2p-allow-block-list = { workspace = true } libp2p-autonat = { workspace = true, optional = true } diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index dd1929e6b3e..dae139619ea 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -306,39 +306,74 @@ impl SwarmBuilder { .without_quic() .with_other_transport(constructor) } - - #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] - pub fn with_websocket( - self, - ) -> SwarmBuilder< - Provider, - WebsocketTlsPhase, - > { - self.without_tcp() - .without_quic() - .without_any_other_transports() - .without_dns() - .without_relay() - .with_websocket() - } } +macro_rules! impl_tcp_phase_with_websocket { + ($providerKebabCase:literal, $providerCamelCase:ident, $websocketStream:ty) => { + #[cfg(feature = $providerKebabCase)] + impl SwarmBuilder<$providerCamelCase, TcpPhase> { + #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] + pub async fn with_websocket < + SecUpgrade, + SecStream, + SecError, + MuxUpgrade, + MuxStream, + MuxError, + > ( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + $providerCamelCase, + BandwidthLoggingPhase, + >, + WebsocketError, + > + where + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade<$websocketStream>, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, -#[cfg(any(feature = "tls", feature = "noise"))] -pub struct WithoutTls {} - -#[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub struct AuthenticationError(AuthenticationErrorInner); - -#[derive(Debug, thiserror::Error)] -enum AuthenticationErrorInner { - #[error("Tls")] - #[cfg(all(not(target_arch = "wasm32"), feature = "tls"))] - Tls(#[from] libp2p_tls::certificate::GenError), - #[error("Noise")] - #[cfg(feature = "noise")] - Noise(#[from] libp2p_noise::Error), + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_tcp() + .without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .with_websocket(security_upgrade, multiplexer_upgrade) + .await + } + } + } } +impl_tcp_phase_with_websocket!( + "async-std", + AsyncStd, + rw_stream_sink::RwStreamSink< + libp2p_websocket::BytesConnection, + > +); +impl_tcp_phase_with_websocket!( + "tokio", + Tokio, + rw_stream_sink::RwStreamSink> +); pub struct QuicPhase { transport: T, @@ -457,20 +492,6 @@ impl SwarmBuilder SwarmBuilder< - Provider, - WebsocketTlsPhase, - > { - self.without_quic() - .without_any_other_transports() - .without_dns() - .without_relay() - .with_websocket() - } - pub fn with_behaviour>( self, constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, @@ -506,6 +527,72 @@ impl SwarmBuilder> { .with_dns() } } +macro_rules! impl_quic_phase_with_websocket { + ($providerKebabCase:literal, $providerCamelCase:ident, $websocketStream:ty) => { + #[cfg(feature = $providerKebabCase)] + impl SwarmBuilder<$providerCamelCase, QuicPhase> { + #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] + pub async fn with_websocket < + SecUpgrade, + SecStream, + SecError, + MuxUpgrade, + MuxStream, + MuxError, + > ( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + $providerCamelCase, + BandwidthLoggingPhase, + >, + WebsocketError, + > + where + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade<$websocketStream>, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .with_websocket(security_upgrade, multiplexer_upgrade) + .await + } + } + } +} +impl_quic_phase_with_websocket!( + "async-std", + AsyncStd, + rw_stream_sink::RwStreamSink< + libp2p_websocket::BytesConnection, + > +); +impl_quic_phase_with_websocket!( + "tokio", + Tokio, + rw_stream_sink::RwStreamSink> +); pub struct OtherTransportPhase { transport: T, @@ -784,15 +871,16 @@ impl SwarmBuilder> { // Shortcuts impl SwarmBuilder> { - #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] - pub fn with_websocket( - self, - ) -> SwarmBuilder< - Provider, - WebsocketTlsPhase, - > { - self.without_relay().with_websocket() - } + // TODO + // #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] + // pub fn with_websocket( + // self, + // ) -> SwarmBuilder< + // Provider, + // WebsocketTlsPhase, + // > { + // self.without_relay().with_websocket() + // } pub fn with_behaviour>( self, @@ -809,20 +897,98 @@ pub struct WebsocketPhase { relay_behaviour: R, } -#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -impl SwarmBuilder> { - pub fn with_websocket(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: WebsocketTlsPhase { - transport: self.phase.transport, - relay_behaviour: self.phase.relay_behaviour, - }, +macro_rules! impl_websocket_builder { + ($providerKebabCase:literal, $providerCamelCase:ident, $dnsTcp:expr, $websocketStream:ty) => { + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "websocket"))] + impl SwarmBuilder<$providerCamelCase, WebsocketPhase> { + pub async fn with_websocket< + SecUpgrade, + SecStream, + SecError, + MuxUpgrade, + MuxStream, + MuxError, + >( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + $providerCamelCase, + BandwidthLoggingPhase, + >, + WebsocketError, + > + + where + T: AuthenticatedMultiplexedTransport, + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade<$websocketStream>, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + { + let security_upgrade = security_upgrade.into_security_upgrade(&self.keypair) + .map_err(|e| WebsocketError(WebsocketErrorInner::SecurityUpgrade(e)))?; + let websocket_transport = libp2p_websocket::WsConfig::new( + $dnsTcp.await.map_err(|e| WebsocketError(e.into()))?, + ) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate(security_upgrade) + .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))); + + Ok(SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: BandwidthLoggingPhase { + transport: websocket_transport + .or_transport(self.phase.transport) + .map(|either, _| either.into_inner()), + relay_behaviour: self.phase.relay_behaviour, + }, + }) + } } - } + }; } +impl_websocket_builder!( + "async-std", + AsyncStd, + libp2p_dns::async_std::Transport::system(libp2p_tcp::async_io::Transport::new( + libp2p_tcp::Config::default(), + )), + rw_stream_sink::RwStreamSink< + libp2p_websocket::BytesConnection, + > +); +// TODO: Unnecessary await for Tokio Websocket (i.e. tokio dns). Not ideal but don't know a better way. +impl_websocket_builder!( + "tokio", + Tokio, + futures::future::ready(libp2p_dns::tokio::Transport::system( + libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) + )), + rw_stream_sink::RwStreamSink> +); + impl SwarmBuilder> { @@ -866,199 +1032,14 @@ impl } } -#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -pub struct WebsocketTlsPhase { - transport: T, - relay_behaviour: R, -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -impl SwarmBuilder> { - #[cfg(feature = "tls")] - pub fn with_tls( - self, - ) -> Result< - SwarmBuilder>, - AuthenticationError, - > { - Ok(SwarmBuilder { - phase: WebsocketNoisePhase { - tls_config: libp2p_tls::Config::new(&self.keypair) - .map_err(|e| AuthenticationError(e.into()))?, - relay_behaviour: self.phase.relay_behaviour, - transport: self.phase.transport, - phantom: PhantomData, - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } - - fn without_tls(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: WebsocketNoisePhase { - tls_config: WithoutTls {}, - relay_behaviour: self.phase.relay_behaviour, - transport: self.phase.transport, - phantom: PhantomData, - }, - } - } -} - -// Shortcuts -#[cfg(all( - not(target_arch = "wasm32"), - feature = "websocket", - feature = "noise", - feature = "async-std" -))] -impl SwarmBuilder> { - #[cfg(feature = "noise")] - pub async fn with_noise( - self, - ) -> Result< - SwarmBuilder>, - WebsocketError, - > { - self.without_tls().with_noise().await - } -} -#[cfg(all( - not(target_arch = "wasm32"), - feature = "websocket", - feature = "noise", - feature = "tokio" -))] -impl SwarmBuilder> { - #[cfg(feature = "noise")] - pub async fn with_noise( - self, - ) -> Result< - SwarmBuilder>, - WebsocketError, - > { - self.without_tls().with_noise().await - } -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -pub struct WebsocketNoisePhase { - tls_config: A, - transport: T, - relay_behaviour: R, - phantom: PhantomData, -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -macro_rules! construct_behaviour_builder { - ($self:ident, $dnsTcp:expr, $auth:expr) => {{ - let websocket_transport = - libp2p_websocket::WsConfig::new($dnsTcp.await.map_err(|e| WebsocketError(e.into()))?) - .upgrade(libp2p_core::upgrade::Version::V1) - .authenticate($auth) - .multiplex(libp2p_yamux::Config::default()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))); - - Ok(SwarmBuilder { - keypair: $self.keypair, - phantom: PhantomData, - phase: BandwidthLoggingPhase { - transport: websocket_transport - .or_transport($self.phase.transport) - .map(|either, _| either.into_inner()), - relay_behaviour: $self.phase.relay_behaviour, - }, - }) - }}; -} - -macro_rules! impl_websocket_noise_builder { - ($providerKebabCase:literal, $providerCamelCase:ident, $dnsTcp:expr) => { - #[cfg(all( - not(target_arch = "wasm32"), - feature = $providerKebabCase, - feature = "websocket", - feature = "dns", - feature = "tls" - ))] - impl - SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, libp2p_tls::Config>> - { - #[cfg(feature = "noise")] - pub async fn with_noise(self) -> Result>, WebsocketError> { - construct_behaviour_builder!( - self, - $dnsTcp, - map::Upgrade::new( - libp2p_core::upgrade::SelectUpgrade::new( - self.phase.tls_config, - libp2p_noise::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))?, - ), - |upgrade| match upgrade { - futures::future::Either::Left((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Left(upgrade)) - } - futures::future::Either::Right((peer_id, upgrade)) => { - (peer_id, futures::future::Either::Right(upgrade)) - } - }, - ) - ) - } - pub async fn without_noise(self) -> Result>, WebsocketError> { - construct_behaviour_builder!( - self, - $dnsTcp, - libp2p_tls::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))? - ) - } - } - - #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "dns", feature = "websocket", feature = "noise"))] - impl - SwarmBuilder<$providerCamelCase, WebsocketNoisePhase< T, R, WithoutTls>> - { - pub async fn with_noise(self) -> Result>, WebsocketError> { - let _ = self.phase.tls_config; - - construct_behaviour_builder!( - self, - $dnsTcp, - libp2p_noise::Config::new(&self.keypair).map_err(|e| WebsocketError(AuthenticationErrorInner::from(e).into()))? - ) - } - } - }; -} - -impl_websocket_noise_builder!( - "async-std", - AsyncStd, - libp2p_dns::async_std::Transport::system(libp2p_tcp::async_io::Transport::new( - libp2p_tcp::Config::default(), - )) -); -// TODO: Unnecessary await for Tokio Websocket (i.e. tokio dns). Not ideal but don't know a better way. -impl_websocket_noise_builder!( - "tokio", - Tokio, - futures::future::ready(libp2p_dns::tokio::Transport::system( - libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) - )) -); - #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct WebsocketError(WebsocketErrorInner); +pub struct WebsocketError(WebsocketErrorInner); #[derive(Debug, thiserror::Error)] -enum WebsocketErrorInner { - #[error("Dns")] - #[cfg(any(feature = "tls", feature = "noise"))] - Authentication(#[from] AuthenticationErrorInner), +enum WebsocketErrorInner { + #[error("SecurityUpgrade")] + SecurityUpgrade(Sec), #[cfg(feature = "dns")] #[error("Dns")] Dns(#[from] io::Error), @@ -1570,10 +1551,10 @@ mod tests { libp2p_yamux::Config::default, ) .unwrap() - .with_websocket() - .with_tls() - .unwrap() - .with_noise() + .with_websocket( + (libp2p_tls::Config::new, libp2p_noise::Config::new), + libp2p_yamux::Config::default, + ) .await .unwrap() .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) @@ -1612,10 +1593,10 @@ mod tests { .unwrap() .with_relay(libp2p_tls::Config::new, libp2p_yamux::Config::default) .unwrap() - .with_websocket() - .with_tls() - .unwrap() - .with_noise() + .with_websocket( + libp2p_tls::Config::new, + libp2p_yamux::Config::default, + ) .await .unwrap() .with_bandwidth_logging(); From a60993de2d192433c7274b4f89a357abc5fcdf08 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 15:24:37 +0200 Subject: [PATCH 105/171] Split builder.rs into separate files --- Cargo.lock | 3 + examples/dcutr/src/main.rs | 3 +- interop-tests/Cargo.toml | 5 +- interop-tests/src/arch.rs | 7 +- libp2p/src/builder.rs | 1300 +---------------- libp2p/src/builder/phase.rs | 131 ++ libp2p/src/builder/phase/bandwidth_logging.rs | 70 + libp2p/src/builder/phase/behaviour.rs | 77 + libp2p/src/builder/phase/build.rs | 29 + libp2p/src/builder/phase/dns.rs | 68 + libp2p/src/builder/phase/identity.rs | 23 + libp2p/src/builder/phase/other_transport.rs | 188 +++ libp2p/src/builder/phase/provider.rs | 45 + libp2p/src/builder/phase/quic.rs | 226 +++ libp2p/src/builder/phase/relay.rs | 117 ++ libp2p/src/builder/phase/swarm.rs | 80 + libp2p/src/builder/phase/tcp.rs | 186 +++ libp2p/src/builder/phase/websocket.rs | 166 +++ 18 files changed, 1420 insertions(+), 1304 deletions(-) create mode 100644 libp2p/src/builder/phase.rs create mode 100644 libp2p/src/builder/phase/bandwidth_logging.rs create mode 100644 libp2p/src/builder/phase/behaviour.rs create mode 100644 libp2p/src/builder/phase/build.rs create mode 100644 libp2p/src/builder/phase/dns.rs create mode 100644 libp2p/src/builder/phase/identity.rs create mode 100644 libp2p/src/builder/phase/other_transport.rs create mode 100644 libp2p/src/builder/phase/provider.rs create mode 100644 libp2p/src/builder/phase/quic.rs create mode 100644 libp2p/src/builder/phase/relay.rs create mode 100644 libp2p/src/builder/phase/swarm.rs create mode 100644 libp2p/src/builder/phase/tcp.rs create mode 100644 libp2p/src/builder/phase/websocket.rs diff --git a/Cargo.lock b/Cargo.lock index 482f69efa61..1dfff240524 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2206,8 +2206,11 @@ dependencies = [ "instant", "libp2p", "libp2p-mplex", + "libp2p-noise", + "libp2p-tls", "libp2p-webrtc", "libp2p-webrtc-websys", + "libp2p-yamux", "log", "mime_guess", "rand 0.8.5", diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index b49953992cd..7bc3e83e26c 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -128,8 +128,7 @@ async fn main() -> Result<(), Box> { .with_quic() .with_dns() .await? - .with_relay() - .with_noise()? + .with_relay(noise::Config::new, yamux::Config::default)? .with_behaviour(|keypair, relay_behaviour| Behaviour { relay_client: relay_behaviour, ping: ping::Behaviour::new(ping::Config::new()), diff --git a/interop-tests/Cargo.toml b/interop-tests/Cargo.toml index 1966aee414d..fabd564be90 100644 --- a/interop-tests/Cargo.toml +++ b/interop-tests/Cargo.toml @@ -20,8 +20,11 @@ rand = "0.8.5" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] axum = "0.6" libp2p = { path = "../libp2p", features = ["ping", "noise", "tls", "rsa", "macros", "websocket", "tokio", "yamux", "tcp", "dns", "identify", "quic"] } -libp2p-webrtc = { workspace = true, features = ["tokio"] } libp2p-mplex = { path = "../muxers/mplex" } +libp2p-noise = { workspace = true } +libp2p-tls = { workspace = true } +libp2p-webrtc = { workspace = true, features = ["tokio"] } +libp2p-yamux = { workspace = true } mime_guess = "2.0" redis = { version = "0.23.3", default-features = false, features = ["tokio-comp"] } rust-embed = "8.0" diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index ff5fb26f287..d8073ce925d 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -92,9 +92,7 @@ pub(crate) mod native { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket() - .with_tls()? - .without_noise() + .with_websocket(libp2p_tls::Config::new, libp2p_yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? .build(); @@ -105,8 +103,7 @@ pub(crate) mod native { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket() - .with_noise() + .with_websocket(libp2p_tls::Config::new, libp2p_yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? .build(); diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index dae139619ea..bd47e1727bf 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,16 +1,4 @@ -use libp2p_core::upgrade::SelectUpgrade; -use libp2p_core::{muxing::StreamMuxerBox, Transport}; -use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, StreamMuxer, UpgradeInfo}; -use libp2p_identity::{Keypair, PeerId}; -use libp2p_swarm::{NetworkBehaviour, Swarm}; -use std::convert::Infallible; -use std::io; use std::marker::PhantomData; -use std::sync::Arc; - -use crate::bandwidth::BandwidthSinks; -use crate::builder::select_security::SelectSecurityUpgrade; -use crate::TransportExt; #[cfg(all( not(target_arch = "wasm32"), @@ -20,6 +8,7 @@ use crate::TransportExt; ))] mod map; mod select_security; +mod phase; /// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. /// @@ -71,1288 +60,10 @@ pub struct SwarmBuilder { phase: Phase, } -pub struct InitialPhase {} - -impl SwarmBuilder { - pub fn with_new_identity() -> SwarmBuilder { - SwarmBuilder::with_existing_identity(libp2p_identity::Keypair::generate_ed25519()) - } - - pub fn with_existing_identity( - keypair: libp2p_identity::Keypair, - ) -> SwarmBuilder { - SwarmBuilder { - keypair, - phantom: PhantomData, - phase: ProviderPhase {}, - } - } -} - -pub struct ProviderPhase {} - -impl SwarmBuilder { - #[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] - pub fn with_async_std(self) -> SwarmBuilder { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: TcpPhase {}, - } - } - - #[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] - pub fn with_tokio(self) -> SwarmBuilder { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: TcpPhase {}, - } - } - - #[cfg(feature = "wasm-bindgen")] - pub fn with_wasm_bindgen(self) -> SwarmBuilder { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: TcpPhase {}, - } - } -} - -pub struct TcpPhase {} - -macro_rules! impl_tcp_builder { - ($providerKebabCase:literal, $providerCamelCase:ident, $path:ident) => { - #[cfg(all( - not(target_arch = "wasm32"), - feature = "tcp", - feature = $providerKebabCase, - ))] - impl SwarmBuilder<$providerCamelCase, TcpPhase> { - pub fn with_tcp( - self, - tcp_config: libp2p_tcp::Config, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder<$providerCamelCase, QuicPhase>, - SecUpgrade::Error, - > - where - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - { - Ok(SwarmBuilder { - phase: QuicPhase { - transport: libp2p_tcp::$path::Transport::new(tcp_config) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate( - security_upgrade.into_security_upgrade(&self.keypair)?, - ) - .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } - } - }; -} - -impl_tcp_builder!("async-std", AsyncStd, async_io); -impl_tcp_builder!("tokio", Tokio, tokio); - -pub trait IntoSecurityUpgrade { - type Upgrade; - type Error; - - fn into_security_upgrade(self, keypair: &Keypair) -> Result; -} - -impl IntoSecurityUpgrade for F -where - F: for<'a> FnOnce(&'a Keypair) -> Result, -{ - type Upgrade = T; - type Error = E; - - fn into_security_upgrade(self, keypair: &Keypair) -> Result { - (self)(keypair) - } -} - -impl IntoSecurityUpgrade for (F1, F2) -where - F1: IntoSecurityUpgrade, - F2: IntoSecurityUpgrade, -{ - type Upgrade = SelectSecurityUpgrade; - type Error = either::Either; - - fn into_security_upgrade(self, keypair: &Keypair) -> Result { - let (f1, f2) = self; - - let u1 = f1 - .into_security_upgrade(keypair) - .map_err(either::Either::Left)?; - let u2 = f2 - .into_security_upgrade(keypair) - .map_err(either::Either::Right)?; - - Ok(SelectSecurityUpgrade::new(u1, u2)) - } -} - -pub trait IntoMultiplexerUpgrade { - type Upgrade; - - fn into_multiplexer_upgrade(self) -> Self::Upgrade; -} - -impl IntoMultiplexerUpgrade for F -where - F: FnOnce() -> U, -{ - type Upgrade = U; - - fn into_multiplexer_upgrade(self) -> Self::Upgrade { - (self)() - } -} - -impl IntoMultiplexerUpgrade for (U1, U2) -where - U1: IntoMultiplexerUpgrade, - U2: IntoMultiplexerUpgrade, -{ - type Upgrade = SelectUpgrade; - - fn into_multiplexer_upgrade(self) -> Self::Upgrade { - let (f1, f2) = self; - - let u1 = f1.into_multiplexer_upgrade(); - let u2 = f2.into_multiplexer_upgrade(); - - SelectUpgrade::new(u1, u2) - } -} - -impl SwarmBuilder { - // TODO: This would allow one to build a faulty transport. - fn without_tcp( - self, - ) -> SwarmBuilder> { - SwarmBuilder { - // TODO: Is this a good idea in a production environment? Unfortunately I don't know a - // way around it. One can not define two `with_relay` methods, one with a real transport - // using OrTransport, one with a fake transport discarding it right away. - keypair: self.keypair, - phantom: PhantomData, - phase: QuicPhase { - transport: libp2p_core::transport::dummy::DummyTransport::new(), - }, - } - } -} - -// Shortcuts -#[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = "async-std"))] -impl SwarmBuilder { - pub fn with_quic( - self, - ) -> SwarmBuilder> { - self.without_tcp().with_quic() - } -} -#[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = "tokio"))] -impl SwarmBuilder { - pub fn with_quic( - self, - ) -> SwarmBuilder> { - self.without_tcp().with_quic() - } -} -impl SwarmBuilder { - pub fn with_other_transport< - OtherTransport: AuthenticatedMultiplexedTransport, - R: TryIntoTransport, - >( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result< - SwarmBuilder>, - R::Error, - > { - self.without_tcp() - .without_quic() - .with_other_transport(constructor) - } -} -macro_rules! impl_tcp_phase_with_websocket { - ($providerKebabCase:literal, $providerCamelCase:ident, $websocketStream:ty) => { - #[cfg(feature = $providerKebabCase)] - impl SwarmBuilder<$providerCamelCase, TcpPhase> { - #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] - pub async fn with_websocket < - SecUpgrade, - SecStream, - SecError, - MuxUpgrade, - MuxStream, - MuxError, - > ( - self, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder< - $providerCamelCase, - BandwidthLoggingPhase, - >, - WebsocketError, - > - where - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade<$websocketStream>, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - { - self.without_tcp() - .without_quic() - .without_any_other_transports() - .without_dns() - .without_relay() - .with_websocket(security_upgrade, multiplexer_upgrade) - .await - } - } - } -} -impl_tcp_phase_with_websocket!( - "async-std", - AsyncStd, - rw_stream_sink::RwStreamSink< - libp2p_websocket::BytesConnection, - > -); -impl_tcp_phase_with_websocket!( - "tokio", - Tokio, - rw_stream_sink::RwStreamSink> -); - -pub struct QuicPhase { - transport: T, -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "quic"))] -macro_rules! construct_other_transport_builder { - ($self:ident, $quic:ident, $config:expr) => { - SwarmBuilder { - phase: OtherTransportPhase { - transport: $self - .phase - .transport - .or_transport( - libp2p_quic::$quic::Transport::new($config) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), - ) - .map(|either, _| either.into_inner()), - }, - keypair: $self.keypair, - phantom: PhantomData, - } - }; -} - -macro_rules! impl_quic_builder { - ($providerKebabCase:literal, $providerCamelCase:ident, $quic:ident) => { - #[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = $providerKebabCase))] - impl SwarmBuilder<$providerCamelCase, QuicPhase> { - pub fn with_quic( - self, - ) -> SwarmBuilder< - $providerCamelCase, - OtherTransportPhase, - > { - self.with_quic_config(|key| libp2p_quic::Config::new(&key)) - } - - pub fn with_quic_config( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> libp2p_quic::Config, - ) -> SwarmBuilder< - $providerCamelCase, - OtherTransportPhase, - > { - construct_other_transport_builder!(self, $quic, constructor(&self.keypair)) - } - } - }; -} - -impl_quic_builder!("async-std", AsyncStd, async_std); -impl_quic_builder!("tokio", Tokio, tokio); - -impl SwarmBuilder> { - fn without_quic(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: OtherTransportPhase { - transport: self.phase.transport, - }, - } - } -} - -// Shortcuts -impl SwarmBuilder> { - #[cfg(feature = "relay")] - pub fn with_relay( - self, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder< - Provider, - WebsocketPhase, - >, - SecUpgrade::Error, - > where - - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - { - self.without_quic() - .with_relay(security_upgrade, multiplexer_upgrade) - } - - pub fn with_other_transport< - OtherTransport: AuthenticatedMultiplexedTransport, - R: TryIntoTransport, - >( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result< - SwarmBuilder>, - R::Error, - > { - self.without_quic().with_other_transport(constructor) - } - - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - self.without_quic() - .without_any_other_transports() - .without_dns() - .without_relay() - .without_websocket() - .with_behaviour(constructor) - } -} -#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] -impl SwarmBuilder> { - pub async fn with_dns( - self, - ) -> Result>, io::Error> - { - self.without_quic() - .without_any_other_transports() - .with_dns() - .await - } -} -#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] -impl SwarmBuilder> { - pub fn with_dns( - self, - ) -> Result>, io::Error> - { - self.without_quic() - .without_any_other_transports() - .with_dns() - } -} -macro_rules! impl_quic_phase_with_websocket { - ($providerKebabCase:literal, $providerCamelCase:ident, $websocketStream:ty) => { - #[cfg(feature = $providerKebabCase)] - impl SwarmBuilder<$providerCamelCase, QuicPhase> { - #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] - pub async fn with_websocket < - SecUpgrade, - SecStream, - SecError, - MuxUpgrade, - MuxStream, - MuxError, - > ( - self, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder< - $providerCamelCase, - BandwidthLoggingPhase, - >, - WebsocketError, - > - where - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade<$websocketStream>, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - { - self.without_quic() - .without_any_other_transports() - .without_dns() - .without_relay() - .with_websocket(security_upgrade, multiplexer_upgrade) - .await - } - } - } -} -impl_quic_phase_with_websocket!( - "async-std", - AsyncStd, - rw_stream_sink::RwStreamSink< - libp2p_websocket::BytesConnection, - > -); -impl_quic_phase_with_websocket!( - "tokio", - Tokio, - rw_stream_sink::RwStreamSink> -); - -pub struct OtherTransportPhase { - transport: T, -} - -impl - SwarmBuilder> -{ - pub fn with_other_transport< - OtherTransport: AuthenticatedMultiplexedTransport, - R: TryIntoTransport, - >( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result< - SwarmBuilder>, - R::Error, - > { - Ok(SwarmBuilder { - phase: OtherTransportPhase { - transport: self - .phase - .transport - .or_transport(constructor(&self.keypair).try_into_transport()?) - .map(|either, _| either.into_inner()), - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } - - fn without_any_other_transports(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: DnsPhase { - transport: self.phase.transport, - }, - } - } -} - -// Shortcuts -#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] -impl SwarmBuilder> { - pub async fn with_dns( - self, - ) -> Result>, io::Error> - { - self.without_any_other_transports().with_dns().await - } -} -#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] -impl SwarmBuilder> { - pub fn with_dns( - self, - ) -> Result>, io::Error> - { - self.without_any_other_transports().with_dns() - } -} -#[cfg(feature = "relay")] -impl - SwarmBuilder> -{ - pub fn with_relay( - self, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder< - Provider, - WebsocketPhase, - >, - SecUpgrade::Error, - > where - - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - { - self.without_any_other_transports() - .without_dns() - .with_relay(security_upgrade, multiplexer_upgrade) - } -} -impl - SwarmBuilder> -{ - pub fn with_bandwidth_logging( - self, - ) -> ( - SwarmBuilder< - Provider, - BehaviourPhase, - >, - Arc, - ) { - self.without_any_other_transports() - .without_dns() - .without_relay() - .without_websocket() - .with_bandwidth_logging() - } -} -impl - SwarmBuilder> -{ - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - self.without_any_other_transports() - .without_dns() - .without_relay() - .without_websocket() - .without_bandwidth_logging() - .with_behaviour(constructor) - } -} - -pub struct DnsPhase { - transport: T, -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] -impl SwarmBuilder> { - pub async fn with_dns( - self, - ) -> Result>, io::Error> - { - Ok(SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: RelayPhase { - transport: libp2p_dns::async_std::Transport::system(self.phase.transport).await?, - }, - }) - } -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] -impl SwarmBuilder> { - pub fn with_dns( - self, - ) -> Result>, io::Error> - { - Ok(SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: RelayPhase { - transport: libp2p_dns::tokio::Transport::system(self.phase.transport)?, - }, - }) - } -} - -impl SwarmBuilder> { - fn without_dns(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: RelayPhase { - transport: self.phase.transport, - }, - } - } -} - -// Shortcuts -impl SwarmBuilder> { - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - self.without_dns() - .without_relay() - .without_websocket() - .with_behaviour(constructor) - } -} - -pub struct RelayPhase { - transport: T, -} - -#[cfg(feature = "relay")] -impl SwarmBuilder> { - // TODO: This should be with_relay_client. - pub fn with_relay( - self, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder< - Provider, - WebsocketPhase, - >, - SecUpgrade::Error, - > where - - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - { - let (relay_transport, relay_behaviour) = - libp2p_relay::client::new(self.keypair.public().to_peer_id()); - - Ok(SwarmBuilder { - phase: WebsocketPhase { - relay_behaviour, - transport: self - .phase - .transport - .or_transport( - relay_transport - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate(security_upgrade.into_security_upgrade(&self.keypair)?) - .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))), - ) - .map(|either, _| either.into_inner()), - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } -} - -pub struct NoRelayBehaviour; - -impl SwarmBuilder> { - fn without_relay(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: WebsocketPhase { - transport: self.phase.transport, - relay_behaviour: NoRelayBehaviour, - }, - } - } -} - -// Shortcuts -impl SwarmBuilder> { - // TODO - // #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] - // pub fn with_websocket( - // self, - // ) -> SwarmBuilder< - // Provider, - // WebsocketTlsPhase, - // > { - // self.without_relay().with_websocket() - // } - - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - self.without_relay() - .without_websocket() - .with_behaviour(constructor) - } -} - -pub struct WebsocketPhase { - transport: T, - relay_behaviour: R, -} - -macro_rules! impl_websocket_builder { - ($providerKebabCase:literal, $providerCamelCase:ident, $dnsTcp:expr, $websocketStream:ty) => { - #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "websocket"))] - impl SwarmBuilder<$providerCamelCase, WebsocketPhase> { - pub async fn with_websocket< - SecUpgrade, - SecStream, - SecError, - MuxUpgrade, - MuxStream, - MuxError, - >( - self, - security_upgrade: SecUpgrade, - multiplexer_upgrade: MuxUpgrade, - ) -> Result< - SwarmBuilder< - $providerCamelCase, - BandwidthLoggingPhase, - >, - WebsocketError, - > - - where - T: AuthenticatedMultiplexedTransport, - - SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, - SecError: std::error::Error + Send + Sync + 'static, - SecUpgrade: IntoSecurityUpgrade<$websocketStream>, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - MuxStream: StreamMuxer + Send + 'static, - MuxStream::Substream: Send + 'static, - MuxStream::Error: Send + Sync + 'static, - MuxUpgrade: IntoMultiplexerUpgrade, - MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, - >>::Future: Send, - >>::Future: Send, - MuxError: std::error::Error + Send + Sync + 'static, - <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, - <>::Upgrade as UpgradeInfo>::Info: Send, - - { - let security_upgrade = security_upgrade.into_security_upgrade(&self.keypair) - .map_err(|e| WebsocketError(WebsocketErrorInner::SecurityUpgrade(e)))?; - let websocket_transport = libp2p_websocket::WsConfig::new( - $dnsTcp.await.map_err(|e| WebsocketError(e.into()))?, - ) - .upgrade(libp2p_core::upgrade::Version::V1Lazy) - .authenticate(security_upgrade) - .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) - .map(|(p, c), _| (p, StreamMuxerBox::new(c))); - - Ok(SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: BandwidthLoggingPhase { - transport: websocket_transport - .or_transport(self.phase.transport) - .map(|either, _| either.into_inner()), - relay_behaviour: self.phase.relay_behaviour, - }, - }) - } - } - }; -} - -impl_websocket_builder!( - "async-std", - AsyncStd, - libp2p_dns::async_std::Transport::system(libp2p_tcp::async_io::Transport::new( - libp2p_tcp::Config::default(), - )), - rw_stream_sink::RwStreamSink< - libp2p_websocket::BytesConnection, - > -); -// TODO: Unnecessary await for Tokio Websocket (i.e. tokio dns). Not ideal but don't know a better way. -impl_websocket_builder!( - "tokio", - Tokio, - futures::future::ready(libp2p_dns::tokio::Transport::system( - libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) - )), - rw_stream_sink::RwStreamSink> -); - -impl - SwarmBuilder> -{ - fn without_websocket(self) -> SwarmBuilder> { - SwarmBuilder { - keypair: self.keypair, - phantom: PhantomData, - phase: BandwidthLoggingPhase { - relay_behaviour: self.phase.relay_behaviour, - transport: self.phase.transport, - }, - } - } -} - -// Shortcuts -#[cfg(feature = "relay")] -impl - SwarmBuilder> -{ - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { - self.without_websocket() - .without_bandwidth_logging() - .with_behaviour(constructor) - } -} - -impl - SwarmBuilder> -{ - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - self.without_websocket() - .without_bandwidth_logging() - .with_behaviour(constructor) - } -} - -#[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub struct WebsocketError(WebsocketErrorInner); - -#[derive(Debug, thiserror::Error)] -enum WebsocketErrorInner { - #[error("SecurityUpgrade")] - SecurityUpgrade(Sec), - #[cfg(feature = "dns")] - #[error("Dns")] - Dns(#[from] io::Error), -} - -pub struct BandwidthLoggingPhase { - relay_behaviour: R, - transport: T, -} - -impl - SwarmBuilder> -{ - pub fn with_bandwidth_logging( - self, - ) -> ( - SwarmBuilder>, - Arc, - ) { - let (transport, sinks) = self.phase.transport.with_bandwidth_logging(); - ( - SwarmBuilder { - phase: BehaviourPhase { - relay_behaviour: self.phase.relay_behaviour, - transport, - }, - keypair: self.keypair, - phantom: PhantomData, - }, - sinks, - ) - } - - pub fn without_bandwidth_logging(self) -> SwarmBuilder> { - SwarmBuilder { - phase: BehaviourPhase { - relay_behaviour: self.phase.relay_behaviour, - transport: self.phase.transport, - }, - keypair: self.keypair, - phantom: PhantomData, - } - } -} - -// Shortcuts -#[cfg(feature = "relay")] -impl - SwarmBuilder> -{ - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { - self.without_bandwidth_logging().with_behaviour(constructor) - } -} - -impl - SwarmBuilder> -{ - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - self.without_bandwidth_logging().with_behaviour(constructor) - } -} - -pub struct BehaviourPhase { - relay_behaviour: R, - transport: T, -} - -#[cfg(feature = "relay")] -impl SwarmBuilder> { - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, - ) -> Result>, R::Error> { - Ok(SwarmBuilder { - phase: SwarmPhase { - behaviour: constructor(&self.keypair, self.phase.relay_behaviour) - .try_into_behaviour()?, - transport: self.phase.transport, - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } -} - -impl SwarmBuilder> { - pub fn with_behaviour>( - self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, - ) -> Result>, R::Error> { - // Discard `NoRelayBehaviour`. - let _ = self.phase.relay_behaviour; - - Ok(SwarmBuilder { - phase: SwarmPhase { - behaviour: constructor(&self.keypair).try_into_behaviour()?, - transport: self.phase.transport, - }, - keypair: self.keypair, - phantom: PhantomData, - }) - } -} - -pub struct SwarmPhase { - behaviour: B, - transport: T, -} - -impl SwarmBuilder> { - pub fn with_swarm_config( - self, - config: libp2p_swarm::SwarmConfig, - ) -> SwarmBuilder> { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: config, - }, - keypair: self.keypair, - phantom: PhantomData, - } - } -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] -impl - SwarmBuilder> -{ - pub fn build(self) -> Swarm { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: libp2p_swarm::SwarmConfig::with_async_std_executor(), - }, - keypair: self.keypair, - phantom: PhantomData::, - } - .build() - } -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] -impl - SwarmBuilder> -{ - pub fn build(self) -> Swarm { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: libp2p_swarm::SwarmConfig::with_tokio_executor(), - }, - keypair: self.keypair, - phantom: PhantomData::, - } - .build() - } -} - -#[cfg(feature = "wasm-bindgen")] -impl - SwarmBuilder> -{ - pub fn build(self) -> Swarm { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: libp2p_swarm::SwarmConfig::with_wasm_executor(), - }, - keypair: self.keypair, - phantom: PhantomData::, - } - .build() - } -} - -pub struct BuildPhase { - behaviour: B, - transport: T, - swarm_config: libp2p_swarm::SwarmConfig, -} - -const CONNECTION_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10); - -impl - SwarmBuilder> -{ - pub fn build(self) -> Swarm { - Swarm::new_with_config( - libp2p_core::transport::timeout::TransportTimeout::new( - self.phase.transport, - CONNECTION_TIMEOUT, - ) - .boxed(), - self.phase.behaviour, - self.keypair.public().to_peer_id(), - self.phase.swarm_config, - ) - } -} - -pub enum NoProviderSpecified {} - -#[cfg(feature = "async-std")] -pub enum AsyncStd {} - -#[cfg(feature = "tokio")] -pub enum Tokio {} - -#[cfg(feature = "wasm-bindgen")] -pub enum WasmBindgen {} - -pub trait AuthenticatedMultiplexedTransport: - Transport< - Error = Self::E, - Dial = Self::D, - ListenerUpgrade = Self::U, - Output = (libp2p_identity::PeerId, StreamMuxerBox), - > + Send - + Unpin - + 'static -{ - type E: Send + Sync + 'static; - type D: Send; - type U: Send; -} - -impl AuthenticatedMultiplexedTransport for T -where - T: Transport + Send + Unpin + 'static, - ::Error: Send + Sync + 'static, - ::Dial: Send, - ::ListenerUpgrade: Send, -{ - type E = T::Error; - type D = T::Dial; - type U = T::ListenerUpgrade; -} - -// TODO: Seal this. -pub trait TryIntoBehaviour { - type Error; - - fn try_into_behaviour(self) -> Result; -} - -impl TryIntoBehaviour for B -where - B: NetworkBehaviour, -{ - type Error = Infallible; - - fn try_into_behaviour(self) -> Result { - Ok(self) - } -} - -impl TryIntoBehaviour for Result> -where - B: NetworkBehaviour, -{ - // TODO mxinden: why do we need an io error here? isn't box enough? - type Error = io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? - - fn try_into_behaviour(self) -> Result { - self.map_err(|e| io::Error::new(io::ErrorKind::Other, e)) - } -} - -// TODO: Seal this. -pub trait TryIntoTransport { - type Error; - - fn try_into_transport(self) -> Result; -} - -impl TryIntoTransport for T -where - T: AuthenticatedMultiplexedTransport, -{ - type Error = Infallible; - - fn try_into_transport(self) -> Result { - Ok(self) - } -} - -impl TryIntoTransport for Result> -where - T: AuthenticatedMultiplexedTransport, -{ - // TODO mxinden: why do we need an io error here? isn't box enough? - type Error = io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? - - fn try_into_transport(self) -> Result { - self.map_err(|e| io::Error::new(io::ErrorKind::Other, e)) - } -} - #[cfg(test)] mod tests { - use super::*; + use libp2p_swarm::{NetworkBehaviour, Swarm}; + use crate::SwarmBuilder; #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] @@ -1593,10 +304,7 @@ mod tests { .unwrap() .with_relay(libp2p_tls::Config::new, libp2p_yamux::Config::default) .unwrap() - .with_websocket( - libp2p_tls::Config::new, - libp2p_yamux::Config::default, - ) + .with_websocket(libp2p_tls::Config::new, libp2p_yamux::Config::default) .await .unwrap() .with_bandwidth_logging(); diff --git a/libp2p/src/builder/phase.rs b/libp2p/src/builder/phase.rs new file mode 100644 index 00000000000..deeca3354f5 --- /dev/null +++ b/libp2p/src/builder/phase.rs @@ -0,0 +1,131 @@ +use libp2p_core::{upgrade::SelectUpgrade, Transport, muxing::StreamMuxerBox}; +use libp2p_identity::Keypair; + +use super::select_security::SelectSecurityUpgrade; + +mod identity; +mod provider; +mod tcp; +mod quic; +mod other_transport; +mod dns; +mod relay; +mod websocket; +mod bandwidth_logging; +mod behaviour; +mod swarm; +mod build; + +use provider::*; +use tcp::*; +use quic::*; +use other_transport::*; +use dns::*; +use relay::*; +use websocket::*; +use bandwidth_logging::*; +use behaviour::*; +use swarm::*; +use build::*; + +pub trait IntoSecurityUpgrade { + type Upgrade; + type Error; + + fn into_security_upgrade(self, keypair: &Keypair) -> Result; +} + +impl IntoSecurityUpgrade for F +where + F: for<'a> FnOnce(&'a Keypair) -> Result, +{ + type Upgrade = T; + type Error = E; + + fn into_security_upgrade(self, keypair: &Keypair) -> Result { + (self)(keypair) + } +} + +impl IntoSecurityUpgrade for (F1, F2) +where + F1: IntoSecurityUpgrade, + F2: IntoSecurityUpgrade, +{ + type Upgrade = SelectSecurityUpgrade; + type Error = either::Either; + + fn into_security_upgrade(self, keypair: &Keypair) -> Result { + let (f1, f2) = self; + + let u1 = f1 + .into_security_upgrade(keypair) + .map_err(either::Either::Left)?; + let u2 = f2 + .into_security_upgrade(keypair) + .map_err(either::Either::Right)?; + + Ok(SelectSecurityUpgrade::new(u1, u2)) + } +} + +pub trait IntoMultiplexerUpgrade { + type Upgrade; + + fn into_multiplexer_upgrade(self) -> Self::Upgrade; +} + +impl IntoMultiplexerUpgrade for F +where + F: FnOnce() -> U, +{ + type Upgrade = U; + + fn into_multiplexer_upgrade(self) -> Self::Upgrade { + (self)() + } +} + +impl IntoMultiplexerUpgrade for (U1, U2) +where + U1: IntoMultiplexerUpgrade, + U2: IntoMultiplexerUpgrade, +{ + type Upgrade = SelectUpgrade; + + fn into_multiplexer_upgrade(self) -> Self::Upgrade { + let (f1, f2) = self; + + let u1 = f1.into_multiplexer_upgrade(); + let u2 = f2.into_multiplexer_upgrade(); + + SelectUpgrade::new(u1, u2) + } +} + +pub trait AuthenticatedMultiplexedTransport: + Transport< + Error = Self::E, + Dial = Self::D, + ListenerUpgrade = Self::U, + Output = (libp2p_identity::PeerId, StreamMuxerBox), + > + Send + + Unpin + + 'static +{ + type E: Send + Sync + 'static; + type D: Send; + type U: Send; +} + +impl AuthenticatedMultiplexedTransport for T +where + T: Transport + Send + Unpin + 'static, + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, +{ + type E = T::Error; + type D = T::Dial; + type U = T::ListenerUpgrade; +} diff --git a/libp2p/src/builder/phase/bandwidth_logging.rs b/libp2p/src/builder/phase/bandwidth_logging.rs new file mode 100644 index 00000000000..3f3142d31a2 --- /dev/null +++ b/libp2p/src/builder/phase/bandwidth_logging.rs @@ -0,0 +1,70 @@ +use super::*; +use crate::bandwidth::BandwidthSinks; +use crate::transport_ext::TransportExt; +use crate::SwarmBuilder; +use std::marker::PhantomData; +use std::sync::Arc; + +pub struct BandwidthLoggingPhase { + pub(crate) relay_behaviour: R, + pub(crate) transport: T, +} + +impl + SwarmBuilder> +{ + pub fn with_bandwidth_logging( + self, + ) -> ( + SwarmBuilder>, + Arc, + ) { + let (transport, sinks) = self.phase.transport.with_bandwidth_logging(); + ( + SwarmBuilder { + phase: BehaviourPhase { + relay_behaviour: self.phase.relay_behaviour, + transport, + }, + keypair: self.keypair, + phantom: PhantomData, + }, + sinks, + ) + } + + pub fn without_bandwidth_logging(self) -> SwarmBuilder> { + SwarmBuilder { + phase: BehaviourPhase { + relay_behaviour: self.phase.relay_behaviour, + transport: self.phase.transport, + }, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +// Shortcuts +#[cfg(feature = "relay")] +impl + SwarmBuilder> +{ + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + ) -> Result>, R::Error> { + self.without_bandwidth_logging().with_behaviour(constructor) + } +} + +impl + SwarmBuilder> +{ + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_bandwidth_logging().with_behaviour(constructor) + } +} diff --git a/libp2p/src/builder/phase/behaviour.rs b/libp2p/src/builder/phase/behaviour.rs new file mode 100644 index 00000000000..39b730b896d --- /dev/null +++ b/libp2p/src/builder/phase/behaviour.rs @@ -0,0 +1,77 @@ +use crate::SwarmBuilder; +use std::marker::PhantomData; +use libp2p_swarm::NetworkBehaviour; +use std::convert::Infallible; +use super::*; + +pub struct BehaviourPhase { + pub(crate) relay_behaviour: R, + pub(crate) transport: T, +} + +#[cfg(feature = "relay")] +impl SwarmBuilder> { + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + ) -> Result>, R::Error> { + Ok(SwarmBuilder { + phase: SwarmPhase { + behaviour: constructor(&self.keypair, self.phase.relay_behaviour) + .try_into_behaviour()?, + transport: self.phase.transport, + }, + keypair: self.keypair, + phantom: PhantomData, + }) + } +} + +impl SwarmBuilder> { + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + // Discard `NoRelayBehaviour`. + let _ = self.phase.relay_behaviour; + + Ok(SwarmBuilder { + phase: SwarmPhase { + behaviour: constructor(&self.keypair).try_into_behaviour()?, + transport: self.phase.transport, + }, + keypair: self.keypair, + phantom: PhantomData, + }) + } +} + +// TODO: Seal this. +pub trait TryIntoBehaviour { + type Error; + + fn try_into_behaviour(self) -> Result; +} + +impl TryIntoBehaviour for B +where + B: NetworkBehaviour, +{ + type Error = Infallible; + + fn try_into_behaviour(self) -> Result { + Ok(self) + } +} + +impl TryIntoBehaviour for Result> +where + B: NetworkBehaviour, +{ + // TODO mxinden: why do we need an io error here? isn't box enough? + type Error = std::io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? + + fn try_into_behaviour(self) -> Result { + self.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)) + } +} diff --git a/libp2p/src/builder/phase/build.rs b/libp2p/src/builder/phase/build.rs new file mode 100644 index 00000000000..f78d9f76541 --- /dev/null +++ b/libp2p/src/builder/phase/build.rs @@ -0,0 +1,29 @@ +use crate::SwarmBuilder; +use libp2p_swarm::Swarm; +use libp2p_core::Transport; +use super::*; + +pub struct BuildPhase { + pub(crate) behaviour: B, + pub(crate) transport: T, + pub(crate) swarm_config: libp2p_swarm::SwarmConfig, +} + +const CONNECTION_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10); + +impl + SwarmBuilder> +{ + pub fn build(self) -> Swarm { + Swarm::new_with_config( + libp2p_core::transport::timeout::TransportTimeout::new( + self.phase.transport, + CONNECTION_TIMEOUT, + ) + .boxed(), + self.phase.behaviour, + self.keypair.public().to_peer_id(), + self.phase.swarm_config, + ) + } +} diff --git a/libp2p/src/builder/phase/dns.rs b/libp2p/src/builder/phase/dns.rs new file mode 100644 index 00000000000..1d20cacd26d --- /dev/null +++ b/libp2p/src/builder/phase/dns.rs @@ -0,0 +1,68 @@ +use super::*; +use crate::SwarmBuilder; +use std::marker::PhantomData; + +pub struct DnsPhase { + pub(crate) transport: T, +} + +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] +impl SwarmBuilder> { + pub async fn with_dns( + self, + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { + Ok(SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: RelayPhase { + transport: libp2p_dns::async_std::Transport::system(self.phase.transport).await?, + }, + }) + } +} + +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] +impl SwarmBuilder> { + pub fn with_dns( + self, + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { + Ok(SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: RelayPhase { + transport: libp2p_dns::tokio::Transport::system(self.phase.transport)?, + }, + }) + } +} + +impl SwarmBuilder> { + pub(crate) fn without_dns(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: RelayPhase { + transport: self.phase.transport, + }, + } + } +} + +// Shortcuts +impl SwarmBuilder> { + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_dns() + .without_relay() + .without_websocket() + .with_behaviour(constructor) + } +} diff --git a/libp2p/src/builder/phase/identity.rs b/libp2p/src/builder/phase/identity.rs new file mode 100644 index 00000000000..483b086c235 --- /dev/null +++ b/libp2p/src/builder/phase/identity.rs @@ -0,0 +1,23 @@ +use std::marker::PhantomData; +use crate::SwarmBuilder; +use super::*; + + +// TODO: Rename to IdentityPhase +pub struct InitialPhase {} + +impl SwarmBuilder { + pub fn with_new_identity() -> SwarmBuilder { + SwarmBuilder::with_existing_identity(libp2p_identity::Keypair::generate_ed25519()) + } + + pub fn with_existing_identity( + keypair: libp2p_identity::Keypair, + ) -> SwarmBuilder { + SwarmBuilder { + keypair, + phantom: PhantomData, + phase: ProviderPhase {}, + } + } +} diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs new file mode 100644 index 00000000000..27408502128 --- /dev/null +++ b/libp2p/src/builder/phase/other_transport.rs @@ -0,0 +1,188 @@ +use std::convert::Infallible; +use std::marker::PhantomData; +use std::sync::Arc; + +use libp2p_core::Transport; +#[cfg(feature = "relay")] +use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, StreamMuxer, UpgradeInfo}; +#[cfg(feature = "relay")] +use libp2p_identity::PeerId; + +use crate::bandwidth::BandwidthSinks; +use crate::SwarmBuilder; + +use super::*; + +pub struct OtherTransportPhase { + pub(crate) transport: T, +} + +impl + SwarmBuilder> +{ + pub fn with_other_transport< + OtherTransport: AuthenticatedMultiplexedTransport, + R: TryIntoTransport, + >( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result< + SwarmBuilder>, + R::Error, + > { + Ok(SwarmBuilder { + phase: OtherTransportPhase { + transport: self + .phase + .transport + .or_transport(constructor(&self.keypair).try_into_transport()?) + .map(|either, _| either.into_inner()), + }, + keypair: self.keypair, + phantom: PhantomData, + }) + } + + pub(crate) fn without_any_other_transports(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: DnsPhase { + transport: self.phase.transport, + }, + } + } +} + +// Shortcuts +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] +impl + SwarmBuilder> +{ + pub async fn with_dns( + self, + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { + self.without_any_other_transports().with_dns().await + } +} +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] +impl + SwarmBuilder> +{ + pub fn with_dns( + self, + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { + self.without_any_other_transports().with_dns() + } +} +#[cfg(feature = "relay")] +impl + SwarmBuilder> +{ + pub fn with_relay( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + Provider, + WebsocketPhase, + >, + SecUpgrade::Error, + > where + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_any_other_transports() + .without_dns() + .with_relay(security_upgrade, multiplexer_upgrade) + } +} +impl + SwarmBuilder> +{ + pub fn with_bandwidth_logging( + self, + ) -> ( + SwarmBuilder< + Provider, + BehaviourPhase, + >, + Arc, + ) { + self.without_any_other_transports() + .without_dns() + .without_relay() + .without_websocket() + .with_bandwidth_logging() + } +} +impl + SwarmBuilder> +{ + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_any_other_transports() + .without_dns() + .without_relay() + .without_websocket() + .without_bandwidth_logging() + .with_behaviour(constructor) + } +} + +// TODO: Seal this. +pub trait TryIntoTransport { + type Error; + + fn try_into_transport(self) -> Result; +} + +impl TryIntoTransport for T +where + T: AuthenticatedMultiplexedTransport, +{ + type Error = Infallible; + + fn try_into_transport(self) -> Result { + Ok(self) + } +} + +impl TryIntoTransport for Result> +where + T: AuthenticatedMultiplexedTransport, +{ + // TODO mxinden: why do we need an io error here? isn't box enough? + type Error = std::io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? + + fn try_into_transport(self) -> Result { + self.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)) + } +} diff --git a/libp2p/src/builder/phase/provider.rs b/libp2p/src/builder/phase/provider.rs new file mode 100644 index 00000000000..a9bccaf1c21 --- /dev/null +++ b/libp2p/src/builder/phase/provider.rs @@ -0,0 +1,45 @@ +use super::*; +use crate::SwarmBuilder; +use std::marker::PhantomData; + +pub struct ProviderPhase {} + +impl SwarmBuilder { + #[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] + pub fn with_async_std(self) -> SwarmBuilder { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: TcpPhase {}, + } + } + + #[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] + pub fn with_tokio(self) -> SwarmBuilder { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: TcpPhase {}, + } + } + + #[cfg(feature = "wasm-bindgen")] + pub fn with_wasm_bindgen(self) -> SwarmBuilder { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: TcpPhase {}, + } + } +} + +pub enum NoProviderSpecified {} + +#[cfg(feature = "async-std")] +pub enum AsyncStd {} + +#[cfg(feature = "tokio")] +pub enum Tokio {} + +#[cfg(feature = "wasm-bindgen")] +pub enum WasmBindgen {} diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs new file mode 100644 index 00000000000..f282203ecb9 --- /dev/null +++ b/libp2p/src/builder/phase/quic.rs @@ -0,0 +1,226 @@ +use super::*; +use libp2p_core::Transport; +use crate::SwarmBuilder; +use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; +use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; +use libp2p_identity::PeerId; +use std::marker::PhantomData; +use std::io; + +pub struct QuicPhase { + pub(crate) transport: T, +} + +#[cfg(all(not(target_arch = "wasm32"), feature = "quic"))] +macro_rules! construct_other_transport_builder { + ($self:ident, $quic:ident, $config:expr) => { + SwarmBuilder { + phase: OtherTransportPhase { + transport: $self + .phase + .transport + .or_transport( + libp2p_quic::$quic::Transport::new($config) + .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), + ) + .map(|either, _| either.into_inner()), + }, + keypair: $self.keypair, + phantom: PhantomData, + } + }; +} + +macro_rules! impl_quic_builder { + ($providerKebabCase:literal, $providerCamelCase:ty, $quic:ident) => { + #[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = $providerKebabCase))] + impl SwarmBuilder<$providerCamelCase, QuicPhase> { + pub fn with_quic( + self, + ) -> SwarmBuilder< + $providerCamelCase, + OtherTransportPhase, + > { + self.with_quic_config(|key| libp2p_quic::Config::new(&key)) + } + + pub fn with_quic_config( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> libp2p_quic::Config, + ) -> SwarmBuilder< + $providerCamelCase, + OtherTransportPhase, + > { + construct_other_transport_builder!(self, $quic, constructor(&self.keypair)) + } + } + }; +} + +impl_quic_builder!("async-std", AsyncStd, async_std); +impl_quic_builder!("tokio", super::provider::Tokio, tokio); + +impl SwarmBuilder> { + pub(crate) fn without_quic(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: OtherTransportPhase { + transport: self.phase.transport, + }, + } + } +} + +// Shortcuts +impl SwarmBuilder> { + #[cfg(feature = "relay")] + pub fn with_relay( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + Provider, + super::websocket::WebsocketPhase, + >, + SecUpgrade::Error, + > where + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_quic() + .with_relay(security_upgrade, multiplexer_upgrade) + } + + pub fn with_other_transport< + OtherTransport: AuthenticatedMultiplexedTransport, + R: TryIntoTransport, + >( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result< + SwarmBuilder>, + R::Error, + > { + self.without_quic().with_other_transport(constructor) + } + + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .without_websocket() + .with_behaviour(constructor) + } +} +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std", feature = "dns"))] +impl SwarmBuilder> { + pub async fn with_dns( + self, + ) -> Result>, io::Error> + { + self.without_quic() + .without_any_other_transports() + .with_dns() + .await + } +} +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio", feature = "dns"))] +impl SwarmBuilder> { + pub fn with_dns( + self, + ) -> Result>, io::Error> + { + self.without_quic() + .without_any_other_transports() + .with_dns() + } +} +macro_rules! impl_quic_phase_with_websocket { + ($providerKebabCase:literal, $providerCamelCase:ty, $websocketStream:ty) => { + #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] + impl SwarmBuilder<$providerCamelCase, QuicPhase> { + pub async fn with_websocket < + SecUpgrade, + SecStream, + SecError, + MuxUpgrade, + MuxStream, + MuxError, + > ( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + $providerCamelCase, + BandwidthLoggingPhase, + >, + super::websocket::WebsocketError, + > + where + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade<$websocketStream>, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .with_websocket(security_upgrade, multiplexer_upgrade) + .await + } + } + } +} +impl_quic_phase_with_websocket!( + "async-std", + super::provider::AsyncStd, + rw_stream_sink::RwStreamSink< + libp2p_websocket::BytesConnection, + > +); +impl_quic_phase_with_websocket!( + "tokio", + super::provider::Tokio, + rw_stream_sink::RwStreamSink> +); diff --git a/libp2p/src/builder/phase/relay.rs b/libp2p/src/builder/phase/relay.rs new file mode 100644 index 00000000000..ffc105c0b14 --- /dev/null +++ b/libp2p/src/builder/phase/relay.rs @@ -0,0 +1,117 @@ +use std::marker::PhantomData; + +#[cfg(feature = "relay")] +use libp2p_core::muxing::StreamMuxerBox; +#[cfg(feature = "relay")] +use libp2p_core::Transport; +#[cfg(feature = "relay")] +use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, StreamMuxer, UpgradeInfo}; +#[cfg(feature = "relay")] +use libp2p_identity::PeerId; + +use crate::SwarmBuilder; + +use super::*; + +pub struct RelayPhase { + pub(crate) transport: T, +} + +#[cfg(feature = "relay")] +impl SwarmBuilder> { + // TODO: This should be with_relay_client. + pub fn with_relay( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + Provider, + WebsocketPhase, + >, + SecUpgrade::Error, + > where + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + let (relay_transport, relay_behaviour) = + libp2p_relay::client::new(self.keypair.public().to_peer_id()); + + Ok(SwarmBuilder { + phase: WebsocketPhase { + relay_behaviour, + transport: self + .phase + .transport + .or_transport( + relay_transport + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate(security_upgrade.into_security_upgrade(&self.keypair)?) + .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + ) + .map(|either, _| either.into_inner()), + }, + keypair: self.keypair, + phantom: PhantomData, + }) + } +} + +pub struct NoRelayBehaviour; + +impl SwarmBuilder> { + pub(crate) fn without_relay( + self, + ) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: WebsocketPhase { + transport: self.phase.transport, + relay_behaviour: NoRelayBehaviour, + }, + } + } +} + +// Shortcuts +impl SwarmBuilder> { + // TODO + // #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] + // pub fn with_websocket( + // self, + // ) -> SwarmBuilder< + // Provider, + // WebsocketTlsPhase, + // > { + // self.without_relay().with_websocket() + // } + + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_relay() + .without_websocket() + .with_behaviour(constructor) + } +} diff --git a/libp2p/src/builder/phase/swarm.rs b/libp2p/src/builder/phase/swarm.rs new file mode 100644 index 00000000000..32b55c92bd1 --- /dev/null +++ b/libp2p/src/builder/phase/swarm.rs @@ -0,0 +1,80 @@ +use super::*; +use crate::SwarmBuilder; +use libp2p_swarm::{NetworkBehaviour, Swarm}; +use std::marker::PhantomData; + +pub struct SwarmPhase { + pub(crate) behaviour: B, + pub(crate) transport: T, +} + +impl SwarmBuilder> { + pub fn with_swarm_config( + self, + config: libp2p_swarm::SwarmConfig, + ) -> SwarmBuilder> { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: config, + }, + keypair: self.keypair, + phantom: PhantomData, + } + } +} + +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] +impl + SwarmBuilder> +{ + pub fn build(self) -> Swarm { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: libp2p_swarm::SwarmConfig::with_async_std_executor(), + }, + keypair: self.keypair, + phantom: PhantomData::, + } + .build() + } +} + +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] +impl + SwarmBuilder> +{ + pub fn build(self) -> Swarm { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: libp2p_swarm::SwarmConfig::with_tokio_executor(), + }, + keypair: self.keypair, + phantom: PhantomData::, + } + .build() + } +} + +#[cfg(feature = "wasm-bindgen")] +impl + SwarmBuilder> +{ + pub fn build(self) -> Swarm { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: libp2p_swarm::SwarmConfig::with_wasm_executor(), + }, + keypair: self.keypair, + phantom: PhantomData::, + } + .build() + } +} diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs new file mode 100644 index 00000000000..042999f0d2b --- /dev/null +++ b/libp2p/src/builder/phase/tcp.rs @@ -0,0 +1,186 @@ +use super::*; +use libp2p_core::Transport; +use crate::SwarmBuilder; +use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; +use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; +use libp2p_identity::PeerId; +use std::marker::PhantomData; + +pub struct TcpPhase {} + +macro_rules! impl_tcp_builder { + ($providerKebabCase:literal, $providerCamelCase:ty, $path:ident) => { + #[cfg(all( + not(target_arch = "wasm32"), + feature = "tcp", + feature = $providerKebabCase, + ))] + impl SwarmBuilder<$providerCamelCase, TcpPhase> { + pub fn with_tcp( + self, + tcp_config: libp2p_tcp::Config, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder<$providerCamelCase, QuicPhase>, + SecUpgrade::Error, + > + where + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + Ok(SwarmBuilder { + phase: QuicPhase { + transport: libp2p_tcp::$path::Transport::new(tcp_config) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate( + security_upgrade.into_security_upgrade(&self.keypair)?, + ) + .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))), + }, + keypair: self.keypair, + phantom: PhantomData, + }) + } + } + }; +} + +impl_tcp_builder!("async-std", super::provider::AsyncStd, async_io); +impl_tcp_builder!("tokio", super::provider::Tokio, tokio); + +impl SwarmBuilder { + // TODO: This would allow one to build a faulty transport. + pub(crate) fn without_tcp( + self, + ) -> SwarmBuilder> { + SwarmBuilder { + // TODO: Is this a good idea in a production environment? Unfortunately I don't know a + // way around it. One can not define two `with_relay` methods, one with a real transport + // using OrTransport, one with a fake transport discarding it right away. + keypair: self.keypair, + phantom: PhantomData, + phase: QuicPhase { + transport: libp2p_core::transport::dummy::DummyTransport::new(), + }, + } + } +} + +// Shortcuts +#[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = "async-std"))] +impl SwarmBuilder { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + self.without_tcp().with_quic() + } +} +#[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = "tokio"))] +impl SwarmBuilder { + pub fn with_quic( + self, + ) -> SwarmBuilder> { + self.without_tcp().with_quic() + } +} +impl SwarmBuilder { + pub fn with_other_transport< + OtherTransport: AuthenticatedMultiplexedTransport, + R: TryIntoTransport, + >( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result< + SwarmBuilder>, + R::Error, + > { + self.without_tcp() + .without_quic() + .with_other_transport(constructor) + } +} +macro_rules! impl_tcp_phase_with_websocket { + ($providerKebabCase:literal, $providerCamelCase:ty, $websocketStream:ty) => { + #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] + impl SwarmBuilder<$providerCamelCase, TcpPhase> { + pub async fn with_websocket < + SecUpgrade, + SecStream, + SecError, + MuxUpgrade, + MuxStream, + MuxError, + > ( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + $providerCamelCase, + BandwidthLoggingPhase, + >, + WebsocketError, + > + where + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade<$websocketStream>, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_tcp() + .without_quic() + .without_any_other_transports() + .without_dns() + .without_relay() + .with_websocket(security_upgrade, multiplexer_upgrade) + .await + } + } + } +} +impl_tcp_phase_with_websocket!( + "async-std", + super::provider::AsyncStd, + rw_stream_sink::RwStreamSink< + libp2p_websocket::BytesConnection, + > +); +impl_tcp_phase_with_websocket!( + "tokio", + super::provider::Tokio, + rw_stream_sink::RwStreamSink> +); diff --git a/libp2p/src/builder/phase/websocket.rs b/libp2p/src/builder/phase/websocket.rs new file mode 100644 index 00000000000..2a05ba6f79d --- /dev/null +++ b/libp2p/src/builder/phase/websocket.rs @@ -0,0 +1,166 @@ +use super::*; +use crate::SwarmBuilder; +#[cfg(feature = "websocket")] +use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; +#[cfg(feature = "websocket")] +use libp2p_core::Transport; +#[cfg(feature = "websocket")] +use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; +#[cfg(feature = "websocket")] +use libp2p_identity::PeerId; +use std::marker::PhantomData; + +pub struct WebsocketPhase { + pub(crate) transport: T, + pub(crate) relay_behaviour: R, +} + +macro_rules! impl_websocket_builder { + ($providerKebabCase:literal, $providerCamelCase:ty, $dnsTcp:expr, $websocketStream:ty) => { + #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "websocket"))] + impl SwarmBuilder<$providerCamelCase, WebsocketPhase> { + pub async fn with_websocket< + SecUpgrade, + SecStream, + SecError, + MuxUpgrade, + MuxStream, + MuxError, + >( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + $providerCamelCase, + BandwidthLoggingPhase, + >, + WebsocketError, + > + + where + T: AuthenticatedMultiplexedTransport, + + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade<$websocketStream>, + SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + { + let security_upgrade = security_upgrade.into_security_upgrade(&self.keypair) + .map_err(|e| WebsocketError(WebsocketErrorInner::SecurityUpgrade(e)))?; + let websocket_transport = libp2p_websocket::WsConfig::new( + $dnsTcp.await.map_err(|e| WebsocketError(e.into()))?, + ) + .upgrade(libp2p_core::upgrade::Version::V1Lazy) + .authenticate(security_upgrade) + .multiplex(multiplexer_upgrade.into_multiplexer_upgrade()) + .map(|(p, c), _| (p, StreamMuxerBox::new(c))); + + Ok(SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: BandwidthLoggingPhase { + transport: websocket_transport + .or_transport(self.phase.transport) + .map(|either, _| either.into_inner()), + relay_behaviour: self.phase.relay_behaviour, + }, + }) + } + } + }; +} + +impl_websocket_builder!( + "async-std", + super::provider::AsyncStd, + libp2p_dns::async_std::Transport::system(libp2p_tcp::async_io::Transport::new( + libp2p_tcp::Config::default(), + )), + rw_stream_sink::RwStreamSink< + libp2p_websocket::BytesConnection, + > +); +// TODO: Unnecessary await for Tokio Websocket (i.e. tokio dns). Not ideal but don't know a better way. +impl_websocket_builder!( + "tokio", + super::provider::Tokio, + futures::future::ready(libp2p_dns::tokio::Transport::system( + libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) + )), + rw_stream_sink::RwStreamSink> +); + +impl + SwarmBuilder> +{ + pub(crate) fn without_websocket(self) -> SwarmBuilder> { + SwarmBuilder { + keypair: self.keypair, + phantom: PhantomData, + phase: BandwidthLoggingPhase { + relay_behaviour: self.phase.relay_behaviour, + transport: self.phase.transport, + }, + } + } +} + +// Shortcuts +#[cfg(feature = "relay")] +impl + SwarmBuilder> +{ + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair, libp2p_relay::client::Behaviour) -> R, + ) -> Result>, R::Error> { + self.without_websocket() + .without_bandwidth_logging() + .with_behaviour(constructor) + } +} + +impl + SwarmBuilder> +{ + pub fn with_behaviour>( + self, + constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, + ) -> Result>, R::Error> { + self.without_websocket() + .without_bandwidth_logging() + .with_behaviour(constructor) + } +} + +#[derive(Debug, thiserror::Error)] +#[error(transparent)] +#[cfg(feature = "websocket")] +pub struct WebsocketError(WebsocketErrorInner); + +#[derive(Debug, thiserror::Error)] +#[cfg(feature = "websocket")] +enum WebsocketErrorInner { + #[error("SecurityUpgrade")] + SecurityUpgrade(Sec), + #[cfg(feature = "dns")] + #[error("Dns")] + Dns(#[from] std::io::Error), +} From 4b052e560170b08b334c12ef9a6e07a7829dadab Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 15:42:20 +0200 Subject: [PATCH 106/171] Update upnp and browser webrtc --- examples/browser-webrtc/src/main.rs | 31 ++++++++++++++-------------- examples/upnp/Cargo.toml | 2 +- examples/upnp/src/main.rs | 32 +++++++++-------------------- libp2p/src/builder/phase/quic.rs | 9 +++++--- libp2p/src/builder/phase/tcp.rs | 1 + swarm-test/src/lib.rs | 2 +- swarm/src/lib.rs | 2 +- 7 files changed, 36 insertions(+), 43 deletions(-) diff --git a/examples/browser-webrtc/src/main.rs b/examples/browser-webrtc/src/main.rs index ed936243c0a..baac6d1f06d 100644 --- a/examples/browser-webrtc/src/main.rs +++ b/examples/browser-webrtc/src/main.rs @@ -7,11 +7,9 @@ use axum::http::StatusCode; use axum::response::{Html, IntoResponse}; use axum::{http::Method, routing::get, Router}; use futures::StreamExt; -use libp2p::swarm::SwarmBuilder; use libp2p::{ core::muxing::StreamMuxerBox, core::Transport, - identity, multiaddr::{Multiaddr, Protocol}, ping, swarm::SwarmEvent, @@ -29,19 +27,22 @@ async fn main() -> anyhow::Result<()> { .parse_default_env() .init(); - let id_keys = identity::Keypair::generate_ed25519(); - let local_peer_id = id_keys.public().to_peer_id(); - let transport = webrtc::tokio::Transport::new( - id_keys, - webrtc::tokio::Certificate::generate(&mut thread_rng())?, - ) - .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) - .boxed(); - - let mut swarm = - SwarmBuilder::with_tokio_executor(transport, ping::Behaviour::default(), local_peer_id) - .idle_connection_timeout(Duration::from_secs(30)) // Allows us to observe the pings. - .build(); + let mut swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_other_transport(|id_keys| { + Ok(webrtc::tokio::Transport::new( + id_keys.clone(), + webrtc::tokio::Certificate::generate(&mut thread_rng())?, + ) + .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn)))) + })? + .with_behaviour(|_| ping::Behaviour::default())? + .with_swarm_config( + libp2p::swarm::SwarmConfig::with_tokio_executor().with_idle_connection_timeout( + Duration::from_secs(30), // Allows us to observe the pings. + ), + ) + .build(); let address_webrtc = Multiaddr::from(Ipv4Addr::UNSPECIFIED) .with(Protocol::Udp(0)) diff --git a/examples/upnp/Cargo.toml b/examples/upnp/Cargo.toml index afb8f61d2a2..6dc28ca69a9 100644 --- a/examples/upnp/Cargo.toml +++ b/examples/upnp/Cargo.toml @@ -8,4 +8,4 @@ license = "MIT" [dependencies] tokio = { version = "1", features = [ "rt-multi-thread", "macros"] } futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["tokio", "dns", "macros", "noise", "ping", "tcp", "websocket", "yamux", "upnp"] } +libp2p = { path = "../../libp2p", features = ["tokio", "dns", "macros", "noise", "ping", "tcp", "yamux", "upnp"] } diff --git a/examples/upnp/src/main.rs b/examples/upnp/src/main.rs index b4350dc82ad..c602a687db7 100644 --- a/examples/upnp/src/main.rs +++ b/examples/upnp/src/main.rs @@ -21,32 +21,20 @@ #![doc = include_str!("../README.md")] use futures::prelude::*; -use libp2p::core::upgrade::Version; -use libp2p::{ - identity, noise, - swarm::{SwarmBuilder, SwarmEvent}, - tcp, upnp, yamux, Multiaddr, PeerId, Transport, -}; +use libp2p::{noise, swarm::SwarmEvent, upnp, yamux, Multiaddr}; use std::error::Error; #[tokio::main] async fn main() -> Result<(), Box> { - let local_key = identity::Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - println!("Local peer id: {local_peer_id:?}"); - - let transport = tcp::tokio::Transport::default() - .upgrade(Version::V1Lazy) - .authenticate(noise::Config::new(&local_key)?) - .multiplex(yamux::Config::default()) - .boxed(); - - let mut swarm = SwarmBuilder::with_tokio_executor( - transport, - upnp::tokio::Behaviour::default(), - local_peer_id, - ) - .build(); + let mut swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp( + Default::default(), + noise::Config::new, + yamux::Config::default, + )? + .with_behaviour(|_| upnp::tokio::Behaviour::default())? + .build(); // Tell the swarm to listen on all interfaces and a random, OS-assigned // port. diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index f282203ecb9..35ce11d5372 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -1,11 +1,14 @@ use super::*; +#[cfg(feature = "websocket")] use libp2p_core::Transport; use crate::SwarmBuilder; +#[cfg(feature = "websocket")] use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; +#[cfg(feature = "websocket")] use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; +#[cfg(feature = "websocket")] use libp2p_identity::PeerId; use std::marker::PhantomData; -use std::io; pub struct QuicPhase { pub(crate) transport: T, @@ -140,7 +143,7 @@ impl SwarmBuilder SwarmBuilder> { pub async fn with_dns( self, - ) -> Result>, io::Error> + ) -> Result>, std::io::Error> { self.without_quic() .without_any_other_transports() @@ -152,7 +155,7 @@ impl SwarmBuilder SwarmBuilder> { pub fn with_dns( self, - ) -> Result>, io::Error> + ) -> Result>, std::io::Error> { self.without_quic() .without_any_other_transports() diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index 042999f0d2b..ab7af1cdfad 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -1,4 +1,5 @@ use super::*; +#[cfg(feature = "websocket")] use libp2p_core::Transport; use crate::SwarmBuilder; use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index 06aa1fb73fd..158a6b38152 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -220,7 +220,7 @@ where transport, behaviour_fn(identity), peer_id, - SwarmConfig::without_executor().idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., + SwarmConfig::without_executor().with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., ) } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index c07995b7a42..29d9d808a55 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1497,7 +1497,7 @@ impl SwarmConfig { /// How long to keep a connection alive once it is idling. /// /// Defaults to 0. - pub fn idle_connection_timeout(mut self, timeout: Duration) -> Self { + pub fn with_idle_connection_timeout(mut self, timeout: Duration) -> Self { self.pool_config.idle_connection_timeout = timeout; self } From 5faae591171574f69aa1817100f375c26eadb377 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 15:59:38 +0200 Subject: [PATCH 107/171] Rename SwarmConfig to Config --- examples/browser-webrtc/src/main.rs | 2 +- libp2p/src/builder.rs | 2 +- libp2p/src/builder/map.rs | 76 ----------------------------- libp2p/src/builder/phase/build.rs | 2 +- libp2p/src/builder/phase/swarm.rs | 8 +-- protocols/dcutr/tests/lib.rs | 4 +- protocols/kad/src/behaviour/test.rs | 4 +- protocols/perf/src/bin/perf.rs | 4 +- protocols/relay/tests/lib.rs | 6 +-- swarm-test/src/lib.rs | 6 +-- swarm/CHANGELOG.md | 2 +- swarm/src/lib.rs | 50 +++++++++---------- transports/pnet/tests/smoke.rs | 4 +- transports/tls/tests/smoke.rs | 4 +- 14 files changed, 48 insertions(+), 126 deletions(-) delete mode 100644 libp2p/src/builder/map.rs diff --git a/examples/browser-webrtc/src/main.rs b/examples/browser-webrtc/src/main.rs index baac6d1f06d..bd067605546 100644 --- a/examples/browser-webrtc/src/main.rs +++ b/examples/browser-webrtc/src/main.rs @@ -38,7 +38,7 @@ async fn main() -> anyhow::Result<()> { })? .with_behaviour(|_| ping::Behaviour::default())? .with_swarm_config( - libp2p::swarm::SwarmConfig::with_tokio_executor().with_idle_connection_timeout( + libp2p::swarm::Config::with_tokio_executor().with_idle_connection_timeout( Duration::from_secs(30), // Allows us to observe the pings. ), ) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index bd47e1727bf..3a32703ead4 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -6,7 +6,7 @@ use std::marker::PhantomData; feature = "noise", any(feature = "tcp", feature = "relay", feature = "websocket") ))] -mod map; +// mod map; mod select_security; mod phase; diff --git a/libp2p/src/builder/map.rs b/libp2p/src/builder/map.rs deleted file mode 100644 index d3909c61b7b..00000000000 --- a/libp2p/src/builder/map.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2018 Parity Technologies (UK) Ltd. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -use futures::future::{self, TryFutureExt}; -use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; - -/// Upgrade applying a function to an inner upgrade. -#[derive(Debug, Clone)] -pub(crate) struct Upgrade { - upgrade: U, - fun: F, -} - -impl Upgrade { - /// Applies the function on the result of the upgrade. - pub(crate) fn new(upgrade: U, fun: F) -> Self { - Upgrade { upgrade, fun } - } -} - -impl UpgradeInfo for Upgrade -where - U: UpgradeInfo, -{ - type Info = U::Info; - type InfoIter = U::InfoIter; - - fn protocol_info(&self) -> Self::InfoIter { - self.upgrade.protocol_info() - } -} - -impl InboundUpgrade for Upgrade -where - U: InboundUpgrade, - F: FnOnce(U::Output) -> D, -{ - type Output = D; - type Error = U::Error; - type Future = future::MapOk; - - fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future { - self.upgrade.upgrade_inbound(sock, info).map_ok(self.fun) - } -} - -impl OutboundUpgrade for Upgrade -where - U: OutboundUpgrade, - F: FnOnce(U::Output) -> D, -{ - type Output = D; - type Error = U::Error; - type Future = future::MapOk; - - fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future { - self.upgrade.upgrade_outbound(sock, info).map_ok(self.fun) - } -} diff --git a/libp2p/src/builder/phase/build.rs b/libp2p/src/builder/phase/build.rs index f78d9f76541..669b9fc82c5 100644 --- a/libp2p/src/builder/phase/build.rs +++ b/libp2p/src/builder/phase/build.rs @@ -6,7 +6,7 @@ use super::*; pub struct BuildPhase { pub(crate) behaviour: B, pub(crate) transport: T, - pub(crate) swarm_config: libp2p_swarm::SwarmConfig, + pub(crate) swarm_config: libp2p_swarm::Config, } const CONNECTION_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10); diff --git a/libp2p/src/builder/phase/swarm.rs b/libp2p/src/builder/phase/swarm.rs index 32b55c92bd1..680a0107a4a 100644 --- a/libp2p/src/builder/phase/swarm.rs +++ b/libp2p/src/builder/phase/swarm.rs @@ -11,7 +11,7 @@ pub struct SwarmPhase { impl SwarmBuilder> { pub fn with_swarm_config( self, - config: libp2p_swarm::SwarmConfig, + config: libp2p_swarm::Config, ) -> SwarmBuilder> { SwarmBuilder { phase: BuildPhase { @@ -34,7 +34,7 @@ impl phase: BuildPhase { behaviour: self.phase.behaviour, transport: self.phase.transport, - swarm_config: libp2p_swarm::SwarmConfig::with_async_std_executor(), + swarm_config: libp2p_swarm::Config::with_async_std_executor(), }, keypair: self.keypair, phantom: PhantomData::, @@ -52,7 +52,7 @@ impl phase: BuildPhase { behaviour: self.phase.behaviour, transport: self.phase.transport, - swarm_config: libp2p_swarm::SwarmConfig::with_tokio_executor(), + swarm_config: libp2p_swarm::Config::with_tokio_executor(), }, keypair: self.keypair, phantom: PhantomData::, @@ -70,7 +70,7 @@ impl phase: BuildPhase { behaviour: self.phase.behaviour, transport: self.phase.transport, - swarm_config: libp2p_swarm::SwarmConfig::with_wasm_executor(), + swarm_config: libp2p_swarm::Config::with_wasm_executor(), }, keypair: self.keypair, phantom: PhantomData::, diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index 45250d6b089..0c6d444ed60 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -26,7 +26,7 @@ use libp2p_identity as identity; use libp2p_identity::PeerId; use libp2p_plaintext as plaintext; use libp2p_relay as relay; -use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; +use libp2p_swarm::{NetworkBehaviour, Swarm, Config, SwarmEvent}; use libp2p_swarm_test::SwarmExt as _; use std::time::Duration; @@ -130,7 +130,7 @@ fn build_client() -> Swarm { dcutr: dcutr::Behaviour::new(local_peer_id), }, local_peer_id, - SwarmConfig::without_executor(), + Config::without_executor(), ) } diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index 3c764f4ac25..799720ca194 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -37,7 +37,7 @@ use libp2p_core::{ use libp2p_identity as identity; use libp2p_identity::PeerId; use libp2p_noise as noise; -use libp2p_swarm::{ConnectionId, Swarm, SwarmConfig, SwarmEvent}; +use libp2p_swarm::{ConnectionId, Swarm, Config, SwarmEvent}; use libp2p_yamux as yamux; use quickcheck::*; use rand::{random, rngs::StdRng, thread_rng, Rng, SeedableRng}; @@ -71,7 +71,7 @@ fn build_node_with_config(cfg: Config) -> (Multiaddr, TestSwarm) { transport, behaviour, local_id, - SwarmConfig::without_executor(), + Config::without_executor(), ); let address: Multiaddr = Protocol::Memory(random::()).into(); diff --git a/protocols/perf/src/bin/perf.rs b/protocols/perf/src/bin/perf.rs index df7e859222d..07229b38c24 100644 --- a/protocols/perf/src/bin/perf.rs +++ b/protocols/perf/src/bin/perf.rs @@ -31,7 +31,7 @@ use libp2p_core::{ }; use libp2p_identity::PeerId; use libp2p_perf::{Run, RunDuration, RunParams}; -use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; +use libp2p_swarm::{NetworkBehaviour, Swarm, Config, SwarmEvent}; use log::{error, info}; use serde::{Deserialize, Serialize}; @@ -418,7 +418,7 @@ async fn swarm() -> Result> { transport, Default::default(), local_peer_id, - SwarmConfig::with_tokio_executor() + Config::with_tokio_executor() .with_substream_upgrade_protocol_override(upgrade::Version::V1Lazy), ); diff --git a/protocols/relay/tests/lib.rs b/protocols/relay/tests/lib.rs index 926b23d1795..931ff7692a6 100644 --- a/protocols/relay/tests/lib.rs +++ b/protocols/relay/tests/lib.rs @@ -33,7 +33,7 @@ use libp2p_identity::PeerId; use libp2p_ping as ping; use libp2p_plaintext as plaintext; use libp2p_relay as relay; -use libp2p_swarm::{NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; +use libp2p_swarm::{NetworkBehaviour, Swarm, Config, SwarmEvent}; use std::time::Duration; #[test] @@ -323,7 +323,7 @@ fn build_relay() -> Swarm { ), }, local_peer_id, - SwarmConfig::with_async_std_executor(), + Config::with_async_std_executor(), ) } @@ -344,7 +344,7 @@ fn build_client() -> Swarm { relay: behaviour, }, local_peer_id, - SwarmConfig::with_async_std_executor(), + Config::with_async_std_executor(), ) } diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index 158a6b38152..cfe630045d1 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -27,9 +27,7 @@ use libp2p_core::{ use libp2p_identity::{Keypair, PeerId}; use libp2p_plaintext as plaintext; use libp2p_swarm::dial_opts::PeerCondition; -use libp2p_swarm::{ - dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent, THandlerErr, -}; +use libp2p_swarm::{self as swarm, dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmEvent, THandlerErr}; use libp2p_yamux as yamux; use std::fmt::Debug; use std::time::Duration; @@ -220,7 +218,7 @@ where transport, behaviour_fn(identity), peer_id, - SwarmConfig::without_executor().with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., + swarm::Config::without_executor().with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., ) } diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 0032f9fac3e..5e00e07b069 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -2,7 +2,7 @@ - Deprecate old `libp2p::swarm::SwarmBuilder`. Most users should use the new `libp2p::SwarmBuilder`. - In some special cases, users may need to use `Swarm::new_with_config` and `SwarmConfig` instead of the new `libp2p::SwarmBuilder`. + In some special cases, users may need to use `Swarm::new_with_config` and `Config` instead of the new `libp2p::SwarmBuilder`. See [PR 4120]. [PR 4120]: https://github.com/libp2p/rust-libp2p/pull/4120 diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 29d9d808a55..dccf4c15b3d 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -361,12 +361,12 @@ where TBehaviour: NetworkBehaviour, { /// Creates a new [`Swarm`] from the given [`Transport`], [`NetworkBehaviour`], [`PeerId`] and - /// [`SwarmConfig`]. + /// [`Config`]. pub fn new_with_config( transport: transport::Boxed<(PeerId, StreamMuxerBox)>, behaviour: TBehaviour, local_peer_id: PeerId, - config: SwarmConfig, + config: Config, ) -> Self { Swarm { local_peer_id, @@ -1367,12 +1367,12 @@ impl<'a> PollParameters for SwarmPollParameters<'a> { } } -pub struct SwarmConfig { +pub struct Config { pool_config: PoolConfig, } -impl SwarmConfig { - /// Creates a new [`SwarmConfig`] from the given executor. The [`Swarm`] is obtained via +impl Config { + /// Creates a new [`Config`] from the given executor. The [`Swarm`] is obtained via /// [`Swarm::new_with_config`]. pub fn with_executor(executor: impl Executor + Send + 'static) -> Self { Self { @@ -1394,7 +1394,7 @@ impl SwarmConfig { Self::with_executor(crate::executor::WasmBindgenExecutor) } - /// Builds a new [`SwarmConfig`] from the given `tokio` executor. + /// Builds a new [`Config`] from the given `tokio` executor. #[cfg(all( feature = "tokio", not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")) @@ -1403,7 +1403,7 @@ impl SwarmConfig { Self::with_executor(crate::executor::TokioExecutor) } - /// Builds a new [`SwarmConfig`] from the given `async-std` executor. + /// Builds a new [`Config`] from the given `async-std` executor. #[cfg(all( feature = "async-std", not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")) @@ -1412,14 +1412,14 @@ impl SwarmConfig { Self::with_executor(crate::executor::AsyncStdExecutor) } - // TODO: Should we remove this from `SwarmConfig`?! + // TODO: Should we remove this from `Config`?! // - /// Creates a new [`SwarmConfig`]. + /// Creates a new [`Config`]. /// /// ## ⚠️ Performance warning /// All connections will be polled on the current task, thus quite bad performance /// characteristics should be expected. Whenever possible use an executor and - /// [`SwarmConfig::with_executor`]. + /// [`Config::with_executor`]. pub fn without_executor() -> Self { Self { pool_config: PoolConfig::new(None), @@ -2002,7 +2002,7 @@ mod tests { } fn new_test_swarm( - config: SwarmConfig, + config: Config, ) -> Swarm>> { let id_keys = identity::Keypair::generate_ed25519(); let local_public_key = id_keys.public(); @@ -2069,8 +2069,8 @@ mod tests { /// with pairs of [`FromSwarm::ConnectionEstablished`] / [`FromSwarm::ConnectionClosed`] #[test] fn test_swarm_disconnect() { - let mut swarm1 = new_test_swarm(SwarmConfig::without_executor()); - let mut swarm2 = new_test_swarm(SwarmConfig::without_executor()); + let mut swarm1 = new_test_swarm(Config::without_executor()); + let mut swarm2 = new_test_swarm(Config::without_executor()); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2131,8 +2131,8 @@ mod tests { /// with pairs of [`FromSwarm::ConnectionEstablished`] / [`FromSwarm::ConnectionClosed`] #[test] fn test_behaviour_disconnect_all() { - let mut swarm1 = new_test_swarm(SwarmConfig::without_executor()); - let mut swarm2 = new_test_swarm(SwarmConfig::without_executor()); + let mut swarm1 = new_test_swarm(Config::without_executor()); + let mut swarm2 = new_test_swarm(Config::without_executor()); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2197,8 +2197,8 @@ mod tests { /// with pairs of [`FromSwarm::ConnectionEstablished`] / [`FromSwarm::ConnectionClosed`] #[test] fn test_behaviour_disconnect_one() { - let mut swarm1 = new_test_swarm(SwarmConfig::without_executor()); - let mut swarm2 = new_test_swarm(SwarmConfig::without_executor()); + let mut swarm1 = new_test_swarm(Config::without_executor()); + let mut swarm2 = new_test_swarm(Config::without_executor()); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2277,7 +2277,7 @@ mod tests { fn prop(concurrency_factor: DialConcurrencyFactor) { block_on(async { let mut swarm = new_test_swarm( - SwarmConfig::without_executor() + Config::without_executor() .with_dial_concurrency_factor(concurrency_factor.0), ); @@ -2345,8 +2345,8 @@ mod tests { // Checks whether dialing an address containing the wrong peer id raises an error // for the expected peer id instead of the obtained peer id. - let mut swarm1 = new_test_swarm(SwarmConfig::without_executor()); - let mut swarm2 = new_test_swarm(SwarmConfig::without_executor()); + let mut swarm1 = new_test_swarm(Config::without_executor()); + let mut swarm2 = new_test_swarm(Config::without_executor()); swarm1.listen_on("/memory/0".parse().unwrap()).unwrap(); @@ -2405,7 +2405,7 @@ mod tests { // // The last two can happen in any order. - let mut swarm = new_test_swarm(SwarmConfig::without_executor()); + let mut swarm = new_test_swarm(Config::without_executor()); swarm.listen_on("/memory/0".parse().unwrap()).unwrap(); let local_address = @@ -2465,7 +2465,7 @@ mod tests { fn dial_self_by_id() { // Trying to dial self by passing the same `PeerId` shouldn't even be possible in the first // place. - let swarm = new_test_swarm(SwarmConfig::without_executor()); + let swarm = new_test_swarm(Config::without_executor()); let peer_id = *swarm.local_peer_id(); assert!(!swarm.is_connected(&peer_id)); } @@ -2476,7 +2476,7 @@ mod tests { let target = PeerId::random(); - let mut swarm = new_test_swarm(SwarmConfig::without_executor()); + let mut swarm = new_test_swarm(Config::without_executor()); let addresses = HashSet::from([ multiaddr![Ip4([0, 0, 0, 0]), Tcp(rand::random::())], @@ -2522,8 +2522,8 @@ mod tests { fn aborting_pending_connection_surfaces_error() { let _ = env_logger::try_init(); - let mut dialer = new_test_swarm(SwarmConfig::without_executor()); - let mut listener = new_test_swarm(SwarmConfig::without_executor()); + let mut dialer = new_test_swarm(Config::without_executor()); + let mut listener = new_test_swarm(Config::without_executor()); let listener_peer_id = *listener.local_peer_id(); listener.listen_on(multiaddr![Memory(0u64)]).unwrap(); diff --git a/transports/pnet/tests/smoke.rs b/transports/pnet/tests/smoke.rs index eaefee70a16..4e8b9038fa5 100644 --- a/transports/pnet/tests/smoke.rs +++ b/transports/pnet/tests/smoke.rs @@ -6,7 +6,7 @@ use libp2p_core::upgrade::Version; use libp2p_core::Transport; use libp2p_core::{multiaddr::Protocol, Multiaddr}; use libp2p_pnet::{PnetConfig, PreSharedKey}; -use libp2p_swarm::{dummy, NetworkBehaviour, Swarm, SwarmConfig, SwarmEvent}; +use libp2p_swarm::{dummy, NetworkBehaviour, Swarm, Config, SwarmEvent}; const TIMEOUT: Duration = Duration::from_secs(5); @@ -117,7 +117,7 @@ where transport, dummy::Behaviour, identity.public().to_peer_id(), - SwarmConfig::with_tokio_executor(), + Config::with_tokio_executor(), ) } diff --git a/transports/tls/tests/smoke.rs b/transports/tls/tests/smoke.rs index 84156bb83ce..479e8ff5c3c 100644 --- a/transports/tls/tests/smoke.rs +++ b/transports/tls/tests/smoke.rs @@ -3,7 +3,7 @@ use libp2p_core::multiaddr::Protocol; use libp2p_core::transport::MemoryTransport; use libp2p_core::upgrade::Version; use libp2p_core::Transport; -use libp2p_swarm::{dummy, Swarm, SwarmConfig, SwarmEvent}; +use libp2p_swarm::{dummy, Swarm, Config, SwarmEvent}; use std::time::Duration; #[tokio::test] @@ -69,6 +69,6 @@ fn make_swarm() -> Swarm { transport, dummy::Behaviour, identity.public().to_peer_id(), - SwarmConfig::without_executor().idle_connection_timeout(Duration::from_secs(60)), + Config::without_executor().idle_connection_timeout(Duration::from_secs(60)), ) } From 4d7d3c6ccf7a3eb7d020db3acb78c7f075b77772 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 16:11:26 +0200 Subject: [PATCH 108/171] Fix wasm compilation --- interop-tests/src/arch.rs | 18 +----------------- interop-tests/src/lib.rs | 12 +++++++----- libp2p/src/builder.rs | 7 ------- libp2p/src/builder/phase/tcp.rs | 3 +++ 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index d8073ce925d..6ba364640ed 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -200,7 +200,7 @@ pub(crate) mod wasm { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_wasm_bindgen() .with_other_transport(|key| { - webrtc::Transport::new(webrtc::Config::new(&local_key)) + webrtc::Transport::new(webrtc::Config::new(&key)) .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) })? .with_behaviour(behaviour_constructor)? @@ -209,22 +209,6 @@ pub(crate) mod wasm { } _ => bail!("Only webtransport and webrtc-direct are supported with wasm"), } - - if let Transport::Webtransport = transport { - let swarm = libp2p::SwarmBuilder::with_new_identity() - .with_wasm_bindgen() - .with_other_transport(|key| { - libp2p::webtransport_websys::Transport::new( - libp2p::webtransport_websys::Config::new(key), - ) - .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) - })? - .with_behaviour(behaviour_constructor)? - .build(); - return Ok((swarm, format!("/ip4/{ip}/udp/0/quic/webtransport"))); - } else { - bail!("Only webtransport supported with wasm") - } } pub(crate) struct RedisClient(String); diff --git a/interop-tests/src/lib.rs b/interop-tests/src/lib.rs index 42af8ea1252..7661445fef0 100644 --- a/interop-tests/src/lib.rs +++ b/interop-tests/src/lib.rs @@ -32,13 +32,15 @@ pub async fn run_test( log::info!("Running ping test: {}", swarm.local_peer_id()); - let mut maybe_id = None; - // See https://github.com/libp2p/rust-libp2p/issues/4071. #[cfg(not(target_arch = "wasm32"))] - if transport == Transport::WebRtcDirect { - maybe_id = Some(swarm.listen_on(local_addr.parse()?)?); - } + let maybe_id = if transport == Transport::WebRtcDirect { + Some(swarm.listen_on(local_addr.parse()?)?) + } else { + None + }; + #[cfg(target_arch = "wasm32")] + let maybe_id = None; // Run a ping interop test. Based on `is_dialer`, either dial the address // retrieved via `listenAddr` key over the redis connection. Or wait to be pinged and have diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 3a32703ead4..f92582151cb 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,12 +1,5 @@ use std::marker::PhantomData; -#[cfg(all( - not(target_arch = "wasm32"), - feature = "tls", - feature = "noise", - any(feature = "tcp", feature = "relay", feature = "websocket") -))] -// mod map; mod select_security; mod phase; diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index ab7af1cdfad..0efc83a87e3 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -2,8 +2,11 @@ use super::*; #[cfg(feature = "websocket")] use libp2p_core::Transport; use crate::SwarmBuilder; +#[cfg(any(feature = "tcp", feature = "websocket"))] use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; +#[cfg(any(feature = "tcp", feature = "websocket"))] use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; +#[cfg(any(feature = "tcp", feature = "websocket"))] use libp2p_identity::PeerId; use std::marker::PhantomData; From 46c00a2f0f894110e238d63b60812d2b78cf2a54 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 16:25:05 +0200 Subject: [PATCH 109/171] More wasm compilation flags --- libp2p/src/builder/phase/provider.rs | 4 ++-- libp2p/src/builder/phase/quic.rs | 31 ++++++++++++++++----------- libp2p/src/builder/phase/tcp.rs | 30 +++++++++++++++++--------- libp2p/src/builder/phase/websocket.rs | 12 +++++------ 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/libp2p/src/builder/phase/provider.rs b/libp2p/src/builder/phase/provider.rs index a9bccaf1c21..c976cb4f418 100644 --- a/libp2p/src/builder/phase/provider.rs +++ b/libp2p/src/builder/phase/provider.rs @@ -35,10 +35,10 @@ impl SwarmBuilder { pub enum NoProviderSpecified {} -#[cfg(feature = "async-std")] +#[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] pub enum AsyncStd {} -#[cfg(feature = "tokio")] +#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] pub enum Tokio {} #[cfg(feature = "wasm-bindgen")] diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index 35ce11d5372..16b1ec91218 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -1,13 +1,14 @@ use super::*; -#[cfg(feature = "websocket")] -use libp2p_core::Transport; use crate::SwarmBuilder; -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] +use libp2p_core::Transport; +#[cfg(any( + feature = "relay", + all(not(target_arch = "wasm32"), feature = "websocket") +))] use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; -#[cfg(feature = "websocket")] -use libp2p_identity::PeerId; use std::marker::PhantomData; pub struct QuicPhase { @@ -93,13 +94,13 @@ impl SwarmBuilder, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + SecUpgrade::Upgrade: InboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static, >>::Future: Send, >>::Future: Send, <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, <>::Upgrade as UpgradeInfo>::Info: Send, - MuxStream: StreamMuxer + Send + 'static, + MuxStream: libp2p_core::muxing::StreamMuxer + Send + 'static, MuxStream::Substream: Send + 'static, MuxStream::Error: Send + Sync + 'static, MuxUpgrade: IntoMultiplexerUpgrade, @@ -143,8 +144,10 @@ impl SwarmBuilder SwarmBuilder> { pub async fn with_dns( self, - ) -> Result>, std::io::Error> - { + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { self.without_quic() .without_any_other_transports() .with_dns() @@ -155,8 +158,10 @@ impl SwarmBuilder SwarmBuilder> { pub fn with_dns( self, - ) -> Result>, std::io::Error> - { + ) -> Result< + SwarmBuilder>, + std::io::Error, + > { self.without_quic() .without_any_other_transports() .with_dns() @@ -188,7 +193,7 @@ macro_rules! impl_quic_phase_with_websocket { SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, SecError: std::error::Error + Send + Sync + 'static, SecUpgrade: IntoSecurityUpgrade<$websocketStream>, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + SecUpgrade::Upgrade: InboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static, >>::Future: Send, >>::Future: Send, <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index 0efc83a87e3..19cf1d2bacc 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -1,13 +1,17 @@ use super::*; -#[cfg(feature = "websocket")] -use libp2p_core::Transport; use crate::SwarmBuilder; -#[cfg(any(feature = "tcp", feature = "websocket"))] +#[cfg(all( + not(target_arch = "wasm32"), + any(feature = "tcp", feature = "websocket") +))] use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; -#[cfg(any(feature = "tcp", feature = "websocket"))] +#[cfg(all(feature = "websocket", not(target_arch = "wasm32")))] +use libp2p_core::Transport; +#[cfg(all( + not(target_arch = "wasm32"), + any(feature = "tcp", feature = "websocket") +))] use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; -#[cfg(any(feature = "tcp", feature = "websocket"))] -use libp2p_identity::PeerId; use std::marker::PhantomData; pub struct TcpPhase {} @@ -33,7 +37,7 @@ macro_rules! impl_tcp_builder { SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, SecError: std::error::Error + Send + Sync + 'static, SecUpgrade: IntoSecurityUpgrade, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + SecUpgrade::Upgrade: InboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static, >>::Future: Send, >>::Future: Send, <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, @@ -94,7 +98,10 @@ impl SwarmBuilder { impl SwarmBuilder { pub fn with_quic( self, - ) -> SwarmBuilder> { + ) -> SwarmBuilder< + super::provider::AsyncStd, + OtherTransportPhase, + > { self.without_tcp().with_quic() } } @@ -102,7 +109,10 @@ impl SwarmBuilder { impl SwarmBuilder { pub fn with_quic( self, - ) -> SwarmBuilder> { + ) -> SwarmBuilder< + super::provider::Tokio, + OtherTransportPhase, + > { self.without_tcp().with_quic() } } @@ -148,7 +158,7 @@ macro_rules! impl_tcp_phase_with_websocket { SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, SecError: std::error::Error + Send + Sync + 'static, SecUpgrade: IntoSecurityUpgrade<$websocketStream>, - SecUpgrade::Upgrade: InboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + SecUpgrade::Upgrade: InboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static, >>::Future: Send, >>::Future: Send, <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, diff --git a/libp2p/src/builder/phase/websocket.rs b/libp2p/src/builder/phase/websocket.rs index 2a05ba6f79d..24ab464eaca 100644 --- a/libp2p/src/builder/phase/websocket.rs +++ b/libp2p/src/builder/phase/websocket.rs @@ -1,12 +1,12 @@ use super::*; use crate::SwarmBuilder; -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] use libp2p_core::Transport; -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] use libp2p_identity::PeerId; use std::marker::PhantomData; @@ -152,11 +152,11 @@ impl #[derive(Debug, thiserror::Error)] #[error(transparent)] -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] pub struct WebsocketError(WebsocketErrorInner); #[derive(Debug, thiserror::Error)] -#[cfg(feature = "websocket")] +#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] enum WebsocketErrorInner { #[error("SecurityUpgrade")] SecurityUpgrade(Sec), From ec4257772c9507493c327abf1d2d5bb5a4069b4a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 16:43:58 +0200 Subject: [PATCH 110/171] Fix ipfs-kad example --- examples/ipfs-kad/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ipfs-kad/Cargo.toml b/examples/ipfs-kad/Cargo.toml index 0526060eaa6..4f1e654eba1 100644 --- a/examples/ipfs-kad/Cargo.toml +++ b/examples/ipfs-kad/Cargo.toml @@ -10,4 +10,4 @@ async-std = { version = "1.12", features = ["attributes"] } async-trait = "0.1" env_logger = "0.10" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "noise", "tcp", "websocket", "yamux", "rsa"] } +libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "noise", "tcp", "yamux", "rsa"] } From 9f6950e30d268f84bec48b8c55fb5416cbbb2a5a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 16:49:46 +0200 Subject: [PATCH 111/171] Remove reference to keep alive behaviour --- examples/metrics/src/main.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index 1e5324d3332..78f3334fb47 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -24,12 +24,13 @@ use env_logger::Env; use futures::{executor::block_on, StreamExt}; use libp2p::core::Multiaddr; use libp2p::metrics::{Metrics, Recorder}; -use libp2p::swarm::{NetworkBehaviour, SwarmEvent}; +use libp2p::swarm::{self as swarm, NetworkBehaviour, SwarmEvent}; use libp2p::{identify, identity, noise, ping, tcp, yamux}; use log::info; use prometheus_client::registry::Registry; use std::error::Error; use std::thread; +use std::time::Duration; mod http_service; @@ -44,6 +45,10 @@ fn main() -> Result<(), Box> { yamux::Config::default, )? .with_behaviour(|key| Behaviour::new(key.public()))? + .with_swarm_config( + swarm::Config::with_async_std_executor() + .with_idle_connection_timeout(Duration::from_secs(u64::MAX)), + ) .build(); info!("Local peer id: {:?}", swarm.local_peer_id()); @@ -82,9 +87,6 @@ fn main() -> Result<(), Box> { } /// Our network behaviour. -/// -/// For illustrative purposes, this includes the [`keep_alive::Behaviour`]) behaviour so the ping actually happen -/// and can be observed via the metrics. #[derive(NetworkBehaviour)] struct Behaviour { identify: identify::Behaviour, From 3bcbca3aa4541323331e61f46ca5acb0c8dd2b74 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 16:52:15 +0200 Subject: [PATCH 112/171] Fix example warning --- libp2p/src/builder/phase/quic.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index 16b1ec91218..d6b593f3796 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -1,9 +1,7 @@ use super::*; use crate::SwarmBuilder; #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -use libp2p_core::muxing::{StreamMuxer, StreamMuxerBox}; -#[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -use libp2p_core::Transport; +use libp2p_core::muxing::{StreamMuxer}; #[cfg(any( feature = "relay", all(not(target_arch = "wasm32"), feature = "websocket") @@ -23,10 +21,11 @@ macro_rules! construct_other_transport_builder { transport: $self .phase .transport - .or_transport( - libp2p_quic::$quic::Transport::new($config) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))), - ) + .or_transport(libp2p_quic::$quic::Transport::new($config).map( + |(peer_id, muxer), _| { + (peer_id, libp2p_core::muxing::StreamMuxerBox::new(muxer)) + }, + )) .map(|either, _| either.into_inner()), }, keypair: $self.keypair, From 288d96484abff7ad579b84d92381358702acf962 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 16:52:46 +0200 Subject: [PATCH 113/171] cargo fmt --- examples/file-sharing/src/network.rs | 5 ++++- libp2p/src/builder.rs | 4 ++-- libp2p/src/builder/phase.rs | 30 +++++++++++++-------------- libp2p/src/builder/phase/behaviour.rs | 4 ++-- libp2p/src/builder/phase/build.rs | 4 ++-- libp2p/src/builder/phase/identity.rs | 5 ++--- libp2p/src/builder/phase/quic.rs | 2 +- protocols/dcutr/tests/lib.rs | 2 +- protocols/kad/src/behaviour/test.rs | 10 +++------ protocols/perf/src/bin/perf.rs | 2 +- protocols/relay/tests/lib.rs | 2 +- swarm-test/src/lib.rs | 4 +++- swarm/src/lib.rs | 3 +-- transports/pnet/tests/smoke.rs | 2 +- transports/tls/tests/smoke.rs | 2 +- 15 files changed, 40 insertions(+), 41 deletions(-) diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index ec817eb6200..9a33dd9aed8 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -48,7 +48,10 @@ pub(crate) async fn new( yamux::Config::default, )? .with_behaviour(|key| ComposedBehaviour { - kademlia: kad::Behaviour::new(peer_id, kad::store::MemoryStore::new(key.public().to_peer_id())), + kademlia: kad::Behaviour::new( + peer_id, + kad::store::MemoryStore::new(key.public().to_peer_id()), + ), request_response: request_response::cbor::Behaviour::new( [( StreamProtocol::new("/file-exchange/1"), diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index f92582151cb..44866b9775d 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; -mod select_security; mod phase; +mod select_security; /// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. /// @@ -55,8 +55,8 @@ pub struct SwarmBuilder { #[cfg(test)] mod tests { - use libp2p_swarm::{NetworkBehaviour, Swarm}; use crate::SwarmBuilder; + use libp2p_swarm::{NetworkBehaviour, Swarm}; #[test] #[cfg(all(feature = "tokio", feature = "tcp", feature = "tls", feature = "noise"))] diff --git a/libp2p/src/builder/phase.rs b/libp2p/src/builder/phase.rs index deeca3354f5..85d6ab86b5a 100644 --- a/libp2p/src/builder/phase.rs +++ b/libp2p/src/builder/phase.rs @@ -1,32 +1,32 @@ -use libp2p_core::{upgrade::SelectUpgrade, Transport, muxing::StreamMuxerBox}; +use libp2p_core::{muxing::StreamMuxerBox, upgrade::SelectUpgrade, Transport}; use libp2p_identity::Keypair; use super::select_security::SelectSecurityUpgrade; +mod bandwidth_logging; +mod behaviour; +mod build; +mod dns; mod identity; +mod other_transport; mod provider; -mod tcp; mod quic; -mod other_transport; -mod dns; mod relay; -mod websocket; -mod bandwidth_logging; -mod behaviour; mod swarm; -mod build; +mod tcp; +mod websocket; +use bandwidth_logging::*; +use behaviour::*; +use build::*; +use dns::*; +use other_transport::*; use provider::*; -use tcp::*; use quic::*; -use other_transport::*; -use dns::*; use relay::*; -use websocket::*; -use bandwidth_logging::*; -use behaviour::*; use swarm::*; -use build::*; +use tcp::*; +use websocket::*; pub trait IntoSecurityUpgrade { type Upgrade; diff --git a/libp2p/src/builder/phase/behaviour.rs b/libp2p/src/builder/phase/behaviour.rs index 39b730b896d..50d7b60e770 100644 --- a/libp2p/src/builder/phase/behaviour.rs +++ b/libp2p/src/builder/phase/behaviour.rs @@ -1,8 +1,8 @@ +use super::*; use crate::SwarmBuilder; -use std::marker::PhantomData; use libp2p_swarm::NetworkBehaviour; use std::convert::Infallible; -use super::*; +use std::marker::PhantomData; pub struct BehaviourPhase { pub(crate) relay_behaviour: R, diff --git a/libp2p/src/builder/phase/build.rs b/libp2p/src/builder/phase/build.rs index 669b9fc82c5..cf24045cb6b 100644 --- a/libp2p/src/builder/phase/build.rs +++ b/libp2p/src/builder/phase/build.rs @@ -1,7 +1,7 @@ +use super::*; use crate::SwarmBuilder; -use libp2p_swarm::Swarm; use libp2p_core::Transport; -use super::*; +use libp2p_swarm::Swarm; pub struct BuildPhase { pub(crate) behaviour: B, diff --git a/libp2p/src/builder/phase/identity.rs b/libp2p/src/builder/phase/identity.rs index 483b086c235..764b2cefb5b 100644 --- a/libp2p/src/builder/phase/identity.rs +++ b/libp2p/src/builder/phase/identity.rs @@ -1,7 +1,6 @@ -use std::marker::PhantomData; -use crate::SwarmBuilder; use super::*; - +use crate::SwarmBuilder; +use std::marker::PhantomData; // TODO: Rename to IdentityPhase pub struct InitialPhase {} diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index d6b593f3796..598d8760d57 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -1,7 +1,7 @@ use super::*; use crate::SwarmBuilder; #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -use libp2p_core::muxing::{StreamMuxer}; +use libp2p_core::muxing::StreamMuxer; #[cfg(any( feature = "relay", all(not(target_arch = "wasm32"), feature = "websocket") diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index 0c6d444ed60..213b80e930b 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -26,7 +26,7 @@ use libp2p_identity as identity; use libp2p_identity::PeerId; use libp2p_plaintext as plaintext; use libp2p_relay as relay; -use libp2p_swarm::{NetworkBehaviour, Swarm, Config, SwarmEvent}; +use libp2p_swarm::{Config, NetworkBehaviour, Swarm, SwarmEvent}; use libp2p_swarm_test::SwarmExt as _; use std::time::Duration; diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index 799720ca194..ab66acc7e67 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -37,7 +37,7 @@ use libp2p_core::{ use libp2p_identity as identity; use libp2p_identity::PeerId; use libp2p_noise as noise; -use libp2p_swarm::{ConnectionId, Swarm, Config, SwarmEvent}; +use libp2p_swarm::{Config, ConnectionId, Swarm, SwarmEvent}; use libp2p_yamux as yamux; use quickcheck::*; use rand::{random, rngs::StdRng, thread_rng, Rng, SeedableRng}; @@ -67,12 +67,8 @@ fn build_node_with_config(cfg: Config) -> (Multiaddr, TestSwarm) { let store = MemoryStore::new(local_id); let behaviour = Behaviour::with_config(local_id, store, cfg); - let mut swarm = Swarm::new_with_config( - transport, - behaviour, - local_id, - Config::without_executor(), - ); + let mut swarm = + Swarm::new_with_config(transport, behaviour, local_id, Config::without_executor()); let address: Multiaddr = Protocol::Memory(random::()).into(); swarm.listen_on(address.clone()).unwrap(); diff --git a/protocols/perf/src/bin/perf.rs b/protocols/perf/src/bin/perf.rs index 07229b38c24..9172d6c76a5 100644 --- a/protocols/perf/src/bin/perf.rs +++ b/protocols/perf/src/bin/perf.rs @@ -31,7 +31,7 @@ use libp2p_core::{ }; use libp2p_identity::PeerId; use libp2p_perf::{Run, RunDuration, RunParams}; -use libp2p_swarm::{NetworkBehaviour, Swarm, Config, SwarmEvent}; +use libp2p_swarm::{Config, NetworkBehaviour, Swarm, SwarmEvent}; use log::{error, info}; use serde::{Deserialize, Serialize}; diff --git a/protocols/relay/tests/lib.rs b/protocols/relay/tests/lib.rs index 931ff7692a6..de90417a2dd 100644 --- a/protocols/relay/tests/lib.rs +++ b/protocols/relay/tests/lib.rs @@ -33,7 +33,7 @@ use libp2p_identity::PeerId; use libp2p_ping as ping; use libp2p_plaintext as plaintext; use libp2p_relay as relay; -use libp2p_swarm::{NetworkBehaviour, Swarm, Config, SwarmEvent}; +use libp2p_swarm::{Config, NetworkBehaviour, Swarm, SwarmEvent}; use std::time::Duration; #[test] diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index cfe630045d1..7c4f71c588f 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -27,7 +27,9 @@ use libp2p_core::{ use libp2p_identity::{Keypair, PeerId}; use libp2p_plaintext as plaintext; use libp2p_swarm::dial_opts::PeerCondition; -use libp2p_swarm::{self as swarm, dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmEvent, THandlerErr}; +use libp2p_swarm::{ + self as swarm, dial_opts::DialOpts, NetworkBehaviour, Swarm, SwarmEvent, THandlerErr, +}; use libp2p_yamux as yamux; use std::fmt::Debug; use std::time::Duration; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index dccf4c15b3d..ef8bdce3a37 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -2277,8 +2277,7 @@ mod tests { fn prop(concurrency_factor: DialConcurrencyFactor) { block_on(async { let mut swarm = new_test_swarm( - Config::without_executor() - .with_dial_concurrency_factor(concurrency_factor.0), + Config::without_executor().with_dial_concurrency_factor(concurrency_factor.0), ); // Listen on `concurrency_factor + 1` addresses. diff --git a/transports/pnet/tests/smoke.rs b/transports/pnet/tests/smoke.rs index 4e8b9038fa5..af9251440dd 100644 --- a/transports/pnet/tests/smoke.rs +++ b/transports/pnet/tests/smoke.rs @@ -6,7 +6,7 @@ use libp2p_core::upgrade::Version; use libp2p_core::Transport; use libp2p_core::{multiaddr::Protocol, Multiaddr}; use libp2p_pnet::{PnetConfig, PreSharedKey}; -use libp2p_swarm::{dummy, NetworkBehaviour, Swarm, Config, SwarmEvent}; +use libp2p_swarm::{dummy, Config, NetworkBehaviour, Swarm, SwarmEvent}; const TIMEOUT: Duration = Duration::from_secs(5); diff --git a/transports/tls/tests/smoke.rs b/transports/tls/tests/smoke.rs index 479e8ff5c3c..19e2c0a4e5d 100644 --- a/transports/tls/tests/smoke.rs +++ b/transports/tls/tests/smoke.rs @@ -3,7 +3,7 @@ use libp2p_core::multiaddr::Protocol; use libp2p_core::transport::MemoryTransport; use libp2p_core::upgrade::Version; use libp2p_core::Transport; -use libp2p_swarm::{dummy, Swarm, Config, SwarmEvent}; +use libp2p_swarm::{dummy, Config, Swarm, SwarmEvent}; use std::time::Duration; #[tokio::test] From d8869e5ed6eedda5ba880ef7c178d6d3b0f5efac Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 17:00:23 +0200 Subject: [PATCH 114/171] Fix doc tests --- libp2p/src/builder.rs | 22 ++++++++++-------- libp2p/src/tutorials/ping.rs | 43 ++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 44866b9775d..2551173d3f0 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -29,17 +29,21 @@ mod select_security; /// /// let swarm = SwarmBuilder::with_new_identity() /// .with_tokio() -/// .with_tcp() -/// .with_tls()? -/// .with_noise()? +/// .with_tcp( +/// Default::default(), +/// (libp2p_tls::Config::new, libp2p_noise::Config::new), +/// libp2p_yamux::Config::default, +/// )? /// .with_quic() /// .with_dns()? -/// .with_relay() -/// .with_tls()? -/// .with_noise()? -/// .with_websocket() -/// .with_tls()? -/// .with_noise() +/// .with_relay( +/// (libp2p_tls::Config::new, libp2p_noise::Config::new), +/// libp2p_yamux::Config::default, +/// )? +/// .with_websocket( +/// (libp2p_tls::Config::new, libp2p_noise::Config::new), +/// libp2p_yamux::Config::default, +/// ) /// .await? /// .with_behaviour(|_key, relay| MyBehaviour { relay })? /// .build(); diff --git a/libp2p/src/tutorials/ping.rs b/libp2p/src/tutorials/ping.rs index 6e6aa4fb121..0e46d40a4bd 100644 --- a/libp2p/src/tutorials/ping.rs +++ b/libp2p/src/tutorials/ping.rs @@ -99,8 +99,11 @@ //! async fn main() -> Result<(), Box> { //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() -//! .with_tcp() -//! .with_tls()?; +//! .with_tcp( +//! Default::default(), +//! libp2p_tls::Config::new, +//! libp2p_yamux::Config::default, +//! )?; //! //! Ok(()) //! } @@ -137,9 +140,12 @@ //! async fn main() -> Result<(), Box> { //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() -//! .with_tcp() -//! .with_tls()? -//! .with_behaviour(|_| Behaviour::default())?; +//! .with_tcp( +//! Default::default(), +//! libp2p_tls::Config::new, +//! libp2p_yamux::Config::default, +//! )? +//! .with_behaviour(|_| ping::Behaviour::default())?; //! //! Ok(()) //! } @@ -165,9 +171,12 @@ //! async fn main() -> Result<(), Box> { //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() -//! .with_tcp() -//! .with_tls()? -//! .with_behaviour(|_| Behaviour::default())? +//! .with_tcp( +//! Default::default(), +//! libp2p_tls::Config::new, +//! libp2p_yamux::Config::default, +//! )? +//! .with_behaviour(|_| ping::Behaviour::default())? //! .build(); //! //! Ok(()) @@ -245,9 +254,12 @@ //! async fn main() -> Result<(), Box> { //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() -//! .with_tcp() -//! .with_tls()? -//! .with_behaviour(|_| Behaviour::default())? +//! .with_tcp( +//! Default::default(), +//! libp2p_tls::Config::new, +//! libp2p_yamux::Config::default, +//! )? +//! .with_behaviour(|_| ping::Behaviour::default())? //! .build(); //! //! // Tell the swarm to listen on all interfaces and a random, OS-assigned @@ -283,9 +295,12 @@ //! async fn main() -> Result<(), Box> { //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() -//! .with_tcp() -//! .with_tls()? -//! .with_behaviour(|_| Behaviour::default())? +//! .with_tcp( +//! Default::default(), +//! libp2p_tls::Config::new, +//! libp2p_yamux::Config::default, +//! )? +//! .with_behaviour(|_| ping::Behaviour::default())? //! .build(); //! //! // Tell the swarm to listen on all interfaces and a random, OS-assigned From 09e7bae01f35790a2274b2a4405f43b547709147 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 17:01:06 +0200 Subject: [PATCH 115/171] fix swarm test --- swarm/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index ef8bdce3a37..a170ab05ad2 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -2017,7 +2017,7 @@ mod tests { transport, behaviour, local_public_key.into(), - config.idle_connection_timeout(Duration::from_secs(5)), + config.with_idle_connection_timeout(Duration::from_secs(5)), ) } From f1ef2ec0ce98b486474dc294f2f32be0c748a97b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 17:03:39 +0200 Subject: [PATCH 116/171] Fix kad tests --- protocols/kad/src/behaviour/test.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index ab66acc7e67..f4b25e7bd07 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -37,7 +37,7 @@ use libp2p_core::{ use libp2p_identity as identity; use libp2p_identity::PeerId; use libp2p_noise as noise; -use libp2p_swarm::{Config, ConnectionId, Swarm, SwarmEvent}; +use libp2p_swarm::{self as swarm, ConnectionId, Swarm, SwarmEvent}; use libp2p_yamux as yamux; use quickcheck::*; use rand::{random, rngs::StdRng, thread_rng, Rng, SeedableRng}; @@ -68,7 +68,7 @@ fn build_node_with_config(cfg: Config) -> (Multiaddr, TestSwarm) { let behaviour = Behaviour::with_config(local_id, store, cfg); let mut swarm = - Swarm::new_with_config(transport, behaviour, local_id, Config::without_executor()); + Swarm::new_with_config(transport, behaviour, local_id, swarm::Config::without_executor()); let address: Multiaddr = Protocol::Memory(random::()).into(); swarm.listen_on(address.clone()).unwrap(); From 1a2c5407504137117204709149843e8d57c9c4be Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sat, 30 Sep 2023 17:05:24 +0200 Subject: [PATCH 117/171] Fix swarm config method names --- swarm/src/lib.rs | 2 +- transports/tls/tests/smoke.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index a170ab05ad2..d4885705e3a 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1451,7 +1451,7 @@ impl Config { /// usage, and more importantly the latency between the moment when an /// event is emitted and the moment when it is received by the /// [`NetworkBehaviour`]. - pub fn per_connection_event_buffer_size(mut self, n: usize) -> Self { + pub fn with_per_connection_event_buffer_size(mut self, n: usize) -> Self { self.pool_config = self.pool_config.with_per_connection_event_buffer_size(n); self } diff --git a/transports/tls/tests/smoke.rs b/transports/tls/tests/smoke.rs index 19e2c0a4e5d..8863bb17645 100644 --- a/transports/tls/tests/smoke.rs +++ b/transports/tls/tests/smoke.rs @@ -69,6 +69,6 @@ fn make_swarm() -> Swarm { transport, dummy::Behaviour, identity.public().to_peer_id(), - Config::without_executor().idle_connection_timeout(Duration::from_secs(60)), + Config::without_executor().with_idle_connection_timeout(Duration::from_secs(60)), ) } From c6409290c405dbe499f320258d9e2df041b592c4 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:16:44 +0200 Subject: [PATCH 118/171] Rename to with_relay_client --- examples/dcutr/src/main.rs | 2 +- libp2p/src/builder.rs | 6 +++--- libp2p/src/builder/phase/other_transport.rs | 4 ++-- libp2p/src/builder/phase/quic.rs | 4 ++-- libp2p/src/builder/phase/relay.rs | 3 +-- libp2p/src/builder/phase/tcp.rs | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 7bc3e83e26c..2267efb77d8 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -128,7 +128,7 @@ async fn main() -> Result<(), Box> { .with_quic() .with_dns() .await? - .with_relay(noise::Config::new, yamux::Config::default)? + .with_relay_client(noise::Config::new, yamux::Config::default)? .with_behaviour(|keypair, relay_behaviour| Behaviour { relay_client: relay_behaviour, ping: ping::Behaviour::new(ping::Config::new()), diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 2551173d3f0..d4e05dc5f67 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -36,7 +36,7 @@ mod select_security; /// )? /// .with_quic() /// .with_dns()? -/// .with_relay( +/// .with_relay_client( /// (libp2p_tls::Config::new, libp2p_noise::Config::new), /// libp2p_yamux::Config::default, /// )? @@ -184,7 +184,7 @@ mod tests { libp2p_yamux::Config::default, ) .unwrap() - .with_relay(libp2p_tls::Config::new, libp2p_yamux::Config::default) + .with_relay_client(libp2p_tls::Config::new, libp2p_yamux::Config::default) .unwrap() .with_behaviour(|_, relay| Behaviour { dummy: libp2p_swarm::dummy::Behaviour, @@ -299,7 +299,7 @@ mod tests { .with_quic() .with_dns() .unwrap() - .with_relay(libp2p_tls::Config::new, libp2p_yamux::Config::default) + .with_relay_client(libp2p_tls::Config::new, libp2p_yamux::Config::default) .unwrap() .with_websocket(libp2p_tls::Config::new, libp2p_yamux::Config::default) .await diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index 27408502128..e997b33b67f 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -85,7 +85,7 @@ impl impl SwarmBuilder> { - pub fn with_relay( + pub fn with_relay_client( self, security_upgrade: SecUpgrade, multiplexer_upgrade: MuxUpgrade, @@ -119,7 +119,7 @@ impl { self.without_any_other_transports() .without_dns() - .with_relay(security_upgrade, multiplexer_upgrade) + .with_relay_client(security_upgrade, multiplexer_upgrade) } } impl diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index 598d8760d57..70956eabfaa 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -78,7 +78,7 @@ impl SwarmBuilder> { // Shortcuts impl SwarmBuilder> { #[cfg(feature = "relay")] - pub fn with_relay( + pub fn with_relay_client( self, security_upgrade: SecUpgrade, multiplexer_upgrade: MuxUpgrade, @@ -111,7 +111,7 @@ impl SwarmBuilder>::Upgrade as UpgradeInfo>::Info: Send, { self.without_quic() - .with_relay(security_upgrade, multiplexer_upgrade) + .with_relay_client(security_upgrade, multiplexer_upgrade) } pub fn with_other_transport< diff --git a/libp2p/src/builder/phase/relay.rs b/libp2p/src/builder/phase/relay.rs index ffc105c0b14..bf4b1af5564 100644 --- a/libp2p/src/builder/phase/relay.rs +++ b/libp2p/src/builder/phase/relay.rs @@ -19,8 +19,7 @@ pub struct RelayPhase { #[cfg(feature = "relay")] impl SwarmBuilder> { - // TODO: This should be with_relay_client. - pub fn with_relay( + pub fn with_relay_client( self, security_upgrade: SecUpgrade, multiplexer_upgrade: MuxUpgrade, diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index 19cf1d2bacc..0741c5fdce1 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -82,7 +82,7 @@ impl SwarmBuilder { ) -> SwarmBuilder> { SwarmBuilder { // TODO: Is this a good idea in a production environment? Unfortunately I don't know a - // way around it. One can not define two `with_relay` methods, one with a real transport + // way around it. One can not define two `with_relay_client` methods, one with a real transport // using OrTransport, one with a fake transport discarding it right away. keypair: self.keypair, phantom: PhantomData, From 3845c23f64f3da9e3e71ba9c8cc81489cbe1e9e9 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:19:28 +0200 Subject: [PATCH 119/171] Implement with_websocket for RelayPhase --- libp2p/src/builder/phase/relay.rs | 73 ++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 11 deletions(-) diff --git a/libp2p/src/builder/phase/relay.rs b/libp2p/src/builder/phase/relay.rs index bf4b1af5564..b60ba2ba593 100644 --- a/libp2p/src/builder/phase/relay.rs +++ b/libp2p/src/builder/phase/relay.rs @@ -94,17 +94,6 @@ impl SwarmBuilder> { // Shortcuts impl SwarmBuilder> { - // TODO - // #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] - // pub fn with_websocket( - // self, - // ) -> SwarmBuilder< - // Provider, - // WebsocketTlsPhase, - // > { - // self.without_relay().with_websocket() - // } - pub fn with_behaviour>( self, constructor: impl FnOnce(&libp2p_identity::Keypair) -> R, @@ -114,3 +103,65 @@ impl SwarmBuilder { + #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] + impl SwarmBuilder<$providerCamelCase, RelayPhase> { + pub async fn with_websocket < + SecUpgrade, + SecStream, + SecError, + MuxUpgrade, + MuxStream, + MuxError, + > ( + self, + security_upgrade: SecUpgrade, + multiplexer_upgrade: MuxUpgrade, + ) -> Result< + SwarmBuilder< + $providerCamelCase, + BandwidthLoggingPhase, + >, + super::websocket::WebsocketError, + > + where + SecStream: futures::AsyncRead + futures::AsyncWrite + Unpin + Send + 'static, + SecError: std::error::Error + Send + Sync + 'static, + SecUpgrade: IntoSecurityUpgrade<$websocketStream>, + SecUpgrade::Upgrade: InboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + OutboundUpgrade, Output = (libp2p_identity::PeerId, SecStream), Error = SecError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + + MuxStream: StreamMuxer + Send + 'static, + MuxStream::Substream: Send + 'static, + MuxStream::Error: Send + Sync + 'static, + MuxUpgrade: IntoMultiplexerUpgrade, + MuxUpgrade::Upgrade: InboundUpgrade, Output = MuxStream, Error = MuxError> + OutboundUpgrade, Output = MuxStream, Error = MuxError> + Clone + Send + 'static, + >>::Future: Send, + >>::Future: Send, + MuxError: std::error::Error + Send + Sync + 'static, + <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, + <>::Upgrade as UpgradeInfo>::Info: Send, + { + self.without_relay() + .with_websocket(security_upgrade, multiplexer_upgrade) + .await + } + } + } +} +impl_relay_phase_with_websocket!( + "async-std", + super::provider::AsyncStd, + rw_stream_sink::RwStreamSink< + libp2p_websocket::BytesConnection, + > +); +impl_relay_phase_with_websocket!( + "tokio", + super::provider::Tokio, + rw_stream_sink::RwStreamSink> +); From 4a8d38b24b0fa448976b2c4292f8cb1109928f33 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:20:43 +0200 Subject: [PATCH 120/171] Rename to IdentityPhase --- libp2p/src/builder/phase/identity.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libp2p/src/builder/phase/identity.rs b/libp2p/src/builder/phase/identity.rs index 764b2cefb5b..ceb86819dc7 100644 --- a/libp2p/src/builder/phase/identity.rs +++ b/libp2p/src/builder/phase/identity.rs @@ -2,10 +2,9 @@ use super::*; use crate::SwarmBuilder; use std::marker::PhantomData; -// TODO: Rename to IdentityPhase -pub struct InitialPhase {} +pub struct IdentityPhase {} -impl SwarmBuilder { +impl SwarmBuilder { pub fn with_new_identity() -> SwarmBuilder { SwarmBuilder::with_existing_identity(libp2p_identity::Keypair::generate_ed25519()) } From b135900b74842ccd2e93d308dded778d41a4cc81 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:29:52 +0200 Subject: [PATCH 121/171] Introduce BehaviourError --- libp2p/src/builder/phase/other_transport.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index e997b33b67f..8b7cdd093b3 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -179,10 +179,14 @@ impl TryIntoTransport for Result enough? - type Error = std::io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? + type Error = BehaviourError; fn try_into_transport(self) -> Result { - self.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)) + self.map_err(BehaviourError) } } + + +#[derive(Debug, thiserror::Error)] +#[error("failed to build behaviour: {0}")] +pub struct BehaviourError(Box); From b4e160b0523c843f99627b16c464cfa0f968c9ff Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:34:09 +0200 Subject: [PATCH 122/171] Introduce TransportError --- libp2p/src/builder/phase/behaviour.rs | 9 ++++++--- libp2p/src/builder/phase/other_transport.rs | 8 ++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/libp2p/src/builder/phase/behaviour.rs b/libp2p/src/builder/phase/behaviour.rs index 50d7b60e770..3ce8aa5e8c9 100644 --- a/libp2p/src/builder/phase/behaviour.rs +++ b/libp2p/src/builder/phase/behaviour.rs @@ -68,10 +68,13 @@ impl TryIntoBehaviour for Result enough? - type Error = std::io::Error; // TODO: Consider a dedicated type here with a descriptive message like "failed to build behaviour"? + type Error = BehaviourError; fn try_into_behaviour(self) -> Result { - self.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)) + self.map_err(BehaviourError) } } + +#[derive(Debug, thiserror::Error)] +#[error("failed to build behaviour: {0}")] +pub struct BehaviourError(Box); diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index 8b7cdd093b3..4f337af9c3d 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -179,14 +179,14 @@ impl TryIntoTransport for Result Result { - self.map_err(BehaviourError) + self.map_err(TransportError) } } #[derive(Debug, thiserror::Error)] -#[error("failed to build behaviour: {0}")] -pub struct BehaviourError(Box); +#[error("failed to build transport: {0}")] +pub struct TransportError(Box); From cb59522a8e777588a003a703877fceec7a016a79 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:37:34 +0200 Subject: [PATCH 123/171] Refactor nested quic macro --- libp2p/src/builder/phase/quic.rs | 37 +++++++++++++------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index 70956eabfaa..f1dd20d7a78 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -13,27 +13,6 @@ pub struct QuicPhase { pub(crate) transport: T, } -#[cfg(all(not(target_arch = "wasm32"), feature = "quic"))] -macro_rules! construct_other_transport_builder { - ($self:ident, $quic:ident, $config:expr) => { - SwarmBuilder { - phase: OtherTransportPhase { - transport: $self - .phase - .transport - .or_transport(libp2p_quic::$quic::Transport::new($config).map( - |(peer_id, muxer), _| { - (peer_id, libp2p_core::muxing::StreamMuxerBox::new(muxer)) - }, - )) - .map(|either, _| either.into_inner()), - }, - keypair: $self.keypair, - phantom: PhantomData, - } - }; -} - macro_rules! impl_quic_builder { ($providerKebabCase:literal, $providerCamelCase:ty, $quic:ident) => { #[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = $providerKebabCase))] @@ -54,7 +33,21 @@ macro_rules! impl_quic_builder { $providerCamelCase, OtherTransportPhase, > { - construct_other_transport_builder!(self, $quic, constructor(&self.keypair)) + SwarmBuilder { + phase: OtherTransportPhase { + transport: self + .phase + .transport + .or_transport(libp2p_quic::$quic::Transport::new(constructor(&self.keypair)).map( + |(peer_id, muxer), _| { + (peer_id, libp2p_core::muxing::StreamMuxerBox::new(muxer)) + }, + )) + .map(|either, _| either.into_inner()), + }, + keypair: self.keypair, + phantom: PhantomData, + } } } }; From cc84f7cb75acda77bbd6e612eb44989091fb550f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:40:00 +0200 Subject: [PATCH 124/171] Reword note on dummy transport usage --- libp2p/src/builder/phase/tcp.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index 0741c5fdce1..ca783b8be73 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -76,17 +76,17 @@ impl_tcp_builder!("async-std", super::provider::AsyncStd, async_io); impl_tcp_builder!("tokio", super::provider::Tokio, tokio); impl SwarmBuilder { - // TODO: This would allow one to build a faulty transport. pub(crate) fn without_tcp( self, ) -> SwarmBuilder> { SwarmBuilder { - // TODO: Is this a good idea in a production environment? Unfortunately I don't know a - // way around it. One can not define two `with_relay_client` methods, one with a real transport - // using OrTransport, one with a fake transport discarding it right away. keypair: self.keypair, phantom: PhantomData, phase: QuicPhase { + // Note that this allows a user to build a faulty (i.e. dummy) transport only. + // Ideally the final build step would not exist unless one adds another transport + // after `without_tcp`. Though currently this would introduce significant + // complexity to each following step. transport: libp2p_core::transport::dummy::DummyTransport::new(), }, } From 705b086f9d78618f823092f0a7b0e525e653e4eb Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:42:46 +0200 Subject: [PATCH 125/171] Rephase note on unnecessary tokio await --- libp2p/src/builder/phase/websocket.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libp2p/src/builder/phase/websocket.rs b/libp2p/src/builder/phase/websocket.rs index 24ab464eaca..f3554232b89 100644 --- a/libp2p/src/builder/phase/websocket.rs +++ b/libp2p/src/builder/phase/websocket.rs @@ -97,10 +97,11 @@ impl_websocket_builder!( libp2p_websocket::BytesConnection, > ); -// TODO: Unnecessary await for Tokio Websocket (i.e. tokio dns). Not ideal but don't know a better way. impl_websocket_builder!( "tokio", super::provider::Tokio, + // Note this is an unnecessary await for Tokio Websocket (i.e. tokio dns) in order to be consistent + // with above AsyncStd construction. futures::future::ready(libp2p_dns::tokio::Transport::system( libp2p_tcp::tokio::Transport::new(libp2p_tcp::Config::default()) )), From 52ac76cdb129fdcc861fb48e3a74ac919f1951c9 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 10:55:52 +0200 Subject: [PATCH 126/171] Seal TryInto traits --- libp2p/src/builder/phase/behaviour.rs | 14 ++++++++++++-- libp2p/src/builder/phase/other_transport.rs | 13 +++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libp2p/src/builder/phase/behaviour.rs b/libp2p/src/builder/phase/behaviour.rs index 3ce8aa5e8c9..e29c290f458 100644 --- a/libp2p/src/builder/phase/behaviour.rs +++ b/libp2p/src/builder/phase/behaviour.rs @@ -46,8 +46,7 @@ impl SwarmBuilder> { } } -// TODO: Seal this. -pub trait TryIntoBehaviour { +pub trait TryIntoBehaviour: private::Sealed { type Error; fn try_into_behaviour(self) -> Result; @@ -75,6 +74,17 @@ where } } +mod private { + pub trait Sealed {} +} + +impl private::Sealed for B {} + +impl private::Sealed + for Result> +{ +} + #[derive(Debug, thiserror::Error)] #[error("failed to build behaviour: {0}")] pub struct BehaviourError(Box); diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index 4f337af9c3d..7a3046dc3c9 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -157,8 +157,7 @@ impl } } -// TODO: Seal this. -pub trait TryIntoTransport { +pub trait TryIntoTransport: private::Sealed { type Error; fn try_into_transport(self) -> Result; @@ -186,6 +185,16 @@ where } } +mod private { + pub trait Sealed {} +} + +impl private::Sealed for T {} + +impl private::Sealed + for Result> +{ +} #[derive(Debug, thiserror::Error)] #[error("failed to build transport: {0}")] From 83e3674dc492854642012495a93f6e4a00a204fd Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 11:05:51 +0200 Subject: [PATCH 127/171] Rename to providerPascalCase --- libp2p/src/builder/phase/quic.rs | 14 +++++++------- libp2p/src/builder/phase/relay.rs | 6 +++--- libp2p/src/builder/phase/tcp.rs | 12 ++++++------ libp2p/src/builder/phase/websocket.rs | 6 +++--- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index f1dd20d7a78..675baaf413c 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -14,13 +14,13 @@ pub struct QuicPhase { } macro_rules! impl_quic_builder { - ($providerKebabCase:literal, $providerCamelCase:ty, $quic:ident) => { + ($providerKebabCase:literal, $providerPascalCase:ty, $quic:ident) => { #[cfg(all(not(target_arch = "wasm32"), feature = "quic", feature = $providerKebabCase))] - impl SwarmBuilder<$providerCamelCase, QuicPhase> { + impl SwarmBuilder<$providerPascalCase, QuicPhase> { pub fn with_quic( self, ) -> SwarmBuilder< - $providerCamelCase, + $providerPascalCase, OtherTransportPhase, > { self.with_quic_config(|key| libp2p_quic::Config::new(&key)) @@ -30,7 +30,7 @@ macro_rules! impl_quic_builder { self, constructor: impl FnOnce(&libp2p_identity::Keypair) -> libp2p_quic::Config, ) -> SwarmBuilder< - $providerCamelCase, + $providerPascalCase, OtherTransportPhase, > { SwarmBuilder { @@ -160,9 +160,9 @@ impl SwarmBuilder { + ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => { #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] - impl SwarmBuilder<$providerCamelCase, QuicPhase> { + impl SwarmBuilder<$providerPascalCase, QuicPhase> { pub async fn with_websocket < SecUpgrade, SecStream, @@ -176,7 +176,7 @@ macro_rules! impl_quic_phase_with_websocket { multiplexer_upgrade: MuxUpgrade, ) -> Result< SwarmBuilder< - $providerCamelCase, + $providerPascalCase, BandwidthLoggingPhase, >, super::websocket::WebsocketError, diff --git a/libp2p/src/builder/phase/relay.rs b/libp2p/src/builder/phase/relay.rs index b60ba2ba593..e0dc7d2b7ae 100644 --- a/libp2p/src/builder/phase/relay.rs +++ b/libp2p/src/builder/phase/relay.rs @@ -104,9 +104,9 @@ impl SwarmBuilder { + ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => { #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] - impl SwarmBuilder<$providerCamelCase, RelayPhase> { + impl SwarmBuilder<$providerPascalCase, RelayPhase> { pub async fn with_websocket < SecUpgrade, SecStream, @@ -120,7 +120,7 @@ macro_rules! impl_relay_phase_with_websocket { multiplexer_upgrade: MuxUpgrade, ) -> Result< SwarmBuilder< - $providerCamelCase, + $providerPascalCase, BandwidthLoggingPhase, >, super::websocket::WebsocketError, diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index ca783b8be73..26137c00d0e 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -17,20 +17,20 @@ use std::marker::PhantomData; pub struct TcpPhase {} macro_rules! impl_tcp_builder { - ($providerKebabCase:literal, $providerCamelCase:ty, $path:ident) => { + ($providerKebabCase:literal, $providerPascalCase:ty, $path:ident) => { #[cfg(all( not(target_arch = "wasm32"), feature = "tcp", feature = $providerKebabCase, ))] - impl SwarmBuilder<$providerCamelCase, TcpPhase> { + impl SwarmBuilder<$providerPascalCase, TcpPhase> { pub fn with_tcp( self, tcp_config: libp2p_tcp::Config, security_upgrade: SecUpgrade, multiplexer_upgrade: MuxUpgrade, ) -> Result< - SwarmBuilder<$providerCamelCase, QuicPhase>, + SwarmBuilder<$providerPascalCase, QuicPhase>, SecUpgrade::Error, > where @@ -133,9 +133,9 @@ impl SwarmBuilder { } } macro_rules! impl_tcp_phase_with_websocket { - ($providerKebabCase:literal, $providerCamelCase:ty, $websocketStream:ty) => { + ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => { #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] - impl SwarmBuilder<$providerCamelCase, TcpPhase> { + impl SwarmBuilder<$providerPascalCase, TcpPhase> { pub async fn with_websocket < SecUpgrade, SecStream, @@ -149,7 +149,7 @@ macro_rules! impl_tcp_phase_with_websocket { multiplexer_upgrade: MuxUpgrade, ) -> Result< SwarmBuilder< - $providerCamelCase, + $providerPascalCase, BandwidthLoggingPhase, >, WebsocketError, diff --git a/libp2p/src/builder/phase/websocket.rs b/libp2p/src/builder/phase/websocket.rs index f3554232b89..6a0d9c5e331 100644 --- a/libp2p/src/builder/phase/websocket.rs +++ b/libp2p/src/builder/phase/websocket.rs @@ -16,9 +16,9 @@ pub struct WebsocketPhase { } macro_rules! impl_websocket_builder { - ($providerKebabCase:literal, $providerCamelCase:ty, $dnsTcp:expr, $websocketStream:ty) => { + ($providerKebabCase:literal, $providerPascalCase:ty, $dnsTcp:expr, $websocketStream:ty) => { #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "websocket"))] - impl SwarmBuilder<$providerCamelCase, WebsocketPhase> { + impl SwarmBuilder<$providerPascalCase, WebsocketPhase> { pub async fn with_websocket< SecUpgrade, SecStream, @@ -32,7 +32,7 @@ macro_rules! impl_websocket_builder { multiplexer_upgrade: MuxUpgrade, ) -> Result< SwarmBuilder< - $providerCamelCase, + $providerPascalCase, BandwidthLoggingPhase, >, WebsocketError, From 9ee251fbff8dff002791f4be3e474b14fb4564e7 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 11:28:05 +0200 Subject: [PATCH 128/171] interop: re-introduce mplex --- interop-tests/native-ping-version.json | 3 +- interop-tests/src/arch.rs | 92 +++++++++++++++++--------- libp2p/src/builder/phase/relay.rs | 2 +- 3 files changed, 65 insertions(+), 32 deletions(-) diff --git a/interop-tests/native-ping-version.json b/interop-tests/native-ping-version.json index eb88d21d9c5..9ed05e88b8a 100644 --- a/interop-tests/native-ping-version.json +++ b/interop-tests/native-ping-version.json @@ -12,6 +12,7 @@ "noise" ], "muxers": [ - "yamux" + "yamux", + "mplex" ] } diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 6ba364640ed..31f333ec3d1 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -18,6 +18,7 @@ pub(crate) mod native { use libp2p::identity::Keypair; use libp2p::swarm::{NetworkBehaviour, Swarm}; use libp2p::{noise, tcp, tls, yamux, Transport as _}; + use libp2p_mplex as mplex; use libp2p_webrtc as webrtc; use redis::AsyncCommands; @@ -35,23 +36,17 @@ pub(crate) mod native { tokio::time::sleep(duration).boxed() } - fn expect_muxer_yamux() -> Result<()> { - match from_env("muxer")? { - Muxer::Yamux => (), - Muxer::Mplex => { - bail!("Only Yamux is supported, not Mplex") - } - }; - Ok(()) - } - pub(crate) async fn build_swarm( ip: &str, transport: Transport, behaviour_constructor: impl FnOnce(&Keypair) -> B, ) -> Result<(Swarm, String)> { - let (swarm, addr) = match (transport, from_env::("security")) { - (Transport::QuicV1, _) => { + let (swarm, addr) = match ( + transport, + from_env::("security"), + from_env::("muxer"), + ) { + (Transport::QuicV1, _, _) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_quic() @@ -59,9 +54,7 @@ pub(crate) mod native { .build(); (swarm, format!("/ip4/{ip}/udp/0/quic-v1")) } - (Transport::Tcp, Ok(SecProtocol::Tls)) => { - expect_muxer_yamux()?; - + (Transport::Tcp, Ok(SecProtocol::Tls), Ok(Muxer::Yamux)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp( @@ -73,9 +66,19 @@ pub(crate) mod native { .build(); (swarm, format!("/ip4/{ip}/tcp/0")) } - (Transport::Tcp, Ok(SecProtocol::Noise)) => { - expect_muxer_yamux()?; - + (Transport::Tcp, Ok(SecProtocol::Tls), Ok(Muxer::Mplex)) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_tcp( + tcp::Config::default(), + tls::Config::new, + mplex::MplexConfig::default, + )? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0")) + } + (Transport::Tcp, Ok(SecProtocol::Noise), Ok(Muxer::Yamux)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp( @@ -87,29 +90,55 @@ pub(crate) mod native { .build(); (swarm, format!("/ip4/{ip}/tcp/0")) } - (Transport::Ws, Ok(SecProtocol::Tls)) => { - expect_muxer_yamux()?; - + (Transport::Tcp, Ok(SecProtocol::Noise), Ok(Muxer::Mplex)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(libp2p_tls::Config::new, libp2p_yamux::Config::default) + .with_tcp( + tcp::Config::default(), + noise::Config::new, + mplex::MplexConfig::default, + )? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0")) + } + (Transport::Ws, Ok(SecProtocol::Tls), Ok(Muxer::Yamux)) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_websocket(libp2p_tls::Config::new, yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? .build(); (swarm, format!("/ip4/{ip}/tcp/0/ws")) } - (Transport::Ws, Ok(SecProtocol::Noise)) => { - expect_muxer_yamux()?; - + (Transport::Ws, Ok(SecProtocol::Tls), Ok(Muxer::Mplex)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(libp2p_tls::Config::new, libp2p_yamux::Config::default) + .with_websocket(libp2p_tls::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? .build(); (swarm, format!("/ip4/{ip}/tcp/0/ws")) } - (Transport::WebRtcDirect, _) => { + (Transport::Ws, Ok(SecProtocol::Noise), Ok(Muxer::Yamux)) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_websocket(libp2p_tls::Config::new, yamux::Config::default) + .await? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0/ws")) + } + (Transport::Ws, Ok(SecProtocol::Noise), Ok(Muxer::Mplex)) => { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_websocket(libp2p_tls::Config::new, mplex::MplexConfig::default) + .await? + .with_behaviour(behaviour_constructor)? + .build(); + (swarm, format!("/ip4/{ip}/tcp/0/ws")) + } + (Transport::WebRtcDirect, _, _) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_other_transport(|key| { @@ -124,9 +153,12 @@ pub(crate) mod native { (swarm, format!("/ip4/{ip}/udp/0/webrtc-direct")) } - (Transport::Tcp, Err(_)) => bail!("Missing security protocol for TCP transport"), - (Transport::Ws, Err(_)) => bail!("Missing security protocol for Websocket transport"), - (Transport::Webtransport, _) => bail!("Webtransport can only be used with wasm"), + (Transport::Tcp, Err(_), _) => bail!("Missing security protocol for TCP transport"), + (Transport::Ws, Err(_), _) => { + bail!("Missing security protocol for Websocket transport") + } + (Transport::Webtransport, _, _) => bail!("Webtransport can only be used with wasm"), + (_, _, Err(e)) => bail!("muxer selection: {e}"), }; Ok((swarm, addr)) } diff --git a/libp2p/src/builder/phase/relay.rs b/libp2p/src/builder/phase/relay.rs index e0dc7d2b7ae..8cde349404a 100644 --- a/libp2p/src/builder/phase/relay.rs +++ b/libp2p/src/builder/phase/relay.rs @@ -4,7 +4,7 @@ use std::marker::PhantomData; use libp2p_core::muxing::StreamMuxerBox; #[cfg(feature = "relay")] use libp2p_core::Transport; -#[cfg(feature = "relay")] +#[cfg(any(feature = "relay", feature = "websocket"))] use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, StreamMuxer, UpgradeInfo}; #[cfg(feature = "relay")] use libp2p_identity::PeerId; From 3e34a6581b44c5ffc804a27378667f6db39e5fd1 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 12:46:45 +0200 Subject: [PATCH 129/171] Refactor websocket error handling --- libp2p/src/builder/phase/websocket.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libp2p/src/builder/phase/websocket.rs b/libp2p/src/builder/phase/websocket.rs index 6a0d9c5e331..7e21851f2f5 100644 --- a/libp2p/src/builder/phase/websocket.rs +++ b/libp2p/src/builder/phase/websocket.rs @@ -63,9 +63,9 @@ macro_rules! impl_websocket_builder { { let security_upgrade = security_upgrade.into_security_upgrade(&self.keypair) - .map_err(|e| WebsocketError(WebsocketErrorInner::SecurityUpgrade(e)))?; + .map_err(WebsocketErrorInner::SecurityUpgrade)?; let websocket_transport = libp2p_websocket::WsConfig::new( - $dnsTcp.await.map_err(|e| WebsocketError(e.into()))?, + $dnsTcp.await.map_err(WebsocketErrorInner::Dns)?, ) .upgrade(libp2p_core::upgrade::Version::V1Lazy) .authenticate(security_upgrade) @@ -154,7 +154,7 @@ impl #[derive(Debug, thiserror::Error)] #[error(transparent)] #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] -pub struct WebsocketError(WebsocketErrorInner); +pub struct WebsocketError(#[from] WebsocketErrorInner); #[derive(Debug, thiserror::Error)] #[cfg(all(not(target_arch = "wasm32"), feature = "websocket"))] From 4853caf887182a86cc71ace075f568a8b0aee7bd Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 12:55:21 +0200 Subject: [PATCH 130/171] Remove without_executor --- swarm-test/Cargo.toml | 2 +- swarm-test/src/lib.rs | 2 +- swarm/src/lib.rs | 20 +++----------------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/swarm-test/Cargo.toml b/swarm-test/Cargo.toml index 67753b1c522..5744ee6a6c5 100644 --- a/swarm-test/Cargo.toml +++ b/swarm-test/Cargo.toml @@ -16,7 +16,7 @@ async-trait = "0.1.73" libp2p-core = { workspace = true } libp2p-identity = { workspace = true } libp2p-plaintext = { workspace = true } -libp2p-swarm = { workspace = true } +libp2p-swarm = { workspace = true, features = ["async-std"] } libp2p-tcp = { workspace = true, features = ["async-io"] } libp2p-yamux = { workspace = true } futures = "0.3.28" diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index 7c4f71c588f..cba774a3105 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -220,7 +220,7 @@ where transport, behaviour_fn(identity), peer_id, - swarm::Config::without_executor().with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., + swarm::Config::with_async_std_executor().with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., ) } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 141c917e9c2..660026e0470 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1412,20 +1412,6 @@ impl Config { Self::with_executor(crate::executor::AsyncStdExecutor) } - // TODO: Should we remove this from `Config`?! - // - /// Creates a new [`Config`]. - /// - /// ## ⚠️ Performance warning - /// All connections will be polled on the current task, thus quite bad performance - /// characteristics should be expected. Whenever possible use an executor and - /// [`Config::with_executor`]. - pub fn without_executor() -> Self { - Self { - pool_config: PoolConfig::new(None), - } - } - /// Configures the number of events from the [`NetworkBehaviour`] in /// destination to the [`ConnectionHandler`] that can be buffered before /// the [`Swarm`] has to wait. An individual buffer with this number of @@ -2067,10 +2053,10 @@ mod tests { /// /// The test expects both behaviours to be notified via calls to [`NetworkBehaviour::on_swarm_event`] /// with pairs of [`FromSwarm::ConnectionEstablished`] / [`FromSwarm::ConnectionClosed`] - #[test] + #[tokio::test] fn test_swarm_disconnect() { - let mut swarm1 = new_test_swarm(Config::without_executor()); - let mut swarm2 = new_test_swarm(Config::without_executor()); + let mut swarm1 = new_test_swarm(Config::with_tokio_executor()); + let mut swarm2 = new_test_swarm(Config::with_tokio_executor()); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); From fe794518fca80188ffff35b62a4498bf61cbf6c3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 12:57:33 +0200 Subject: [PATCH 131/171] Rename new_with_config to new --- libp2p/src/builder/phase/build.rs | 2 +- protocols/dcutr/tests/lib.rs | 2 +- protocols/kad/src/behaviour/test.rs | 2 +- protocols/perf/src/bin/perf.rs | 2 +- protocols/relay/tests/lib.rs | 4 ++-- swarm-test/src/lib.rs | 2 +- swarm/CHANGELOG.md | 2 +- swarm/src/lib.rs | 8 ++++---- transports/pnet/tests/smoke.rs | 2 +- transports/tls/tests/smoke.rs | 2 +- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libp2p/src/builder/phase/build.rs b/libp2p/src/builder/phase/build.rs index cf24045cb6b..5b9551c33f3 100644 --- a/libp2p/src/builder/phase/build.rs +++ b/libp2p/src/builder/phase/build.rs @@ -15,7 +15,7 @@ impl> { pub fn build(self) -> Swarm { - Swarm::new_with_config( + Swarm::new( libp2p_core::transport::timeout::TransportTimeout::new( self.phase.transport, CONNECTION_TIMEOUT, diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index 213b80e930b..066cb9c6967 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -123,7 +123,7 @@ fn build_client() -> Swarm { .multiplex(libp2p_yamux::Config::default()) .boxed(); - Swarm::new_with_config( + Swarm::new( transport, Client { relay: behaviour, diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index f4b25e7bd07..39a872da3fd 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -68,7 +68,7 @@ fn build_node_with_config(cfg: Config) -> (Multiaddr, TestSwarm) { let behaviour = Behaviour::with_config(local_id, store, cfg); let mut swarm = - Swarm::new_with_config(transport, behaviour, local_id, swarm::Config::without_executor()); + Swarm::new(transport, behaviour, local_id, swarm::Config::without_executor()); let address: Multiaddr = Protocol::Memory(random::()).into(); swarm.listen_on(address.clone()).unwrap(); diff --git a/protocols/perf/src/bin/perf.rs b/protocols/perf/src/bin/perf.rs index fe1411cff29..418c7fef97f 100644 --- a/protocols/perf/src/bin/perf.rs +++ b/protocols/perf/src/bin/perf.rs @@ -414,7 +414,7 @@ async fn swarm() -> Result> { .boxed() }; - let swarm = Swarm::new_with_config( + let swarm = Swarm::new( transport, Default::default(), local_peer_id, diff --git a/protocols/relay/tests/lib.rs b/protocols/relay/tests/lib.rs index de90417a2dd..f5c834bcb37 100644 --- a/protocols/relay/tests/lib.rs +++ b/protocols/relay/tests/lib.rs @@ -310,7 +310,7 @@ fn build_relay() -> Swarm { let transport = upgrade_transport(MemoryTransport::default().boxed(), &local_key); - Swarm::new_with_config( + Swarm::new( transport, Relay { ping: ping::Behaviour::new(ping::Config::new()), @@ -337,7 +337,7 @@ fn build_client() -> Swarm { &local_key, ); - Swarm::new_with_config( + Swarm::new( transport, Client { ping: ping::Behaviour::new(ping::Config::new()), diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index cba774a3105..670b9a146ab 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -216,7 +216,7 @@ where .timeout(Duration::from_secs(20)) .boxed(); - Swarm::new_with_config( + Swarm::new( transport, behaviour_fn(identity), peer_id, diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 5e00e07b069..5d2ff1bff33 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -2,7 +2,7 @@ - Deprecate old `libp2p::swarm::SwarmBuilder`. Most users should use the new `libp2p::SwarmBuilder`. - In some special cases, users may need to use `Swarm::new_with_config` and `Config` instead of the new `libp2p::SwarmBuilder`. + In some special cases, users may need to use `Swarm::new` and `Config` instead of the new `libp2p::SwarmBuilder`. See [PR 4120]. [PR 4120]: https://github.com/libp2p/rust-libp2p/pull/4120 diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 660026e0470..30f72274ecd 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -362,7 +362,7 @@ where { /// Creates a new [`Swarm`] from the given [`Transport`], [`NetworkBehaviour`], [`PeerId`] and /// [`Config`]. - pub fn new_with_config( + pub fn new( transport: transport::Boxed<(PeerId, StreamMuxerBox)>, behaviour: TBehaviour, local_peer_id: PeerId, @@ -1373,7 +1373,7 @@ pub struct Config { impl Config { /// Creates a new [`Config`] from the given executor. The [`Swarm`] is obtained via - /// [`Swarm::new_with_config`]. + /// [`Swarm::new`]. pub fn with_executor(executor: impl Executor + Send + 'static) -> Self { Self { pool_config: PoolConfig::new(Some(Box::new(executor))), @@ -1491,7 +1491,7 @@ impl Config { /// A [`SwarmBuilder`] provides an API for configuring and constructing a [`Swarm`]. #[deprecated( - note = "Use the new `libp2p::SwarmBuilder` instead of `libp2p::swarm::SwarmBuilder` or create a `Swarm` directly via `Swarm::new_with_config`." + note = "Use the new `libp2p::SwarmBuilder` instead of `libp2p::swarm::SwarmBuilder` or create a `Swarm` directly via `Swarm::new`." )] pub struct SwarmBuilder { local_peer_id: PeerId, @@ -1999,7 +1999,7 @@ mod tests { .boxed(); let behaviour = CallTraceBehaviour::new(MockBehaviour::new(dummy::ConnectionHandler)); - Swarm::new_with_config( + Swarm::new( transport, behaviour, local_public_key.into(), diff --git a/transports/pnet/tests/smoke.rs b/transports/pnet/tests/smoke.rs index af9251440dd..79ffaeab447 100644 --- a/transports/pnet/tests/smoke.rs +++ b/transports/pnet/tests/smoke.rs @@ -113,7 +113,7 @@ where .authenticate(libp2p_noise::Config::new(&identity).unwrap()) .multiplex(libp2p_yamux::Config::default()) .boxed(); - Swarm::new_with_config( + Swarm::new( transport, dummy::Behaviour, identity.public().to_peer_id(), diff --git a/transports/tls/tests/smoke.rs b/transports/tls/tests/smoke.rs index 8863bb17645..b5195da8009 100644 --- a/transports/tls/tests/smoke.rs +++ b/transports/tls/tests/smoke.rs @@ -65,7 +65,7 @@ fn make_swarm() -> Swarm { .multiplex(libp2p_yamux::Config::default()) .boxed(); - Swarm::new_with_config( + Swarm::new( transport, dummy::Behaviour, identity.public().to_peer_id(), From 80b8657f3959f51541391728a89f63e074e51e24 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 13:14:04 +0200 Subject: [PATCH 132/171] Reword libp2p changelog --- libp2p/CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 649f5b0374f..df683afc3ed 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -1,7 +1,6 @@ ## 0.52.4 - unreleased -- Introduce the new `libp2p::SwarmBuilder`. - Users should use the new `libp2p::SwarmBuilder` instead of the now deprecated `libp2p::swarm::SwarmBuilder`. +- Introduce a new `libp2p::SwarmBuilder` in favor of the now deprecated `libp2p::swarm::SwarmBuilder`. See `libp2p::SwarmBuilder` docs on how to use the new builder. Also see [PR 4120]. From 63633dcfcc21b385f9e1f9f0fec7550f07cb446f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 13:15:04 +0200 Subject: [PATCH 133/171] Reword swarm changelog --- swarm/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 5d2ff1bff33..d0567f7d7a1 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,7 +1,7 @@ ## 0.43.6 - unreleased -- Deprecate old `libp2p::swarm::SwarmBuilder`. - Most users should use the new `libp2p::SwarmBuilder`. +- Deprecate `libp2p::swarm::SwarmBuilder`. + Most users should use `libp2p::SwarmBuilder`. In some special cases, users may need to use `Swarm::new` and `Config` instead of the new `libp2p::SwarmBuilder`. See [PR 4120]. From 5828b9ee1cb73d70a01cf06d715e2dd111969bb5 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 13:23:53 +0200 Subject: [PATCH 134/171] refactor(examples/dcutr): use tokio --- Cargo.lock | 2 +- examples/dcutr/Cargo.toml | 4 ++-- examples/dcutr/src/main.rs | 7 +++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 537ed001fe8..39c340c27a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1230,13 +1230,13 @@ dependencies = [ name = "dcutr-example" version = "0.1.0" dependencies = [ - "async-std", "clap", "env_logger 0.10.0", "futures", "futures-timer", "libp2p", "log", + "tokio", ] [[package]] diff --git a/examples/dcutr/Cargo.toml b/examples/dcutr/Cargo.toml index 5f0e2782dc7..11cdc31f71b 100644 --- a/examples/dcutr/Cargo.toml +++ b/examples/dcutr/Cargo.toml @@ -6,10 +6,10 @@ publish = false license = "MIT" [dependencies] -async-std = { version = "1.12.0", features = ["attributes"] } clap = { version = "4.3.23", features = ["derive"] } env_logger = "0.10.0" futures = "0.3.28" futures-timer = "3.0" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "dcutr", "identify", "macros", "noise", "ping", "quic", "relay", "rendezvous", "tcp", "tokio", "yamux"] } +libp2p = { path = "../../libp2p", features = ["dns", "dcutr", "identify", "macros", "noise", "ping", "quic", "relay", "rendezvous", "tcp", "tokio", "yamux"] } log = "0.4" +tokio = { version = "1.29", features = ["macros", "net", "rt", "signal"] } diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 2267efb77d8..a3e2df12f64 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -69,7 +69,7 @@ impl FromStr for Mode { } } -#[async_std::main] +#[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); @@ -119,15 +119,14 @@ async fn main() -> Result<(), Box> { let mut swarm = libp2p::SwarmBuilder::with_existing_identity(generate_ed25519(opts.secret_key_seed)) - .with_async_std() + .with_tokio() .with_tcp( tcp::Config::default().port_reuse(true).nodelay(true), noise::Config::new, yamux::Config::default, )? .with_quic() - .with_dns() - .await? + .with_dns()? .with_relay_client(noise::Config::new, yamux::Config::default)? .with_behaviour(|keypair, relay_behaviour| Behaviour { relay_client: relay_behaviour, From 2b680d6da21c96f46c04c7292ee74c8a3383ddff Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 2 Oct 2023 14:28:34 +0200 Subject: [PATCH 135/171] Minor fixes --- examples/metrics/src/main.rs | 2 - examples/ping/src/main.rs | 2 - examples/rendezvous/src/bin/rzv-register.rs | 5 +- examples/rendezvous/src/main.rs | 6 +- interop-tests/native-ping-version.json | 4 +- libp2p/src/builder.rs | 4 +- protocols/dcutr/tests/lib.rs | 2 +- protocols/kad/src/behaviour/test.rs | 2 +- swarm/Cargo.toml | 2 +- swarm/src/connection.rs | 4 +- swarm/src/lib.rs | 120 ++++++++++---------- 11 files changed, 81 insertions(+), 72 deletions(-) diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index 78f3334fb47..b5e2a396072 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -51,8 +51,6 @@ fn main() -> Result<(), Box> { ) .build(); - info!("Local peer id: {:?}", swarm.local_peer_id()); - swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; if let Some(addr) = std::env::args().nth(1) { diff --git a/examples/ping/src/main.rs b/examples/ping/src/main.rs index d7d3d9a8d7a..376f12ede5a 100644 --- a/examples/ping/src/main.rs +++ b/examples/ping/src/main.rs @@ -37,8 +37,6 @@ async fn main() -> Result<(), Box> { .unwrap() .build(); - println!("Local peer id: {:?}", swarm.local_peer_id()); - // Tell the swarm to listen on all interfaces and a random, OS-assigned // port. swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index 19984de74ef..1861ce964f9 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -48,7 +48,10 @@ async fn main() { ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), }) .unwrap() - // .TODO idle_connection_timeout(Duration::from_secs(5)) + .with_swarm_config( + libp2p::swarm::Config::with_tokio_executor() + .with_idle_connection_timeout(Duration::from_secs(5)), + ) .build(); // In production the external address should be the publicly facing IP address of the rendezvous point. diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 65fa669a158..52f4be3e767 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -48,10 +48,12 @@ async fn main() -> Result<(), Box> { rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), })? + .with_swarm_config( + libp2p::swarm::Config::with_tokio_executor() + .with_idle_connection_timeout(Duration::from_secs(5)), + ) .build(); - // TODO: Set idle connection timeout. - let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/62649".parse().unwrap()); while let Some(event) = swarm.next().await { diff --git a/interop-tests/native-ping-version.json b/interop-tests/native-ping-version.json index 9ed05e88b8a..c509f72bfd0 100644 --- a/interop-tests/native-ping-version.json +++ b/interop-tests/native-ping-version.json @@ -12,7 +12,7 @@ "noise" ], "muxers": [ - "yamux", - "mplex" + "mplex", + "yamux" ] } diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index d4e05dc5f67..288a228bee8 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -3,7 +3,9 @@ use std::marker::PhantomData; mod phase; mod select_security; -/// Build a [`Swarm`] by combining an identity, a set of [`Transport`]s and a [`NetworkBehaviour`]. +/// Build a [`Swarm`](libp2p_swarm::Swarm) by combining an identity, a set of +/// [`Transport`](libp2p_core::Transport)s and a +/// [`NetworkBehaviour`](libp2p_swarm::NetworkBehaviour). /// /// ``` /// # use libp2p::{swarm::NetworkBehaviour, SwarmBuilder}; diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index 066cb9c6967..e13037adb7a 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -130,7 +130,7 @@ fn build_client() -> Swarm { dcutr: dcutr::Behaviour::new(local_peer_id), }, local_peer_id, - Config::without_executor(), + Config::with_async_std_executor(), ) } diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index 39a872da3fd..c4b14415d86 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -68,7 +68,7 @@ fn build_node_with_config(cfg: Config) -> (Multiaddr, TestSwarm) { let behaviour = Behaviour::with_config(local_id, store, cfg); let mut swarm = - Swarm::new(transport, behaviour, local_id, swarm::Config::without_executor()); + Swarm::new(transport, behaviour, local_id, swarm::Config::with_async_std_executor()); let address: Multiaddr = Protocol::Memory(random::()).into(); swarm.listen_on(address.clone()).unwrap(); diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 7893a20d125..6ba199281a3 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -55,7 +55,7 @@ quickcheck = { workspace = true } void = "1" once_cell = "1.18.0" trybuild = "1.0.85" -tokio = { version = "1.29.1", features = ["time", "rt", "macros"] } +tokio = { version = "1.29.1", features = ["time", "rt", "macros", "rt-multi-thread"] } [[test]] name = "swarm_derive" diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index d99319cf2cb..89ec4a598b7 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -749,6 +749,8 @@ mod tests { #[test] fn max_negotiating_inbound_streams() { + let _ = env_logger::try_init(); + fn prop(max_negotiating_inbound_streams: u8) { let max_negotiating_inbound_streams: usize = max_negotiating_inbound_streams.into(); @@ -757,7 +759,7 @@ mod tests { StreamMuxerBox::new(DummyStreamMuxer { counter: alive_substream_counter.clone(), }), - MockConnectionHandler::new(Duration::ZERO), + MockConnectionHandler::new(Duration::from_secs(10)), None, max_negotiating_inbound_streams, Duration::ZERO, diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 30f72274ecd..90fe85d1595 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -422,7 +422,9 @@ where /// # use libp2p_swarm::dummy; /// # use libp2p_identity::PeerId; /// # - /// let mut swarm = SwarmBuilder::without_executor( + /// # #[tokio::main] + /// # async fn main() { + /// let mut swarm = SwarmBuilder::with_tokio_executor( /// DummyTransport::new().boxed(), /// dummy::Behaviour, /// PeerId::random(), @@ -433,6 +435,7 @@ where /// /// // Dial an unknown peer. /// swarm.dial("/ip6/::1/tcp/12345".parse::().unwrap()); + /// # } /// ``` pub fn dial(&mut self, opts: impl Into) -> Result<(), DialError> { let dial_opts = opts.into(); @@ -1968,8 +1971,7 @@ mod tests { use super::*; use crate::dummy; use crate::test::{CallTraceBehaviour, MockBehaviour}; - use futures::executor::block_on; - use futures::{executor, future}; + use futures::future; use libp2p_core::multiaddr::multiaddr; use libp2p_core::transport::memory::MemoryTransportError; use libp2p_core::transport::TransportEvent; @@ -2054,7 +2056,7 @@ mod tests { /// The test expects both behaviours to be notified via calls to [`NetworkBehaviour::on_swarm_event`] /// with pairs of [`FromSwarm::ConnectionEstablished`] / [`FromSwarm::ConnectionClosed`] #[tokio::test] - fn test_swarm_disconnect() { + async fn test_swarm_disconnect() { let mut swarm1 = new_test_swarm(Config::with_tokio_executor()); let mut swarm2 = new_test_swarm(Config::with_tokio_executor()); @@ -2074,7 +2076,7 @@ mod tests { } let mut state = State::Connecting; - executor::block_on(future::poll_fn(move |cx| loop { + future::poll_fn(move |cx| loop { let poll1 = Swarm::poll_next_event(Pin::new(&mut swarm1), cx); let poll2 = Swarm::poll_next_event(Pin::new(&mut swarm2), cx); match state { @@ -2106,7 +2108,8 @@ mod tests { if poll1.is_pending() && poll2.is_pending() { return Poll::Pending; } - })) + }) + .await } /// Establishes multiple connections between two peers, @@ -2115,10 +2118,10 @@ mod tests { /// /// The test expects both behaviours to be notified via calls to [`NetworkBehaviour::on_swarm_event`] /// with pairs of [`FromSwarm::ConnectionEstablished`] / [`FromSwarm::ConnectionClosed`] - #[test] - fn test_behaviour_disconnect_all() { - let mut swarm1 = new_test_swarm(Config::without_executor()); - let mut swarm2 = new_test_swarm(Config::without_executor()); + #[tokio::test] + async fn test_behaviour_disconnect_all() { + let mut swarm1 = new_test_swarm(Config::with_tokio_executor()); + let mut swarm2 = new_test_swarm(Config::with_tokio_executor()); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2136,7 +2139,7 @@ mod tests { } let mut state = State::Connecting; - executor::block_on(future::poll_fn(move |cx| loop { + future::poll_fn(move |cx| loop { let poll1 = Swarm::poll_next_event(Pin::new(&mut swarm1), cx); let poll2 = Swarm::poll_next_event(Pin::new(&mut swarm2), cx); match state { @@ -2172,7 +2175,8 @@ mod tests { if poll1.is_pending() && poll2.is_pending() { return Poll::Pending; } - })) + }) + .await } /// Establishes multiple connections between two peers, @@ -2181,10 +2185,10 @@ mod tests { /// /// The test expects both behaviours to be notified via calls to [`NetworkBehaviour::on_swarm_event`] /// with pairs of [`FromSwarm::ConnectionEstablished`] / [`FromSwarm::ConnectionClosed`] - #[test] - fn test_behaviour_disconnect_one() { - let mut swarm1 = new_test_swarm(Config::without_executor()); - let mut swarm2 = new_test_swarm(Config::without_executor()); + #[tokio::test] + async fn test_behaviour_disconnect_one() { + let mut swarm1 = new_test_swarm(Config::with_tokio_executor()); + let mut swarm2 = new_test_swarm(Config::with_tokio_executor()); let addr1: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); let addr2: Multiaddr = multiaddr::Protocol::Memory(rand::random::()).into(); @@ -2202,7 +2206,7 @@ mod tests { let mut state = State::Connecting; let mut disconnected_conn_id = None; - executor::block_on(future::poll_fn(move |cx| loop { + future::poll_fn(move |cx| loop { let poll1 = Swarm::poll_next_event(Pin::new(&mut swarm1), cx); let poll2 = Swarm::poll_next_event(Pin::new(&mut swarm2), cx); match state { @@ -2246,7 +2250,8 @@ mod tests { if poll1.is_pending() && poll2.is_pending() { return Poll::Pending; } - })) + }) + .await } #[test] @@ -2261,9 +2266,10 @@ mod tests { } fn prop(concurrency_factor: DialConcurrencyFactor) { - block_on(async { + tokio::runtime::Runtime::new().unwrap().block_on(async { let mut swarm = new_test_swarm( - Config::without_executor().with_dial_concurrency_factor(concurrency_factor.0), + Config::with_tokio_executor() + .with_dial_concurrency_factor(concurrency_factor.0), ); // Listen on `concurrency_factor + 1` addresses. @@ -2320,31 +2326,29 @@ mod tests { QuickCheck::new().tests(10).quickcheck(prop as fn(_) -> _); } - #[test] - fn invalid_peer_id() { + #[tokio::test] + async fn invalid_peer_id() { // Checks whether dialing an address containing the wrong peer id raises an error // for the expected peer id instead of the obtained peer id. - let mut swarm1 = new_test_swarm(Config::without_executor()); - let mut swarm2 = new_test_swarm(Config::without_executor()); + let mut swarm1 = new_test_swarm(Config::with_tokio_executor()); + let mut swarm2 = new_test_swarm(Config::with_tokio_executor()); swarm1.listen_on("/memory/0".parse().unwrap()).unwrap(); - let address = - futures::executor::block_on(future::poll_fn(|cx| match swarm1.poll_next_unpin(cx) { - Poll::Ready(Some(SwarmEvent::NewListenAddr { address, .. })) => { - Poll::Ready(address) - } - Poll::Pending => Poll::Pending, - _ => panic!("Was expecting the listen address to be reported"), - })); + let address = future::poll_fn(|cx| match swarm1.poll_next_unpin(cx) { + Poll::Ready(Some(SwarmEvent::NewListenAddr { address, .. })) => Poll::Ready(address), + Poll::Pending => Poll::Pending, + _ => panic!("Was expecting the listen address to be reported"), + }) + .await; let other_id = PeerId::random(); let other_addr = address.with(multiaddr::Protocol::P2p(other_id)); swarm2.dial(other_addr.clone()).unwrap(); - let (peer_id, error) = futures::executor::block_on(future::poll_fn(|cx| { + let (peer_id, error) = future::poll_fn(|cx| { if let Poll::Ready(Some(SwarmEvent::IncomingConnection { .. })) = swarm1.poll_next_unpin(cx) {} @@ -2356,7 +2360,8 @@ mod tests { Poll::Ready(x) => panic!("unexpected {x:?}"), Poll::Pending => Poll::Pending, } - })); + }) + .await; assert_eq!(peer_id.unwrap(), other_id); match error { DialError::WrongPeerId { obtained, endpoint } => { @@ -2373,8 +2378,8 @@ mod tests { } } - #[test] - fn dial_self() { + #[tokio::test] + async fn dial_self() { // Check whether dialing ourselves correctly fails. // // Dialing the same address we're listening should result in three events: @@ -2385,17 +2390,15 @@ mod tests { // // The last two can happen in any order. - let mut swarm = new_test_swarm(Config::without_executor()); + let mut swarm = new_test_swarm(Config::with_tokio_executor()); swarm.listen_on("/memory/0".parse().unwrap()).unwrap(); - let local_address = - futures::executor::block_on(future::poll_fn(|cx| match swarm.poll_next_unpin(cx) { - Poll::Ready(Some(SwarmEvent::NewListenAddr { address, .. })) => { - Poll::Ready(address) - } - Poll::Pending => Poll::Pending, - _ => panic!("Was expecting the listen address to be reported"), - })); + let local_address = future::poll_fn(|cx| match swarm.poll_next_unpin(cx) { + Poll::Ready(Some(SwarmEvent::NewListenAddr { address, .. })) => Poll::Ready(address), + Poll::Pending => Poll::Pending, + _ => panic!("Was expecting the listen address to be reported"), + }) + .await; swarm.listened_addrs.clear(); // This is a hack to actually execute the dial to ourselves which would otherwise be filtered. @@ -2403,7 +2406,7 @@ mod tests { let mut got_dial_err = false; let mut got_inc_err = false; - futures::executor::block_on(future::poll_fn(|cx| -> Poll> { + future::poll_fn(|cx| -> Poll> { loop { match swarm.poll_next_unpin(cx) { Poll::Ready(Some(SwarmEvent::OutgoingConnectionError { @@ -2437,26 +2440,27 @@ mod tests { Poll::Pending => break Poll::Pending, } } - })) + }) + .await .unwrap(); } - #[test] - fn dial_self_by_id() { + #[tokio::test] + async fn dial_self_by_id() { // Trying to dial self by passing the same `PeerId` shouldn't even be possible in the first // place. - let swarm = new_test_swarm(Config::without_executor()); + let swarm = new_test_swarm(Config::with_tokio_executor()); let peer_id = *swarm.local_peer_id(); assert!(!swarm.is_connected(&peer_id)); } - #[async_std::test] + #[tokio::test] async fn multiple_addresses_err() { // Tries dialing multiple addresses, and makes sure there's one dialing error per address. let target = PeerId::random(); - let mut swarm = new_test_swarm(Config::without_executor()); + let mut swarm = new_test_swarm(Config::with_tokio_executor()); let addresses = HashSet::from([ multiaddr![Ip4([0, 0, 0, 0]), Tcp(rand::random::())], @@ -2498,16 +2502,16 @@ mod tests { } } - #[test] - fn aborting_pending_connection_surfaces_error() { + #[tokio::test] + async fn aborting_pending_connection_surfaces_error() { let _ = env_logger::try_init(); - let mut dialer = new_test_swarm(Config::without_executor()); - let mut listener = new_test_swarm(Config::without_executor()); + let mut dialer = new_test_swarm(Config::with_tokio_executor()); + let mut listener = new_test_swarm(Config::with_tokio_executor()); let listener_peer_id = *listener.local_peer_id(); listener.listen_on(multiaddr![Memory(0u64)]).unwrap(); - let listener_address = match block_on(listener.next()).unwrap() { + let listener_address = match listener.next().await.unwrap() { SwarmEvent::NewListenAddr { address, .. } => address, e => panic!("Unexpected network event: {e:?}"), }; @@ -2524,7 +2528,7 @@ mod tests { .disconnect_peer_id(listener_peer_id) .expect_err("Expect peer to not yet be connected."); - match block_on(dialer.next()).unwrap() { + match dialer.next().await.unwrap() { SwarmEvent::OutgoingConnectionError { error: DialError::Aborted, .. From 1fd5a5f6d96c0d1c9a4a1e513c4f21b450c88d83 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:24:08 +0200 Subject: [PATCH 136/171] Have with_swarm_config take closure --- examples/browser-webrtc/src/main.rs | 8 ++-- examples/metrics/src/main.rs | 7 +--- examples/rendezvous/src/bin/rzv-register.rs | 5 +-- examples/rendezvous/src/main.rs | 5 +-- libp2p/src/builder/phase/swarm.rs | 45 ++++++++++++++------- 5 files changed, 39 insertions(+), 31 deletions(-) diff --git a/examples/browser-webrtc/src/main.rs b/examples/browser-webrtc/src/main.rs index bd067605546..4ee86cd1229 100644 --- a/examples/browser-webrtc/src/main.rs +++ b/examples/browser-webrtc/src/main.rs @@ -37,11 +37,11 @@ async fn main() -> anyhow::Result<()> { .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn)))) })? .with_behaviour(|_| ping::Behaviour::default())? - .with_swarm_config( - libp2p::swarm::Config::with_tokio_executor().with_idle_connection_timeout( + .with_swarm_config(|cfg| { + cfg.with_idle_connection_timeout( Duration::from_secs(30), // Allows us to observe the pings. - ), - ) + ) + }) .build(); let address_webrtc = Multiaddr::from(Ipv4Addr::UNSPECIFIED) diff --git a/examples/metrics/src/main.rs b/examples/metrics/src/main.rs index b5e2a396072..09d4f7a5941 100644 --- a/examples/metrics/src/main.rs +++ b/examples/metrics/src/main.rs @@ -24,7 +24,7 @@ use env_logger::Env; use futures::{executor::block_on, StreamExt}; use libp2p::core::Multiaddr; use libp2p::metrics::{Metrics, Recorder}; -use libp2p::swarm::{self as swarm, NetworkBehaviour, SwarmEvent}; +use libp2p::swarm::{NetworkBehaviour, SwarmEvent}; use libp2p::{identify, identity, noise, ping, tcp, yamux}; use log::info; use prometheus_client::registry::Registry; @@ -45,10 +45,7 @@ fn main() -> Result<(), Box> { yamux::Config::default, )? .with_behaviour(|key| Behaviour::new(key.public()))? - .with_swarm_config( - swarm::Config::with_async_std_executor() - .with_idle_connection_timeout(Duration::from_secs(u64::MAX)), - ) + .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX))) .build(); swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; diff --git a/examples/rendezvous/src/bin/rzv-register.rs b/examples/rendezvous/src/bin/rzv-register.rs index 1861ce964f9..928dcdd1625 100644 --- a/examples/rendezvous/src/bin/rzv-register.rs +++ b/examples/rendezvous/src/bin/rzv-register.rs @@ -48,10 +48,7 @@ async fn main() { ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), }) .unwrap() - .with_swarm_config( - libp2p::swarm::Config::with_tokio_executor() - .with_idle_connection_timeout(Duration::from_secs(5)), - ) + .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5))) .build(); // In production the external address should be the publicly facing IP address of the rendezvous point. diff --git a/examples/rendezvous/src/main.rs b/examples/rendezvous/src/main.rs index 52f4be3e767..e40507c3fc3 100644 --- a/examples/rendezvous/src/main.rs +++ b/examples/rendezvous/src/main.rs @@ -48,10 +48,7 @@ async fn main() -> Result<(), Box> { rendezvous: rendezvous::server::Behaviour::new(rendezvous::server::Config::default()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), })? - .with_swarm_config( - libp2p::swarm::Config::with_tokio_executor() - .with_idle_connection_timeout(Duration::from_secs(5)), - ) + .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5))) .build(); let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/62649".parse().unwrap()); diff --git a/libp2p/src/builder/phase/swarm.rs b/libp2p/src/builder/phase/swarm.rs index 680a0107a4a..07526f28cbe 100644 --- a/libp2p/src/builder/phase/swarm.rs +++ b/libp2p/src/builder/phase/swarm.rs @@ -8,23 +8,40 @@ pub struct SwarmPhase { pub(crate) transport: T, } -impl SwarmBuilder> { - pub fn with_swarm_config( - self, - config: libp2p_swarm::Config, - ) -> SwarmBuilder> { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: config, - }, - keypair: self.keypair, - phantom: PhantomData, +macro_rules! impl_with_swarm_config { + ($providerKebabCase:literal, $providerPascalCase:ty, $config:expr) => { + #[cfg(feature = $providerKebabCase)] + impl SwarmBuilder<$providerPascalCase, SwarmPhase> { + pub fn with_swarm_config( + self, + constructor: impl FnOnce(libp2p_swarm::Config) -> libp2p_swarm::Config, + ) -> SwarmBuilder<$providerPascalCase, BuildPhase> { + SwarmBuilder { + phase: BuildPhase { + behaviour: self.phase.behaviour, + transport: self.phase.transport, + swarm_config: constructor($config), + }, + keypair: self.keypair, + phantom: PhantomData, + } + } } - } + }; } +impl_with_swarm_config!( + "async-std", + super::provider::AsyncStd, + libp2p_swarm::Config::with_async_std_executor() +); + +impl_with_swarm_config!( + "tokio", + super::provider::Tokio, + libp2p_swarm::Config::with_tokio_executor() +); + #[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] impl SwarmBuilder> From 4743616ec9552afd5c9db9c0a040ef10cc5560e6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:28:39 +0200 Subject: [PATCH 137/171] Have with_quic_config take closure --- libp2p/src/builder/phase/quic.rs | 15 +++++++++------ misc/server/src/main.rs | 8 +++----- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index 675baaf413c..bffe2bf08d4 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -23,12 +23,12 @@ macro_rules! impl_quic_builder { $providerPascalCase, OtherTransportPhase, > { - self.with_quic_config(|key| libp2p_quic::Config::new(&key)) + self.with_quic_config(std::convert::identity) } pub fn with_quic_config( self, - constructor: impl FnOnce(&libp2p_identity::Keypair) -> libp2p_quic::Config, + constructor: impl FnOnce(libp2p_quic::Config) -> libp2p_quic::Config, ) -> SwarmBuilder< $providerPascalCase, OtherTransportPhase, @@ -38,11 +38,14 @@ macro_rules! impl_quic_builder { transport: self .phase .transport - .or_transport(libp2p_quic::$quic::Transport::new(constructor(&self.keypair)).map( - |(peer_id, muxer), _| { + .or_transport( + libp2p_quic::$quic::Transport::new(constructor( + libp2p_quic::Config::new(&self.keypair), + )) + .map(|(peer_id, muxer), _| { (peer_id, libp2p_core::muxing::StreamMuxerBox::new(muxer)) - }, - )) + }), + ) .map(|either, _| either.into_inner()), }, keypair: self.keypair, diff --git a/misc/server/src/main.rs b/misc/server/src/main.rs index c9acc427337..5aed20840e5 100644 --- a/misc/server/src/main.rs +++ b/misc/server/src/main.rs @@ -7,7 +7,6 @@ use libp2p::identity; use libp2p::identity::PeerId; use libp2p::kad; use libp2p::metrics::{Metrics, Recorder}; -use libp2p::quic; use libp2p::swarm::SwarmEvent; use libp2p::tcp; use libp2p::{identify, noise, yamux}; @@ -80,10 +79,9 @@ async fn main() -> Result<(), Box> { noise::Config::new, yamux::Config::default, )? - .with_quic_config(|key| { - let mut config = quic::Config::new(key); - config.support_draft_29 = true; - config + .with_quic_config(|mut cfg| { + cfg.support_draft_29 = true; + cfg }) .with_dns()? .with_behaviour(|key| { From 7a8ee9b1d678b93f6c708a706ec201e6957d5fec Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:29:53 +0200 Subject: [PATCH 138/171] Remove unwrap --- examples/identify/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index c73fe57051a..2bcf074a64c 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -40,8 +40,7 @@ async fn main() -> Result<(), Box> { "/ipfs/id/1.0.0".to_string(), key.public(), )) - }) - .unwrap() + })? .build(); println!("Local peer id: {:?}", swarm.local_peer_id()); From e962f029782bf70611d9cf9b2dae81e556a76c42 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:30:26 +0200 Subject: [PATCH 139/171] Remove duplicate local peer id print --- examples/identify/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/identify/src/main.rs b/examples/identify/src/main.rs index 2bcf074a64c..d6be9cb9435 100644 --- a/examples/identify/src/main.rs +++ b/examples/identify/src/main.rs @@ -43,8 +43,6 @@ async fn main() -> Result<(), Box> { })? .build(); - println!("Local peer id: {:?}", swarm.local_peer_id()); - // Tell the swarm to listen on all interfaces and a random, OS-assigned // port. swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; From 358e7ff6711579b2273f92967ac9c166268540a5 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:31:06 +0200 Subject: [PATCH 140/171] Handle behaviour error --- examples/ipfs-kad/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index 2e7e55eb599..c55b418d5c5 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -51,8 +51,7 @@ async fn main() -> Result<(), Box> { cfg.set_query_timeout(Duration::from_secs(5 * 60)); let store = kad::store::MemoryStore::new(key.public().to_peer_id()); kad::Behaviour::with_config(key.public().to_peer_id(), store, cfg) - }) - .unwrap() + })? .build(); // Add the bootnodes to the local routing table. `libp2p-dns` built From 711d7b6c7ba321bea1383c5a98483920fb1fa3c3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:31:47 +0200 Subject: [PATCH 141/171] Handle behaviour error --- examples/ping/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/ping/src/main.rs b/examples/ping/src/main.rs index 376f12ede5a..3340f05863e 100644 --- a/examples/ping/src/main.rs +++ b/examples/ping/src/main.rs @@ -33,8 +33,7 @@ async fn main() -> Result<(), Box> { noise::Config::new, yamux::Config::default, )? - .with_behaviour(|_| ping::Behaviour::default()) - .unwrap() + .with_behaviour(|_| ping::Behaviour::default())? .build(); // Tell the swarm to listen on all interfaces and a random, OS-assigned From 99d7b6dc236a9fd7151842f4db285ae171d51cc6 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:32:40 +0200 Subject: [PATCH 142/171] Ping idle connection timeout --- examples/ping/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/ping/src/main.rs b/examples/ping/src/main.rs index 3340f05863e..5d2e70032f7 100644 --- a/examples/ping/src/main.rs +++ b/examples/ping/src/main.rs @@ -22,7 +22,7 @@ use futures::prelude::*; use libp2p::{noise, ping, swarm::SwarmEvent, tcp, yamux, Multiaddr}; -use std::error::Error; +use std::{error::Error, time::Duration}; #[async_std::main] async fn main() -> Result<(), Box> { @@ -34,6 +34,7 @@ async fn main() -> Result<(), Box> { yamux::Config::default, )? .with_behaviour(|_| ping::Behaviour::default())? + .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(u64::MAX))) .build(); // Tell the swarm to listen on all interfaces and a random, OS-assigned From 9bd04c73cb1f713dddce819b0cbf84abd6a4be92 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:35:26 +0200 Subject: [PATCH 143/171] Interop remove separate yamux import --- Cargo.lock | 1 - interop-tests/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39c340c27a8..82b456ac735 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2210,7 +2210,6 @@ dependencies = [ "libp2p-tls", "libp2p-webrtc", "libp2p-webrtc-websys", - "libp2p-yamux", "log", "mime_guess", "rand 0.8.5", diff --git a/interop-tests/Cargo.toml b/interop-tests/Cargo.toml index fabd564be90..6eb1735528c 100644 --- a/interop-tests/Cargo.toml +++ b/interop-tests/Cargo.toml @@ -24,7 +24,6 @@ libp2p-mplex = { path = "../muxers/mplex" } libp2p-noise = { workspace = true } libp2p-tls = { workspace = true } libp2p-webrtc = { workspace = true, features = ["tokio"] } -libp2p-yamux = { workspace = true } mime_guess = "2.0" redis = { version = "0.23.3", default-features = false, features = ["tokio-comp"] } rust-embed = "8.0" From 5a8c85393ee9805a7e41026f22d60989963d6e9e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:36:33 +0200 Subject: [PATCH 144/171] Use tls instead of libp2p-tls --- interop-tests/src/arch.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 31f333ec3d1..3d7a32ba45d 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -105,7 +105,7 @@ pub(crate) mod native { (Transport::Ws, Ok(SecProtocol::Tls), Ok(Muxer::Yamux)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(libp2p_tls::Config::new, yamux::Config::default) + .with_websocket(tls::Config::new, yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? .build(); @@ -114,7 +114,7 @@ pub(crate) mod native { (Transport::Ws, Ok(SecProtocol::Tls), Ok(Muxer::Mplex)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(libp2p_tls::Config::new, mplex::MplexConfig::default) + .with_websocket(tls::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? .build(); @@ -123,7 +123,7 @@ pub(crate) mod native { (Transport::Ws, Ok(SecProtocol::Noise), Ok(Muxer::Yamux)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(libp2p_tls::Config::new, yamux::Config::default) + .with_websocket(tls::Config::new, yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? .build(); @@ -132,7 +132,7 @@ pub(crate) mod native { (Transport::Ws, Ok(SecProtocol::Noise), Ok(Muxer::Mplex)) => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(libp2p_tls::Config::new, mplex::MplexConfig::default) + .with_websocket(tls::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? .build(); From 371b380cae3a09b5eadf4f5cfe5eb98339021c0d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:38:51 +0200 Subject: [PATCH 145/171] Require errors to be 'static --- libp2p/src/builder/phase/behaviour.rs | 2 +- libp2p/src/builder/phase/other_transport.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libp2p/src/builder/phase/behaviour.rs b/libp2p/src/builder/phase/behaviour.rs index e29c290f458..939db935c80 100644 --- a/libp2p/src/builder/phase/behaviour.rs +++ b/libp2p/src/builder/phase/behaviour.rs @@ -87,4 +87,4 @@ impl private::Sealed #[derive(Debug, thiserror::Error)] #[error("failed to build behaviour: {0}")] -pub struct BehaviourError(Box); +pub struct BehaviourError(Box); diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index 7a3046dc3c9..ec537e75965 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -198,4 +198,4 @@ impl private::Sealed #[derive(Debug, thiserror::Error)] #[error("failed to build transport: {0}")] -pub struct TransportError(Box); +pub struct TransportError(Box); From a5dc83c1e0dbfc92e282a93092e335cf87ab6319 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:41:51 +0200 Subject: [PATCH 146/171] Extend license header --- libp2p/src/builder/select_security.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/libp2p/src/builder/select_security.rs b/libp2p/src/builder/select_security.rs index 472d69053f0..91dbae869c6 100644 --- a/libp2p/src/builder/select_security.rs +++ b/libp2p/src/builder/select_security.rs @@ -1,3 +1,4 @@ +// Copyright 2023 Protocol Labs. // Copyright 2018 Parity Technologies (UK) Ltd. // // Permission is hereby granted, free of charge, to any person obtaining a From 8c12ec51bb4a7729eb8477fdaaed7e6d714f24dc Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:43:43 +0200 Subject: [PATCH 147/171] Use libp2p_tcp::Config::default() --- libp2p/src/tutorials/ping.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libp2p/src/tutorials/ping.rs b/libp2p/src/tutorials/ping.rs index 0e46d40a4bd..f1f3d7703aa 100644 --- a/libp2p/src/tutorials/ping.rs +++ b/libp2p/src/tutorials/ping.rs @@ -100,7 +100,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( -//! Default::default(), +//! libp2p_tcp::Config::default(), //! libp2p_tls::Config::new, //! libp2p_yamux::Config::default, //! )?; @@ -141,7 +141,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( -//! Default::default(), +//! libp2p_tcp::Config::default(), //! libp2p_tls::Config::new, //! libp2p_yamux::Config::default, //! )? @@ -172,7 +172,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( -//! Default::default(), +//! libp2p_tcp::Config::default(), //! libp2p_tls::Config::new, //! libp2p_yamux::Config::default, //! )? @@ -255,7 +255,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( -//! Default::default(), +//! libp2p_tcp::Config::default(), //! libp2p_tls::Config::new, //! libp2p_yamux::Config::default, //! )? @@ -296,7 +296,7 @@ //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( -//! Default::default(), +//! libp2p_tcp::Config::default(), //! libp2p_tls::Config::new, //! libp2p_yamux::Config::default, //! )? From 5f060b4ef2e9722d03fdd099a3254ee9524d734a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:48:39 +0200 Subject: [PATCH 148/171] Fix bad merge --- misc/server/src/main.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/misc/server/src/main.rs b/misc/server/src/main.rs index 5aed20840e5..97abad48bb3 100644 --- a/misc/server/src/main.rs +++ b/misc/server/src/main.rs @@ -1,6 +1,5 @@ use base64::Engine; use clap::Parser; -use futures::executor::block_on; use futures::stream::StreamExt; use futures_timer::Delay; use libp2p::identity; @@ -17,7 +16,6 @@ use std::error::Error; use std::path::PathBuf; use std::str::FromStr; use std::task::Poll; -use std::thread; use std::time::Duration; use zeroize::Zeroizing; @@ -120,11 +118,10 @@ async fn main() -> Result<(), Box> { "A metric with a constant '1' value labeled by version", build_info, ); - thread::spawn(move || { - block_on(http_service::metrics_server( - metric_registry, - opt.metrics_path, - )) + tokio::spawn(async move { + if let Err(e) = http_service::metrics_server(metric_registry, opt.metrics_path).await { + log::error!("Metrics server failed: {e}"); + } }); let mut bootstrap_timer = Delay::new(BOOTSTRAP_INTERVAL); From 0058b0258bd0f89a4e2fb26ee8d626ef2aa9f34d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 17:49:59 +0200 Subject: [PATCH 149/171] Reduce diff --- misc/server/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/misc/server/src/main.rs b/misc/server/src/main.rs index 97abad48bb3..ef0b6d9534a 100644 --- a/misc/server/src/main.rs +++ b/misc/server/src/main.rs @@ -99,6 +99,7 @@ async fn main() -> Result<(), Box> { Err(e) => return Err(e.into()), } } + if config.addresses.append_announce.is_empty() { warn!("No external addresses configured."); } From e0a4a8e382d41aa42dd79644b7e18334b12487b9 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 19:05:52 +0200 Subject: [PATCH 150/171] Use new SwarmBuilder in examples/browser-webrtc wasm --- examples/browser-webrtc/src/lib.rs | 20 ++++----- libp2p/src/builder/phase/swarm.rs | 70 ++++++++---------------------- 2 files changed, 26 insertions(+), 64 deletions(-) diff --git a/examples/browser-webrtc/src/lib.rs b/examples/browser-webrtc/src/lib.rs index 1a9856dadcc..88420805901 100644 --- a/examples/browser-webrtc/src/lib.rs +++ b/examples/browser-webrtc/src/lib.rs @@ -18,19 +18,17 @@ pub async fn run(libp2p_endpoint: String) -> Result<(), JsError> { let body = Body::from_current_window()?; body.append_p("Let's ping the WebRTC Server!")?; - let local_key = Keypair::generate_ed25519(); - let local_peer_id = PeerId::from(local_key.public()); - let mut swarm = SwarmBuilder::with_wasm_executor( - libp2p_webrtc_websys::Transport::new(libp2p_webrtc_websys::Config::new(&local_key)).boxed(), - Behaviour { + let swarm = libp2p::SwarmBuilder::with_new_identity() + .with_wasm_bindgen() + .with_other_transport(|key| { + libp2p_webrtc_websys::Transport::new(libp2p_webrtc_websys::Config::new(&key)) + .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) + })? + .with_behaviour(|_| Behaviour { ping: ping::Behaviour::new(ping::Config::new()), keep_alive: keep_alive::Behaviour, - }, - local_peer_id, - ) - .build(); - - log::info!("Initialize swarm with identity: {local_peer_id}"); + })? + .build(); let addr = libp2p_endpoint.parse::()?; log::info!("Dialing {addr}"); diff --git a/libp2p/src/builder/phase/swarm.rs b/libp2p/src/builder/phase/swarm.rs index 07526f28cbe..bd58512f307 100644 --- a/libp2p/src/builder/phase/swarm.rs +++ b/libp2p/src/builder/phase/swarm.rs @@ -26,72 +26,36 @@ macro_rules! impl_with_swarm_config { phantom: PhantomData, } } + + // Shortcuts + pub fn build(self) -> Swarm + where + B: NetworkBehaviour, + T: AuthenticatedMultiplexedTransport, + { + self.with_swarm_config(std::convert::identity).build() + } } }; } +#[cfg(not(target_arch = "wasm32"))] impl_with_swarm_config!( "async-std", super::provider::AsyncStd, libp2p_swarm::Config::with_async_std_executor() ); +#[cfg(not(target_arch = "wasm32"))] impl_with_swarm_config!( "tokio", super::provider::Tokio, libp2p_swarm::Config::with_tokio_executor() ); -#[cfg(all(not(target_arch = "wasm32"), feature = "async-std"))] -impl - SwarmBuilder> -{ - pub fn build(self) -> Swarm { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: libp2p_swarm::Config::with_async_std_executor(), - }, - keypair: self.keypair, - phantom: PhantomData::, - } - .build() - } -} - -#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))] -impl - SwarmBuilder> -{ - pub fn build(self) -> Swarm { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: libp2p_swarm::Config::with_tokio_executor(), - }, - keypair: self.keypair, - phantom: PhantomData::, - } - .build() - } -} - -#[cfg(feature = "wasm-bindgen")] -impl - SwarmBuilder> -{ - pub fn build(self) -> Swarm { - SwarmBuilder { - phase: BuildPhase { - behaviour: self.phase.behaviour, - transport: self.phase.transport, - swarm_config: libp2p_swarm::Config::with_wasm_executor(), - }, - keypair: self.keypair, - phantom: PhantomData::, - } - .build() - } -} +#[cfg(target_arch = "wasm32")] +impl_with_swarm_config!( + "wasm-bindgen", + super::provider::WasmBindgen, + libp2p_swarm::Config::with_wasm_executor() +); From 20bdf2cafb6426a9ec1a2eb9a67e8c128a49206f Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 4 Oct 2023 15:20:13 +0200 Subject: [PATCH 151/171] Update libp2p/src/tutorials/ping.rs Co-authored-by: Thomas Eizinger --- libp2p/src/tutorials/ping.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/src/tutorials/ping.rs b/libp2p/src/tutorials/ping.rs index f1f3d7703aa..f67ddd301b2 100644 --- a/libp2p/src/tutorials/ping.rs +++ b/libp2p/src/tutorials/ping.rs @@ -154,7 +154,7 @@ //! ## Swarm //! //! Now that we have a [`Transport`] and a [`NetworkBehaviour`], we can build the [`Swarm`] -//! whcihconnects the two, allowing both to make progress. Put simply, a [`Swarm`] drives both a +//! which connects the two, allowing both to make progress. Put simply, a [`Swarm`] drives both a //! [`Transport`] and a [`NetworkBehaviour`] forward, passing commands from the [`NetworkBehaviour`] //! to the [`Transport`] as well as events from the [`Transport`] to the [`NetworkBehaviour`]. As you can see, after [`Swarm`] initialization, we //! removed the print of the local [`PeerId`](crate::PeerId) because every time a [`Swarm`] is From fa90d63260d888de827d0662d768049dd2dec721 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 3 Oct 2023 19:20:13 +0200 Subject: [PATCH 152/171] fmt --- protocols/kad/src/behaviour/test.rs | 8 ++++++-- swarm-test/src/lib.rs | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index c4b14415d86..79826d2653b 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -67,8 +67,12 @@ fn build_node_with_config(cfg: Config) -> (Multiaddr, TestSwarm) { let store = MemoryStore::new(local_id); let behaviour = Behaviour::with_config(local_id, store, cfg); - let mut swarm = - Swarm::new(transport, behaviour, local_id, swarm::Config::with_async_std_executor()); + let mut swarm = Swarm::new( + transport, + behaviour, + local_id, + swarm::Config::with_async_std_executor(), + ); let address: Multiaddr = Protocol::Memory(random::()).into(); swarm.listen_on(address.clone()).unwrap(); diff --git a/swarm-test/src/lib.rs b/swarm-test/src/lib.rs index 670b9a146ab..41a606b300c 100644 --- a/swarm-test/src/lib.rs +++ b/swarm-test/src/lib.rs @@ -220,7 +220,8 @@ where transport, behaviour_fn(identity), peer_id, - swarm::Config::with_async_std_executor().with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., + swarm::Config::with_async_std_executor() + .with_idle_connection_timeout(Duration::from_secs(5)), // Some tests need connections to be kept alive beyond what the individual behaviour configures., ) } From 6be89c9c64c9384cb31278b0163a5c628fb86ff2 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 4 Oct 2023 15:14:27 +0200 Subject: [PATCH 153/171] Use webrtc_websys module --- examples/browser-webrtc/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/browser-webrtc/src/lib.rs b/examples/browser-webrtc/src/lib.rs index 88420805901..dc54a2a0dbe 100644 --- a/examples/browser-webrtc/src/lib.rs +++ b/examples/browser-webrtc/src/lib.rs @@ -6,6 +6,7 @@ use libp2p::core::Multiaddr; use libp2p::identity::{Keypair, PeerId}; use libp2p::ping; use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmBuilder, SwarmEvent}; +use libp2p::webrtc_websys; use std::convert::From; use std::io; use wasm_bindgen::prelude::*; @@ -21,7 +22,7 @@ pub async fn run(libp2p_endpoint: String) -> Result<(), JsError> { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_wasm_bindgen() .with_other_transport(|key| { - libp2p_webrtc_websys::Transport::new(libp2p_webrtc_websys::Config::new(&key)) + webrtc_websys::Transport::new(webrtc_websys::Config::new(&key)) .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) })? .with_behaviour(|_| Behaviour { From 04929dbe499c5b2fc3d358431614d0e1a8fb049b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 4 Oct 2023 15:14:43 +0200 Subject: [PATCH 154/171] Use with_tokio_executor --- transports/tls/tests/smoke.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transports/tls/tests/smoke.rs b/transports/tls/tests/smoke.rs index b5195da8009..d488ae7846a 100644 --- a/transports/tls/tests/smoke.rs +++ b/transports/tls/tests/smoke.rs @@ -69,6 +69,6 @@ fn make_swarm() -> Swarm { transport, dummy::Behaviour, identity.public().to_peer_id(), - Config::without_executor().with_idle_connection_timeout(Duration::from_secs(60)), + Config::with_tokio_executor().with_idle_connection_timeout(Duration::from_secs(60)), ) } From 3717d1fe2a3b0e2514c35b600073516791dcbf00 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 4 Oct 2023 15:28:07 +0200 Subject: [PATCH 155/171] Re-introduce env_logger and fix idle timeout --- libp2p/src/tutorials/ping.rs | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/libp2p/src/tutorials/ping.rs b/libp2p/src/tutorials/ping.rs index f67ddd301b2..dcb0715399a 100644 --- a/libp2p/src/tutorials/ping.rs +++ b/libp2p/src/tutorials/ping.rs @@ -75,6 +75,8 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { +//! env_logger::init(); +//! //! let mut swarm = libp2p::SwarmBuilder::with_new_identity(); //! //! Ok(()) @@ -97,6 +99,8 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { +//! env_logger::init(); +//! //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( @@ -138,6 +142,8 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { +//! env_logger::init(); +//! //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( @@ -156,11 +162,7 @@ //! Now that we have a [`Transport`] and a [`NetworkBehaviour`], we can build the [`Swarm`] //! which connects the two, allowing both to make progress. Put simply, a [`Swarm`] drives both a //! [`Transport`] and a [`NetworkBehaviour`] forward, passing commands from the [`NetworkBehaviour`] -//! to the [`Transport`] as well as events from the [`Transport`] to the [`NetworkBehaviour`]. As you can see, after [`Swarm`] initialization, we -//! removed the print of the local [`PeerId`](crate::PeerId) because every time a [`Swarm`] is -//! created, it prints the local [`PeerId`](crate::PeerId) in the logs at the INFO level. In order -//! to continue to see the local [`PeerId`](crate::PeerId) you must initialize the logger -//! (In our example, `env_logger` is used) +//! to the [`Transport`] as well as events from the [`Transport`] to the [`NetworkBehaviour`]. //! //! ```rust //! use libp2p::swarm::{NetworkBehaviour, SwarmBuilder}; @@ -169,6 +171,8 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { +//! env_logger::init(); +//! //! let mut swarm = libp2p::SwarmBuilder::with_new_identity() //! .with_async_std() //! .with_tcp( @@ -201,17 +205,17 @@ //! //! #[async_std::main] //! async fn main() -> Result<(), Box> { -//! use std::time::Duration; -//! let local_key = identity::Keypair::generate_ed25519(); -//! let local_peer_id = PeerId::from(local_key.public()); -//! println!("Local peer id: {local_peer_id:?}"); +//! env_logger::init(); //! -//! let transport = libp2p::development_transport(local_key).await?; -//! -//! let behaviour = ping::Behaviour::default(); -//! -//! let mut swarm = SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id) -//! .idle_connection_timeout(Duration::from_secs(30)) // Allows us to observe pings for 30 seconds. +//! let mut swarm = libp2p::SwarmBuilder::with_new_identity() +//! .with_async_std() +//! .with_tcp( +//! libp2p_tcp::Config::default(), +//! libp2p_tls::Config::new, +//! libp2p_yamux::Config::default, +//! )? +//! .with_behaviour(|_| ping::Behaviour::default())? +//! .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(30))) // Allows us to observe pings for 30 seconds. //! .build(); //! //! Ok(()) @@ -260,6 +264,7 @@ //! libp2p_yamux::Config::default, //! )? //! .with_behaviour(|_| ping::Behaviour::default())? +//! .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(30))) // Allows us to observe pings for 30 seconds. //! .build(); //! //! // Tell the swarm to listen on all interfaces and a random, OS-assigned @@ -301,6 +306,7 @@ //! libp2p_yamux::Config::default, //! )? //! .with_behaviour(|_| ping::Behaviour::default())? +//! .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(30))) // Allows us to observe pings for 30 seconds. //! .build(); //! //! // Tell the swarm to listen on all interfaces and a random, OS-assigned From bb91e8ba28adca30ebd3078bfdf6875afff8d556 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 4 Oct 2023 15:30:27 +0200 Subject: [PATCH 156/171] Remove duplicate peer id printing --- misc/server/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/misc/server/src/main.rs b/misc/server/src/main.rs index ef0b6d9534a..ee2d7610f38 100644 --- a/misc/server/src/main.rs +++ b/misc/server/src/main.rs @@ -68,7 +68,6 @@ async fn main() -> Result<(), Box> { (peer_id, keypair) }; - info!("Local peer id: {local_peer_id}"); let mut swarm = libp2p::SwarmBuilder::with_existing_identity(local_keypair) .with_tokio() From 5014087aef6616e52ae6734bd16ab14a200e3264 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 8 Oct 2023 18:32:17 +0200 Subject: [PATCH 157/171] Don't require StreamMuxerBox in with_other_transport --- examples/browser-webrtc/src/lib.rs | 1 - examples/ipfs-private/src/main.rs | 3 +- interop-tests/src/arch.rs | 8 ++--- libp2p/src/builder.rs | 21 ++++++----- libp2p/src/builder/phase/other_transport.rs | 39 +++++++++++---------- libp2p/src/builder/phase/quic.rs | 12 +++++-- libp2p/src/builder/phase/tcp.rs | 12 +++++-- 7 files changed, 57 insertions(+), 39 deletions(-) diff --git a/examples/browser-webrtc/src/lib.rs b/examples/browser-webrtc/src/lib.rs index dc54a2a0dbe..ef0fd1d0b58 100644 --- a/examples/browser-webrtc/src/lib.rs +++ b/examples/browser-webrtc/src/lib.rs @@ -23,7 +23,6 @@ pub async fn run(libp2p_endpoint: String) -> Result<(), JsError> { .with_wasm_bindgen() .with_other_transport(|key| { webrtc_websys::Transport::new(webrtc_websys::Config::new(&key)) - .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) })? .with_behaviour(|_| Behaviour { ping: ping::Behaviour::new(ping::Config::new()), diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 997399db848..a765f681f8a 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -24,7 +24,7 @@ use async_std::io; use either::Either; use futures::{prelude::*, select}; use libp2p::{ - core::{muxing::StreamMuxerBox, transport::upgrade::Version}, + core::transport::upgrade::Version, gossipsub, identify, multiaddr::Protocol, noise, ping, @@ -129,7 +129,6 @@ async fn main() -> Result<(), Box> { .upgrade(Version::V1Lazy) .authenticate(noise_config) .multiplex(yamux_config) - .map(|(peer_id, muxer), _| (peer_id, StreamMuxerBox::new(muxer))) })? .with_dns() .await? diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 3d7a32ba45d..b03d8280c6d 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -14,10 +14,9 @@ pub(crate) mod native { use env_logger::{Env, Target}; use futures::future::BoxFuture; use futures::FutureExt; - use libp2p::core::muxing::StreamMuxerBox; use libp2p::identity::Keypair; use libp2p::swarm::{NetworkBehaviour, Swarm}; - use libp2p::{noise, tcp, tls, yamux, Transport as _}; + use libp2p::{noise, tcp, tls, yamux}; use libp2p_mplex as mplex; use libp2p_webrtc as webrtc; use redis::AsyncCommands; @@ -145,8 +144,7 @@ pub(crate) mod native { Ok(webrtc::tokio::Transport::new( key.clone(), webrtc::tokio::Certificate::generate(&mut rand::thread_rng())?, - ) - .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn)))) + )) })? .with_behaviour(behaviour_constructor)? .build(); @@ -189,7 +187,6 @@ pub(crate) mod native { pub(crate) mod wasm { use anyhow::{bail, Result}; use futures::future::{BoxFuture, FutureExt}; - use libp2p::core::muxing::StreamMuxerBox; use libp2p::identity::Keypair; use libp2p::swarm::{NetworkBehaviour, Swarm}; use libp2p::Transport as _; @@ -222,7 +219,6 @@ pub(crate) mod wasm { libp2p::webtransport_websys::Transport::new( libp2p::webtransport_websys::Config::new(key), ) - .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) })? .with_behaviour(behaviour_constructor)? .build(); diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 288a228bee8..1e907d56ab9 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -224,18 +224,23 @@ mod tests { #[test] #[cfg(feature = "tokio")] fn other_transport() -> Result<(), Box> { + use libp2p_core::{muxing::StreamMuxerBox, transport::dummy::DummyTransport}; + use libp2p_identity::PeerId; + let _ = SwarmBuilder::with_new_identity() .with_tokio() // Closure can either return a Transport directly. - .with_other_transport(|_| libp2p_core::transport::dummy::DummyTransport::new())? + .with_other_transport(|_| DummyTransport::<(PeerId, StreamMuxerBox)>::new())? // Or a Result containing a Transport. - .with_other_transport(|_| { - if true { - Ok(libp2p_core::transport::dummy::DummyTransport::new()) - } else { - Err(Box::from("test")) - } - })? + .with_other_transport( + |_| { + if true { + Ok(DummyTransport::<(PeerId, StreamMuxerBox)>::new()) + } else { + Err(Box::from("test")) + } + }, + )? .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .unwrap() .build(); diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index ec537e75965..e5c8269e35b 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use libp2p_core::Transport; #[cfg(feature = "relay")] -use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, StreamMuxer, UpgradeInfo}; +use libp2p_core::{InboundUpgrade, Negotiated, OutboundUpgrade, UpgradeInfo}; #[cfg(feature = "relay")] use libp2p_identity::PeerId; @@ -21,7 +21,8 @@ impl SwarmBuilder> { pub fn with_other_transport< - OtherTransport: AuthenticatedMultiplexedTransport, + Muxer: libp2p_core::muxing::StreamMuxer + Send + 'static, + OtherTransport: Transport + Send + Unpin + 'static, R: TryIntoTransport, >( self, @@ -29,13 +30,24 @@ impl ) -> Result< SwarmBuilder>, R::Error, - > { + > + where + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, + ::Substream: Send, + ::Error: Send + Sync, + { Ok(SwarmBuilder { phase: OtherTransportPhase { transport: self .phase .transport - .or_transport(constructor(&self.keypair).try_into_transport()?) + .or_transport( + constructor(&self.keypair) + .try_into_transport()? + .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))), + ) .map(|either, _| either.into_inner()), }, keypair: self.keypair, @@ -106,7 +118,7 @@ impl <<>::Upgrade as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send, <>::Upgrade as UpgradeInfo>::Info: Send, - MuxStream: StreamMuxer + Send + 'static, + MuxStream: libp2p_core::muxing::StreamMuxer + Send + 'static, MuxStream::Substream: Send + 'static, MuxStream::Error: Send + Sync + 'static, MuxUpgrade: IntoMultiplexerUpgrade, @@ -163,10 +175,7 @@ pub trait TryIntoTransport: private::Sealed { fn try_into_transport(self) -> Result; } -impl TryIntoTransport for T -where - T: AuthenticatedMultiplexedTransport, -{ +impl TryIntoTransport for T { type Error = Infallible; fn try_into_transport(self) -> Result { @@ -174,10 +183,7 @@ where } } -impl TryIntoTransport for Result> -where - T: AuthenticatedMultiplexedTransport, -{ +impl TryIntoTransport for Result> { type Error = TransportError; fn try_into_transport(self) -> Result { @@ -189,12 +195,9 @@ mod private { pub trait Sealed {} } -impl private::Sealed for T {} +impl private::Sealed for T {} -impl private::Sealed - for Result> -{ -} +impl private::Sealed for Result> {} #[derive(Debug, thiserror::Error)] #[error("failed to build transport: {0}")] diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index bffe2bf08d4..b59dffd0b2c 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -111,7 +111,8 @@ impl SwarmBuilder + Send + Unpin + 'static, R: TryIntoTransport, >( self, @@ -119,7 +120,14 @@ impl SwarmBuilder Result< SwarmBuilder>, R::Error, - > { + > + where + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, + ::Substream: Send, + ::Error: Send + Sync, + { self.without_quic().with_other_transport(constructor) } diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index 26137c00d0e..3276e0bf1a1 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -118,7 +118,8 @@ impl SwarmBuilder { } impl SwarmBuilder { pub fn with_other_transport< - OtherTransport: AuthenticatedMultiplexedTransport, + Muxer: libp2p_core::muxing::StreamMuxer + Send + 'static, + OtherTransport: Transport + Send + Unpin + 'static, R: TryIntoTransport, >( self, @@ -126,7 +127,14 @@ impl SwarmBuilder { ) -> Result< SwarmBuilder>, R::Error, - > { + > + where + ::Error: Send + Sync + 'static, + ::Dial: Send, + ::ListenerUpgrade: Send, + ::Substream: Send, + ::Error: Send + Sync, + { self.without_tcp() .without_quic() .with_other_transport(constructor) From aec063de4df0129ee4ba22fd86e90cae3b8e5e82 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 8 Oct 2023 18:32:59 +0200 Subject: [PATCH 158/171] fmt --- libp2p/src/builder.rs | 16 +++++++--------- libp2p/src/builder/phase/other_transport.rs | 5 ++++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 1e907d56ab9..84782fb3a8d 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -232,15 +232,13 @@ mod tests { // Closure can either return a Transport directly. .with_other_transport(|_| DummyTransport::<(PeerId, StreamMuxerBox)>::new())? // Or a Result containing a Transport. - .with_other_transport( - |_| { - if true { - Ok(DummyTransport::<(PeerId, StreamMuxerBox)>::new()) - } else { - Err(Box::from("test")) - } - }, - )? + .with_other_transport(|_| { + if true { + Ok(DummyTransport::<(PeerId, StreamMuxerBox)>::new()) + } else { + Err(Box::from("test")) + } + })? .with_behaviour(|_| libp2p_swarm::dummy::Behaviour) .unwrap() .build(); diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index e5c8269e35b..11b929a0b5d 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -197,7 +197,10 @@ mod private { impl private::Sealed for T {} -impl private::Sealed for Result> {} +impl private::Sealed + for Result> +{ +} #[derive(Debug, thiserror::Error)] #[error("failed to build transport: {0}")] From 19d4f2106b1cf1cd6d66f5512963fa7a0cde8aa3 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 8 Oct 2023 19:55:05 +0200 Subject: [PATCH 159/171] Minor follow-ups --- examples/ipfs-private/src/main.rs | 2 -- examples/rendezvous/src/bin/rzv-discover.rs | 2 +- examples/rendezvous/src/bin/rzv-identify.rs | 2 +- libp2p/src/builder.rs | 4 ++++ 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index feb3c27b66a..861648fecdd 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -150,8 +150,6 @@ async fn main() -> Result<(), Box> { })? .build(); - println!("using random peer id: {:?}", swarm.local_peer_id()); - println!("Subscribing to {gossipsub_topic:?}"); swarm .behaviour_mut() diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index da32e6d7f09..69eae25f34d 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -51,7 +51,7 @@ async fn main() -> Result<(), Box> { ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), }) .unwrap() - // TODO .idle_connection_timeout(Duration::from_secs(5)) + .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5))) .build(); swarm.dial(rendezvous_point_address.clone()).unwrap(); diff --git a/examples/rendezvous/src/bin/rzv-identify.rs b/examples/rendezvous/src/bin/rzv-identify.rs index 0fe66ab3a1a..be644dbb9f8 100644 --- a/examples/rendezvous/src/bin/rzv-identify.rs +++ b/examples/rendezvous/src/bin/rzv-identify.rs @@ -52,7 +52,7 @@ async fn main() { ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), }) .unwrap() - // TODO .idle_connection_timeout(Duration::from_secs(5)) + .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5))) .build(); let _ = swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap()); diff --git a/libp2p/src/builder.rs b/libp2p/src/builder.rs index 84782fb3a8d..1b07689d2f6 100644 --- a/libp2p/src/builder.rs +++ b/libp2p/src/builder.rs @@ -9,6 +9,9 @@ mod select_security; /// /// ``` /// # use libp2p::{swarm::NetworkBehaviour, SwarmBuilder}; +/// # use libp2p::core::transport::dummy::DummyTransport; +/// # use libp2p::core::muxing::StreamMuxerBox; +/// # use libp2p::identity::PeerId; /// # use std::error::Error; /// # /// # #[cfg(all( @@ -37,6 +40,7 @@ mod select_security; /// libp2p_yamux::Config::default, /// )? /// .with_quic() +/// .with_other_transport(|_key| DummyTransport::<(PeerId, StreamMuxerBox)>::new())? /// .with_dns()? /// .with_relay_client( /// (libp2p_tls::Config::new, libp2p_noise::Config::new), From 766c87704f8d3bb0538debaf4e3b4254160dd60b Mon Sep 17 00:00:00 2001 From: Max Inden Date: Sun, 8 Oct 2023 20:07:06 +0200 Subject: [PATCH 160/171] Fix wasm arch --- interop-tests/src/arch.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index b03d8280c6d..c93fe49f318 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -227,10 +227,7 @@ pub(crate) mod wasm { Transport::WebRtcDirect => { let swarm = libp2p::SwarmBuilder::with_new_identity() .with_wasm_bindgen() - .with_other_transport(|key| { - webrtc::Transport::new(webrtc::Config::new(&key)) - .map(|(peer_id, conn), _| (peer_id, StreamMuxerBox::new(conn))) - })? + .with_other_transport(|key| webrtc::Transport::new(webrtc::Config::new(&key)))? .with_behaviour(behaviour_constructor)? .build(); return Ok((swarm, format!("/ip4/{ip}/udp/0/webrtc-direct"))); From 9afde0341bf20c7899da163dad7b36cf1df72216 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 9 Oct 2023 15:03:57 +0200 Subject: [PATCH 161/171] Use #[allow(unused_imports)] --- libp2p/src/builder/phase.rs | 11 +++++++---- libp2p/src/builder/phase/build.rs | 2 ++ libp2p/src/builder/phase/provider.rs | 9 +++++---- libp2p/src/builder/phase/swarm.rs | 11 +++++------ libp2p/src/lib.rs | 5 +++-- transports/tls/Cargo.toml | 2 +- 6 files changed, 23 insertions(+), 17 deletions(-) diff --git a/libp2p/src/builder/phase.rs b/libp2p/src/builder/phase.rs index 85d6ab86b5a..dbf9eb883ae 100644 --- a/libp2p/src/builder/phase.rs +++ b/libp2p/src/builder/phase.rs @@ -1,7 +1,4 @@ -use libp2p_core::{muxing::StreamMuxerBox, upgrade::SelectUpgrade, Transport}; -use libp2p_identity::Keypair; - -use super::select_security::SelectSecurityUpgrade; +#![allow(unused_imports)] mod bandwidth_logging; mod behaviour; @@ -28,6 +25,12 @@ use swarm::*; use tcp::*; use websocket::*; +use super::select_security::SelectSecurityUpgrade; +use super::SwarmBuilder; + +use libp2p_core::{muxing::StreamMuxerBox, upgrade::SelectUpgrade, Transport}; +use libp2p_identity::Keypair; + pub trait IntoSecurityUpgrade { type Upgrade; type Error; diff --git a/libp2p/src/builder/phase/build.rs b/libp2p/src/builder/phase/build.rs index 5b9551c33f3..80a83994eeb 100644 --- a/libp2p/src/builder/phase/build.rs +++ b/libp2p/src/builder/phase/build.rs @@ -1,4 +1,6 @@ +#[allow(unused_imports)] use super::*; + use crate::SwarmBuilder; use libp2p_core::Transport; use libp2p_swarm::Swarm; diff --git a/libp2p/src/builder/phase/provider.rs b/libp2p/src/builder/phase/provider.rs index c976cb4f418..32321442689 100644 --- a/libp2p/src/builder/phase/provider.rs +++ b/libp2p/src/builder/phase/provider.rs @@ -1,6 +1,7 @@ +#[allow(unused_imports)] use super::*; + use crate::SwarmBuilder; -use std::marker::PhantomData; pub struct ProviderPhase {} @@ -9,7 +10,7 @@ impl SwarmBuilder { pub fn with_async_std(self) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, - phantom: PhantomData, + phantom: std::marker::PhantomData, phase: TcpPhase {}, } } @@ -18,7 +19,7 @@ impl SwarmBuilder { pub fn with_tokio(self) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, - phantom: PhantomData, + phantom: std::marker::PhantomData, phase: TcpPhase {}, } } @@ -27,7 +28,7 @@ impl SwarmBuilder { pub fn with_wasm_bindgen(self) -> SwarmBuilder { SwarmBuilder { keypair: self.keypair, - phantom: PhantomData, + phantom: std::marker::PhantomData, phase: TcpPhase {}, } } diff --git a/libp2p/src/builder/phase/swarm.rs b/libp2p/src/builder/phase/swarm.rs index bd58512f307..ee456ced927 100644 --- a/libp2p/src/builder/phase/swarm.rs +++ b/libp2p/src/builder/phase/swarm.rs @@ -1,8 +1,7 @@ +#[allow(unused_imports)] use super::*; -use crate::SwarmBuilder; -use libp2p_swarm::{NetworkBehaviour, Swarm}; -use std::marker::PhantomData; +#[allow(dead_code)] pub struct SwarmPhase { pub(crate) behaviour: B, pub(crate) transport: T, @@ -23,14 +22,14 @@ macro_rules! impl_with_swarm_config { swarm_config: constructor($config), }, keypair: self.keypair, - phantom: PhantomData, + phantom: std::marker::PhantomData, } } // Shortcuts - pub fn build(self) -> Swarm + pub fn build(self) -> libp2p_swarm::Swarm where - B: NetworkBehaviour, + B: libp2p_swarm::NetworkBehaviour, T: AuthenticatedMultiplexedTransport, { self.with_swarm_config(std::convert::identity).build() diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 85fa2b53f04..68bc9bf5850 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -22,8 +22,9 @@ //! //! To learn more about the general libp2p multi-language framework visit . //! -//! To get started with this libp2p implementation in Rust, please take a look at the [`tutorials`]. -//! Further examples can be found in the [examples] directory. +//! To get started with this libp2p implementation in Rust, please take a look +//! at the [`tutorials`]. Further examples can be found in the +//! [examples] directory. //! //! [examples]: https://github.com/libp2p/rust-libp2p/tree/master/examples diff --git a/transports/tls/Cargo.toml b/transports/tls/Cargo.toml index b2ca28784f7..33f230678ff 100644 --- a/transports/tls/Cargo.toml +++ b/transports/tls/Cargo.toml @@ -31,7 +31,7 @@ hex = "0.4.3" hex-literal = "0.4.1" libp2p-core = { workspace = true } libp2p-identity = { workspace = true, features = ["ed25519", "rsa", "secp256k1", "ecdsa"] } -libp2p-swarm = { workspace = true } +libp2p-swarm = { workspace = true, features = ["tokio"] } libp2p-yamux = { workspace = true } tokio = { version = "1.32.0", features = ["full"] } From 334589e7ebe0040a8186ba83abdbb483a30f40d0 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 9 Oct 2023 15:06:02 +0200 Subject: [PATCH 162/171] Remove obsolete peer id print --- examples/dcutr/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 21254171a3f..f9ddb1e2ef1 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -105,8 +105,6 @@ async fn main() -> Result<(), Box> { })? .build(); - info!("Local peer id: {:?}", swarm.local_peer_id()); - swarm .listen_on("/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap()) .unwrap(); From c150965fdd78ed62797a4380adf1a8ad225dfd09 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 9 Oct 2023 15:06:46 +0200 Subject: [PATCH 163/171] Don't unwrap --- examples/rendezvous/src/bin/rzv-discover.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/rendezvous/src/bin/rzv-discover.rs b/examples/rendezvous/src/bin/rzv-discover.rs index 69eae25f34d..42a5a20b6ad 100644 --- a/examples/rendezvous/src/bin/rzv-discover.rs +++ b/examples/rendezvous/src/bin/rzv-discover.rs @@ -49,8 +49,7 @@ async fn main() -> Result<(), Box> { .with_behaviour(|key| MyBehaviour { rendezvous: rendezvous::client::Behaviour::new(key.clone()), ping: ping::Behaviour::new(ping::Config::new().with_interval(Duration::from_secs(1))), - }) - .unwrap() + })? .with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(5))) .build(); From 87808e2110ab7898eec2707154ac9cac2d17852e Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 9 Oct 2023 15:08:07 +0200 Subject: [PATCH 164/171] Remove obsolete comment --- libp2p/src/builder/phase/tcp.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index 3276e0bf1a1..2dce2c30eb9 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -83,10 +83,6 @@ impl SwarmBuilder { keypair: self.keypair, phantom: PhantomData, phase: QuicPhase { - // Note that this allows a user to build a faulty (i.e. dummy) transport only. - // Ideally the final build step would not exist unless one adds another transport - // after `without_tcp`. Though currently this would introduce significant - // complexity to each following step. transport: libp2p_core::transport::dummy::DummyTransport::new(), }, } From e0029e485f24981bc505ec584763ca2f2f479308 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 9 Oct 2023 15:23:03 +0200 Subject: [PATCH 165/171] Document with_tcp with_relay_client with_websocket taking function pointer --- libp2p/src/builder/phase/other_transport.rs | 1 + libp2p/src/builder/phase/quic.rs | 2 ++ libp2p/src/builder/phase/relay.rs | 25 +++++++++++++++++++++ libp2p/src/builder/phase/tcp.rs | 22 ++++++++++++++++++ libp2p/src/builder/phase/websocket.rs | 21 +++++++++++++++++ 5 files changed, 71 insertions(+) diff --git a/libp2p/src/builder/phase/other_transport.rs b/libp2p/src/builder/phase/other_transport.rs index 11b929a0b5d..6a050f4f2de 100644 --- a/libp2p/src/builder/phase/other_transport.rs +++ b/libp2p/src/builder/phase/other_transport.rs @@ -97,6 +97,7 @@ impl impl SwarmBuilder> { + /// See [`SwarmBuilder::with_relay_client`]. pub fn with_relay_client( self, security_upgrade: SecUpgrade, diff --git a/libp2p/src/builder/phase/quic.rs b/libp2p/src/builder/phase/quic.rs index b59dffd0b2c..6ef056aeaf0 100644 --- a/libp2p/src/builder/phase/quic.rs +++ b/libp2p/src/builder/phase/quic.rs @@ -73,6 +73,7 @@ impl SwarmBuilder> { // Shortcuts impl SwarmBuilder> { + /// See [`SwarmBuilder::with_relay_client`]. #[cfg(feature = "relay")] pub fn with_relay_client( self, @@ -174,6 +175,7 @@ macro_rules! impl_quic_phase_with_websocket { ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => { #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] impl SwarmBuilder<$providerPascalCase, QuicPhase> { + /// See [`SwarmBuilder::with_websocket`]. pub async fn with_websocket < SecUpgrade, SecStream, diff --git a/libp2p/src/builder/phase/relay.rs b/libp2p/src/builder/phase/relay.rs index 8cde349404a..abfc58ec064 100644 --- a/libp2p/src/builder/phase/relay.rs +++ b/libp2p/src/builder/phase/relay.rs @@ -19,6 +19,31 @@ pub struct RelayPhase { #[cfg(feature = "relay")] impl SwarmBuilder> { + /// Adds a relay client transport. + /// + /// Note that both `security_upgrade` and `multiplexer_upgrade` take function pointers, + /// i.e. they take the function themselves (without the invocation via `()`), not the + /// result of the function invocation. See example below. + /// + /// ``` rust + /// # use libp2p::SwarmBuilder; + /// # use std::error::Error; + /// # async fn build_swarm() -> Result<(), Box> { + /// let swarm = SwarmBuilder::with_new_identity() + /// .with_tokio() + /// .with_tcp( + /// Default::default(), + /// (libp2p_tls::Config::new, libp2p_noise::Config::new), + /// libp2p_yamux::Config::default, + /// )? + /// .with_relay_client( + /// (libp2p_tls::Config::new, libp2p_noise::Config::new), + /// libp2p_yamux::Config::default, + /// )? + /// # ; + /// # Ok(()) + /// # } + /// ``` pub fn with_relay_client( self, security_upgrade: SecUpgrade, diff --git a/libp2p/src/builder/phase/tcp.rs b/libp2p/src/builder/phase/tcp.rs index 2dce2c30eb9..d2b69798252 100644 --- a/libp2p/src/builder/phase/tcp.rs +++ b/libp2p/src/builder/phase/tcp.rs @@ -24,6 +24,27 @@ macro_rules! impl_tcp_builder { feature = $providerKebabCase, ))] impl SwarmBuilder<$providerPascalCase, TcpPhase> { + /// Adds a TCP based transport. + /// + /// Note that both `security_upgrade` and `multiplexer_upgrade` take function pointers, + /// i.e. they take the function themselves (without the invocation via `()`), not the + /// result of the function invocation. See example below. + /// + /// ``` rust + /// # use libp2p::SwarmBuilder; + /// # use std::error::Error; + /// # async fn build_swarm() -> Result<(), Box> { + /// let swarm = SwarmBuilder::with_new_identity() + /// .with_tokio() + /// .with_tcp( + /// Default::default(), + /// (libp2p_tls::Config::new, libp2p_noise::Config::new), + /// libp2p_yamux::Config::default, + /// )? + /// # ; + /// # Ok(()) + /// # } + /// ``` pub fn with_tcp( self, tcp_config: libp2p_tcp::Config, @@ -140,6 +161,7 @@ macro_rules! impl_tcp_phase_with_websocket { ($providerKebabCase:literal, $providerPascalCase:ty, $websocketStream:ty) => { #[cfg(all(feature = $providerKebabCase, not(target_arch = "wasm32"), feature = "websocket"))] impl SwarmBuilder<$providerPascalCase, TcpPhase> { + /// See [`SwarmBuilder::with_websocket`]. pub async fn with_websocket < SecUpgrade, SecStream, diff --git a/libp2p/src/builder/phase/websocket.rs b/libp2p/src/builder/phase/websocket.rs index 7e21851f2f5..bc536b4a7d1 100644 --- a/libp2p/src/builder/phase/websocket.rs +++ b/libp2p/src/builder/phase/websocket.rs @@ -17,6 +17,27 @@ pub struct WebsocketPhase { macro_rules! impl_websocket_builder { ($providerKebabCase:literal, $providerPascalCase:ty, $dnsTcp:expr, $websocketStream:ty) => { + /// Adds a websocket client transport. + /// + /// Note that both `security_upgrade` and `multiplexer_upgrade` take function pointers, + /// i.e. they take the function themselves (without the invocation via `()`), not the + /// result of the function invocation. See example below. + /// + /// ``` rust + /// # use libp2p::SwarmBuilder; + /// # use std::error::Error; + /// # async fn build_swarm() -> Result<(), Box> { + /// let swarm = SwarmBuilder::with_new_identity() + /// .with_tokio() + /// .with_websocket( + /// (libp2p_tls::Config::new, libp2p_noise::Config::new), + /// libp2p_yamux::Config::default, + /// ) + /// .await? + /// # ; + /// # Ok(()) + /// # } + /// ``` #[cfg(all(not(target_arch = "wasm32"), feature = $providerKebabCase, feature = "websocket"))] impl SwarmBuilder<$providerPascalCase, WebsocketPhase> { pub async fn with_websocket< From a01570679594b4d72166967845a723764c155319 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 9 Oct 2023 15:34:02 +0200 Subject: [PATCH 166/171] Fix intra-doc link --- swarm/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 9e0be9032c1..52498156f1f 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -1476,7 +1476,7 @@ impl Config { /// negotiating inbound streams. The total number of inbound streams on a /// connection is the sum of negotiating and negotiated streams. A limit on /// the total number of streams can be enforced at the - /// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level. + /// [`StreamMuxerBox`] level. pub fn with_max_negotiating_inbound_streams(mut self, v: usize) -> Self { self.pool_config = self.pool_config.with_max_negotiating_inbound_streams(v); self From 59409d30ef218f6575be7c5c168c931e19d1f3fc Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 10 Oct 2023 15:29:17 +1100 Subject: [PATCH 167/171] Reduce diff --- interop-tests/src/arch.rs | 121 +++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 548cb67ebd5..e7de2eb352d 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -38,105 +38,105 @@ pub(crate) mod native { pub(crate) async fn build_swarm( ip: &str, transport: Transport, - security_protocol: Option, + sec_protocol: Option, muxer: Option, behaviour_constructor: impl FnOnce(&Keypair) -> B, ) -> Result<(Swarm, String)> { - let (swarm, addr) = match (transport, security_protocol, muxer) { - (Transport::QuicV1, None, None) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + let (swarm, addr) = match (transport, sec_protocol, muxer) { + (Transport::QuicV1, None, None) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_quic() .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/udp/0/quic-v1")) - } - (Transport::Tcp, Some(SecProtocol::Tls), Some(Muxer::Yamux)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/udp/0/quic-v1"), + ), + (Transport::Tcp, Some(SecProtocol::Tls), Some(Muxer::Mplex)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp( tcp::Config::default(), tls::Config::new, - yamux::Config::default, + mplex::MplexConfig::default, )? .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0")) - } - (Transport::Tcp, Some(SecProtocol::Tls), Some(Muxer::Mplex)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0"), + ), + (Transport::Tcp, Some(SecProtocol::Tls), Some(Muxer::Yamux)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp( tcp::Config::default(), tls::Config::new, - mplex::MplexConfig::default, + yamux::Config::default, )? .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0")) - } - (Transport::Tcp, Some(SecProtocol::Noise), Some(Muxer::Yamux)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0"), + ), + (Transport::Tcp, Some(SecProtocol::Noise), Some(Muxer::Mplex)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp( tcp::Config::default(), noise::Config::new, - yamux::Config::default, + mplex::MplexConfig::default, )? .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0")) - } - (Transport::Tcp, Some(SecProtocol::Noise), Some(Muxer::Mplex)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0"), + ), + (Transport::Tcp, Some(SecProtocol::Noise), Some(Muxer::Yamux)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_tcp( tcp::Config::default(), noise::Config::new, - mplex::MplexConfig::default, + yamux::Config::default, )? .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0")) - } - (Transport::Ws, Some(SecProtocol::Tls), Some(Muxer::Yamux)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() - .with_tokio() - .with_websocket(tls::Config::new, yamux::Config::default) - .await? - .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0/ws")) - } - (Transport::Ws, Some(SecProtocol::Tls), Some(Muxer::Mplex)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0"), + ), + (Transport::Ws, Some(SecProtocol::Tls), Some(Muxer::Mplex)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_websocket(tls::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0/ws")) - } - (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Yamux)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0/ws"), + ), + (Transport::Ws, Some(SecProtocol::Tls), Some(Muxer::Yamux)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_websocket(tls::Config::new, yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0/ws")) - } - (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Mplex)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0/ws"), + ), + (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Mplex)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_websocket(tls::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? - .build(); - (swarm, format!("/ip4/{ip}/tcp/0/ws")) - } - (Transport::WebRtcDirect, None, None) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0/ws"), + ), + (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Yamux)) => ( + libp2p::SwarmBuilder::with_new_identity() + .with_tokio() + .with_websocket(tls::Config::new, yamux::Config::default) + .await? + .with_behaviour(behaviour_constructor)? + .build(), + format!("/ip4/{ip}/tcp/0/ws"), + ), + (Transport::WebRtcDirect, None, None) => ( + libp2p::SwarmBuilder::with_new_identity() .with_tokio() .with_other_transport(|key| { Ok(webrtc::tokio::Transport::new( @@ -145,10 +145,9 @@ pub(crate) mod native { )) })? .with_behaviour(behaviour_constructor)? - .build(); - - (swarm, format!("/ip4/{ip}/udp/0/webrtc-direct")) - } + .build(), + format!("/ip4/{ip}/udp/0/webrtc-direct"), + ), (t, s, m) => bail!("Unsupported combination: {t:?} {s:?} {m:?}"), }; Ok((swarm, addr)) From 4eee7afd7e7ac34ea170a04cf31e3c8e96a68eb4 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 10 Oct 2023 15:31:58 +1100 Subject: [PATCH 168/171] Reduce diff --- interop-tests/src/arch.rs | 44 ++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index e7de2eb352d..8457d0b99cb 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -208,8 +208,8 @@ pub(crate) mod wasm { behaviour_constructor: impl FnOnce(&Keypair) -> B, ) -> Result<(Swarm, String)> { Ok(match (transport, sec_protocol, muxer) { - (Transport::Webtransport, None, None) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + (Transport::Webtransport, None, None) => ( + libp2p::SwarmBuilder::with_new_identity() .with_wasm_bindgen() .with_other_transport(|local_key| { webtransport_websys::Transport::new(webtransport_websys::Config::new( @@ -217,12 +217,11 @@ pub(crate) mod wasm { )) })? .with_behaviour(behaviour_constructor)? - .build(); - - (swarm, format!("/ip4/{ip}/udp/0/quic/webtransport")) - } - (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Mplex)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/udp/0/quic/webtransport"), + ), + (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Mplex)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_wasm_bindgen() .with_other_transport(|local_key| { Ok(websocket_websys::Transport::default() @@ -234,12 +233,11 @@ pub(crate) mod wasm { .multiplex(mplex::MplexConfig::new())) })? .with_behaviour(behaviour_constructor)? - .build(); - - (swarm, format!("/ip4/{ip}/tcp/0/wss")) - } - (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Yamux)) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0/wss"), + ), + (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Yamux)) => ( + libp2p::SwarmBuilder::with_new_identity() .with_wasm_bindgen() .with_other_transport(|local_key| { Ok(websocket_websys::Transport::default() @@ -251,21 +249,19 @@ pub(crate) mod wasm { .multiplex(yamux::Config::default())) })? .with_behaviour(behaviour_constructor)? - .build(); - - (swarm, format!("/ip4/{ip}/tcp/0/wss")) - } - (Transport::WebRtcDirect, None, None) => { - let swarm = libp2p::SwarmBuilder::with_new_identity() + .build(), + format!("/ip4/{ip}/tcp/0/wss"), + ), + (Transport::WebRtcDirect, None, None) => ( + libp2p::SwarmBuilder::with_new_identity() .with_wasm_bindgen() .with_other_transport(|local_key| { webrtc_websys::Transport::new(webrtc_websys::Config::new(&local_key)) })? .with_behaviour(behaviour_constructor)? - .build(); - - (swarm, format!("/ip4/{ip}/udp/0/webrtc-direct")) - } + .build(), + format!("/ip4/{ip}/udp/0/webrtc-direct"), + ), (t, s, m) => bail!("Unsupported combination: {t:?} {s:?} {m:?}"), }) } From 01fbf434075317c68559b04088cff659553d2b34 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 10 Oct 2023 15:34:53 +1100 Subject: [PATCH 169/171] Fix bug sec protocol selection --- interop-tests/src/arch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index 8457d0b99cb..d342e576a29 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -120,7 +120,7 @@ pub(crate) mod native { (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Mplex)) => ( libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(tls::Config::new, mplex::MplexConfig::default) + .with_websocket(noise::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? .build(), From 88d4361b642288e23c02b601e49d716edfcd2ff5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 10 Oct 2023 15:58:29 +1100 Subject: [PATCH 170/171] Configure idle-connection timeout --- interop-tests/src/arch.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index d342e576a29..ed8093de802 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -48,6 +48,7 @@ pub(crate) mod native { .with_tokio() .with_quic() .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/udp/0/quic-v1"), ), @@ -60,6 +61,7 @@ pub(crate) mod native { mplex::MplexConfig::default, )? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0"), ), @@ -72,6 +74,7 @@ pub(crate) mod native { yamux::Config::default, )? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0"), ), @@ -84,6 +87,7 @@ pub(crate) mod native { mplex::MplexConfig::default, )? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0"), ), @@ -96,6 +100,7 @@ pub(crate) mod native { yamux::Config::default, )? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0"), ), @@ -105,6 +110,7 @@ pub(crate) mod native { .with_websocket(tls::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0/ws"), ), @@ -114,6 +120,7 @@ pub(crate) mod native { .with_websocket(tls::Config::new, yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0/ws"), ), @@ -123,6 +130,7 @@ pub(crate) mod native { .with_websocket(noise::Config::new, mplex::MplexConfig::default) .await? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0/ws"), ), @@ -132,6 +140,7 @@ pub(crate) mod native { .with_websocket(tls::Config::new, yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0/ws"), ), @@ -145,6 +154,7 @@ pub(crate) mod native { )) })? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/udp/0/webrtc-direct"), ), @@ -217,6 +227,7 @@ pub(crate) mod wasm { )) })? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/udp/0/quic/webtransport"), ), @@ -233,6 +244,7 @@ pub(crate) mod wasm { .multiplex(mplex::MplexConfig::new())) })? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0/wss"), ), @@ -249,6 +261,7 @@ pub(crate) mod wasm { .multiplex(yamux::Config::default())) })? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/tcp/0/wss"), ), @@ -259,6 +272,7 @@ pub(crate) mod wasm { webrtc_websys::Transport::new(webrtc_websys::Config::new(&local_key)) })? .with_behaviour(behaviour_constructor)? + .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5))) .build(), format!("/ip4/{ip}/udp/0/webrtc-direct"), ), From 06ba9254292d7c395ee788cb1d225be9438568f8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 10 Oct 2023 16:42:34 +1100 Subject: [PATCH 171/171] Fix interop config bug --- interop-tests/src/arch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interop-tests/src/arch.rs b/interop-tests/src/arch.rs index ed8093de802..d90af53abb1 100644 --- a/interop-tests/src/arch.rs +++ b/interop-tests/src/arch.rs @@ -137,7 +137,7 @@ pub(crate) mod native { (Transport::Ws, Some(SecProtocol::Noise), Some(Muxer::Yamux)) => ( libp2p::SwarmBuilder::with_new_identity() .with_tokio() - .with_websocket(tls::Config::new, yamux::Config::default) + .with_websocket(noise::Config::new, yamux::Config::default) .await? .with_behaviour(behaviour_constructor)? .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(5)))