Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions Cargo.lock

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

26 changes: 13 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,43 +78,43 @@ libp2p = { version = "0.56.1", path = "libp2p" }
libp2p-allow-block-list = { version = "0.6.0", path = "misc/allow-block-list" }
libp2p-autonat = { version = "0.15.0", path = "protocols/autonat" }
libp2p-connection-limits = { version = "0.6.0", path = "misc/connection-limits" }
libp2p-core = { version = "0.43.1", path = "core" }
libp2p-core = { version = "0.44.0", path = "core" }
libp2p-dcutr = { version = "0.14.0", path = "protocols/dcutr" }
libp2p-dns = { version = "0.44.0", path = "transports/dns" }
libp2p-dns = { version = "0.45.0", path = "transports/dns" }
libp2p-floodsub = { version = "0.47.0", path = "protocols/floodsub" }
libp2p-gossipsub = { version = "0.50.0", path = "protocols/gossipsub" }
libp2p-identify = { version = "0.47.0", path = "protocols/identify" }
libp2p-identity = { version = "0.2.12" }
libp2p-kad = { version = "0.49.0", path = "protocols/kad" }
libp2p-mdns = { version = "0.48.0", path = "protocols/mdns" }
libp2p-memory-connection-limits = { version = "0.5.0", path = "misc/memory-connection-limits" }
libp2p-metrics = { version = "0.17.1", path = "misc/metrics" }
libp2p-metrics = { version = "0.17.2", path = "misc/metrics" }
libp2p-mplex = { version = "0.43.1", path = "muxers/mplex" }
libp2p-noise = { version = "0.46.1", path = "transports/noise" }
libp2p-peer-store = { version = "0.1.0", path = "misc/peer-store" }
libp2p-perf = { version = "0.4.0", path = "protocols/perf" }
libp2p-ping = { version = "0.47.0", path = "protocols/ping" }
libp2p-plaintext = { version = "0.43.0", path = "transports/plaintext" }
libp2p-pnet = { version = "0.26.0", path = "transports/pnet" }
libp2p-quic = { version = "0.13.0", path = "transports/quic" }
libp2p-relay = { version = "0.21.1", path = "protocols/relay" }
libp2p-quic = { version = "0.14.0", path = "transports/quic" }
libp2p-relay = { version = "0.22.0", path = "protocols/relay" }
libp2p-rendezvous = { version = "0.17.0", path = "protocols/rendezvous" }
libp2p-request-response = { version = "0.29.0", path = "protocols/request-response" }
libp2p-server = { version = "0.12.7", path = "misc/server" }
libp2p-stream = { version = "0.4.0-alpha", path = "protocols/stream" }
libp2p-swarm = { version = "0.47.0", path = "swarm" }
libp2p-swarm = { version = "0.47.1", path = "swarm" }
libp2p-swarm-derive = { version = "=0.35.1", path = "swarm-derive" } # `libp2p-swarm-derive` may not be compatible with different `libp2p-swarm` non-breaking releases. E.g. `libp2p-swarm` might introduce a new enum variant `FromSwarm` (which is `#[non-exhaustive]`) in a non-breaking release. Older versions of `libp2p-swarm-derive` would not forward this enum variant within the `NetworkBehaviour` hierarchy. Thus the version pinning is required.
libp2p-swarm-test = { version = "0.6.0", path = "swarm-test" }
libp2p-tcp = { version = "0.44.0", path = "transports/tcp" }
libp2p-tcp = { version = "0.45.0", path = "transports/tcp" }
libp2p-tls = { version = "0.6.2", path = "transports/tls" }
libp2p-uds = { version = "0.43.0", path = "transports/uds" }
libp2p-uds = { version = "0.44.0", path = "transports/uds" }
libp2p-upnp = { version = "0.6.0", path = "protocols/upnp" }
libp2p-webrtc = { version = "0.9.0-alpha.2", path = "transports/webrtc" }
libp2p-webrtc = { version = "0.10.0-alpha", path = "transports/webrtc" }
libp2p-webrtc-utils = { version = "0.4.0", path = "misc/webrtc-utils" }
libp2p-webrtc-websys = { version = "0.4.0", path = "transports/webrtc-websys" }
libp2p-websocket = { version = "0.45.2", path = "transports/websocket" }
libp2p-websocket-websys = { version = "0.5.0", path = "transports/websocket-websys" }
libp2p-webtransport-websys = { version = "0.5.1", path = "transports/webtransport-websys" }
libp2p-webrtc-websys = { version = "0.5.0", path = "transports/webrtc-websys" }
libp2p-websocket = { version = "0.46.0", path = "transports/websocket" }
libp2p-websocket-websys = { version = "0.6.0", path = "transports/websocket-websys" }
libp2p-webtransport-websys = { version = "0.6.0", path = "transports/webtransport-websys" }
libp2p-yamux = { version = "0.47.0", path = "muxers/yamux" }

# External dependencies
Expand Down
10 changes: 8 additions & 2 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.44.0
- Updated `Transport::Dial` future for outbound connections, which on success now yields:
- `Transport::Output` as a handle to the established data stream,
- `Transport::PortUse` as the port reuse policy used while creating the outbound connection.
See [PR 6187](https://github.com/libp2p/rust-libp2p/pull/6187)

## 0.43.1
- Remove `once_cell` dependency.
See [PR 5913](https://github.com/libp2p/rust-libp2p/pull/5913)
Expand All @@ -10,8 +16,8 @@
## 0.42.0

- Update `Transport::dial` function signature with a `DialOpts` param and remove `Transport::dial_as_listener`:
- `DialOpts` struct contains `PortUse` and `Endpoint`,
- `PortUse` allows controlling port allocation of new connections (defaults to `PortUse::Reuse`) -
- `DialOpts` struct contains `PortUse` and `Endpoint`,
- `PortUse` allows controlling port allocation of new connections (defaults to `PortUse::Reuse`) -
- Add `port_use` field to `ConnectedPoint`
- Set `endpoint` field in `DialOpts` to `Endpoint::Listener` to dial as a listener
- Remove `Transport::address_translation` and relocate functionality to `libp2p_swarm`
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "libp2p-core"
edition.workspace = true
rust-version = { workspace = true }
description = "Core traits and structs of libp2p"
version = "0.43.1"
version = "0.44.0"
authors = ["Parity Technologies <[email protected]>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"
Expand Down
61 changes: 46 additions & 15 deletions core/src/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use pin_project::pin_project;

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

Expand Down Expand Up @@ -91,16 +91,16 @@ where
}
}

/// Implements `Future` and dispatches all method calls to either `First` or `Second`.
#[pin_project(project = EitherFutureProj)]
/// Future for listener upgrades that returns Either<A::Output, B::Output>
#[pin_project(project = EitherUpgradeFutureProj)]
#[derive(Debug, Copy, Clone)]
#[must_use = "futures do nothing unless polled"]
pub enum EitherFuture<A, B> {
pub enum EitherUpgradeFuture<A, B> {
First(#[pin] A),
Second(#[pin] B),
}

impl<AFuture, BFuture, AInner, BInner> Future for EitherFuture<AFuture, BFuture>
impl<AFuture, BFuture, AInner, BInner> Future for EitherUpgradeFuture<AFuture, BFuture>
where
AFuture: TryFuture<Ok = AInner>,
BFuture: TryFuture<Ok = BInner>,
Expand All @@ -109,25 +109,54 @@ where

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
EitherFutureProj::First(a) => TryFuture::try_poll(a, cx)
EitherUpgradeFutureProj::First(a) => TryFuture::try_poll(a, cx)
.map_ok(future::Either::Left)
.map_err(Either::Left),
EitherFutureProj::Second(a) => TryFuture::try_poll(a, cx)
EitherUpgradeFutureProj::Second(b) => TryFuture::try_poll(b, cx)
.map_ok(future::Either::Right)
.map_err(Either::Right),
}
}
}

/// Future for dials that returns (Either<A::Output, B::Output>, PortUse)
#[pin_project(project = EitherDialFutureProj)]
#[derive(Debug, Copy, Clone)]
#[must_use = "futures do nothing unless polled"]
pub enum EitherDialFuture<A, B> {
First(#[pin] A),
Second(#[pin] B),
}

impl<AFuture, BFuture, AInner, BInner> Future for EitherDialFuture<AFuture, BFuture>
where
AFuture: TryFuture<Ok = (AInner, PortUse)>,
BFuture: TryFuture<Ok = (BInner, PortUse)>,
{
type Output =
Result<(future::Either<AInner, BInner>, PortUse), Either<AFuture::Error, BFuture::Error>>;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
EitherDialFutureProj::First(a) => TryFuture::try_poll(a, cx)
.map_ok(|(inner, port_use)| (future::Either::Left(inner), port_use))
.map_err(Either::Left),
EitherDialFutureProj::Second(b) => TryFuture::try_poll(b, cx)
.map_ok(|(inner, port_use)| (future::Either::Right(inner), port_use))
.map_err(Either::Right),
}
}
}

impl<A, B> Transport for Either<A, B>
where
B: Transport,
A: Transport,
{
type Output = future::Either<A::Output, B::Output>;
type Error = Either<A::Error, B::Error>;
type ListenerUpgrade = EitherFuture<A::ListenerUpgrade, B::ListenerUpgrade>;
type Dial = EitherFuture<A::Dial, B::Dial>;
type ListenerUpgrade = EitherUpgradeFuture<A::ListenerUpgrade, B::ListenerUpgrade>;
type Dial = EitherDialFuture<A::Dial, B::Dial>;

fn poll(
self: Pin<&mut Self>,
Expand All @@ -136,15 +165,17 @@ where
match self.as_pin_mut() {
Either::Left(a) => match a.poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(event) => {
Poll::Ready(event.map_upgrade(EitherFuture::First).map_err(Either::Left))
}
Poll::Ready(event) => Poll::Ready(
event
.map_upgrade(EitherUpgradeFuture::First)
.map_err(Either::Left),
),
},
Either::Right(b) => match b.poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(event) => Poll::Ready(
event
.map_upgrade(EitherFuture::Second)
.map_upgrade(EitherUpgradeFuture::Second)
.map_err(Either::Right),
),
},
Expand Down Expand Up @@ -184,12 +215,12 @@ where
use TransportError::*;
match self {
Either::Left(a) => match a.dial(addr, opts) {
Ok(connec) => Ok(EitherFuture::First(connec)),
Ok(connec) => Ok(EitherDialFuture::First(connec)),
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
Err(Other(err)) => Err(Other(Either::Left(err))),
},
Either::Right(b) => match b.dial(addr, opts) {
Ok(connec) => Ok(EitherFuture::Second(connec)),
Ok(connec) => Ok(EitherDialFuture::Second(connec)),
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
Err(Other(err)) => Err(Other(Either::Right(err))),
},
Expand Down
8 changes: 5 additions & 3 deletions core/src/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,11 @@ pub trait Transport {
/// of the connection setup process.
type ListenerUpgrade: Future<Output = Result<Self::Output, Self::Error>>;

/// A pending [`Output`](Transport::Output) for an outbound connection,
/// obtained from [dialing](Transport::dial).
type Dial: Future<Output = Result<Self::Output, Self::Error>>;
/// A pending future for an outbound connection obtained from [dialing](Transport::dial).
///
/// On success, the future yields a tuple containing the [`Output`](Transport::Output)
/// of the connection setup process and the [`PortUse`] policy of the connection.
type Dial: Future<Output = Result<(Self::Output, PortUse), Self::Error>>;

/// Listens on the given [`Multiaddr`] for inbound connections with a provided [`ListenerId`].
fn listen_on(
Expand Down
Loading