core/muxing: Force StreamMuxer::Substream to implement Async{Read,Write} (#2707)

Co-authored-by: Max Inden <mail@max-inden.de>
This commit is contained in:
Thomas Eizinger
2022-06-23 13:52:11 +02:00
committed by GitHub
parent 118046c9e0
commit eb490c08e9
65 changed files with 380 additions and 792 deletions

View File

@ -44,10 +44,27 @@
# `libp2p` facade crate # `libp2p` facade crate
# 0.46.0 [unreleased] # 0.46.0 [unreleased]
- Semver bump Rust from `1.56.1` to `1.60.0` . See [PR 2646]. - Semver bump Rust from `1.56.1` to `1.60.0` . See [PR 2646].
- Added weak dependencies for features. See [PR 2646]. - Added weak dependencies for features. See [PR 2646].
- Update individual crates. - Update individual crates.
- Update to [`libp2p-autonat` `v0.5.0`](protocols/autonat/CHANGELOG.md#050).
- Update to [`libp2p-core` `v0.34.0`](core/CHANGELOG.md#0340).
- Update to [`libp2p-dcutr` `v0.4.0`](protocols/dcutr/CHANGELOG.md#040).
- Update to [`libp2p-floodsub` `v0.37.0`](protocols/floodsub/CHANGELOG.md#0370).
- Update to [`libp2p-identify` `v0.37.0`](protocols/identify/CHANGELOG.md#0370).
- Update to [`libp2p-kad` `v0.38.0`](protocols/kad/CHANGELOG.md#0380).
- Update to [`libp2p-metrics` `v0.7.0`](misc/metrics/CHANGELOG.md#070).
- Update to [`libp2p-mplex` `v0.34.0`](muxers/mplex/CHANGELOG.md). - Update to [`libp2p-mplex` `v0.34.0`](muxers/mplex/CHANGELOG.md).
- Update to [`libp2p-noise` `v0.37.0`](transports/noise/CHANGELOG.md#0370).
- Update to [`libp2p-ping` `v0.37.0`](protocols/ping/CHANGELOG.md#0370).
- Update to [`libp2p-plaintext` `v0.34.0`](transports/plaintext/CHANGELOG.md#0340).
- Update to [`libp2p-relay` `v0.10.0`](protocols/relay/CHANGELOG.md#0100).
- Update to [`libp2p-rendezvous` `v0.7.0`](protocols/rendezvous/CHANGELOG.md#070).
- Update to [`libp2p-request-response` `v0.19.0`](protocols/request-response/CHANGELOG.md#0190).
- Update to [`libp2p-swarm` `v0.37.0`](swarm/CHANGELOG.md#0370).
- Update to [`libp2p-wasm-ext` `v0.34.0`](transports/wasm-ext/CHANGELOG.md#0340).
- Update to [`libp2p-yamux` `v0.38.0`](muxers/yamux/CHANGELOG.md#0380).
- Update to `libp2p-uds` [`v0.33.0`](transports/uds/CHANGELOG.md). - Update to `libp2p-uds` [`v0.33.0`](transports/uds/CHANGELOG.md).
[PR 2646]: https://github.com/libp2p/rust-libp2p/pull/2646 [PR 2646]: https://github.com/libp2p/rust-libp2p/pull/2646

View File

@ -3,7 +3,7 @@ name = "libp2p"
edition = "2021" edition = "2021"
rust-version = "1.60.0" rust-version = "1.60.0"
description = "Peer-to-peer networking library" description = "Peer-to-peer networking library"
version = "0.46.0" version = "0.47.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -76,26 +76,26 @@ getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature
instant = "0.1.11" # Explicit dependency to be used in `wasm-bindgen` feature instant = "0.1.11" # Explicit dependency to be used in `wasm-bindgen` feature
lazy_static = "1.2" lazy_static = "1.2"
libp2p-autonat = { version = "0.4.0", path = "protocols/autonat", optional = true } libp2p-autonat = { version = "0.5.0", path = "protocols/autonat", optional = true }
libp2p-core = { version = "0.33.0", path = "core", default-features = false } libp2p-core = { version = "0.34.0", path = "core", default-features = false }
libp2p-dcutr = { version = "0.3.1", path = "protocols/dcutr", optional = true } libp2p-dcutr = { version = "0.4.0", path = "protocols/dcutr", optional = true }
libp2p-floodsub = { version = "0.36.0", path = "protocols/floodsub", optional = true } libp2p-floodsub = { version = "0.37.0", path = "protocols/floodsub", optional = true }
libp2p-identify = { version = "0.36.1", path = "protocols/identify", optional = true } libp2p-identify = { version = "0.37.0", path = "protocols/identify", optional = true }
libp2p-kad = { version = "0.37.1", path = "protocols/kad", optional = true } libp2p-kad = { version = "0.38.0", path = "protocols/kad", optional = true }
libp2p-metrics = { version = "0.6.0", path = "misc/metrics", optional = true } libp2p-metrics = { version = "0.7.0", path = "misc/metrics", optional = true }
libp2p-mplex = { version = "0.34.0", path = "muxers/mplex", optional = true } libp2p-mplex = { version = "0.34.0", path = "muxers/mplex", optional = true }
libp2p-noise = { version = "0.36.0", path = "transports/noise", optional = true } libp2p-noise = { version = "0.37.0", path = "transports/noise", optional = true }
libp2p-ping = { version = "0.36.0", path = "protocols/ping", optional = true } libp2p-ping = { version = "0.37.0", path = "protocols/ping", optional = true }
libp2p-plaintext = { version = "0.33.0", path = "transports/plaintext", optional = true } libp2p-plaintext = { version = "0.34.0", path = "transports/plaintext", optional = true }
libp2p-pnet = { version = "0.22.0", path = "transports/pnet", optional = true } libp2p-pnet = { version = "0.22.0", path = "transports/pnet", optional = true }
libp2p-relay = { version = "0.9.1", path = "protocols/relay", optional = true } libp2p-relay = { version = "0.10.0", path = "protocols/relay", optional = true }
libp2p-rendezvous = { version = "0.6.0", path = "protocols/rendezvous", optional = true } libp2p-rendezvous = { version = "0.7.0", path = "protocols/rendezvous", optional = true }
libp2p-request-response = { version = "0.18.0", path = "protocols/request-response", optional = true } libp2p-request-response = { version = "0.19.0", path = "protocols/request-response", optional = true }
libp2p-swarm = { version = "0.36.1", path = "swarm" } libp2p-swarm = { version = "0.37.0", path = "swarm" }
libp2p-swarm-derive = { version = "0.27.0", path = "swarm-derive" } libp2p-swarm-derive = { version = "0.27.0", path = "swarm-derive" }
libp2p-uds = { version = "0.33.0", path = "transports/uds", optional = true } libp2p-uds = { version = "0.33.0", path = "transports/uds", optional = true }
libp2p-wasm-ext = { version = "0.33.0", path = "transports/wasm-ext", default-features = false, optional = true } libp2p-wasm-ext = { version = "0.34.0", path = "transports/wasm-ext", default-features = false, optional = true }
libp2p-yamux = { version = "0.37.0", path = "muxers/yamux", optional = true } libp2p-yamux = { version = "0.38.0", path = "muxers/yamux", optional = true }
multiaddr = { version = "0.14.0" } multiaddr = { version = "0.14.0" }
parking_lot = "0.12.0" parking_lot = "0.12.0"
pin-project = "1.0.0" pin-project = "1.0.0"
@ -103,14 +103,14 @@ rand = "0.7.3" # Explicit dependency to be used in `wasm-bindgen` feature
smallvec = "1.6.1" smallvec = "1.6.1"
[target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))'.dependencies] [target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))'.dependencies]
libp2p-deflate = { version = "0.33.0", path = "transports/deflate", optional = true } libp2p-deflate = { version = "0.34.0", path = "transports/deflate", optional = true }
libp2p-dns = { version = "0.33.0", path = "transports/dns", optional = true, default-features = false } libp2p-dns = { version = "0.34.0", path = "transports/dns", optional = true, default-features = false }
libp2p-mdns = { version = "0.37.0", path = "protocols/mdns", optional = true } libp2p-mdns = { version = "0.38.0", path = "protocols/mdns", optional = true }
libp2p-tcp = { version = "0.33.0", path = "transports/tcp", default-features = false, optional = true } libp2p-tcp = { version = "0.34.0", path = "transports/tcp", default-features = false, optional = true }
libp2p-websocket = { version = "0.35.0", path = "transports/websocket", optional = true } libp2p-websocket = { version = "0.36.0", path = "transports/websocket", optional = true }
[target.'cfg(not(target_os = "unknown"))'.dependencies] [target.'cfg(not(target_os = "unknown"))'.dependencies]
libp2p-gossipsub = { version = "0.38.0", path = "protocols/gossipsub", optional = true } libp2p-gossipsub = { version = "0.39.0", path = "protocols/gossipsub", optional = true }
[dev-dependencies] [dev-dependencies]
async-std = { version = "1.6.2", features = ["attributes"] } async-std = { version = "1.6.2", features = ["attributes"] }

View File

@ -1,8 +1,11 @@
# 0.33.1 - unreleased # 0.34.0 - unreleased
- Introduce `StreamMuxerEvent::map_inbound_stream`. See [PR 2691]. - Introduce `StreamMuxerEvent::map_inbound_stream`. See [PR 2691].
- Remove `{read,write,flush,shutdown,destroy}_substream` functions from `StreamMuxer` trait
in favor of forcing `StreamMuxer::Substream` to implement `AsyncRead + AsyncWrite`. See [PR 2707].
[PR 2691]: https://github.com/libp2p/rust-libp2p/pull/2691 [PR 2691]: https://github.com/libp2p/rust-libp2p/pull/2691
[PR 2707]: https://github.com/libp2p/rust-libp2p/pull/2707
# 0.33.0 # 0.33.0

View File

@ -3,7 +3,7 @@ name = "libp2p-core"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Core traits and structs of libp2p" description = "Core traits and structs of libp2p"
version = "0.33.1" version = "0.34.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"

View File

@ -259,85 +259,6 @@ where
} }
} }
fn read_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
}
_ => panic!("Wrong API usage"),
}
}
fn write_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
}
_ => panic!("Wrong API usage"),
}
}
fn flush_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.flush_substream(cx, sub).map_err(|e| e.into())
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.flush_substream(cx, sub).map_err(|e| e.into())
}
_ => panic!("Wrong API usage"),
}
}
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
}
_ => panic!("Wrong API usage"),
}
}
fn destroy_substream(&self, substream: Self::Substream) {
match self {
EitherOutput::First(inner) => match substream {
EitherOutput::First(substream) => inner.destroy_substream(substream),
_ => panic!("Wrong API usage"),
},
EitherOutput::Second(inner) => match substream {
EitherOutput::Second(substream) => inner.destroy_substream(substream),
_ => panic!("Wrong API usage"),
},
}
}
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self { match self {
EitherOutput::First(inner) => inner.poll_close(cx).map_err(|e| e.into()), EitherOutput::First(inner) => inner.poll_close(cx).map_err(|e| e.into()),

View File

@ -21,8 +21,7 @@
//! Muxing is the process of splitting a connection into multiple substreams. //! Muxing is the process of splitting a connection into multiple substreams.
//! //!
//! The main item of this module is the `StreamMuxer` trait. An implementation of `StreamMuxer` //! The main item of this module is the `StreamMuxer` trait. An implementation of `StreamMuxer`
//! has ownership of a connection, lets you open and close substreams, and read/write data //! has ownership of a connection, lets you open and close substreams.
//! on open substreams.
//! //!
//! > **Note**: You normally don't need to use the methods of the `StreamMuxer` directly, as this //! > **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.
@ -51,31 +50,27 @@
//! The upgrade process will take ownership of the connection, which makes it possible for the //! 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. //! implementation of `StreamMuxer` to control everything that happens on the wire.
use futures::{future, prelude::*, task::Context, task::Poll}; use futures::{task::Context, task::Poll, AsyncRead, AsyncWrite};
use multiaddr::Multiaddr; use multiaddr::Multiaddr;
use std::{fmt, io, ops::Deref, pin::Pin}; use std::io;
pub use self::boxed::StreamMuxerBox; pub use self::boxed::StreamMuxerBox;
pub use self::boxed::SubstreamBox;
pub use self::singleton::SingletonMuxer; pub use self::singleton::SingletonMuxer;
mod boxed; mod boxed;
mod singleton; mod singleton;
/// Implemented on objects that can open and manage substreams. /// Provides multiplexing for a connection by allowing users to open substreams.
/// ///
/// The state of a muxer, as exposed by this API, is the following: /// A substream created by a [`StreamMuxer`] is a type that implements [`AsyncRead`] and [`AsyncWrite`].
///
/// - A connection to the remote. The `poll_event`, `flush_all` and `close` methods operate
/// on this.
/// - A list of substreams that are open. The `poll_outbound`, `read_substream`, `write_substream`,
/// `flush_substream`, `shutdown_substream` and `destroy_substream` methods allow controlling
/// these entries.
/// - A list of outbound substreams being opened. The `open_outbound`, `poll_outbound` and
/// `destroy_outbound` methods allow controlling these entries.
/// ///
/// Inbound substreams are reported via [`StreamMuxer::poll_event`].
/// Outbound substreams can be opened via [`StreamMuxer::open_outbound`] and subsequent polling via
/// [`StreamMuxer::poll_outbound`].
pub trait StreamMuxer { pub trait StreamMuxer {
/// Type of the object that represents the raw substream where data can be read and written. /// Type of the object that represents the raw substream where data can be read and written.
type Substream; type Substream: AsyncRead + AsyncWrite;
/// Future that will be resolved when the outgoing substream is open. /// Future that will be resolved when the outgoing substream is open.
type OutboundSubstream; type OutboundSubstream;
@ -126,86 +121,12 @@ pub trait StreamMuxer {
/// or if you want to interrupt it. /// or if you want to interrupt it.
fn destroy_outbound(&self, s: Self::OutboundSubstream); fn destroy_outbound(&self, s: Self::OutboundSubstream);
/// Reads data from a substream. The behaviour is the same as `futures::AsyncRead::poll_read`.
///
/// If `Pending` is returned, then the current task will be notified once the substream
/// is ready to be read. However, for each individual substream, only the latest task that
/// was used to call this method may be notified.
///
/// If `Async::Ready(0)` is returned, the substream has been closed by the remote and should
/// no longer be read afterwards.
///
/// An error can be generated if the connection has been closed, or if a protocol misbehaviour
/// happened.
fn read_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>>;
/// Write data to a substream. The behaviour is the same as `futures::AsyncWrite::poll_write`.
///
/// If `Pending` is returned, then the current task will be notified once the substream
/// is ready to be read. For each individual substream, only the latest task that was used to
/// call this method may be notified.
///
/// Calling `write_substream` does not guarantee that data will arrive to the remote. To
/// ensure that, you should call `flush_substream`.
///
/// It is incorrect to call this method on a substream if you called `shutdown_substream` on
/// this substream earlier.
fn write_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>>;
/// Flushes a substream. The behaviour is the same as `futures::AsyncWrite::poll_flush`.
///
/// After this method has been called, data written earlier on the substream is guaranteed to
/// be received by the remote.
///
/// If `Pending` is returned, then the current task will be notified once the substream
/// is ready to be read. For each individual substream, only the latest task that was used to
/// call this method may be notified.
///
/// > **Note**: This method may be implemented as a call to `flush_all`.
fn flush_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>>;
/// Attempts to shut down the writing side of a substream. The behaviour is similar to
/// `AsyncWrite::poll_close`.
///
/// Contrary to `AsyncWrite::poll_close`, shutting down a substream does not imply
/// `flush_substream`. If you want to make sure that the remote is immediately informed about
/// the shutdown, use `flush_substream` or `flush_all`.
///
/// After this method has been called, you should no longer attempt to write to this substream.
///
/// An error can be generated if the connection has been closed, or if a protocol misbehaviour
/// happened.
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>>;
/// Destroys a substream.
fn destroy_substream(&self, s: Self::Substream);
/// Closes this `StreamMuxer`. /// Closes this `StreamMuxer`.
/// ///
/// After this has returned `Poll::Ready(Ok(()))`, the muxer has become useless. All /// After this has returned `Poll::Ready(Ok(()))`, the muxer has become useless. All
/// subsequent reads must return either `EOF` or an error. All subsequent writes, shutdowns, /// subsequent reads must return either `EOF` or an error. All subsequent writes, shutdowns,
/// or polls must generate an error or be ignored. /// or polls must generate an error or be ignored.
/// ///
/// Calling this method implies `flush_all`.
///
/// > **Note**: You are encouraged to call this method and wait for it to return `Ready`, so /// > **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 /// > that the remote is properly informed of the shutdown. However, apart from
/// > properly informing the remote, there is no difference between this and /// > properly informing the remote, there is no difference between this and
@ -247,252 +168,3 @@ impl<T> StreamMuxerEvent<T> {
} }
} }
} }
/// Polls for an event from the muxer and, if an inbound substream, wraps this substream in an
/// object that implements `Read`/`Write`/`AsyncRead`/`AsyncWrite`.
pub fn event_from_ref_and_wrap<P>(
muxer: P,
) -> impl Future<Output = Result<StreamMuxerEvent<SubstreamRef<P>>, <P::Target as StreamMuxer>::Error>>
where
P: Deref + Clone,
P::Target: StreamMuxer,
{
let muxer2 = muxer.clone();
future::poll_fn(move |cx| muxer.poll_event(cx)).map_ok(|event| match event {
StreamMuxerEvent::InboundSubstream(substream) => {
StreamMuxerEvent::InboundSubstream(substream_from_ref(muxer2, substream))
}
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
})
}
/// Same as `outbound_from_ref`, but wraps the output in an object that
/// implements `Read`/`Write`/`AsyncRead`/`AsyncWrite`.
pub fn outbound_from_ref_and_wrap<P>(muxer: P) -> OutboundSubstreamRefWrapFuture<P>
where
P: Deref + Clone,
P::Target: StreamMuxer,
{
let inner = outbound_from_ref(muxer);
OutboundSubstreamRefWrapFuture { inner }
}
/// Future returned by `outbound_from_ref_and_wrap`.
pub struct OutboundSubstreamRefWrapFuture<P>
where
P: Deref + Clone,
P::Target: StreamMuxer,
{
inner: OutboundSubstreamRefFuture<P>,
}
impl<P> Future for OutboundSubstreamRefWrapFuture<P>
where
P: Deref + Clone,
P::Target: StreamMuxer,
{
type Output = Result<SubstreamRef<P>, <P::Target as StreamMuxer>::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match Future::poll(Pin::new(&mut self.inner), cx) {
Poll::Ready(Ok(substream)) => {
let out = substream_from_ref(self.inner.muxer.clone(), substream);
Poll::Ready(Ok(out))
}
Poll::Pending => Poll::Pending,
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
}
}
}
/// Builds a new future for an outbound substream, where the muxer is a reference.
pub fn outbound_from_ref<P>(muxer: P) -> OutboundSubstreamRefFuture<P>
where
P: Deref,
P::Target: StreamMuxer,
{
let outbound = muxer.open_outbound();
OutboundSubstreamRefFuture {
muxer,
outbound: Some(outbound),
}
}
/// Future returned by `outbound_from_ref`.
pub struct OutboundSubstreamRefFuture<P>
where
P: Deref,
P::Target: StreamMuxer,
{
muxer: P,
outbound: Option<<P::Target as StreamMuxer>::OutboundSubstream>,
}
impl<P> Unpin for OutboundSubstreamRefFuture<P>
where
P: Deref,
P::Target: StreamMuxer,
{
}
impl<P> Future for OutboundSubstreamRefFuture<P>
where
P: Deref,
P::Target: StreamMuxer,
{
type Output = Result<<P::Target as StreamMuxer>::Substream, <P::Target as StreamMuxer>::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
this.muxer
.poll_outbound(cx, this.outbound.as_mut().expect("outbound was empty"))
}
}
impl<P> Drop for OutboundSubstreamRefFuture<P>
where
P: Deref,
P::Target: StreamMuxer,
{
fn drop(&mut self) {
self.muxer
.destroy_outbound(self.outbound.take().expect("outbound was empty"))
}
}
/// Builds an implementation of `Read`/`Write`/`AsyncRead`/`AsyncWrite` from an `Arc` to the
/// muxer and a substream.
pub fn substream_from_ref<P>(
muxer: P,
substream: <P::Target as StreamMuxer>::Substream,
) -> SubstreamRef<P>
where
P: Deref,
P::Target: StreamMuxer,
{
SubstreamRef {
muxer,
substream: Some(substream),
shutdown_state: ShutdownState::Shutdown,
}
}
/// Stream returned by `substream_from_ref`.
pub struct SubstreamRef<P>
where
P: Deref,
P::Target: StreamMuxer,
{
muxer: P,
substream: Option<<P::Target as StreamMuxer>::Substream>,
shutdown_state: ShutdownState,
}
enum ShutdownState {
Shutdown,
Flush,
Done,
}
impl<P> fmt::Debug for SubstreamRef<P>
where
P: Deref,
P::Target: StreamMuxer,
<P::Target as StreamMuxer>::Substream: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "Substream({:?})", self.substream)
}
}
impl<P> Unpin for SubstreamRef<P>
where
P: Deref,
P::Target: StreamMuxer,
{
}
impl<P> AsyncRead for SubstreamRef<P>
where
P: Deref,
P::Target: StreamMuxer,
{
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
let s = this.substream.as_mut().expect("substream was empty");
this.muxer.read_substream(cx, s, buf).map_err(|e| e.into())
}
}
impl<P> AsyncWrite for SubstreamRef<P>
where
P: Deref,
P::Target: StreamMuxer,
{
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
let s = this.substream.as_mut().expect("substream was empty");
this.muxer.write_substream(cx, s, buf).map_err(|e| e.into())
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
let s = this.substream.as_mut().expect("substream was empty");
loop {
match this.shutdown_state {
ShutdownState::Shutdown => match this.muxer.shutdown_substream(cx, s) {
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Flush,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
Poll::Pending => return Poll::Pending,
},
ShutdownState::Flush => match this.muxer.flush_substream(cx, s) {
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Done,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
Poll::Pending => return Poll::Pending,
},
ShutdownState::Done => {
return Poll::Ready(Ok(()));
}
}
}
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
let s = this.substream.as_mut().expect("substream was empty");
this.muxer.flush_substream(cx, s).map_err(|e| e.into())
}
}
impl<P> Drop for SubstreamRef<P>
where
P: Deref,
P::Target: StreamMuxer,
{
fn drop(&mut self) {
self.muxer
.destroy_substream(self.substream.take().expect("substream was empty"))
}
}

View File

@ -1,27 +1,35 @@
use crate::muxing::StreamMuxerEvent; use crate::muxing::StreamMuxerEvent;
use crate::StreamMuxer; use crate::StreamMuxer;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use futures::{AsyncRead, AsyncWrite};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::fmt;
use std::io; use std::io;
use std::io::{IoSlice, IoSliceMut};
use std::pin::Pin;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll}; use std::task::{Context, Poll};
/// Abstract `StreamMuxer`. /// Abstract `StreamMuxer`.
pub struct StreamMuxerBox { pub struct StreamMuxerBox {
inner: Box< inner: Box<
dyn StreamMuxer<Substream = usize, OutboundSubstream = usize, Error = io::Error> dyn StreamMuxer<Substream = SubstreamBox, OutboundSubstream = usize, Error = io::Error>
+ Send + Send
+ Sync, + Sync,
>, >,
} }
/// Abstract type for asynchronous reading and writing.
///
/// A [`SubstreamBox`] erases the concrete type it is given and only retains its `AsyncRead`
/// and `AsyncWrite` capabilities.
pub struct SubstreamBox(Box<dyn AsyncReadWrite + Send + Unpin>);
struct Wrap<T> struct Wrap<T>
where where
T: StreamMuxer, T: StreamMuxer,
{ {
inner: T, inner: T,
substreams: Mutex<FnvHashMap<usize, T::Substream>>,
next_substream: AtomicUsize,
outbound: Mutex<FnvHashMap<usize, T::OutboundSubstream>>, outbound: Mutex<FnvHashMap<usize, T::OutboundSubstream>>,
next_outbound: AtomicUsize, next_outbound: AtomicUsize,
} }
@ -29,8 +37,9 @@ where
impl<T> StreamMuxer for Wrap<T> impl<T> StreamMuxer for Wrap<T>
where where
T: StreamMuxer, T: StreamMuxer,
T::Substream: Send + Unpin + 'static,
{ {
type Substream = usize; // TODO: use a newtype type Substream = SubstreamBox;
type OutboundSubstream = usize; // TODO: use a newtype type OutboundSubstream = usize; // TODO: use a newtype
type Error = io::Error; type Error = io::Error;
@ -48,9 +57,9 @@ where
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())), Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
}; };
let id = self.next_substream.fetch_add(1, Ordering::Relaxed); Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(SubstreamBox::new(
self.substreams.lock().insert(id, substream); substream,
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(id))) ))))
} }
#[inline] #[inline]
@ -76,9 +85,8 @@ where
Poll::Ready(Ok(s)) => s, Poll::Ready(Ok(s)) => s,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())), Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
}; };
let id = self.next_substream.fetch_add(1, Ordering::Relaxed);
self.substreams.lock().insert(id, substream); Poll::Ready(Ok(SubstreamBox::new(substream)))
Poll::Ready(Ok(id))
} }
#[inline] #[inline]
@ -88,63 +96,6 @@ where
.destroy_outbound(list.remove(&substream).unwrap()) .destroy_outbound(list.remove(&substream).unwrap())
} }
#[inline]
fn read_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>> {
let mut list = self.substreams.lock();
self.inner
.read_substream(cx, list.get_mut(s).unwrap(), buf)
.map_err(|e| e.into())
}
#[inline]
fn write_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>> {
let mut list = self.substreams.lock();
self.inner
.write_substream(cx, list.get_mut(s).unwrap(), buf)
.map_err(|e| e.into())
}
#[inline]
fn flush_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
let mut list = self.substreams.lock();
self.inner
.flush_substream(cx, list.get_mut(s).unwrap())
.map_err(|e| e.into())
}
#[inline]
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
let mut list = self.substreams.lock();
self.inner
.shutdown_substream(cx, list.get_mut(s).unwrap())
.map_err(|e| e.into())
}
#[inline]
fn destroy_substream(&self, substream: Self::Substream) {
let mut list = self.substreams.lock();
self.inner
.destroy_substream(list.remove(&substream).unwrap())
}
#[inline] #[inline]
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_close(cx).map_err(|e| e.into()) self.inner.poll_close(cx).map_err(|e| e.into())
@ -157,12 +108,10 @@ impl StreamMuxerBox {
where where
T: StreamMuxer + Send + Sync + 'static, T: StreamMuxer + Send + Sync + 'static,
T::OutboundSubstream: Send, T::OutboundSubstream: Send,
T::Substream: Send, T::Substream: Send + Unpin + 'static,
{ {
let wrap = Wrap { let wrap = Wrap {
inner: muxer, inner: muxer,
substreams: Mutex::new(Default::default()),
next_substream: AtomicUsize::new(0),
outbound: Mutex::new(Default::default()), outbound: Mutex::new(Default::default()),
next_outbound: AtomicUsize::new(0), next_outbound: AtomicUsize::new(0),
}; };
@ -174,7 +123,7 @@ impl StreamMuxerBox {
} }
impl StreamMuxer for StreamMuxerBox { impl StreamMuxer for StreamMuxerBox {
type Substream = usize; // TODO: use a newtype type Substream = SubstreamBox;
type OutboundSubstream = usize; // TODO: use a newtype type OutboundSubstream = usize; // TODO: use a newtype
type Error = io::Error; type Error = io::Error;
@ -205,51 +154,82 @@ impl StreamMuxer for StreamMuxerBox {
self.inner.destroy_outbound(substream) self.inner.destroy_outbound(substream)
} }
#[inline]
fn read_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>> {
self.inner.read_substream(cx, s, buf)
}
#[inline]
fn write_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>> {
self.inner.write_substream(cx, s, buf)
}
#[inline]
fn flush_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
self.inner.flush_substream(cx, s)
}
#[inline]
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
self.inner.shutdown_substream(cx, s)
}
#[inline]
fn destroy_substream(&self, s: Self::Substream) {
self.inner.destroy_substream(s)
}
#[inline] #[inline]
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.inner.poll_close(cx) self.inner.poll_close(cx)
} }
} }
impl SubstreamBox {
/// Construct a new [`SubstreamBox`] from something that implements [`AsyncRead`] and [`AsyncWrite`].
pub fn new<S: AsyncRead + AsyncWrite + Send + Unpin + 'static>(stream: S) -> Self {
Self(Box::new(stream))
}
}
impl fmt::Debug for SubstreamBox {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SubstreamBox({})", self.0.type_name())
}
}
/// Workaround because Rust does not allow `Box<dyn AsyncRead + AsyncWrite>`.
trait AsyncReadWrite: AsyncRead + AsyncWrite + Unpin {
/// Helper function to capture the erased inner type.
///
/// Used to make the [`Debug`] implementation of [`SubstreamBox`] more useful.
fn type_name(&self) -> &'static str;
}
impl<S> AsyncReadWrite for S
where
S: AsyncRead + AsyncWrite + Unpin,
{
fn type_name(&self) -> &'static str {
std::any::type_name::<S>()
}
}
impl AsyncRead for SubstreamBox {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<std::io::Result<usize>> {
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<std::io::Result<usize>> {
Pin::new(&mut self.get_mut().0).poll_read_vectored(cx, bufs)
}
}
impl AsyncWrite for SubstreamBox {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<std::io::Result<usize>> {
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<std::io::Result<usize>> {
Pin::new(&mut self.get_mut().0).poll_write_vectored(cx, bufs)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
Pin::new(&mut self.get_mut().0).poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
Pin::new(&mut self.get_mut().0).poll_close(cx)
}
}

View File

@ -24,14 +24,8 @@ use crate::{
}; };
use futures::prelude::*; use futures::prelude::*;
use parking_lot::Mutex; use std::cell::Cell;
use std::{ use std::{io, task::Context, task::Poll};
io,
pin::Pin,
sync::atomic::{AtomicBool, Ordering},
task::Context,
task::Poll,
};
/// Implementation of `StreamMuxer` that allows only one substream on top of a connection, /// Implementation of `StreamMuxer` that allows only one substream on top of a connection,
/// yielding the connection itself. /// yielding the connection itself.
@ -40,9 +34,7 @@ use std::{
/// Most notably, no protocol is negotiated. /// Most notably, no protocol is negotiated.
pub struct SingletonMuxer<TSocket> { pub struct SingletonMuxer<TSocket> {
/// The inner connection. /// The inner connection.
inner: Mutex<TSocket>, inner: Cell<Option<TSocket>>,
/// If true, a substream has been produced and any further attempt should fail.
substream_extracted: AtomicBool,
/// Our local endpoint. Always the same value as was passed to `new`. /// Our local endpoint. Always the same value as was passed to `new`.
endpoint: Endpoint, endpoint: Endpoint,
} }
@ -54,15 +46,12 @@ impl<TSocket> SingletonMuxer<TSocket> {
/// If `endpoint` is `Listener`, then only one inbound substream will be permitted. /// If `endpoint` is `Listener`, then only one inbound substream will be permitted.
pub fn new(inner: TSocket, endpoint: Endpoint) -> Self { pub fn new(inner: TSocket, endpoint: Endpoint) -> Self {
SingletonMuxer { SingletonMuxer {
inner: Mutex::new(inner), inner: Cell::new(Some(inner)),
substream_extracted: AtomicBool::new(false),
endpoint, endpoint,
} }
} }
} }
/// Substream of the `SingletonMuxer`.
pub struct Substream {}
/// Outbound substream attempt of the `SingletonMuxer`. /// Outbound substream attempt of the `SingletonMuxer`.
pub struct OutboundSubstream {} pub struct OutboundSubstream {}
@ -70,7 +59,7 @@ impl<TSocket> StreamMuxer for SingletonMuxer<TSocket>
where where
TSocket: AsyncRead + AsyncWrite + Unpin, TSocket: AsyncRead + AsyncWrite + Unpin,
{ {
type Substream = Substream; type Substream = TSocket;
type OutboundSubstream = OutboundSubstream; type OutboundSubstream = OutboundSubstream;
type Error = io::Error; type Error = io::Error;
@ -83,8 +72,8 @@ where
Endpoint::Listener => {} Endpoint::Listener => {}
} }
if !self.substream_extracted.swap(true, Ordering::Relaxed) { if let Some(stream) = self.inner.replace(None) {
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(Substream {}))) Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(stream)))
} else { } else {
Poll::Pending Poll::Pending
} }
@ -104,8 +93,8 @@ where
Endpoint::Dialer => {} Endpoint::Dialer => {}
} }
if !self.substream_extracted.swap(true, Ordering::Relaxed) { if let Some(stream) = self.inner.replace(None) {
Poll::Ready(Ok(Substream {})) Poll::Ready(Ok(stream))
} else { } else {
Poll::Pending Poll::Pending
} }
@ -113,42 +102,6 @@ where
fn destroy_outbound(&self, _: Self::OutboundSubstream) {} fn destroy_outbound(&self, _: Self::OutboundSubstream) {}
fn read_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
AsyncRead::poll_read(Pin::new(&mut *self.inner.lock()), cx, buf)
}
fn write_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
AsyncWrite::poll_write(Pin::new(&mut *self.inner.lock()), cx, buf)
}
fn flush_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
) -> Poll<Result<(), io::Error>> {
AsyncWrite::poll_flush(Pin::new(&mut *self.inner.lock()), cx)
}
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
) -> Poll<Result<(), io::Error>> {
AsyncWrite::poll_close(Pin::new(&mut *self.inner.lock()), cx)
}
fn destroy_substream(&self, _: Self::Substream) {}
fn poll_close(&self, _cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> { fn poll_close(&self, _cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }

View File

@ -300,7 +300,7 @@ impl<T> Multiplexed<T> {
T::ListenerUpgrade: Send + 'static, T::ListenerUpgrade: Send + 'static,
T::Error: Send + Sync, T::Error: Send + Sync,
M: StreamMuxer + Send + Sync + 'static, M: StreamMuxer + Send + Sync + 'static,
M::Substream: Send + 'static, M::Substream: Send + Unpin + 'static,
M::OutboundSubstream: Send + 'static, M::OutboundSubstream: Send + 'static,
{ {
boxed(self.map(|(i, m), _| (i, StreamMuxerBox::new(m)))) boxed(self.map(|(i, m), _| (i, StreamMuxerBox::new(m))))

View File

@ -13,5 +13,5 @@ clap = {version = "3.1.6", features = ["derive"]}
zeroize = "1" zeroize = "1"
serde = { version = "1.0.136", features = ["derive"] } serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79" serde_json = "1.0.79"
libp2p-core = { path = "../../core", default-features = false, version = "0.33.0"} libp2p-core = { path = "../../core", default-features = false, version = "0.34.0"}
base64 = "0.13.0" base64 = "0.13.0"

View File

@ -1,3 +1,19 @@
# 0.7.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
- Update to `libp2p-dcutr` `v0.4.0`.
- Update to `libp2p-ping` `v0.37.0`.
- Update to `libp2p-identify` `v0.37.0`.
- Update to `libp2p-relay` `v0.10.0`.
- Update to `libp2p-kad` `v0.38.0`.
# 0.6.1 # 0.6.1
- Update `dcutr` events from `libp2p_relay_events` to `libp2p_dcutr_events`, to avoid conflict with `relay` events. - Update `dcutr` events from `libp2p_relay_events` to `libp2p_dcutr_events`, to avoid conflict with `relay` events.

View File

@ -3,7 +3,7 @@ name = "libp2p-metrics"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Metrics for libp2p" description = "Metrics for libp2p"
version = "0.6.1" version = "0.7.0"
authors = ["Max Inden <mail@max-inden.de>"] authors = ["Max Inden <mail@max-inden.de>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -19,17 +19,17 @@ relay = ["libp2p-relay"]
dcutr = ["libp2p-dcutr"] dcutr = ["libp2p-dcutr"]
[dependencies] [dependencies]
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-dcutr = { version = "0.3.0", path = "../../protocols/dcutr", optional = true } libp2p-dcutr = { version = "0.4.0", path = "../../protocols/dcutr", optional = true }
libp2p-identify = { version = "0.36.0", path = "../../protocols/identify", optional = true } libp2p-identify = { version = "0.37.0", path = "../../protocols/identify", optional = true }
libp2p-kad = { version = "0.37.0", path = "../../protocols/kad", optional = true } libp2p-kad = { version = "0.38.0", path = "../../protocols/kad", optional = true }
libp2p-ping = { version = "0.36.0", path = "../../protocols/ping", optional = true } libp2p-ping = { version = "0.37.0", path = "../../protocols/ping", optional = true }
libp2p-relay = { version = "0.9.0", path = "../../protocols/relay", optional = true } libp2p-relay = { version = "0.10.0", path = "../../protocols/relay", optional = true }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
prometheus-client = "0.16.0" prometheus-client = "0.16.0"
[target.'cfg(not(target_os = "unknown"))'.dependencies] [target.'cfg(not(target_os = "unknown"))'.dependencies]
libp2p-gossipsub = { version = "0.38.0", path = "../../protocols/gossipsub", optional = true } libp2p-gossipsub = { version = "0.39.0", path = "../../protocols/gossipsub", optional = true }
[dev-dependencies] [dev-dependencies]
log = "0.4.0" log = "0.4.0"

View File

@ -1,6 +1,7 @@
# 0.34.0 [unreleased] # 0.34.0 [unreleased]
- `Substream` now implements `AsyncRead` and `AsyncWrite`. See [PR 2706]. - `Substream` now implements `AsyncRead` and `AsyncWrite`. See [PR 2706].
- Update to `libp2p-core` `v0.34.0`
[PR 2706]: https://github.com/libp2p/rust-libp2p/pull/2706/ [PR 2706]: https://github.com/libp2p/rust-libp2p/pull/2706/

View File

@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
bytes = "1" bytes = "1"
futures = "0.3.1" futures = "0.3.1"
asynchronous-codec = "0.6" asynchronous-codec = "0.6"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
log = "0.4" log = "0.4"
nohash-hasher = "0.2" nohash-hasher = "0.2"
parking_lot = "0.12" parking_lot = "0.12"

View File

@ -32,6 +32,7 @@ use libp2p_core::{
}; };
use libp2p_mplex as mplex; use libp2p_mplex as mplex;
use libp2p_plaintext::PlainText2Config; use libp2p_plaintext::PlainText2Config;
use std::pin::Pin;
use std::time::Duration; use std::time::Duration;
type BenchTransport = transport::Boxed<(PeerId, muxing::StreamMuxerBox)>; type BenchTransport = transport::Boxed<(PeerId, muxing::StreamMuxerBox)>;
@ -115,7 +116,7 @@ fn run(transport: &mut BenchTransport, payload: &Vec<u8>, listen_addr: &Multiadd
loop { loop {
// Read in typical chunk sizes of up to 8KiB. // Read in typical chunk sizes of up to 8KiB.
let end = off + std::cmp::min(buf.len() - off, 8 * 1024); let end = off + std::cmp::min(buf.len() - off, 8 * 1024);
let n = poll_fn(|cx| conn.read_substream(cx, &mut s, &mut buf[off..end])) let n = poll_fn(|cx| Pin::new(&mut s).poll_read(cx, &mut buf[off..end]))
.await .await
.unwrap(); .unwrap();
off += n; off += n;
@ -139,12 +140,12 @@ fn run(transport: &mut BenchTransport, payload: &Vec<u8>, listen_addr: &Multiadd
.unwrap(); .unwrap();
let mut off = 0; let mut off = 0;
loop { loop {
let n = poll_fn(|cx| conn.write_substream(cx, &mut stream, &payload[off..])) let n = poll_fn(|cx| Pin::new(&mut stream).poll_write(cx, &payload[off..]))
.await .await
.unwrap(); .unwrap();
off += n; off += n;
if off == payload.len() { if off == payload.len() {
poll_fn(|cx| conn.flush_substream(cx, &mut stream)) poll_fn(|cx| Pin::new(&mut stream).poll_flush(cx))
.await .await
.unwrap(); .unwrap();
return; return;

View File

@ -116,44 +116,6 @@ where
// Nothing to do, since `open_outbound` creates no new local state. // Nothing to do, since `open_outbound` creates no new local state.
} }
fn read_substream(
&self,
cx: &mut Context<'_>,
substream: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
Pin::new(substream).poll_read(cx, buf)
}
fn write_substream(
&self,
cx: &mut Context<'_>,
substream: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
Pin::new(substream).poll_write(cx, buf)
}
fn flush_substream(
&self,
cx: &mut Context<'_>,
substream: &mut Self::Substream,
) -> Poll<Result<(), io::Error>> {
Pin::new(substream).poll_flush(cx)
}
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
substream: &mut Self::Substream,
) -> Poll<Result<(), io::Error>> {
Pin::new(substream).poll_close(cx)
}
fn destroy_substream(&self, sub: Self::Substream) {
std::mem::drop(sub)
}
fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> { fn poll_close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
self.io.lock().poll_close(cx) self.io.lock().poll_close(cx)
} }

View File

@ -18,8 +18,9 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
use futures::future::poll_fn;
use futures::{channel::oneshot, prelude::*}; use futures::{channel::oneshot, prelude::*};
use libp2p_core::{muxing, upgrade, Transport}; use libp2p_core::{upgrade, StreamMuxer, Transport};
use libp2p_tcp::TcpConfig; use libp2p_tcp::TcpConfig;
use std::sync::Arc; use std::sync::Arc;
@ -60,7 +61,8 @@ fn async_write() {
.await .await
.unwrap(); .unwrap();
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client)) let mut outbound_token = client.open_outbound();
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
.await .await
.unwrap(); .unwrap();
@ -76,7 +78,7 @@ fn async_write() {
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap()); let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
let mut inbound = loop { let mut inbound = loop {
if let Some(s) = muxing::event_from_ref_and_wrap(client.clone()) if let Some(s) = poll_fn(|cx| client.poll_event(cx))
.await .await
.unwrap() .unwrap()
.into_inbound_substream() .into_inbound_substream()

View File

@ -18,8 +18,9 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
use futures::future::poll_fn;
use futures::{channel::oneshot, prelude::*}; use futures::{channel::oneshot, prelude::*};
use libp2p_core::{muxing, upgrade, Transport}; use libp2p_core::{upgrade, StreamMuxer, Transport};
use libp2p_tcp::TcpConfig; use libp2p_tcp::TcpConfig;
use std::sync::Arc; use std::sync::Arc;
@ -60,7 +61,8 @@ fn client_to_server_outbound() {
.await .await
.unwrap(); .unwrap();
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client)) let mut outbound_token = client.open_outbound();
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
.await .await
.unwrap(); .unwrap();
@ -76,7 +78,7 @@ fn client_to_server_outbound() {
let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap()); let client = Arc::new(transport.dial(rx.await.unwrap()).unwrap().await.unwrap());
let mut inbound = loop { let mut inbound = loop {
if let Some(s) = muxing::event_from_ref_and_wrap(client.clone()) if let Some(s) = poll_fn(|cx| client.poll_event(cx))
.await .await
.unwrap() .unwrap()
.into_inbound_substream() .into_inbound_substream()
@ -131,7 +133,7 @@ fn client_to_server_inbound() {
); );
let mut inbound = loop { let mut inbound = loop {
if let Some(s) = muxing::event_from_ref_and_wrap(client.clone()) if let Some(s) = poll_fn(|cx| client.poll_event(cx))
.await .await
.unwrap() .unwrap()
.into_inbound_substream() .into_inbound_substream()
@ -151,7 +153,9 @@ fn client_to_server_inbound() {
.and_then(move |c, e| upgrade::apply(c, mplex, e, upgrade::Version::V1)); .and_then(move |c, e| upgrade::apply(c, mplex, e, upgrade::Version::V1));
let client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap(); let client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap();
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client))
let mut outbound_token = client.open_outbound();
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
.await .await
.unwrap(); .unwrap();
outbound.write_all(b"hello world").await.unwrap(); outbound.write_all(b"hello world").await.unwrap();
@ -196,7 +200,8 @@ fn protocol_not_match() {
.await .await
.unwrap(); .unwrap();
let mut outbound = muxing::outbound_from_ref_and_wrap(Arc::new(client)) let mut outbound_token = client.open_outbound();
let mut outbound = poll_fn(|cx| client.poll_outbound(cx, &mut outbound_token))
.await .await
.unwrap(); .unwrap();

View File

@ -1,3 +1,7 @@
# 0.38.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.37.0 # 0.37.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-yamux"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Yamux multiplexing protocol for libp2p" description = "Yamux multiplexing protocol for libp2p"
version = "0.37.0" version = "0.38.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
parking_lot = "0.12" parking_lot = "0.12"
thiserror = "1.0" thiserror = "1.0"
yamux = "0.10.0" yamux = "0.10.0"

View File

@ -137,46 +137,6 @@ where
self.0.lock().control.abort_open_stream() self.0.lock().control.abort_open_stream()
} }
fn read_substream(
&self,
c: &mut Context<'_>,
s: &mut Self::Substream,
b: &mut [u8],
) -> Poll<YamuxResult<usize>> {
Pin::new(s)
.poll_read(c, b)
.map_err(|e| YamuxError(e.into()))
}
fn write_substream(
&self,
c: &mut Context<'_>,
s: &mut Self::Substream,
b: &[u8],
) -> Poll<YamuxResult<usize>> {
Pin::new(s)
.poll_write(c, b)
.map_err(|e| YamuxError(e.into()))
}
fn flush_substream(
&self,
c: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<YamuxResult<()>> {
Pin::new(s).poll_flush(c).map_err(|e| YamuxError(e.into()))
}
fn shutdown_substream(
&self,
c: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<YamuxResult<()>> {
Pin::new(s).poll_close(c).map_err(|e| YamuxError(e.into()))
}
fn destroy_substream(&self, _: Self::Substream) {}
fn poll_close(&self, c: &mut Context<'_>) -> Poll<YamuxResult<()>> { fn poll_close(&self, c: &mut Context<'_>) -> Poll<YamuxResult<()>> {
let mut inner = self.0.lock(); let mut inner = self.0.lock();

View File

@ -1,3 +1,11 @@
# 0.5.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
- Update to `libp2p-request-response` `v0.19.0`.
# 0.4.1 # 0.4.1
- Export `DEFAULT_PROTOCOL_NAME`. - Export `DEFAULT_PROTOCOL_NAME`.

View File

@ -3,7 +3,7 @@ name = "libp2p-autonat"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "NAT and firewall detection for libp2p" description = "NAT and firewall detection for libp2p"
version = "0.4.1" version = "0.5.0"
authors = ["David Craven <david@craven.ch>", "Elena Frank <elena.frank@protonmail.com>"] authors = ["David Craven <david@craven.ch>", "Elena Frank <elena.frank@protonmail.com>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -18,9 +18,9 @@ async-trait = "0.1"
futures = "0.3" futures = "0.3"
futures-timer = "3.0" futures-timer = "3.0"
instant = "0.1" instant = "0.1"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
libp2p-request-response = { version = "0.18.0", path = "../request-response" } libp2p-request-response = { version = "0.19.0", path = "../request-response" }
log = "0.4" log = "0.4"
rand = "0.8" rand = "0.8"
prost = "0.10" prost = "0.10"

View File

@ -1,3 +1,9 @@
# 0.4.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.3.1 # 0.3.1
- Upgrade at most one inbound connect request. - Upgrade at most one inbound connect request.

View File

@ -3,7 +3,7 @@ name = "libp2p-dcutr"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Direct connection upgrade through relay" description = "Direct connection upgrade through relay"
version = "0.3.1" version = "0.4.0"
authors = ["Max Inden <mail@max-inden.de>"] authors = ["Max Inden <mail@max-inden.de>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -17,8 +17,8 @@ either = "1.6.0"
futures = "0.3.1" futures = "0.3.1"
futures-timer = "3.0" futures-timer = "3.0"
instant = "0.1.11" instant = "0.1.11"
libp2p-core = { version = "0.33.0", path = "../../core" } libp2p-core = { version = "0.34.0", path = "../../core" }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
log = "0.4" log = "0.4"
prost-codec = { version = "0.1", path = "../../misc/prost-codec" } prost-codec = { version = "0.1", path = "../../misc/prost-codec" }
prost = "0.10" prost = "0.10"

View File

@ -1,3 +1,9 @@
# 0.37.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.36.0 # 0.36.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-floodsub"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Floodsub protocol for libp2p" description = "Floodsub protocol for libp2p"
version = "0.36.0" version = "0.37.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -14,8 +14,8 @@ categories = ["network-programming", "asynchronous"]
cuckoofilter = "0.5.0" cuckoofilter = "0.5.0"
fnv = "1.0" fnv = "1.0"
futures = "0.3.1" futures = "0.3.1"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
log = "0.4" log = "0.4"
prost = "0.10" prost = "0.10"
rand = "0.7" rand = "0.7"

View File

@ -1,3 +1,9 @@
# 0.39.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.38.1 # 0.38.1
- Fix duplicate connection id. See [PR 2702]. - Fix duplicate connection id. See [PR 2702].

View File

@ -3,7 +3,7 @@ name = "libp2p-gossipsub"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Gossipsub protocol for libp2p" description = "Gossipsub protocol for libp2p"
version = "0.38.1" version = "0.39.0"
authors = ["Age Manning <Age@AgeManning.com>"] authors = ["Age Manning <Age@AgeManning.com>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -11,8 +11,8 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
categories = ["network-programming", "asynchronous"] categories = ["network-programming", "asynchronous"]
[dependencies] [dependencies]
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
bytes = "1.0" bytes = "1.0"
byteorder = "1.3.4" byteorder = "1.3.4"
fnv = "1.0.7" fnv = "1.0.7"

View File

@ -1,3 +1,9 @@
# 0.37.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.36.1 # 0.36.1
- Allow at most one inbound identify push stream. - Allow at most one inbound identify push stream.

View File

@ -3,7 +3,7 @@ name = "libp2p-identify"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Nodes identifcation protocol for libp2p" description = "Nodes identifcation protocol for libp2p"
version = "0.36.1" version = "0.37.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -14,8 +14,8 @@ categories = ["network-programming", "asynchronous"]
asynchronous-codec = "0.6" asynchronous-codec = "0.6"
futures = "0.3.1" futures = "0.3.1"
futures-timer = "3.0.2" futures-timer = "3.0.2"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
log = "0.4.1" log = "0.4.1"
lru = "0.7.2" lru = "0.7.2"
prost-codec = { version = "0.1", path = "../../misc/prost-codec" } prost-codec = { version = "0.1", path = "../../misc/prost-codec" }

View File

@ -1,3 +1,9 @@
# 0.38.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.37.1 # 0.37.1
- Limit # of inbound streams to 32. [See PR 2699]. - Limit # of inbound streams to 32. [See PR 2699].

View File

@ -3,7 +3,7 @@ name = "libp2p-kad"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Kademlia protocol for libp2p" description = "Kademlia protocol for libp2p"
version = "0.37.1" version = "0.38.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -18,8 +18,8 @@ fnv = "1.0"
asynchronous-codec = "0.6" asynchronous-codec = "0.6"
futures = "0.3.1" futures = "0.3.1"
log = "0.4" log = "0.4"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
prost = "0.10" prost = "0.10"
rand = "0.7.2" rand = "0.7.2"
sha2 = "0.10.0" sha2 = "0.10.0"

View File

@ -1,3 +1,9 @@
# 0.38.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.37.0 # 0.37.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -2,7 +2,7 @@
name = "libp2p-mdns" name = "libp2p-mdns"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
version = "0.37.0" version = "0.38.0"
description = "Implementation of the libp2p mDNS discovery method" description = "Implementation of the libp2p mDNS discovery method"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
@ -17,8 +17,8 @@ dns-parser = "0.8.0"
futures = "0.3.13" futures = "0.3.13"
if-watch = "1.0.0" if-watch = "1.0.0"
lazy_static = "1.4.0" lazy_static = "1.4.0"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
log = "0.4.14" log = "0.4.14"
rand = "0.8.3" rand = "0.8.3"
smallvec = "1.6.1" smallvec = "1.6.1"

View File

@ -1,3 +1,9 @@
# 0.37.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.36.0 # 0.36.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-ping"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Ping protocol for libp2p" description = "Ping protocol for libp2p"
version = "0.36.0" version = "0.37.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -14,8 +14,8 @@ categories = ["network-programming", "asynchronous"]
futures = "0.3.1" futures = "0.3.1"
futures-timer = "3.0.2" futures-timer = "3.0.2"
instant = "0.1.11" instant = "0.1.11"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
log = "0.4.1" log = "0.4.1"
rand = "0.7.2" rand = "0.7.2"
void = "1.0" void = "1.0"

View File

@ -1,3 +1,9 @@
# 0.10.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.9.1 # 0.9.1
- Respond to at most one incoming reservation request. Deny <= 8 incoming - Respond to at most one incoming reservation request. Deny <= 8 incoming

View File

@ -3,7 +3,7 @@ name = "libp2p-relay"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Communications relaying for libp2p" description = "Communications relaying for libp2p"
version = "0.9.1" version = "0.10.0"
authors = ["Parity Technologies <admin@parity.io>", "Max Inden <mail@max-inden.de>"] authors = ["Parity Technologies <admin@parity.io>", "Max Inden <mail@max-inden.de>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -17,8 +17,8 @@ either = "1.6.0"
futures = "0.3.1" futures = "0.3.1"
futures-timer = "3" futures-timer = "3"
instant = "0.1.11" instant = "0.1.11"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
log = "0.4" log = "0.4"
pin-project = "1" pin-project = "1"
prost-codec = { version = "0.1", path = "../../misc/prost-codec" } prost-codec = { version = "0.1", path = "../../misc/prost-codec" }

View File

@ -1,3 +1,9 @@
# 0.7.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.6.0 # 0.6.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-rendezvous"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Rendezvous protocol for libp2p" description = "Rendezvous protocol for libp2p"
version = "0.6.0" version = "0.7.0"
authors = ["The COMIT guys <hello@comit.network>"] authors = ["The COMIT guys <hello@comit.network>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -12,8 +12,8 @@ categories = ["network-programming", "asynchronous"]
[dependencies] [dependencies]
asynchronous-codec = "0.6" asynchronous-codec = "0.6"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
prost = "0.10" prost = "0.10"
void = "1" void = "1"
log = "0.4" log = "0.4"

View File

@ -1,3 +1,9 @@
# 0.19.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
- Update to `libp2p-swarm` `v0.37.0`.
# 0.18.0 # 0.18.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-request-response"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Generic Request/Response Protocols" description = "Generic Request/Response Protocols"
version = "0.18.0" version = "0.19.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -15,8 +15,8 @@ async-trait = "0.1"
bytes = "1" bytes = "1"
futures = "0.3.1" futures = "0.3.1"
instant = "0.1.11" instant = "0.1.11"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
libp2p-swarm = { version = "0.36.0", path = "../../swarm" } libp2p-swarm = { version = "0.37.0", path = "../../swarm" }
log = "0.4.11" log = "0.4.11"
rand = "0.7" rand = "0.7"
smallvec = "1.6.1" smallvec = "1.6.1"

View File

@ -1,3 +1,7 @@
# 0.37.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.36.2 [unreleased] # 0.36.2 [unreleased]
- Extend log message when exceeding inbound negotiating streams with peer ID and limit. See [PR 2716]. - Extend log message when exceeding inbound negotiating streams with peer ID and limit. See [PR 2716].

View File

@ -3,7 +3,7 @@ name = "libp2p-swarm"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "The libp2p swarm" description = "The libp2p swarm"
version = "0.36.2" version = "0.37.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -16,7 +16,7 @@ fnv = "1.0"
futures = "0.3.1" futures = "0.3.1"
futures-timer = "3.0.2" futures-timer = "3.0.2"
instant = "0.1.11" instant = "0.1.11"
libp2p-core = { version = "0.33.0", path = "../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../core", default-features = false }
log = "0.4" log = "0.4"
pin-project = "1.0.0" pin-project = "1.0.0"
rand = "0.7" rand = "0.7"

View File

@ -32,7 +32,7 @@ pub use error::{
pub use listeners::{ListenersEvent, ListenersStream}; pub use listeners::{ListenersEvent, ListenersStream};
pub use pool::{ConnectionCounters, ConnectionLimits}; pub use pool::{ConnectionCounters, ConnectionLimits};
pub use pool::{EstablishedConnection, PendingConnection}; pub use pool::{EstablishedConnection, PendingConnection};
pub use substream::{Close, Substream, SubstreamEndpoint}; pub use substream::{Close, SubstreamEndpoint};
use crate::handler::ConnectionHandler; use crate::handler::ConnectionHandler;
use crate::IntoConnectionHandler; use crate::IntoConnectionHandler;

View File

@ -18,7 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
use crate::connection::{Substream, SubstreamEndpoint}; use crate::connection::SubstreamEndpoint;
use crate::handler::{ use crate::handler::{
ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive, ConnectionHandler, ConnectionHandlerEvent, ConnectionHandlerUpgrErr, KeepAlive,
}; };
@ -30,7 +30,7 @@ use futures::stream::FuturesUnordered;
use futures_timer::Delay; use futures_timer::Delay;
use instant::Instant; use instant::Instant;
use libp2p_core::{ use libp2p_core::{
muxing::StreamMuxerBox, muxing::SubstreamBox,
upgrade::{self, InboundUpgradeApply, OutboundUpgradeApply, UpgradeError}, upgrade::{self, InboundUpgradeApply, OutboundUpgradeApply, UpgradeError},
Multiaddr, Multiaddr,
}; };
@ -55,20 +55,14 @@ where
negotiating_in: FuturesUnordered< negotiating_in: FuturesUnordered<
SubstreamUpgrade< SubstreamUpgrade<
TConnectionHandler::InboundOpenInfo, TConnectionHandler::InboundOpenInfo,
InboundUpgradeApply< InboundUpgradeApply<SubstreamBox, SendWrapper<TConnectionHandler::InboundProtocol>>,
Substream<StreamMuxerBox>,
SendWrapper<TConnectionHandler::InboundProtocol>,
>,
>, >,
>, >,
/// Futures that upgrade outgoing substreams. /// Futures that upgrade outgoing substreams.
negotiating_out: FuturesUnordered< negotiating_out: FuturesUnordered<
SubstreamUpgrade< SubstreamUpgrade<
TConnectionHandler::OutboundOpenInfo, TConnectionHandler::OutboundOpenInfo,
OutboundUpgradeApply< OutboundUpgradeApply<SubstreamBox, SendWrapper<TConnectionHandler::OutboundProtocol>>,
Substream<StreamMuxerBox>,
SendWrapper<TConnectionHandler::OutboundProtocol>,
>,
>, >,
>, >,
/// For each outbound substream request, how to upgrade it. The first element of the tuple /// For each outbound substream request, how to upgrade it. The first element of the tuple
@ -87,8 +81,8 @@ where
/// Note: This only enforces a limit on the number of concurrently /// Note: This only enforces a limit on the number of concurrently
/// negotiating inbound streams. The total number of inbound streams on a /// negotiating inbound streams. The total number of inbound streams on a
/// connection is the sum of negotiating and negotiated streams. A limit on /// connection is the sum of negotiating and negotiated streams. A limit on
/// the total number of streams can be enforced at the [`StreamMuxerBox`] /// the total number of streams can be enforced at the
/// level. /// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level.
max_negotiating_inbound_streams: usize, max_negotiating_inbound_streams: usize,
} }
@ -254,7 +248,7 @@ where
{ {
pub fn inject_substream( pub fn inject_substream(
&mut self, &mut self,
substream: Substream<StreamMuxerBox>, substream: SubstreamBox,
// The first element of the tuple is the unique upgrade identifier // The first element of the tuple is the unique upgrade identifier
// (see `unique_dial_upgrade_id`). // (see `unique_dial_upgrade_id`).
endpoint: SubstreamEndpoint<OutboundOpenInfo<TConnectionHandler>>, endpoint: SubstreamEndpoint<OutboundOpenInfo<TConnectionHandler>>,

View File

@ -20,7 +20,7 @@
use futures::prelude::*; use futures::prelude::*;
use libp2p_core::multiaddr::Multiaddr; use libp2p_core::multiaddr::Multiaddr;
use libp2p_core::muxing::{substream_from_ref, StreamMuxer, StreamMuxerEvent, SubstreamRef}; use libp2p_core::muxing::{StreamMuxer, StreamMuxerEvent};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::sync::Arc; use std::sync::Arc;
use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll}; use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll};
@ -55,9 +55,6 @@ pub struct Close<TMuxer> {
muxer: Arc<TMuxer>, muxer: Arc<TMuxer>,
} }
/// A successfully opened substream.
pub type Substream<TMuxer> = SubstreamRef<Arc<TMuxer>>;
/// Event that can happen on the `Muxing`. /// Event that can happen on the `Muxing`.
pub enum SubstreamEvent<TMuxer, TUserData> pub enum SubstreamEvent<TMuxer, TUserData>
where where
@ -67,7 +64,7 @@ where
InboundSubstream { InboundSubstream {
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is /// The newly-opened substream. Will return EOF of an error if the `Muxing` is
/// destroyed or `close_graceful` is called. /// destroyed or `close_graceful` is called.
substream: Substream<TMuxer>, substream: TMuxer::Substream,
}, },
/// An outbound substream has successfully been opened. /// An outbound substream has successfully been opened.
@ -76,7 +73,7 @@ where
user_data: TUserData, user_data: TUserData,
/// The newly-opened substream. Will return EOF of an error if the `Muxing` is /// The newly-opened substream. Will return EOF of an error if the `Muxing` is
/// destroyed or `close_graceful` is called. /// destroyed or `close_graceful` is called.
substream: Substream<TMuxer>, substream: TMuxer::Substream,
}, },
/// Address to the remote has changed. The previous one is now obsolete. /// Address to the remote has changed. The previous one is now obsolete.
@ -141,7 +138,6 @@ where
// Polling inbound substream. // Polling inbound substream.
match self.inner.poll_event(cx) { match self.inner.poll_event(cx) {
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(substream))) => { Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(substream))) => {
let substream = substream_from_ref(self.inner.clone(), substream);
return Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream })); return Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream }));
} }
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) => { Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) => {
@ -157,7 +153,6 @@ where
let (user_data, mut outbound) = self.outbound_substreams.swap_remove(n); let (user_data, mut outbound) = self.outbound_substreams.swap_remove(n);
match self.inner.poll_outbound(cx, &mut outbound) { match self.inner.poll_outbound(cx, &mut outbound) {
Poll::Ready(Ok(substream)) => { Poll::Ready(Ok(substream)) => {
let substream = substream_from_ref(self.inner.clone(), substream);
self.inner.destroy_outbound(outbound); self.inner.destroy_outbound(outbound);
return Poll::Ready(Ok(SubstreamEvent::OutboundSubstream { return Poll::Ready(Ok(SubstreamEvent::OutboundSubstream {
user_data, user_data,

View File

@ -79,11 +79,12 @@ pub use handler::{
pub use registry::{AddAddressResult, AddressRecord, AddressScore}; pub use registry::{AddAddressResult, AddressRecord, AddressScore};
use connection::pool::{Pool, PoolConfig, PoolEvent}; use connection::pool::{Pool, PoolConfig, PoolEvent};
use connection::{EstablishedConnection, IncomingInfo, ListenersEvent, ListenersStream, Substream}; use connection::{EstablishedConnection, IncomingInfo, ListenersEvent, ListenersStream};
use dial_opts::{DialOpts, PeerCondition}; use dial_opts::{DialOpts, PeerCondition};
use either::Either; use either::Either;
use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream}; use futures::{executor::ThreadPoolBuilder, prelude::*, stream::FusedStream};
use libp2p_core::connection::{ConnectionId, PendingPoint}; use libp2p_core::connection::{ConnectionId, PendingPoint};
use libp2p_core::muxing::SubstreamBox;
use libp2p_core::{ use libp2p_core::{
connection::{ConnectedPoint, ListenerId}, connection::{ConnectedPoint, ListenerId},
multiaddr::Protocol, multiaddr::Protocol,
@ -110,7 +111,7 @@ use upgrade::UpgradeInfoSend as _;
/// ///
/// Implements the [`AsyncRead`](futures::io::AsyncRead) and /// Implements the [`AsyncRead`](futures::io::AsyncRead) and
/// [`AsyncWrite`](futures::io::AsyncWrite) traits. /// [`AsyncWrite`](futures::io::AsyncWrite) traits.
pub type NegotiatedSubstream = Negotiated<Substream<StreamMuxerBox>>; pub type NegotiatedSubstream = Negotiated<SubstreamBox>;
/// Event generated by the [`NetworkBehaviour`] that the swarm will report back. /// Event generated by the [`NetworkBehaviour`] that the swarm will report back.
type TBehaviourOutEvent<TBehaviour> = <TBehaviour as NetworkBehaviour>::OutEvent; type TBehaviourOutEvent<TBehaviour> = <TBehaviour as NetworkBehaviour>::OutEvent;

View File

@ -1,3 +1,7 @@
# 0.34.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.33.0 # 0.33.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-deflate"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Deflate encryption protocol for libp2p" description = "Deflate encryption protocol for libp2p"
version = "0.33.0" version = "0.34.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
flate2 = "1.0" flate2 = "1.0"
[dev-dependencies] [dev-dependencies]

View File

@ -1,3 +1,7 @@
# 0.34.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.33.0 # 0.33.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-dns"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "DNS transport implementation for libp2p" description = "DNS transport implementation for libp2p"
version = "0.33.0" version = "0.34.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -11,7 +11,7 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
categories = ["network-programming", "asynchronous"] categories = ["network-programming", "asynchronous"]
[dependencies] [dependencies]
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
log = "0.4.1" log = "0.4.1"
futures = "0.3.1" futures = "0.3.1"
async-std-resolver = { version = "0.21", optional = true } async-std-resolver = { version = "0.21", optional = true }

View File

@ -1,3 +1,7 @@
# 0.37.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.36.0 # 0.36.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-noise"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Cryptographic handshake protocol using the noise framework." description = "Cryptographic handshake protocol using the noise framework."
version = "0.36.0" version = "0.37.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -13,7 +13,7 @@ bytes = "1"
curve25519-dalek = "3.0.0" curve25519-dalek = "3.0.0"
futures = "0.3.1" futures = "0.3.1"
lazy_static = "1.2" lazy_static = "1.2"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
log = "0.4" log = "0.4"
prost = "0.10" prost = "0.10"
rand = "0.8.3" rand = "0.8.3"

View File

@ -1,3 +1,7 @@
# 0.34.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.33.0 # 0.33.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-plaintext"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Plaintext encryption dummy protocol for libp2p" description = "Plaintext encryption dummy protocol for libp2p"
version = "0.33.0" version = "0.34.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
bytes = "1" bytes = "1"
futures = "0.3.1" futures = "0.3.1"
asynchronous-codec = "0.6" asynchronous-codec = "0.6"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
log = "0.4.8" log = "0.4.8"
prost = "0.10" prost = "0.10"
unsigned-varint = { version = "0.7", features = ["asynchronous_codec"] } unsigned-varint = { version = "0.7", features = ["asynchronous_codec"] }

View File

@ -1,3 +1,7 @@
# 0.34.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.33.0 # 0.33.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-tcp"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "TCP/IP transport protocol for libp2p" description = "TCP/IP transport protocol for libp2p"
version = "0.33.0" version = "0.34.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -18,7 +18,7 @@ if-watch = { version = "1.0.0", optional = true }
if-addrs = { version = "0.7.0", optional = true } if-addrs = { version = "0.7.0", optional = true }
ipnet = "2.0.0" ipnet = "2.0.0"
libc = "0.2.80" libc = "0.2.80"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
log = "0.4.11" log = "0.4.11"
socket2 = { version = "0.4.0", features = ["all"] } socket2 = { version = "0.4.0", features = ["all"] }
tokio-crate = { package = "tokio", version = "1.0.1", default-features = false, features = ["net"], optional = true } tokio-crate = { package = "tokio", version = "1.0.1", default-features = false, features = ["net"], optional = true }

View File

@ -1,6 +1,7 @@
# 0.33.0 - [unreleased] # 0.33.0 [unreleased]
- Update dependencies. - Update dependencies.
- Update to `libp2p-core` `v0.34.0`.
# 0.32.0 [2022-01-27] # 0.32.0 [2022-01-27]

View File

@ -12,7 +12,7 @@ categories = ["network-programming", "asynchronous"]
[target.'cfg(all(unix, not(target_os = "emscripten")))'.dependencies] [target.'cfg(all(unix, not(target_os = "emscripten")))'.dependencies]
async-std = { version = "1.6.2", optional = true } async-std = { version = "1.6.2", optional = true }
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
log = "0.4.1" log = "0.4.1"
futures = "0.3.1" futures = "0.3.1"
tokio = { version = "1.15", default-features = false, features = ["net"], optional = true } tokio = { version = "1.15", default-features = false, features = ["net"], optional = true }

View File

@ -1,3 +1,7 @@
# 0.34.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.33.0 # 0.33.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-wasm-ext"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "Allows passing in an external transport in a WASM environment" description = "Allows passing in an external transport in a WASM environment"
version = "0.33.0" version = "0.34.0"
authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"] authors = ["Pierre Krieger <pierre.krieger1708@gmail.com>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -13,7 +13,7 @@ categories = ["network-programming", "asynchronous"]
[dependencies] [dependencies]
futures = "0.3.1" futures = "0.3.1"
js-sys = "0.3.50" js-sys = "0.3.50"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
parity-send-wrapper = "0.1.0" parity-send-wrapper = "0.1.0"
wasm-bindgen = "0.2.42" wasm-bindgen = "0.2.42"
wasm-bindgen-futures = "0.4.4" wasm-bindgen-futures = "0.4.4"

View File

@ -1,3 +1,7 @@
# 0.36.0 [unreleased]
- Update to `libp2p-core` `v0.34.0`.
# 0.35.0 # 0.35.0
- Update to `libp2p-core` `v0.33.0`. - Update to `libp2p-core` `v0.33.0`.

View File

@ -3,7 +3,7 @@ name = "libp2p-websocket"
edition = "2021" edition = "2021"
rust-version = "1.56.1" rust-version = "1.56.1"
description = "WebSocket transport for libp2p" description = "WebSocket transport for libp2p"
version = "0.35.0" version = "0.36.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT" license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p" repository = "https://github.com/libp2p/rust-libp2p"
@ -14,7 +14,7 @@ categories = ["network-programming", "asynchronous"]
futures-rustls = "0.22" futures-rustls = "0.22"
either = "1.5.3" either = "1.5.3"
futures = "0.3.1" futures = "0.3.1"
libp2p-core = { version = "0.33.0", path = "../../core", default-features = false } libp2p-core = { version = "0.34.0", path = "../../core", default-features = false }
log = "0.4.8" log = "0.4.8"
parking_lot = "0.12.0" parking_lot = "0.12.0"
quicksink = "0.1" quicksink = "0.1"