Skip to content

Commit

Permalink
merge with remote branch origin/master
Browse files Browse the repository at this point in the history
  • Loading branch information
hopinheimer committed Nov 28, 2024
2 parents 8caeed2 + b187c14 commit ad94224
Show file tree
Hide file tree
Showing 366 changed files with 4,353 additions and 3,342 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ libp2p-mdns = { version = "0.46.0", path = "protocols/mdns" }
libp2p-memory-connection-limits = { version = "0.3.1", path = "misc/memory-connection-limits" }
libp2p-metrics = { version = "0.15.0", path = "misc/metrics" }
libp2p-mplex = { version = "0.42.0", path = "muxers/mplex" }
libp2p-noise = { version = "0.45.0", path = "transports/noise" }
libp2p-noise = { version = "0.45.1", path = "transports/noise" }
libp2p-perf = { version = "0.4.0", path = "protocols/perf" }
libp2p-ping = { version = "0.45.1", path = "protocols/ping" }
libp2p-plaintext = { version = "0.42.0", path = "transports/plaintext" }
Expand All @@ -111,7 +111,7 @@ libp2p-webrtc-utils = { version = "0.3.0", path = "misc/webrtc-utils" }
libp2p-webrtc-websys = { version = "0.4.0-alpha.2", path = "transports/webrtc-websys" }
libp2p-websocket = { version = "0.44.1", path = "transports/websocket" }
libp2p-websocket-websys = { version = "0.4.1", path = "transports/websocket-websys" }
libp2p-webtransport-websys = { version = "0.4.0", path = "transports/webtransport-websys" }
libp2p-webtransport-websys = { version = "0.4.1", path = "transports/webtransport-websys" }
libp2p-yamux = { version = "0.46.0", path = "muxers/yamux" }

# External dependencies
Expand Down
22 changes: 10 additions & 12 deletions core/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,16 @@ pub enum ConnectedPoint {
///
/// - [`Endpoint::Dialer`] represents the default non-overriding option.
///
/// - [`Endpoint::Listener`] represents the overriding option.
/// Realization depends on the transport protocol. E.g. in the case of
/// TCP, both endpoints dial each other, resulting in a _simultaneous
/// open_ TCP connection. On this new connection both endpoints assume
/// to be the dialer of the connection. This is problematic during the
/// connection upgrade process where an upgrade assumes one side to be
/// the listener. With the help of this option, both peers can
/// negotiate the roles (dialer and listener) for the new connection
/// ahead of time, through some external channel, e.g. the DCUtR
/// protocol, and thus have one peer dial the other and upgrade the
/// connection as a dialer and one peer dial the other and upgrade the
/// connection _as a listener_ overriding its role.
/// - [`Endpoint::Listener`] represents the overriding option. Realization depends on the
/// transport protocol. E.g. in the case of TCP, both endpoints dial each other,
/// resulting in a _simultaneous open_ TCP connection. On this new connection both
/// endpoints assume to be the dialer of the connection. This is problematic during the
/// connection upgrade process where an upgrade assumes one side to be the listener. With
/// the help of this option, both peers can negotiate the roles (dialer and listener) for
/// the new connection ahead of time, through some external channel, e.g. the DCUtR
/// protocol, and thus have one peer dial the other and upgrade the connection as a
/// dialer and one peer dial the other and upgrade the connection _as a listener_
/// overriding its role.
role_override: Endpoint,
/// Whether the port for the outgoing connection was reused from a listener
/// or a new port was allocated. This is useful for address translation.
Expand Down
17 changes: 10 additions & 7 deletions core/src/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

use crate::muxing::StreamMuxerEvent;
use crate::transport::DialOpts;
use crate::{
muxing::StreamMuxer,
transport::{ListenerId, Transport, TransportError, TransportEvent},
Multiaddr,
use std::{
pin::Pin,
task::{Context, Poll},
};

use either::Either;
use futures::prelude::*;
use pin_project::pin_project;
use std::{pin::Pin, task::Context, task::Poll};

use crate::{
muxing::{StreamMuxer, StreamMuxerEvent},
transport::{DialOpts, ListenerId, Transport, TransportError, TransportEvent},
Multiaddr,
};

impl<A, B> StreamMuxer for future::Either<A, B>
where
Expand Down
17 changes: 8 additions & 9 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,21 @@
//!
//! The main concepts of libp2p-core are:
//!
//! - The [`Transport`] trait defines how to reach a remote node or listen for
//! incoming remote connections. See the [`transport`] module.
//! - The [`StreamMuxer`] trait is implemented on structs that hold a connection
//! to a remote and can subdivide this connection into multiple substreams.
//! See the [`muxing`] module.
//! - The [`UpgradeInfo`], [`InboundUpgrade`] and [`OutboundUpgrade`] traits
//! define how to upgrade each individual substream to use a protocol.
//! See the `upgrade` module.
//! - The [`Transport`] trait defines how to reach a remote node or listen for incoming remote
//! connections. See the [`transport`] module.
//! - The [`StreamMuxer`] trait is implemented on structs that hold a connection to a remote and can
//! subdivide this connection into multiple substreams. See the [`muxing`] module.
//! - The [`UpgradeInfo`], [`InboundUpgrade`] and [`OutboundUpgrade`] traits define how to upgrade
//! each individual substream to use a protocol. See the `upgrade` module.
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

mod proto {
#![allow(unreachable_pub)]
include!("generated/mod.rs");
pub use self::{
envelope_proto::*, peer_record_proto::mod_PeerRecord::*, peer_record_proto::PeerRecord,
envelope_proto::*,
peer_record_proto::{mod_PeerRecord::*, PeerRecord},
};
}

Expand Down
48 changes: 27 additions & 21 deletions core/src/muxing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
//! has ownership of a connection, lets you open and close substreams.
//!
//! > **Note**: You normally don't need to use the methods of the `StreamMuxer` directly, as this
//! > is managed by the library's internals.
//! > is managed by the library's internals.
//!
//! Each substream of a connection is an isolated stream of data. All the substreams are muxed
//! together so that the data read from or written to each substream doesn't influence the other
Expand All @@ -36,9 +36,9 @@
//! require maintaining long-lived channels of communication.
//!
//! > **Example**: The Kademlia protocol opens a new substream for each request it wants to
//! > perform. Multiple requests can be performed simultaneously by opening multiple
//! > substreams, without having to worry about associating responses with the
//! > right request.
//! > perform. Multiple requests can be performed simultaneously by opening multiple
//! > substreams, without having to worry about associating responses with the
//! > right request.
//!
//! # Implementing a muxing protocol
//!
Expand All @@ -50,21 +50,23 @@
//! The upgrade process will take ownership of the connection, which makes it possible for the
//! implementation of `StreamMuxer` to control everything that happens on the wire.
use futures::{task::Context, task::Poll, AsyncRead, AsyncWrite};
use std::{future::Future, pin::Pin};

use futures::{
task::{Context, Poll},
AsyncRead, AsyncWrite,
};
use multiaddr::Multiaddr;
use std::future::Future;
use std::pin::Pin;

pub use self::boxed::StreamMuxerBox;
pub use self::boxed::SubstreamBox;
pub use self::boxed::{StreamMuxerBox, SubstreamBox};

mod boxed;

/// Provides multiplexing for a connection by allowing users to open substreams.
///
/// A substream created by a [`StreamMuxer`] is a type that implements [`AsyncRead`] and [`AsyncWrite`].
/// The [`StreamMuxer`] itself is modelled closely after [`AsyncWrite`]. It features `poll`-style
/// functions that allow the implementation to make progress on various tasks.
/// A substream created by a [`StreamMuxer`] is a type that implements [`AsyncRead`] and
/// [`AsyncWrite`]. The [`StreamMuxer`] itself is modelled closely after [`AsyncWrite`]. It features
/// `poll`-style functions that allow the implementation to make progress on various tasks.
pub trait StreamMuxer {
/// Type of the object that represents the raw substream where data can be read and written.
type Substream: AsyncRead + AsyncWrite;
Expand All @@ -90,13 +92,13 @@ pub trait StreamMuxer {

/// Poll to close this [`StreamMuxer`].
///
/// After this has returned `Poll::Ready(Ok(()))`, the muxer has become useless and may be safely
/// dropped.
/// After this has returned `Poll::Ready(Ok(()))`, the muxer has become useless and may be
/// safely dropped.
///
/// > **Note**: You are encouraged to call this method and wait for it to return `Ready`, so
/// > that the remote is properly informed of the shutdown. However, apart from
/// > properly informing the remote, there is no difference between this and
/// > immediately dropping the muxer.
/// > that the remote is properly informed of the shutdown. However, apart from
/// > properly informing the remote, there is no difference between this and
/// > immediately dropping the muxer.
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;

/// Poll to allow the underlying connection to make progress.
Expand All @@ -120,7 +122,8 @@ pub enum StreamMuxerEvent {

/// Extension trait for [`StreamMuxer`].
pub trait StreamMuxerExt: StreamMuxer + Sized {
/// Convenience function for calling [`StreamMuxer::poll_inbound`] for [`StreamMuxer`]s that are `Unpin`.
/// Convenience function for calling [`StreamMuxer::poll_inbound`]
/// for [`StreamMuxer`]s that are `Unpin`.
fn poll_inbound_unpin(
&mut self,
cx: &mut Context<'_>,
Expand All @@ -131,7 +134,8 @@ pub trait StreamMuxerExt: StreamMuxer + Sized {
Pin::new(self).poll_inbound(cx)
}

/// Convenience function for calling [`StreamMuxer::poll_outbound`] for [`StreamMuxer`]s that are `Unpin`.
/// Convenience function for calling [`StreamMuxer::poll_outbound`]
/// for [`StreamMuxer`]s that are `Unpin`.
fn poll_outbound_unpin(
&mut self,
cx: &mut Context<'_>,
Expand All @@ -142,15 +146,17 @@ pub trait StreamMuxerExt: StreamMuxer + Sized {
Pin::new(self).poll_outbound(cx)
}

/// Convenience function for calling [`StreamMuxer::poll`] for [`StreamMuxer`]s that are `Unpin`.
/// Convenience function for calling [`StreamMuxer::poll`]
/// for [`StreamMuxer`]s that are `Unpin`.
fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<StreamMuxerEvent, Self::Error>>
where
Self: Unpin,
{
Pin::new(self).poll(cx)
}

/// Convenience function for calling [`StreamMuxer::poll_close`] for [`StreamMuxer`]s that are `Unpin`.
/// Convenience function for calling [`StreamMuxer::poll_close`]
/// for [`StreamMuxer`]s that are `Unpin`.
fn poll_close_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>
where
Self: Unpin,
Expand Down
20 changes: 12 additions & 8 deletions core/src/muxing/boxed.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::muxing::{StreamMuxer, StreamMuxerEvent};
use std::{
error::Error,
fmt, io,
io::{IoSlice, IoSliceMut},
pin::Pin,
task::{Context, Poll},
};

use futures::{AsyncRead, AsyncWrite};
use pin_project::pin_project;
use std::error::Error;
use std::fmt;
use std::io;
use std::io::{IoSlice, IoSliceMut};
use std::pin::Pin;
use std::task::{Context, Poll};

use crate::muxing::{StreamMuxer, StreamMuxerEvent};

/// Abstract `StreamMuxer`.
pub struct StreamMuxerBox {
Expand Down Expand Up @@ -139,7 +142,8 @@ impl StreamMuxer for StreamMuxerBox {
}

impl SubstreamBox {
/// Construct a new [`SubstreamBox`] from something that implements [`AsyncRead`] and [`AsyncWrite`].
/// Construct a new [`SubstreamBox`] from something
/// that implements [`AsyncRead`] and [`AsyncWrite`].
pub fn new<S: AsyncRead + AsyncWrite + Send + 'static>(stream: S) -> Self {
Self(Box::pin(stream))
}
Expand Down
21 changes: 11 additions & 10 deletions core/src/peer_record.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
use crate::signed_envelope::SignedEnvelope;
use crate::{proto, signed_envelope, DecodeError, Multiaddr};
use libp2p_identity::Keypair;
use libp2p_identity::PeerId;
use libp2p_identity::SigningError;
use libp2p_identity::{Keypair, PeerId, SigningError};
use quick_protobuf::{BytesReader, Writer};
use web_time::SystemTime;

use crate::{proto, signed_envelope, signed_envelope::SignedEnvelope, DecodeError, Multiaddr};

const PAYLOAD_TYPE: &str = "/libp2p/routing-state-record";
const DOMAIN_SEP: &str = "libp2p-routing-state";

/// Represents a peer routing record.
///
/// Peer records are designed to be distributable and carry a signature by being wrapped in a signed envelope.
/// For more information see RFC0003 of the libp2p specifications: <https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md>
/// Peer records are designed to be distributable and carry a signature by being wrapped in a signed
/// envelope. For more information see RFC0003 of the libp2p specifications: <https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md>
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PeerRecord {
peer_id: PeerId,
Expand All @@ -21,14 +19,16 @@ pub struct PeerRecord {

/// A signed envelope representing this [`PeerRecord`].
///
/// If this [`PeerRecord`] was constructed from a [`SignedEnvelope`], this is the original instance.
/// If this [`PeerRecord`] was constructed from a [`SignedEnvelope`], this is the original
/// instance.
envelope: SignedEnvelope,
}

impl PeerRecord {
/// Attempt to re-construct a [`PeerRecord`] from a [`SignedEnvelope`].
///
/// If this function succeeds, the [`SignedEnvelope`] contained a peer record with a valid signature and can hence be considered authenticated.
/// If this function succeeds, the [`SignedEnvelope`] contained a peer record with a valid
/// signature and can hence be considered authenticated.
pub fn from_signed_envelope(envelope: SignedEnvelope) -> Result<Self, FromEnvelopeError> {
use quick_protobuf::MessageRead;

Expand Down Expand Up @@ -60,7 +60,8 @@ impl PeerRecord {

/// Construct a new [`PeerRecord`] by authenticating the provided addresses with the given key.
///
/// This is the same key that is used for authenticating every libp2p connection of your application, i.e. what you use when setting up your [`crate::transport::Transport`].
/// This is the same key that is used for authenticating every libp2p connection of your
/// application, i.e. what you use when setting up your [`crate::transport::Transport`].
pub fn new(key: &Keypair, addresses: Vec<Multiaddr>) -> Result<Self, SigningError> {
use quick_protobuf::MessageWrite;

Expand Down
20 changes: 12 additions & 8 deletions core/src/signed_envelope.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::{proto, DecodeError};
use libp2p_identity::SigningError;
use libp2p_identity::{Keypair, PublicKey};
use quick_protobuf::{BytesReader, Writer};
use std::fmt;

use libp2p_identity::{Keypair, PublicKey, SigningError};
use quick_protobuf::{BytesReader, Writer};
use unsigned_varint::encode::usize_buffer;

/// A signed envelope contains an arbitrary byte string payload, a signature of the payload, and the public key that can be used to verify the signature.
use crate::{proto, DecodeError};

/// A signed envelope contains an arbitrary byte string payload, a signature of the payload, and the
/// public key that can be used to verify the signature.
///
/// For more details see libp2p RFC0002: <https://github.com/libp2p/specs/blob/master/RFC/0002-signed-envelopes.md>
#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -46,8 +48,9 @@ impl SignedEnvelope {

/// Extract the payload and signing key of this [`SignedEnvelope`].
///
/// You must provide the correct domain-separation string and expected payload type in order to get the payload.
/// This guards against accidental mis-use of the payload where the signature was created for a different purpose or payload type.
/// You must provide the correct domain-separation string and expected payload type in order to
/// get the payload. This guards against accidental mis-use of the payload where the
/// signature was created for a different purpose or payload type.
///
/// It is the caller's responsibility to check that the signing key is what
/// is expected. For example, checking that the signing key is from a
Expand Down Expand Up @@ -156,7 +159,8 @@ pub enum DecodingError {
/// Errors that occur whilst extracting the payload of a [`SignedEnvelope`].
#[derive(Debug)]
pub enum ReadPayloadError {
/// The signature on the signed envelope does not verify with the provided domain separation string.
/// The signature on the signed envelope does not verify
/// with the provided domain separation string.
InvalidSignature,
/// The payload contained in the envelope is not of the expected type.
UnexpectedPayloadType { expected: Vec<u8>, got: Vec<u8> },
Expand Down
Loading

0 comments on commit ad94224

Please sign in to comment.