From 6985d7246220388738ce7bec644fef170db0c52a Mon Sep 17 00:00:00 2001 From: Max Inden Date: Thu, 11 May 2023 11:04:16 +0200 Subject: [PATCH 01/38] chore: update `ROADMAP.md` Pull-Request: #3904. --- ROADMAP.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 15a14f56f45..cecfdc7de2b 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -10,9 +10,9 @@ roadmap](https://github.com/libp2p/specs/blob/master/ROADMAP.md). ## Kademlia client mode -| Category | Status | Target Completion | Tracking | Dependencies | Dependents | -|--------------|--------|-------------------|---------------------------------------------------|-----------------------------------------------------------------|------------| -| Optimization | todo | Q1/2023 | https://github.com/libp2p/rust-libp2p/issues/2032 | [Cross behaviour communication](#cross-behaviour-communication) | | +| Category | Status | Target Completion | Tracking | Dependencies | Dependents | +|--------------|-------------|-------------------|---------------------------------------------------|-----------------------------------------------------------------|------------| +| Optimization | in progress | Q1/2023 | https://github.com/libp2p/rust-libp2p/issues/2032 | [Cross behaviour communication](#cross-behaviour-communication) | | Kademlia client mode will enhance routing table health and thus have a positive impact on all Kademlia operations. @@ -25,6 +25,14 @@ Kademlia operations. We added alpha support for QUIC in Q4/2022 wrapping `quinn-proto`. Evaluate using `quinn` directly, replacing the wrapper. +## Attempt to switch from webrtc-rs to str0m + +| Category | Status | Target Completion | Tracking | Dependencies | Dependents | +|--------------|--------|-------------------|---------------------------------------------------|--------------|------------| +| Connectivity | todo | | https://github.com/libp2p/rust-libp2p/issues/3659 | | | + +Reduce maintenance burden and reduce dependency footprint. + ## Optimize Hole punching | Category | Status | Target Completion | Tracking | Dependencies | Dependents | @@ -73,6 +81,17 @@ where the latter only have a self-signed TLS certificate. Compared to WebRTC, th more performant. It is dependent on QUIC support in rust-libp2p. Given that we will support WebRTC (browser-to-server) this is not a high priority. +## Automate port-forwarding e.g. via UPnP + +| Category | Status | Target Completion | Tracking | Dependencies | Dependents | +|--------------|--------|-------------------|---------------------------------------------------|--------------|------------| +| Connectivity | todo | | https://github.com/libp2p/rust-libp2p/issues/3903 | | | + +Leverage protocols like UPnP to configure port-forwarding on ones router when behind NAT and/or +firewall. Another technique in addition to hole punching increasing the probability for a node to +become publicly reachable when behind a firewall and/or NAT. + + ## Done ### Alpha QUIC support From 1bf6264cbea1df0c11273e5e10677db788d349e5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 12 May 2023 04:26:01 +0200 Subject: [PATCH 02/38] feat: properly encapsulate `quick_protobuf::Error` I noticed that we also still leak that dependency in several crates by providing a `From` impl so I've removed that one as well. Resolves #3534. Pull-Request: #3894. --- core/src/lib.rs | 17 ++--------------- core/src/peer_record.rs | 3 +-- core/src/signed_envelope.rs | 3 +-- transports/noise/src/io/handshake.rs | 5 +++-- transports/noise/src/lib.rs | 27 ++++----------------------- transports/plaintext/src/error.rs | 8 ++++---- transports/plaintext/src/handshake.rs | 4 ++-- 7 files changed, 17 insertions(+), 50 deletions(-) diff --git a/core/src/lib.rs b/core/src/lib.rs index c40e64c5d8b..a11480047bd 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -47,8 +47,6 @@ mod proto { /// Multi-address re-export. pub use multiaddr; -use std::fmt; -use std::fmt::Formatter; pub type Negotiated = multistream_select::Negotiated; #[deprecated(since = "0.39.0", note = "Depend on `libp2p-identity` instead.")] @@ -130,16 +128,5 @@ pub use transport::Transport; pub use upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeError, UpgradeInfo}; #[derive(Debug, thiserror::Error)] -pub struct DecodeError(String); - -impl From for DecodeError { - fn from(e: quick_protobuf::Error) -> Self { - Self(e.to_string()) - } -} - -impl fmt::Display for DecodeError { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) - } -} +#[error(transparent)] +pub struct DecodeError(quick_protobuf::Error); diff --git a/core/src/peer_record.rs b/core/src/peer_record.rs index 35433dc245f..a73168a30f1 100644 --- a/core/src/peer_record.rs +++ b/core/src/peer_record.rs @@ -36,8 +36,7 @@ impl PeerRecord { let (payload, signing_key) = envelope.payload_and_signing_key(String::from(DOMAIN_SEP), PAYLOAD_TYPE.as_bytes())?; let mut reader = BytesReader::from_bytes(payload); - let record = - proto::PeerRecord::from_reader(&mut reader, payload).map_err(DecodeError::from)?; + let record = proto::PeerRecord::from_reader(&mut reader, payload).map_err(DecodeError)?; let peer_id = PeerId::from_bytes(&record.peer_id)?; diff --git a/core/src/signed_envelope.rs b/core/src/signed_envelope.rs index a50146f87d1..19a0cac4f82 100644 --- a/core/src/signed_envelope.rs +++ b/core/src/signed_envelope.rs @@ -97,8 +97,7 @@ impl SignedEnvelope { use quick_protobuf::MessageRead; let mut reader = BytesReader::from_bytes(bytes); - let envelope = - proto::Envelope::from_reader(&mut reader, bytes).map_err(DecodeError::from)?; + let envelope = proto::Envelope::from_reader(&mut reader, bytes).map_err(DecodeError)?; Ok(Self { key: PublicKey::try_decode_protobuf(&envelope.public_key)?, diff --git a/transports/noise/src/io/handshake.rs b/transports/noise/src/io/handshake.rs index 18816a3b28d..3027fbfbd19 100644 --- a/transports/noise/src/io/handshake.rs +++ b/transports/noise/src/io/handshake.rs @@ -28,7 +28,7 @@ mod proto { use crate::io::{framed::NoiseFramed, Output}; use crate::protocol::{KeypairIdentity, STATIC_KEY_DOMAIN}; -use crate::Error; +use crate::{DecodeError, Error}; use bytes::Bytes; use futures::prelude::*; use libp2p_identity as identity; @@ -140,7 +140,8 @@ where { let msg = recv(state).await?; let mut reader = BytesReader::from_bytes(&msg[..]); - let pb = proto::NoiseHandshakePayload::from_reader(&mut reader, &msg[..])?; + let pb = + proto::NoiseHandshakePayload::from_reader(&mut reader, &msg[..]).map_err(DecodeError)?; state.id_remote_pubkey = Some(identity::PublicKey::try_decode_protobuf(&pb.identity_key)?); diff --git a/transports/noise/src/lib.rs b/transports/noise/src/lib.rs index e3b03db24cd..b7360c0c799 100644 --- a/transports/noise/src/lib.rs +++ b/transports/noise/src/lib.rs @@ -69,8 +69,6 @@ use libp2p_core::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; use libp2p_identity as identity; use libp2p_identity::PeerId; use snow::params::NoiseParams; -use std::fmt; -use std::fmt::Formatter; use std::pin::Pin; /// The configuration for the noise handshake. @@ -211,29 +209,12 @@ pub enum Error { BadSignature, #[error("Authentication failed")] AuthenticationFailed, - #[error(transparent)] - InvalidPayload(DecodeError), + #[error("failed to decode protobuf ")] + InvalidPayload(#[from] DecodeError), #[error(transparent)] SigningError(#[from] libp2p_identity::SigningError), } #[derive(Debug, thiserror::Error)] -pub struct DecodeError(String); - -impl fmt::Display for DecodeError { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) - } -} - -impl From for DecodeError { - fn from(e: quick_protobuf::Error) -> Self { - Self(e.to_string()) - } -} - -impl From for Error { - fn from(e: quick_protobuf::Error) -> Self { - Error::InvalidPayload(e.into()) - } -} +#[error(transparent)] +pub struct DecodeError(quick_protobuf::Error); diff --git a/transports/plaintext/src/error.rs b/transports/plaintext/src/error.rs index 133cca746af..2daac496f12 100644 --- a/transports/plaintext/src/error.rs +++ b/transports/plaintext/src/error.rs @@ -41,7 +41,7 @@ pub enum PlainTextError { } #[derive(Debug)] -pub struct DecodeError(quick_protobuf::Error); +pub struct DecodeError(pub(crate) quick_protobuf::Error); impl fmt::Display for DecodeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -87,9 +87,9 @@ impl From for PlainTextError { } } -impl From for PlainTextError { - fn from(err: quick_protobuf::Error) -> PlainTextError { - PlainTextError::InvalidPayload(DecodeError(err)) +impl From for PlainTextError { + fn from(err: DecodeError) -> PlainTextError { + PlainTextError::InvalidPayload(err) } } diff --git a/transports/plaintext/src/handshake.rs b/transports/plaintext/src/handshake.rs index b1e322459af..46dd6119d92 100644 --- a/transports/plaintext/src/handshake.rs +++ b/transports/plaintext/src/handshake.rs @@ -18,7 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::error::PlainTextError; +use crate::error::{DecodeError, PlainTextError}; use crate::proto::Exchange; use crate::PlainText2Config; @@ -74,7 +74,7 @@ impl HandshakeContext { exchange_bytes: BytesMut, ) -> Result, PlainTextError> { let mut reader = BytesReader::from_bytes(&exchange_bytes); - let prop = Exchange::from_reader(&mut reader, &exchange_bytes)?; + let prop = Exchange::from_reader(&mut reader, &exchange_bytes).map_err(DecodeError)?; let public_key = PublicKey::try_decode_protobuf(&prop.pubkey.unwrap_or_default())?; let peer_id = PeerId::from_bytes(&prop.id.unwrap_or_default())?; From 25958a2f8c5457b85f92c8e77726705ab531f4fe Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 12 May 2023 04:43:14 +0200 Subject: [PATCH 03/38] feat(identity): make `secp256k1::SecretKey::sign` infallible Previously, this function would return an error in case the provided digest is not of 32 bytes long. As per our [spec](https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#secp256k1), we hash _all_ messages with SHA256 before signing, thus this error can never happen in practice. This brings us one step closer to an infallible `Keypair::sign` which is now only fallible due to RSA signing. If we manage to fix that as well, constructors like `noise::Config::new` will become infallible. Pull-Request: #3850. --- identity/CHANGELOG.md | 4 ++++ identity/src/keypair.rs | 2 +- identity/src/secp256k1.rs | 30 +++++++++++++++--------------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/identity/CHANGELOG.md b/identity/CHANGELOG.md index 14d6405743b..cbfb817ca6c 100644 --- a/identity/CHANGELOG.md +++ b/identity/CHANGELOG.md @@ -8,6 +8,10 @@ - Make `Keypair` and `PublicKey` opaque. See [PR 3866]. +- Remove `identity::secp256k1::SecretKey::sign_hash` and make `identity::secp256k1::SecretKey::sign` infallible. + See [PR 3850]. + +[PR 3850]: https://github.com/libp2p/rust-libp2p/pull/3850 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 [PR 3863]: https://github.com/libp2p/rust-libp2p/pull/3863 [PR 3866]: https://github.com/libp2p/rust-libp2p/pull/3866 diff --git a/identity/src/keypair.rs b/identity/src/keypair.rs index a3128e56fbc..8249cbe96f9 100644 --- a/identity/src/keypair.rs +++ b/identity/src/keypair.rs @@ -198,7 +198,7 @@ impl Keypair { #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] KeyPairInner::Rsa(ref pair) => pair.sign(msg), #[cfg(feature = "secp256k1")] - KeyPairInner::Secp256k1(ref pair) => pair.secret().sign(msg), + KeyPairInner::Secp256k1(ref pair) => Ok(pair.secret().sign(msg)), #[cfg(feature = "ecdsa")] KeyPairInner::Ecdsa(ref pair) => Ok(pair.secret().sign(msg)), } diff --git a/identity/src/secp256k1.rs b/identity/src/secp256k1.rs index 413e2566227..0fe48d38dfb 100644 --- a/identity/src/secp256k1.rs +++ b/identity/src/secp256k1.rs @@ -20,7 +20,7 @@ //! Secp256k1 keys. -use super::error::{DecodingError, SigningError}; +use super::error::DecodingError; use asn1_der::typed::{DerDecodable, Sequence}; use core::cmp; use core::fmt; @@ -142,25 +142,25 @@ impl SecretKey { /// ECDSA signature, as defined in [RFC3278]. /// /// [RFC3278]: https://tools.ietf.org/html/rfc3278#section-8.2 - pub fn sign(&self, msg: &[u8]) -> Result, SigningError> { - self.sign_hash(Sha256::digest(msg).as_ref()) - } + pub fn sign(&self, msg: &[u8]) -> Vec { + let generic_array = Sha256::digest(msg); - /// Returns the raw bytes of the secret key. - pub fn to_bytes(&self) -> [u8; 32] { - self.0.serialize() - } + // FIXME: Once `generic-array` hits 1.0, we should be able to just use `Into` here. + let mut array = [0u8; 32]; + array.copy_from_slice(generic_array.as_slice()); + + let message = Message::parse(&array); - /// Sign a raw message of length 256 bits with this secret key, produces a DER-encoded - /// ECDSA signature. - pub fn sign_hash(&self, msg: &[u8]) -> Result, SigningError> { - let m = Message::parse_slice(msg) - .map_err(|_| SigningError::new("failed to parse secp256k1 digest"))?; - Ok(libsecp256k1::sign(&m, &self.0) + libsecp256k1::sign(&message, &self.0) .0 .serialize_der() .as_ref() - .into()) + .into() + } + + /// Returns the raw bytes of the secret key. + pub fn to_bytes(&self) -> [u8; 32] { + self.0.serialize() } } From 234a0d24dbb211e0264afe34f41afdfb873f74ce Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 12 May 2023 05:01:06 +0200 Subject: [PATCH 04/38] feat(yamux): future-proof public API With this set of changes, we prepare the public API of `libp2p-yamux` to be as minimal as possible and allow for upgrades of the underlying `yamux` library in patch releases. Related: #3013. Pull-Request: #3908. --- muxers/yamux/CHANGELOG.md | 4 + muxers/yamux/src/lib.rs | 227 +++++++++++++------------------------- 2 files changed, 81 insertions(+), 150 deletions(-) diff --git a/muxers/yamux/CHANGELOG.md b/muxers/yamux/CHANGELOG.md index e4c72580947..126b261355d 100644 --- a/muxers/yamux/CHANGELOG.md +++ b/muxers/yamux/CHANGELOG.md @@ -6,8 +6,12 @@ - Remove deprecated items. See [PR 3897]. +- Remove `Incoming`, `LocalIncoming` and `LocalConfig` as well as anything from the underlying `yamux` crate from the public API. + See [PR 3908]. + [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 [PR 3897]: https://github.com/libp2p/rust-libp2p/pull/3897 +[PR 3908]: https://github.com/libp2p/rust-libp2p/pull/3908 ## 0.43.1 diff --git a/muxers/yamux/src/lib.rs b/muxers/yamux/src/lib.rs index f398c022ee8..fcfa068d2ac 100644 --- a/muxers/yamux/src/lib.rs +++ b/muxers/yamux/src/lib.rs @@ -22,15 +22,11 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -use futures::{ - future, - prelude::*, - ready, - stream::{BoxStream, LocalBoxStream}, -}; +use futures::{future, prelude::*, ready, stream::BoxStream}; use libp2p_core::muxing::{StreamMuxer, StreamMuxerEvent}; use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; use std::collections::VecDeque; +use std::io::{IoSlice, IoSliceMut}; use std::task::Waker; use std::{ fmt, io, iter, mem, @@ -41,23 +37,25 @@ use thiserror::Error; use yamux::ConnectionError; /// A Yamux connection. -pub struct Muxer { +pub struct Muxer { /// The [`futures::stream::Stream`] of incoming substreams. - incoming: S, + incoming: BoxStream<'static, Result>, /// Handle to control the connection. control: yamux::Control, /// Temporarily buffers inbound streams in case our node is performing backpressure on the remote. /// - /// The only way how yamux can make progress is by driving the [`Incoming`] stream. However, the + /// The only way how yamux can make progress is by driving the stream. However, the /// [`StreamMuxer`] interface is designed to allow a caller to selectively make progress via /// [`StreamMuxer::poll_inbound`] and [`StreamMuxer::poll_outbound`] whilst the more general /// [`StreamMuxer::poll`] is designed to make progress on existing streams etc. /// /// This buffer stores inbound streams that are created whilst [`StreamMuxer::poll`] is called. /// Once the buffer is full, new inbound streams are dropped. - inbound_stream_buffer: VecDeque, + inbound_stream_buffer: VecDeque, /// Waker to be called when new inbound streams are available. inbound_stream_waker: Option, + + _phantom: std::marker::PhantomData, } const MAX_BUFFERED_INBOUND_STREAMS: usize = 25; @@ -68,7 +66,7 @@ impl fmt::Debug for Muxer { } } -impl Muxer> +impl Muxer where C: AsyncRead + AsyncWrite + Send + Unpin + 'static, { @@ -78,43 +76,20 @@ where let ctrl = conn.control(); Self { - incoming: Incoming { - stream: yamux::into_stream(conn).err_into().boxed(), - _marker: std::marker::PhantomData, - }, - control: ctrl, - inbound_stream_buffer: VecDeque::default(), - inbound_stream_waker: None, - } - } -} - -impl Muxer> -where - C: AsyncRead + AsyncWrite + Unpin + 'static, -{ - /// Create a new Yamux connection (which is ![`Send`]). - fn local(io: C, cfg: yamux::Config, mode: yamux::Mode) -> Self { - let conn = yamux::Connection::new(io, cfg, mode); - let ctrl = conn.control(); - - Self { - incoming: LocalIncoming { - stream: yamux::into_stream(conn).err_into().boxed_local(), - _marker: std::marker::PhantomData, - }, + incoming: yamux::into_stream(conn).err_into().boxed(), control: ctrl, inbound_stream_buffer: VecDeque::default(), inbound_stream_waker: None, + _phantom: Default::default(), } } } -impl StreamMuxer for Muxer +impl StreamMuxer for Muxer where - S: Stream> + Unpin, + C: AsyncRead + AsyncWrite + Send + Unpin + 'static, { - type Substream = yamux::Stream; + type Substream = Stream; type Error = Error; fn poll_inbound( @@ -136,6 +111,7 @@ where ) -> Poll> { Pin::new(&mut self.control) .poll_open_stream(cx) + .map_ok(Stream) .map_err(Error) } @@ -148,7 +124,7 @@ where let inbound_stream = ready!(this.poll_inner(cx))?; if this.inbound_stream_buffer.len() >= MAX_BUFFERED_INBOUND_STREAMS { - log::warn!("dropping {inbound_stream} because buffer is full"); + log::warn!("dropping {} because buffer is full", inbound_stream.0); drop(inbound_stream); } else { this.inbound_stream_buffer.push_back(inbound_stream); @@ -168,7 +144,9 @@ where return Poll::Ready(Ok(())); } - while let Poll::Ready(maybe_inbound_stream) = self.incoming.poll_next_unpin(c)? { + while let Poll::Ready(maybe_inbound_stream) = + self.incoming.poll_next_unpin(c).map_err(Error)? + { match maybe_inbound_stream { Some(inbound_stream) => mem::drop(inbound_stream), None => return Poll::Ready(Ok(())), @@ -179,14 +157,64 @@ where } } -impl Muxer +/// A stream produced by the yamux multiplexer. +#[derive(Debug)] +pub struct Stream(yamux::Stream); + +impl AsyncRead for Stream { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_read(cx, buf) + } + + fn poll_read_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + Pin::new(&mut self.0).poll_read_vectored(cx, bufs) + } +} + +impl AsyncWrite for Stream { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.0).poll_write(cx, buf) + } + + fn poll_write_vectored( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + Pin::new(&mut self.0).poll_write_vectored(cx, bufs) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.0).poll_close(cx) + } +} + +impl Muxer where - S: Stream> + Unpin, + C: AsyncRead + AsyncWrite + Send + Unpin + 'static, { - fn poll_inner(&mut self, cx: &mut Context<'_>) -> Poll> { + fn poll_inner(&mut self, cx: &mut Context<'_>) -> Poll> { self.incoming.poll_next_unpin(cx).map(|maybe_stream| { let stream = maybe_stream - .transpose()? + .transpose() + .map_err(Error)? + .map(Stream) .ok_or(Error(ConnectionError::Closed))?; Ok(stream) @@ -241,10 +269,6 @@ impl WindowUpdateMode { } } -/// The yamux configuration for upgrading I/O resources which are ![`Send`]. -#[derive(Clone)] -pub struct LocalConfig(Config); - impl Config { /// Creates a new `YamuxConfig` in client mode, regardless of whether /// it will be used for an inbound or outbound upgrade. @@ -288,12 +312,6 @@ impl Config { self.inner.set_window_update_mode(mode.0); self } - - /// Converts the config into a [`LocalConfig`] for use with upgrades - /// of I/O streams that are ![`Send`]. - pub fn into_local(self) -> LocalConfig { - LocalConfig(self) - } } impl Default for Config { @@ -315,20 +333,11 @@ impl UpgradeInfo for Config { } } -impl UpgradeInfo for LocalConfig { - type Info = &'static str; - type InfoIter = iter::Once; - - fn protocol_info(&self) -> Self::InfoIter { - iter::once("/yamux/1.0.0") - } -} - impl InboundUpgrade for Config where C: AsyncRead + AsyncWrite + Send + Unpin + 'static, { - type Output = Muxer>; + type Output = Muxer; type Error = io::Error; type Future = future::Ready>; @@ -338,26 +347,11 @@ where } } -impl InboundUpgrade for LocalConfig -where - C: AsyncRead + AsyncWrite + Unpin + 'static, -{ - type Output = Muxer>; - type Error = io::Error; - type Future = future::Ready>; - - fn upgrade_inbound(self, io: C, _: Self::Info) -> Self::Future { - let cfg = self.0; - let mode = cfg.mode.unwrap_or(yamux::Mode::Server); - future::ready(Ok(Muxer::local(io, cfg.inner, mode))) - } -} - impl OutboundUpgrade for Config where C: AsyncRead + AsyncWrite + Send + Unpin + 'static, { - type Output = Muxer>; + type Output = Muxer; type Error = io::Error; type Future = future::Ready>; @@ -367,25 +361,10 @@ where } } -impl OutboundUpgrade for LocalConfig -where - C: AsyncRead + AsyncWrite + Unpin + 'static, -{ - type Output = Muxer>; - type Error = io::Error; - type Future = future::Ready>; - - fn upgrade_outbound(self, io: C, _: Self::Info) -> Self::Future { - let cfg = self.0; - let mode = cfg.mode.unwrap_or(yamux::Mode::Client); - future::ready(Ok(Muxer::local(io, cfg.inner, mode))) - } -} - /// The Yamux [`StreamMuxer`] error type. #[derive(Debug, Error)] -#[error("yamux error: {0}")] -pub struct Error(#[from] yamux::ConnectionError); +#[error(transparent)] +pub struct Error(yamux::ConnectionError); impl From for io::Error { fn from(err: Error) -> Self { @@ -395,55 +374,3 @@ impl From for io::Error { } } } - -/// The [`futures::stream::Stream`] of incoming substreams. -pub struct Incoming { - stream: BoxStream<'static, Result>, - _marker: std::marker::PhantomData, -} - -impl fmt::Debug for Incoming { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("Incoming") - } -} - -/// The [`futures::stream::Stream`] of incoming substreams (`!Send`). -pub struct LocalIncoming { - stream: LocalBoxStream<'static, Result>, - _marker: std::marker::PhantomData, -} - -impl fmt::Debug for LocalIncoming { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("LocalIncoming") - } -} - -impl Stream for Incoming { - type Item = Result; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - self.stream.as_mut().poll_next_unpin(cx) - } - - fn size_hint(&self) -> (usize, Option) { - self.stream.size_hint() - } -} - -impl Unpin for Incoming {} - -impl Stream for LocalIncoming { - type Item = Result; - - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - self.stream.as_mut().poll_next_unpin(cx) - } - - fn size_hint(&self) -> (usize, Option) { - self.stream.size_hint() - } -} - -impl Unpin for LocalIncoming {} From 9e625881d53373f3a26284bd88fa8f583878106b Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 12 May 2023 08:19:23 +0200 Subject: [PATCH 05/38] feat(swarm): deprecate `NegotiatedSubstream` in favor of `Stream` This patch tackles two things at once that are fairly intertwined: 1. There is no such thing as a "substream" in libp2p, the spec and other implementations only talk about "streams". We fix this by deprecating `NegotiatedSubstream`. 2. Previously, `NegotiatedSubstream` was a type alias that pointed to a type from `multistream-select`, effectively leaking the version of `multistream-select` to all dependencies of `libp2p-swarm`. We fix this by introducing a `Stream` newtype. Resolves: #3759. Related: #3748. Pull-Request: #3912. --- Cargo.lock | 1 + libp2p/src/lib.rs | 2 +- protocols/dcutr/src/protocol/inbound.rs | 8 +- protocols/dcutr/src/protocol/outbound.rs | 6 +- protocols/gossipsub/src/handler.rs | 14 +- protocols/kad/src/handler.rs | 36 ++--- protocols/ping/src/handler.rs | 8 +- protocols/relay/src/behaviour/handler.rs | 12 +- protocols/relay/src/priv_client.rs | 8 +- protocols/relay/src/protocol/inbound_hop.rs | 12 +- protocols/relay/src/protocol/inbound_stop.rs | 10 +- protocols/relay/src/protocol/outbound_hop.rs | 8 +- protocols/relay/src/protocol/outbound_stop.rs | 8 +- protocols/rendezvous/src/handler/inbound.rs | 12 +- protocols/rendezvous/src/handler/outbound.rs | 4 +- protocols/rendezvous/src/substream_handler.rs | 7 +- .../request-response/src/handler/protocol.rs | 18 +-- swarm/CHANGELOG.md | 4 + swarm/Cargo.toml | 1 + swarm/src/connection.rs | 125 ++++++++++-------- swarm/src/handler/multi.rs | 6 +- swarm/src/lib.rs | 12 +- swarm/src/stream.rs | 59 +++++++++ swarm/src/upgrade.rs | 22 +-- 24 files changed, 234 insertions(+), 169 deletions(-) create mode 100644 swarm/src/stream.rs diff --git a/Cargo.lock b/Cargo.lock index 2e850e031a0..3bb82a6a6aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2989,6 +2989,7 @@ dependencies = [ "libp2p-swarm-test", "libp2p-yamux", "log", + "multistream-select", "once_cell", "quickcheck-ext", "rand 0.8.5", diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index 3a8c09a068b..f086c2872f4 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -177,7 +177,7 @@ pub use self::swarm::Swarm; pub use self::transport_ext::TransportExt; pub use libp2p_identity as identity; pub use libp2p_identity::PeerId; -pub use libp2p_swarm::StreamProtocol; +pub use libp2p_swarm::{Stream, StreamProtocol}; /// Builds a `Transport` based on TCP/IP that supports the most commonly-used features of libp2p: /// diff --git a/protocols/dcutr/src/protocol/inbound.rs b/protocols/dcutr/src/protocol/inbound.rs index 83fa926a550..d38b6f4559a 100644 --- a/protocols/dcutr/src/protocol/inbound.rs +++ b/protocols/dcutr/src/protocol/inbound.rs @@ -22,7 +22,7 @@ use crate::proto; use asynchronous_codec::Framed; use futures::{future::BoxFuture, prelude::*}; use libp2p_core::{multiaddr::Protocol, upgrade, Multiaddr}; -use libp2p_swarm::{NegotiatedSubstream, StreamProtocol}; +use libp2p_swarm::{Stream, StreamProtocol}; use std::convert::TryFrom; use std::iter; use thiserror::Error; @@ -38,12 +38,12 @@ impl upgrade::UpgradeInfo for Upgrade { } } -impl upgrade::InboundUpgrade for Upgrade { +impl upgrade::InboundUpgrade for Upgrade { type Output = PendingConnect; type Error = UpgradeError; type Future = BoxFuture<'static, Result>; - fn upgrade_inbound(self, substream: NegotiatedSubstream, _: Self::Info) -> Self::Future { + fn upgrade_inbound(self, substream: Stream, _: Self::Info) -> Self::Future { let mut substream = Framed::new( substream, quick_protobuf_codec::Codec::new(super::MAX_MESSAGE_SIZE_BYTES), @@ -92,7 +92,7 @@ impl upgrade::InboundUpgrade for Upgrade { } pub struct PendingConnect { - substream: Framed>, + substream: Framed>, remote_obs_addrs: Vec, } diff --git a/protocols/dcutr/src/protocol/outbound.rs b/protocols/dcutr/src/protocol/outbound.rs index 00b16e20617..960d98cbe66 100644 --- a/protocols/dcutr/src/protocol/outbound.rs +++ b/protocols/dcutr/src/protocol/outbound.rs @@ -24,7 +24,7 @@ use futures::{future::BoxFuture, prelude::*}; use futures_timer::Delay; use instant::Instant; use libp2p_core::{multiaddr::Protocol, upgrade, Multiaddr}; -use libp2p_swarm::{NegotiatedSubstream, StreamProtocol}; +use libp2p_swarm::{Stream, StreamProtocol}; use std::convert::TryFrom; use std::iter; use thiserror::Error; @@ -48,12 +48,12 @@ impl Upgrade { } } -impl upgrade::OutboundUpgrade for Upgrade { +impl upgrade::OutboundUpgrade for Upgrade { type Output = Connect; type Error = UpgradeError; type Future = BoxFuture<'static, Result>; - fn upgrade_outbound(self, substream: NegotiatedSubstream, _: Self::Info) -> Self::Future { + fn upgrade_outbound(self, substream: Stream, _: Self::Info) -> Self::Future { let mut substream = Framed::new( substream, quick_protobuf_codec::Codec::new(super::MAX_MESSAGE_SIZE_BYTES), diff --git a/protocols/gossipsub/src/handler.rs b/protocols/gossipsub/src/handler.rs index 65a4a31b60c..5a5b91d00d1 100644 --- a/protocols/gossipsub/src/handler.rs +++ b/protocols/gossipsub/src/handler.rs @@ -33,7 +33,7 @@ use libp2p_swarm::handler::{ FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, StreamUpgradeError, SubstreamProtocol, }; -use libp2p_swarm::NegotiatedSubstream; +use libp2p_swarm::Stream; use smallvec::SmallVec; use std::{ pin::Pin, @@ -143,9 +143,9 @@ pub enum DisabledHandler { /// State of the inbound substream, opened either by us or by the remote. enum InboundSubstreamState { /// Waiting for a message from the remote. The idle state for an inbound substream. - WaitingInput(Framed), + WaitingInput(Framed), /// The substream is being closed. - Closing(Framed), + Closing(Framed), /// An error occurred during processing. Poisoned, } @@ -153,11 +153,11 @@ enum InboundSubstreamState { /// State of the outbound substream, opened either by us or by the remote. enum OutboundSubstreamState { /// Waiting for the user to send a message. The idle state for an outbound substream. - WaitingOutput(Framed), + WaitingOutput(Framed), /// Waiting to send a message to the remote. - PendingSend(Framed, proto::RPC), + PendingSend(Framed, proto::RPC), /// Waiting to flush the substream so that the data arrives to the remote. - PendingFlush(Framed), + PendingFlush(Framed), /// An error occurred during processing. Poisoned, } @@ -185,7 +185,7 @@ impl Handler { impl EnabledHandler { fn on_fully_negotiated_inbound( &mut self, - (substream, peer_kind): (Framed, PeerKind), + (substream, peer_kind): (Framed, PeerKind), ) { // update the known kind of peer if self.peer_kind.is_none() { diff --git a/protocols/kad/src/handler.rs b/protocols/kad/src/handler.rs index 3fa123410ee..25daa8dcd15 100644 --- a/protocols/kad/src/handler.rs +++ b/protocols/kad/src/handler.rs @@ -33,7 +33,7 @@ use libp2p_swarm::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, KeepAlive, NegotiatedSubstream, StreamUpgradeError, + ConnectionHandler, ConnectionHandlerEvent, KeepAlive, Stream, StreamUpgradeError, SubstreamProtocol, }; use log::trace; @@ -116,20 +116,16 @@ pub struct KademliaHandlerConfig { /// State of an active outbound substream. enum OutboundSubstreamState { /// Waiting to send a message to the remote. - PendingSend( - KadOutStreamSink, - KadRequestMsg, - Option, - ), + PendingSend(KadOutStreamSink, KadRequestMsg, Option), /// Waiting to flush the substream so that the data arrives to the remote. - PendingFlush(KadOutStreamSink, Option), + PendingFlush(KadOutStreamSink, Option), /// Waiting for an answer back from the remote. // TODO: add timeout - WaitingAnswer(KadOutStreamSink, TUserData), + WaitingAnswer(KadOutStreamSink, TUserData), /// An error happened on the substream and we should report the error to the user. ReportError(KademliaHandlerQueryErr, TUserData), /// The substream is being closed. - Closing(KadOutStreamSink), + Closing(KadOutStreamSink), /// The substream is complete and will not perform any more work. Done, Poisoned, @@ -142,24 +138,16 @@ enum InboundSubstreamState { /// Whether it is the first message to be awaited on this stream. first: bool, connection_id: UniqueConnecId, - substream: KadInStreamSink, + substream: KadInStreamSink, }, /// Waiting for the behaviour to send a [`KademliaHandlerIn`] event containing the response. - WaitingBehaviour( - UniqueConnecId, - KadInStreamSink, - Option, - ), + WaitingBehaviour(UniqueConnecId, KadInStreamSink, Option), /// Waiting to send an answer back to the remote. - PendingSend( - UniqueConnecId, - KadInStreamSink, - KadResponseMsg, - ), + PendingSend(UniqueConnecId, KadInStreamSink, KadResponseMsg), /// Waiting to flush an answer back to the remote. - PendingFlush(UniqueConnecId, KadInStreamSink), + PendingFlush(UniqueConnecId, KadInStreamSink), /// The substream is being closed. - Closing(KadInStreamSink), + Closing(KadInStreamSink), /// The substream was cancelled in favor of a new one. Cancelled, @@ -813,7 +801,7 @@ impl Default for KademliaHandlerConfig { } } -impl Stream for OutboundSubstreamState +impl futures::Stream for OutboundSubstreamState where TUserData: Unpin, { @@ -949,7 +937,7 @@ where } } -impl Stream for InboundSubstreamState +impl futures::Stream for InboundSubstreamState where TUserData: Unpin, { diff --git a/protocols/ping/src/handler.rs b/protocols/ping/src/handler.rs index be05c88f7d4..94b484927b8 100644 --- a/protocols/ping/src/handler.rs +++ b/protocols/ping/src/handler.rs @@ -27,7 +27,7 @@ use libp2p_swarm::handler::{ ConnectionEvent, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound, }; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, KeepAlive, NegotiatedSubstream, StreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, KeepAlive, Stream, StreamProtocol, StreamUpgradeError, SubstreamProtocol, }; use std::collections::VecDeque; @@ -390,15 +390,15 @@ impl ConnectionHandler for Handler { } } -type PingFuture = BoxFuture<'static, Result<(NegotiatedSubstream, Duration), io::Error>>; -type PongFuture = BoxFuture<'static, Result>; +type PingFuture = BoxFuture<'static, Result<(Stream, Duration), io::Error>>; +type PongFuture = BoxFuture<'static, Result>; /// The current state w.r.t. outbound pings. enum OutboundState { /// A new substream is being negotiated for the ping protocol. OpenStream, /// The substream is idle, waiting to send the next ping. - Idle(NegotiatedSubstream), + Idle(Stream), /// A ping is being sent and the response awaited. Ping(PingFuture), } diff --git a/protocols/relay/src/behaviour/handler.rs b/protocols/relay/src/behaviour/handler.rs index ff2abc65aa0..7494d055f36 100644 --- a/protocols/relay/src/behaviour/handler.rs +++ b/protocols/relay/src/behaviour/handler.rs @@ -37,8 +37,8 @@ use libp2p_swarm::handler::{ ListenUpgradeError, }; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, ConnectionId, KeepAlive, NegotiatedSubstream, - StreamUpgradeError, SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, ConnectionId, KeepAlive, Stream, StreamUpgradeError, + SubstreamProtocol, }; use std::collections::VecDeque; use std::fmt; @@ -77,7 +77,7 @@ pub enum In { dst_peer_id: PeerId, inbound_circuit_req: inbound_hop::CircuitReq, dst_handler_notifier: oneshot::Sender<()>, - dst_stream: NegotiatedSubstream, + dst_stream: Stream, dst_pending_data: Bytes, }, } @@ -193,7 +193,7 @@ pub enum Event { src_connection_id: ConnectionId, inbound_circuit_req: inbound_hop::CircuitReq, dst_handler_notifier: oneshot::Sender<()>, - dst_stream: NegotiatedSubstream, + dst_stream: Stream, dst_pending_data: Bytes, }, /// Negotiating an outbound substream for an inbound circuit request failed. @@ -914,10 +914,10 @@ pub struct OutboundOpenInfo { pub(crate) struct CircuitParts { circuit_id: CircuitId, - src_stream: NegotiatedSubstream, + src_stream: Stream, src_pending_data: Bytes, dst_peer_id: PeerId, dst_handler_notifier: oneshot::Sender<()>, - dst_stream: NegotiatedSubstream, + dst_stream: Stream, dst_pending_data: Bytes, } diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 656196fb9cd..8592c57d3b6 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -39,8 +39,8 @@ use libp2p_identity::PeerId; use libp2p_swarm::behaviour::{ConnectionClosed, ConnectionEstablished, FromSwarm}; use libp2p_swarm::dial_opts::DialOpts; use libp2p_swarm::{ - dummy, ConnectionDenied, ConnectionHandler, ConnectionId, DialFailure, NegotiatedSubstream, - NetworkBehaviour, NotifyHandler, PollParameters, StreamUpgradeError, THandler, THandlerInEvent, + dummy, ConnectionDenied, ConnectionHandler, ConnectionId, DialFailure, NetworkBehaviour, + NotifyHandler, PollParameters, Stream, StreamUpgradeError, THandler, THandlerInEvent, THandlerOutEvent, ToSwarm, }; use std::collections::{hash_map, HashMap, VecDeque}; @@ -391,7 +391,7 @@ enum ConnectionState { }, Operational { read_buffer: Bytes, - substream: NegotiatedSubstream, + substream: Stream, /// "Drop notifier" pattern to signal to the transport that the connection has been dropped. /// /// This is flagged as "dead-code" by the compiler because we never read from it here. @@ -425,7 +425,7 @@ impl ConnectionState { } pub(crate) fn new_outbound( - substream: NegotiatedSubstream, + substream: Stream, read_buffer: Bytes, drop_notifier: oneshot::Sender, ) -> Self { diff --git a/protocols/relay/src/protocol/inbound_hop.rs b/protocols/relay/src/protocol/inbound_hop.rs index 1af258fc25b..c5886d93ba6 100644 --- a/protocols/relay/src/protocol/inbound_hop.rs +++ b/protocols/relay/src/protocol/inbound_hop.rs @@ -26,7 +26,7 @@ use futures::{future::BoxFuture, prelude::*}; use instant::{Duration, SystemTime}; use libp2p_core::{upgrade, Multiaddr}; use libp2p_identity::PeerId; -use libp2p_swarm::{NegotiatedSubstream, StreamProtocol}; +use libp2p_swarm::{Stream, StreamProtocol}; use std::convert::TryInto; use std::iter; use thiserror::Error; @@ -46,12 +46,12 @@ impl upgrade::UpgradeInfo for Upgrade { } } -impl upgrade::InboundUpgrade for Upgrade { +impl upgrade::InboundUpgrade for Upgrade { type Output = Req; type Error = UpgradeError; type Future = BoxFuture<'static, Result>; - fn upgrade_inbound(self, substream: NegotiatedSubstream, _: Self::Info) -> Self::Future { + fn upgrade_inbound(self, substream: Stream, _: Self::Info) -> Self::Future { let mut substream = Framed::new( substream, quick_protobuf_codec::Codec::new(MAX_MESSAGE_SIZE), @@ -126,7 +126,7 @@ pub enum Req { } pub struct ReservationReq { - substream: Framed>, + substream: Framed>, reservation_duration: Duration, max_circuit_duration: Duration, max_circuit_bytes: u64, @@ -183,7 +183,7 @@ impl ReservationReq { pub struct CircuitReq { dst: PeerId, - substream: Framed>, + substream: Framed>, } impl CircuitReq { @@ -191,7 +191,7 @@ impl CircuitReq { self.dst } - pub async fn accept(mut self) -> Result<(NegotiatedSubstream, Bytes), UpgradeError> { + pub async fn accept(mut self) -> Result<(Stream, Bytes), UpgradeError> { let msg = proto::HopMessage { type_pb: proto::HopMessageType::STATUS, peer: None, diff --git a/protocols/relay/src/protocol/inbound_stop.rs b/protocols/relay/src/protocol/inbound_stop.rs index bfffb6a1e9c..c279c8ee601 100644 --- a/protocols/relay/src/protocol/inbound_stop.rs +++ b/protocols/relay/src/protocol/inbound_stop.rs @@ -25,7 +25,7 @@ use bytes::Bytes; use futures::{future::BoxFuture, prelude::*}; use libp2p_core::upgrade; use libp2p_identity::PeerId; -use libp2p_swarm::{NegotiatedSubstream, StreamProtocol}; +use libp2p_swarm::{Stream, StreamProtocol}; use std::iter; use thiserror::Error; @@ -40,12 +40,12 @@ impl upgrade::UpgradeInfo for Upgrade { } } -impl upgrade::InboundUpgrade for Upgrade { +impl upgrade::InboundUpgrade for Upgrade { type Output = Circuit; type Error = UpgradeError; type Future = BoxFuture<'static, Result>; - fn upgrade_inbound(self, substream: NegotiatedSubstream, _: Self::Info) -> Self::Future { + fn upgrade_inbound(self, substream: Stream, _: Self::Info) -> Self::Future { let mut substream = Framed::new( substream, quick_protobuf_codec::Codec::new(MAX_MESSAGE_SIZE), @@ -111,7 +111,7 @@ pub enum FatalUpgradeError { } pub struct Circuit { - substream: Framed>, + substream: Framed>, src_peer_id: PeerId, limit: Option, } @@ -125,7 +125,7 @@ impl Circuit { self.limit } - pub async fn accept(mut self) -> Result<(NegotiatedSubstream, Bytes), UpgradeError> { + pub async fn accept(mut self) -> Result<(Stream, Bytes), UpgradeError> { let msg = proto::StopMessage { type_pb: proto::StopMessageType::STATUS, peer: None, diff --git a/protocols/relay/src/protocol/outbound_hop.rs b/protocols/relay/src/protocol/outbound_hop.rs index 07d09157404..bec348e87db 100644 --- a/protocols/relay/src/protocol/outbound_hop.rs +++ b/protocols/relay/src/protocol/outbound_hop.rs @@ -27,7 +27,7 @@ use futures_timer::Delay; use instant::{Duration, SystemTime}; use libp2p_core::{upgrade, Multiaddr}; use libp2p_identity::PeerId; -use libp2p_swarm::{NegotiatedSubstream, StreamProtocol}; +use libp2p_swarm::{Stream, StreamProtocol}; use std::convert::TryFrom; use std::iter; use thiserror::Error; @@ -46,12 +46,12 @@ impl upgrade::UpgradeInfo for Upgrade { } } -impl upgrade::OutboundUpgrade for Upgrade { +impl upgrade::OutboundUpgrade for Upgrade { type Output = Output; type Error = UpgradeError; type Future = BoxFuture<'static, Result>; - fn upgrade_outbound(self, substream: NegotiatedSubstream, _: Self::Info) -> Self::Future { + fn upgrade_outbound(self, substream: Stream, _: Self::Info) -> Self::Future { let msg = match self { Upgrade::Reserve => proto::HopMessage { type_pb: proto::HopMessageType::RESERVE, @@ -269,7 +269,7 @@ pub enum Output { limit: Option, }, Circuit { - substream: NegotiatedSubstream, + substream: Stream, read_buffer: Bytes, limit: Option, }, diff --git a/protocols/relay/src/protocol/outbound_stop.rs b/protocols/relay/src/protocol/outbound_stop.rs index 782808acc57..836468a8605 100644 --- a/protocols/relay/src/protocol/outbound_stop.rs +++ b/protocols/relay/src/protocol/outbound_stop.rs @@ -25,7 +25,7 @@ use bytes::Bytes; use futures::{future::BoxFuture, prelude::*}; use libp2p_core::upgrade; use libp2p_identity::PeerId; -use libp2p_swarm::{NegotiatedSubstream, StreamProtocol}; +use libp2p_swarm::{Stream, StreamProtocol}; use std::convert::TryInto; use std::iter; use std::time::Duration; @@ -46,12 +46,12 @@ impl upgrade::UpgradeInfo for Upgrade { } } -impl upgrade::OutboundUpgrade for Upgrade { - type Output = (NegotiatedSubstream, Bytes); +impl upgrade::OutboundUpgrade for Upgrade { + type Output = (Stream, Bytes); type Error = UpgradeError; type Future = BoxFuture<'static, Result>; - fn upgrade_outbound(self, substream: NegotiatedSubstream, _: Self::Info) -> Self::Future { + fn upgrade_outbound(self, substream: Stream, _: Self::Info) -> Self::Future { let msg = proto::StopMessage { type_pb: proto::StopMessageType::CONNECT, peer: Some(proto::Peer { diff --git a/protocols/rendezvous/src/handler/inbound.rs b/protocols/rendezvous/src/handler/inbound.rs index 5ed2e4052ab..bf0083780c5 100644 --- a/protocols/rendezvous/src/handler/inbound.rs +++ b/protocols/rendezvous/src/handler/inbound.rs @@ -26,7 +26,7 @@ use crate::handler::PROTOCOL_IDENT; use crate::substream_handler::{Next, PassthroughProtocol, SubstreamHandler}; use asynchronous_codec::Framed; use futures::{SinkExt, StreamExt}; -use libp2p_swarm::{NegotiatedSubstream, SubstreamProtocol}; +use libp2p_swarm::SubstreamProtocol; use std::fmt; use std::task::{Context, Poll}; @@ -35,13 +35,13 @@ use std::task::{Context, Poll}; #[allow(clippy::enum_variant_names)] pub enum Stream { /// We are in the process of reading a message from the substream. - PendingRead(Framed), + PendingRead(Framed), /// We read a message, dispatched it to the behaviour and are waiting for the response. - PendingBehaviour(Framed), + PendingBehaviour(Framed), /// We are in the process of sending a response. - PendingSend(Framed, Message), + PendingSend(Framed, Message), /// We've sent the message and are now closing down the substream. - PendingClose(Framed), + PendingClose(Framed), } impl fmt::Debug for Stream { @@ -93,7 +93,7 @@ impl SubstreamHandler for Stream { SubstreamProtocol::new(PassthroughProtocol::new(PROTOCOL_IDENT), open_info) } - fn new(substream: NegotiatedSubstream, _: Self::OpenInfo) -> Self { + fn new(substream: libp2p_swarm::Stream, _: Self::OpenInfo) -> Self { Stream::PendingRead(Framed::new(substream, RendezvousCodec::default())) } diff --git a/protocols/rendezvous/src/handler/outbound.rs b/protocols/rendezvous/src/handler/outbound.rs index d80bcdeb82a..dd44bf8c2b4 100644 --- a/protocols/rendezvous/src/handler/outbound.rs +++ b/protocols/rendezvous/src/handler/outbound.rs @@ -25,7 +25,7 @@ use crate::substream_handler::{FutureSubstream, Next, PassthroughProtocol, Subst use crate::{ErrorCode, Namespace, Registration, Ttl}; use asynchronous_codec::Framed; use futures::{SinkExt, TryFutureExt, TryStreamExt}; -use libp2p_swarm::{NegotiatedSubstream, SubstreamProtocol}; +use libp2p_swarm::SubstreamProtocol; use std::task::Context; use void::Void; @@ -43,7 +43,7 @@ impl SubstreamHandler for Stream { SubstreamProtocol::new(PassthroughProtocol::new(PROTOCOL_IDENT), open_info) } - fn new(substream: NegotiatedSubstream, info: Self::OpenInfo) -> Self { + fn new(substream: libp2p_swarm::Stream, info: Self::OpenInfo) -> Self { let mut stream = Framed::new(substream, RendezvousCodec::default()); let sent_message = match info { OpenInfo::RegisterRequest(new_registration) => Message::Register(new_registration), diff --git a/protocols/rendezvous/src/substream_handler.rs b/protocols/rendezvous/src/substream_handler.rs index e4645449795..289c6a36d7e 100644 --- a/protocols/rendezvous/src/substream_handler.rs +++ b/protocols/rendezvous/src/substream_handler.rs @@ -31,8 +31,7 @@ use instant::Instant; use libp2p_core::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; use libp2p_swarm::handler::{ConnectionEvent, FullyNegotiatedInbound, FullyNegotiatedOutbound}; use libp2p_swarm::{ - ConnectionHandler, ConnectionHandlerEvent, KeepAlive, NegotiatedSubstream, StreamProtocol, - SubstreamProtocol, + ConnectionHandler, ConnectionHandlerEvent, KeepAlive, Stream, StreamProtocol, SubstreamProtocol, }; use std::collections::{HashMap, VecDeque}; use std::fmt; @@ -51,7 +50,7 @@ pub trait SubstreamHandler: Sized { fn upgrade(open_info: Self::OpenInfo) -> SubstreamProtocol; - fn new(substream: NegotiatedSubstream, info: Self::OpenInfo) -> Self; + fn new(substream: Stream, info: Self::OpenInfo) -> Self; fn on_event(self, event: Self::InEvent) -> Self; fn advance(self, cx: &mut Context<'_>) -> Result, Self::Error>; } @@ -541,7 +540,7 @@ impl SubstreamHandler for void::Void { type Error = void::Void; type OpenInfo = (); - fn new(_: NegotiatedSubstream, _: Self::OpenInfo) -> Self { + fn new(_: Stream, _: Self::OpenInfo) -> Self { unreachable!("we should never yield a substream") } diff --git a/protocols/request-response/src/handler/protocol.rs b/protocols/request-response/src/handler/protocol.rs index 84ef365734f..1368a3c1f98 100644 --- a/protocols/request-response/src/handler/protocol.rs +++ b/protocols/request-response/src/handler/protocol.rs @@ -28,7 +28,7 @@ use crate::RequestId; use futures::{channel::oneshot, future::BoxFuture, prelude::*}; use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; -use libp2p_swarm::NegotiatedSubstream; +use libp2p_swarm::Stream; use smallvec::SmallVec; use std::{fmt, io}; @@ -88,7 +88,7 @@ where } } -impl InboundUpgrade for ResponseProtocol +impl InboundUpgrade for ResponseProtocol where TCodec: Codec + Send + 'static, { @@ -96,11 +96,7 @@ where type Error = io::Error; type Future = BoxFuture<'static, Result>; - fn upgrade_inbound( - mut self, - mut io: NegotiatedSubstream, - protocol: Self::Info, - ) -> Self::Future { + fn upgrade_inbound(mut self, mut io: Stream, protocol: Self::Info) -> Self::Future { async move { let read = self.codec.read_request(&protocol, &mut io); let request = read.await?; @@ -163,7 +159,7 @@ where } } -impl OutboundUpgrade for RequestProtocol +impl OutboundUpgrade for RequestProtocol where TCodec: Codec + Send + 'static, { @@ -171,11 +167,7 @@ where type Error = io::Error; type Future = BoxFuture<'static, Result>; - fn upgrade_outbound( - mut self, - mut io: NegotiatedSubstream, - protocol: Self::Info, - ) -> Self::Future { + fn upgrade_outbound(mut self, mut io: Stream, protocol: Self::Info) -> Self::Future { async move { let write = self.codec.write_request(&protocol, &mut io, self.request); write.await?; diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 14a584217ad..86023f5541f 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -42,6 +42,9 @@ See [PR 3651]. +- Deprecate the `NegotiatedSubstream` type and replace it with `Stream`. + See [PR 3912]. + [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 [PR 3651]: https://github.com/libp2p/rust-libp2p/pull/3651 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 @@ -51,6 +54,7 @@ [PR 3884]: https://github.com/libp2p/rust-libp2p/pull/3884 [PR 3885]: https://github.com/libp2p/rust-libp2p/pull/3885 [PR 3886]: https://github.com/libp2p/rust-libp2p/pull/3886 +[PR 3912]: https://github.com/libp2p/rust-libp2p/pull/3912 ## 0.42.2 diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 699e0c74b83..483c65f8dfd 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -26,6 +26,7 @@ void = "1" wasm-bindgen-futures = { version = "0.4.34", optional = true } getrandom = { version = "0.2.9", features = ["js"], optional = true } # Explicit dependency to be used in `wasm-bindgen` feature once_cell = "1.17.1" +multistream-select = { workspace = true } [target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))'.dependencies] async-std = { version = "1.6.2", optional = true } diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index 32a24161393..30f95a29317 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -34,10 +34,12 @@ use crate::handler::{ FullyNegotiatedOutbound, ListenUpgradeError, ProtocolSupport, ProtocolsAdded, ProtocolsChange, UpgradeInfoSend, }; -use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper}; +use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend}; use crate::{ - ConnectionHandlerEvent, KeepAlive, StreamProtocol, StreamUpgradeError, SubstreamProtocol, + ConnectionHandlerEvent, KeepAlive, Stream, StreamProtocol, StreamUpgradeError, + SubstreamProtocol, }; +use futures::future::BoxFuture; use futures::stream::FuturesUnordered; use futures::FutureExt; use futures::StreamExt; @@ -47,9 +49,7 @@ use libp2p_core::connection::ConnectedPoint; use libp2p_core::multiaddr::Multiaddr; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerEvent, StreamMuxerExt, SubstreamBox}; use libp2p_core::upgrade; -use libp2p_core::upgrade::{ - InboundUpgradeApply, NegotiationError, OutboundUpgradeApply, ProtocolError, -}; +use libp2p_core::upgrade::{NegotiationError, ProtocolError}; use libp2p_core::Endpoint; use libp2p_identity::PeerId; use std::collections::HashSet; @@ -120,16 +120,18 @@ where handler: THandler, /// Futures that upgrade incoming substreams. negotiating_in: FuturesUnordered< - SubstreamUpgrade< + StreamUpgrade< THandler::InboundOpenInfo, - InboundUpgradeApply>, + ::Output, + ::Error, >, >, /// Futures that upgrade outgoing substreams. negotiating_out: FuturesUnordered< - SubstreamUpgrade< + StreamUpgrade< THandler::OutboundOpenInfo, - OutboundUpgradeApply>, + ::Output, + ::Error, >, >, /// The currently planned connection & handler shutdown. @@ -396,7 +398,7 @@ where Poll::Ready(substream) => { let (user_data, timeout, upgrade) = requested_substream.extract(); - negotiating_out.push(SubstreamUpgrade::new_outbound( + negotiating_out.push(StreamUpgrade::new_outbound( substream, user_data, timeout, @@ -415,7 +417,7 @@ where Poll::Ready(substream) => { let protocol = handler.listen_protocol(); - negotiating_in.push(SubstreamUpgrade::new_inbound(substream, protocol)); + negotiating_in.push(StreamUpgrade::new_inbound(substream, protocol)); continue; // Go back to the top, handler can potentially make progress again. } @@ -470,24 +472,23 @@ impl<'a> IncomingInfo<'a> { } } -struct SubstreamUpgrade { +struct StreamUpgrade { user_data: Option, timeout: Delay, - upgrade: Upgrade, + upgrade: BoxFuture<'static, Result>>, } -impl - SubstreamUpgrade>> -where - Upgrade: Send + OutboundUpgradeSend, -{ - fn new_outbound( +impl StreamUpgrade { + fn new_outbound( substream: SubstreamBox, user_data: UserData, timeout: Delay, upgrade: Upgrade, version_override: Option, - ) -> Self { + ) -> Self + where + Upgrade: OutboundUpgradeSend, + { let effective_version = match version_override { Some(version_override) if version_override != upgrade::Version::default() => { log::debug!( @@ -500,45 +501,77 @@ where } _ => upgrade::Version::default(), }; + let protocols = upgrade.protocol_info(); Self { user_data: Some(user_data), timeout, - upgrade: upgrade::apply_outbound(substream, SendWrapper(upgrade), effective_version), + upgrade: Box::pin(async move { + let (info, stream) = multistream_select::dialer_select_proto( + substream, + protocols, + effective_version, + ) + .await + .map_err(to_stream_upgrade_error)?; + + let output = upgrade + .upgrade_outbound(Stream::new(stream), info) + .await + .map_err(StreamUpgradeError::Apply)?; + + Ok(output) + }), } } } -impl - SubstreamUpgrade>> -where - Upgrade: Send + InboundUpgradeSend, -{ - fn new_inbound( +impl StreamUpgrade { + fn new_inbound( substream: SubstreamBox, protocol: SubstreamProtocol, - ) -> Self { + ) -> Self + where + Upgrade: InboundUpgradeSend, + { let timeout = *protocol.timeout(); let (upgrade, open_info) = protocol.into_upgrade(); + let protocols = upgrade.protocol_info(); Self { user_data: Some(open_info), timeout: Delay::new(timeout), - upgrade: upgrade::apply_inbound(substream, SendWrapper(upgrade)), + upgrade: Box::pin(async move { + let (info, stream) = + multistream_select::listener_select_proto(substream, protocols) + .await + .map_err(to_stream_upgrade_error)?; + + let output = upgrade + .upgrade_inbound(Stream::new(stream), info) + .await + .map_err(StreamUpgradeError::Apply)?; + + Ok(output) + }), + } + } +} + +fn to_stream_upgrade_error(e: NegotiationError) -> StreamUpgradeError { + match e { + NegotiationError::Failed => StreamUpgradeError::NegotiationFailed, + NegotiationError::ProtocolError(ProtocolError::IoError(e)) => StreamUpgradeError::Io(e), + NegotiationError::ProtocolError(other) => { + StreamUpgradeError::Io(io::Error::new(io::ErrorKind::Other, other)) } } } -impl Unpin for SubstreamUpgrade {} +impl Unpin for StreamUpgrade {} -impl Future for SubstreamUpgrade -where - Upgrade: Future>> + Unpin, -{ - type Output = ( - UserData, - Result>, - ); +impl Future for StreamUpgrade { + type Output = (UserData, Result>); fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll { match self.timeout.poll_unpin(cx) { @@ -560,21 +593,7 @@ where .take() .expect("Future not to be polled again once ready."); - Poll::Ready(( - user_data, - result.map_err(|e| match e { - upgrade::UpgradeError::Select(NegotiationError::Failed) => { - StreamUpgradeError::NegotiationFailed - } - upgrade::UpgradeError::Select(NegotiationError::ProtocolError( - ProtocolError::IoError(e), - )) => StreamUpgradeError::Io(e), - upgrade::UpgradeError::Select(NegotiationError::ProtocolError(other)) => { - StreamUpgradeError::Io(io::Error::new(io::ErrorKind::Other, other)) - } - upgrade::UpgradeError::Apply(e) => StreamUpgradeError::Apply(e), - }), - )) + Poll::Ready((user_data, result)) } } diff --git a/swarm/src/handler/multi.rs b/swarm/src/handler/multi.rs index 61c357b6597..5caf611278f 100644 --- a/swarm/src/handler/multi.rs +++ b/swarm/src/handler/multi.rs @@ -27,7 +27,7 @@ use crate::handler::{ SubstreamProtocol, }; use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend}; -use crate::NegotiatedSubstream; +use crate::Stream; use futures::{future::BoxFuture, prelude::*}; use rand::Rng; use std::{ @@ -373,7 +373,7 @@ where type Error = (K, ::Error); type Future = BoxFuture<'static, Result>; - fn upgrade_inbound(mut self, resource: NegotiatedSubstream, info: Self::Info) -> Self::Future { + fn upgrade_inbound(mut self, resource: Stream, info: Self::Info) -> Self::Future { let IndexedProtoName(index, info) = info; let (key, upgrade) = self.upgrades.remove(index); upgrade @@ -395,7 +395,7 @@ where type Error = (K, ::Error); type Future = BoxFuture<'static, Result>; - fn upgrade_outbound(mut self, resource: NegotiatedSubstream, info: Self::Info) -> Self::Future { + fn upgrade_outbound(mut self, resource: Stream, info: Self::Info) -> Self::Future { let IndexedProtoName(index, info) = info; let (key, upgrade) = self.upgrades.remove(index); upgrade diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index a32beda411b..0796a26f593 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -58,6 +58,7 @@ mod connection; mod executor; mod registry; +mod stream; mod stream_protocol; #[cfg(test)] mod test; @@ -125,6 +126,7 @@ pub use handler::{ #[cfg(feature = "macros")] pub use libp2p_swarm_derive::NetworkBehaviour; pub use registry::{AddAddressResult, AddressRecord, AddressScore}; +pub use stream::Stream; pub use stream_protocol::{InvalidProtocol, StreamProtocol}; use crate::handler::UpgradeInfoSend; @@ -135,14 +137,13 @@ use connection::{ }; use dial_opts::{DialOpts, PeerCondition}; use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream}; -use libp2p_core::muxing::SubstreamBox; use libp2p_core::{ connection::ConnectedPoint, multiaddr, multihash::Multihash, muxing::StreamMuxerBox, transport::{self, ListenerId, TransportError, TransportEvent}, - Endpoint, Multiaddr, Negotiated, Transport, + Endpoint, Multiaddr, Transport, }; use libp2p_identity::PeerId; use registry::{AddressIntoIter, Addresses}; @@ -160,7 +161,8 @@ use std::{ /// /// Implements the [`AsyncRead`](futures::io::AsyncRead) and /// [`AsyncWrite`](futures::io::AsyncWrite) traits. -pub type NegotiatedSubstream = Negotiated; +#[deprecated(note = "The 'substream' terminology is deprecated. Use 'Stream' instead")] +pub type NegotiatedSubstream = Stream; /// Event generated by the [`NetworkBehaviour`] that the swarm will report back. type TBehaviourOutEvent = ::OutEvent; @@ -1378,8 +1380,8 @@ where /// connection and listener status. See [`SwarmEvent`] for details. /// /// Note: This stream is infinite and it is guaranteed that -/// [`Stream::poll_next`] will never return `Poll::Ready(None)`. -impl Stream for Swarm +/// [`futures::Stream::poll_next`] will never return `Poll::Ready(None)`. +impl futures::Stream for Swarm where TBehaviour: NetworkBehaviour, { diff --git a/swarm/src/stream.rs b/swarm/src/stream.rs new file mode 100644 index 00000000000..3c4c52afc33 --- /dev/null +++ b/swarm/src/stream.rs @@ -0,0 +1,59 @@ +use futures::{AsyncRead, AsyncWrite}; +use libp2p_core::muxing::SubstreamBox; +use libp2p_core::Negotiated; +use std::io::{IoSlice, IoSliceMut}; +use std::pin::Pin; +use std::task::{Context, Poll}; + +#[derive(Debug)] +pub struct Stream(Negotiated); + +impl Stream { + pub(crate) fn new(stream: Negotiated) -> Self { + Self(stream) + } +} + +impl AsyncRead for Stream { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_read(cx, buf) + } + + fn poll_read_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &mut [IoSliceMut<'_>], + ) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_read_vectored(cx, bufs) + } +} + +impl AsyncWrite for Stream { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_write(cx, buf) + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>], + ) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_write_vectored(cx, bufs) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_flush(cx) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_close(cx) + } +} diff --git a/swarm/src/upgrade.rs b/swarm/src/upgrade.rs index b584dfae9fd..53b627458c9 100644 --- a/swarm/src/upgrade.rs +++ b/swarm/src/upgrade.rs @@ -18,7 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::NegotiatedSubstream; +use crate::Stream; use futures::prelude::*; use libp2p_core::upgrade; @@ -66,12 +66,12 @@ pub trait OutboundUpgradeSend: UpgradeInfoSend { type Future: Future> + Send + 'static; /// Equivalent to [`OutboundUpgrade::upgrade_outbound`](upgrade::OutboundUpgrade::upgrade_outbound). - fn upgrade_outbound(self, socket: NegotiatedSubstream, info: Self::Info) -> Self::Future; + fn upgrade_outbound(self, socket: Stream, info: Self::Info) -> Self::Future; } impl OutboundUpgradeSend for T where - T: upgrade::OutboundUpgrade + UpgradeInfoSend, + T: upgrade::OutboundUpgrade + UpgradeInfoSend, TInfo: AsRef + Clone + Send + 'static, T::Output: Send + 'static, T::Error: Send + 'static, @@ -81,7 +81,7 @@ where type Error = T::Error; type Future = T::Future; - fn upgrade_outbound(self, socket: NegotiatedSubstream, info: TInfo) -> Self::Future { + fn upgrade_outbound(self, socket: Stream, info: TInfo) -> Self::Future { upgrade::OutboundUpgrade::upgrade_outbound(self, socket, info) } } @@ -100,12 +100,12 @@ pub trait InboundUpgradeSend: UpgradeInfoSend { type Future: Future> + Send + 'static; /// Equivalent to [`InboundUpgrade::upgrade_inbound`](upgrade::InboundUpgrade::upgrade_inbound). - fn upgrade_inbound(self, socket: NegotiatedSubstream, info: Self::Info) -> Self::Future; + fn upgrade_inbound(self, socket: Stream, info: Self::Info) -> Self::Future; } impl InboundUpgradeSend for T where - T: upgrade::InboundUpgrade + UpgradeInfoSend, + T: upgrade::InboundUpgrade + UpgradeInfoSend, TInfo: AsRef + Clone + Send + 'static, T::Output: Send + 'static, T::Error: Send + 'static, @@ -115,7 +115,7 @@ where type Error = T::Error; type Future = T::Future; - fn upgrade_inbound(self, socket: NegotiatedSubstream, info: TInfo) -> Self::Future { + fn upgrade_inbound(self, socket: Stream, info: TInfo) -> Self::Future { upgrade::InboundUpgrade::upgrade_inbound(self, socket, info) } } @@ -137,22 +137,22 @@ impl upgrade::UpgradeInfo for SendWrapper { } } -impl upgrade::OutboundUpgrade for SendWrapper { +impl upgrade::OutboundUpgrade for SendWrapper { type Output = T::Output; type Error = T::Error; type Future = T::Future; - fn upgrade_outbound(self, socket: NegotiatedSubstream, info: T::Info) -> Self::Future { + fn upgrade_outbound(self, socket: Stream, info: T::Info) -> Self::Future { OutboundUpgradeSend::upgrade_outbound(self.0, socket, info) } } -impl upgrade::InboundUpgrade for SendWrapper { +impl upgrade::InboundUpgrade for SendWrapper { type Output = T::Output; type Error = T::Error; type Future = T::Future; - fn upgrade_inbound(self, socket: NegotiatedSubstream, info: T::Info) -> Self::Future { + fn upgrade_inbound(self, socket: Stream, info: T::Info) -> Self::Future { InboundUpgradeSend::upgrade_inbound(self.0, socket, info) } } From 5b32c8a0d21c13c8313992b0aa7b2251e3f6003f Mon Sep 17 00:00:00 2001 From: Darius Clark Date: Sun, 14 May 2023 05:42:51 -0400 Subject: [PATCH 06/38] feat(transport): allow `ListenerId` to be user-controlled `Transport::listen_on` is an asynchronous operation. It returns immediately but the actual process of establishing a listening socket happens as part of `Transport::poll` which will return one or more `TransportEvent`s related to a particular `listen_on` call. Currently, `listen_on` returns a `ListenerId` which allows the user of the `Transport` interface to correlate the events with a particular `listen_on` call. This "user" is the `Swarm` runtime. Currently, a user of libp2p establishes a new listening socket by talking to the `Swarm::listen_on` interface and it is not possible to do the same thing via the `NetworkBehaviour` trait. Within the `NetworkBehaviour` trait, we emit _commands_ to the `Swarm` like `ToSwarm::Dial`. These commands don't have a "return value" like a synchronous function does and thus, if we were to add a `ToSwarm::ListenOn` command, it could not receive the `ListenerId` from the `Transport`. To fix this and to be consistent with our [coding guidelines](https://github.com/libp2p/rust-libp2p/blob/master/docs/coding-guidelines.md#allow-correlating-asynchronous-responses-to-their-requests) we change the interface of `Transport::listen_on` to require the user to pass in a `ListenerId`. This will allow us to construct a command in a `NetworkBehaviour` that remembers this ID which enables precise tracking of which events containing a `ListenerId` correlate which a particular `listen_on` command. This is especially important in the context of listening on wildcard addresses like `0.0.0.0` because we end up binding to multiple network interfaces and thus emit multiple events for a single `listen_on` call. Pull-Request: #3567. --- core/CHANGELOG.md | 4 ++ core/src/either.rs | 10 ++-- core/src/transport.rs | 30 ++++++++--- core/src/transport/and_then.rs | 8 ++- core/src/transport/boxed.rs | 22 ++++++-- core/src/transport/choice.rs | 10 ++-- core/src/transport/dummy.rs | 6 ++- core/src/transport/global_only.rs | 8 ++- core/src/transport/map.rs | 8 ++- core/src/transport/map_err.rs | 10 +++- core/src/transport/memory.rs | 55 ++++++++++++++------ core/src/transport/optional.rs | 8 ++- core/src/transport/timeout.rs | 8 ++- core/src/transport/upgrade.rs | 16 ++++-- core/tests/transport_upgrade.rs | 6 ++- muxers/mplex/benches/split_send_size.rs | 5 +- protocols/ping/src/protocol.rs | 4 +- protocols/relay/src/priv_client/transport.rs | 13 +++-- swarm/src/behaviour/listen_addresses.rs | 6 +-- swarm/src/lib.rs | 7 ++- transports/dns/src/lib.rs | 11 ++-- transports/quic/src/lib.rs | 4 +- transports/quic/src/transport.rs | 21 +++++--- transports/quic/tests/smoke.rs | 14 +++-- transports/quic/tests/stream_compliance.rs | 6 ++- transports/tcp/src/lib.rs | 35 +++++++------ transports/tcp/src/provider/async_io.rs | 5 +- transports/tcp/src/provider/tokio.rs | 4 +- transports/uds/src/lib.rs | 11 ++-- transports/wasm-ext/src/lib.rs | 9 ++-- transports/webrtc/src/tokio/transport.rs | 18 ++++--- transports/webrtc/tests/smoke.rs | 6 ++- transports/websocket/src/framed.rs | 12 +++-- transports/websocket/src/lib.rs | 22 +++++--- 34 files changed, 289 insertions(+), 133 deletions(-) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index ad06aefa872..ea2d14a30fb 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,11 +1,15 @@ ## 0.40.0 - unreleased +- Allow `ListenerId` to be user-controlled, i.e. to be provided on `Transport::listen_on`. + See [PR 3567]. + - Raise MSRV to 1.65. See [PR 3715]. - Remove deprecated symbols related to upgrades. See [PR 3867]. +[PR 3567]: https://github.com/libp2p/rust-libp2p/pull/3567 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 [PR 3867]: https://github.com/libp2p/rust-libp2p/pull/3867 diff --git a/core/src/either.rs b/core/src/either.rs index 32e09ca691c..3f79b2b37a9 100644 --- a/core/src/either.rs +++ b/core/src/either.rs @@ -154,14 +154,18 @@ where } } - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { use TransportError::*; match self { - Either::Left(a) => a.listen_on(addr).map_err(|e| match e { + Either::Left(a) => a.listen_on(id, addr).map_err(|e| match e { MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr), Other(err) => Other(Either::Left(err)), }), - Either::Right(b) => b.listen_on(addr).map_err(|e| match e { + Either::Right(b) => b.listen_on(id, addr).map_err(|e| match e { MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr), Other(err) => Other(Either::Right(err)), }), diff --git a/core/src/transport.rs b/core/src/transport.rs index ca1796b3b35..c98612971db 100644 --- a/core/src/transport.rs +++ b/core/src/transport.rs @@ -31,6 +31,7 @@ use std::{ error::Error, fmt, pin::Pin, + sync::atomic::{AtomicUsize, Ordering}, task::{Context, Poll}, }; @@ -55,6 +56,8 @@ pub use self::memory::MemoryTransport; pub use self::optional::OptionalTransport; pub use self::upgrade::Upgrade; +static NEXT_LISTENER_ID: AtomicUsize = AtomicUsize::new(1); + /// A transport provides connection-oriented communication between two peers /// through ordered streams of data (i.e. connections). /// @@ -109,8 +112,12 @@ pub trait Transport { /// obtained from [dialing](Transport::dial). type Dial: Future>; - /// Listens on the given [`Multiaddr`] for inbound connections. - fn listen_on(&mut self, addr: Multiaddr) -> Result>; + /// Listens on the given [`Multiaddr`] for inbound connections with a provided [`ListenerId`]. + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError>; /// Remove a listener. /// @@ -241,18 +248,25 @@ pub trait Transport { /// The ID of a single listener. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct ListenerId(u64); +pub struct ListenerId(usize); impl ListenerId { + #[deprecated(note = "Renamed to ` ListenerId::next`.")] + #[allow(clippy::new_without_default)] /// Creates a new `ListenerId`. pub fn new() -> Self { - ListenerId(rand::random()) + ListenerId::next() + } + + /// Creates a new `ListenerId`. + pub fn next() -> Self { + ListenerId(NEXT_LISTENER_ID.fetch_add(1, Ordering::SeqCst)) } -} -impl Default for ListenerId { - fn default() -> Self { - Self::new() + #[deprecated(note = "Use ` ListenerId::next` instead.")] + #[allow(clippy::should_implement_trait)] + pub fn default() -> Self { + Self::next() } } diff --git a/core/src/transport/and_then.rs b/core/src/transport/and_then.rs index fb5280568ea..6e0c7e32067 100644 --- a/core/src/transport/and_then.rs +++ b/core/src/transport/and_then.rs @@ -54,9 +54,13 @@ where type ListenerUpgrade = AndThenFuture; type Dial = AndThenFuture; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { self.transport - .listen_on(addr) + .listen_on(id, addr) .map_err(|err| err.map(Either::Left)) } diff --git a/core/src/transport/boxed.rs b/core/src/transport/boxed.rs index a55e4db8466..8274d557e61 100644 --- a/core/src/transport/boxed.rs +++ b/core/src/transport/boxed.rs @@ -52,7 +52,11 @@ type Dial = Pin> + Send>>; type ListenerUpgrade = Pin> + Send>>; trait Abstract { - fn listen_on(&mut self, addr: Multiaddr) -> Result>; + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError>; fn remove_listener(&mut self, id: ListenerId) -> bool; fn dial(&mut self, addr: Multiaddr) -> Result, TransportError>; fn dial_as_listener(&mut self, addr: Multiaddr) -> Result, TransportError>; @@ -70,8 +74,12 @@ where T::Dial: Send + 'static, T::ListenerUpgrade: Send + 'static, { - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - Transport::listen_on(self, addr).map_err(|e| e.map(box_err)) + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + Transport::listen_on(self, id, addr).map_err(|e| e.map(box_err)) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -123,8 +131,12 @@ impl Transport for Boxed { type ListenerUpgrade = ListenerUpgrade; type Dial = Dial; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - self.inner.listen_on(addr) + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + self.inner.listen_on(id, addr) } fn remove_listener(&mut self, id: ListenerId) -> bool { diff --git a/core/src/transport/choice.rs b/core/src/transport/choice.rs index bb7d542d292..b7eaacabfeb 100644 --- a/core/src/transport/choice.rs +++ b/core/src/transport/choice.rs @@ -46,13 +46,17 @@ where type ListenerUpgrade = EitherFuture; type Dial = EitherFuture; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - let addr = match self.0.listen_on(addr) { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + let addr = match self.0.listen_on(id, addr) { Err(TransportError::MultiaddrNotSupported(addr)) => addr, res => return res.map_err(|err| err.map(Either::Left)), }; - let addr = match self.1.listen_on(addr) { + let addr = match self.1.listen_on(id, addr) { Err(TransportError::MultiaddrNotSupported(addr)) => addr, res => return res.map_err(|err| err.map(Either::Right)), }; diff --git a/core/src/transport/dummy.rs b/core/src/transport/dummy.rs index a7d1cab9089..951d1039328 100644 --- a/core/src/transport/dummy.rs +++ b/core/src/transport/dummy.rs @@ -59,7 +59,11 @@ impl Transport for DummyTransport { type ListenerUpgrade = futures::future::Pending>; type Dial = futures::future::Pending>; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + _id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { Err(TransportError::MultiaddrNotSupported(addr)) } diff --git a/core/src/transport/global_only.rs b/core/src/transport/global_only.rs index b0a12de0f70..4f1fe8ab794 100644 --- a/core/src/transport/global_only.rs +++ b/core/src/transport/global_only.rs @@ -276,8 +276,12 @@ impl crate::Transport for Transport { type ListenerUpgrade = ::ListenerUpgrade; type Dial = ::Dial; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - self.inner.listen_on(addr) + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + self.inner.listen_on(id, addr) } fn remove_listener(&mut self, id: ListenerId) -> bool { diff --git a/core/src/transport/map.rs b/core/src/transport/map.rs index 50f7b826d36..553f3e6338d 100644 --- a/core/src/transport/map.rs +++ b/core/src/transport/map.rs @@ -61,8 +61,12 @@ where type ListenerUpgrade = MapFuture; type Dial = MapFuture; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - self.transport.listen_on(addr) + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + self.transport.listen_on(id, addr) } fn remove_listener(&mut self, id: ListenerId) -> bool { diff --git a/core/src/transport/map_err.rs b/core/src/transport/map_err.rs index 99f2912447f..56e1ebf2929 100644 --- a/core/src/transport/map_err.rs +++ b/core/src/transport/map_err.rs @@ -50,9 +50,15 @@ where type ListenerUpgrade = MapErrListenerUpgrade; type Dial = MapErrDial; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let map = self.map.clone(); - self.transport.listen_on(addr).map_err(|err| err.map(map)) + self.transport + .listen_on(id, addr) + .map_err(|err| err.map(map)) } fn remove_listener(&mut self, id: ListenerId) -> bool { diff --git a/core/src/transport/memory.rs b/core/src/transport/memory.rs index 7e079d07fb5..4c30ee9b65d 100644 --- a/core/src/transport/memory.rs +++ b/core/src/transport/memory.rs @@ -179,7 +179,11 @@ impl Transport for MemoryTransport { type ListenerUpgrade = Ready>; type Dial = DialFuture; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let port = if let Ok(port) = parse_memory_addr(&addr) { port } else { @@ -191,7 +195,6 @@ impl Transport for MemoryTransport { None => return Err(TransportError::Other(MemoryTransportError::Unreachable)), }; - let id = ListenerId::new(); let listener = Listener { id, port, @@ -201,7 +204,7 @@ impl Transport for MemoryTransport { }; self.listeners.push_back(Box::pin(listener)); - Ok(id) + Ok(()) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -457,30 +460,40 @@ mod tests { let addr_1: Multiaddr = "/memory/1639174018481".parse().unwrap(); let addr_2: Multiaddr = "/memory/8459375923478".parse().unwrap(); - let listener_id_1 = transport.listen_on(addr_1.clone()).unwrap(); + let listener_id_1 = ListenerId::next(); + + transport.listen_on(listener_id_1, addr_1.clone()).unwrap(); assert!( transport.remove_listener(listener_id_1), "Listener doesn't exist." ); - let listener_id_2 = transport.listen_on(addr_1.clone()).unwrap(); - let listener_id_3 = transport.listen_on(addr_2.clone()).unwrap(); + let listener_id_2 = ListenerId::next(); + transport.listen_on(listener_id_2, addr_1.clone()).unwrap(); + let listener_id_3 = ListenerId::next(); + transport.listen_on(listener_id_3, addr_2.clone()).unwrap(); - assert!(transport.listen_on(addr_1.clone()).is_err()); - assert!(transport.listen_on(addr_2.clone()).is_err()); + assert!(transport + .listen_on(ListenerId::next(), addr_1.clone()) + .is_err()); + assert!(transport + .listen_on(ListenerId::next(), addr_2.clone()) + .is_err()); assert!( transport.remove_listener(listener_id_2), "Listener doesn't exist." ); - assert!(transport.listen_on(addr_1).is_ok()); - assert!(transport.listen_on(addr_2.clone()).is_err()); + assert!(transport.listen_on(ListenerId::next(), addr_1).is_ok()); + assert!(transport + .listen_on(ListenerId::next(), addr_2.clone()) + .is_err()); assert!( transport.remove_listener(listener_id_3), "Listener doesn't exist." ); - assert!(transport.listen_on(addr_2).is_ok()); + assert!(transport.listen_on(ListenerId::next(), addr_2).is_ok()); } #[test] @@ -489,8 +502,11 @@ mod tests { assert!(transport .dial("/memory/810172461024613".parse().unwrap()) .is_err()); - let _listener = transport - .listen_on("/memory/810172461024613".parse().unwrap()) + transport + .listen_on( + ListenerId::next(), + "/memory/810172461024613".parse().unwrap(), + ) .unwrap(); assert!(transport .dial("/memory/810172461024613".parse().unwrap()) @@ -504,7 +520,8 @@ mod tests { let mut transport = MemoryTransport::default().boxed(); futures::executor::block_on(async { - let listener_id = transport.listen_on(addr.clone()).unwrap(); + let listener_id = ListenerId::next(); + transport.listen_on(listener_id, addr.clone()).unwrap(); let reported_addr = transport .select_next_some() .await @@ -539,7 +556,7 @@ mod tests { let mut t1 = MemoryTransport::default().boxed(); let listener = async move { - t1.listen_on(t1_addr.clone()).unwrap(); + t1.listen_on(ListenerId::next(), t1_addr.clone()).unwrap(); let upgrade = loop { let event = t1.select_next_some().await; if let Some(upgrade) = event.into_incoming() { @@ -577,7 +594,9 @@ mod tests { let mut listener_transport = MemoryTransport::default().boxed(); let listener = async move { - listener_transport.listen_on(listener_addr.clone()).unwrap(); + listener_transport + .listen_on(ListenerId::next(), listener_addr.clone()) + .unwrap(); loop { if let TransportEvent::Incoming { send_back_addr, .. } = listener_transport.select_next_some().await @@ -614,7 +633,9 @@ mod tests { let mut listener_transport = MemoryTransport::default().boxed(); let listener = async move { - listener_transport.listen_on(listener_addr.clone()).unwrap(); + listener_transport + .listen_on(ListenerId::next(), listener_addr.clone()) + .unwrap(); loop { if let TransportEvent::Incoming { send_back_addr, .. } = listener_transport.select_next_some().await diff --git a/core/src/transport/optional.rs b/core/src/transport/optional.rs index 2d93077659c..839f55a4000 100644 --- a/core/src/transport/optional.rs +++ b/core/src/transport/optional.rs @@ -60,9 +60,13 @@ where type ListenerUpgrade = T::ListenerUpgrade; type Dial = T::Dial; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { if let Some(inner) = self.0.as_mut() { - inner.listen_on(addr) + inner.listen_on(id, addr) } else { Err(TransportError::MultiaddrNotSupported(addr)) } diff --git a/core/src/transport/timeout.rs b/core/src/transport/timeout.rs index c796e6f0775..0e8ab3f5201 100644 --- a/core/src/transport/timeout.rs +++ b/core/src/transport/timeout.rs @@ -85,9 +85,13 @@ where type ListenerUpgrade = Timeout; type Dial = Timeout; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { self.inner - .listen_on(addr) + .listen_on(id, addr) .map_err(|err| err.map(TransportTimeoutError::Other)) } diff --git a/core/src/transport/upgrade.rs b/core/src/transport/upgrade.rs index 9f6998d9968..201918f2635 100644 --- a/core/src/transport/upgrade.rs +++ b/core/src/transport/upgrade.rs @@ -350,8 +350,12 @@ where self.0.dial_as_listener(addr) } - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - self.0.listen_on(addr) + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + self.0.listen_on(id, addr) } fn address_translation(&self, server: &Multiaddr, observed: &Multiaddr) -> Option { @@ -429,9 +433,13 @@ where }) } - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { self.inner - .listen_on(addr) + .listen_on(id, addr) .map_err(|err| err.map(TransportUpgradeError::Transport)) } diff --git a/core/tests/transport_upgrade.rs b/core/tests/transport_upgrade.rs index ac724a64ffa..193ee73cbc8 100644 --- a/core/tests/transport_upgrade.rs +++ b/core/tests/transport_upgrade.rs @@ -19,7 +19,7 @@ // DEALINGS IN THE SOFTWARE. use futures::prelude::*; -use libp2p_core::transport::{MemoryTransport, Transport}; +use libp2p_core::transport::{ListenerId, MemoryTransport, Transport}; use libp2p_core::upgrade::{self, InboundUpgrade, OutboundUpgrade, UpgradeInfo}; use libp2p_identity as identity; use libp2p_mplex::MplexConfig; @@ -102,7 +102,9 @@ fn upgrade_pipeline() { let listen_addr1 = Multiaddr::from(Protocol::Memory(random::())); let listen_addr2 = listen_addr1.clone(); - listener_transport.listen_on(listen_addr1).unwrap(); + listener_transport + .listen_on(ListenerId::next(), listen_addr1) + .unwrap(); let server = async move { loop { diff --git a/muxers/mplex/benches/split_send_size.rs b/muxers/mplex/benches/split_send_size.rs index 56bd934f302..dfdc619afb1 100644 --- a/muxers/mplex/benches/split_send_size.rs +++ b/muxers/mplex/benches/split_send_size.rs @@ -27,6 +27,7 @@ use futures::future::poll_fn; use futures::prelude::*; use futures::{channel::oneshot, future::join}; use libp2p_core::muxing::StreamMuxerExt; +use libp2p_core::transport::ListenerId; use libp2p_core::{multiaddr::multiaddr, muxing, transport, upgrade, Multiaddr, Transport}; use libp2p_identity as identity; use libp2p_identity::PeerId; @@ -100,7 +101,9 @@ fn run( payload: &Vec, listen_addr: &Multiaddr, ) { - receiver_trans.listen_on(listen_addr.clone()).unwrap(); + receiver_trans + .listen_on(ListenerId::next(), listen_addr.clone()) + .unwrap(); let (addr_sender, addr_receiver) = oneshot::channel(); let mut addr_sender = Some(addr_sender); let payload_len = payload.len(); diff --git a/protocols/ping/src/protocol.rs b/protocols/ping/src/protocol.rs index 34f816522d9..59e583a8b3b 100644 --- a/protocols/ping/src/protocol.rs +++ b/protocols/ping/src/protocol.rs @@ -88,7 +88,7 @@ mod tests { use futures::StreamExt; use libp2p_core::{ multiaddr::multiaddr, - transport::{memory::MemoryTransport, Transport}, + transport::{memory::MemoryTransport, ListenerId, Transport}, }; use rand::{thread_rng, Rng}; use std::time::Duration; @@ -97,7 +97,7 @@ mod tests { fn ping_pong() { let mem_addr = multiaddr![Memory(thread_rng().gen::())]; let mut transport = MemoryTransport::new().boxed(); - transport.listen_on(mem_addr).unwrap(); + transport.listen_on(ListenerId::next(), mem_addr).unwrap(); let listener_addr = transport .select_next_some() diff --git a/protocols/relay/src/priv_client/transport.rs b/protocols/relay/src/priv_client/transport.rs index 6dceefd8661..23e0e34e237 100644 --- a/protocols/relay/src/priv_client/transport.rs +++ b/protocols/relay/src/priv_client/transport.rs @@ -70,7 +70,7 @@ use thiserror::Error; /// 3. Listen for incoming relayed connections via specific relay. /// /// ``` -/// # use libp2p_core::{Multiaddr, multiaddr::{Protocol}, Transport, PeerId}; +/// # use libp2p_core::{Multiaddr, multiaddr::{Protocol}, transport::ListenerId, Transport, PeerId}; /// # use libp2p_core::transport::memory::MemoryTransport; /// # use libp2p_core::transport::choice::OrTransport; /// # use libp2p_relay as relay; @@ -85,7 +85,7 @@ use thiserror::Error; /// .with(Protocol::Memory(40)) // Relay address. /// .with(Protocol::P2p(relay_id.into())) // Relay peer id. /// .with(Protocol::P2pCircuit); // Signal to listen via remote relay node. -/// transport.listen_on(relay_addr).unwrap(); +/// transport.listen_on(ListenerId::next(), relay_addr).unwrap(); /// ``` pub struct Transport { to_behaviour: mpsc::Sender, @@ -111,7 +111,11 @@ impl libp2p_core::Transport for Transport { type ListenerUpgrade = Ready>; type Dial = BoxFuture<'static, Result>; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + listener_id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let (relay_peer_id, relay_addr) = match parse_relayed_multiaddr(addr)? { RelayedMultiaddr { relay_peer_id: None, @@ -138,7 +142,6 @@ impl libp2p_core::Transport for Transport { to_listener, }); - let listener_id = ListenerId::new(); let listener = Listener { listener_id, queued_events: Default::default(), @@ -146,7 +149,7 @@ impl libp2p_core::Transport for Transport { is_closed: false, }; self.listeners.push(listener); - Ok(listener_id) + Ok(()) } fn remove_listener(&mut self, id: ListenerId) -> bool { diff --git a/swarm/src/behaviour/listen_addresses.rs b/swarm/src/behaviour/listen_addresses.rs index 2a8adb8f573..8882db64a50 100644 --- a/swarm/src/behaviour/listen_addresses.rs +++ b/swarm/src/behaviour/listen_addresses.rs @@ -34,7 +34,7 @@ impl ListenAddresses { mod tests { use super::*; use crate::dummy; - use libp2p_core::multiaddr::Protocol; + use libp2p_core::{multiaddr::Protocol, transport::ListenerId}; use once_cell::sync::Lazy; #[test] @@ -62,14 +62,14 @@ mod tests { fn new_listen_addr() -> FromSwarm<'static, dummy::ConnectionHandler> { FromSwarm::NewListenAddr(NewListenAddr { - listener_id: Default::default(), + listener_id: ListenerId::next(), addr: &MEMORY_ADDR, }) } fn expired_listen_addr() -> FromSwarm<'static, dummy::ConnectionHandler> { FromSwarm::ExpiredListenAddr(ExpiredListenAddr { - listener_id: Default::default(), + listener_id: ListenerId::next(), addr: &MEMORY_ADDR, }) } diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 0796a26f593..3360a0bfa99 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -474,7 +474,8 @@ where /// Listeners report their new listening addresses as [`SwarmEvent::NewListenAddr`]. /// Depending on the underlying transport, one listener may have multiple listening addresses. pub fn listen_on(&mut self, addr: Multiaddr) -> Result> { - let id = self.transport.listen_on(addr)?; + let id = ListenerId::next(); + self.transport.listen_on(id, addr)?; self.behaviour .on_swarm_event(FromSwarm::NewListener(behaviour::NewListener { listener_id: id, @@ -2222,7 +2223,9 @@ mod tests { let mut transports = Vec::new(); for _ in 0..num_listen_addrs { let mut transport = transport::MemoryTransport::default().boxed(); - transport.listen_on("/memory/0".parse().unwrap()).unwrap(); + transport + .listen_on(ListenerId::next(), "/memory/0".parse().unwrap()) + .unwrap(); match transport.select_next_some().await { TransportEvent::NewAddress { listen_addr, .. } => { diff --git a/transports/dns/src/lib.rs b/transports/dns/src/lib.rs index 7de86ba358c..c39b9ad05ec 100644 --- a/transports/dns/src/lib.rs +++ b/transports/dns/src/lib.rs @@ -198,10 +198,14 @@ where BoxFuture<'static, Result>, >; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { self.inner .lock() - .listen_on(addr) + .listen_on(id, addr) .map_err(|e| e.map(DnsErr::Transport)) } @@ -599,8 +603,9 @@ mod tests { fn listen_on( &mut self, + _: ListenerId, _: Multiaddr, - ) -> Result> { + ) -> Result<(), TransportError> { unreachable!() } diff --git a/transports/quic/src/lib.rs b/transports/quic/src/lib.rs index af6dd1871dd..594ba0b6108 100644 --- a/transports/quic/src/lib.rs +++ b/transports/quic/src/lib.rs @@ -32,7 +32,7 @@ //! # fn main() -> std::io::Result<()> { //! # //! use libp2p_quic as quic; -//! use libp2p_core::{Multiaddr, Transport}; +//! use libp2p_core::{Multiaddr, Transport, transport::ListenerId}; //! //! let keypair = libp2p_identity::Keypair::generate_ed25519(); //! let quic_config = quic::Config::new(&keypair); @@ -40,7 +40,7 @@ //! let mut quic_transport = quic::async_std::Transport::new(quic_config); //! //! let addr = "/ip4/127.0.0.1/udp/12345/quic-v1".parse().expect("address should be valid"); -//! quic_transport.listen_on(addr).expect("listen error."); +//! quic_transport.listen_on(ListenerId::next(), addr).expect("listen error."); //! # //! # Ok(()) //! # } diff --git a/transports/quic/src/transport.rs b/transports/quic/src/transport.rs index d68eb7f1928..668034ed147 100644 --- a/transports/quic/src/transport.rs +++ b/transports/quic/src/transport.rs @@ -98,10 +98,13 @@ impl Transport for GenTransport

{ type ListenerUpgrade = Connecting; type Dial = BoxFuture<'static, Result>; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + listener_id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let (socket_addr, version) = multiaddr_to_socketaddr(&addr, self.support_draft_29) .ok_or(TransportError::MultiaddrNotSupported(addr))?; - let listener_id = ListenerId::new(); let listener = Listener::new( listener_id, socket_addr, @@ -120,7 +123,7 @@ impl Transport for GenTransport

{ // New outbound connections will use the bidirectional (listener) endpoint. self.dialer.remove(&socket_addr.ip().into()); - Ok(listener_id) + Ok(()) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -772,8 +775,9 @@ mod test { // Run test twice to check that there is no unexpected behaviour if `Transport.listener` // is temporarily empty. for _ in 0..2 { - let id = transport - .listen_on("/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap()) + let id = ListenerId::next(); + transport + .listen_on(id, "/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap()) .unwrap(); // Copy channel to use it later. @@ -866,8 +870,11 @@ mod test { .await; // Start listening so that the dialer and driver are dropped. - let _ = transport - .listen_on("/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap()) + transport + .listen_on( + ListenerId::next(), + "/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap(), + ) .unwrap(); assert!(!transport.dialer.contains_key(&SocketFamily::Ipv4)); diff --git a/transports/quic/tests/smoke.rs b/transports/quic/tests/smoke.rs index a576d3c9ef5..93bb78e2ae8 100644 --- a/transports/quic/tests/smoke.rs +++ b/transports/quic/tests/smoke.rs @@ -115,9 +115,10 @@ async fn wrapped_with_delay() { fn listen_on( &mut self, + id: ListenerId, addr: Multiaddr, - ) -> Result> { - self.0.lock().unwrap().listen_on(addr) + ) -> Result<(), TransportError> { + self.0.lock().unwrap().listen_on(id, addr) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -327,7 +328,10 @@ async fn draft_29_support() { let (_, mut d_transport) = create_transport::(|cfg| cfg.support_draft_29 = false); assert!(matches!( - d_transport.listen_on("/ip4/127.0.0.1/udp/0/quic".parse().unwrap()), + d_transport.listen_on( + ListenerId::next(), + "/ip4/127.0.0.1/udp/0/quic".parse().unwrap() + ), Err(TransportError::MultiaddrNotSupported(_)) )); let d_quic_v1_addr = start_listening(&mut d_transport, "/ip4/127.0.0.1/udp/0/quic-v1").await; @@ -509,7 +513,9 @@ fn create_transport( } async fn start_listening(transport: &mut Boxed<(PeerId, StreamMuxerBox)>, addr: &str) -> Multiaddr { - transport.listen_on(addr.parse().unwrap()).unwrap(); + transport + .listen_on(ListenerId::next(), addr.parse().unwrap()) + .unwrap(); match transport.next().await { Some(TransportEvent::NewAddress { listen_addr, .. }) => listen_addr, e => panic!("{e:?}"), diff --git a/transports/quic/tests/stream_compliance.rs b/transports/quic/tests/stream_compliance.rs index ec4c3121819..0eff0584588 100644 --- a/transports/quic/tests/stream_compliance.rs +++ b/transports/quic/tests/stream_compliance.rs @@ -1,5 +1,6 @@ use futures::channel::oneshot; use futures::StreamExt; +use libp2p_core::transport::ListenerId; use libp2p_core::Transport; use libp2p_quic as quic; use std::time::Duration; @@ -23,7 +24,10 @@ async fn connected_peers() -> (quic::Connection, quic::Connection) { let mut listener = new_transport().boxed(); listener - .listen_on("/ip4/127.0.0.1/udp/0/quic-v1".parse().unwrap()) + .listen_on( + ListenerId::next(), + "/ip4/127.0.0.1/udp/0/quic-v1".parse().unwrap(), + ) .unwrap(); let listen_address = listener.next().await.unwrap().into_new_address().unwrap(); diff --git a/transports/tcp/src/lib.rs b/transports/tcp/src/lib.rs index 78f6c3f4656..e4576137ec8 100644 --- a/transports/tcp/src/lib.rs +++ b/transports/tcp/src/lib.rs @@ -248,7 +248,7 @@ impl Config { /// let listen_addr2: Multiaddr = "/ip4/127.0.0.1/tcp/9002".parse().unwrap(); /// /// let mut tcp1 = libp2p_tcp::async_io::Transport::new(libp2p_tcp::Config::new().port_reuse(true)).boxed(); - /// tcp1.listen_on( listen_addr1.clone()).expect("listener"); + /// tcp1.listen_on(ListenerId::next(), listen_addr1.clone()).expect("listener"); /// match tcp1.select_next_some().await { /// TransportEvent::NewAddress { listen_addr, .. } => { /// println!("Listening on {:?}", listen_addr); @@ -259,7 +259,7 @@ impl Config { /// } /// /// let mut tcp2 = libp2p_tcp::async_io::Transport::new(libp2p_tcp::Config::new().port_reuse(true)).boxed(); - /// tcp2.listen_on( listen_addr2).expect("listener"); + /// tcp2.listen_on(ListenerId::next(), listen_addr2).expect("listener"); /// match tcp2.select_next_some().await { /// TransportEvent::NewAddress { listen_addr, .. } => { /// println!("Listening on {:?}", listen_addr); @@ -437,19 +437,22 @@ where type Dial = Pin> + Send>>; type ListenerUpgrade = Ready>; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let socket_addr = if let Ok(sa) = multiaddr_to_socketaddr(addr.clone()) { sa } else { return Err(TransportError::MultiaddrNotSupported(addr)); }; - let id = ListenerId::new(); log::debug!("listening on {}", socket_addr); let listener = self .do_listen(id, socket_addr) .map_err(TransportError::Other)?; self.listeners.push(listener); - Ok(id) + Ok(()) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -916,7 +919,7 @@ mod tests { async fn listener(addr: Multiaddr, mut ready_tx: mpsc::Sender) { let mut tcp = Transport::::default().boxed(); - tcp.listen_on(addr).unwrap(); + tcp.listen_on(ListenerId::next(), addr).unwrap(); loop { match tcp.select_next_some().await { TransportEvent::NewAddress { listen_addr, .. } => { @@ -985,7 +988,7 @@ mod tests { async fn listener(addr: Multiaddr, mut ready_tx: mpsc::Sender) { let mut tcp = Transport::::default().boxed(); - tcp.listen_on(addr).unwrap(); + tcp.listen_on(ListenerId::next(), addr).unwrap(); loop { match tcp.select_next_some().await { @@ -1058,7 +1061,7 @@ mod tests { port_reuse_rx: oneshot::Receiver>, ) { let mut tcp = Transport::::new(Config::new()).boxed(); - tcp.listen_on(addr).unwrap(); + tcp.listen_on(ListenerId::next(), addr).unwrap(); loop { match tcp.select_next_some().await { TransportEvent::NewAddress { listen_addr, .. } => { @@ -1093,7 +1096,7 @@ mod tests { ) { let dest_addr = ready_rx.next().await.unwrap(); let mut tcp = Transport::::new(Config::new().port_reuse(true)); - tcp.listen_on(addr).unwrap(); + tcp.listen_on(ListenerId::next(), addr).unwrap(); match poll_fn(|cx| Pin::new(&mut tcp).poll(cx)).await { TransportEvent::NewAddress { .. } => { // Check that tcp and listener share the same port reuse SocketAddr @@ -1161,7 +1164,7 @@ mod tests { async fn listen_twice(addr: Multiaddr) { let mut tcp = Transport::::new(Config::new().port_reuse(true)); - tcp.listen_on(addr).unwrap(); + tcp.listen_on(ListenerId::next(), addr).unwrap(); match poll_fn(|cx| Pin::new(&mut tcp).poll(cx)).await { TransportEvent::NewAddress { listen_addr: addr1, .. @@ -1176,7 +1179,7 @@ mod tests { assert_eq!(port_reuse_tcp, port_reuse_listener1); // Listen on the same address a second time. - tcp.listen_on(addr1.clone()).unwrap(); + tcp.listen_on(ListenerId::next(), addr1.clone()).unwrap(); match poll_fn(|cx| Pin::new(&mut tcp).poll(cx)).await { TransportEvent::NewAddress { listen_addr: addr2, .. @@ -1215,7 +1218,7 @@ mod tests { async fn listen(addr: Multiaddr) -> Multiaddr { let mut tcp = Transport::::default().boxed(); - tcp.listen_on(addr).unwrap(); + tcp.listen_on(ListenerId::next(), addr).unwrap(); tcp.select_next_some() .await .into_new_address() @@ -1252,13 +1255,13 @@ mod tests { #[cfg(feature = "async-io")] { let mut tcp = async_io::Transport::default(); - assert!(tcp.listen_on(addr.clone()).is_err()); + assert!(tcp.listen_on(ListenerId::next(), addr.clone()).is_err()); } #[cfg(feature = "tokio")] { let mut tcp = tokio::Transport::default(); - assert!(tcp.listen_on(addr).is_err()); + assert!(tcp.listen_on(ListenerId::next(), addr).is_err()); } } @@ -1320,8 +1323,8 @@ mod tests { async fn cycle_listeners() -> bool { let mut tcp = Transport::::default().boxed(); - let listener_id = tcp - .listen_on("/ip4/127.0.0.1/tcp/0".parse().unwrap()) + let listener_id = ListenerId::next(); + tcp.listen_on(listener_id, "/ip4/127.0.0.1/tcp/0".parse().unwrap()) .unwrap(); tcp.remove_listener(listener_id) } diff --git a/transports/tcp/src/provider/async_io.rs b/transports/tcp/src/provider/async_io.rs index 590f109d3c3..9f43ed23236 100644 --- a/transports/tcp/src/provider/async_io.rs +++ b/transports/tcp/src/provider/async_io.rs @@ -32,14 +32,15 @@ use std::task::{Context, Poll}; /// /// ```rust /// # use libp2p_tcp as tcp; -/// # use libp2p_core::Transport; +/// # use libp2p_core::{Transport, transport::ListenerId}; /// # use futures::future; /// # use std::pin::Pin; /// # /// # #[async_std::main] /// # async fn main() { /// let mut transport = tcp::async_io::Transport::new(tcp::Config::default()); -/// let id = transport.listen_on("/ip4/127.0.0.1/tcp/0".parse().unwrap()).unwrap(); +/// let id = ListenerId::next(); +/// transport.listen_on(id, "/ip4/127.0.0.1/tcp/0".parse().unwrap()).unwrap(); /// /// let addr = future::poll_fn(|cx| Pin::new(&mut transport).poll(cx)).await.into_new_address().unwrap(); /// diff --git a/transports/tcp/src/provider/tokio.rs b/transports/tcp/src/provider/tokio.rs index e4b75c8d814..b991c6bdae1 100644 --- a/transports/tcp/src/provider/tokio.rs +++ b/transports/tcp/src/provider/tokio.rs @@ -36,14 +36,14 @@ use std::task::{Context, Poll}; /// /// ```rust /// # use libp2p_tcp as tcp; -/// # use libp2p_core::Transport; +/// # use libp2p_core::{Transport, transport::ListenerId}; /// # use futures::future; /// # use std::pin::Pin; /// # /// # #[tokio::main] /// # async fn main() { /// let mut transport = tcp::tokio::Transport::new(tcp::Config::default()); -/// let id = transport.listen_on("/ip4/127.0.0.1/tcp/0".parse().unwrap()).unwrap(); +/// let id = transport.listen_on(ListenerId::next(), "/ip4/127.0.0.1/tcp/0".parse().unwrap()).unwrap(); /// /// let addr = future::poll_fn(|cx| Pin::new(&mut transport).poll(cx)).await.into_new_address().unwrap(); /// diff --git a/transports/uds/src/lib.rs b/transports/uds/src/lib.rs index 5f3f9ab7265..78a6b0f05b8 100644 --- a/transports/uds/src/lib.rs +++ b/transports/uds/src/lib.rs @@ -93,10 +93,10 @@ macro_rules! codegen { fn listen_on( &mut self, + id: ListenerId, addr: Multiaddr, - ) -> Result> { + ) -> Result<(), TransportError> { if let Ok(path) = multiaddr_to_path(&addr) { - let id = ListenerId::new(); let listener = $build_listener(path) .map_err(Err) .map_ok(move |listener| { @@ -138,7 +138,7 @@ macro_rules! codegen { .try_flatten_stream() .boxed(); self.listeners.push_back((id, listener)); - Ok(id) + Ok(()) } else { Err(TransportError::MultiaddrNotSupported(addr)) } @@ -260,6 +260,7 @@ mod tests { use futures::{channel::oneshot, prelude::*}; use libp2p_core::{ multiaddr::{Multiaddr, Protocol}, + transport::ListenerId, Transport, }; use std::{self, borrow::Cow, path::Path}; @@ -292,7 +293,7 @@ mod tests { async_std::task::spawn(async move { let mut transport = UdsConfig::new().boxed(); - transport.listen_on(addr).unwrap(); + transport.listen_on(ListenerId::next(), addr).unwrap(); let listen_addr = transport .select_next_some() @@ -328,7 +329,7 @@ mod tests { let mut uds = UdsConfig::new(); let addr = "/unix//foo/bar".parse::().unwrap(); - assert!(uds.listen_on(addr).is_err()); + assert!(uds.listen_on(ListenerId::next(), addr).is_err()); } #[test] diff --git a/transports/wasm-ext/src/lib.rs b/transports/wasm-ext/src/lib.rs index 164cbff45c3..91236ca8758 100644 --- a/transports/wasm-ext/src/lib.rs +++ b/transports/wasm-ext/src/lib.rs @@ -198,7 +198,11 @@ impl Transport for ExtTransport { type ListenerUpgrade = Ready>; type Dial = Dial; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + listener_id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let iter = self.inner.listen_on(&addr.to_string()).map_err(|err| { if is_not_supported_error(&err) { TransportError::MultiaddrNotSupported(addr) @@ -206,7 +210,6 @@ impl Transport for ExtTransport { TransportError::Other(JsErr::from(err)) } })?; - let listener_id = ListenerId::new(); let listen = Listen { listener_id, iterator: SendWrapper::new(iter), @@ -215,7 +218,7 @@ impl Transport for ExtTransport { is_closed: false, }; self.listeners.push(listen); - Ok(listener_id) + Ok(()) } fn remove_listener(&mut self, id: ListenerId) -> bool { diff --git a/transports/webrtc/src/tokio/transport.rs b/transports/webrtc/src/tokio/transport.rs index 904da61c44a..21f465ba063 100644 --- a/transports/webrtc/src/tokio/transport.rs +++ b/transports/webrtc/src/tokio/transport.rs @@ -80,9 +80,11 @@ impl libp2p_core::Transport for Transport { type ListenerUpgrade = BoxFuture<'static, Result>; type Dial = BoxFuture<'static, Result>; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - let id = ListenerId::new(); - + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let socket_addr = parse_webrtc_listen_addr(&addr).ok_or(TransportError::MultiaddrNotSupported(addr))?; let udp_mux = UDPMuxNewAddr::listen_on(socket_addr) @@ -93,7 +95,7 @@ impl libp2p_core::Transport for Transport { .map_err(|e| TransportError::Other(Error::Io(e)))?, ); - Ok(id) + Ok(()) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -596,8 +598,12 @@ mod tests { // Run test twice to check that there is no unexpected behaviour if `QuicTransport.listener` // is temporarily empty. for _ in 0..2 { - let listener = transport - .listen_on("/ip4/0.0.0.0/udp/0/webrtc-direct".parse().unwrap()) + let listener = ListenerId::next(); + transport + .listen_on( + listener, + "/ip4/0.0.0.0/udp/0/webrtc-direct".parse().unwrap(), + ) .unwrap(); match poll_fn(|cx| Pin::new(&mut transport).as_mut().poll(cx)).await { TransportEvent::NewAddress { diff --git a/transports/webrtc/tests/smoke.rs b/transports/webrtc/tests/smoke.rs index bca159d785b..8e56b99723d 100644 --- a/transports/webrtc/tests/smoke.rs +++ b/transports/webrtc/tests/smoke.rs @@ -23,7 +23,7 @@ use futures::future::{BoxFuture, Either}; use futures::stream::StreamExt; use futures::{future, ready, AsyncReadExt, AsyncWriteExt, FutureExt, SinkExt}; use libp2p_core::muxing::{StreamMuxerBox, StreamMuxerExt}; -use libp2p_core::transport::{Boxed, TransportEvent}; +use libp2p_core::transport::{Boxed, ListenerId, TransportEvent}; use libp2p_core::{Multiaddr, Transport}; use libp2p_identity::PeerId; use libp2p_webrtc as webrtc; @@ -81,7 +81,9 @@ fn create_transport() -> (PeerId, Boxed<(PeerId, StreamMuxerBox)>) { } async fn start_listening(transport: &mut Boxed<(PeerId, StreamMuxerBox)>, addr: &str) -> Multiaddr { - transport.listen_on(addr.parse().unwrap()).unwrap(); + transport + .listen_on(ListenerId::next(), addr.parse().unwrap()) + .unwrap(); match transport.next().await { Some(TransportEvent::NewAddress { listen_addr, .. }) => listen_addr, e => panic!("{e:?}"), diff --git a/transports/websocket/src/framed.rs b/transports/websocket/src/framed.rs index 318090d10d2..a81f6d4553b 100644 --- a/transports/websocket/src/framed.rs +++ b/transports/websocket/src/framed.rs @@ -122,7 +122,11 @@ where type ListenerUpgrade = BoxFuture<'static, Result>; type Dial = BoxFuture<'static, Result>; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { let mut inner_addr = addr.clone(); let proto = match inner_addr.pop() { Some(p @ Protocol::Wss(_)) => { @@ -139,10 +143,10 @@ where return Err(TransportError::MultiaddrNotSupported(addr)); } }; - match self.transport.lock().listen_on(inner_addr) { - Ok(id) => { + match self.transport.lock().listen_on(id, inner_addr) { + Ok(()) => { self.listener_protos.insert(id, proto); - Ok(id) + Ok(()) } Err(e) => Err(e.map(Error::Transport)), } diff --git a/transports/websocket/src/lib.rs b/transports/websocket/src/lib.rs index 369e1d612bf..fa12232244b 100644 --- a/transports/websocket/src/lib.rs +++ b/transports/websocket/src/lib.rs @@ -64,7 +64,7 @@ use std::{ /// /// ``` /// # use futures::future; -/// # use libp2p_core::Transport; +/// # use libp2p_core::{transport::ListenerId, Transport}; /// # use libp2p_dns as dns; /// # use libp2p_tcp as tcp; /// # use libp2p_websocket as websocket; @@ -83,7 +83,7 @@ use std::{ /// let cert = websocket::tls::Certificate::new(rcgen_cert.serialize_der().unwrap()); /// transport.set_tls_config(websocket::tls::Config::new(priv_key, vec![cert]).unwrap()); /// -/// let id = transport.listen_on("/ip4/127.0.0.1/tcp/0/wss".parse().unwrap()).unwrap(); +/// let id = transport.listen_on(ListenerId::next(), "/ip4/127.0.0.1/tcp/0/wss".parse().unwrap()).unwrap(); /// /// let addr = future::poll_fn(|cx| Pin::new(&mut transport).poll(cx)).await.into_new_address().unwrap(); /// println!("Listening on {addr}"); @@ -95,7 +95,7 @@ use std::{ /// /// ``` /// # use futures::future; -/// # use libp2p_core::Transport; +/// # use libp2p_core::{transport::ListenerId, Transport}; /// # use libp2p_dns as dns; /// # use libp2p_tcp as tcp; /// # use libp2p_websocket as websocket; @@ -108,7 +108,7 @@ use std::{ /// tcp::async_io::Transport::new(tcp::Config::default()), /// ); /// -/// let id = transport.listen_on("/ip4/127.0.0.1/tcp/0/ws".parse().unwrap()).unwrap(); +/// let id = transport.listen_on(ListenerId::next(), "/ip4/127.0.0.1/tcp/0/ws".parse().unwrap()).unwrap(); /// /// let addr = future::poll_fn(|cx| Pin::new(&mut transport).poll(cx)).await.into_new_address().unwrap(); /// println!("Listening on {addr}"); @@ -195,8 +195,12 @@ where type ListenerUpgrade = MapFuture, WrapperFn>; type Dial = MapFuture, WrapperFn>; - fn listen_on(&mut self, addr: Multiaddr) -> Result> { - self.transport.listen_on(addr) + fn listen_on( + &mut self, + id: ListenerId, + addr: Multiaddr, + ) -> Result<(), TransportError> { + self.transport.listen_on(id, addr) } fn remove_listener(&mut self, id: ListenerId) -> bool { @@ -293,7 +297,7 @@ where mod tests { use super::WsConfig; use futures::prelude::*; - use libp2p_core::{multiaddr::Protocol, Multiaddr, Transport}; + use libp2p_core::{multiaddr::Protocol, transport::ListenerId, Multiaddr, Transport}; use libp2p_identity::PeerId; use libp2p_tcp as tcp; @@ -315,7 +319,9 @@ mod tests { async fn connect(listen_addr: Multiaddr) { let mut ws_config = new_ws_config().boxed(); - ws_config.listen_on(listen_addr).expect("listener"); + ws_config + .listen_on(ListenerId::next(), listen_addr) + .expect("listener"); let addr = ws_config .next() From 6e36e8aa35689cc0098ae55eee1423fb12ca07de Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sun, 14 May 2023 12:58:08 +0200 Subject: [PATCH 07/38] feat(swarm): rename associated types for message passing Previously, the associated types on `NetworkBehaviour` and `ConnectionHandler` carried generic names like `InEvent` and `OutEvent`. These names are _correct_ in that `OutEvent`s are passed out and `InEvent`s are passed in but they don't help users understand how these types are used. In theory, a `ConnectionHandler` could be used separately from `NetworkBehaviour`s but that is highly unlikely. Thus, we rename these associated types to indicate, where the message is going to be sent to: - `NetworkBehaviour::OutEvent` is renamed to `ToSwarm`: It describes the message(s) a `NetworkBehaviour` can emit to the `Swarm`. The user is going to receive those in `SwarmEvent::Behaviour`. - `ConnectionHandler::InEvent` is renamed to `FromBehaviour`: It describes the message(s) a `ConnectionHandler` can receive from its behaviour via `ConnectionHandler::on_swarm_event`. The `NetworkBehaviour` can send it via the `ToSwarm::NotifyHandler` command. - `ConnectionHandler::OutEvent` is renamed to `ToBehaviour`: It describes the message(s) a `ConnectionHandler` can send back to the behaviour via the now also renamed `ConnectionHandlerEvent::NotifyBehaviour` (previously `ConnectionHandlerEvent::Custom`) Resolves: #2854. Pull-Request: #3848. --- Cargo.lock | 44 +++++++++++++++++ examples/dcutr/src/main.rs | 2 +- .../distributed-key-value-store/Cargo.toml | 2 +- .../distributed-key-value-store/src/main.rs | 2 +- examples/file-sharing/src/network.rs | 2 +- examples/ipfs-private/src/main.rs | 2 +- libp2p/CHANGELOG.md | 3 ++ misc/allow-block-list/src/lib.rs | 4 +- misc/connection-limits/src/lib.rs | 4 +- protocols/autonat/src/behaviour.rs | 6 +-- protocols/dcutr/src/behaviour_impl.rs | 4 +- protocols/dcutr/src/handler/direct.rs | 8 +-- protocols/dcutr/src/handler/relayed.rs | 10 ++-- protocols/dcutr/tests/lib.rs | 2 +- protocols/floodsub/src/layer.rs | 4 +- protocols/gossipsub/src/behaviour.rs | 4 +- protocols/gossipsub/src/handler.rs | 8 +-- protocols/identify/src/behaviour.rs | 4 +- protocols/identify/src/handler.rs | 6 +-- protocols/kad/src/behaviour.rs | 4 +- protocols/kad/src/handler.rs | 6 +-- protocols/mdns/src/behaviour.rs | 4 +- protocols/perf/src/client/behaviour.rs | 4 +- protocols/perf/src/client/handler.rs | 10 ++-- protocols/perf/src/server/behaviour.rs | 4 +- protocols/perf/src/server/handler.rs | 8 +-- protocols/ping/src/handler.rs | 4 +- protocols/ping/src/lib.rs | 4 +- protocols/relay/src/behaviour.rs | 4 +- protocols/relay/src/behaviour/handler.rs | 10 ++-- protocols/relay/src/priv_client.rs | 4 +- protocols/relay/src/priv_client/handler.rs | 10 ++-- protocols/rendezvous/src/client.rs | 4 +- protocols/rendezvous/src/server.rs | 4 +- protocols/rendezvous/src/substream_handler.rs | 8 +-- protocols/request-response/src/handler.rs | 11 +++-- protocols/request-response/src/lib.rs | 4 +- swarm-derive/CHANGELOG.md | 3 ++ swarm-derive/Cargo.toml | 2 + swarm-derive/src/lib.rs | 49 +++++++++++++------ swarm-test/src/lib.rs | 28 +++++------ swarm/CHANGELOG.md | 5 +- swarm/Cargo.toml | 1 + swarm/src/behaviour.rs | 14 +++--- swarm/src/behaviour/either.rs | 4 +- swarm/src/behaviour/toggle.rs | 12 ++--- swarm/src/connection.rs | 22 ++++----- swarm/src/connection/pool.rs | 10 ++-- swarm/src/connection/pool/task.rs | 4 +- swarm/src/dummy.rs | 12 ++--- swarm/src/handler.rs | 16 +++--- swarm/src/handler/either.rs | 8 +-- swarm/src/handler/map_in.rs | 8 +-- swarm/src/handler/map_out.rs | 10 ++-- swarm/src/handler/multi.rs | 8 +-- swarm/src/handler/one_shot.rs | 8 +-- swarm/src/handler/pending.rs | 8 +-- swarm/src/handler/select.rs | 8 +-- swarm/src/keep_alive.rs | 12 ++--- swarm/src/lib.rs | 22 ++++----- swarm/src/test.rs | 16 +++--- swarm/tests/swarm_derive.rs | 36 ++++++++------ swarm/tests/ui/fail/out_event_deprecation.rs | 21 ++++++++ .../ui/fail/out_event_deprecation.stderr | 14 ++++++ transports/webrtc/examples/listen_ping.rs | 2 +- 65 files changed, 355 insertions(+), 236 deletions(-) create mode 100644 swarm/tests/ui/fail/out_event_deprecation.rs create mode 100644 swarm/tests/ui/fail/out_event_deprecation.stderr diff --git a/Cargo.lock b/Cargo.lock index 3bb82a6a6aa..9422ccd9af4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -541,6 +541,15 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +[[package]] +name = "basic-toml" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c0de75129aa8d0cceaf750b89013f0e08804d6ec61416da787b35ad0d7cddf1" +dependencies = [ + "serde", +] + [[package]] name = "bimap" version = "0.6.3" @@ -1816,6 +1825,12 @@ dependencies = [ "polyval 0.5.3", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "gloo-timers" version = "0.2.6" @@ -2995,6 +3010,7 @@ dependencies = [ "rand 0.8.5", "smallvec", "tokio", + "trybuild", "void", "wasm-bindgen-futures", ] @@ -3004,6 +3020,8 @@ name = "libp2p-swarm-derive" version = "0.33.0" dependencies = [ "heck", + "proc-macro-warning", + "proc-macro2", "quote", "syn 2.0.15", ] @@ -3976,6 +3994,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-warning" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e99670bafb56b9a106419397343bdbc8b8742c3cc449fec6345f86173f47cd4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "proc-macro2" version = "1.0.56" @@ -5210,6 +5239,21 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +[[package]] +name = "trybuild" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501dbdbb99861e4ab6b60eb6a7493956a9defb644fd034bc4a5ef27c693c8a3a" +dependencies = [ + "basic-toml", + "glob", + "once_cell", + "serde", + "serde_derive", + "serde_json", + "termcolor", +] + [[package]] name = "turn" version = "0.6.1" diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index 4dbee86fac3..e8f5673e7c4 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -104,7 +104,7 @@ fn main() -> Result<(), Box> { .boxed(); #[derive(NetworkBehaviour)] - #[behaviour(out_event = "Event", event_process = false)] + #[behaviour(to_swarm = "Event", event_process = false)] struct Behaviour { relay_client: relay::client::Behaviour, ping: ping::Behaviour, diff --git a/examples/distributed-key-value-store/Cargo.toml b/examples/distributed-key-value-store/Cargo.toml index b690baac2e8..8d9681e52d2 100644 --- a/examples/distributed-key-value-store/Cargo.toml +++ b/examples/distributed-key-value-store/Cargo.toml @@ -11,4 +11,4 @@ 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"] } -multiaddr = { version = "0.17.1" } \ No newline at end of file +multiaddr = { version = "0.17.1" } diff --git a/examples/distributed-key-value-store/src/main.rs b/examples/distributed-key-value-store/src/main.rs index 952e55ba6e7..ce617aca5e4 100644 --- a/examples/distributed-key-value-store/src/main.rs +++ b/examples/distributed-key-value-store/src/main.rs @@ -71,7 +71,7 @@ async fn main() -> Result<(), Box> { // We create a custom network behaviour that combines Kademlia and mDNS. #[derive(NetworkBehaviour)] - #[behaviour(out_event = "MyBehaviourEvent")] + #[behaviour(to_swarm = "MyBehaviourEvent")] struct MyBehaviour { kademlia: Kademlia, mdns: mdns::async_io::Behaviour, diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 404aef01c4d..c88db696dff 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -408,7 +408,7 @@ impl EventLoop { } #[derive(NetworkBehaviour)] -#[behaviour(out_event = "ComposedEvent")] +#[behaviour(to_swarm = "ComposedEvent")] struct ComposedBehaviour { request_response: request_response::Behaviour, kademlia: Kademlia, diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index fd18581407b..364cccd02a1 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -145,7 +145,7 @@ async fn main() -> Result<(), Box> { // We create a custom network behaviour that combines gossipsub, ping and identify. #[derive(NetworkBehaviour)] - #[behaviour(out_event = "MyBehaviourEvent")] + #[behaviour(to_swarm = "MyBehaviourEvent")] struct MyBehaviour { gossipsub: gossipsub::Behaviour, identify: identify::Behaviour, diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index bc47bcb0827..18206718799 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -9,9 +9,12 @@ This newtype enforces additional variants like a leading forward-slash. We encourage users to use `StreamProtocol` when implementing `UpgradeInfo`. See [PR 3746]. + +- Rename `NetworkBehaviour::OutEvent` to `NetworkBehaviour::ToSwarm`, `ConnectionHandler::InEvent` to `ConnectionHandler::FromBehaviour`, `ConnectionHandler::OutEvent` to `ConnectionHandler::ToBehaviour`. See [PR 3848]. [PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3848]: https://github.com/libp2p/rust-libp2p/pull/3848 ## 0.51.3 diff --git a/misc/allow-block-list/src/lib.rs b/misc/allow-block-list/src/lib.rs index d501ab73324..521aa0026cc 100644 --- a/misc/allow-block-list/src/lib.rs +++ b/misc/allow-block-list/src/lib.rs @@ -191,7 +191,7 @@ where S: Enforce, { type ConnectionHandler = dummy::ConnectionHandler; - type OutEvent = Void; + type ToSwarm = Void; fn handle_established_inbound_connection( &mut self, @@ -261,7 +261,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(peer) = self.close_connections.pop_front() { return Poll::Ready(ToSwarm::CloseConnection { peer_id: peer, diff --git a/misc/connection-limits/src/lib.rs b/misc/connection-limits/src/lib.rs index b781e83d92d..1a568cb7ab9 100644 --- a/misc/connection-limits/src/lib.rs +++ b/misc/connection-limits/src/lib.rs @@ -201,7 +201,7 @@ impl ConnectionLimits { impl NetworkBehaviour for Behaviour { type ConnectionHandler = dummy::ConnectionHandler; - type OutEvent = Void; + type ToSwarm = Void; fn handle_pending_inbound_connection( &mut self, @@ -355,7 +355,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { Poll::Pending } } diff --git a/protocols/autonat/src/behaviour.rs b/protocols/autonat/src/behaviour.rs index c46d8044989..17681341489 100644 --- a/protocols/autonat/src/behaviour.rs +++ b/protocols/autonat/src/behaviour.rs @@ -209,7 +209,7 @@ pub struct Behaviour { last_probe: Option, - pending_actions: VecDeque::OutEvent, THandlerInEvent>>, + pending_actions: VecDeque::ToSwarm, THandlerInEvent>>, probe_id: ProbeId, @@ -427,7 +427,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = as NetworkBehaviour>::ConnectionHandler; - type OutEvent = Event; + type ToSwarm = Event; fn poll(&mut self, cx: &mut Context<'_>, params: &mut impl PollParameters) -> Poll { loop { @@ -594,7 +594,7 @@ impl NetworkBehaviour for Behaviour { } } -type Action = ToSwarm<::OutEvent, THandlerInEvent>; +type Action = ToSwarm<::ToSwarm, THandlerInEvent>; // Trait implemented for `AsClient` and `AsServer` to handle events from the inner [`request_response::Behaviour`] Protocol. trait HandleInnerEvent { diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 2c1698f2258..5b89f2ef2c2 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -237,7 +237,7 @@ impl NetworkBehaviour for Behaviour { handler::relayed::Handler, Either, >; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -415,7 +415,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(event) = self.queued_events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/dcutr/src/handler/direct.rs b/protocols/dcutr/src/handler/direct.rs index e336f750915..a06c9272baa 100644 --- a/protocols/dcutr/src/handler/direct.rs +++ b/protocols/dcutr/src/handler/direct.rs @@ -39,8 +39,8 @@ pub struct Handler { } impl ConnectionHandler for Handler { - type InEvent = void::Void; - type OutEvent = Event; + type FromBehaviour = void::Void; + type ToBehaviour = Event; type Error = StreamUpgradeError; type InboundProtocol = DeniedUpgrade; type OutboundProtocol = DeniedUpgrade; @@ -51,7 +51,7 @@ impl ConnectionHandler for Handler { SubstreamProtocol::new(DeniedUpgrade, ()) } - fn on_behaviour_event(&mut self, _: Self::InEvent) {} + fn on_behaviour_event(&mut self, _: Self::FromBehaviour) {} fn connection_keep_alive(&self) -> KeepAlive { KeepAlive::No @@ -64,7 +64,7 @@ impl ConnectionHandler for Handler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/dcutr/src/handler/relayed.rs b/protocols/dcutr/src/handler/relayed.rs index 8b59b80457b..eb1ad83cecb 100644 --- a/protocols/dcutr/src/handler/relayed.rs +++ b/protocols/dcutr/src/handler/relayed.rs @@ -135,7 +135,7 @@ pub struct Handler { ConnectionHandlerEvent< ::OutboundProtocol, ::OutboundOpenInfo, - ::OutEvent, + ::ToBehaviour, ::Error, >, >, @@ -254,8 +254,8 @@ impl Handler { } impl ConnectionHandler for Handler { - type InEvent = Command; - type OutEvent = Event; + type FromBehaviour = Command; + type ToBehaviour = Event; type Error = StreamUpgradeError< Either, >; @@ -280,7 +280,7 @@ impl ConnectionHandler for Handler { } } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { match event { Command::Connect { obs_addrs } => { self.queued_events @@ -323,7 +323,7 @@ impl ConnectionHandler for Handler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index ba190782b12..5c5fdbb8384 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -137,7 +137,7 @@ fn build_client() -> Swarm { #[derive(NetworkBehaviour)] #[behaviour( - out_event = "ClientEvent", + to_swarm = "ClientEvent", event_process = false, prelude = "libp2p_swarm::derive_prelude" )] diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index a3673a13ed1..f8a498912d6 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -329,7 +329,7 @@ impl Floodsub { impl NetworkBehaviour for Floodsub { type ConnectionHandler = OneShotHandler; - type OutEvent = FloodsubEvent; + type ToSwarm = FloodsubEvent; fn handle_established_inbound_connection( &mut self, @@ -470,7 +470,7 @@ impl NetworkBehaviour for Floodsub { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index c2d6b8da3fe..ba0594a9801 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -3307,7 +3307,7 @@ where F: Send + 'static + TopicSubscriptionFilter, { type ConnectionHandler = Handler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -3465,7 +3465,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/gossipsub/src/handler.rs b/protocols/gossipsub/src/handler.rs index 5a5b91d00d1..615d4ae132b 100644 --- a/protocols/gossipsub/src/handler.rs +++ b/protocols/gossipsub/src/handler.rs @@ -225,7 +225,7 @@ impl EnabledHandler { ConnectionHandlerEvent< ::OutboundProtocol, ::OutboundOpenInfo, - ::OutEvent, + ::ToBehaviour, ::Error, >, > { @@ -393,8 +393,8 @@ impl EnabledHandler { } impl ConnectionHandler for Handler { - type InEvent = HandlerIn; - type OutEvent = HandlerEvent; + type FromBehaviour = HandlerIn; + type ToBehaviour = HandlerEvent; type Error = Void; type InboundOpenInfo = (); type InboundProtocol = either::Either; @@ -457,7 +457,7 @@ impl ConnectionHandler for Handler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/identify/src/behaviour.rs b/protocols/identify/src/behaviour.rs index 6ed242dd8d1..532b86dafa8 100644 --- a/protocols/identify/src/behaviour.rs +++ b/protocols/identify/src/behaviour.rs @@ -234,7 +234,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type OutEvent = Event; + type ToSwarm = Event; #[allow(deprecated)] fn handle_established_inbound_connection( @@ -319,7 +319,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index dfcf2279497..d041fca731a 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -242,8 +242,8 @@ impl Handler { } impl ConnectionHandler for Handler { - type InEvent = InEvent; - type OutEvent = Event; + type FromBehaviour = InEvent; + type ToBehaviour = Event; type Error = io::Error; type InboundProtocol = SelectUpgrade>; type OutboundProtocol = Either>; @@ -254,7 +254,7 @@ impl ConnectionHandler for Handler { SubstreamProtocol::new(SelectUpgrade::new(Identify, Push::inbound()), ()) } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { match event { InEvent::AddressesChanged(addresses) => { self.external_addresses = addresses; diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 9193770e09a..856a994056a 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -1960,7 +1960,7 @@ where TStore: RecordStore + Send + 'static, { type ConnectionHandler = KademliaHandler; - type OutEvent = KademliaEvent; + type ToSwarm = KademliaEvent; fn handle_established_inbound_connection( &mut self, @@ -2301,7 +2301,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { let now = Instant::now(); // Calculate the available capacity for queries triggered by background jobs. diff --git a/protocols/kad/src/handler.rs b/protocols/kad/src/handler.rs index 25daa8dcd15..75721c0dc31 100644 --- a/protocols/kad/src/handler.rs +++ b/protocols/kad/src/handler.rs @@ -599,8 +599,8 @@ impl ConnectionHandler for KademliaHandler where TUserData: Clone + fmt::Debug + Send + 'static + Unpin, { - type InEvent = KademliaHandlerIn; - type OutEvent = KademliaHandlerEvent; + type FromBehaviour = KademliaHandlerIn; + type ToBehaviour = KademliaHandlerEvent; type Error = io::Error; // TODO: better error type? type InboundProtocol = Either; type OutboundProtocol = KademliaProtocolConfig; @@ -701,7 +701,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/mdns/src/behaviour.rs b/protocols/mdns/src/behaviour.rs index 5186ce91cb7..8f01439403f 100644 --- a/protocols/mdns/src/behaviour.rs +++ b/protocols/mdns/src/behaviour.rs @@ -173,7 +173,7 @@ where P: Provider, { type ConnectionHandler = dummy::ConnectionHandler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -252,7 +252,7 @@ where &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { // Poll ifwatch. while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) { match event { diff --git a/protocols/perf/src/client/behaviour.rs b/protocols/perf/src/client/behaviour.rs index 920baed1131..3dd932b0c77 100644 --- a/protocols/perf/src/client/behaviour.rs +++ b/protocols/perf/src/client/behaviour.rs @@ -82,7 +82,7 @@ pub enum PerfError { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_outbound_connection( &mut self, @@ -147,7 +147,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(event) = self.queued_events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/perf/src/client/handler.rs b/protocols/perf/src/client/handler.rs index a87e82cc384..f8a1eff5c10 100644 --- a/protocols/perf/src/client/handler.rs +++ b/protocols/perf/src/client/handler.rs @@ -56,7 +56,7 @@ pub struct Handler { ConnectionHandlerEvent< ::OutboundProtocol, ::OutboundOpenInfo, - ::OutEvent, + ::ToBehaviour, ::Error, >, >, @@ -86,8 +86,8 @@ impl Default for Handler { } impl ConnectionHandler for Handler { - type InEvent = Command; - type OutEvent = Event; + type FromBehaviour = Command; + type ToBehaviour = Event; type Error = Void; type InboundProtocol = DeniedUpgrade; type OutboundProtocol = ReadyUpgrade; @@ -98,7 +98,7 @@ impl ConnectionHandler for Handler { SubstreamProtocol::new(DeniedUpgrade, ()) } - fn on_behaviour_event(&mut self, command: Self::InEvent) { + fn on_behaviour_event(&mut self, command: Self::FromBehaviour) { self.requested_streams.push_back(command); self.queued_events .push_back(ConnectionHandlerEvent::OutboundSubstreamRequest { @@ -168,7 +168,7 @@ impl ConnectionHandler for Handler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/perf/src/server/behaviour.rs b/protocols/perf/src/server/behaviour.rs index 5d63475c999..6f0047913b6 100644 --- a/protocols/perf/src/server/behaviour.rs +++ b/protocols/perf/src/server/behaviour.rs @@ -55,7 +55,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -110,7 +110,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(event) = self.queued_events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/perf/src/server/handler.rs b/protocols/perf/src/server/handler.rs index ab70ba9aa6e..6f5043b66a3 100644 --- a/protocols/perf/src/server/handler.rs +++ b/protocols/perf/src/server/handler.rs @@ -63,8 +63,8 @@ impl Default for Handler { } impl ConnectionHandler for Handler { - type InEvent = Void; - type OutEvent = Event; + type FromBehaviour = Void; + type ToBehaviour = Event; type Error = Void; type InboundProtocol = ReadyUpgrade; type OutboundProtocol = DeniedUpgrade; @@ -75,7 +75,7 @@ impl ConnectionHandler for Handler { SubstreamProtocol::new(ReadyUpgrade::new(crate::PROTOCOL_NAME), ()) } - fn on_behaviour_event(&mut self, v: Self::InEvent) { + fn on_behaviour_event(&mut self, v: Self::FromBehaviour) { void::unreachable(v) } @@ -123,7 +123,7 @@ impl ConnectionHandler for Handler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/ping/src/handler.rs b/protocols/ping/src/handler.rs index 94b484927b8..c21b234b3e3 100644 --- a/protocols/ping/src/handler.rs +++ b/protocols/ping/src/handler.rs @@ -229,8 +229,8 @@ impl Handler { } impl ConnectionHandler for Handler { - type InEvent = Void; - type OutEvent = crate::Result; + type FromBehaviour = Void; + type ToBehaviour = crate::Result; type Error = Failure; type InboundProtocol = ReadyUpgrade; type OutboundProtocol = ReadyUpgrade; diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index aa33c76984f..85be866dbf5 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -98,7 +98,7 @@ impl Default for Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Handler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -133,7 +133,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(e) = self.events.pop_back() { let Event { result, peer } = &e; diff --git a/protocols/relay/src/behaviour.rs b/protocols/relay/src/behaviour.rs index b2d6538fc04..133a5fa7d50 100644 --- a/protocols/relay/src/behaviour.rs +++ b/protocols/relay/src/behaviour.rs @@ -249,7 +249,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Either; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -671,7 +671,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action.build(self.local_peer_id, &self.external_addresses)); } diff --git a/protocols/relay/src/behaviour/handler.rs b/protocols/relay/src/behaviour/handler.rs index 7494d055f36..752e5aeac89 100644 --- a/protocols/relay/src/behaviour/handler.rs +++ b/protocols/relay/src/behaviour/handler.rs @@ -340,7 +340,7 @@ pub struct Handler { ConnectionHandlerEvent< ::OutboundProtocol, ::OutboundOpenInfo, - ::OutEvent, + ::ToBehaviour, ::Error, >, >, @@ -546,8 +546,8 @@ enum ReservationRequestFuture { type Futures = FuturesUnordered>; impl ConnectionHandler for Handler { - type InEvent = In; - type OutEvent = Event; + type FromBehaviour = In; + type ToBehaviour = Event; type Error = StreamUpgradeError< Either, >; @@ -567,7 +567,7 @@ impl ConnectionHandler for Handler { ) } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { match event { In::AcceptReservationReq { inbound_reservation_req, @@ -671,7 +671,7 @@ impl ConnectionHandler for Handler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 8592c57d3b6..1d4237e83d8 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -156,7 +156,7 @@ impl Behaviour { impl NetworkBehaviour for Behaviour { type ConnectionHandler = Either; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -293,7 +293,7 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _poll_parameters: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(action) = self.queued_actions.pop_front() { return Poll::Ready(action); } diff --git a/protocols/relay/src/priv_client/handler.rs b/protocols/relay/src/priv_client/handler.rs index c134031ad7c..dee51cde664 100644 --- a/protocols/relay/src/priv_client/handler.rs +++ b/protocols/relay/src/priv_client/handler.rs @@ -123,7 +123,7 @@ pub struct Handler { ConnectionHandlerEvent< ::OutboundProtocol, ::OutboundOpenInfo, - ::OutEvent, + ::ToBehaviour, ::Error, >, >, @@ -393,8 +393,8 @@ impl Handler { } impl ConnectionHandler for Handler { - type InEvent = In; - type OutEvent = Event; + type FromBehaviour = In; + type ToBehaviour = Event; type Error = StreamUpgradeError< Either, >; @@ -407,7 +407,7 @@ impl ConnectionHandler for Handler { SubstreamProtocol::new(inbound_stop::Upgrade {}, ()) } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { match event { In::Reserve { to_listener } => { self.queued_events @@ -444,7 +444,7 @@ impl ConnectionHandler for Handler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/rendezvous/src/client.rs b/protocols/rendezvous/src/client.rs index e6f842ae942..a8527ba5dfe 100644 --- a/protocols/rendezvous/src/client.rs +++ b/protocols/rendezvous/src/client.rs @@ -163,7 +163,7 @@ pub enum Event { impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -244,7 +244,7 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(event) = self.events.pop_front() { return Poll::Ready(event); } diff --git a/protocols/rendezvous/src/server.rs b/protocols/rendezvous/src/server.rs index 1311d4f903f..8568076202a 100644 --- a/protocols/rendezvous/src/server.rs +++ b/protocols/rendezvous/src/server.rs @@ -110,7 +110,7 @@ pub enum Event { impl NetworkBehaviour for Behaviour { type ConnectionHandler = SubstreamConnectionHandler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -165,7 +165,7 @@ impl NetworkBehaviour for Behaviour { &mut self, cx: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Poll::Ready(ExpiredRegistration(registration)) = self.registrations.poll(cx) { return Poll::Ready(ToSwarm::GenerateEvent(Event::RegistrationExpired( registration, diff --git a/protocols/rendezvous/src/substream_handler.rs b/protocols/rendezvous/src/substream_handler.rs index 289c6a36d7e..6fc5cb561b2 100644 --- a/protocols/rendezvous/src/substream_handler.rs +++ b/protocols/rendezvous/src/substream_handler.rs @@ -354,8 +354,8 @@ where TInboundSubstreamHandler: Send + 'static, TOutboundSubstreamHandler: Send + 'static, { - type InEvent = InEvent; - type OutEvent = OutEvent; + type FromBehaviour = InEvent; + type ToBehaviour = OutEvent; type Error = Void; type InboundProtocol = PassthroughProtocol; type OutboundProtocol = PassthroughProtocol; @@ -402,7 +402,7 @@ where } } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { match event { InEvent::NewSubstream { open_info } => self.new_substreams.push_back(open_info), InEvent::NotifyInboundSubstream { id, message } => { @@ -456,7 +456,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/protocols/request-response/src/handler.rs b/protocols/request-response/src/handler.rs index 3a323d75edc..02e9c8710dd 100644 --- a/protocols/request-response/src/handler.rs +++ b/protocols/request-response/src/handler.rs @@ -239,8 +239,8 @@ impl ConnectionHandler for Handler where TCodec: Codec + Send + Clone + 'static, { - type InEvent = RequestProtocol; - type OutEvent = Event; + type FromBehaviour = RequestProtocol; + type ToBehaviour = Event; type Error = StreamUpgradeError; type InboundProtocol = ResponseProtocol; type OutboundProtocol = RequestProtocol; @@ -281,7 +281,7 @@ where SubstreamProtocol::new(proto, request_id).with_timeout(self.substream_timeout) } - fn on_behaviour_event(&mut self, request: Self::InEvent) { + fn on_behaviour_event(&mut self, request: Self::FromBehaviour) { self.keep_alive = KeepAlive::Yes; self.outbound.push_back(request); } @@ -293,8 +293,9 @@ where fn poll( &mut self, cx: &mut Context<'_>, - ) -> Poll, RequestId, Self::OutEvent, Self::Error>> - { + ) -> Poll< + ConnectionHandlerEvent, RequestId, Self::ToBehaviour, Self::Error>, + > { // Check for a pending (fatal) error. if let Some(err) = self.pending_error.take() { // The handler will not be polled again by the `Swarm`. diff --git a/protocols/request-response/src/lib.rs b/protocols/request-response/src/lib.rs index 4267f83da8c..10c78703e45 100644 --- a/protocols/request-response/src/lib.rs +++ b/protocols/request-response/src/lib.rs @@ -683,7 +683,7 @@ where TCodec: Codec + Send + Clone + 'static, { type ConnectionHandler = Handler; - type OutEvent = Event; + type ToSwarm = Event; fn handle_established_inbound_connection( &mut self, @@ -878,7 +878,7 @@ where &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(ev) = self.pending_events.pop_front() { return Poll::Ready(ev); } else if self.pending_events.capacity() > EMPTY_QUEUE_SHRINK_THRESHOLD { diff --git a/swarm-derive/CHANGELOG.md b/swarm-derive/CHANGELOG.md index 9628e7ea777..900e0d56d3d 100644 --- a/swarm-derive/CHANGELOG.md +++ b/swarm-derive/CHANGELOG.md @@ -3,7 +3,10 @@ - Raise MSRV to 1.65. See [PR 3715]. +- Rename `out_event` to `to_swarm` and deprecate `out_event`. See [PR 3848]. + [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3848]: https://github.com/libp2p/rust-libp2p/pull/3848 ## 0.32.0 diff --git a/swarm-derive/Cargo.toml b/swarm-derive/Cargo.toml index 8d31a389ae5..76b56cdbd45 100644 --- a/swarm-derive/Cargo.toml +++ b/swarm-derive/Cargo.toml @@ -17,6 +17,8 @@ proc-macro = true heck = "0.4" quote = "1.0" syn = { version = "2.0.15", default-features = false, features = ["clone-impls", "derive", "parsing", "printing", "proc-macro"] } +proc-macro-warning = "0.3.1" +proc-macro2 = "1.0" # Passing arguments to the docsrs builder in order to properly document cfg's. # More information: https://docs.rs/about/builds#cross-compiling diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 04a32cf91a7..d08c42f4f02 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -54,6 +54,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let BehaviourAttributes { prelude_path, user_specified_out_event, + deprecation_tokenstream, } = match parse_attributes(ast) { Ok(attrs) => attrs, Err(e) => return e, @@ -96,11 +97,11 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }; let (out_event_name, out_event_definition, out_event_from_clauses) = { - // If we find a `#[behaviour(out_event = "Foo")]` attribute on the - // struct, we set `Foo` as the out event. If not, the `OutEvent` is + // If we find a `#[behaviour(to_swarm = "Foo")]` attribute on the + // struct, we set `Foo` as the out event. If not, the `ToSwarm` is // generated. match user_specified_out_event { - // User provided `OutEvent`. + // User provided `ToSwarm`. Some(name) => { let definition = None; let from_clauses = data_struct @@ -108,12 +109,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .iter() .map(|field| { let ty = &field.ty; - quote! {#name: From< <#ty as #trait_to_impl>::OutEvent >} + quote! {#name: From< <#ty as #trait_to_impl>::ToSwarm >} }) .collect::>(); (name, definition, from_clauses) } - // User did not provide `OutEvent`. Generate it. + // User did not provide `ToSwarm`. Generate it. None => { let enum_name_str = ast.ident.to_string() + "Event"; let enum_name: syn::Type = @@ -135,7 +136,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let enum_variants = fields .clone() - .map(|(variant, ty)| quote! {#variant(<#ty as #trait_to_impl>::OutEvent)}); + .map(|(variant, ty)| quote! {#variant(<#ty as #trait_to_impl>::ToSwarm)}); let visibility = &ast.vis; @@ -146,7 +147,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { let additional_debug = fields .clone() - .map(|(_variant, ty)| quote! { <#ty as #trait_to_impl>::OutEvent : ::core::fmt::Debug }) + .map(|(_variant, ty)| quote! { <#ty as #trait_to_impl>::ToSwarm : ::core::fmt::Debug }) .collect::>(); let where_clause = { @@ -168,7 +169,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .map(|where_clause| quote! {#where_clause, #(#additional_debug),*}); let match_variants = fields.map(|(variant, _ty)| variant); - let msg = format!("`NetworkBehaviour::OutEvent` produced by {name}."); + let msg = format!("`NetworkBehaviour::ToSwarm` produced by {name}."); Some(quote! { #[doc = #msg] @@ -677,9 +678,9 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } let generate_event_match_arm = { - // If the `NetworkBehaviour`'s `OutEvent` is generated by the derive macro, wrap the sub - // `NetworkBehaviour` `OutEvent` in the variant of the generated `OutEvent`. If the - // `NetworkBehaviour`'s `OutEvent` is provided by the user, use the corresponding `From` + // If the `NetworkBehaviour`'s `ToSwarm` is generated by the derive macro, wrap the sub + // `NetworkBehaviour` `ToSwarm` in the variant of the generated `ToSwarm`. If the + // `NetworkBehaviour`'s `ToSwarm` is provided by the user, use the corresponding `From` // implementation. let into_out_event = if out_event_definition.is_some() { let event_variant: syn::Variant = syn::parse_str( @@ -731,13 +732,15 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { // Now the magic happens. let final_quote = quote! { + #deprecation_tokenstream + #out_event_definition impl #impl_generics #trait_to_impl for #name #ty_generics #where_clause { type ConnectionHandler = #connection_handler_ty; - type OutEvent = #out_event_reference; + type ToSwarm = #out_event_reference; #[allow(clippy::needless_question_mark)] fn handle_pending_inbound_connection( @@ -795,7 +798,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } } - fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action>> { + fn poll(&mut self, cx: &mut std::task::Context, poll_params: &mut impl #poll_parameters) -> std::task::Poll<#network_behaviour_action>> { use #prelude_path::futures::*; #(#poll_stmts)* std::task::Poll::Pending @@ -851,6 +854,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { struct BehaviourAttributes { prelude_path: syn::Path, user_specified_out_event: Option, + deprecation_tokenstream: proc_macro2::TokenStream, } /// Parses the `value` of a key=value pair in the `#[behaviour]` attribute into the requested type. @@ -858,7 +862,9 @@ fn parse_attributes(ast: &DeriveInput) -> Result Result unimplemented!(), Meta::List(_) => unimplemented!(), @@ -914,7 +923,7 @@ fn parse_attributes(ast: &DeriveInput) -> Result { return Err(syn::Error::new_spanned( name_value.value, - "`out_event` value must be a quoted type", + "`to_swarm` value must be a quoted type", ) .to_compile_error() .into()); @@ -926,5 +935,15 @@ fn parse_attributes(ast: &DeriveInput) -> Result(&mut self, other: &mut Swarm) where T: NetworkBehaviour + Send, - ::OutEvent: Debug; + ::ToSwarm: Debug; /// Dial the provided address and wait until a connection has been established. /// @@ -68,7 +68,7 @@ pub trait SwarmExt { async fn wait(&mut self, predicate: P) -> E where P: Fn( - SwarmEvent<::OutEvent, THandlerErr>, + SwarmEvent<::ToSwarm, THandlerErr>, ) -> Option, P: Send; @@ -82,12 +82,12 @@ pub trait SwarmExt { /// If the 10s timeout does not fit your usecase, please fall back to `StreamExt::next`. async fn next_swarm_event( &mut self, - ) -> SwarmEvent<::OutEvent, THandlerErr>; + ) -> SwarmEvent<::ToSwarm, THandlerErr>; /// Returns the next behaviour event or times out after 10 seconds. /// /// If the 10s timeout does not fit your usecase, please fall back to `StreamExt::next`. - async fn next_behaviour_event(&mut self) -> ::OutEvent; + async fn next_behaviour_event(&mut self) -> ::ToSwarm; async fn loop_on_next(self); } @@ -108,7 +108,7 @@ pub trait SwarmExt { /// This function utilizes the [`TryIntoOutput`] trait. /// Similar as to the number of expected events, the type of event is inferred based on your usage. /// If you match against a [`SwarmEvent`], the first [`SwarmEvent`] will be returned. -/// If you match against your [`NetworkBehaviour::OutEvent`] type, [`SwarmEvent`]s which are not [`SwarmEvent::Behaviour`] will be skipped until the [`Swarm`] returns a behaviour event. +/// If you match against your [`NetworkBehaviour::ToSwarm`] type, [`SwarmEvent`]s which are not [`SwarmEvent::Behaviour`] will be skipped until the [`Swarm`] returns a behaviour event. /// /// You can implement the [`TryIntoOutput`] for any other type to further customize this behaviour. /// @@ -136,11 +136,11 @@ pub async fn drive< ) -> ([Out1; NUM_EVENTS_SWARM_1], [Out2; NUM_EVENTS_SWARM_2]) where TBehaviour2: NetworkBehaviour + Send, - TBehaviour2::OutEvent: Debug, + TBehaviour2::ToSwarm: Debug, TBehaviour1: NetworkBehaviour + Send, - TBehaviour1::OutEvent: Debug, - SwarmEvent>: TryIntoOutput, - SwarmEvent>: TryIntoOutput, + TBehaviour1::ToSwarm: Debug, + SwarmEvent>: TryIntoOutput, + SwarmEvent>: TryIntoOutput, Out1: Debug, Out2: Debug, { @@ -199,7 +199,7 @@ impl TryIntoOutput SwarmExt for Swarm where B: NetworkBehaviour + Send, - ::OutEvent: Debug, + ::ToSwarm: Debug, { type NB = B; @@ -226,7 +226,7 @@ where async fn connect(&mut self, other: &mut Swarm) where T: NetworkBehaviour + Send, - ::OutEvent: Debug, + ::ToSwarm: Debug, { let external_addresses = other .external_addresses() @@ -283,7 +283,7 @@ where async fn wait(&mut self, predicate: P) -> E where - P: Fn(SwarmEvent<::OutEvent, THandlerErr>) -> Option, + P: Fn(SwarmEvent<::ToSwarm, THandlerErr>) -> Option, P: Send, { loop { @@ -345,7 +345,7 @@ where async fn next_swarm_event( &mut self, - ) -> SwarmEvent<::OutEvent, THandlerErr> { + ) -> SwarmEvent<::ToSwarm, THandlerErr> { match futures::future::select( futures_timer::Delay::new(Duration::from_secs(10)), self.select_next_some(), @@ -361,7 +361,7 @@ where } } - async fn next_behaviour_event(&mut self) -> ::OutEvent { + async fn next_behaviour_event(&mut self) -> ::ToSwarm { loop { if let Ok(event) = self.next_swarm_event().await.try_into_behaviour_event() { return event; diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 86023f5541f..6c4bb389482 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -39,12 +39,14 @@ - `ConnectionHandlerEvent::ReportRemoteProtocols` - `ConnectionEvent::LocalProtocolsChange` - `ConnectionEvent::RemoteProtocolsChange` - + See [PR 3651]. - Deprecate the `NegotiatedSubstream` type and replace it with `Stream`. See [PR 3912]. +- Rename `NetworkBehaviour::OutEvent` to `NetworkBehaviour::ToSwarm`, `ConnectionHandler::InEvent` to `ConnectionHandler::FromBehaviour`, `ConnectionHandler::OutEvent` to `ConnectionHandler::ToBehaviour`. See [PR 3848]. + [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 [PR 3651]: https://github.com/libp2p/rust-libp2p/pull/3651 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 @@ -55,6 +57,7 @@ [PR 3885]: https://github.com/libp2p/rust-libp2p/pull/3885 [PR 3886]: https://github.com/libp2p/rust-libp2p/pull/3886 [PR 3912]: https://github.com/libp2p/rust-libp2p/pull/3912 +[PR 3848]: https://github.com/libp2p/rust-libp2p/pull/3848 ## 0.42.2 diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 483c65f8dfd..51214454973 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -54,6 +54,7 @@ libp2p-yamux = { workspace = true } quickcheck = { workspace = true } void = "1" once_cell = "1.17.1" +trybuild = "1.0.80" [[test]] name = "swarm_derive" diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index 9953b08793b..e35f412f0ce 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -77,14 +77,14 @@ use std::{task::Context, task::Poll}; /// [`NetworkBehaviour::poll`] it will first poll the first `struct` member until it returns /// [`Poll::Pending`] before moving on to later members. /// -/// Events ([`NetworkBehaviour::OutEvent`]) returned by each `struct` member are wrapped in a new +/// Events ([`NetworkBehaviour::ToSwarm`]) returned by each `struct` member are wrapped in a new /// `enum` event, with an `enum` variant for each `struct` member. Users can define this event -/// `enum` themselves and provide the name to the derive macro via `#[behaviour(out_event = -/// "MyCustomOutEvent")]`. If the user does not specify an `out_event`, the derive macro generates +/// `enum` themselves and provide the name to the derive macro via `#[behaviour(to_swarm = +/// "MyCustomOutEvent")]`. If the user does not specify an `to_swarm`, the derive macro generates /// the event definition itself, naming it `Event`. /// /// The aforementioned conversion of each of the event types generated by the struct members to the -/// custom `out_event` is handled by [`From`] implementations which the user needs to define in +/// custom `to_swarm` is handled by [`From`] implementations which the user needs to define in /// addition to the event `enum` itself. /// /// ``` rust @@ -92,7 +92,7 @@ use std::{task::Context, task::Poll}; /// # use libp2p_ping as ping; /// # use libp2p_swarm_derive::NetworkBehaviour; /// #[derive(NetworkBehaviour)] -/// #[behaviour(out_event = "Event")] +/// #[behaviour(to_swarm = "Event")] /// # #[behaviour(prelude = "libp2p_swarm::derive_prelude")] /// struct MyBehaviour { /// identify: identify::Behaviour, @@ -121,7 +121,7 @@ pub trait NetworkBehaviour: 'static { type ConnectionHandler: ConnectionHandler; /// Event generated by the `NetworkBehaviour` and that the swarm will report back. - type OutEvent: Send + 'static; + type ToSwarm: Send + 'static; /// Callback that is invoked for every new inbound connection. /// @@ -212,7 +212,7 @@ pub trait NetworkBehaviour: 'static { &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll>>; + ) -> Poll>>; } /// Parameters passed to `poll()`, that the `NetworkBehaviour` has access to. diff --git a/swarm/src/behaviour/either.rs b/swarm/src/behaviour/either.rs index bf59949ccfe..c6e0870d11c 100644 --- a/swarm/src/behaviour/either.rs +++ b/swarm/src/behaviour/either.rs @@ -33,7 +33,7 @@ where R: NetworkBehaviour, { type ConnectionHandler = Either, THandler>; - type OutEvent = Either; + type ToSwarm = Either; fn handle_pending_inbound_connection( &mut self, @@ -156,7 +156,7 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { let event = match self { Either::Left(behaviour) => futures::ready!(behaviour.poll(cx, params)) .map_out(Either::Left) diff --git a/swarm/src/behaviour/toggle.rs b/swarm/src/behaviour/toggle.rs index 0e687fe9355..92bd8963502 100644 --- a/swarm/src/behaviour/toggle.rs +++ b/swarm/src/behaviour/toggle.rs @@ -71,7 +71,7 @@ where TBehaviour: NetworkBehaviour, { type ConnectionHandler = ToggleConnectionHandler>; - type OutEvent = TBehaviour::OutEvent; + type ToSwarm = TBehaviour::ToSwarm; fn handle_pending_inbound_connection( &mut self, @@ -182,7 +182,7 @@ where &mut self, cx: &mut Context<'_>, params: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { if let Some(inner) = self.inner.as_mut() { inner.poll(cx, params) } else { @@ -267,8 +267,8 @@ impl ConnectionHandler for ToggleConnectionHandler where TInner: ConnectionHandler, { - type InEvent = TInner::InEvent; - type OutEvent = TInner::OutEvent; + type FromBehaviour = TInner::FromBehaviour; + type ToBehaviour = TInner::ToBehaviour; type Error = TInner::Error; type InboundProtocol = Either, SendWrapper>; type OutboundProtocol = TInner::OutboundProtocol; @@ -286,7 +286,7 @@ where } } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { self.inner .as_mut() .expect("Can't receive events if disabled; QED") @@ -307,7 +307,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index 30f95a29317..43be1c98e3a 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -209,7 +209,7 @@ where } /// Notifies the connection handler of an event. - pub(crate) fn on_behaviour_event(&mut self, event: THandler::InEvent) { + pub(crate) fn on_behaviour_event(&mut self, event: THandler::FromBehaviour) { self.handler.on_behaviour_event(event); } @@ -224,7 +224,7 @@ where pub(crate) fn poll( self: Pin<&mut Self>, cx: &mut Context<'_>, - ) -> Poll, ConnectionError>> { + ) -> Poll, ConnectionError>> { let Self { requested_substreams, muxing, @@ -439,7 +439,7 @@ where #[cfg(test)] fn poll_noop_waker( &mut self, - ) -> Poll, ConnectionError>> { + ) -> Poll, ConnectionError>> { Pin::new(self).poll(&mut Context::from_waker(futures::task::noop_waker_ref())) } } @@ -995,8 +995,8 @@ mod tests { } impl ConnectionHandler for MockConnectionHandler { - type InEvent = Void; - type OutEvent = Void; + type FromBehaviour = Void; + type ToBehaviour = Void; type Error = Void; type InboundProtocol = DeniedUpgrade; type OutboundProtocol = DeniedUpgrade; @@ -1037,7 +1037,7 @@ mod tests { } } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { void::unreachable(event) } @@ -1052,7 +1052,7 @@ mod tests { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { @@ -1069,8 +1069,8 @@ mod tests { } impl ConnectionHandler for ConfigurableProtocolConnectionHandler { - type InEvent = Void; - type OutEvent = Void; + type FromBehaviour = Void; + type ToBehaviour = Void; type Error = Void; type InboundProtocol = ManyProtocolsUpgrade; type OutboundProtocol = DeniedUpgrade; @@ -1114,7 +1114,7 @@ mod tests { } } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { void::unreachable(event) } @@ -1129,7 +1129,7 @@ mod tests { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 32a3924232c..36fa0adf3e9 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -90,8 +90,10 @@ where counters: ConnectionCounters, /// The managed connections of each peer that are currently considered established. - established: - FnvHashMap>>, + established: FnvHashMap< + PeerId, + FnvHashMap>, + >, /// The pending connections that are currently being negotiated. pending: HashMap, @@ -285,7 +287,7 @@ pub(crate) enum PoolEvent { id: ConnectionId, peer_id: PeerId, /// The produced event. - event: THandler::OutEvent, + event: THandler::ToBehaviour, }, /// The connection to a node has changed its address. @@ -338,7 +340,7 @@ where pub(crate) fn get_established( &mut self, id: ConnectionId, - ) -> Option<&mut EstablishedConnection> { + ) -> Option<&mut EstablishedConnection> { self.established .values_mut() .find_map(|connections| connections.get_mut(&id)) diff --git a/swarm/src/connection/pool/task.rs b/swarm/src/connection/pool/task.rs index dd318f77d30..175da668bda 100644 --- a/swarm/src/connection/pool/task.rs +++ b/swarm/src/connection/pool/task.rs @@ -77,7 +77,7 @@ pub(crate) enum EstablishedConnectionEvent { Notify { id: ConnectionId, peer_id: PeerId, - event: THandler::OutEvent, + event: THandler::ToBehaviour, }, /// A connection closed, possibly due to an error. /// @@ -171,7 +171,7 @@ pub(crate) async fn new_for_established_connection( connection_id: ConnectionId, peer_id: PeerId, mut connection: crate::connection::Connection, - mut command_receiver: mpsc::Receiver>, + mut command_receiver: mpsc::Receiver>, mut events: mpsc::Sender>, ) where THandler: ConnectionHandler, diff --git a/swarm/src/dummy.rs b/swarm/src/dummy.rs index 83d03a7aadb..563d86a667e 100644 --- a/swarm/src/dummy.rs +++ b/swarm/src/dummy.rs @@ -19,7 +19,7 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; - type OutEvent = Void; + type ToSwarm = Void; fn handle_established_inbound_connection( &mut self, @@ -54,7 +54,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { Poll::Pending } @@ -81,8 +81,8 @@ impl NetworkBehaviour for Behaviour { pub struct ConnectionHandler; impl crate::handler::ConnectionHandler for ConnectionHandler { - type InEvent = Void; - type OutEvent = Void; + type FromBehaviour = Void; + type ToBehaviour = Void; type Error = Void; type InboundProtocol = DeniedUpgrade; type OutboundProtocol = DeniedUpgrade; @@ -93,7 +93,7 @@ impl crate::handler::ConnectionHandler for ConnectionHandler { SubstreamProtocol::new(DeniedUpgrade, ()) } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { void::unreachable(event) } @@ -108,7 +108,7 @@ impl crate::handler::ConnectionHandler for ConnectionHandler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/handler.rs b/swarm/src/handler.rs index 2ce58638bd1..edefb7a1cb9 100644 --- a/swarm/src/handler.rs +++ b/swarm/src/handler.rs @@ -99,10 +99,10 @@ use std::{cmp::Ordering, error, fmt, io, task::Context, task::Poll, time::Durati /// When a connection is closed gracefully, the substreams used by the handler may still /// continue reading data until the remote closes its side of the connection. pub trait ConnectionHandler: Send + 'static { - /// Custom event that can be received from the outside. - type InEvent: fmt::Debug + Send + 'static; - /// Custom event that can be produced by the handler and that will be returned to the outside. - type OutEvent: fmt::Debug + Send + 'static; + /// A type representing the message(s) a [`NetworkBehaviour`](crate::behaviour::NetworkBehaviour) can send to a [`ConnectionHandler`] via [`ToSwarm::NotifyHandler`](crate::behaviour::ToSwarm::NotifyHandler) + type FromBehaviour: fmt::Debug + Send + 'static; + /// A type representing message(s) a [`ConnectionHandler`] can send to a [`NetworkBehaviour`](crate::behaviour::NetworkBehaviour) via [`ConnectionHandlerEvent::Custom`]. + type ToBehaviour: fmt::Debug + Send + 'static; /// The type of errors returned by [`ConnectionHandler::poll`]. type Error: error::Error + fmt::Debug + Send + 'static; /// The inbound upgrade for the protocol(s) used by the handler. @@ -153,7 +153,7 @@ pub trait ConnectionHandler: Send + 'static { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, >; @@ -162,7 +162,7 @@ pub trait ConnectionHandler: Send + 'static { fn map_in_event(self, map: TMap) -> MapInEvent where Self: Sized, - TMap: Fn(&TNewIn) -> Option<&Self::InEvent>, + TMap: Fn(&TNewIn) -> Option<&Self::FromBehaviour>, { MapInEvent::new(self, map) } @@ -171,7 +171,7 @@ pub trait ConnectionHandler: Send + 'static { fn map_out_event(self, map: TMap) -> MapOutEvent where Self: Sized, - TMap: FnMut(Self::OutEvent) -> TNewOut, + TMap: FnMut(Self::ToBehaviour) -> TNewOut, { MapOutEvent::new(self, map) } @@ -190,7 +190,7 @@ pub trait ConnectionHandler: Send + 'static { } /// Informs the handler about an event from the [`NetworkBehaviour`](super::NetworkBehaviour). - fn on_behaviour_event(&mut self, _event: Self::InEvent); + fn on_behaviour_event(&mut self, _event: Self::FromBehaviour); fn on_connection_event( &mut self, diff --git a/swarm/src/handler/either.rs b/swarm/src/handler/either.rs index 08c914abd47..6a60427228d 100644 --- a/swarm/src/handler/either.rs +++ b/swarm/src/handler/either.rs @@ -78,8 +78,8 @@ where L: ConnectionHandler, R: ConnectionHandler, { - type InEvent = Either; - type OutEvent = Either; + type FromBehaviour = Either; + type ToBehaviour = Either; type Error = Either; type InboundProtocol = Either, SendWrapper>; type OutboundProtocol = @@ -100,7 +100,7 @@ where } } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { match (self, event) { (Either::Left(handler), Either::Left(event)) => handler.on_behaviour_event(event), (Either::Right(handler), Either::Right(event)) => handler.on_behaviour_event(event), @@ -122,7 +122,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/handler/map_in.rs b/swarm/src/handler/map_in.rs index 3564de919bb..af828999b03 100644 --- a/swarm/src/handler/map_in.rs +++ b/swarm/src/handler/map_in.rs @@ -45,12 +45,12 @@ impl ConnectionHandler for MapInEvent where TConnectionHandler: ConnectionHandler, - TMap: Fn(TNewIn) -> Option, + TMap: Fn(TNewIn) -> Option, TNewIn: Debug + Send + 'static, TMap: Send + 'static, { - type InEvent = TNewIn; - type OutEvent = TConnectionHandler::OutEvent; + type FromBehaviour = TNewIn; + type ToBehaviour = TConnectionHandler::ToBehaviour; type Error = TConnectionHandler::Error; type InboundProtocol = TConnectionHandler::InboundProtocol; type OutboundProtocol = TConnectionHandler::OutboundProtocol; @@ -78,7 +78,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/handler/map_out.rs b/swarm/src/handler/map_out.rs index 349aa553764..f3240a76b2d 100644 --- a/swarm/src/handler/map_out.rs +++ b/swarm/src/handler/map_out.rs @@ -40,12 +40,12 @@ impl MapOutEvent { impl ConnectionHandler for MapOutEvent where TConnectionHandler: ConnectionHandler, - TMap: FnMut(TConnectionHandler::OutEvent) -> TNewOut, + TMap: FnMut(TConnectionHandler::ToBehaviour) -> TNewOut, TNewOut: Debug + Send + 'static, TMap: Send + 'static, { - type InEvent = TConnectionHandler::InEvent; - type OutEvent = TNewOut; + type FromBehaviour = TConnectionHandler::FromBehaviour; + type ToBehaviour = TNewOut; type Error = TConnectionHandler::Error; type InboundProtocol = TConnectionHandler::InboundProtocol; type OutboundProtocol = TConnectionHandler::OutboundProtocol; @@ -56,7 +56,7 @@ where self.inner.listen_protocol() } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { self.inner.on_behaviour_event(event) } @@ -71,7 +71,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/handler/multi.rs b/swarm/src/handler/multi.rs index 5caf611278f..ced94f1213c 100644 --- a/swarm/src/handler/multi.rs +++ b/swarm/src/handler/multi.rs @@ -110,8 +110,8 @@ where H::InboundProtocol: InboundUpgradeSend, H::OutboundProtocol: OutboundUpgradeSend, { - type InEvent = (K, ::InEvent); - type OutEvent = (K, ::OutEvent); + type FromBehaviour = (K, ::FromBehaviour); + type ToBehaviour = (K, ::ToBehaviour); type Error = ::Error; type InboundProtocol = Upgrade::InboundProtocol>; type OutboundProtocol = ::OutboundProtocol; @@ -222,7 +222,7 @@ where } } - fn on_behaviour_event(&mut self, (key, event): Self::InEvent) { + fn on_behaviour_event(&mut self, (key, event): Self::FromBehaviour) { if let Some(h) = self.handlers.get_mut(&key) { h.on_behaviour_event(event) } else { @@ -245,7 +245,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/handler/one_shot.rs b/swarm/src/handler/one_shot.rs index c4da5877c96..b7c98e189e7 100644 --- a/swarm/src/handler/one_shot.rs +++ b/swarm/src/handler/one_shot.rs @@ -121,8 +121,8 @@ where SubstreamProtocol: Clone, TEvent: Debug + Send + 'static, { - type InEvent = TOutbound; - type OutEvent = TEvent; + type FromBehaviour = TOutbound; + type ToBehaviour = TEvent; type Error = StreamUpgradeError<::Error>; type InboundProtocol = TInbound; type OutboundProtocol = TOutbound; @@ -133,7 +133,7 @@ where self.listen_protocol.clone() } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { self.send_request(event); } @@ -148,7 +148,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/handler/pending.rs b/swarm/src/handler/pending.rs index 7cf8b9209fa..ee6829356bd 100644 --- a/swarm/src/handler/pending.rs +++ b/swarm/src/handler/pending.rs @@ -40,8 +40,8 @@ impl PendingConnectionHandler { } impl ConnectionHandler for PendingConnectionHandler { - type InEvent = Void; - type OutEvent = Void; + type FromBehaviour = Void; + type ToBehaviour = Void; type Error = Void; type InboundProtocol = PendingUpgrade; type OutboundProtocol = PendingUpgrade; @@ -52,7 +52,7 @@ impl ConnectionHandler for PendingConnectionHandler { SubstreamProtocol::new(PendingUpgrade::new(self.protocol_name.clone()), ()) } - fn on_behaviour_event(&mut self, v: Self::InEvent) { + fn on_behaviour_event(&mut self, v: Self::FromBehaviour) { void::unreachable(v) } @@ -67,7 +67,7 @@ impl ConnectionHandler for PendingConnectionHandler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/handler/select.rs b/swarm/src/handler/select.rs index 204d11ce502..48048befc81 100644 --- a/swarm/src/handler/select.rs +++ b/swarm/src/handler/select.rs @@ -179,8 +179,8 @@ where TProto1: ConnectionHandler, TProto2: ConnectionHandler, { - type InEvent = Either; - type OutEvent = Either; + type FromBehaviour = Either; + type ToBehaviour = Either; type Error = Either; type InboundProtocol = SelectUpgrade< SendWrapper<::InboundProtocol>, @@ -201,7 +201,7 @@ where SubstreamProtocol::new(choice, (i1, i2)).with_timeout(timeout) } - fn on_behaviour_event(&mut self, event: Self::InEvent) { + fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { match event { Either::Left(event) => self.proto1.on_behaviour_event(event), Either::Right(event) => self.proto2.on_behaviour_event(event), @@ -222,7 +222,7 @@ where ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/keep_alive.rs b/swarm/src/keep_alive.rs index aa4da2db826..f91f80990a6 100644 --- a/swarm/src/keep_alive.rs +++ b/swarm/src/keep_alive.rs @@ -22,7 +22,7 @@ pub struct Behaviour; impl NetworkBehaviour for Behaviour { type ConnectionHandler = ConnectionHandler; - type OutEvent = Void; + type ToSwarm = Void; fn handle_established_inbound_connection( &mut self, @@ -57,7 +57,7 @@ impl NetworkBehaviour for Behaviour { &mut self, _: &mut Context<'_>, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { Poll::Pending } @@ -84,8 +84,8 @@ impl NetworkBehaviour for Behaviour { pub struct ConnectionHandler; impl crate::handler::ConnectionHandler for ConnectionHandler { - type InEvent = Void; - type OutEvent = Void; + type FromBehaviour = Void; + type ToBehaviour = Void; type Error = Void; type InboundProtocol = DeniedUpgrade; type OutboundProtocol = DeniedUpgrade; @@ -96,7 +96,7 @@ impl crate::handler::ConnectionHandler for ConnectionHandler { SubstreamProtocol::new(DeniedUpgrade, ()) } - fn on_behaviour_event(&mut self, v: Self::InEvent) { + fn on_behaviour_event(&mut self, v: Self::FromBehaviour) { void::unreachable(v) } @@ -111,7 +111,7 @@ impl crate::handler::ConnectionHandler for ConnectionHandler { ConnectionHandlerEvent< Self::OutboundProtocol, Self::OutboundOpenInfo, - Self::OutEvent, + Self::ToBehaviour, Self::Error, >, > { diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 3360a0bfa99..16dd9511d35 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -165,7 +165,7 @@ use std::{ pub type NegotiatedSubstream = Stream; /// Event generated by the [`NetworkBehaviour`] that the swarm will report back. -type TBehaviourOutEvent = ::OutEvent; +type TBehaviourOutEvent = ::ToSwarm; /// [`ConnectionHandler`] of the [`NetworkBehaviour`] for all the protocols the [`NetworkBehaviour`] /// supports. @@ -174,10 +174,10 @@ pub type THandler = ::ConnectionHand /// Custom event that can be received by the [`ConnectionHandler`] of the /// [`NetworkBehaviour`]. -pub type THandlerInEvent = as ConnectionHandler>::InEvent; +pub type THandlerInEvent = as ConnectionHandler>::FromBehaviour; /// Custom event that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. -pub type THandlerOutEvent = as ConnectionHandler>::OutEvent; +pub type THandlerOutEvent = as ConnectionHandler>::ToBehaviour; /// Custom error that can be produced by the [`ConnectionHandler`] of the [`NetworkBehaviour`]. pub type THandlerErr = as ConnectionHandler>::Error; @@ -743,7 +743,7 @@ where fn handle_pool_event( &mut self, event: PoolEvent>, - ) -> Option>> { + ) -> Option>> { match event { PoolEvent::ConnectionEstablished { peer_id, @@ -984,7 +984,7 @@ where as Transport>::ListenerUpgrade, io::Error, >, - ) -> Option>> { + ) -> Option>> { match event { TransportEvent::Incoming { listener_id: _, @@ -1109,8 +1109,8 @@ where fn handle_behaviour_event( &mut self, - event: ToSwarm>, - ) -> Option>> { + event: ToSwarm>, + ) -> Option>> { match event { ToSwarm::GenerateEvent(event) => return Some(SwarmEvent::Behaviour(event)), ToSwarm::Dial { opts } => { @@ -1194,7 +1194,7 @@ where fn poll_next_event( mut self: Pin<&mut Self>, cx: &mut Context<'_>, - ) -> Poll>> { + ) -> Poll>> { // We use a `this` variable because the compiler can't mutably borrow multiple times // across a `Deref`. let this = &mut *self; @@ -1343,8 +1343,8 @@ fn notify_any( where TBehaviour: NetworkBehaviour, THandler: ConnectionHandler< - InEvent = THandlerInEvent, - OutEvent = THandlerOutEvent, + FromBehaviour = THandlerInEvent, + ToBehaviour = THandlerOutEvent, >, { let mut pending = SmallVec::new(); @@ -1923,7 +1923,7 @@ mod tests { ) -> SwarmBuilder>> where T: ConnectionHandler + Clone, - T::OutEvent: Clone, + T::ToBehaviour: Clone, O: Send + 'static, { let id_keys = identity::Keypair::generate_ed25519(); diff --git a/swarm/src/test.rs b/swarm/src/test.rs index ccb282bd3f1..70d4e790956 100644 --- a/swarm/src/test.rs +++ b/swarm/src/test.rs @@ -37,7 +37,7 @@ use std::task::{Context, Poll}; pub(crate) struct MockBehaviour where THandler: ConnectionHandler + Clone, - THandler::OutEvent: Clone, + THandler::ToBehaviour: Clone, TOutEvent: Send + 'static, { /// The prototype protocols handler that is cloned for every @@ -48,13 +48,13 @@ where /// The next action to return from `poll`. /// /// An action is only returned once. - pub(crate) next_action: Option>, + pub(crate) next_action: Option>, } impl MockBehaviour where THandler: ConnectionHandler + Clone, - THandler::OutEvent: Clone, + THandler::ToBehaviour: Clone, TOutEvent: Send + 'static, { pub(crate) fn new(handler_proto: THandler) -> Self { @@ -69,11 +69,11 @@ where impl NetworkBehaviour for MockBehaviour where THandler: ConnectionHandler + Clone, - THandler::OutEvent: Clone, + THandler::ToBehaviour: Clone, TOutEvent: Send + 'static, { type ConnectionHandler = THandler; - type OutEvent = TOutEvent; + type ToSwarm = TOutEvent; fn handle_established_inbound_connection( &mut self, @@ -114,7 +114,7 @@ where &mut self, _: &mut Context, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { self.next_action.take().map_or(Poll::Pending, Poll::Ready) } @@ -381,7 +381,7 @@ where THandlerOutEvent: Clone, { type ConnectionHandler = TInner::ConnectionHandler; - type OutEvent = TInner::OutEvent; + type ToSwarm = TInner::ToSwarm; fn handle_pending_inbound_connection( &mut self, @@ -558,7 +558,7 @@ where &mut self, cx: &mut Context, args: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { self.poll += 1; self.inner.poll(cx, args) } diff --git a/swarm/tests/swarm_derive.rs b/swarm/tests/swarm_derive.rs index 87f99e35736..ab1efaca396 100644 --- a/swarm/tests/swarm_derive.rs +++ b/swarm/tests/swarm_derive.rs @@ -56,7 +56,7 @@ fn one_field() { clippy::used_underscore_binding )] fn foo() { - let _out_event: ::OutEvent = unimplemented!(); + let _out_event: ::ToSwarm = unimplemented!(); match _out_event { FooEvent::Ping(ping::Event { .. }) => {} } @@ -80,7 +80,7 @@ fn two_fields() { clippy::used_underscore_binding )] fn foo() { - let _out_event: ::OutEvent = unimplemented!(); + let _out_event: ::ToSwarm = unimplemented!(); match _out_event { FooEvent::Ping(ping::Event { .. }) => {} FooEvent::Identify(event) => { @@ -108,7 +108,7 @@ fn three_fields() { clippy::used_underscore_binding )] fn foo() { - let _out_event: ::OutEvent = unimplemented!(); + let _out_event: ::ToSwarm = unimplemented!(); match _out_event { FooEvent::Ping(ping::Event { .. }) => {} FooEvent::Identify(event) => { @@ -125,7 +125,7 @@ fn three_fields() { fn custom_event() { #[allow(dead_code)] #[derive(NetworkBehaviour)] - #[behaviour(out_event = "MyEvent", prelude = "libp2p_swarm::derive_prelude")] + #[behaviour(to_swarm = "MyEvent", prelude = "libp2p_swarm::derive_prelude")] struct Foo { ping: ping::Behaviour, identify: identify::Behaviour, @@ -159,7 +159,7 @@ fn custom_event() { fn custom_event_mismatching_field_names() { #[allow(dead_code)] #[derive(NetworkBehaviour)] - #[behaviour(out_event = "MyEvent", prelude = "libp2p_swarm::derive_prelude")] + #[behaviour(to_swarm = "MyEvent", prelude = "libp2p_swarm::derive_prelude")] struct Foo { a: ping::Behaviour, b: identify::Behaviour, @@ -196,7 +196,7 @@ fn bound() { #[behaviour(prelude = "libp2p_swarm::derive_prelude")] struct Foo where - ::OutEvent: Debug, + ::ToSwarm: Debug, { ping: ping::Behaviour, bar: T, @@ -211,7 +211,7 @@ fn where_clause() { struct Foo where T: Copy + NetworkBehaviour, - ::OutEvent: Debug, + ::ToSwarm: Debug, { ping: ping::Behaviour, bar: T, @@ -241,7 +241,7 @@ fn nested_derives_with_import() { clippy::used_underscore_binding )] fn foo() { - let _out_event: ::OutEvent = unimplemented!(); + let _out_event: ::ToSwarm = unimplemented!(); match _out_event { BarEvent::Foo(FooEvent::Ping(ping::Event { .. })) => {} } @@ -271,7 +271,7 @@ fn custom_event_emit_event_through_poll() { #[allow(dead_code, clippy::large_enum_variant)] #[derive(NetworkBehaviour)] #[behaviour( - out_event = "BehaviourOutEvent", + to_swarm = "BehaviourOutEvent", prelude = "libp2p_swarm::derive_prelude" )] struct Foo { @@ -400,7 +400,7 @@ fn custom_event_with_either() { #[allow(dead_code)] #[derive(NetworkBehaviour)] #[behaviour( - out_event = "BehaviourOutEvent", + to_swarm = "BehaviourOutEvent", prelude = "libp2p_swarm::derive_prelude" )] struct Foo { @@ -426,7 +426,7 @@ fn generated_out_event_derive_debug() { fn require_debug() where T: NetworkBehaviour, - ::OutEvent: Debug, + ::ToSwarm: Debug, { } @@ -437,7 +437,7 @@ fn generated_out_event_derive_debug() { fn multiple_behaviour_attributes() { #[allow(dead_code)] #[derive(NetworkBehaviour)] - #[behaviour(out_event = "FooEvent")] + #[behaviour(to_swarm = "FooEvent")] #[behaviour(prelude = "libp2p_swarm::derive_prelude")] struct Foo { ping: ping::Behaviour, @@ -467,7 +467,7 @@ fn custom_out_event_no_type_parameters() { impl NetworkBehaviour for TemplatedBehaviour { type ConnectionHandler = dummy::ConnectionHandler; - type OutEvent = void::Void; + type ToSwarm = void::Void; fn handle_established_inbound_connection( &mut self, @@ -502,7 +502,7 @@ fn custom_out_event_no_type_parameters() { &mut self, _ctx: &mut Context, _: &mut impl PollParameters, - ) -> Poll>> { + ) -> Poll>> { Poll::Pending } @@ -525,7 +525,7 @@ fn custom_out_event_no_type_parameters() { } #[derive(NetworkBehaviour)] - #[behaviour(out_event = "OutEvent", prelude = "libp2p_swarm::derive_prelude")] + #[behaviour(to_swarm = "OutEvent", prelude = "libp2p_swarm::derive_prelude")] struct Behaviour { custom: TemplatedBehaviour, } @@ -544,3 +544,9 @@ fn custom_out_event_no_type_parameters() { require_net_behaviour::>(); require_net_behaviour::>(); } + +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/fail/*.rs"); +} diff --git a/swarm/tests/ui/fail/out_event_deprecation.rs b/swarm/tests/ui/fail/out_event_deprecation.rs new file mode 100644 index 00000000000..f552ca32d10 --- /dev/null +++ b/swarm/tests/ui/fail/out_event_deprecation.rs @@ -0,0 +1,21 @@ +#![deny(warnings)] // Ensure the warnings we produce surface as errors. + +use libp2p_ping as ping; + +#[derive(libp2p_swarm::NetworkBehaviour)] +#[behaviour(out_event = "FooEvent", prelude = "libp2p_swarm::derive_prelude")] +struct Foo { + ping: ping::Behaviour, +} + +struct FooEvent; + +impl From for FooEvent { + fn from(_: ping::Event) -> Self { + unimplemented!() + } +} + +fn main() { + +} diff --git a/swarm/tests/ui/fail/out_event_deprecation.stderr b/swarm/tests/ui/fail/out_event_deprecation.stderr new file mode 100644 index 00000000000..75a65f43f6d --- /dev/null +++ b/swarm/tests/ui/fail/out_event_deprecation.stderr @@ -0,0 +1,14 @@ +error: use of deprecated constant `out_event_renamed_to_to_swarm::_w`: + It is deprecated to use the out_event attribute `#[behaviour(out_event = ...)]`. + Please instead use the to_swarm attribute `#[behaviour(to_swarm = ...)]`. + --> tests/ui/fail/out_event_deprecation.rs:7:8 + | +7 | struct Foo { + | ^^^ + | +note: the lint level is defined here + --> tests/ui/fail/out_event_deprecation.rs:1:9 + | +1 | #![deny(warnings)] // Ensure the warnings we produce surface as errors. + | ^^^^^^^^ + = note: `#[deny(deprecated)]` implied by `#[deny(warnings)]` diff --git a/transports/webrtc/examples/listen_ping.rs b/transports/webrtc/examples/listen_ping.rs index 219acf0d08b..47155bb88df 100644 --- a/transports/webrtc/examples/listen_ping.rs +++ b/transports/webrtc/examples/listen_ping.rs @@ -38,7 +38,7 @@ fn create_swarm() -> Result> { #[derive(NetworkBehaviour, Default)] #[behaviour( - out_event = "Event", + to_swarm = "Event", event_process = false, prelude = "libp2p_swarm::derive_prelude" )] From 38c08049e2fc94420b97cbe724d835f5c6ca1f42 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sun, 14 May 2023 13:23:49 +0200 Subject: [PATCH 08/38] feat(swarm): remove deprecated `NetworkBehaviourAction` type Pull-Request: #3919. --- swarm/CHANGELOG.md | 6 +++++- swarm/src/behaviour.rs | 3 --- swarm/src/lib.rs | 4 ---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 6c4bb389482..159c61af9b6 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -47,17 +47,21 @@ - Rename `NetworkBehaviour::OutEvent` to `NetworkBehaviour::ToSwarm`, `ConnectionHandler::InEvent` to `ConnectionHandler::FromBehaviour`, `ConnectionHandler::OutEvent` to `ConnectionHandler::ToBehaviour`. See [PR 3848]. +- Remove deprecated `NetworkBehaviourAction` type. + See [PR 3919]. + [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 [PR 3651]: https://github.com/libp2p/rust-libp2p/pull/3651 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 [PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746 +[PR 3848]: https://github.com/libp2p/rust-libp2p/pull/3848 [PR 3865]: https://github.com/libp2p/rust-libp2p/pull/3865 [PR 3882]: https://github.com/libp2p/rust-libp2p/pull/3882 [PR 3884]: https://github.com/libp2p/rust-libp2p/pull/3884 [PR 3885]: https://github.com/libp2p/rust-libp2p/pull/3885 [PR 3886]: https://github.com/libp2p/rust-libp2p/pull/3886 [PR 3912]: https://github.com/libp2p/rust-libp2p/pull/3912 -[PR 3848]: https://github.com/libp2p/rust-libp2p/pull/3848 +[PR 3919]: https://github.com/libp2p/rust-libp2p/pull/3919 ## 0.42.2 diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index e35f412f0ce..c5e5b7f25c3 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -257,9 +257,6 @@ pub trait PollParameters { fn local_peer_id(&self) -> &PeerId; } -#[deprecated(note = "Use `ToSwarm` instead.")] -pub type NetworkBehaviourAction = ToSwarm; - /// A command issued from a [`NetworkBehaviour`] for the [`Swarm`]. /// /// [`Swarm`]: super::Swarm diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 16dd9511d35..f0f5f07cb97 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -92,8 +92,6 @@ pub mod derive_prelude { pub use crate::ConnectionHandlerSelect; pub use crate::DialError; pub use crate::NetworkBehaviour; - #[allow(deprecated)] - pub use crate::NetworkBehaviourAction; pub use crate::PollParameters; pub use crate::THandler; pub use crate::THandlerInEvent; @@ -108,8 +106,6 @@ pub mod derive_prelude { pub use libp2p_identity::PeerId; } -#[allow(deprecated)] -pub use behaviour::NetworkBehaviourAction; pub use behaviour::{ AddressChange, CloseConnection, ConnectionClosed, DialFailure, ExpiredExternalAddr, ExpiredListenAddr, ExternalAddresses, FromSwarm, ListenAddresses, ListenFailure, From a00daca5fa39e68437c91335f46dcd4c685dee18 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sun, 14 May 2023 15:12:06 +0200 Subject: [PATCH 09/38] refactor(swarm-derive): improve warning message Pull-Request: #3921. --- Cargo.lock | 28 +++++++++---------- swarm-derive/Cargo.toml | 2 +- swarm-derive/src/lib.rs | 20 ++++++------- .../ui/fail/out_event_deprecation.stderr | 10 +++---- 4 files changed, 27 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9422ccd9af4..c3d47a09b4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -455,7 +455,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -827,7 +827,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -1703,7 +1703,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -3023,7 +3023,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -3996,13 +3996,13 @@ dependencies = [ [[package]] name = "proc-macro-warning" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e99670bafb56b9a106419397343bdbc8b8742c3cc449fec6345f86173f47cd4" +checksum = "70550716265d1ec349c41f70dd4f964b4fd88394efe4405f0c1da679c4799a07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4113,9 +4113,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -4655,7 +4655,7 @@ checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -4931,9 +4931,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.15" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", @@ -5018,7 +5018,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] @@ -5100,7 +5100,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn 2.0.16", ] [[package]] diff --git a/swarm-derive/Cargo.toml b/swarm-derive/Cargo.toml index 76b56cdbd45..cc4e3ebb7c8 100644 --- a/swarm-derive/Cargo.toml +++ b/swarm-derive/Cargo.toml @@ -17,7 +17,7 @@ proc-macro = true heck = "0.4" quote = "1.0" syn = { version = "2.0.15", default-features = false, features = ["clone-impls", "derive", "parsing", "printing", "proc-macro"] } -proc-macro-warning = "0.3.1" +proc-macro-warning = "0.4.0" proc-macro2 = "1.0" # Passing arguments to the docsrs builder in order to properly document cfg's. diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index d08c42f4f02..77f25aadbfe 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -25,6 +25,7 @@ use heck::ToUpperCamelCase; use proc_macro::TokenStream; use quote::quote; use syn::punctuated::Punctuated; +use syn::spanned::Spanned; use syn::{ parse_macro_input, Data, DataStruct, DeriveInput, Expr, ExprLit, Lit, Meta, MetaNameValue, Token, @@ -864,7 +865,6 @@ fn parse_attributes(ast: &DeriveInput) -> Result Result unimplemented!(), @@ -935,15 +941,5 @@ fn parse_attributes(ast: &DeriveInput) -> Result tests/ui/fail/out_event_deprecation.rs:7:8 +error: use of deprecated constant `out_event_renamed_to_to_swarm::_w`: The `out_event` attribute has been renamed to `to_swarm`. + --> tests/ui/fail/out_event_deprecation.rs:6:13 | -7 | struct Foo { - | ^^^ +6 | #[behaviour(out_event = "FooEvent", prelude = "libp2p_swarm::derive_prelude")] + | ^^^^^^^^^ | note: the lint level is defined here --> tests/ui/fail/out_event_deprecation.rs:1:9 From fd829efd0eb32be40699c83143eeb88ea1678561 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 03:47:21 +0200 Subject: [PATCH 10/38] fix(identify): always assert both identify responses Previously, we used to race the two identify responses and assert the one that finished earlier. In practice, this didn't work but sometimes caused a timeout. See https://github.com/libp2p/rust-libp2p/actions/runs/4973490081/jobs/8899378998#step:7:98 for an example. Interestingly enough, refactoring this test to always assert both responses reveals a bug! The memory transport by default behaves like TCP and allocates a new ephemeral port for an outgoing connection. I believe this was never hit because the first swarm would always receive its response first and win the race. To assert this properly, we would have to implement port reuse for the memory transport which I think is unnecessary, hence I just commented out the assertion. Pull-Request: #3924. --- protocols/identify/tests/smoke.rs | 90 +++++++++++++++++-------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/protocols/identify/tests/smoke.rs b/protocols/identify/tests/smoke.rs index 9abe6a73b8a..5aff98f9595 100644 --- a/protocols/identify/tests/smoke.rs +++ b/protocols/identify/tests/smoke.rs @@ -1,4 +1,3 @@ -use futures::prelude::*; use libp2p_core::multiaddr::Protocol; use libp2p_identify as identify; use libp2p_swarm::{keep_alive, Swarm, SwarmEvent}; @@ -7,8 +6,10 @@ use std::iter; #[async_std::test] async fn periodic_identify() { + let _ = env_logger::try_init(); + let mut swarm1 = Swarm::new_ephemeral(|identity| { - identify::Behaviour::new( + Behaviour::new( identify::Config::new("a".to_string(), identity.public()) .with_agent_version("b".to_string()), ) @@ -16,7 +17,7 @@ async fn periodic_identify() { let swarm1_peer_id = *swarm1.local_peer_id(); let mut swarm2 = Swarm::new_ephemeral(|identity| { - identify::Behaviour::new( + Behaviour::new( identify::Config::new("c".to_string(), identity.public()) .with_agent_version("d".to_string()), ) @@ -27,44 +28,53 @@ async fn periodic_identify() { let (swarm2_memory_listen, swarm2_tcp_listen_addr) = swarm2.listen().await; swarm2.connect(&mut swarm1).await; - // nb. Either swarm may receive the `Identified` event first, upon which - // it will permit the connection to be closed, as defined by - // `Handler::connection_keep_alive`. Hence the test succeeds if - // either `Identified` event arrives correctly. - loop { - match future::select(swarm1.next_behaviour_event(), swarm2.next_behaviour_event()) - .await - .factor_second() - .0 - { - future::Either::Left(identify::Event::Received { info, .. }) => { - assert_eq!(info.public_key.to_peer_id(), swarm2_peer_id); - assert_eq!(info.protocol_version, "c"); - assert_eq!(info.agent_version, "d"); - assert!(!info.protocols.is_empty()); - assert_eq!( - info.observed_addr, - swarm1_memory_listen.with(Protocol::P2p(swarm1_peer_id.into())) - ); - assert!(info.listen_addrs.contains(&swarm2_tcp_listen_addr)); - assert!(info.listen_addrs.contains(&swarm2_memory_listen)); - return; - } - future::Either::Right(identify::Event::Received { info, .. }) => { - assert_eq!(info.public_key.to_peer_id(), swarm1_peer_id); - assert_eq!(info.protocol_version, "a"); - assert_eq!(info.agent_version, "b"); - assert!(!info.protocols.is_empty()); - assert_eq!( - info.observed_addr, - swarm2_memory_listen.with(Protocol::P2p(swarm2_peer_id.into())) - ); - assert!(info.listen_addrs.contains(&swarm1_tcp_listen_addr)); - assert!(info.listen_addrs.contains(&swarm1_memory_listen)); - return; - } - _ => {} + use identify::Event::Received; + use identify::Event::Sent; + + match libp2p_swarm_test::drive(&mut swarm1, &mut swarm2).await { + ( + [BehaviourEvent::Identify(Received { info: s1_info, .. }), BehaviourEvent::Identify(Sent { .. })], + [BehaviourEvent::Identify(Received { info: s2_info, .. }), BehaviourEvent::Identify(Sent { .. })], + ) + | ( + [BehaviourEvent::Identify(Sent { .. }), BehaviourEvent::Identify(Received { info: s1_info, .. })], + [BehaviourEvent::Identify(Sent { .. }), BehaviourEvent::Identify(Received { info: s2_info, .. })], + ) + | ( + [BehaviourEvent::Identify(Received { info: s1_info, .. }), BehaviourEvent::Identify(Sent { .. })], + [BehaviourEvent::Identify(Sent { .. }), BehaviourEvent::Identify(Received { info: s2_info, .. })], + ) + | ( + [BehaviourEvent::Identify(Sent { .. }), BehaviourEvent::Identify(Received { info: s1_info, .. })], + [BehaviourEvent::Identify(Received { info: s2_info, .. }), BehaviourEvent::Identify(Sent { .. })], + ) => { + assert_eq!(s1_info.public_key.to_peer_id(), swarm2_peer_id); + assert_eq!(s1_info.protocol_version, "c"); + assert_eq!(s1_info.agent_version, "d"); + assert!(!s1_info.protocols.is_empty()); + assert_eq!( + s1_info.observed_addr, + swarm1_memory_listen + .clone() + .with(Protocol::P2p(swarm1_peer_id.into())) + ); + assert!(s1_info.listen_addrs.contains(&swarm2_tcp_listen_addr)); + assert!(s1_info.listen_addrs.contains(&swarm2_memory_listen)); + + assert_eq!(s2_info.public_key.to_peer_id(), swarm1_peer_id); + assert_eq!(s2_info.protocol_version, "a"); + assert_eq!(s2_info.agent_version, "b"); + assert!(!s2_info.protocols.is_empty()); + + // Cannot assert observed address of dialer because memory transport uses ephemeral, outgoing ports. + // assert_eq!( + // s2_info.observed_addr, + // swarm2_memory_listen.with(Protocol::P2p(swarm2_peer_id.into())) + // ); + assert!(s2_info.listen_addrs.contains(&swarm1_tcp_listen_addr)); + assert!(s2_info.listen_addrs.contains(&swarm1_memory_listen)); } + other => panic!("Unexpected events: {other:?}"), } } From 8c00dc9680a4076577ad561be83996e6b2c38395 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 04:05:42 +0200 Subject: [PATCH 11/38] fix(identify): always assert both identify responses Previously, we used to race the two identify responses and assert the one that finished earlier. In practice, this didn't work but sometimes caused a timeout. See https://github.com/libp2p/rust-libp2p/actions/runs/4973490081/jobs/8899378998#step:7:98 for an example. Interestingly enough, refactoring this test to always assert both responses reveals a bug! The memory transport by default behaves like TCP and allocates a new ephemeral port for an outgoing connection. I believe this was never hit because the first swarm would always receive its response first and win the race. To assert this properly, we would have to implement port reuse for the memory transport which I think is unnecessary, hence I just commented out the assertion. Pull-Request: #3924. From 1742bffcea4691f013e966393ae0d7fe95f8834c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 04:40:55 +0200 Subject: [PATCH 12/38] feat(request-response): don't close connection on stream errors Related: #3591. Pull-Request: #3913. --- Cargo.lock | 3 +++ examples/file-sharing/Cargo.toml | 3 ++- examples/file-sharing/src/network.rs | 4 ++-- protocols/request-response/CHANGELOG.md | 5 +++++ protocols/request-response/Cargo.toml | 2 ++ protocols/request-response/src/handler.rs | 26 ++++++++--------------- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3d47a09b4f..73a76d54dfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1603,6 +1603,7 @@ dependencies = [ "futures", "libp2p", "multiaddr", + "void", ] [[package]] @@ -2978,8 +2979,10 @@ dependencies = [ "libp2p-swarm-test", "libp2p-tcp", "libp2p-yamux", + "log", "rand 0.8.5", "smallvec", + "void", ] [[package]] diff --git a/examples/file-sharing/Cargo.toml b/examples/file-sharing/Cargo.toml index 9f2ab176db9..ad6a410c2cc 100644 --- a/examples/file-sharing/Cargo.toml +++ b/examples/file-sharing/Cargo.toml @@ -13,4 +13,5 @@ either = "1.8" env_logger = "0.10" futures = "0.3.28" libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "noise", "macros", "request-response", "tcp", "websocket", "yamux"] } -multiaddr = { version = "0.17.1" } \ No newline at end of file +multiaddr = { version = "0.17.1" } +void = "1.0.2" diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index c88db696dff..4048dcb2184 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -16,7 +16,7 @@ use libp2p::{ multiaddr::Protocol, noise, request_response::{self, ProtocolSupport, RequestId, ResponseChannel}, - swarm::{NetworkBehaviour, StreamUpgradeError, Swarm, SwarmBuilder, SwarmEvent}, + swarm::{NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent}, tcp, yamux, PeerId, Transport, }; @@ -216,7 +216,7 @@ impl EventLoop { async fn handle_event( &mut self, - event: SwarmEvent, io::Error>>, + event: SwarmEvent>, ) { match event { SwarmEvent::Behaviour(ComposedEvent::Kademlia( diff --git a/protocols/request-response/CHANGELOG.md b/protocols/request-response/CHANGELOG.md index b2adb03c67b..442906f4621 100644 --- a/protocols/request-response/CHANGELOG.md +++ b/protocols/request-response/CHANGELOG.md @@ -8,9 +8,14 @@ These variants are no longer constructed. See [PR 3605]. +- Don't close connections if individual streams fail. + Log the error instead. + See [PR 3913]. + [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 [PR 3702]: https://github.com/libp2p/rust-libp2p/pull/3702 +[PR 3913]: https://github.com/libp2p/rust-libp2p/pull/3913 ## 0.24.1 diff --git a/protocols/request-response/Cargo.toml b/protocols/request-response/Cargo.toml index 3bde34e2cc1..55108a2411f 100644 --- a/protocols/request-response/Cargo.toml +++ b/protocols/request-response/Cargo.toml @@ -19,6 +19,8 @@ libp2p-swarm = { workspace = true } libp2p-identity = { workspace = true } rand = "0.8" smallvec = "1.6.1" +void = "1.0.2" +log = "0.4.17" [dev-dependencies] async-std = { version = "1.6.2", features = ["attributes"] } diff --git a/protocols/request-response/src/handler.rs b/protocols/request-response/src/handler.rs index 02e9c8710dd..54b1b925847 100644 --- a/protocols/request-response/src/handler.rs +++ b/protocols/request-response/src/handler.rs @@ -39,7 +39,7 @@ use libp2p_swarm::{ use smallvec::SmallVec; use std::{ collections::VecDeque, - fmt, io, + fmt, sync::{ atomic::{AtomicU64, Ordering}, Arc, @@ -65,8 +65,6 @@ where substream_timeout: Duration, /// The current connection keep-alive. keep_alive: KeepAlive, - /// A pending fatal error that results in the connection being closed. - pending_error: Option>, /// Queue of events to emit in `poll()`. pending_events: VecDeque>, /// Outbound upgrades waiting to be emitted as an `OutboundSubstreamRequest`. @@ -107,7 +105,6 @@ where outbound: VecDeque::new(), inbound: FuturesUnordered::new(), pending_events: VecDeque::new(), - pending_error: None, inbound_request_id, } } @@ -151,21 +148,22 @@ where self.pending_events .push_back(Event::OutboundUnsupportedProtocols(info)); } - _ => { - // Anything else is considered a fatal error or misbehaviour of - // the remote peer and results in closing the connection. - self.pending_error = Some(error); + StreamUpgradeError::Apply(e) => { + log::debug!("outbound stream {info} failed: {e}"); + } + StreamUpgradeError::Io(e) => { + log::debug!("outbound stream {info} failed: {e}"); } } } fn on_listen_upgrade_error( &mut self, - ListenUpgradeError { error, .. }: ListenUpgradeError< + ListenUpgradeError { error, info }: ListenUpgradeError< ::InboundOpenInfo, ::InboundProtocol, >, ) { - self.pending_error = Some(StreamUpgradeError::Apply(error)); + log::debug!("inbound stream {info} failed: {error}"); } } @@ -241,7 +239,7 @@ where { type FromBehaviour = RequestProtocol; type ToBehaviour = Event; - type Error = StreamUpgradeError; + type Error = void::Void; type InboundProtocol = ResponseProtocol; type OutboundProtocol = RequestProtocol; type OutboundOpenInfo = RequestId; @@ -296,12 +294,6 @@ where ) -> Poll< ConnectionHandlerEvent, RequestId, Self::ToBehaviour, Self::Error>, > { - // Check for a pending (fatal) error. - if let Some(err) = self.pending_error.take() { - // The handler will not be polled again by the `Swarm`. - return Poll::Ready(ConnectionHandlerEvent::Close(err)); - } - // Drain pending events. if let Some(event) = self.pending_events.pop_front() { return Poll::Ready(ConnectionHandlerEvent::Custom(event)); From 2d83725c096ce7d895100bc5897359bb9660bea7 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Mon, 15 May 2023 04:58:06 +0200 Subject: [PATCH 13/38] feat(metrics)!: expose identify metrics for connected peers only Previously we would increase a counter / gauge / histogram on each received identify information. These metrics are missleading, as e.g. they depend on the identify interval and don't represent the set of currently connected peers. With this commit, identify information is tracked for the currently connected peers only. Instead of an increase on each received identify information, metrics represent the status quo (Gauge). Example: ``` \# HELP libp2p_libp2p_identify_remote_protocols Number of connected nodes supporting a specific protocol, with "unrecognized" for each peer supporting one or more unrecognized protocols... \# TYPE libp2p_libp2p_identify_remote_protocols gauge libp2p_libp2p_identify_remote_protocols_total{protocol="/ipfs/id/push/1.0.0"} 1 libp2p_libp2p_identify_remote_protocols_total{protocol="/ipfs/id/1.0.0"} 1 libp2p_libp2p_identify_remote_protocols_total{protocol="/ipfs/ping/1.0.0"} 1 libp2p_libp2p_identify_remote_protocols_total{protocol="unrecognized"} 1 \# HELP libp2p_libp2p_identify_remote_listen_addresses Number of connected nodes advertising a specific listen address... \# TYPE libp2p_libp2p_identify_remote_listen_addresses gauge libp2p_libp2p_identify_remote_listen_addresses_total{listen_address="/ip4/tcp"} 1 libp2p_libp2p_identify_remote_listen_addresses_total{listen_address="/ip4/udp/quic"} 1 \# HELP libp2p_libp2p_identify_local_observed_addresses Number of connected nodes observing the local node at a specific address... \# TYPE libp2p_libp2p_identify_local_observed_addresses gauge libp2p_libp2p_identify_local_observed_addresses_total{observed_address="/ip4/tcp"} 1 ``` Pull-Request: #3325. --- Cargo.lock | 5 +- examples/metrics/Cargo.toml | 2 +- examples/metrics/src/http_service.rs | 2 +- misc/metrics/CHANGELOG.md | 20 ++ misc/metrics/Cargo.toml | 3 +- misc/metrics/src/identify.rs | 291 ++++++++++++++------------- protocols/gossipsub/Cargo.toml | 2 +- 7 files changed, 180 insertions(+), 145 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73a76d54dfe..b0380178273 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2732,6 +2732,7 @@ dependencies = [ "libp2p-ping", "libp2p-relay", "libp2p-swarm", + "once_cell", "prometheus-client", ] @@ -4019,9 +4020,9 @@ dependencies = [ [[package]] name = "prometheus-client" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e227aeb6c2cfec819e999c4773b35f8c7fa37298a203ff46420095458eee567e" +checksum = "38974b1966bd5b6c7c823a20c1e07d5b84b171db20bac601e9b529720f7299f8" dependencies = [ "dtoa", "itoa", diff --git a/examples/metrics/Cargo.toml b/examples/metrics/Cargo.toml index ba08cdaebe7..d170cc2f28d 100644 --- a/examples/metrics/Cargo.toml +++ b/examples/metrics/Cargo.toml @@ -12,4 +12,4 @@ hyper = { version = "0.14", features = ["server", "tcp", "http1"] } libp2p = { path = "../../libp2p", features = ["async-std", "metrics", "ping", "noise", "identify", "tcp", "yamux", "macros"] } log = "0.4.0" tokio = { version = "1", features = ["rt-multi-thread"] } -prometheus-client = "0.20.0" +prometheus-client = "0.21.0" diff --git a/examples/metrics/src/http_service.rs b/examples/metrics/src/http_service.rs index 84102c2b558..46cb7aacb84 100644 --- a/examples/metrics/src/http_service.rs +++ b/examples/metrics/src/http_service.rs @@ -33,7 +33,7 @@ const METRICS_CONTENT_TYPE: &str = "application/openmetrics-text;charset=utf-8;v pub(crate) async fn metrics_server(registry: Registry) -> Result<(), std::io::Error> { // Serve on localhost. - let addr = ([127, 0, 0, 1], 0).into(); + let addr = ([127, 0, 0, 1], 8080).into(); // Use the tokio runtime to run the hyper server. let rt = tokio::runtime::Runtime::new()?; diff --git a/misc/metrics/CHANGELOG.md b/misc/metrics/CHANGELOG.md index 4c653ca0051..ca090d60171 100644 --- a/misc/metrics/CHANGELOG.md +++ b/misc/metrics/CHANGELOG.md @@ -1,9 +1,29 @@ ## 0.13.0 - unreleased +- Previously `libp2p-metrics::identify` would increase a counter / gauge / histogram on each + received identify information. These metrics are misleading, as e.g. they depend on the identify + interval and don't represent the set of currently connected peers. With this change, identify + information is tracked for the currently connected peers only. Instead of an increase on each + received identify information, metrics represent the status quo (Gauge). + + Metrics removed: + - `libp2p_identify_protocols` + - `libp2p_identify_received_info_listen_addrs` + - `libp2p_identify_received_info_protocols` + - `libp2p_identify_listen_addresses` + + Metrics added: + - `libp2p_identify_remote_protocols` + - `libp2p_identify_remote_listen_addresses` + - `libp2p_identify_local_observed_addresses` + + See [PR 3325]. + - Raise MSRV to 1.65. See [PR 3715]. [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3325]: https://github.com/libp2p/rust-libp2p/pull/3325 ## 0.12.0 diff --git a/misc/metrics/Cargo.toml b/misc/metrics/Cargo.toml index 9fafe680115..78cb5b3fa2c 100644 --- a/misc/metrics/Cargo.toml +++ b/misc/metrics/Cargo.toml @@ -27,7 +27,8 @@ libp2p-ping = { workspace = true, optional = true } libp2p-relay = { workspace = true, optional = true } libp2p-swarm = { workspace = true } libp2p-identity = { workspace = true } -prometheus-client = "0.20.0" +prometheus-client = { version = "0.21.0" } +once_cell = "1.16.0" [target.'cfg(not(target_os = "unknown"))'.dependencies] libp2p-gossipsub = { workspace = true, optional = true } diff --git a/misc/metrics/src/identify.rs b/misc/metrics/src/identify.rs index ffd0cdb9fc2..e3e147062b3 100644 --- a/misc/metrics/src/identify.rs +++ b/misc/metrics/src/identify.rs @@ -21,39 +21,78 @@ use crate::protocol_stack; use libp2p_identity::PeerId; use libp2p_swarm::StreamProtocol; -use prometheus_client::encoding::{EncodeLabelSet, EncodeMetric, MetricEncoder}; +use once_cell::sync::Lazy; +use prometheus_client::collector::Collector; +use prometheus_client::encoding::EncodeLabelSet; use prometheus_client::metrics::counter::Counter; -use prometheus_client::metrics::family::Family; -use prometheus_client::metrics::histogram::{exponential_buckets, Histogram}; -use prometheus_client::metrics::MetricType; -use prometheus_client::registry::Registry; +use prometheus_client::metrics::family::ConstFamily; +use prometheus_client::metrics::gauge::ConstGauge; +use prometheus_client::registry::{Descriptor, LocalMetric, Registry}; +use prometheus_client::MaybeOwned; +use std::borrow::Cow; use std::collections::HashMap; -use std::iter; use std::sync::{Arc, Mutex}; +static PROTOCOLS_DESCRIPTOR: Lazy = Lazy::new(|| { + Descriptor::new( + "remote_protocols", + r#"Number of connected nodes supporting a specific protocol, with "unrecognized" for each + peer supporting one or more unrecognized protocols"#, + None, + None, + vec![], + ) +}); +static LISTEN_ADDRESSES_DESCRIPTOR: Lazy = Lazy::new(|| { + Descriptor::new( + "remote_listen_addresses", + "Number of connected nodes advertising a specific listen address", + None, + None, + vec![], + ) +}); +static OBSERVED_ADDRESSES_DESCRIPTOR: Lazy = Lazy::new(|| { + Descriptor::new( + "local_observed_addresses", + "Number of connected nodes observing the local node at a specific address", + None, + None, + vec![], + ) +}); +const ALLOWED_PROTOCOLS: &[StreamProtocol] = &[ + #[cfg(feature = "dcutr")] + libp2p_dcutr::PROTOCOL_NAME, + // #[cfg(feature = "gossipsub")] + // #[cfg(not(target_os = "unknown"))] + // TODO: Add Gossipsub protocol name + libp2p_identify::PROTOCOL_NAME, + libp2p_identify::PUSH_PROTOCOL_NAME, + #[cfg(feature = "kad")] + libp2p_kad::PROTOCOL_NAME, + #[cfg(feature = "ping")] + libp2p_ping::PROTOCOL_NAME, + #[cfg(feature = "relay")] + libp2p_relay::STOP_PROTOCOL_NAME, + #[cfg(feature = "relay")] + libp2p_relay::HOP_PROTOCOL_NAME, +]; + pub(crate) struct Metrics { - protocols: Protocols, + peers: Peers, error: Counter, pushed: Counter, received: Counter, - received_info_listen_addrs: Histogram, - received_info_protocols: Histogram, sent: Counter, - listen_addresses: Family, } impl Metrics { pub(crate) fn new(registry: &mut Registry) -> Self { let sub_registry = registry.sub_registry_with_prefix("identify"); - let protocols = Protocols::default(); - sub_registry.register( - "protocols", - "Number of connected nodes supporting a specific protocol, with \ - \"unrecognized\" for each peer supporting one or more unrecognized \ - protocols", - protocols.clone(), - ); + let peers = Peers::default(); + sub_registry.register_collector(Box::new(peers.clone())); let error = Counter::default(); sub_registry.register( @@ -78,24 +117,6 @@ impl Metrics { received.clone(), ); - let received_info_listen_addrs = - Histogram::new(iter::once(0.0).chain(exponential_buckets(1.0, 2.0, 9))); - sub_registry.register( - "received_info_listen_addrs", - "Number of listen addresses for remote peer received in \ - identification information", - received_info_listen_addrs.clone(), - ); - - let received_info_protocols = - Histogram::new(iter::once(0.0).chain(exponential_buckets(1.0, 2.0, 9))); - sub_registry.register( - "received_info_protocols", - "Number of protocols supported by the remote peer received in \ - identification information", - received_info_protocols.clone(), - ); - let sent = Counter::default(); sub_registry.register( "sent", @@ -104,22 +125,12 @@ impl Metrics { sent.clone(), ); - let listen_addresses = Family::default(); - sub_registry.register( - "listen_addresses", - "Number of listen addresses for remote peer per protocol stack", - listen_addresses.clone(), - ); - Self { - protocols, + peers, error, pushed, received, - received_info_listen_addrs, - received_info_protocols, sent, - listen_addresses, } } } @@ -134,58 +145,8 @@ impl super::Recorder for Metrics { self.pushed.inc(); } libp2p_identify::Event::Received { peer_id, info, .. } => { - { - let mut protocols = info - .protocols - .iter() - .filter(|p| { - let allowed_protocols: &[StreamProtocol] = &[ - #[cfg(feature = "dcutr")] - libp2p_dcutr::PROTOCOL_NAME, - // #[cfg(feature = "gossipsub")] - // #[cfg(not(target_os = "unknown"))] - // TODO: Add Gossipsub protocol name - libp2p_identify::PROTOCOL_NAME, - libp2p_identify::PUSH_PROTOCOL_NAME, - #[cfg(feature = "kad")] - libp2p_kad::PROTOCOL_NAME, - #[cfg(feature = "ping")] - libp2p_ping::PROTOCOL_NAME, - #[cfg(feature = "relay")] - libp2p_relay::STOP_PROTOCOL_NAME, - #[cfg(feature = "relay")] - libp2p_relay::HOP_PROTOCOL_NAME, - ]; - - allowed_protocols.contains(p) - }) - .map(|p| p.to_string()) - .collect::>(); - - // Signal via an additional label value that one or more - // protocols of the remote peer have not been recognized. - if protocols.len() < info.protocols.len() { - protocols.push("unrecognized".to_string()); - } - - protocols.sort_unstable(); - protocols.dedup(); - - self.protocols.add(*peer_id, protocols); - } - self.received.inc(); - self.received_info_protocols - .observe(info.protocols.len() as f64); - self.received_info_listen_addrs - .observe(info.listen_addrs.len() as f64); - for listen_addr in &info.listen_addrs { - self.listen_addresses - .get_or_create(&AddressLabels { - protocols: protocol_stack::as_string(listen_addr), - }) - .inc(); - } + self.peers.record(*peer_id, info.clone()); } libp2p_identify::Event::Sent { .. } => { self.sent.inc(); @@ -203,7 +164,7 @@ impl super::Recorder>>>, -} +#[derive(Default, Debug, Clone)] +struct Peers(Arc>>); -impl Protocols { - fn add(&self, peer: PeerId, protocols: Vec) { - self.peers - .lock() - .expect("Lock not to be poisoned") - .insert(peer, protocols); +impl Peers { + fn record(&self, peer_id: PeerId, info: libp2p_identify::Info) { + self.0.lock().unwrap().insert(peer_id, info); } - fn remove(&self, peer: PeerId) { - self.peers - .lock() - .expect("Lock not to be poisoned") - .remove(&peer); + fn remove(&self, peer_id: PeerId) { + self.0.lock().unwrap().remove(&peer_id); } } -impl EncodeMetric for Protocols { - fn encode(&self, mut encoder: MetricEncoder) -> Result<(), std::fmt::Error> { - let count_by_protocol = self - .peers - .lock() - .expect("Lock not to be poisoned") - .iter() - .fold( - HashMap::::default(), - |mut acc, (_, protocols)| { - for protocol in protocols { - let count = acc.entry(protocol.to_string()).or_default(); - *count += 1; - } - acc - }, - ); +impl Collector for Peers { + fn collect<'a>( + &'a self, + ) -> Box, MaybeOwned<'a, Box>)> + 'a> + { + let mut count_by_protocols: HashMap = Default::default(); + let mut count_by_listen_addresses: HashMap = Default::default(); + let mut count_by_observed_addresses: HashMap = Default::default(); + + for (_, peer_info) in self.0.lock().unwrap().iter() { + { + let mut protocols: Vec<_> = peer_info + .protocols + .iter() + .map(|p| { + if ALLOWED_PROTOCOLS.contains(&p) { + p.to_string() + } else { + "unrecognized".to_string() + } + }) + .collect(); + protocols.sort(); + protocols.dedup(); + + for protocol in protocols.into_iter() { + let count = count_by_protocols.entry(protocol).or_default(); + *count += 1; + } + } + + { + let mut addrs: Vec<_> = peer_info + .listen_addrs + .iter() + .map(protocol_stack::as_string) + .collect(); + addrs.sort(); + addrs.dedup(); + + for addr in addrs { + let count = count_by_listen_addresses.entry(addr).or_default(); + *count += 1; + } + } - for (protocol, count) in count_by_protocol { - encoder - .encode_family(&[("protocol", protocol)])? - .encode_gauge(&count)?; + { + let count = count_by_observed_addresses + .entry(protocol_stack::as_string(&peer_info.observed_addr)) + .or_default(); + *count += 1; + } } - Ok(()) - } + let count_by_protocols: Box = + Box::new(ConstFamily::new(count_by_protocols.into_iter().map( + |(protocol, count)| ([("protocol", protocol)], ConstGauge::new(count)), + ))); + + let count_by_listen_addresses: Box = + Box::new(ConstFamily::new(count_by_listen_addresses.into_iter().map( + |(protocol, count)| ([("listen_address", protocol)], ConstGauge::new(count)), + ))); + + let count_by_observed_addresses: Box = Box::new(ConstFamily::new( + count_by_observed_addresses + .into_iter() + .map(|(protocol, count)| { + ([("observed_address", protocol)], ConstGauge::new(count)) + }), + )); - fn metric_type(&self) -> MetricType { - MetricType::Gauge + Box::new( + [ + ( + Cow::Borrowed(&*PROTOCOLS_DESCRIPTOR), + MaybeOwned::Owned(count_by_protocols), + ), + ( + Cow::Borrowed(&*LISTEN_ADDRESSES_DESCRIPTOR), + MaybeOwned::Owned(count_by_listen_addresses), + ), + ( + Cow::Borrowed(&*OBSERVED_ADDRESSES_DESCRIPTOR), + MaybeOwned::Owned(count_by_observed_addresses), + ), + ] + .into_iter(), + ) } } diff --git a/protocols/gossipsub/Cargo.toml b/protocols/gossipsub/Cargo.toml index 9cc46dc3664..813428bc008 100644 --- a/protocols/gossipsub/Cargo.toml +++ b/protocols/gossipsub/Cargo.toml @@ -35,7 +35,7 @@ wasm-timer = "0.2.5" instant = "0.1.11" void = "1.0.2" # Metrics dependencies -prometheus-client = "0.20.0" +prometheus-client = "0.21.0" [dev-dependencies] async-std = { version = "1.6.3", features = ["unstable"] } From 856af16512fa08922a1cb337bf6428da478906ad Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 13:20:52 +0200 Subject: [PATCH 14/38] fix(metrics): don't grab unnecessary reference This clippy warning started to pop up on my machine. Not sure how it slipped through CI! Pull-Request: #3939. --- misc/metrics/src/identify.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/metrics/src/identify.rs b/misc/metrics/src/identify.rs index e3e147062b3..51ed7c380d2 100644 --- a/misc/metrics/src/identify.rs +++ b/misc/metrics/src/identify.rs @@ -203,7 +203,7 @@ impl Collector for Peers { .protocols .iter() .map(|p| { - if ALLOWED_PROTOCOLS.contains(&p) { + if ALLOWED_PROTOCOLS.contains(p) { p.to_string() } else { "unrecognized".to_string() From 3cc6c7e080c6ce3a982ddcf598b449222baeba3c Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 15 May 2023 13:39:54 +0200 Subject: [PATCH 15/38] feat(identity): remove deprecated items Related: https://github.com/libp2p/rust-libp2p/issues/3647. Pull-Request: #3928. --- identity/CHANGELOG.md | 3 ++ identity/src/ecdsa.rs | 27 ------------- identity/src/ed25519.rs | 51 ------------------------- identity/src/keypair.rs | 80 --------------------------------------- identity/src/rsa.rs | 19 ---------- identity/src/secp256k1.rs | 40 -------------------- 6 files changed, 3 insertions(+), 217 deletions(-) diff --git a/identity/CHANGELOG.md b/identity/CHANGELOG.md index cbfb817ca6c..d808b466ceb 100644 --- a/identity/CHANGELOG.md +++ b/identity/CHANGELOG.md @@ -11,10 +11,13 @@ - Remove `identity::secp256k1::SecretKey::sign_hash` and make `identity::secp256k1::SecretKey::sign` infallible. See [PR 3850]. +- Remove deprecated items. See [PR 3928]. + [PR 3850]: https://github.com/libp2p/rust-libp2p/pull/3850 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 [PR 3863]: https://github.com/libp2p/rust-libp2p/pull/3863 [PR 3866]: https://github.com/libp2p/rust-libp2p/pull/3866 +[PR 3928]: https://github.com/libp2p/rust-libp2p/pull/3928 [protobuf format]: https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md#keys ## 0.1.2 diff --git a/identity/src/ecdsa.rs b/identity/src/ecdsa.rs index 90a8c3089c4..21970f2ffdc 100644 --- a/identity/src/ecdsa.rs +++ b/identity/src/ecdsa.rs @@ -109,15 +109,6 @@ impl SecretKey { self.0.to_bytes().to_vec() } - /// Decode a secret key from a byte buffer containing raw scalar of the key. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `SecretKey::try_from_bytes` instead" - )] - pub fn from_bytes(buf: &[u8]) -> Result { - Self::try_from_bytes(buf) - } - /// Try to parse a secret key from a byte buffer containing raw scalar of the key. pub fn try_from_bytes(buf: impl AsRef<[u8]>) -> Result { SigningKey::from_bytes(buf.as_ref().into()) @@ -166,15 +157,6 @@ impl PublicKey { self.0.verify(msg, &sig).is_ok() } - /// Decode a public key from a byte buffer containing raw components of a key with or without compression. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_from_bytes` instead." - )] - pub fn from_bytes(k: &[u8]) -> Result { - Self::try_from_bytes(k) - } - /// Try to parse a public key from a byte buffer containing raw components of a key with or without compression. pub fn try_from_bytes(k: &[u8]) -> Result { let enc_pt = EncodedPoint::from_bytes(k) @@ -196,15 +178,6 @@ impl PublicKey { Self::add_asn1_header(&buf) } - /// Decode a public key into a DER encoded byte buffer as defined by SEC1 standard. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_decode_der` instead." - )] - pub fn decode_der(k: &[u8]) -> Result { - Self::try_decode_der(k) - } - /// Try to decode a public key from a DER encoded byte buffer as defined by SEC1 standard. pub fn try_decode_der(k: &[u8]) -> Result { let buf = Self::del_asn1_header(k).ok_or_else(|| { diff --git a/identity/src/ed25519.rs b/identity/src/ed25519.rs index 90782de378a..bcd3eb44359 100644 --- a/identity/src/ed25519.rs +++ b/identity/src/ed25519.rs @@ -38,14 +38,6 @@ impl Keypair { Keypair::from(SecretKey::generate()) } - /// Encode the keypair into a byte array by concatenating the bytes - /// of the secret scalar and the compressed public point, - /// an informal standard for encoding Ed25519 keypairs. - #[deprecated(since = "0.2.0", note = "Renamed to `Keypair::to_bytes`")] - pub fn encode(&self) -> [u8; 64] { - self.to_bytes() - } - /// Convert the keypair into a byte array by concatenating the bytes /// of the secret scalar and the compressed public point, /// an informal standard for encoding Ed25519 keypairs. @@ -53,18 +45,6 @@ impl Keypair { self.0.to_bytes() } - /// Decode a keypair from the [binary format](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5) - /// produced by [`Keypair::to_bytes`], zeroing the input on success. - /// - /// Note that this binary format is the same as `ed25519_dalek`'s and `ed25519_zebra`'s. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `Keypair::try_from_bytes` instead." - )] - pub fn decode(kp: &mut [u8]) -> Result { - Self::try_from_bytes(kp) - } - /// Try to parse a keypair from the [binary format](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5) /// produced by [`Keypair::to_bytes`], zeroing the input on success. /// @@ -182,31 +162,12 @@ impl PublicKey { .is_ok() } - /// Encode the public key into a byte array in compressed form, i.e. - /// where one coordinate is represented by a single bit. - #[deprecated( - since = "0.2.0", - note = "Renamed to `PublicKey::to_bytes` to reflect actual behaviour." - )] - pub fn encode(&self) -> [u8; 32] { - self.to_bytes() - } - /// Convert the public key to a byte array in compressed form, i.e. /// where one coordinate is represented by a single bit. pub fn to_bytes(&self) -> [u8; 32] { self.0.to_bytes() } - /// Decode a public key from a byte array as produced by `to_bytes`. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_from_bytes` instead." - )] - pub fn decode(k: &[u8]) -> Result { - Self::try_from_bytes(k) - } - /// Try to parse a public key from a byte array containing the actual key as produced by `to_bytes`. pub fn try_from_bytes(k: &[u8]) -> Result { ed25519::PublicKey::from_bytes(k) @@ -251,18 +212,6 @@ impl SecretKey { ) } - /// Create an Ed25519 secret key from a byte slice, zeroing the input on success. - /// If the bytes do not constitute a valid Ed25519 secret key, an error is - /// returned. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `SecretKey::try_from_bytes` instead." - )] - #[allow(unused_mut)] - pub fn from_bytes(mut sk_bytes: impl AsMut<[u8]>) -> Result { - Self::try_from_bytes(sk_bytes) - } - /// Try to parse an Ed25519 secret key from a byte slice /// containing the actual key, zeroing the input on success. /// If the bytes do not constitute a valid Ed25519 secret key, an error is diff --git a/identity/src/keypair.rs b/identity/src/keypair.rs index 8249cbe96f9..b31949cf081 100644 --- a/identity/src/keypair.rs +++ b/identity/src/keypair.rs @@ -106,53 +106,21 @@ impl Keypair { } } - #[cfg(feature = "ed25519")] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `Keypair::try_into_ed25519` instead." - )] - pub fn into_ed25519(self) -> Option { - self.try_into().ok() - } - #[cfg(feature = "ed25519")] pub fn try_into_ed25519(self) -> Result { self.try_into() } - #[cfg(feature = "secp256k1")] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `Keypair::try_into_secp256k1` instead." - )] - pub fn into_secp256k1(self) -> Option { - self.try_into().ok() - } - #[cfg(feature = "secp256k1")] pub fn try_into_secp256k1(self) -> Result { self.try_into() } - #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `Keypair::try_into_rsa` instead." - )] - pub fn into_rsa(self) -> Option { - self.try_into().ok() - } - #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] pub fn try_into_rsa(self) -> Result { self.try_into() } - #[cfg(feature = "ecdsa")] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `Keypair::try_into_ecdsa` instead." - )] - pub fn into_ecdsa(self) -> Option { - self.try_into().ok() - } - #[cfg(feature = "ecdsa")] pub fn try_into_ecdsa(self) -> Result { self.try_into() @@ -480,65 +448,26 @@ impl PublicKey { } } - #[cfg(feature = "ed25519")] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_into_ed25519` instead." - )] - pub fn into_ed25519(self) -> Option { - self.try_into().ok() - } - #[cfg(feature = "ed25519")] pub fn try_into_ed25519(self) -> Result { self.try_into() } - #[cfg(feature = "secp256k1")] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_into_secp256k1` instead." - )] - pub fn into_secp256k1(self) -> Option { - self.try_into().ok() - } - #[cfg(feature = "secp256k1")] pub fn try_into_secp256k1(self) -> Result { self.try_into() } - #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_into_rsa` instead." - )] - pub fn into_rsa(self) -> Option { - self.try_into().ok() - } - #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] pub fn try_into_rsa(self) -> Result { self.try_into() } - #[cfg(feature = "ecdsa")] - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_into_ecdsa` instead." - )] - pub fn into_ecdsa(self) -> Option { - self.try_into().ok() - } - #[cfg(feature = "ecdsa")] pub fn try_into_ecdsa(self) -> Result { self.try_into() } - /// Encode the public key into a protobuf structure for storage or - /// exchange with other nodes. - #[deprecated(note = "Renamed to `PublicKey::encode_protobuf`.")] - pub fn to_protobuf_encoding(&self) -> Vec { - Self::encode_protobuf(self) - } - /// Encode the public key into a protobuf structure for storage or /// exchange with other nodes. pub fn encode_protobuf(&self) -> Vec { @@ -570,15 +499,6 @@ impl PublicKey { unreachable!() } - /// Decode a public key from a protobuf structure, e.g. read from storage - /// or received from another node. - #[deprecated( - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_decode_protobuf` instead." - )] - pub fn from_protobuf_encoding(bytes: &[u8]) -> Result { - Self::try_decode_protobuf(bytes) - } - /// Decode a public key from a protobuf structure, e.g. read from storage /// or received from another node. #[allow(unused_variables)] diff --git a/identity/src/rsa.rs b/identity/src/rsa.rs index e4e16af206c..05bd5c4c15f 100644 --- a/identity/src/rsa.rs +++ b/identity/src/rsa.rs @@ -42,15 +42,6 @@ impl std::fmt::Debug for Keypair { } impl Keypair { - /// Decode an RSA keypair from a DER-encoded private key in PKCS#8 PrivateKeyInfo - /// format (i.e. unencrypted) as defined in [RFC5208]. - /// - /// [RFC5208]: https://tools.ietf.org/html/rfc5208#section-5 - #[deprecated(since = "0.2.0", note = "Renamed to `Keypair::try_decode_pkcs8`.")] - pub fn from_pkcs8(der: &mut [u8]) -> Result { - Self::try_decode_pkcs8(der) - } - /// Decode an RSA keypair from a DER-encoded private key in PKCS#8 PrivateKeyInfo /// format (i.e. unencrypted) as defined in [RFC5208]. /// @@ -116,16 +107,6 @@ impl PublicKey { .expect("RSA X.509 public key encoding failed.") } - /// Decode an RSA public key from a DER-encoded X.509 SubjectPublicKeyInfo - /// structure. See also `encode_x509`. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_decode_x509` instead." - )] - pub fn decode_x509(pk: &[u8]) -> Result { - Self::try_decode_x509(pk) - } - /// Decode an RSA public key from a DER-encoded X.509 SubjectPublicKeyInfo /// structure. See also `encode_x509`. pub fn try_decode_x509(pk: &[u8]) -> Result { diff --git a/identity/src/secp256k1.rs b/identity/src/secp256k1.rs index 0fe48d38dfb..a32a64e7b37 100644 --- a/identity/src/secp256k1.rs +++ b/identity/src/secp256k1.rs @@ -92,20 +92,6 @@ impl SecretKey { SecretKey(libsecp256k1::SecretKey::random(&mut rand::thread_rng())) } - /// Create a secret key from a byte slice, zeroing the slice on success. - /// If the bytes do not constitute a valid Secp256k1 secret key, an - /// error is returned. - /// - /// Note that the expected binary format is the same as `libsecp256k1`'s. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `SecretKey::try_from_bytes` instead." - )] - #[allow(unused_mut)] - pub fn from_bytes(mut sk: impl AsMut<[u8]>) -> Result { - Self::try_from_bytes(sk) - } - /// Create a secret key from a byte slice, zeroing the slice on success. /// If the bytes do not constitute a valid Secp256k1 secret key, an /// error is returned. @@ -215,43 +201,17 @@ impl PublicKey { .unwrap_or(false) } - /// Encode the public key in compressed form, i.e. with one coordinate - /// represented by a single bit. - #[deprecated(since = "0.2.0", note = "Renamed to `PublicKey::to_bytes`.")] - pub fn encode(&self) -> [u8; 33] { - self.to_bytes() - } - /// Convert the public key to a byte buffer in compressed form, i.e. with one coordinate /// represented by a single bit. pub fn to_bytes(&self) -> [u8; 33] { self.0.serialize_compressed() } - /// Encode the public key in uncompressed form. - #[deprecated( - since = "0.2.0", - note = "Renamed to `PublicKey::to_bytes_uncompressed`." - )] - pub fn encode_uncompressed(&self) -> [u8; 65] { - self.to_bytes_uncompressed() - } - /// Convert the public key to a byte buffer in uncompressed form. pub fn to_bytes_uncompressed(&self) -> [u8; 65] { self.0.serialize() } - /// Decode a public key from a byte slice in the the format produced - /// by `encode`. - #[deprecated( - since = "0.2.0", - note = "This method name does not follow Rust naming conventions, use `PublicKey::try_from_bytes` instead." - )] - pub fn decode(k: &[u8]) -> Result { - Self::try_from_bytes(k) - } - /// Decode a public key from a byte slice in the the format produced /// by `encode`. pub fn try_from_bytes(k: &[u8]) -> Result { From 0bc724ab006153ecb51797a8fb3d3cb6941903cf Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 13:58:28 +0200 Subject: [PATCH 16/38] ci: reduce size of Rust interop-test image By using a multi-stage docker build, a distroless base image and a release build, we can get the size of the Rust interop test down to 50MB. Previously, the image would be around 500MB. A debug build image would still have ~400MB. The release build slows down our interop build step by about 1min 20s. That however is only because we don't currently seem to utilize the caches that from what I understand should work on self-hosted runners. I opted https://github.com/libp2p/rust-libp2p/issues/3925 for that. Resolves: #3881. Pull-Request: #3926. --- interop-tests/Dockerfile | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/interop-tests/Dockerfile b/interop-tests/Dockerfile index 129b981307c..e0a5ddfc31f 100644 --- a/interop-tests/Dockerfile +++ b/interop-tests/Dockerfile @@ -1,15 +1,24 @@ # syntax=docker/dockerfile:1.5-labs -FROM rust:1.67.0 +FROM rust:1.67.0 as builder + +# Install zlib as long as libp2p-websocket requires it: https://github.com/paritytech/soketto/issues/72 +RUN apt-get update && \ + apt-get download zlib1g && \ + mkdir /dpkg && \ + for deb in *.deb; do dpkg --extract $deb /dpkg || exit 10; done # Run with access to the target cache to speed up builds WORKDIR /workspace ADD . . RUN --mount=type=cache,target=./target \ --mount=type=cache,target=/usr/local/cargo/registry \ - cargo build --package interop-tests + cargo build --release --package interop-tests RUN --mount=type=cache,target=./target \ - mv ./target/debug/ping /usr/local/bin/testplan + mv ./target/release/ping /usr/local/bin/testplan +FROM gcr.io/distroless/cc +COPY --from=builder /usr/local/bin/testplan /usr/local/bin/testplan +COPY --from=builder /dpkg / ENV RUST_BACKTRACE=1 ENTRYPOINT ["testplan"] From adcc10b8412a9c80b1dafbb3d6514d4d8d05533f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 14:15:14 +0200 Subject: [PATCH 17/38] refactor(swarm-derive): better error reporting for invalid attributes This PR refactors the error reporting away from panicking to returning `syn::Result` and adds two unit tests for the parsing of attributes that users interact with. Pull-Request: #3922. --- swarm-derive/src/lib.rs | 88 ++++++------------- swarm-derive/src/syn_ext.rs | 16 ++++ swarm/tests/ui/fail/prelude_not_string.rs | 11 +++ swarm/tests/ui/fail/prelude_not_string.stderr | 5 ++ swarm/tests/ui/fail/to_swarm_not_string.rs | 19 ++++ .../tests/ui/fail/to_swarm_not_string.stderr | 5 ++ 6 files changed, 82 insertions(+), 62 deletions(-) create mode 100644 swarm-derive/src/syn_ext.rs create mode 100644 swarm/tests/ui/fail/prelude_not_string.rs create mode 100644 swarm/tests/ui/fail/prelude_not_string.stderr create mode 100644 swarm/tests/ui/fail/to_swarm_not_string.rs create mode 100644 swarm/tests/ui/fail/to_swarm_not_string.stderr diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 77f25aadbfe..8bcf90e8798 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -21,45 +21,48 @@ #![recursion_limit = "256"] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +mod syn_ext; + +use crate::syn_ext::RequireStrLit; use heck::ToUpperCamelCase; use proc_macro::TokenStream; use quote::quote; use syn::punctuated::Punctuated; use syn::spanned::Spanned; -use syn::{ - parse_macro_input, Data, DataStruct, DeriveInput, Expr, ExprLit, Lit, Meta, MetaNameValue, - Token, -}; +use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Meta, Token}; /// Generates a delegating `NetworkBehaviour` implementation for the struct this is used for. See /// the trait documentation for better description. #[proc_macro_derive(NetworkBehaviour, attributes(behaviour))] pub fn hello_macro_derive(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); - build(&ast) + build(&ast).unwrap_or_else(|e| e.to_compile_error().into()) } /// The actual implementation. -fn build(ast: &DeriveInput) -> TokenStream { +fn build(ast: &DeriveInput) -> syn::Result { match ast.data { Data::Struct(ref s) => build_struct(ast, s), - Data::Enum(_) => unimplemented!("Deriving NetworkBehaviour is not implemented for enums"), - Data::Union(_) => unimplemented!("Deriving NetworkBehaviour is not implemented for unions"), + Data::Enum(_) => Err(syn::Error::new_spanned( + ast, + "Cannot derive `NetworkBehaviour` on enums", + )), + Data::Union(_) => Err(syn::Error::new_spanned( + ast, + "Cannot derive `NetworkBehaviour` on union", + )), } } /// The version for structs -fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { +fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> syn::Result { let name = &ast.ident; let (_, ty_generics, where_clause) = ast.generics.split_for_impl(); let BehaviourAttributes { prelude_path, user_specified_out_event, deprecation_tokenstream, - } = match parse_attributes(ast) { - Ok(attrs) => attrs, - Err(e) => return e, - }; + } = parse_attributes(ast)?; let multiaddr = quote! { #prelude_path::Multiaddr }; let trait_to_impl = quote! { #prelude_path::NetworkBehaviour }; @@ -849,7 +852,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { } }; - final_quote.into() + Ok(final_quote.into()) } struct BehaviourAttributes { @@ -859,7 +862,7 @@ struct BehaviourAttributes { } /// Parses the `value` of a key=value pair in the `#[behaviour]` attribute into the requested type. -fn parse_attributes(ast: &DeriveInput) -> Result { +fn parse_attributes(ast: &DeriveInput) -> syn::Result { let mut attributes = BehaviourAttributes { prelude_path: syn::parse_quote! { ::libp2p::swarm::derive_prelude }, user_specified_out_event: None, @@ -871,33 +874,13 @@ fn parse_attributes(ast: &DeriveInput) -> Result::parse_terminated) - .expect("`parse_args_with` never fails when parsing nested meta"); + let nested = attr.parse_args_with(Punctuated::::parse_terminated)?; for meta in nested { if meta.path().is_ident("prelude") { - match meta { - Meta::Path(_) => unimplemented!(), - Meta::List(_) => unimplemented!(), - Meta::NameValue(MetaNameValue { - value: - Expr::Lit(ExprLit { - lit: Lit::Str(s), .. - }), - .. - }) => { - attributes.prelude_path = syn::parse_str(&s.value()).unwrap(); - } - Meta::NameValue(name_value) => { - return Err(syn::Error::new_spanned( - name_value.value, - "`prelude` value must be a quoted path", - ) - .to_compile_error() - .into()); - } - } + let value = meta.require_name_value()?.value.require_str_lit()?; + + attributes.prelude_path = syn::parse_str(&value)?; continue; } @@ -912,29 +895,10 @@ fn parse_attributes(ast: &DeriveInput) -> Result unimplemented!(), - Meta::List(_) => unimplemented!(), - - Meta::NameValue(MetaNameValue { - value: - Expr::Lit(ExprLit { - lit: Lit::Str(s), .. - }), - .. - }) => { - attributes.user_specified_out_event = - Some(syn::parse_str(&s.value()).unwrap()); - } - Meta::NameValue(name_value) => { - return Err(syn::Error::new_spanned( - name_value.value, - "`to_swarm` value must be a quoted type", - ) - .to_compile_error() - .into()); - } - } + + let value = meta.require_name_value()?.value.require_str_lit()?; + + attributes.user_specified_out_event = Some(syn::parse_str(&value)?); continue; } diff --git a/swarm-derive/src/syn_ext.rs b/swarm-derive/src/syn_ext.rs new file mode 100644 index 00000000000..d57a8a5dc43 --- /dev/null +++ b/swarm-derive/src/syn_ext.rs @@ -0,0 +1,16 @@ +use syn::{Expr, ExprLit, Lit}; + +pub(crate) trait RequireStrLit { + fn require_str_lit(&self) -> syn::Result; +} + +impl RequireStrLit for Expr { + fn require_str_lit(&self) -> syn::Result { + match self { + Expr::Lit(ExprLit { + lit: Lit::Str(str), .. + }) => Ok(str.value()), + _ => Err(syn::Error::new_spanned(self, "expected a string literal")), + } + } +} diff --git a/swarm/tests/ui/fail/prelude_not_string.rs b/swarm/tests/ui/fail/prelude_not_string.rs new file mode 100644 index 00000000000..727f2439ec0 --- /dev/null +++ b/swarm/tests/ui/fail/prelude_not_string.rs @@ -0,0 +1,11 @@ +use libp2p_ping as ping; + +#[derive(libp2p_swarm::NetworkBehaviour)] +#[behaviour(prelude = libp2p_swarm::derive_prelude)] +struct Foo { + ping: ping::Behaviour, +} + +fn main() { + +} diff --git a/swarm/tests/ui/fail/prelude_not_string.stderr b/swarm/tests/ui/fail/prelude_not_string.stderr new file mode 100644 index 00000000000..2c2a79805d9 --- /dev/null +++ b/swarm/tests/ui/fail/prelude_not_string.stderr @@ -0,0 +1,5 @@ +error: expected a string literal + --> tests/ui/fail/prelude_not_string.rs:4:23 + | +4 | #[behaviour(prelude = libp2p_swarm::derive_prelude)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/swarm/tests/ui/fail/to_swarm_not_string.rs b/swarm/tests/ui/fail/to_swarm_not_string.rs new file mode 100644 index 00000000000..e0ff56e41a7 --- /dev/null +++ b/swarm/tests/ui/fail/to_swarm_not_string.rs @@ -0,0 +1,19 @@ +use libp2p_ping as ping; + +#[derive(libp2p_swarm::NetworkBehaviour)] +#[behaviour(out_event = FooEvent, prelude = "libp2p_swarm::derive_prelude")] +struct Foo { + ping: ping::Behaviour, +} + +struct FooEvent; + +impl From for FooEvent { + fn from(_: ping::Event) -> Self { + unimplemented!() + } +} + +fn main() { + +} diff --git a/swarm/tests/ui/fail/to_swarm_not_string.stderr b/swarm/tests/ui/fail/to_swarm_not_string.stderr new file mode 100644 index 00000000000..f2fbba685cb --- /dev/null +++ b/swarm/tests/ui/fail/to_swarm_not_string.stderr @@ -0,0 +1,5 @@ +error: expected a string literal + --> tests/ui/fail/to_swarm_not_string.rs:4:25 + | +4 | #[behaviour(out_event = FooEvent, prelude = "libp2p_swarm::derive_prelude")] + | ^^^^^^^^ From 5c785b92e73a6c21d52e6f9a560a0f619a33808f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 14:38:44 +0200 Subject: [PATCH 18/38] feat(plaintext): remove `Plaintext1Config` `Plaintext2Config` works with the upgrade infrastructure and is thus preferable. Related: #3915. Pull-Request: #3940. --- Cargo.lock | 1 - transports/plaintext/CHANGELOG.md | 5 +++ transports/plaintext/Cargo.toml | 1 - transports/plaintext/src/lib.rs | 60 ------------------------------- 4 files changed, 5 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0380178273..cdf3ed1e04a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2856,7 +2856,6 @@ dependencies = [ "quickcheck-ext", "rand 0.8.5", "unsigned-varint", - "void", ] [[package]] diff --git a/transports/plaintext/CHANGELOG.md b/transports/plaintext/CHANGELOG.md index 5f04ca16cba..be1791c17c3 100644 --- a/transports/plaintext/CHANGELOG.md +++ b/transports/plaintext/CHANGELOG.md @@ -3,7 +3,12 @@ - Raise MSRV to 1.65. See [PR 3715]. +- Remove `Plaintext1Config`. + Use `Plaintext2Config` instead. + See [PR 3915]. + [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3915]: https://github.com/libp2p/rust-libp2p/pull/3915 ## 0.39.1 diff --git a/transports/plaintext/Cargo.toml b/transports/plaintext/Cargo.toml index 6946f22558e..ba60454d675 100644 --- a/transports/plaintext/Cargo.toml +++ b/transports/plaintext/Cargo.toml @@ -19,7 +19,6 @@ libp2p-identity = { workspace = true } log = "0.4.8" quick-protobuf = "0.8" unsigned-varint = { version = "0.7", features = ["asynchronous_codec"] } -void = "1.0.2" [dev-dependencies] env_logger = "0.10.0" diff --git a/transports/plaintext/src/lib.rs b/transports/plaintext/src/lib.rs index 64aea0b82a6..76e70a025b7 100644 --- a/transports/plaintext/src/lib.rs +++ b/transports/plaintext/src/lib.rs @@ -26,7 +26,6 @@ use crate::error::PlainTextError; use bytes::Bytes; use futures::future::BoxFuture; -use futures::future::{self, Ready}; use futures::prelude::*; use libp2p_core::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}; use libp2p_identity as identity; @@ -38,7 +37,6 @@ use std::{ pin::Pin, task::{Context, Poll}, }; -use void::Void; mod error; mod handshake; @@ -48,64 +46,6 @@ mod proto { pub(crate) use self::structs::Exchange; } -/// `PlainText1Config` is an insecure connection handshake for testing purposes only. -/// -/// > **Note**: Given that `PlainText1Config` has no notion of exchanging peer identity information it is not compatible -/// > with the `libp2p_core::transport::upgrade::Builder` pattern. See -/// > [`PlainText2Config`](struct.PlainText2Config.html) if compatibility is needed. Even though not compatible with the -/// > Builder pattern one can still do an upgrade *manually*: -/// -/// ``` -/// # use libp2p_core::transport::{ Transport, memory::MemoryTransport }; -/// # use libp2p_plaintext::PlainText1Config; -/// # -/// MemoryTransport::default() -/// .and_then(move |io, endpoint| { -/// libp2p_core::upgrade::apply( -/// io, -/// PlainText1Config{}, -/// endpoint, -/// libp2p_core::transport::upgrade::Version::V1, -/// ) -/// }) -/// .map(|plaintext, _endpoint| { -/// unimplemented!(); -/// // let peer_id = somehow_derive_peer_id(); -/// // return (peer_id, plaintext); -/// }); -/// ``` -#[derive(Debug, Copy, Clone)] -pub struct PlainText1Config; - -impl UpgradeInfo for PlainText1Config { - type Info = &'static str; - type InfoIter = iter::Once; - - fn protocol_info(&self) -> Self::InfoIter { - iter::once("/plaintext/1.0.0") - } -} - -impl InboundUpgrade for PlainText1Config { - type Output = C; - type Error = Void; - type Future = Ready>; - - fn upgrade_inbound(self, i: C, _: Self::Info) -> Self::Future { - future::ready(Ok(i)) - } -} - -impl OutboundUpgrade for PlainText1Config { - type Output = C; - type Error = Void; - type Future = Ready>; - - fn upgrade_outbound(self, i: C, _: Self::Info) -> Self::Future { - future::ready(Ok(i)) - } -} - /// `PlainText2Config` is an insecure connection handshake for testing purposes only, implementing /// the libp2p plaintext connection handshake specification. #[derive(Clone)] From 08f0b5e9c9df3939766b12ae6a53dae9e2584cf8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 15:24:18 +0200 Subject: [PATCH 19/38] feat(core): make the `upgrade` module an implementation detail Resolves: #3748. Pull-Request: #3915. --- core/CHANGELOG.md | 5 +++++ core/src/upgrade.rs | 4 +++- core/src/upgrade/apply.rs | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index ea2d14a30fb..44be3acd4cb 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -23,10 +23,15 @@ - Add `global_only::Transport` that refuses to dial IP addresses from private ranges. See [PR 3814]. +- Remove `upgrade::{apply, apply_inbound, apply_outbound, InboundUpgradeApply, OutboundUpgradeApply}` from public API. + These are implementation details that should not be depended on. + See [PR 3915]. + [spec]: https://github.com/libp2p/specs/blob/master/connections/README.md#multistream-select [PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746 [PR 3883]: https://github.com/libp2p/rust-libp2p/pull/3883 [PR 3814]: https://github.com/libp2p/rust-libp2p/pull/3814 +[PR 3915]: https://github.com/libp2p/rust-libp2p/pull/3915 ## 0.39.2 diff --git a/core/src/upgrade.rs b/core/src/upgrade.rs index 3d0b752f4b8..8219ac03a73 100644 --- a/core/src/upgrade.rs +++ b/core/src/upgrade.rs @@ -66,10 +66,12 @@ mod ready; mod select; mod transfer; +pub(crate) use apply::{ + apply, apply_inbound, apply_outbound, InboundUpgradeApply, OutboundUpgradeApply, +}; use futures::future::Future; pub use self::{ - apply::{apply, apply_inbound, apply_outbound, InboundUpgradeApply, OutboundUpgradeApply}, denied::DeniedUpgrade, error::UpgradeError, pending::PendingUpgrade, diff --git a/core/src/upgrade/apply.rs b/core/src/upgrade/apply.rs index 1dca0be4ad5..50aa8e2c0dd 100644 --- a/core/src/upgrade/apply.rs +++ b/core/src/upgrade/apply.rs @@ -29,7 +29,7 @@ pub(crate) use multistream_select::Version; // TODO: Still needed? /// Applies an upgrade to the inbound and outbound direction of a connection or substream. -pub fn apply( +pub(crate) fn apply( conn: C, up: U, cp: ConnectedPoint, @@ -48,7 +48,7 @@ where } /// Tries to perform an upgrade on an inbound connection or substream. -pub fn apply_inbound(conn: C, up: U) -> InboundUpgradeApply +pub(crate) fn apply_inbound(conn: C, up: U) -> InboundUpgradeApply where C: AsyncRead + AsyncWrite + Unpin, U: InboundUpgrade>, @@ -62,7 +62,7 @@ where } /// Tries to perform an upgrade on an outbound connection or substream. -pub fn apply_outbound(conn: C, up: U, v: Version) -> OutboundUpgradeApply +pub(crate) fn apply_outbound(conn: C, up: U, v: Version) -> OutboundUpgradeApply where C: AsyncRead + AsyncWrite + Unpin, U: OutboundUpgrade>, From 0b209f71cc7f9286eda99741ec3e5b1fb4a6ccb7 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 15 May 2023 16:11:13 +0200 Subject: [PATCH 20/38] feat(libp2p): remove deprecated `mplex` module Pull-Request: #3920. --- Cargo.lock | 3 +-- examples/chat-example/src/main.rs | 2 +- examples/ipfs-kad/Cargo.toml | 2 +- examples/ipfs-kad/src/main.rs | 2 +- libp2p/CHANGELOG.md | 8 +++++++- libp2p/Cargo.toml | 4 ---- libp2p/src/lib.rs | 25 ++++--------------------- libp2p/src/transport_ext.rs | 4 ++-- libp2p/src/tutorials/ping.rs | 2 +- protocols/gossipsub/Cargo.toml | 2 +- protocols/gossipsub/src/lib.rs | 4 ++-- 11 files changed, 21 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cdf3ed1e04a..0d898d0360b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2387,7 +2387,6 @@ dependencies = [ "libp2p-kad", "libp2p-mdns", "libp2p-metrics", - "libp2p-mplex", "libp2p-noise", "libp2p-perf", "libp2p-ping", @@ -2591,10 +2590,10 @@ dependencies = [ "instant", "libp2p-core", "libp2p-identity", - "libp2p-mplex", "libp2p-noise", "libp2p-swarm", "libp2p-swarm-test", + "libp2p-yamux", "log", "prometheus-client", "quick-protobuf", diff --git a/examples/chat-example/src/main.rs b/examples/chat-example/src/main.rs index 2c038724c37..338b2e360ec 100644 --- a/examples/chat-example/src/main.rs +++ b/examples/chat-example/src/main.rs @@ -74,7 +74,7 @@ async fn main() -> Result<(), Box> { 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 Mplex protocol. + // 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")) diff --git a/examples/ipfs-kad/Cargo.toml b/examples/ipfs-kad/Cargo.toml index 7e156572781..701e4543408 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", "mplex", "noise", "tcp", "websocket", "yamux"] } +libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "noise", "tcp", "websocket", "yamux"] } diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index 9799ca8df0a..42735de2741 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 local_key = identity::Keypair::generate_ed25519(); let local_peer_id = PeerId::from(local_key.public()); - // Set up a an encrypted DNS-enabled TCP Transport over the Mplex protocol + // 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. diff --git a/libp2p/CHANGELOG.md b/libp2p/CHANGELOG.md index 18206718799..e073fccf7dd 100644 --- a/libp2p/CHANGELOG.md +++ b/libp2p/CHANGELOG.md @@ -12,9 +12,15 @@ - Rename `NetworkBehaviour::OutEvent` to `NetworkBehaviour::ToSwarm`, `ConnectionHandler::InEvent` to `ConnectionHandler::FromBehaviour`, `ConnectionHandler::OutEvent` to `ConnectionHandler::ToBehaviour`. See [PR 3848]. -[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746 +- Remove deprecated `mplex` module. + You can still depend on `libp2p-mplex` directly but we strongly encourage to migrate to `yamux`. + This also removes `mplex` from the `development_transport` and `tokio_development_transport` functions. + See [PR 3920]. + [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3746]: https://github.com/libp2p/rust-libp2p/pull/3746 [PR 3848]: https://github.com/libp2p/rust-libp2p/pull/3848 +[PR 3920]: https://github.com/libp2p/rust-libp2p/pull/3920 ## 0.51.3 diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index b4fa79d6343..95cd9c08681 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -26,7 +26,6 @@ full = [ "macros", "mdns", "metrics", - "mplex", "noise", "perf", "ping", @@ -65,7 +64,6 @@ kad = ["dep:libp2p-kad", "libp2p-metrics?/kad"] macros = ["libp2p-swarm/macros"] mdns = ["dep:libp2p-mdns"] metrics = ["dep:libp2p-metrics"] -mplex = ["dep:libp2p-mplex"] noise = ["dep:libp2p-noise"] perf = ["dep:libp2p-perf"] ping = ["dep:libp2p-ping", "libp2p-metrics?/ping"] @@ -106,7 +104,6 @@ libp2p-identify = { workspace = true, optional = true } libp2p-identity = { workspace = true } libp2p-kad = { workspace = true, optional = true } libp2p-metrics = { workspace = true, optional = true } -libp2p-mplex = { workspace = true, optional = true } libp2p-noise = { workspace = true, optional = true } libp2p-ping = { workspace = true, optional = true } libp2p-plaintext = { workspace = true, optional = true } @@ -144,7 +141,6 @@ 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/lib.rs b/libp2p/src/lib.rs index f086c2872f4..917c1c86edc 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -82,13 +82,6 @@ pub use libp2p_mdns as mdns; #[cfg(feature = "metrics")] #[doc(inline)] pub use libp2p_metrics as metrics; -#[cfg(feature = "mplex")] -#[deprecated( - note = "`mplex` is not recommended anymore. Please use `yamux` instead or depend on `libp2p-mplex` directly if you need it for legacy use cases." -)] -pub mod mplex { - pub use libp2p_mplex::*; -} #[cfg(feature = "noise")] #[doc(inline)] pub use libp2p_noise as noise; @@ -184,7 +177,7 @@ pub use libp2p_swarm::{Stream, StreamProtocol}; /// * DNS resolution. /// * Noise protocol encryption. /// * Websockets. -/// * Both Yamux and Mplex for substream multiplexing. +/// * Yamux for substream multiplexing. /// /// All async I/O of the transport is based on `async-std`. /// @@ -198,7 +191,6 @@ pub use libp2p_swarm::{Stream, StreamProtocol}; ), feature = "websocket", feature = "noise", - feature = "mplex", feature = "yamux" ))] #[cfg_attr( @@ -231,11 +223,7 @@ pub async fn development_transport( Ok(transport .upgrade(core::upgrade::Version::V1) .authenticate(noise::Config::new(&keypair).unwrap()) - .multiplex(core::upgrade::SelectUpgrade::new( - yamux::Config::default(), - #[allow(deprecated)] - mplex::MplexConfig::default(), - )) + .multiplex(yamux::Config::default()) .timeout(std::time::Duration::from_secs(20)) .boxed()) } @@ -245,7 +233,7 @@ pub async fn development_transport( /// * DNS resolution. /// * Noise protocol encryption. /// * Websockets. -/// * Both Yamux and Mplex for substream multiplexing. +/// * Yamux for substream multiplexing. /// /// All async I/O of the transport is based on `tokio`. /// @@ -259,7 +247,6 @@ pub async fn development_transport( ), feature = "websocket", feature = "noise", - feature = "mplex", feature = "yamux" ))] #[cfg_attr( @@ -288,11 +275,7 @@ pub fn tokio_development_transport( Ok(transport .upgrade(core::upgrade::Version::V1) .authenticate(noise::Config::new(&keypair).unwrap()) - .multiplex(core::upgrade::SelectUpgrade::new( - yamux::Config::default(), - #[allow(deprecated)] - mplex::MplexConfig::default(), - )) + .multiplex(yamux::Config::default()) .timeout(std::time::Duration::from_secs(20)) .boxed()) } diff --git a/libp2p/src/transport_ext.rs b/libp2p/src/transport_ext.rs index b51b8e8298a..8f7c16574f6 100644 --- a/libp2p/src/transport_ext.rs +++ b/libp2p/src/transport_ext.rs @@ -43,7 +43,7 @@ pub trait TransportExt: Transport { /// # Example /// /// ``` - /// use libp2p_mplex as mplex; + /// use libp2p_yamux as yamux; /// use libp2p_noise as noise; /// use libp2p_tcp as tcp; /// use libp2p::{ @@ -61,7 +61,7 @@ pub trait TransportExt: Transport { /// noise::Config::new(&id_keys) /// .expect("Signing libp2p-noise static DH keypair failed."), /// ) - /// .multiplex(mplex::MplexConfig::new()) + /// .multiplex(yamux::Config::default()) /// .boxed(); /// /// let (transport, sinks) = transport.with_bandwidth_logging(); diff --git a/libp2p/src/tutorials/ping.rs b/libp2p/src/tutorials/ping.rs index 295e37e24b1..b698c6ab3bb 100644 --- a/libp2p/src/tutorials/ping.rs +++ b/libp2p/src/tutorials/ping.rs @@ -55,7 +55,7 @@ //! edition = "2021" //! //! [dependencies] -//! libp2p = { version = "0.50", features = ["tcp", "dns", "async-std", "noise", "mplex", "yamux", "websocket", "ping", "macros"] } +//! 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"] } //! ``` diff --git a/protocols/gossipsub/Cargo.toml b/protocols/gossipsub/Cargo.toml index 813428bc008..80645f509ba 100644 --- a/protocols/gossipsub/Cargo.toml +++ b/protocols/gossipsub/Cargo.toml @@ -42,7 +42,7 @@ async-std = { version = "1.6.3", features = ["unstable"] } env_logger = "0.10.0" hex = "0.4.2" libp2p-core = { workspace = true } -libp2p-mplex = { workspace = true } +libp2p-yamux = { workspace = true } libp2p-noise = { workspace = true } libp2p-swarm-test = { workspace = true } quickcheck = { workspace = true } diff --git a/protocols/gossipsub/src/lib.rs b/protocols/gossipsub/src/lib.rs index cebd24444ee..b5ea9999a5a 100644 --- a/protocols/gossipsub/src/lib.rs +++ b/protocols/gossipsub/src/lib.rs @@ -99,12 +99,12 @@ //! let local_key = identity::Keypair::generate_ed25519(); //! let local_peer_id = local_key.public().to_peer_id(); //! -//! // Set up an encrypted TCP Transport over the Mplex +//! // Set up an encrypted TCP Transport over yamux //! // This is test transport (memory). //! let transport = MemoryTransport::default() //! .upgrade(libp2p_core::upgrade::Version::V1) //! .authenticate(libp2p_noise::Config::new(&local_key).unwrap()) -//! .multiplex(libp2p_mplex::MplexConfig::new()) +//! .multiplex(libp2p_yamux::Config::default()) //! .boxed(); //! //! // Create a Gossipsub topic From 21c003701d5f52d124a4a5b5cff375690d8d254f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 16:49:23 +0000 Subject: [PATCH 21/38] deps: bump serde from 1.0.162 to 1.0.163 Pull-Request: #3933. --- Cargo.lock | 8 ++++---- misc/keygen/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d898d0360b..f502a190c7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4633,9 +4633,9 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -4651,9 +4651,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.162" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", diff --git a/misc/keygen/Cargo.toml b/misc/keygen/Cargo.toml index 11441a8b43a..a1f00ea2a2d 100644 --- a/misc/keygen/Cargo.toml +++ b/misc/keygen/Cargo.toml @@ -12,7 +12,7 @@ publish = false [dependencies] clap = { version = "4.2.7", features = ["derive"] } zeroize = "1" -serde = { version = "1.0.162", features = ["derive"] } +serde = { version = "1.0.163", features = ["derive"] } serde_json = "1.0.96" libp2p-core = { workspace = true } base64 = "0.21.0" From 86ea8fe4aab2da063b1cf1840fa5a3507bc28b8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 17:08:16 +0000 Subject: [PATCH 22/38] deps: bump wasm-bindgen-futures from 0.4.34 to 0.4.35 Pull-Request: #3935. --- Cargo.lock | 32 ++++++++++++++++---------------- swarm/Cargo.toml | 2 +- transports/wasm-ext/Cargo.toml | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f502a190c7a..2810d96ffc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2303,9 +2303,9 @@ checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -5450,9 +5450,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5460,24 +5460,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" dependencies = [ "cfg-if", "js-sys", @@ -5487,9 +5487,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5497,22 +5497,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" [[package]] name = "wasm-timer" diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 51214454973..b707de8ce34 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -23,7 +23,7 @@ log = "0.4" rand = "0.8" smallvec = "1.6.1" void = "1" -wasm-bindgen-futures = { version = "0.4.34", optional = true } +wasm-bindgen-futures = { version = "0.4.35", optional = true } getrandom = { version = "0.2.9", features = ["js"], optional = true } # Explicit dependency to be used in `wasm-bindgen` feature once_cell = "1.17.1" multistream-select = { workspace = true } diff --git a/transports/wasm-ext/Cargo.toml b/transports/wasm-ext/Cargo.toml index 98fc25362c4..d865495ff01 100644 --- a/transports/wasm-ext/Cargo.toml +++ b/transports/wasm-ext/Cargo.toml @@ -16,7 +16,7 @@ js-sys = "0.3.61" libp2p-core = { workspace = true } parity-send-wrapper = "0.1.0" wasm-bindgen = "0.2.42" -wasm-bindgen-futures = "0.4.34" +wasm-bindgen-futures = "0.4.35" [features] websocket = [] From 3021814e6b74356fc0d6d7d61ddab3b7fe6d1adb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 17:30:19 +0000 Subject: [PATCH 23/38] deps: bump socket2 from 0.5.2 to 0.5.3 Pull-Request: #3934. --- Cargo.lock | 8 ++++---- protocols/mdns/Cargo.toml | 2 +- transports/tcp/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2810d96ffc1..c2a5f7c8cac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2712,7 +2712,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2 0.5.2", + "socket2 0.5.3", "tokio", "trust-dns-proto", "void", @@ -3059,7 +3059,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "log", - "socket2 0.5.2", + "socket2 0.5.3", "tokio", ] @@ -4818,9 +4818,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d283f86695ae989d1e18440a943880967156325ba025f05049946bff47bcc2b" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", "windows-sys 0.48.0", diff --git a/protocols/mdns/Cargo.toml b/protocols/mdns/Cargo.toml index c7236a8c9d6..c830ce8483b 100644 --- a/protocols/mdns/Cargo.toml +++ b/protocols/mdns/Cargo.toml @@ -21,7 +21,7 @@ libp2p-identity = { workspace = true } log = "0.4.14" rand = "0.8.3" smallvec = "1.6.1" -socket2 = { version = "0.5.2", features = ["all"] } +socket2 = { version = "0.5.3", features = ["all"] } tokio = { version = "1.28", default-features = false, features = ["net", "time"], optional = true} trust-dns-proto = { version = "0.22.0", default-features = false, features = ["mdns", "tokio-runtime"] } void = "1.0.2" diff --git a/transports/tcp/Cargo.toml b/transports/tcp/Cargo.toml index d6e4c1acda1..59eac1e9327 100644 --- a/transports/tcp/Cargo.toml +++ b/transports/tcp/Cargo.toml @@ -19,7 +19,7 @@ libc = "0.2.143" libp2p-core = { workspace = true } libp2p-identity = { workspace = true } log = "0.4.11" -socket2 = { version = "0.5.2", features = ["all"] } +socket2 = { version = "0.5.3", features = ["all"] } tokio = { version = "1.28.0", default-features = false, features = ["net"], optional = true } [features] From 2512b6cd18fe04a772a84596cb0ee88647fd6e4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 17:49:21 +0000 Subject: [PATCH 24/38] deps: bump pin-project from 1.0.12 to 1.1.0 Pull-Request: #3937. --- Cargo.lock | 10 +++++----- core/Cargo.toml | 2 +- misc/multistream-select/Cargo.toml | 2 +- misc/rw-stream-sink/Cargo.toml | 2 +- transports/pnet/Cargo.toml | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2a5f7c8cac..21221f6eccb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3792,22 +3792,22 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.16", ] [[package]] diff --git a/core/Cargo.toml b/core/Cargo.toml index 6812e5f3b34..03e92dc6e6b 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -23,7 +23,7 @@ multihash = { version = "0.17.0", default-features = false, features = ["std"] } multistream-select = { workspace = true } once_cell = "1.17.1" parking_lot = "0.12.0" -pin-project = "1.0.0" +pin-project = "1.1.0" quick-protobuf = "0.8" rand = "0.8" rw-stream-sink = { workspace = true } diff --git a/misc/multistream-select/Cargo.toml b/misc/multistream-select/Cargo.toml index b8ebd0cab68..329e6b92ab2 100644 --- a/misc/multistream-select/Cargo.toml +++ b/misc/multistream-select/Cargo.toml @@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"] bytes = "1" futures = "0.3" log = "0.4" -pin-project = "1.0.0" +pin-project = "1.1.0" smallvec = "1.6.1" unsigned-varint = "0.7" diff --git a/misc/rw-stream-sink/Cargo.toml b/misc/rw-stream-sink/Cargo.toml index 85871d3671e..61640ccd890 100644 --- a/misc/rw-stream-sink/Cargo.toml +++ b/misc/rw-stream-sink/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] [dependencies] futures = "0.3.28" -pin-project = "1.0.10" +pin-project = "1.1.0" static_assertions = "1" [dev-dependencies] diff --git a/transports/pnet/Cargo.toml b/transports/pnet/Cargo.toml index 3c834079e93..da5c55b538f 100644 --- a/transports/pnet/Cargo.toml +++ b/transports/pnet/Cargo.toml @@ -16,7 +16,7 @@ log = "0.4.8" salsa20 = "0.10" sha3 = "0.10" rand = "0.8" -pin-project = "1.0.2" +pin-project = "1.1.0" [dev-dependencies] libp2p-core = { workspace = true, features = ["rsa", "ecdsa", "secp256k1"] } From 7c64c422ad1f88f7ab954d7ee6cf62ca606b573d Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 15 May 2023 22:31:30 +0200 Subject: [PATCH 25/38] chore(relay): remove deprecated items Related: https://github.com/libp2p/rust-libp2p/issues/3647. Pull-Request: #3948. --- libp2p/src/tutorials/hole_punching.rs | 2 +- protocols/relay/CHANGELOG.md | 3 + protocols/relay/src/lib.rs | 1 - protocols/relay/src/priv_client.rs | 5 - protocols/relay/src/priv_client/transport.rs | 5 +- protocols/relay/src/v2.rs | 163 ------------------- 6 files changed, 7 insertions(+), 172 deletions(-) delete mode 100644 protocols/relay/src/v2.rs diff --git a/libp2p/src/tutorials/hole_punching.rs b/libp2p/src/tutorials/hole_punching.rs index 8c898f7f4f4..161a2feeec4 100644 --- a/libp2p/src/tutorials/hole_punching.rs +++ b/libp2p/src/tutorials/hole_punching.rs @@ -25,7 +25,7 @@ //! post](https://blog.ipfs.io/2022-01-20-libp2p-hole-punching/) to familiarize yourself with libp2p's hole //! punching mechanism on a conceptual level. //! -//! We will be using the [Circuit Relay v2](crate::relay::v2) and the [Direct Connection +//! We will be using the [Circuit Relay](crate::relay) and the [Direct Connection //! Upgrade through Relay (DCUtR)](crate::dcutr) protocol. //! //! You will need 3 machines for this tutorial: diff --git a/protocols/relay/CHANGELOG.md b/protocols/relay/CHANGELOG.md index 137fbf38292..e4f5c83201f 100644 --- a/protocols/relay/CHANGELOG.md +++ b/protocols/relay/CHANGELOG.md @@ -10,9 +10,12 @@ These variants are no longer constructed. See [PR 3605]. +- Remove deprecated items. See [PR 3948]. + [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 [PR 3829]: https://github.com/libp2p/rust-libp2p/pull/3829 +[PR 3948]: https://github.com/libp2p/rust-libp2p/pull/3948 ## 0.15.2 diff --git a/protocols/relay/src/lib.rs b/protocols/relay/src/lib.rs index 8421026d984..b411c650aeb 100644 --- a/protocols/relay/src/lib.rs +++ b/protocols/relay/src/lib.rs @@ -28,7 +28,6 @@ mod copy_future; mod multiaddr_ext; mod priv_client; mod protocol; -pub mod v2; mod proto { #![allow(unreachable_pub)] diff --git a/protocols/relay/src/priv_client.rs b/protocols/relay/src/priv_client.rs index 1d4237e83d8..7a264bacb03 100644 --- a/protocols/relay/src/priv_client.rs +++ b/protocols/relay/src/priv_client.rs @@ -118,11 +118,6 @@ pub fn new(local_peer_id: PeerId) -> (Transport, Behaviour) { } impl Behaviour { - #[deprecated(since = "0.15.0", note = "Use libp2p_relay::client::new instead.")] - pub fn new_transport_and_behaviour(local_peer_id: PeerId) -> (transport::Transport, Self) { - new(local_peer_id) - } - fn on_connection_closed( &mut self, ConnectionClosed { diff --git a/protocols/relay/src/priv_client/transport.rs b/protocols/relay/src/priv_client/transport.rs index 23e0e34e237..aaaf760966f 100644 --- a/protocols/relay/src/priv_client/transport.rs +++ b/protocols/relay/src/priv_client/transport.rs @@ -301,7 +301,7 @@ fn parse_relayed_multiaddr(addr: Multiaddr) -> Result::Item>, @@ -422,8 +422,9 @@ impl From for TransportError { /// Message from the [`Transport`] to the [`Behaviour`](crate::Behaviour) /// [`NetworkBehaviour`](libp2p_swarm::NetworkBehaviour). -pub enum TransportToBehaviourMsg { +pub(crate) enum TransportToBehaviourMsg { /// Dial destination node via relay node. + #[allow(dead_code)] DialReq { request_id: RequestId, relay_addr: Multiaddr, diff --git a/protocols/relay/src/v2.rs b/protocols/relay/src/v2.rs deleted file mode 100644 index ab222062eec..00000000000 --- a/protocols/relay/src/v2.rs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright 2021 Protocol Labs. -// -// 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. - -//! Implementation of the [libp2p circuit relay v2 -//! specification](https://github.com/libp2p/specs/blob/master/relay/circuit-v2.md). - -pub mod client { - #[deprecated(since = "0.15.0", note = "Use libp2p_relay::client::Event instead.")] - pub type Event = crate::client::Event; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::client::Behaviour instead." - )] - pub type Client = crate::client::Behaviour; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::client::Connection instead." - )] - pub type RelayedConnection = crate::client::Connection; - - pub mod transport { - use futures::future::BoxFuture; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::client::Transport instead." - )] - pub type ClientTransport = crate::client::Transport; - - #[deprecated( - since = "0.15.0", - note = "RelayListener will become crate-private in the future - as it shouldn't be required by end users." - )] - pub type RelayListener = crate::priv_client::transport::Listener; - - #[deprecated( - since = "0.15.0", - note = "RelayedDial type alias will be deprecated, - users should create the alias themselves if needed." - )] - pub type RelayedDial = BoxFuture< - 'static, - Result, - >; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::client::transport::Error instead." - )] - pub type RelayError = crate::client::transport::Error; - - #[deprecated( - since = "0.15.0", - note = "TransportToBehaviourMsg will become crate-private in the future - as it shouldn't be required by end users." - )] - pub type TransportToBehaviourMsg = crate::priv_client::transport::TransportToBehaviourMsg; - - #[deprecated( - since = "0.15.0", - note = "ToListenerMsg will become crate-private in the future - as it shouldn't be required by end users." - )] - pub type ToListenerMsg = crate::priv_client::transport::ToListenerMsg; - - #[deprecated( - since = "0.15.0", - note = "Reservation will become crate-private in the future - as it shouldn't be required by end users." - )] - pub type Reservation = crate::priv_client::transport::Reservation; - } -} - -pub mod relay { - #[deprecated(since = "0.15.0", note = "Use libp2p_relay::Config instead.")] - pub type Config = crate::Config; - - #[deprecated(since = "0.15.0", note = "Use libp2p_relay::Event instead.")] - pub type Event = crate::Event; - - #[deprecated(since = "0.15.0", note = "Use libp2p_relay::Behaviour instead.")] - pub type Relay = crate::Behaviour; - - #[deprecated(since = "0.15.0", note = "Use libp2p_relay::CircuitId instead.")] - pub type CircuitId = crate::CircuitId; - - pub mod rate_limiter { - use instant::Instant; - use libp2p_core::Multiaddr; - use libp2p_identity::PeerId; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::behaviour::rate_limiter::RateLimiter instead." - )] - pub trait RateLimiter: Send { - fn try_next(&mut self, peer: PeerId, addr: &Multiaddr, now: Instant) -> bool; - } - - #[allow(deprecated)] - impl RateLimiter for T - where - T: crate::behaviour::rate_limiter::RateLimiter, - { - fn try_next(&mut self, peer: PeerId, addr: &Multiaddr, now: Instant) -> bool { - self.try_next(peer, addr, now) - } - } - } -} - -pub mod protocol { - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::inbound::hop::FatalUpgradeError instead." - )] - pub type InboundHopFatalUpgradeError = crate::inbound::hop::FatalUpgradeError; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::inbound::stop::FatalUpgradeError instead." - )] - pub type InboundStopFatalUpgradeError = crate::inbound::stop::FatalUpgradeError; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::outbound::hop::FatalUpgradeError instead." - )] - pub type OutboundHopFatalUpgradeError = crate::outbound::hop::FatalUpgradeError; - - #[deprecated( - since = "0.15.0", - note = "Use libp2p_relay::outbound::stop::FatalUpgradeError instead." - )] - pub type OutboundStopFatalUpgradeError = crate::outbound::stop::FatalUpgradeError; -} - -#[deprecated( - since = "0.15.0", - note = "RequestId will be deprecated as it isn't used" -)] -pub type RequestId = super::RequestId; From 3f88fb6059f5800a145f60acda1e06a5f591b35c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 May 2023 21:00:03 +0000 Subject: [PATCH 26/38] deps: bump js-sys from 0.3.61 to 0.3.62 Pull-Request: #3930. --- transports/wasm-ext/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transports/wasm-ext/Cargo.toml b/transports/wasm-ext/Cargo.toml index d865495ff01..ff4efb610e0 100644 --- a/transports/wasm-ext/Cargo.toml +++ b/transports/wasm-ext/Cargo.toml @@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"] [dependencies] futures = "0.3.28" -js-sys = "0.3.61" +js-sys = "0.3.62" libp2p-core = { workspace = true } parity-send-wrapper = "0.1.0" wasm-bindgen = "0.2.42" From 4fdd83e42fc93856ada03909ba53d5837e06279c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Tue, 16 May 2023 07:31:30 +0200 Subject: [PATCH 27/38] fix(identity): remove unused file secp256r1.pk8 Introduced in https://github.com/libp2p/rust-libp2p/pull/3863/. Pull-Request: #3950. --- identity/src/test/secp256r1.pk8 | Bin 138 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 identity/src/test/secp256r1.pk8 diff --git a/identity/src/test/secp256r1.pk8 b/identity/src/test/secp256r1.pk8 deleted file mode 100644 index 81813a77b3e5703d99ca6318ee0862171d0a96f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmXqLY-eI*Fc4;A*J|@PXUoLM#sOw9GqSVf8e}suGO{QXoHWsAT(-o<`RQAKo_}7) zl^mu=&f2zFU=!b|P1BX{FfVjrc4A=R(UTIooXHWw5tw&7E>8J($<)(NloV%O;$rF( qHm+q}SGDAghINqSB_3baZ~rQ{y`Lk(ctBRVxV~_yW&P%Jb?X7gpE3*p From fbd471cd7944e305c3538c166a03490080f92206 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 16 May 2023 11:40:00 +0200 Subject: [PATCH 28/38] feat(websocket): remove deflate compression option This option is the only reason we pull in a dependency on the shared `zlib` library. Unfortunately, we cannot use a pure Rust backend here because that one does not support configuring the window bits of the deflate algorithm which is used in the deflate websocket extension. Using websockets in libp2p is already crazy inefficient because you end up with double encryption when using `/wss` (which is enforced by browsers if your website is served via https). A good encryption algorithm like noise or TLS produces an output that looks completely random. Any attempt in compressing this is pretty much wasted CPU power. Thus, I think removing this configuration option does not really hurt and allows us to remove the dependency on the `zlib` shared library. Pull-Request: #3949. --- .github/workflows/ci.yml | 3 --- Cargo.lock | 25 ------------------------- interop-tests/Dockerfile | 7 ------- transports/websocket/CHANGELOG.md | 5 +++++ transports/websocket/Cargo.toml | 2 +- transports/websocket/src/framed.rs | 30 ++---------------------------- transports/websocket/src/lib.rs | 6 ------ 7 files changed, 8 insertions(+), 70 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f56b5e6f6b..b6b241ea099 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,9 +31,6 @@ jobs: env: CRATE: ${{ matrix.crate }} steps: - - name: Install zlib for `libp2p-websocket` # https://github.com/paritytech/soketto/issues/72 - run: sudo apt-get install zlib1g-dev --yes - - uses: actions/checkout@v3 - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 diff --git a/Cargo.lock b/Cargo.lock index 21221f6eccb..329746059f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1613,7 +1613,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", - "libz-sys", "miniz_oxide", ] @@ -3230,17 +3229,6 @@ dependencies = [ "libsecp256k1-core", ] -[[package]] -name = "libz-sys" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - [[package]] name = "linked-hash-map" version = "0.5.6" @@ -3859,12 +3847,6 @@ dependencies = [ "spki 0.7.1", ] -[[package]] -name = "pkg-config" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" - [[package]] name = "platforms" version = "3.0.2" @@ -4834,7 +4816,6 @@ checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" dependencies = [ "base64 0.13.1", "bytes", - "flate2", "futures", "httparse", "log", @@ -5382,12 +5363,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" diff --git a/interop-tests/Dockerfile b/interop-tests/Dockerfile index e0a5ddfc31f..0d80a872f5c 100644 --- a/interop-tests/Dockerfile +++ b/interop-tests/Dockerfile @@ -1,12 +1,6 @@ # syntax=docker/dockerfile:1.5-labs FROM rust:1.67.0 as builder -# Install zlib as long as libp2p-websocket requires it: https://github.com/paritytech/soketto/issues/72 -RUN apt-get update && \ - apt-get download zlib1g && \ - mkdir /dpkg && \ - for deb in *.deb; do dpkg --extract $deb /dpkg || exit 10; done - # Run with access to the target cache to speed up builds WORKDIR /workspace ADD . . @@ -19,6 +13,5 @@ RUN --mount=type=cache,target=./target \ FROM gcr.io/distroless/cc COPY --from=builder /usr/local/bin/testplan /usr/local/bin/testplan -COPY --from=builder /dpkg / ENV RUST_BACKTRACE=1 ENTRYPOINT ["testplan"] diff --git a/transports/websocket/CHANGELOG.md b/transports/websocket/CHANGELOG.md index b8e795fd8d3..a952e082181 100644 --- a/transports/websocket/CHANGELOG.md +++ b/transports/websocket/CHANGELOG.md @@ -3,7 +3,12 @@ - Raise MSRV to 1.65. See [PR 3715]. +- Remove `WsConfig::use_deflate` option. + This allows us to remove the dependency on the `zlib` shared library. + See [PR 3949]. + [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3949]: https://github.com/libp2p/rust-libp2p/pull/3949 ## 0.41.0 diff --git a/transports/websocket/Cargo.toml b/transports/websocket/Cargo.toml index 643bf15b15f..14c093a7fb7 100644 --- a/transports/websocket/Cargo.toml +++ b/transports/websocket/Cargo.toml @@ -20,7 +20,7 @@ log = "0.4.8" parking_lot = "0.12.0" quicksink = "0.1" rw-stream-sink = { workspace = true } -soketto = { version = "0.7.0", features = ["deflate"] } +soketto = "0.7.0" url = "2.1" webpki-roots = "0.23" diff --git a/transports/websocket/src/framed.rs b/transports/websocket/src/framed.rs index a81f6d4553b..b5a0b1b98f1 100644 --- a/transports/websocket/src/framed.rs +++ b/transports/websocket/src/framed.rs @@ -32,7 +32,6 @@ use log::{debug, trace}; use parking_lot::Mutex; use soketto::{ connection::{self, CloseReason}, - extension::deflate::Deflate, handshake, }; use std::{collections::HashMap, ops::DerefMut, sync::Arc}; @@ -51,7 +50,6 @@ pub struct WsConfig { max_data_size: usize, tls_config: tls::Config, max_redirects: u8, - use_deflate: bool, /// Websocket protocol of the inner listener. /// /// This is the suffix of the address provided in `listen_on`. @@ -67,7 +65,6 @@ impl WsConfig { max_data_size: MAX_DATA_SIZE, tls_config: tls::Config::client(), max_redirects: 0, - use_deflate: false, listener_protos: HashMap::new(), } } @@ -99,12 +96,6 @@ impl WsConfig { self.tls_config = c; self } - - /// Should the deflate extension (RFC 7692) be used if supported? - pub fn use_deflate(&mut self, flag: bool) -> &mut Self { - self.use_deflate = flag; - self - } } type TlsOrPlain = future::Either, server::TlsStream>, T>; @@ -285,19 +276,12 @@ where let transport = self.transport.clone(); let tls_config = self.tls_config.clone(); - let use_deflate = self.use_deflate; let max_redirects = self.max_redirects; let future = async move { loop { - match Self::dial_once( - transport.clone(), - addr, - tls_config.clone(), - use_deflate, - role_override, - ) - .await + match Self::dial_once(transport.clone(), addr, tls_config.clone(), role_override) + .await { Ok(Either::Left(redirect)) => { if remaining_redirects == 0 { @@ -321,7 +305,6 @@ where transport: Arc>, addr: WsAddress, tls_config: tls::Config, - use_deflate: bool, role_override: Endpoint, ) -> Result>, Error> { trace!("Dialing websocket address: {:?}", addr); @@ -364,10 +347,6 @@ where let mut client = handshake::Client::new(stream, &addr.host_port, addr.path.as_ref()); - if use_deflate { - client.add_extension(Box::new(Deflate::new(connection::Mode::Client))); - } - match client .handshake() .map_err(|e| Error::Handshake(Box::new(e))) @@ -403,7 +382,6 @@ where let remote_addr2 = remote_addr.clone(); // used for logging let tls_config = self.tls_config.clone(); let max_size = self.max_data_size; - let use_deflate = self.use_deflate; async move { let stream = upgrade.map_err(Error::Transport).await?; @@ -440,10 +418,6 @@ where let mut server = handshake::Server::new(stream); - if use_deflate { - server.add_extension(Box::new(Deflate::new(connection::Mode::Server))); - } - let ws_key = { let request = server .receive_request() diff --git a/transports/websocket/src/lib.rs b/transports/websocket/src/lib.rs index fa12232244b..7462f281817 100644 --- a/transports/websocket/src/lib.rs +++ b/transports/websocket/src/lib.rs @@ -174,12 +174,6 @@ where self.transport.inner_mut().set_tls_config(c); self } - - /// Should the deflate extension (RFC 7692) be used if supported? - pub fn use_deflate(&mut self, flag: bool) -> &mut Self { - self.transport.inner_mut().use_deflate(flag); - self - } } impl Transport for WsConfig From 9f3c85164cedde7619dc066526e57b4149c1e6b4 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 16 May 2023 21:20:00 +0200 Subject: [PATCH 29/38] feat(swarm): rename `Custom` variant to `NotifyBehaviour` Rename `ConnectionHandlerEvent::Custom` to `ConnectionHandlerEvent::NotifyBehaviour`. Related #3848. Pull-Request: #3955. --- protocols/dcutr/src/handler/direct.rs | 2 +- protocols/dcutr/src/handler/relayed.rs | 48 +++---- protocols/gossipsub/src/handler.rs | 14 +- protocols/identify/src/handler.rs | 21 +-- protocols/kad/src/handler.rs | 48 ++++--- protocols/perf/src/client/handler.rs | 4 +- protocols/perf/src/server/handler.rs | 4 +- protocols/ping/src/handler.rs | 14 +- protocols/relay/src/behaviour/handler.rs | 122 ++++++++++-------- protocols/relay/src/priv_client/handler.rs | 42 +++--- protocols/rendezvous/src/substream_handler.rs | 28 ++-- protocols/request-response/src/handler.rs | 4 +- swarm/CHANGELOG.md | 3 + swarm/src/connection.rs | 2 +- swarm/src/handler.rs | 22 +++- swarm/src/handler/map_out.rs | 4 +- swarm/src/handler/one_shot.rs | 4 +- swarm/src/handler/select.rs | 10 +- 18 files changed, 221 insertions(+), 175 deletions(-) diff --git a/protocols/dcutr/src/handler/direct.rs b/protocols/dcutr/src/handler/direct.rs index a06c9272baa..cd994be5c30 100644 --- a/protocols/dcutr/src/handler/direct.rs +++ b/protocols/dcutr/src/handler/direct.rs @@ -70,7 +70,7 @@ impl ConnectionHandler for Handler { > { if !self.reported { self.reported = true; - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::DirectConnectionEstablished, )); } diff --git a/protocols/dcutr/src/handler/relayed.rs b/protocols/dcutr/src/handler/relayed.rs index eb1ad83cecb..c71b27b831d 100644 --- a/protocols/dcutr/src/handler/relayed.rs +++ b/protocols/dcutr/src/handler/relayed.rs @@ -171,12 +171,13 @@ impl Handler { ConnectedPoint::Dialer { address, role_override: _ } => address.clone(), ConnectedPoint::Listener { ..} => unreachable!("`::listen_protocol` denies all incoming substreams as a listener."), }; - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::InboundConnectRequest { - inbound_connect: Box::new(inbound_connect), - remote_addr, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::InboundConnectRequest { + inbound_connect: Box::new(inbound_connect), + remote_addr, + }, + )); } // A connection listener denies all incoming substreams, thus none can ever be fully negotiated. future::Either::Right(output) => void::unreachable(output), @@ -197,11 +198,12 @@ impl Handler { self.endpoint.is_listener(), "A connection dialer never initiates a connection upgrade." ); - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::OutboundConnectNegotiated { - remote_addrs: obs_addrs, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::OutboundConnectNegotiated { + remote_addrs: obs_addrs, + }, + )); } fn on_listen_upgrade_error( @@ -228,21 +230,23 @@ impl Handler { match error { StreamUpgradeError::Timeout => { - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::OutboundNegotiationFailed { - error: StreamUpgradeError::Timeout, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::OutboundNegotiationFailed { + error: StreamUpgradeError::Timeout, + }, + )); } StreamUpgradeError::NegotiationFailed => { // The remote merely doesn't support the DCUtR protocol. // This is no reason to close the connection, which may // successfully communicate with other protocols already. - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::OutboundNegotiationFailed { - error: StreamUpgradeError::NegotiationFailed, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::OutboundNegotiationFailed { + error: StreamUpgradeError::NegotiationFailed, + }, + )); } _ => { // Anything else is considered a fatal error or misbehaviour of @@ -342,7 +346,7 @@ impl ConnectionHandler for Handler { self.inbound_connect = None; match result { Ok(addresses) => { - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::InboundConnectNegotiated(addresses), )); } diff --git a/protocols/gossipsub/src/handler.rs b/protocols/gossipsub/src/handler.rs index 615d4ae132b..8508e026cee 100644 --- a/protocols/gossipsub/src/handler.rs +++ b/protocols/gossipsub/src/handler.rs @@ -232,9 +232,9 @@ impl EnabledHandler { if !self.peer_kind_sent { if let Some(peer_kind) = self.peer_kind.as_ref() { self.peer_kind_sent = true; - return Poll::Ready(ConnectionHandlerEvent::Custom(HandlerEvent::PeerKind( - peer_kind.clone(), - ))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + HandlerEvent::PeerKind(peer_kind.clone()), + )); } } @@ -261,7 +261,7 @@ impl EnabledHandler { self.last_io_activity = Instant::now(); self.inbound_substream = Some(InboundSubstreamState::WaitingInput(substream)); - return Poll::Ready(ConnectionHandlerEvent::Custom(message)); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(message)); } Poll::Ready(Some(Err(error))) => { log::debug!("Failed to read from inbound stream: {error}"); @@ -466,9 +466,9 @@ impl ConnectionHandler for Handler { Handler::Disabled(DisabledHandler::ProtocolUnsupported { peer_kind_sent }) => { if !*peer_kind_sent { *peer_kind_sent = true; - return Poll::Ready(ConnectionHandlerEvent::Custom(HandlerEvent::PeerKind( - PeerKind::NotSupported, - ))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + HandlerEvent::PeerKind(PeerKind::NotSupported), + )); } Poll::Pending diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index d041fca731a..4c7ae58631e 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -174,13 +174,13 @@ impl Handler { future::Either::Left(remote_info) => { self.update_supported_protocols_for_remote(&remote_info); self.events - .push(ConnectionHandlerEvent::Custom(Event::Identified( + .push(ConnectionHandlerEvent::NotifyBehaviour(Event::Identified( remote_info, ))); } - future::Either::Right(()) => self - .events - .push(ConnectionHandlerEvent::Custom(Event::IdentificationPushed)), + future::Either::Right(()) => self.events.push(ConnectionHandlerEvent::NotifyBehaviour( + Event::IdentificationPushed, + )), } } @@ -192,10 +192,9 @@ impl Handler { >, ) { let err = err.map_upgrade_err(|e| e.into_inner()); - self.events - .push(ConnectionHandlerEvent::Custom(Event::IdentificationError( - err, - ))); + self.events.push(ConnectionHandlerEvent::NotifyBehaviour( + Event::IdentificationError(err), + )); self.trigger_next_identify.reset(self.interval); } @@ -309,7 +308,9 @@ impl ConnectionHandler for Handler { if let Ok(info) = res { self.update_supported_protocols_for_remote(&info); - return Poll::Ready(ConnectionHandlerEvent::Custom(Event::Identified(info))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Event::Identified( + info, + ))); } } @@ -319,7 +320,7 @@ impl ConnectionHandler for Handler { .map(|()| Event::Identification) .unwrap_or_else(|err| Event::IdentificationError(StreamUpgradeError::Apply(err))); - return Poll::Ready(ConnectionHandlerEvent::Custom(event)); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)); } Poll::Pending diff --git a/protocols/kad/src/handler.rs b/protocols/kad/src/handler.rs index 75721c0dc31..99535e083f2 100644 --- a/protocols/kad/src/handler.rs +++ b/protocols/kad/src/handler.rs @@ -707,7 +707,7 @@ where > { if let ProtocolStatus::Confirmed = self.protocol_status { self.protocol_status = ProtocolStatus::Reported; - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::ProtocolConfirmed { endpoint: self.endpoint.clone(), }, @@ -826,7 +826,7 @@ where Err(error) => { *this = OutboundSubstreamState::Done; let event = user_data.map(|user_data| { - ConnectionHandlerEvent::Custom( + ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::QueryError { error: KademliaHandlerQueryErr::Io(error), user_data, @@ -844,10 +844,12 @@ where Poll::Ready(Err(error)) => { *this = OutboundSubstreamState::Done; let event = user_data.map(|user_data| { - ConnectionHandlerEvent::Custom(KademliaHandlerEvent::QueryError { - error: KademliaHandlerQueryErr::Io(error), - user_data, - }) + ConnectionHandlerEvent::NotifyBehaviour( + KademliaHandlerEvent::QueryError { + error: KademliaHandlerQueryErr::Io(error), + user_data, + }, + ) }); return Poll::Ready(event); @@ -870,10 +872,12 @@ where Poll::Ready(Err(error)) => { *this = OutboundSubstreamState::Done; let event = user_data.map(|user_data| { - ConnectionHandlerEvent::Custom(KademliaHandlerEvent::QueryError { - error: KademliaHandlerQueryErr::Io(error), - user_data, - }) + ConnectionHandlerEvent::NotifyBehaviour( + KademliaHandlerEvent::QueryError { + error: KademliaHandlerQueryErr::Io(error), + user_data, + }, + ) }); return Poll::Ready(event); @@ -886,7 +890,9 @@ where *this = OutboundSubstreamState::Closing(substream); let event = process_kad_response(msg, user_data); - return Poll::Ready(Some(ConnectionHandlerEvent::Custom(event))); + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( + event, + ))); } Poll::Pending => { *this = OutboundSubstreamState::WaitingAnswer(substream, user_data); @@ -899,7 +905,9 @@ where user_data, }; - return Poll::Ready(Some(ConnectionHandlerEvent::Custom(event))); + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( + event, + ))); } Poll::Ready(None) => { *this = OutboundSubstreamState::Done; @@ -910,7 +918,9 @@ where user_data, }; - return Poll::Ready(Some(ConnectionHandlerEvent::Custom(event))); + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( + event, + ))); } } } @@ -918,7 +928,7 @@ where *this = OutboundSubstreamState::Done; let event = KademliaHandlerEvent::QueryError { error, user_data }; - return Poll::Ready(Some(ConnectionHandlerEvent::Custom(event))); + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour(event))); } OutboundSubstreamState::Closing(mut stream) => match stream.poll_close_unpin(cx) { Poll::Ready(Ok(())) | Poll::Ready(Err(_)) => return Poll::Ready(None), @@ -971,7 +981,7 @@ where Poll::Ready(Some(Ok(KadRequestMsg::FindNode { key }))) => { *this = InboundSubstreamState::WaitingBehaviour(connection_id, substream, None); - return Poll::Ready(Some(ConnectionHandlerEvent::Custom( + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::FindNodeReq { key, request_id: KademliaRequestId { @@ -983,7 +993,7 @@ where Poll::Ready(Some(Ok(KadRequestMsg::GetProviders { key }))) => { *this = InboundSubstreamState::WaitingBehaviour(connection_id, substream, None); - return Poll::Ready(Some(ConnectionHandlerEvent::Custom( + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::GetProvidersReq { key, request_id: KademliaRequestId { @@ -998,14 +1008,14 @@ where connection_id, substream, }; - return Poll::Ready(Some(ConnectionHandlerEvent::Custom( + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::AddProvider { key, provider }, ))); } Poll::Ready(Some(Ok(KadRequestMsg::GetValue { key }))) => { *this = InboundSubstreamState::WaitingBehaviour(connection_id, substream, None); - return Poll::Ready(Some(ConnectionHandlerEvent::Custom( + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::GetRecord { key, request_id: KademliaRequestId { @@ -1017,7 +1027,7 @@ where Poll::Ready(Some(Ok(KadRequestMsg::PutValue { record }))) => { *this = InboundSubstreamState::WaitingBehaviour(connection_id, substream, None); - return Poll::Ready(Some(ConnectionHandlerEvent::Custom( + return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::PutRecord { record, request_id: KademliaRequestId { diff --git a/protocols/perf/src/client/handler.rs b/protocols/perf/src/client/handler.rs index f8a1eff5c10..8a6df43d198 100644 --- a/protocols/perf/src/client/handler.rs +++ b/protocols/perf/src/client/handler.rs @@ -146,7 +146,7 @@ impl ConnectionHandler for Handler { .pop_front() .expect("requested stream without pending command"); self.queued_events - .push_back(ConnectionHandlerEvent::Custom(Event { + .push_back(ConnectionHandlerEvent::NotifyBehaviour(Event { id, result: Err(error), })); @@ -179,7 +179,7 @@ impl ConnectionHandler for Handler { while let Poll::Ready(Some(result)) = self.outbound.poll_next_unpin(cx) { match result { - Ok(event) => return Poll::Ready(ConnectionHandlerEvent::Custom(event)), + Ok(event) => return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)), Err(e) => { panic!("{e:?}") } diff --git a/protocols/perf/src/server/handler.rs b/protocols/perf/src/server/handler.rs index 6f5043b66a3..e8f7b72e605 100644 --- a/protocols/perf/src/server/handler.rs +++ b/protocols/perf/src/server/handler.rs @@ -129,7 +129,9 @@ impl ConnectionHandler for Handler { > { while let Poll::Ready(Some(result)) = self.inbound.poll_next_unpin(cx) { match result { - Ok(stats) => return Poll::Ready(ConnectionHandlerEvent::Custom(Event { stats })), + Ok(stats) => { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Event { stats })) + } Err(e) => { error!("{e:?}") } diff --git a/protocols/ping/src/handler.rs b/protocols/ping/src/handler.rs index c21b234b3e3..e8fa40b0a67 100644 --- a/protocols/ping/src/handler.rs +++ b/protocols/ping/src/handler.rs @@ -258,7 +258,9 @@ impl ConnectionHandler for Handler { } State::Inactive { reported: false } => { self.state = State::Inactive { reported: true }; - return Poll::Ready(ConnectionHandlerEvent::Custom(Err(Failure::Unsupported))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Err( + Failure::Unsupported, + ))); } State::Active => {} } @@ -274,7 +276,7 @@ impl ConnectionHandler for Handler { Poll::Ready(Ok(stream)) => { // A ping from a remote peer has been answered, wait for the next. self.inbound = Some(protocol::recv_ping(stream).boxed()); - return Poll::Ready(ConnectionHandlerEvent::Custom(Ok(Success::Pong))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Ok(Success::Pong))); } } } @@ -299,7 +301,7 @@ impl ConnectionHandler for Handler { return Poll::Ready(ConnectionHandlerEvent::Close(error)); } - return Poll::Ready(ConnectionHandlerEvent::Custom(Err(error))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Err(error))); } } @@ -318,9 +320,9 @@ impl ConnectionHandler for Handler { self.failures = 0; self.timer.reset(self.config.interval); self.outbound = Some(OutboundState::Idle(stream)); - return Poll::Ready(ConnectionHandlerEvent::Custom(Ok(Success::Ping { - rtt, - }))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Ok( + Success::Ping { rtt }, + ))); } Poll::Ready(Err(e)) => { self.pending_errors diff --git a/protocols/relay/src/behaviour/handler.rs b/protocols/relay/src/behaviour/handler.rs index 752e5aeac89..9c1b8524ec3 100644 --- a/protocols/relay/src/behaviour/handler.rs +++ b/protocols/relay/src/behaviour/handler.rs @@ -410,21 +410,23 @@ impl Handler { ) { match request { inbound_hop::Req::Reserve(inbound_reservation_req) => { - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::ReservationReqReceived { - inbound_reservation_req, - endpoint: self.endpoint.clone(), - renewed: self.active_reservation.is_some(), - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::ReservationReqReceived { + inbound_reservation_req, + endpoint: self.endpoint.clone(), + renewed: self.active_reservation.is_some(), + }, + )); } inbound_hop::Req::Connect(inbound_circuit_req) => { - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::CircuitReqReceived { - inbound_circuit_req, - endpoint: self.endpoint.clone(), - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::CircuitReqReceived { + inbound_circuit_req, + endpoint: self.endpoint.clone(), + }, + )); } } } @@ -448,17 +450,18 @@ impl Handler { let (tx, rx) = oneshot::channel(); self.alive_lend_out_substreams.push(rx); - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::OutboundConnectNegotiated { - circuit_id, - src_peer_id, - src_connection_id, - inbound_circuit_req, - dst_handler_notifier: tx, - dst_stream, - dst_pending_data, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::OutboundConnectNegotiated { + circuit_id, + src_peer_id, + src_connection_id, + inbound_circuit_req, + dst_handler_notifier: tx, + dst_stream, + dst_pending_data, + }, + )); } fn on_listen_upgrade_error( @@ -525,16 +528,17 @@ impl Handler { src_connection_id, } = open_info; - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::OutboundConnectNegotiationFailed { - circuit_id, - src_peer_id, - src_connection_id, - inbound_circuit_req, - status, - error: non_fatal_error, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::OutboundConnectNegotiationFailed { + circuit_id, + src_peer_id, + src_connection_id, + inbound_circuit_req, + status, + error: non_fatal_error, + }, + )); } } @@ -692,18 +696,22 @@ impl ConnectionHandler for Handler { { match result { Ok(()) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(Event::CircuitClosed { - circuit_id, - dst_peer_id, - error: None, - })) + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + Event::CircuitClosed { + circuit_id, + dst_peer_id, + error: None, + }, + )) } Err(e) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(Event::CircuitClosed { - circuit_id, - dst_peer_id, - error: Some(e), - })) + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + Event::CircuitClosed { + circuit_id, + dst_peer_id, + error: Some(e), + }, + )) } } } @@ -714,13 +722,15 @@ impl ConnectionHandler for Handler { { match result { Ok(()) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(Event::CircuitReqDenied { - circuit_id, - dst_peer_id, - })); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + Event::CircuitReqDenied { + circuit_id, + dst_peer_id, + }, + )); } Err(error) => { - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::CircuitReqDenyFailed { circuit_id, dst_peer_id, @@ -773,7 +783,7 @@ impl ConnectionHandler for Handler { self.circuits.push(circuit); - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::CircuitReqAccepted { circuit_id, dst_peer_id, @@ -781,7 +791,7 @@ impl ConnectionHandler for Handler { )); } Err((circuit_id, dst_peer_id, error)) => { - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::CircuitReqAcceptFailed { circuit_id, dst_peer_id, @@ -799,7 +809,7 @@ impl ConnectionHandler for Handler { .map(|fut| fut.poll_unpin(cx)) { self.active_reservation = None; - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::ReservationTimedOut {}, )); } @@ -816,12 +826,12 @@ impl ConnectionHandler for Handler { .active_reservation .replace(Delay::new(self.config.reservation_duration)) .is_some(); - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::ReservationReqAccepted { renewed }, )); } Err(error) => { - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::ReservationReqAcceptFailed { error }, )); } @@ -834,12 +844,12 @@ impl ConnectionHandler for Handler { match result { Ok(()) => { - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::ReservationReqDenied {}, )) } Err(error) => { - return Poll::Ready(ConnectionHandlerEvent::Custom( + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( Event::ReservationReqDenyFailed { error }, )); } diff --git a/protocols/relay/src/priv_client/handler.rs b/protocols/relay/src/priv_client/handler.rs index dee51cde664..414ec4fc8df 100644 --- a/protocols/relay/src/priv_client/handler.rs +++ b/protocols/relay/src/priv_client/handler.rs @@ -194,9 +194,10 @@ impl Handler { relay_addr: self.remote_addr.clone(), }); - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::InboundCircuitEstablished { src_peer_id, limit }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::InboundCircuitEstablished { src_peer_id, limit }, + )); } Reservation::None => { let src_peer_id = inbound_circuit.src_peer_id(); @@ -254,7 +255,7 @@ impl Handler { ); self.queued_events - .push_back(ConnectionHandlerEvent::Custom(event)); + .push_back(ConnectionHandlerEvent::NotifyBehaviour(event)); } // Outbound circuit @@ -272,9 +273,10 @@ impl Handler { })) { Ok(()) => { self.alive_lend_out_substreams.push(rx); - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::OutboundCircuitEstablished { limit }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::OutboundCircuitEstablished { limit }, + )); } Err(_) => debug!( "Oneshot to `client::transport::Dial` future dropped. \ @@ -350,12 +352,13 @@ impl Handler { } let renewal = self.reservation.failed(); - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::ReservationReqFailed { - renewal, - error: non_fatal_error, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::ReservationReqFailed { + renewal, + error: non_fatal_error, + }, + )); } OutboundOpenInfo::Connect { send_back } => { let non_fatal_error = match error { @@ -382,11 +385,12 @@ impl Handler { let _ = send_back.send(Err(())); - self.queued_events.push_back(ConnectionHandlerEvent::Custom( - Event::OutboundCircuitReqFailed { - error: non_fatal_error, - }, - )); + self.queued_events + .push_back(ConnectionHandlerEvent::NotifyBehaviour( + Event::OutboundCircuitReqFailed { + error: non_fatal_error, + }, + )); } } } @@ -485,7 +489,7 @@ impl ConnectionHandler for Handler { }); if let Some((src_peer_id, event)) = maybe_event { self.circuit_deny_futs.remove(&src_peer_id); - return Poll::Ready(ConnectionHandlerEvent::Custom(event)); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)); } // Send errors to transport. diff --git a/protocols/rendezvous/src/substream_handler.rs b/protocols/rendezvous/src/substream_handler.rs index 6fc5cb561b2..2434b691fb2 100644 --- a/protocols/rendezvous/src/substream_handler.rs +++ b/protocols/rendezvous/src/substream_handler.rs @@ -468,32 +468,28 @@ where match poll_substreams(&mut self.inbound_substreams, cx) { Poll::Ready(Ok((id, message))) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(OutEvent::InboundEvent { - id, - message, - })) + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + OutEvent::InboundEvent { id, message }, + )) } Poll::Ready(Err((id, error))) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(OutEvent::InboundError { - id, - error, - })) + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + OutEvent::InboundError { id, error }, + )) } Poll::Pending => {} } match poll_substreams(&mut self.outbound_substreams, cx) { Poll::Ready(Ok((id, message))) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(OutEvent::OutboundEvent { - id, - message, - })) + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + OutEvent::OutboundEvent { id, message }, + )) } Poll::Ready(Err((id, error))) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(OutEvent::OutboundError { - id, - error, - })) + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + OutEvent::OutboundError { id, error }, + )) } Poll::Pending => {} } diff --git a/protocols/request-response/src/handler.rs b/protocols/request-response/src/handler.rs index 54b1b925847..35a2db98bdc 100644 --- a/protocols/request-response/src/handler.rs +++ b/protocols/request-response/src/handler.rs @@ -296,7 +296,7 @@ where > { // Drain pending events. if let Some(event) = self.pending_events.pop_front() { - return Poll::Ready(ConnectionHandlerEvent::Custom(event)); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)); } else if self.pending_events.capacity() > EMPTY_QUEUE_SHRINK_THRESHOLD { self.pending_events.shrink_to_fit(); } @@ -307,7 +307,7 @@ where Ok(((id, rq), rs_sender)) => { // We received an inbound request. self.keep_alive = KeepAlive::Yes; - return Poll::Ready(ConnectionHandlerEvent::Custom(Event::Request { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Event::Request { request_id: id, request: rq, sender: rs_sender, diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 159c61af9b6..1284f57cffa 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -50,6 +50,8 @@ - Remove deprecated `NetworkBehaviourAction` type. See [PR 3919]. +- Rename `ConnectionHandlerEvent::Custom` to `ConnectionHandlerEvent::NotifyBehaviour`. See [PR 3955]. + [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 [PR 3651]: https://github.com/libp2p/rust-libp2p/pull/3651 [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 @@ -62,6 +64,7 @@ [PR 3886]: https://github.com/libp2p/rust-libp2p/pull/3886 [PR 3912]: https://github.com/libp2p/rust-libp2p/pull/3912 [PR 3919]: https://github.com/libp2p/rust-libp2p/pull/3919 +[PR 3955]: https://github.com/libp2p/rust-libp2p/pull/3955 ## 0.42.2 diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index 43be1c98e3a..eab521593ac 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -263,7 +263,7 @@ where requested_substreams.push(SubstreamRequested::new(user_data, timeout, upgrade)); continue; // Poll handler until exhausted. } - Poll::Ready(ConnectionHandlerEvent::Custom(event)) => { + Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)) => { return Poll::Ready(Ok(Event::Handler(event))); } Poll::Ready(ConnectionHandlerEvent::Close(err)) => { diff --git a/swarm/src/handler.rs b/swarm/src/handler.rs index edefb7a1cb9..dcc7ab1c09d 100644 --- a/swarm/src/handler.rs +++ b/swarm/src/handler.rs @@ -101,7 +101,7 @@ use std::{cmp::Ordering, error, fmt, io, task::Context, task::Poll, time::Durati pub trait ConnectionHandler: Send + 'static { /// A type representing the message(s) a [`NetworkBehaviour`](crate::behaviour::NetworkBehaviour) can send to a [`ConnectionHandler`] via [`ToSwarm::NotifyHandler`](crate::behaviour::ToSwarm::NotifyHandler) type FromBehaviour: fmt::Debug + Send + 'static; - /// A type representing message(s) a [`ConnectionHandler`] can send to a [`NetworkBehaviour`](crate::behaviour::NetworkBehaviour) via [`ConnectionHandlerEvent::Custom`]. + /// A type representing message(s) a [`ConnectionHandler`] can send to a [`NetworkBehaviour`](crate::behaviour::NetworkBehaviour) via [`ConnectionHandlerEvent::NotifyBehaviour`]. type ToBehaviour: fmt::Debug + Send + 'static; /// The type of errors returned by [`ConnectionHandler::poll`]. type Error: error::Error + fmt::Debug + Send + 'static; @@ -508,8 +508,8 @@ pub enum ConnectionHandlerEvent protocol: protocol.map_info(map), } } - ConnectionHandlerEvent::Custom(val) => ConnectionHandlerEvent::Custom(val), + ConnectionHandlerEvent::NotifyBehaviour(val) => { + ConnectionHandlerEvent::NotifyBehaviour(val) + } ConnectionHandlerEvent::Close(val) => ConnectionHandlerEvent::Close(val), ConnectionHandlerEvent::ReportRemoteProtocols(support) => { ConnectionHandlerEvent::ReportRemoteProtocols(support) @@ -562,7 +564,9 @@ impl protocol: protocol.map_upgrade(map), } } - ConnectionHandlerEvent::Custom(val) => ConnectionHandlerEvent::Custom(val), + ConnectionHandlerEvent::NotifyBehaviour(val) => { + ConnectionHandlerEvent::NotifyBehaviour(val) + } ConnectionHandlerEvent::Close(val) => ConnectionHandlerEvent::Close(val), ConnectionHandlerEvent::ReportRemoteProtocols(support) => { ConnectionHandlerEvent::ReportRemoteProtocols(support) @@ -582,7 +586,9 @@ impl ConnectionHandlerEvent::OutboundSubstreamRequest { protocol } => { ConnectionHandlerEvent::OutboundSubstreamRequest { protocol } } - ConnectionHandlerEvent::Custom(val) => ConnectionHandlerEvent::Custom(map(val)), + ConnectionHandlerEvent::NotifyBehaviour(val) => { + ConnectionHandlerEvent::NotifyBehaviour(map(val)) + } ConnectionHandlerEvent::Close(val) => ConnectionHandlerEvent::Close(val), ConnectionHandlerEvent::ReportRemoteProtocols(support) => { ConnectionHandlerEvent::ReportRemoteProtocols(support) @@ -602,7 +608,9 @@ impl ConnectionHandlerEvent::OutboundSubstreamRequest { protocol } => { ConnectionHandlerEvent::OutboundSubstreamRequest { protocol } } - ConnectionHandlerEvent::Custom(val) => ConnectionHandlerEvent::Custom(val), + ConnectionHandlerEvent::NotifyBehaviour(val) => { + ConnectionHandlerEvent::NotifyBehaviour(val) + } ConnectionHandlerEvent::Close(val) => ConnectionHandlerEvent::Close(map(val)), ConnectionHandlerEvent::ReportRemoteProtocols(support) => { ConnectionHandlerEvent::ReportRemoteProtocols(support) diff --git a/swarm/src/handler/map_out.rs b/swarm/src/handler/map_out.rs index f3240a76b2d..e92d1403ce6 100644 --- a/swarm/src/handler/map_out.rs +++ b/swarm/src/handler/map_out.rs @@ -76,7 +76,9 @@ where >, > { self.inner.poll(cx).map(|ev| match ev { - ConnectionHandlerEvent::Custom(ev) => ConnectionHandlerEvent::Custom((self.map)(ev)), + ConnectionHandlerEvent::NotifyBehaviour(ev) => { + ConnectionHandlerEvent::NotifyBehaviour((self.map)(ev)) + } ConnectionHandlerEvent::Close(err) => ConnectionHandlerEvent::Close(err), ConnectionHandlerEvent::OutboundSubstreamRequest { protocol } => { ConnectionHandlerEvent::OutboundSubstreamRequest { protocol } diff --git a/swarm/src/handler/one_shot.rs b/swarm/src/handler/one_shot.rs index b7c98e189e7..439d3f47ee3 100644 --- a/swarm/src/handler/one_shot.rs +++ b/swarm/src/handler/one_shot.rs @@ -157,7 +157,9 @@ where } if !self.events_out.is_empty() { - return Poll::Ready(ConnectionHandlerEvent::Custom(self.events_out.remove(0))); + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + self.events_out.remove(0), + )); } else { self.events_out.shrink_to_fit(); } diff --git a/swarm/src/handler/select.rs b/swarm/src/handler/select.rs index 48048befc81..65db4ab525b 100644 --- a/swarm/src/handler/select.rs +++ b/swarm/src/handler/select.rs @@ -227,8 +227,8 @@ where >, > { match self.proto1.poll(cx) { - Poll::Ready(ConnectionHandlerEvent::Custom(event)) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(Either::Left(event))); + Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)) => { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Either::Left(event))); } Poll::Ready(ConnectionHandlerEvent::Close(event)) => { return Poll::Ready(ConnectionHandlerEvent::Close(Either::Left(event))); @@ -247,8 +247,10 @@ where }; match self.proto2.poll(cx) { - Poll::Ready(ConnectionHandlerEvent::Custom(event)) => { - return Poll::Ready(ConnectionHandlerEvent::Custom(Either::Right(event))); + Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)) => { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Either::Right( + event, + ))); } Poll::Ready(ConnectionHandlerEvent::Close(event)) => { return Poll::Ready(ConnectionHandlerEvent::Close(Either::Right(event))); From a580906a88790ba2e1537d88f5e0431a2a4f1e1f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 May 2023 19:41:17 +0000 Subject: [PATCH 30/38] deps: bump Swatinem/rust-cache from 2.2.1 to 2.3.0 Pull-Request: #3929. --- .github/workflows/cache-factory.yml | 2 +- .github/workflows/ci.yml | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cache-factory.yml b/.github/workflows/cache-factory.yml index 2f4e807f7d9..b2493c0f336 100644 --- a/.github/workflows/cache-factory.yml +++ b/.github/workflows/cache-factory.yml @@ -22,7 +22,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: shared-key: stable-cache diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6b241ea099..d22f3333e6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: shared-key: stable-cache save-if: false @@ -107,7 +107,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: key: ${{ matrix.target }} save-if: ${{ github.ref == 'refs/heads/master' }} @@ -132,7 +132,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: save-if: ${{ github.ref == 'refs/heads/master' }} @@ -153,7 +153,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: key: ${{ matrix.features }} save-if: ${{ github.ref == 'refs/heads/master' }} @@ -170,7 +170,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: save-if: ${{ github.ref == 'refs/heads/master' }} @@ -196,7 +196,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: save-if: ${{ github.ref == 'refs/heads/master' }} @@ -213,7 +213,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: save-if: ${{ github.ref == 'refs/heads/master' }} @@ -229,7 +229,7 @@ jobs: - uses: r7kamura/rust-problem-matchers@d58b70c4a13c4866d96436315da451d8106f8f08 #v1.3.0 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 with: shared-key: stable-cache save-if: false @@ -295,7 +295,7 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 - run: cargo install --version 0.10.0 pb-rs --locked @@ -321,5 +321,5 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: Swatinem/rust-cache@6fd3edff6979b79f87531400ad694fb7f2c84b1f # v2.2.1 + - uses: Swatinem/rust-cache@060bda31e0be4f453bb6ed2d7e5427b31734ad01 # v2.3.0 - run: cargo metadata --locked --format-version=1 > /dev/null From cc5b346a7cde97573d96eef17904144cafb72de5 Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 17 May 2023 07:19:53 +0200 Subject: [PATCH 31/38] feat(swarm): expose `ConnectionId` and add conn duration metric - Exposes the `ConnectionId` in the various `SwarmEvent` variants. - Tracks connection duration in `libp2p-metrics::swarm`. Pull-Request: #3927. --- Cargo.lock | 5 +- examples/dcutr/src/main.rs | 2 +- examples/file-sharing/src/network.rs | 5 +- misc/metrics/CHANGELOG.md | 5 ++ misc/metrics/Cargo.toml | 3 +- misc/metrics/src/swarm.rs | 107 ++++++++++++++++++------- protocols/autonat/tests/test_server.rs | 18 ++++- protocols/dcutr/tests/lib.rs | 5 +- protocols/perf/src/bin/perf-client.rs | 4 +- protocols/perf/tests/lib.rs | 2 +- protocols/relay/tests/lib.rs | 10 ++- swarm/CHANGELOG.md | 5 ++ swarm/src/lib.rs | 35 +++++++- 13 files changed, 157 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 329746059f0..cc9d5e1bfe6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2721,6 +2721,7 @@ dependencies = [ name = "libp2p-metrics" version = "0.13.0" dependencies = [ + "instant", "libp2p-core", "libp2p-dcutr", "libp2p-gossipsub", @@ -4000,9 +4001,9 @@ dependencies = [ [[package]] name = "prometheus-client" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38974b1966bd5b6c7c823a20c1e07d5b84b171db20bac601e9b529720f7299f8" +checksum = "78c2f43e8969d51935d2a7284878ae053ba30034cd563f673cde37ba5205685e" dependencies = [ "dtoa", "itoa", diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index e8f5673e7c4..06269f3c444 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -267,7 +267,7 @@ fn main() -> Result<(), Box> { } => { info!("Established connection to {:?} via {:?}", peer_id, endpoint); } - SwarmEvent::OutgoingConnectionError { peer_id, error } => { + SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => { info!("Outgoing connection error to {:?}: {:?}", peer_id, error); } _ => {} diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 4048dcb2184..49479bf81ed 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -329,7 +329,10 @@ impl EventLoop { } } SwarmEvent::IncomingConnectionError { .. } => {} - SwarmEvent::Dialing(peer_id) => eprintln!("Dialing {peer_id}"), + SwarmEvent::Dialing { + peer_id: Some(peer_id), + .. + } => eprintln!("Dialing {peer_id}"), e => panic!("{e:?}"), } } diff --git a/misc/metrics/CHANGELOG.md b/misc/metrics/CHANGELOG.md index ca090d60171..10f8dd07ead 100644 --- a/misc/metrics/CHANGELOG.md +++ b/misc/metrics/CHANGELOG.md @@ -22,7 +22,12 @@ - Raise MSRV to 1.65. See [PR 3715]. +- Replace `libp2p_swarm_connections_closed` `Counter` with `libp2p_swarm_connections_duration` `Histogram` which additionally tracks the duration of a connection. + Note that you can use the `_count` metric of the `Histogram` as a replacement for the `Counter`. + See [PR 3927]. + [PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715 +[PR 3927]: https://github.com/libp2p/rust-libp2p/pull/3927 [PR 3325]: https://github.com/libp2p/rust-libp2p/pull/3325 ## 0.12.0 diff --git a/misc/metrics/Cargo.toml b/misc/metrics/Cargo.toml index 78cb5b3fa2c..9126d5485e0 100644 --- a/misc/metrics/Cargo.toml +++ b/misc/metrics/Cargo.toml @@ -19,6 +19,7 @@ relay = ["libp2p-relay"] dcutr = ["libp2p-dcutr"] [dependencies] +instant = "0.1.11" libp2p-core = { workspace = true } libp2p-dcutr = { workspace = true, optional = true } libp2p-identify = { workspace = true, optional = true } @@ -27,7 +28,7 @@ libp2p-ping = { workspace = true, optional = true } libp2p-relay = { workspace = true, optional = true } libp2p-swarm = { workspace = true } libp2p-identity = { workspace = true } -prometheus-client = { version = "0.21.0" } +prometheus-client = { version = "0.21.1"} once_cell = "1.16.0" [target.'cfg(not(target_os = "unknown"))'.dependencies] diff --git a/misc/metrics/src/swarm.rs b/misc/metrics/src/swarm.rs index 50abb7a0c80..4aae2ab4fb3 100644 --- a/misc/metrics/src/swarm.rs +++ b/misc/metrics/src/swarm.rs @@ -18,20 +18,25 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; + use crate::protocol_stack; +use instant::Instant; +use libp2p_swarm::ConnectionId; use prometheus_client::encoding::{EncodeLabelSet, EncodeLabelValue}; use prometheus_client::metrics::counter::Counter; use prometheus_client::metrics::family::Family; use prometheus_client::metrics::histogram::{exponential_buckets, Histogram}; -use prometheus_client::registry::Registry; +use prometheus_client::registry::{Registry, Unit}; pub(crate) struct Metrics { connections_incoming: Family, connections_incoming_error: Family, - connections_established: Family, - connections_establishment_duration: Family, - connections_closed: Family, + connections_established: Family, + connections_establishment_duration: Family, + connections_duration: Family, new_listen_addr: Family, expired_listen_addr: Family, @@ -41,6 +46,8 @@ pub(crate) struct Metrics { dial_attempt: Counter, outgoing_connection_error: Family, + + connections: Arc>>, } impl Metrics { @@ -110,19 +117,26 @@ impl Metrics { connections_established.clone(), ); - let connections_closed = Family::default(); + let connections_establishment_duration = { + let constructor: fn() -> Histogram = + || Histogram::new(exponential_buckets(0.01, 1.5, 20)); + Family::new_with_constructor(constructor) + }; sub_registry.register( - "connections_closed", - "Number of connections closed", - connections_closed.clone(), + "connections_establishment_duration", + "Time it took (locally) to establish connections", + connections_establishment_duration.clone(), ); - let connections_establishment_duration = Family::new_with_constructor( - create_connection_establishment_duration_histogram as fn() -> Histogram, - ); - sub_registry.register( + let connections_duration = { + let constructor: fn() -> Histogram = + || Histogram::new(exponential_buckets(0.01, 3.0, 20)); + Family::new_with_constructor(constructor) + }; + sub_registry.register_with_unit( "connections_establishment_duration", "Time it took (locally) to establish connections", + Unit::Seconds, connections_establishment_duration.clone(), ); @@ -130,7 +144,6 @@ impl Metrics { connections_incoming, connections_incoming_error, connections_established, - connections_closed, new_listen_addr, expired_listen_addr, listener_closed, @@ -138,6 +151,8 @@ impl Metrics { dial_attempt, outgoing_connection_error, connections_establishment_duration, + connections_duration, + connections: Default::default(), } } } @@ -149,9 +164,10 @@ impl super::Recorder { - let labels = ConnectionEstablishedLabels { + let labels = ConnectionLabels { role: endpoint.into(), protocols: protocol_stack::as_string(endpoint.get_remote_address()), }; @@ -159,14 +175,33 @@ impl super::Recorder { - self.connections_closed - .get_or_create(&ConnectionClosedLabels { + libp2p_swarm::SwarmEvent::ConnectionClosed { + endpoint, + connection_id, + cause, + .. + } => { + let labels = ConnectionClosedLabels { + connection: ConnectionLabels { role: endpoint.into(), protocols: protocol_stack::as_string(endpoint.get_remote_address()), - }) - .inc(); + }, + cause: cause.as_ref().map(Into::into), + }; + self.connections_duration.get_or_create(&labels).observe( + self.connections + .lock() + .expect("lock not to be poisoned") + .remove(connection_id) + .expect("closed connection to previously be established") + .elapsed() + .as_secs_f64(), + ); } libp2p_swarm::SwarmEvent::IncomingConnection { send_back_addr, .. } => { self.connections_incoming @@ -187,7 +222,7 @@ impl super::Recorder { + libp2p_swarm::SwarmEvent::OutgoingConnectionError { error, peer_id, .. } => { let peer = match peer_id { Some(_) => PeerStatus::Known, None => PeerStatus::Unknown, @@ -261,7 +296,7 @@ impl super::Recorder { self.listener_error.inc(); } - libp2p_swarm::SwarmEvent::Dialing(_) => { + libp2p_swarm::SwarmEvent::Dialing { .. } => { self.dial_attempt.inc(); } } @@ -269,17 +304,33 @@ impl super::Recorder, + #[prometheus(flatten)] + connection: ConnectionLabels, +} + +#[derive(EncodeLabelValue, Hash, Clone, Eq, PartialEq, Debug)] +enum ConnectionError { + Io, + KeepAliveTimeout, + Handler, +} + +impl From<&libp2p_swarm::ConnectionError> for ConnectionError { + fn from(value: &libp2p_swarm::ConnectionError) -> Self { + match value { + libp2p_swarm::ConnectionError::IO(_) => ConnectionError::Io, + libp2p_swarm::ConnectionError::KeepAliveTimeout => ConnectionError::KeepAliveTimeout, + libp2p_swarm::ConnectionError::Handler(_) => ConnectionError::Handler, + } + } } #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] @@ -359,7 +410,3 @@ impl From<&libp2p_swarm::ListenError> for IncomingConnectionError { } } } - -fn create_connection_establishment_duration_histogram() -> Histogram { - Histogram::new(exponential_buckets(0.01, 1.5, 20)) -} diff --git a/protocols/autonat/tests/test_server.rs b/protocols/autonat/tests/test_server.rs index 319fd84865d..5f6a9a269d4 100644 --- a/protocols/autonat/tests/test_server.rs +++ b/protocols/autonat/tests/test_server.rs @@ -96,6 +96,7 @@ async fn test_dial_back() { num_established, concurrent_dial_errors, established_in: _, + connection_id: _, } => { assert_eq!(peer_id, client_id); assert_eq!(num_established, NonZeroU32::new(2).unwrap()); @@ -103,7 +104,10 @@ async fn test_dial_back() { assert_eq!(address, expect_addr); break; } - SwarmEvent::Dialing(peer) => assert_eq!(peer, client_id), + SwarmEvent::Dialing { + peer_id: Some(peer), + .. + } => assert_eq!(peer, client_id), SwarmEvent::NewListenAddr { .. } | SwarmEvent::ExpiredListenAddr { .. } => {} other => panic!("Unexpected swarm event: {other:?}."), } @@ -143,12 +147,15 @@ async fn test_dial_error() { loop { match server.next_swarm_event().await { - SwarmEvent::OutgoingConnectionError { peer_id, error } => { + SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => { assert_eq!(peer_id.unwrap(), client_id); assert!(matches!(error, DialError::Transport(_))); break; } - SwarmEvent::Dialing(peer) => assert_eq!(peer, client_id), + SwarmEvent::Dialing { + peer_id: Some(peer), + .. + } => assert_eq!(peer, client_id), SwarmEvent::NewListenAddr { .. } | SwarmEvent::ExpiredListenAddr { .. } => {} other => panic!("Unexpected swarm event: {other:?}."), } @@ -307,7 +314,10 @@ async fn test_dial_multiple_addr() { assert_eq!(address, dial_addresses[1]); break; } - SwarmEvent::Dialing(peer) => assert_eq!(peer, client_id), + SwarmEvent::Dialing { + peer_id: Some(peer), + .. + } => assert_eq!(peer, client_id), SwarmEvent::NewListenAddr { .. } | SwarmEvent::ExpiredListenAddr { .. } => {} other => panic!("Unexpected swarm event: {other:?}."), } diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index 5c5fdbb8384..377f65fbc2e 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -193,7 +193,10 @@ async fn wait_for_reservation( break; } } - SwarmEvent::Dialing(peer_id) if peer_id == relay_peer_id => {} + SwarmEvent::Dialing { + peer_id: Some(peer_id), + .. + } if peer_id == relay_peer_id => {} SwarmEvent::ConnectionEstablished { peer_id, .. } if peer_id == relay_peer_id => {} e => panic!("{e:?}"), } diff --git a/protocols/perf/src/bin/perf-client.rs b/protocols/perf/src/bin/perf-client.rs index ddf3708ef5c..0b9a3d96ab6 100644 --- a/protocols/perf/src/bin/perf-client.rs +++ b/protocols/perf/src/bin/perf-client.rs @@ -86,7 +86,7 @@ async fn main() -> Result<()> { let server_peer_id = loop { match swarm.next().await.unwrap() { SwarmEvent::ConnectionEstablished { peer_id, .. } => break peer_id, - SwarmEvent::OutgoingConnectionError { peer_id, error } => { + SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => { bail!("Outgoing connection error to {:?}: {:?}", peer_id, error); } e => panic!("{e:?}"), @@ -113,7 +113,7 @@ async fn main() -> Result<()> { } => { info!("Established connection to {:?} via {:?}", peer_id, endpoint); } - SwarmEvent::OutgoingConnectionError { peer_id, error } => { + SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => { info!("Outgoing connection error to {:?}: {:?}", peer_id, error); } SwarmEvent::Behaviour(libp2p_perf::client::Event { id: _, result }) => break result?, diff --git a/protocols/perf/tests/lib.rs b/protocols/perf/tests/lib.rs index 1d93ce3ee8d..facde7d808d 100644 --- a/protocols/perf/tests/lib.rs +++ b/protocols/perf/tests/lib.rs @@ -53,7 +53,7 @@ async fn perf() { .wait(|e| match e { SwarmEvent::IncomingConnection { .. } => panic!(), SwarmEvent::ConnectionEstablished { .. } => None, - SwarmEvent::Dialing(_) => None, + SwarmEvent::Dialing { .. } => None, SwarmEvent::Behaviour(client::Event { result, .. }) => Some(result), e => panic!("{e:?}"), }) diff --git a/protocols/relay/tests/lib.rs b/protocols/relay/tests/lib.rs index 2103893ba12..f3cb950c3c9 100644 --- a/protocols/relay/tests/lib.rs +++ b/protocols/relay/tests/lib.rs @@ -222,7 +222,10 @@ async fn connection_established_to( ) { loop { match swarm.select_next_some().await { - SwarmEvent::Dialing(peer_id) if peer_id == relay_peer_id => {} + SwarmEvent::Dialing { + peer_id: Some(peer_id), + .. + } if peer_id == relay_peer_id => {} SwarmEvent::ConnectionEstablished { peer_id, .. } if peer_id == relay_peer_id => {} SwarmEvent::Behaviour(ClientEvent::Ping(ping::Event { peer, .. })) if peer == other => { break @@ -419,7 +422,10 @@ async fn wait_for_reservation( async fn wait_for_dial(client: &mut Swarm, remote: PeerId) -> bool { loop { match client.select_next_some().await { - SwarmEvent::Dialing(peer_id) if peer_id == remote => {} + SwarmEvent::Dialing { + peer_id: Some(peer_id), + .. + } if peer_id == remote => {} SwarmEvent::ConnectionEstablished { peer_id, .. } if peer_id == remote => return true, SwarmEvent::OutgoingConnectionError { peer_id, .. } if peer_id == Some(remote) => { return false diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index 1284f57cffa..8a7ce3707db 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -50,6 +50,10 @@ - Remove deprecated `NetworkBehaviourAction` type. See [PR 3919]. +- Expose `ConnectionId` on `SwarmEvent::{ConnectionEstablished,ConnectionClosed,IncomingConnection,IncomingConnectionError,OutgoingConnectionError,Dialing}`. + Also emit `SwarmEvent::Dialing` for dials with unknown `PeerId`. + See [PR 3927]. + - Rename `ConnectionHandlerEvent::Custom` to `ConnectionHandlerEvent::NotifyBehaviour`. See [PR 3955]. [PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605 @@ -64,6 +68,7 @@ [PR 3886]: https://github.com/libp2p/rust-libp2p/pull/3886 [PR 3912]: https://github.com/libp2p/rust-libp2p/pull/3912 [PR 3919]: https://github.com/libp2p/rust-libp2p/pull/3919 +[PR 3927]: https://github.com/libp2p/rust-libp2p/pull/3927 [PR 3955]: https://github.com/libp2p/rust-libp2p/pull/3955 ## 0.42.2 diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index f0f5f07cb97..0f2f3fc1093 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -187,6 +187,8 @@ pub enum SwarmEvent { ConnectionEstablished { /// Identity of the peer that we have connected to. peer_id: PeerId, + /// Identifier of the connection. + connection_id: ConnectionId, /// Endpoint of the connection that has been opened. endpoint: ConnectedPoint, /// Number of established connections to this peer, including the one that has just been @@ -204,6 +206,8 @@ pub enum SwarmEvent { ConnectionClosed { /// Identity of the peer that we have connected to. peer_id: PeerId, + /// Identifier of the connection. + connection_id: ConnectionId, /// Endpoint of the connection that has been closed. endpoint: ConnectedPoint, /// Number of other remaining connections to this same peer. @@ -218,6 +222,8 @@ pub enum SwarmEvent { /// [`IncomingConnectionError`](SwarmEvent::IncomingConnectionError) event will later be /// generated for this connection. IncomingConnection { + /// Identifier of the connection. + connection_id: ConnectionId, /// Local connection address. /// This address has been earlier reported with a [`NewListenAddr`](SwarmEvent::NewListenAddr) /// event. @@ -230,6 +236,8 @@ pub enum SwarmEvent { /// This can include, for example, an error during the handshake of the encryption layer, or /// the connection unexpectedly closed. IncomingConnectionError { + /// Identifier of the connection. + connection_id: ConnectionId, /// Local connection address. /// This address has been earlier reported with a [`NewListenAddr`](SwarmEvent::NewListenAddr) /// event. @@ -241,6 +249,8 @@ pub enum SwarmEvent { }, /// An error happened on an outbound connection. OutgoingConnectionError { + /// Identifier of the connection. + connection_id: ConnectionId, /// If known, [`PeerId`] of the peer we tried to reach. peer_id: Option, /// Error that has been encountered. @@ -286,7 +296,13 @@ pub enum SwarmEvent { /// reported if the dialing attempt succeeds, otherwise a /// [`OutgoingConnectionError`](SwarmEvent::OutgoingConnectionError) event /// is reported. - Dialing(PeerId), + Dialing { + /// Identity of the peer that we are connecting to. + peer_id: Option, + + /// Identifier of the connection. + connection_id: ConnectionId, + }, } impl SwarmEvent { @@ -773,6 +789,7 @@ where return Some(SwarmEvent::OutgoingConnectionError { peer_id: Some(peer_id), + connection_id: id, error: dial_error, }); } @@ -801,6 +818,7 @@ where )); return Some(SwarmEvent::IncomingConnectionError { + connection_id: id, send_back_addr, local_addr, error: listen_error, @@ -856,6 +874,7 @@ where self.supported_protocols = supported_protocols; return Some(SwarmEvent::ConnectionEstablished { peer_id, + connection_id: id, num_established, endpoint, concurrent_dial_errors, @@ -884,6 +903,7 @@ where return Some(SwarmEvent::OutgoingConnectionError { peer_id: peer, + connection_id, error, }); } @@ -904,6 +924,7 @@ where connection_id: id, })); return Some(SwarmEvent::IncomingConnectionError { + connection_id: id, local_addr, send_back_addr, error, @@ -946,6 +967,7 @@ where })); return Some(SwarmEvent::ConnectionClosed { peer_id, + connection_id: id, endpoint, cause: error, num_established, @@ -1008,6 +1030,7 @@ where })); return Some(SwarmEvent::IncomingConnectionError { + connection_id, local_addr, send_back_addr, error: listen_error, @@ -1025,6 +1048,7 @@ where ); Some(SwarmEvent::IncomingConnection { + connection_id, local_addr, send_back_addr, }) @@ -1111,10 +1135,12 @@ where ToSwarm::GenerateEvent(event) => return Some(SwarmEvent::Behaviour(event)), ToSwarm::Dial { opts } => { let peer_id = opts.get_or_parse_peer_id(); + let connection_id = opts.connection_id(); if let Ok(()) = self.dial(opts) { - if let Ok(Some(peer_id)) = peer_id { - return Some(SwarmEvent::Dialing(peer_id)); - } + return Some(SwarmEvent::Dialing { + peer_id: peer_id.ok().flatten(), + connection_id, + }); } } ToSwarm::NotifyHandler { @@ -2432,6 +2458,7 @@ mod tests { peer_id, // multiaddr, error: DialError::Transport(errors), + .. } => { assert_eq!(target, peer_id.unwrap()); From b3fa954d4bd9c3f2943bee9ec9cb3e11d09eb7c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:08:56 +0000 Subject: [PATCH 32/38] deps: bump libc from 0.2.143 to 0.2.144 Pull-Request: #3932. --- Cargo.lock | 4 ++-- transports/tcp/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc9d5e1bfe6..e7b3c2993b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2348,9 +2348,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.143" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libm" diff --git a/transports/tcp/Cargo.toml b/transports/tcp/Cargo.toml index 59eac1e9327..1ed5813c11a 100644 --- a/transports/tcp/Cargo.toml +++ b/transports/tcp/Cargo.toml @@ -15,7 +15,7 @@ async-io = { version = "1.13.0", optional = true } futures = "0.3.28" futures-timer = "3.0" if-watch = "3.0.1" -libc = "0.2.143" +libc = "0.2.144" libp2p-core = { workspace = true } libp2p-identity = { workspace = true } log = "0.4.11" From 2651e197e6febedc1cf3d2bc86fcaa49945f851c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:28:46 +0000 Subject: [PATCH 33/38] deps: bump proc-macro2 from 1.0.56 to 1.0.57 Pull-Request: #3946. --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7b3c2993b9..b3dc9cd3b18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3992,9 +3992,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" dependencies = [ "unicode-ident", ] From 74fa48b43fd47474cc5f461b04bce92aaf75493f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 15:47:10 +0000 Subject: [PATCH 34/38] deps: bump tokio from 1.28.0 to 1.28.1 Pull-Request: #3931. --- Cargo.lock | 4 ++-- interop-tests/Cargo.toml | 2 +- transports/pnet/Cargo.toml | 2 +- transports/quic/Cargo.toml | 4 ++-- transports/tcp/Cargo.toml | 4 ++-- transports/tls/Cargo.toml | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3dc9cd3b18..a46a8bc50b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5059,9 +5059,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.28.0" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg", "bytes", diff --git a/interop-tests/Cargo.toml b/interop-tests/Cargo.toml index 22b825efc91..2cd4084b1d6 100644 --- a/interop-tests/Cargo.toml +++ b/interop-tests/Cargo.toml @@ -17,4 +17,4 @@ libp2p-mplex = { path = "../muxers/mplex" } log = "0.4" rand = "0.8.5" redis = { version = "0.23.0", default-features = false, features = ["tokio-comp"] } -tokio = { version = "1.28.0", features = ["full"] } +tokio = { version = "1.28.1", features = ["full"] } diff --git a/transports/pnet/Cargo.toml b/transports/pnet/Cargo.toml index da5c55b538f..36c841e93b2 100644 --- a/transports/pnet/Cargo.toml +++ b/transports/pnet/Cargo.toml @@ -27,7 +27,7 @@ libp2p-tcp = { workspace = true, features = ["tokio"] } libp2p-websocket = { workspace = true } libp2p-yamux = { workspace = true } quickcheck = { workspace = true } -tokio = { version = "1.28.0", features = ["full"] } +tokio = { version = "1.28.1", features = ["full"] } # Passing arguments to the docsrs builder in order to properly document cfg's. # More information: https://docs.rs/about/builds#cross-compiling diff --git a/transports/quic/Cargo.toml b/transports/quic/Cargo.toml index 1b491ce0c37..d4f81b63d94 100644 --- a/transports/quic/Cargo.toml +++ b/transports/quic/Cargo.toml @@ -23,7 +23,7 @@ quinn-proto = { version = "0.9.3", default-features = false, features = ["tls-ru rand = "0.8.5" rustls = { version = "0.20.2", default-features = false } thiserror = "1.0.40" -tokio = { version = "1.28.0", default-features = false, features = ["net", "rt"], optional = true } +tokio = { version = "1.28.1", default-features = false, features = ["net", "rt"], optional = true } [features] tokio = ["dep:tokio", "if-watch/tokio"] @@ -44,7 +44,7 @@ libp2p-noise = { workspace = true } libp2p-tcp = { workspace = true, features = ["async-io"] } libp2p-yamux = { workspace = true } quickcheck = "1" -tokio = { version = "1.28.0", features = ["macros", "rt-multi-thread", "time"] } +tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread", "time"] } [[test]] name = "stream_compliance" diff --git a/transports/tcp/Cargo.toml b/transports/tcp/Cargo.toml index 1ed5813c11a..93b034905e5 100644 --- a/transports/tcp/Cargo.toml +++ b/transports/tcp/Cargo.toml @@ -20,7 +20,7 @@ libp2p-core = { workspace = true } libp2p-identity = { workspace = true } log = "0.4.11" socket2 = { version = "0.5.3", features = ["all"] } -tokio = { version = "1.28.0", default-features = false, features = ["net"], optional = true } +tokio = { version = "1.28.1", default-features = false, features = ["net"], optional = true } [features] tokio = ["dep:tokio", "if-watch/tokio"] @@ -28,7 +28,7 @@ async-io = ["dep:async-io", "if-watch/smol"] [dev-dependencies] async-std = { version = "1.6.5", features = ["attributes"] } -tokio = { version = "1.28.0", default-features = false, features = ["full"] } +tokio = { version = "1.28.1", default-features = false, features = ["full"] } env_logger = "0.10.0" # Passing arguments to the docsrs builder in order to properly document cfg's. diff --git a/transports/tls/Cargo.toml b/transports/tls/Cargo.toml index f7cfc01444c..b03723dd344 100644 --- a/transports/tls/Cargo.toml +++ b/transports/tls/Cargo.toml @@ -33,7 +33,7 @@ libp2p-core = { workspace = true } libp2p-identity = { workspace = true, features = ["ed25519", "rsa", "secp256k1", "ecdsa"] } libp2p-swarm = { workspace = true } libp2p-yamux = { workspace = true } -tokio = { version = "1.28.0", features = ["full"] } +tokio = { version = "1.28.1", features = ["full"] } # Passing arguments to the docsrs builder in order to properly document cfg's. # More information: https://docs.rs/about/builds#cross-compiling From a2ad916bc4d071dcda6d67483f9c8e798f4195c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 May 2023 16:05:23 +0000 Subject: [PATCH 35/38] deps: bump wasm-bindgen from 0.2.85 to 0.2.86 Pull-Request: #3961. --- Cargo.lock | 20 ++++++++++---------- transports/wasm-ext/Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a46a8bc50b5..eaa3b29d347 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5426,9 +5426,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -5436,9 +5436,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", @@ -5463,9 +5463,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5473,9 +5473,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", @@ -5486,9 +5486,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.85" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "wasm-timer" diff --git a/transports/wasm-ext/Cargo.toml b/transports/wasm-ext/Cargo.toml index ff4efb610e0..56afae87028 100644 --- a/transports/wasm-ext/Cargo.toml +++ b/transports/wasm-ext/Cargo.toml @@ -15,7 +15,7 @@ futures = "0.3.28" js-sys = "0.3.62" libp2p-core = { workspace = true } parity-send-wrapper = "0.1.0" -wasm-bindgen = "0.2.42" +wasm-bindgen = "0.2.86" wasm-bindgen-futures = "0.4.35" [features] From b655e84d06789628f4a42979f6f81dcf462274f2 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Thu, 18 May 2023 20:44:25 +0200 Subject: [PATCH 36/38] refactor(dcutr): fix typo in `observed_addreses` Pull-Request: #3962. --- protocols/dcutr/src/behaviour_impl.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 5b89f2ef2c2..57692d38898 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -98,7 +98,7 @@ impl Behaviour { } } - fn observed_addreses(&self) -> Vec { + fn observed_addresses(&self) -> Vec { self.external_addresses .iter() .cloned() @@ -132,7 +132,7 @@ impl Behaviour { peer_id, handler: NotifyHandler::One(connection_id), event: Either::Left(handler::relayed::Command::Connect { - obs_addrs: self.observed_addreses(), + obs_addrs: self.observed_addresses(), }), }, ToSwarm::GenerateEvent(Event::InitiatedDirectConnectionUpgrade { @@ -189,7 +189,7 @@ impl Behaviour { handler: NotifyHandler::One(relayed_connection_id), peer_id, event: Either::Left(handler::relayed::Command::Connect { - obs_addrs: self.observed_addreses(), + obs_addrs: self.observed_addresses(), }), }) } else { @@ -339,7 +339,7 @@ impl NetworkBehaviour for Behaviour { peer_id: event_source, event: Either::Left(handler::relayed::Command::AcceptInboundConnect { inbound_connect, - obs_addrs: self.observed_addreses(), + obs_addrs: self.observed_addresses(), }), }, ToSwarm::GenerateEvent(Event::RemoteInitiatedDirectConnectionUpgrade { From c224ffe01266e33101b609c10772fc116f7cf929 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 19 May 2023 01:13:16 +0200 Subject: [PATCH 37/38] feat(kad): Remove `TUserData` and replace with `QueryId` Kademlia `ConnectionHandler` used a generic `TUserData` that is replaced by `QueryId` always used in practice. Resolves #3607. Pull-Request: #3959. --- protocols/kad/src/behaviour.rs | 54 +++++----- protocols/kad/src/handler.rs | 173 ++++++++++++++------------------- 2 files changed, 99 insertions(+), 128 deletions(-) diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index 856a994056a..5d6a20fd859 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -103,7 +103,7 @@ pub struct Kademlia { connection_idle_timeout: Duration, /// Queued events to return when the behaviour is being polled. - queued_events: VecDeque>>, + queued_events: VecDeque>, listen_addresses: ListenAddresses, @@ -1959,7 +1959,7 @@ impl NetworkBehaviour for Kademlia where TStore: RecordStore + Send + 'static, { - type ConnectionHandler = KademliaHandler; + type ConnectionHandler = KademliaHandler; type ToSwarm = KademliaEvent; fn handle_established_inbound_connection( @@ -2081,9 +2081,9 @@ where KademliaHandlerEvent::FindNodeRes { closer_peers, - user_data, + query_id, } => { - self.discovered(&user_data, &source, closer_peers.iter()); + self.discovered(&query_id, &source, closer_peers.iter()); } KademliaHandlerEvent::GetProvidersReq { key, request_id } => { @@ -2113,11 +2113,11 @@ where KademliaHandlerEvent::GetProvidersRes { closer_peers, provider_peers, - user_data, + query_id, } => { let peers = closer_peers.iter().chain(provider_peers.iter()); - self.discovered(&user_data, &source, peers); - if let Some(query) = self.queries.get_mut(&user_data) { + self.discovered(&query_id, &source, peers); + if let Some(query) = self.queries.get_mut(&query_id) { let stats = query.stats().clone(); if let QueryInfo::GetProviders { ref key, @@ -2131,7 +2131,7 @@ where self.queued_events.push_back(ToSwarm::GenerateEvent( KademliaEvent::OutboundQueryProgressed { - id: user_data, + id: query_id, result: QueryResult::GetProviders(Ok( GetProvidersOk::FoundProviders { key: key.clone(), @@ -2147,16 +2147,16 @@ where } } - KademliaHandlerEvent::QueryError { user_data, error } => { + KademliaHandlerEvent::QueryError { query_id, error } => { log::debug!( "Request to {:?} in query {:?} failed with {:?}", source, - user_data, + query_id, error ); // If the query to which the error relates is still active, // signal the failure w.r.t. `source`. - if let Some(query) = self.queries.get_mut(&user_data) { + if let Some(query) = self.queries.get_mut(&query_id) { query.on_failure(&source) } } @@ -2209,9 +2209,9 @@ where KademliaHandlerEvent::GetRecordRes { record, closer_peers, - user_data, + query_id, } => { - if let Some(query) = self.queries.get_mut(&user_data) { + if let Some(query) = self.queries.get_mut(&query_id) { let stats = query.stats().clone(); if let QueryInfo::GetRecord { key, @@ -2229,7 +2229,7 @@ where self.queued_events.push_back(ToSwarm::GenerateEvent( KademliaEvent::OutboundQueryProgressed { - id: user_data, + id: query_id, result: QueryResult::GetRecord(Ok(GetRecordOk::FoundRecord( record, ))), @@ -2258,15 +2258,15 @@ where } } - self.discovered(&user_data, &source, closer_peers.iter()); + self.discovered(&query_id, &source, closer_peers.iter()); } KademliaHandlerEvent::PutRecord { record, request_id } => { self.record_received(source, connection, request_id, record); } - KademliaHandlerEvent::PutRecordRes { user_data, .. } => { - if let Some(query) = self.queries.get_mut(&user_data) { + KademliaHandlerEvent::PutRecordRes { query_id, .. } => { + if let Some(query) = self.queries.get_mut(&query_id) { query.on_success(&source, vec![]); if let QueryInfo::PutRecord { phase: PutRecordPhase::PutRecord { success, .. }, @@ -2284,7 +2284,7 @@ where debug!( "PutRecord query ({:?}) reached quorum ({}/{}) with response \ from peer {} but could not yet finish.", - user_data, + query_id, peers.len(), quorum, source, @@ -2907,7 +2907,7 @@ struct QueryInner { /// /// A request is pending if the targeted peer is not currently connected /// and these requests are sent as soon as a connection to the peer is established. - pending_rpcs: SmallVec<[(PeerId, KademliaHandlerIn); K_VALUE.get()]>, + pending_rpcs: SmallVec<[(PeerId, KademliaHandlerIn); K_VALUE.get()]>, } impl QueryInner { @@ -3019,24 +3019,24 @@ pub enum QueryInfo { impl QueryInfo { /// Creates an event for a handler to issue an outgoing request in the /// context of a query. - fn to_request(&self, query_id: QueryId) -> KademliaHandlerIn { + fn to_request(&self, query_id: QueryId) -> KademliaHandlerIn { match &self { QueryInfo::Bootstrap { peer, .. } => KademliaHandlerIn::FindNodeReq { key: peer.to_bytes(), - user_data: query_id, + query_id, }, QueryInfo::GetClosestPeers { key, .. } => KademliaHandlerIn::FindNodeReq { key: key.clone(), - user_data: query_id, + query_id, }, QueryInfo::GetProviders { key, .. } => KademliaHandlerIn::GetProvidersReq { key: key.clone(), - user_data: query_id, + query_id, }, QueryInfo::AddProvider { key, phase, .. } => match phase { AddProviderPhase::GetClosestPeers => KademliaHandlerIn::FindNodeReq { key: key.to_vec(), - user_data: query_id, + query_id, }, AddProviderPhase::AddProvider { provider_id, @@ -3053,16 +3053,16 @@ impl QueryInfo { }, QueryInfo::GetRecord { key, .. } => KademliaHandlerIn::GetRecord { key: key.clone(), - user_data: query_id, + query_id, }, QueryInfo::PutRecord { record, phase, .. } => match phase { PutRecordPhase::GetClosestPeers => KademliaHandlerIn::FindNodeReq { key: record.key.to_vec(), - user_data: query_id, + query_id, }, PutRecordPhase::PutRecord { .. } => KademliaHandlerIn::PutRecord { record: record.clone(), - user_data: query_id, + query_id, }, }, } diff --git a/protocols/kad/src/handler.rs b/protocols/kad/src/handler.rs index 99535e083f2..a874b466286 100644 --- a/protocols/kad/src/handler.rs +++ b/protocols/kad/src/handler.rs @@ -23,6 +23,7 @@ use crate::protocol::{ KademliaProtocolConfig, }; use crate::record_priv::{self, Record}; +use crate::QueryId; use either::Either; use futures::prelude::*; use futures::stream::SelectAll; @@ -52,7 +53,7 @@ const MAX_NUM_SUBSTREAMS: usize = 32; /// make. /// /// It also handles requests made by the remote. -pub struct KademliaHandler { +pub struct KademliaHandler { /// Configuration for the Kademlia protocol. config: KademliaHandlerConfig, @@ -60,17 +61,17 @@ pub struct KademliaHandler { next_connec_unique_id: UniqueConnecId, /// List of active outbound substreams with the state they are in. - outbound_substreams: SelectAll>, + outbound_substreams: SelectAll, /// Number of outbound streams being upgraded right now. num_requested_outbound_streams: usize, /// List of outbound substreams that are waiting to become active next. /// Contains the request we want to send, and the user data if we expect an answer. - pending_messages: VecDeque<(KadRequestMsg, Option)>, + pending_messages: VecDeque<(KadRequestMsg, Option)>, /// List of active inbound substreams with the state they are in. - inbound_substreams: SelectAll>, + inbound_substreams: SelectAll, /// Until when to keep the connection alive. keep_alive: KeepAlive, @@ -114,16 +115,16 @@ pub struct KademliaHandlerConfig { } /// State of an active outbound substream. -enum OutboundSubstreamState { +enum OutboundSubstreamState { /// Waiting to send a message to the remote. - PendingSend(KadOutStreamSink, KadRequestMsg, Option), + PendingSend(KadOutStreamSink, KadRequestMsg, Option), /// Waiting to flush the substream so that the data arrives to the remote. - PendingFlush(KadOutStreamSink, Option), + PendingFlush(KadOutStreamSink, Option), /// Waiting for an answer back from the remote. // TODO: add timeout - WaitingAnswer(KadOutStreamSink, TUserData), + WaitingAnswer(KadOutStreamSink, QueryId), /// An error happened on the substream and we should report the error to the user. - ReportError(KademliaHandlerQueryErr, TUserData), + ReportError(KademliaHandlerQueryErr, QueryId), /// The substream is being closed. Closing(KadOutStreamSink), /// The substream is complete and will not perform any more work. @@ -132,7 +133,7 @@ enum OutboundSubstreamState { } /// State of an active inbound substream. -enum InboundSubstreamState { +enum InboundSubstreamState { /// Waiting for a request from the remote. WaitingMessage { /// Whether it is the first message to be awaited on this stream. @@ -152,11 +153,11 @@ enum InboundSubstreamState { Cancelled, Poisoned { - phantom: PhantomData, + phantom: PhantomData, }, } -impl InboundSubstreamState { +impl InboundSubstreamState { fn try_answer_with( &mut self, id: KademliaRequestId, @@ -211,7 +212,7 @@ impl InboundSubstreamState { /// Event produced by the Kademlia handler. #[derive(Debug)] -pub enum KademliaHandlerEvent { +pub enum KademliaHandlerEvent { /// The configured protocol name has been confirmed by the peer through /// a successfully negotiated substream. /// @@ -235,7 +236,7 @@ pub enum KademliaHandlerEvent { /// Results of the request. closer_peers: Vec, /// The user data passed to the `FindNodeReq`. - user_data: TUserData, + query_id: QueryId, }, /// Same as `FindNodeReq`, but should also return the entries of the local providers list for @@ -254,7 +255,7 @@ pub enum KademliaHandlerEvent { /// Known providers for this key. provider_peers: Vec, /// The user data passed to the `GetProvidersReq`. - user_data: TUserData, + query_id: QueryId, }, /// An error happened when performing a query. @@ -262,7 +263,7 @@ pub enum KademliaHandlerEvent { /// The error that happened. error: KademliaHandlerQueryErr, /// The user data passed to the query. - user_data: TUserData, + query_id: QueryId, }, /// The peer announced itself as a provider of a key. @@ -288,7 +289,7 @@ pub enum KademliaHandlerEvent { /// Nodes closest to the key. closer_peers: Vec, /// The user data passed to the `GetValue`. - user_data: TUserData, + query_id: QueryId, }, /// Request to put a value in the dht records @@ -305,7 +306,7 @@ pub enum KademliaHandlerEvent { /// The value of the stored record. value: Vec, /// The user data passed to the `PutValue`. - user_data: TUserData, + query_id: QueryId, }, } @@ -357,7 +358,7 @@ impl From> for KademliaHandlerQueryErr { /// Event to send to the handler. #[derive(Debug)] -pub enum KademliaHandlerIn { +pub enum KademliaHandlerIn { /// Resets the (sub)stream associated with the given request ID, /// thus signaling an error to the remote. /// @@ -373,7 +374,7 @@ pub enum KademliaHandlerIn { /// Identifier of the node. key: Vec, /// Custom user data. Passed back in the out event when the results arrive. - user_data: TUserData, + query_id: QueryId, }, /// Response to a `FindNodeReq`. @@ -392,7 +393,7 @@ pub enum KademliaHandlerIn { /// Identifier being searched. key: record_priv::Key, /// Custom user data. Passed back in the out event when the results arrive. - user_data: TUserData, + query_id: QueryId, }, /// Response to a `GetProvidersReq`. @@ -423,7 +424,7 @@ pub enum KademliaHandlerIn { /// The key of the record. key: record_priv::Key, /// Custom data. Passed back in the out event when the results arrive. - user_data: TUserData, + query_id: QueryId, }, /// Response to a `GetRecord` request. @@ -440,7 +441,7 @@ pub enum KademliaHandlerIn { PutRecord { record: Record, /// Custom data. Passed back in the out event when the results arrive. - user_data: TUserData, + query_id: QueryId, }, /// Response to a `PutRecord`. @@ -466,10 +467,7 @@ pub struct KademliaRequestId { #[derive(Debug, Copy, Clone, PartialEq, Eq)] struct UniqueConnecId(u64); -impl KademliaHandler -where - TUserData: Clone + fmt::Debug + Send + 'static + Unpin, -{ +impl KademliaHandler { /// Create a [`KademliaHandler`] using the given configuration. pub fn new( config: KademliaHandlerConfig, @@ -499,11 +497,9 @@ where ::OutboundOpenInfo, >, ) { - if let Some((msg, user_data)) = self.pending_messages.pop_front() { + if let Some((msg, query_id)) = self.pending_messages.pop_front() { self.outbound_substreams - .push(OutboundSubstreamState::PendingSend( - protocol, msg, user_data, - )); + .push(OutboundSubstreamState::PendingSend(protocol, msg, query_id)); } else { debug_assert!(false, "Requested outbound stream without message") } @@ -586,21 +582,18 @@ where // TODO: cache the fact that the remote doesn't support kademlia at all, so that we don't // continue trying - if let Some((_, Some(user_data))) = self.pending_messages.pop_front() { + if let Some((_, Some(query_id))) = self.pending_messages.pop_front() { self.outbound_substreams - .push(OutboundSubstreamState::ReportError(error.into(), user_data)); + .push(OutboundSubstreamState::ReportError(error.into(), query_id)); } self.num_requested_outbound_streams -= 1; } } -impl ConnectionHandler for KademliaHandler -where - TUserData: Clone + fmt::Debug + Send + 'static + Unpin, -{ - type FromBehaviour = KademliaHandlerIn; - type ToBehaviour = KademliaHandlerEvent; +impl ConnectionHandler for KademliaHandler { + type FromBehaviour = KademliaHandlerIn; + type ToBehaviour = KademliaHandlerEvent; type Error = io::Error; // TODO: better error type? type InboundProtocol = Either; type OutboundProtocol = KademliaProtocolConfig; @@ -616,7 +609,7 @@ where } } - fn on_behaviour_event(&mut self, message: KademliaHandlerIn) { + fn on_behaviour_event(&mut self, message: KademliaHandlerIn) { match message { KademliaHandlerIn::Reset(request_id) => { if let Some(state) = self @@ -632,17 +625,17 @@ where state.close(); } } - KademliaHandlerIn::FindNodeReq { key, user_data } => { + KademliaHandlerIn::FindNodeReq { key, query_id } => { let msg = KadRequestMsg::FindNode { key }; - self.pending_messages.push_back((msg, Some(user_data))); + self.pending_messages.push_back((msg, Some(query_id))); } KademliaHandlerIn::FindNodeRes { closer_peers, request_id, } => self.answer_pending_request(request_id, KadResponseMsg::FindNode { closer_peers }), - KademliaHandlerIn::GetProvidersReq { key, user_data } => { + KademliaHandlerIn::GetProvidersReq { key, query_id } => { let msg = KadRequestMsg::GetProviders { key }; - self.pending_messages.push_back((msg, Some(user_data))); + self.pending_messages.push_back((msg, Some(query_id))); } KademliaHandlerIn::GetProvidersRes { closer_peers, @@ -659,13 +652,13 @@ where let msg = KadRequestMsg::AddProvider { key, provider }; self.pending_messages.push_back((msg, None)); } - KademliaHandlerIn::GetRecord { key, user_data } => { + KademliaHandlerIn::GetRecord { key, query_id } => { let msg = KadRequestMsg::GetValue { key }; - self.pending_messages.push_back((msg, Some(user_data))); + self.pending_messages.push_back((msg, Some(query_id))); } - KademliaHandlerIn::PutRecord { record, user_data } => { + KademliaHandlerIn::PutRecord { record, query_id } => { let msg = KadRequestMsg::PutValue { record }; - self.pending_messages.push_back((msg, Some(user_data))); + self.pending_messages.push_back((msg, Some(query_id))); } KademliaHandlerIn::GetRecordRes { record, @@ -773,10 +766,7 @@ where } } -impl KademliaHandler -where - TUserData: 'static + Clone + Send + Unpin + fmt::Debug, -{ +impl KademliaHandler { fn answer_pending_request(&mut self, request_id: KademliaRequestId, mut msg: KadResponseMsg) { for state in self.inbound_substreams.iter_mut() { match state.try_answer_with(request_id, msg) { @@ -801,35 +791,27 @@ impl Default for KademliaHandlerConfig { } } -impl futures::Stream for OutboundSubstreamState -where - TUserData: Unpin, -{ - type Item = ConnectionHandlerEvent< - KademliaProtocolConfig, - (), - KademliaHandlerEvent, - io::Error, - >; +impl futures::Stream for OutboundSubstreamState { + type Item = ConnectionHandlerEvent; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); loop { match std::mem::replace(this, OutboundSubstreamState::Poisoned) { - OutboundSubstreamState::PendingSend(mut substream, msg, user_data) => { + OutboundSubstreamState::PendingSend(mut substream, msg, query_id) => { match substream.poll_ready_unpin(cx) { Poll::Ready(Ok(())) => match substream.start_send_unpin(msg) { Ok(()) => { - *this = OutboundSubstreamState::PendingFlush(substream, user_data); + *this = OutboundSubstreamState::PendingFlush(substream, query_id); } Err(error) => { *this = OutboundSubstreamState::Done; - let event = user_data.map(|user_data| { + let event = query_id.map(|query_id| { ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::QueryError { error: KademliaHandlerQueryErr::Io(error), - user_data, + query_id, }, ) }); @@ -838,16 +820,16 @@ where } }, Poll::Pending => { - *this = OutboundSubstreamState::PendingSend(substream, msg, user_data); + *this = OutboundSubstreamState::PendingSend(substream, msg, query_id); return Poll::Pending; } Poll::Ready(Err(error)) => { *this = OutboundSubstreamState::Done; - let event = user_data.map(|user_data| { + let event = query_id.map(|query_id| { ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::QueryError { error: KademliaHandlerQueryErr::Io(error), - user_data, + query_id, }, ) }); @@ -856,26 +838,26 @@ where } } } - OutboundSubstreamState::PendingFlush(mut substream, user_data) => { + OutboundSubstreamState::PendingFlush(mut substream, query_id) => { match substream.poll_flush_unpin(cx) { Poll::Ready(Ok(())) => { - if let Some(user_data) = user_data { - *this = OutboundSubstreamState::WaitingAnswer(substream, user_data); + if let Some(query_id) = query_id { + *this = OutboundSubstreamState::WaitingAnswer(substream, query_id); } else { *this = OutboundSubstreamState::Closing(substream); } } Poll::Pending => { - *this = OutboundSubstreamState::PendingFlush(substream, user_data); + *this = OutboundSubstreamState::PendingFlush(substream, query_id); return Poll::Pending; } Poll::Ready(Err(error)) => { *this = OutboundSubstreamState::Done; - let event = user_data.map(|user_data| { + let event = query_id.map(|query_id| { ConnectionHandlerEvent::NotifyBehaviour( KademliaHandlerEvent::QueryError { error: KademliaHandlerQueryErr::Io(error), - user_data, + query_id, }, ) }); @@ -884,25 +866,25 @@ where } } } - OutboundSubstreamState::WaitingAnswer(mut substream, user_data) => { + OutboundSubstreamState::WaitingAnswer(mut substream, query_id) => { match substream.poll_next_unpin(cx) { Poll::Ready(Some(Ok(msg))) => { *this = OutboundSubstreamState::Closing(substream); - let event = process_kad_response(msg, user_data); + let event = process_kad_response(msg, query_id); return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( event, ))); } Poll::Pending => { - *this = OutboundSubstreamState::WaitingAnswer(substream, user_data); + *this = OutboundSubstreamState::WaitingAnswer(substream, query_id); return Poll::Pending; } Poll::Ready(Some(Err(error))) => { *this = OutboundSubstreamState::Done; let event = KademliaHandlerEvent::QueryError { error: KademliaHandlerQueryErr::Io(error), - user_data, + query_id, }; return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( @@ -915,7 +897,7 @@ where error: KademliaHandlerQueryErr::Io( io::ErrorKind::UnexpectedEof.into(), ), - user_data, + query_id, }; return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour( @@ -924,9 +906,9 @@ where } } } - OutboundSubstreamState::ReportError(error, user_data) => { + OutboundSubstreamState::ReportError(error, query_id) => { *this = OutboundSubstreamState::Done; - let event = KademliaHandlerEvent::QueryError { error, user_data }; + let event = KademliaHandlerEvent::QueryError { error, query_id }; return Poll::Ready(Some(ConnectionHandlerEvent::NotifyBehaviour(event))); } @@ -947,16 +929,8 @@ where } } -impl futures::Stream for InboundSubstreamState -where - TUserData: Unpin, -{ - type Item = ConnectionHandlerEvent< - KademliaProtocolConfig, - (), - KademliaHandlerEvent, - io::Error, - >; +impl futures::Stream for InboundSubstreamState { + type Item = ConnectionHandlerEvent; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { let this = self.get_mut(); @@ -1107,22 +1081,19 @@ where } /// Process a Kademlia message that's supposed to be a response to one of our requests. -fn process_kad_response( - event: KadResponseMsg, - user_data: TUserData, -) -> KademliaHandlerEvent { +fn process_kad_response(event: KadResponseMsg, query_id: QueryId) -> KademliaHandlerEvent { // TODO: must check that the response corresponds to the request match event { KadResponseMsg::Pong => { // We never send out pings. KademliaHandlerEvent::QueryError { error: KademliaHandlerQueryErr::UnexpectedMessage, - user_data, + query_id, } } KadResponseMsg::FindNode { closer_peers } => KademliaHandlerEvent::FindNodeRes { closer_peers, - user_data, + query_id, }, KadResponseMsg::GetProviders { closer_peers, @@ -1130,7 +1101,7 @@ fn process_kad_response( } => KademliaHandlerEvent::GetProvidersRes { closer_peers, provider_peers, - user_data, + query_id, }, KadResponseMsg::GetValue { record, @@ -1138,12 +1109,12 @@ fn process_kad_response( } => KademliaHandlerEvent::GetRecordRes { record, closer_peers, - user_data, + query_id, }, KadResponseMsg::PutValue { key, value, .. } => KademliaHandlerEvent::PutRecordRes { key, value, - user_data, + query_id, }, } } From 9867fcebb61bec5e79301f66637abaa7964b3b80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 May 2023 08:47:51 +0000 Subject: [PATCH 38/38] deps: bump quinn-proto from 0.9.3 to 0.10.1 Pull-Request: #3938. --- Cargo.lock | 37 ++++++++++++++++++++++++------- transports/quic/Cargo.toml | 4 ++-- transports/quic/src/endpoint.rs | 4 ++-- transports/tls/Cargo.toml | 6 ++--- transports/tls/src/certificate.rs | 2 +- transports/tls/src/verifier.rs | 25 ++++++++++----------- 6 files changed, 49 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eaa3b29d347..70164c2e517 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1717,6 +1717,16 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "futures-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" +dependencies = [ + "futures-io", + "rustls 0.21.1", +] + [[package]] name = "futures-sink" version = "0.3.28" @@ -2900,7 +2910,7 @@ dependencies = [ "quickcheck", "quinn-proto", "rand 0.8.5", - "rustls 0.20.8", + "rustls 0.21.1", "thiserror", "tokio", ] @@ -3068,7 +3078,7 @@ name = "libp2p-tls" version = "0.2.0" dependencies = [ "futures", - "futures-rustls", + "futures-rustls 0.24.0", "hex", "hex-literal", "libp2p-core", @@ -3077,7 +3087,7 @@ dependencies = [ "libp2p-yamux", "rcgen 0.10.0", "ring", - "rustls 0.20.8", + "rustls 0.21.1", "thiserror", "tokio", "webpki 0.22.0", @@ -3154,7 +3164,7 @@ dependencies = [ "async-std", "either", "futures", - "futures-rustls", + "futures-rustls 0.22.2", "libp2p-core", "libp2p-dns", "libp2p-identity", @@ -4080,20 +4090,19 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c10f662eee9c94ddd7135043e544f3c82fa839a1e7b865911331961b53186c" +checksum = "85af4ed6ee5a89f26a26086e9089a6643650544c025158449a3626ebf72884b3" dependencies = [ "bytes", "rand 0.8.5", "ring", "rustc-hash", - "rustls 0.20.8", + "rustls 0.21.1", "slab", "thiserror", "tinyvec", "tracing", - "webpki 0.22.0", ] [[package]] @@ -4483,6 +4492,18 @@ dependencies = [ "webpki 0.22.0", ] +[[package]] +name = "rustls" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct 0.7.0", +] + [[package]] name = "rustls-pemfile" version = "1.0.2" diff --git a/transports/quic/Cargo.toml b/transports/quic/Cargo.toml index d4f81b63d94..27b8f5c2fe1 100644 --- a/transports/quic/Cargo.toml +++ b/transports/quic/Cargo.toml @@ -19,9 +19,9 @@ libp2p-tls = { workspace = true } libp2p-identity = { workspace = true } log = "0.4" parking_lot = "0.12.0" -quinn-proto = { version = "0.9.3", default-features = false, features = ["tls-rustls"] } +quinn-proto = { version = "0.10.1", default-features = false, features = ["tls-rustls"] } rand = "0.8.5" -rustls = { version = "0.20.2", default-features = false } +rustls = { version = "0.21.1", default-features = false } thiserror = "1.0.40" tokio = { version = "1.28.1", default-features = false, features = ["net", "rt"], optional = true } diff --git a/transports/quic/src/endpoint.rs b/transports/quic/src/endpoint.rs index 10e650ba41a..cef062a0d7e 100644 --- a/transports/quic/src/endpoint.rs +++ b/transports/quic/src/endpoint.rs @@ -404,7 +404,7 @@ impl Driver

{ rx: mpsc::Receiver, ) -> Self { Driver { - endpoint: quinn_proto::Endpoint::new(endpoint_config, server_config), + endpoint: quinn_proto::Endpoint::new(endpoint_config, server_config, false), client_config, channel, rx, @@ -603,7 +603,7 @@ impl Future for Driver

{ // Start sending a packet on the socket. if let Some(transmit) = self.next_packet_out.take() { self.provider_socket - .start_send(transmit.contents, transmit.destination); + .start_send(transmit.contents.into(), transmit.destination); continue; } diff --git a/transports/tls/Cargo.toml b/transports/tls/Cargo.toml index b03723dd344..fcfdc3e5229 100644 --- a/transports/tls/Cargo.toml +++ b/transports/tls/Cargo.toml @@ -10,19 +10,19 @@ exclude = ["src/test_assets"] [dependencies] futures = { version = "0.3.28", default-features = false } -futures-rustls = "0.22.2" +futures-rustls = "0.24.0" libp2p-core = { workspace = true } libp2p-identity = { workspace = true } rcgen = "0.10.0" ring = "0.16.20" thiserror = "1.0.40" -webpki = "0.22.0" +webpki = { version = "0.22.0", features = ["std"] } x509-parser = "0.15.0" yasna = "0.5.2" # Exposed dependencies. Breaking changes to these are breaking changes to us. [dependencies.rustls] -version = "0.20.7" +version = "0.21.1" default-features = false features = ["dangerous_configuration"] # Must enable this to allow for custom verification code. diff --git a/transports/tls/src/certificate.rs b/transports/tls/src/certificate.rs index 8531ade72fa..ff9d296bb16 100644 --- a/transports/tls/src/certificate.rs +++ b/transports/tls/src/certificate.rs @@ -286,7 +286,7 @@ impl P2pCertificate<'_> { // In particular, MD5 and SHA1 MUST NOT be used. RSA_PKCS1_SHA1 => return Err(webpki::Error::UnsupportedSignatureAlgorithm), ECDSA_SHA1_Legacy => return Err(webpki::Error::UnsupportedSignatureAlgorithm), - Unknown(_) => return Err(webpki::Error::UnsupportedSignatureAlgorithm), + _ => return Err(webpki::Error::UnsupportedSignatureAlgorithm), }; let spki = &self.certificate.tbs_certificate.subject_pki; let key = signature::UnparsedPublicKey::new( diff --git a/transports/tls/src/verifier.rs b/transports/tls/src/verifier.rs index a9d9aecaa65..01fdb8fdf11 100644 --- a/transports/tls/src/verifier.rs +++ b/transports/tls/src/verifier.rs @@ -30,11 +30,11 @@ use rustls::{ TLS13_AES_128_GCM_SHA256, TLS13_AES_256_GCM_SHA384, TLS13_CHACHA20_POLY1305_SHA256, }, client::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}, - internal::msgs::handshake::DigitallySignedStruct, server::{ClientCertVerified, ClientCertVerifier}, - Certificate, DistinguishedNames, SignatureScheme, SupportedCipherSuite, - SupportedProtocolVersion, + Certificate, CertificateError, DigitallySignedStruct, DistinguishedName, SignatureScheme, + SupportedCipherSuite, SupportedProtocolVersion, }; +use std::sync::Arc; /// The protocol versions supported by this verifier. /// @@ -118,8 +118,8 @@ impl ServerCertVerifier for Libp2pCertificateVerifier { // the certificate matches the peer ID they intended to connect to, // and MUST abort the connection if there is a mismatch. if remote_peer_id != peer_id { - return Err(rustls::Error::PeerMisbehavedError( - "Wrong peer ID in p2p extension".to_string(), + return Err(rustls::Error::InvalidCertificate( + CertificateError::ApplicationVerificationFailure, )); } } @@ -162,8 +162,8 @@ impl ClientCertVerifier for Libp2pCertificateVerifier { true } - fn client_auth_root_subjects(&self) -> Option { - Some(vec![]) + fn client_auth_root_subjects(&self) -> &[DistinguishedName] { + &[] } fn verify_client_cert( @@ -236,8 +236,8 @@ impl From for rustls::Error { fn from(certificate::ParseError(e): certificate::ParseError) -> Self { use webpki::Error::*; match e { - BadDer => rustls::Error::InvalidCertificateEncoding, - e => rustls::Error::InvalidCertificateData(format!("invalid peer certificate: {e}")), + BadDer => rustls::Error::InvalidCertificate(CertificateError::BadEncoding), + e => rustls::Error::InvalidCertificate(CertificateError::Other(Arc::new(e))), } } } @@ -245,11 +245,10 @@ impl From for rustls::Error { fn from(certificate::VerificationError(e): certificate::VerificationError) -> Self { use webpki::Error::*; match e { - InvalidSignatureForPublicKey => rustls::Error::InvalidCertificateSignature, - UnsupportedSignatureAlgorithm | UnsupportedSignatureAlgorithmForPublicKey => { - rustls::Error::InvalidCertificateSignatureType + InvalidSignatureForPublicKey => { + rustls::Error::InvalidCertificate(CertificateError::BadSignature) } - e => rustls::Error::InvalidCertificateData(format!("invalid peer certificate: {e}")), + other => rustls::Error::InvalidCertificate(CertificateError::Other(Arc::new(other))), } } }