diff --git a/.github/workflows/cargo-deny-pr.yml b/.github/workflows/cargo-deny-pr.yml index 16b16d16a653..c9c0e7d447b8 100644 --- a/.github/workflows/cargo-deny-pr.yml +++ b/.github/workflows/cargo-deny-pr.yml @@ -1,4 +1,5 @@ name: cargo deny + on: push: paths: @@ -6,6 +7,11 @@ on: pull_request: paths: - '**/Cargo.toml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: cargo-deny: runs-on: ubuntu-latest diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 83bad9cfdc66..b0daf6bb8639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,10 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test-desktop: name: Build and test @@ -18,12 +22,6 @@ jobs: "--benches --all-features", ] steps: - - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 - with: - access_token: ${{ github.token }} - - name: Install Protoc uses: arduino/setup-protoc@v1 @@ -53,12 +51,6 @@ jobs: run: shell: bash steps: - - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 - with: - access_token: ${{ github.token }} - - name: Install Protoc uses: arduino/setup-protoc@v1 @@ -91,12 +83,6 @@ jobs: name: Check rustdoc intra-doc links runs-on: ubuntu-latest steps: - - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 - with: - access_token: ${{ github.token }} - - name: Install Protoc uses: arduino/setup-protoc@v1 @@ -116,12 +102,6 @@ jobs: check-clippy: runs-on: ubuntu-latest steps: - - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 - with: - access_token: ${{ github.token }} - - name: Install Protoc uses: arduino/setup-protoc@v1 @@ -145,12 +125,6 @@ jobs: name: Integration tests runs-on: ubuntu-latest steps: - - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 - with: - access_token: ${{ github.token }} - - name: Install Protoc uses: arduino/setup-protoc@v1 @@ -170,12 +144,6 @@ jobs: rustfmt: runs-on: ubuntu-latest steps: - - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v3 - uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7 @@ -191,12 +159,6 @@ jobs: manifest_lint: runs-on: ubuntu-latest steps: - - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v3 - uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7 @@ -210,7 +172,52 @@ jobs: ALL_FEATURES=$(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.name == "libp2p") | .features | keys | map(select(. != "full")) | sort | join(" ")') FULL_FEATURE=$(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.name == "libp2p") | .features["full"] | sort | join(" ")') + test "$ALL_FEATURES = $FULL_FEATURE" + echo "$ALL_FEATURES"; echo "$FULL_FEATURE"; test "$ALL_FEATURES" = "$FULL_FEATURE" + + gather_crates_for_semver_checks: + runs-on: ubuntu-latest + outputs: + members: ${{ steps.cargo-metadata.outputs.members }} + steps: + - uses: actions/checkout@v3 + + - id: cargo-metadata + run: | + WORKSPACE_MEMBERS=$(cargo metadata --format-version=1 --no-deps | jq -c '.packages | .[] | select(.publish == null) | .name' | jq -s '.' | jq -c '.') + echo "::set-output name=members::${WORKSPACE_MEMBERS}" + + semver-check: + runs-on: ubuntu-latest + needs: gather_crates_for_semver_checks + strategy: + fail-fast: false + matrix: + crate: ${{ fromJSON(needs.gather_crates_for_semver_checks.outputs.members) }} + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@bb6001c4ea612bf59c3abfc4756fbceee4f870c7 # 0.10.0 + with: + access_token: ${{ github.token }} + + - uses: actions/checkout@v3 + + - uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7 + with: + profile: minimal + toolchain: stable + override: true + + - name: Install Protoc + uses: arduino/setup-protoc@v1 + + - uses: Swatinem/rust-cache@6720f05bc48b77f96918929a9019fb2203ff71f8 # v2.0.0 + + - run: cargo install cargo-semver-checks + + - name: Semver Check + run: cargo semver-checks check-release -p ${{ matrix.crate }} diff --git a/.github/workflows/interop-test.yml b/.github/workflows/interop-test.yml index 9413cce7e95e..de5949bd2b7f 100644 --- a/.github/workflows/interop-test.yml +++ b/.github/workflows/interop-test.yml @@ -1,9 +1,14 @@ +name: Interoperability Testing + on: pull_request: push: branches: - master -name: Interoperability Testing + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: # NOTE: during a pull request run, github creates a merge commit referenced in `github.sha` @@ -24,4 +29,4 @@ jobs: composition_file: "ping/_compositions/go-rust-interop-latest.toml" custom_git_target: github.com/${{ github.event.pull_request.head.repo.full_name || github.event.repository.full_name }} custom_git_reference: ${{ github.event.pull_request.head.sha || github.sha }} - custom_interop_target: rust \ No newline at end of file + custom_interop_target: rust diff --git a/CHANGELOG.md b/CHANGELOG.md index f1cf6eed30c1..65999fbb1934 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,11 +43,21 @@ # `libp2p` facade crate -# 0.49.0 - [unreleased] +# 0.49.0 - Remove default features. You need to enable required features explicitly now. As a quick workaround, you may want to use the new `full` feature which activates all features. See [PR 2918]. +- Introduce `tokio` and `async-std` features and deprecate the following ones: + - `tcp-tokio` in favor of `tcp` + `tokio` + - `mdns-tokio` in favor of `mdns` + `tokio` + - `dns-tokio` in favor of `dns` + `tokio` + - `tcp-async-io` in favor of `tcp` + `async-std` + - `mdns-async-io` in favor of `mdns` + `async-std` + - `dns-async-std` in favor of `dns` + `async-std` + + See [PR 2962]. + - Update individual crates. - Update to [`libp2p-autonat` `v0.8.0`](protocols/autonat/CHANGELOG.md#0080). - Update to [`libp2p-core` `v0.37.0`](core/CHANGELOG.md#0370). @@ -75,7 +85,8 @@ - Update to [`libp2p-websocket` `v0.39.0`](transports/websocket/CHANGELOG.md#0390). - Update to [`libp2p-yamux` `v0.41.0`](muxers/mplex/CHANGELOG.md#0410). -- [PR 2918]: https://github.com/libp2p/rust-libp2p/pull/2918 +[PR 2918]: https://github.com/libp2p/rust-libp2p/pull/2918 +[PR 2962]: https://github.com/libp2p/rust-libp2p/pull/2962 # 0.48.0 diff --git a/Cargo.toml b/Cargo.toml index 417c4b8bb0a0..65d2abcf4a05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,11 @@ categories = ["network-programming", "asynchronous"] [features] full = [ + "async-std", "autonat", "dcutr", "deflate", + "dns", "dns-async-std", "dns-tokio", "ecdsa", @@ -22,6 +24,7 @@ full = [ "gossipsub", "identify", "kad", + "mdns", "mdns-async-io", "mdns-tokio", "metrics", @@ -36,8 +39,10 @@ full = [ "rsa", "secp256k1", "serde", + "tcp", "tcp-async-io", "tcp-tokio", + "tokio", "uds", "wasm-bindgen", "wasm-ext", @@ -48,6 +53,7 @@ full = [ autonat = ["dep:libp2p-autonat"] dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"] deflate = ["dep:libp2p-deflate"] +dns = ["dep:libp2p-dns"] dns-async-std = ["dep:libp2p-dns", "libp2p-dns?/async-std"] dns-tokio = ["dep:libp2p-dns", "libp2p-dns?/tokio"] floodsub = ["dep:libp2p-floodsub"] @@ -55,6 +61,7 @@ identify = ["dep:libp2p-identify", "libp2p-metrics?/identify"] kad = ["dep:libp2p-kad", "libp2p-metrics?/kad"] gossipsub = ["dep:libp2p-gossipsub", "libp2p-metrics?/gossipsub"] metrics = ["dep:libp2p-metrics"] +mdns = ["dep:libp2p-mdns"] mdns-async-io = ["dep:libp2p-mdns", "libp2p-mdns?/async-io"] mdns-tokio = ["dep:libp2p-mdns", "libp2p-mdns?/tokio"] mplex = ["dep:libp2p-mplex"] @@ -65,6 +72,7 @@ pnet = ["dep:libp2p-pnet"] relay = ["dep:libp2p-relay", "libp2p-metrics?/relay"] request-response = ["dep:libp2p-request-response"] rendezvous = ["dep:libp2p-rendezvous"] +tcp = ["dep:libp2p-tcp"] tcp-async-io = ["dep:libp2p-tcp", "libp2p-tcp?/async-io"] tcp-tokio = ["dep:libp2p-tcp", "libp2p-tcp?/tokio"] uds = ["dep:libp2p-uds"] @@ -77,6 +85,8 @@ secp256k1 = ["libp2p-core/secp256k1"] rsa = ["libp2p-core/rsa"] ecdsa = ["libp2p-core/ecdsa"] serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] +tokio = ["libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio"] +async-std = ["libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std"] [package.metadata.docs.rs] all-features = true @@ -91,7 +101,7 @@ lazy_static = "1.2" libp2p-autonat = { version = "0.8.0", path = "protocols/autonat", optional = true } libp2p-core = { version = "0.37.0", path = "core" } -libp2p-dcutr = { version = "0.7.0", path = "protocols/dcutr", optional = true } +libp2p-dcutr = { version = "0.7.0", path = "protocols/dcutr", optional = true } libp2p-floodsub = { version = "0.40.1", path = "protocols/floodsub", optional = true } libp2p-identify = { version = "0.40.0", path = "protocols/identify", optional = true } libp2p-kad = { version = "0.41.0", path = "protocols/kad", optional = true } @@ -128,7 +138,7 @@ libp2p-gossipsub = { version = "0.42.1", path = "protocols/gossipsub", optional async-std = { version = "1.6.2", features = ["attributes"] } async-trait = "0.1" env_logger = "0.9.0" -clap = {version = "3.1.6", features = ["derive"]} +clap = { version = "4.0.13", features = ["derive"] } tokio = { version = "1.15", features = ["io-util", "io-std", "macros", "rt", "rt-multi-thread"] } [workspace] diff --git a/README.md b/README.md index 1d5240acd833..7136f1d50ce2 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). - [COMIT](https://github.com/comit-network/xmr-btc-swap) - Bitcoin–Monero Cross-chain Atomic Swap. - [Forest](https://github.com/ChainSafe/forest) - An implementation of Filecoin written in Rust. +- [fuel-core](https://github.com/FuelLabs/fuel-core) - A Rust implementation of the Fuel protocol. - [ipfs-embed](https://github.com/ipfs-rust/ipfs-embed) - A small embeddable ipfs implementation used and maintained by [Actyx][https://www.actyx.com]. - [iroh](https://github.com/n0-computer/iroh) - Next-generation implementation of IPFS for Cloud & Mobile platforms. diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index 9f258c88a242..e996824209c2 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -1,12 +1,15 @@ -# 0.37.0 [unreleased] +# 0.37.0 - Implement `Hash` and `Ord` for `PublicKey`. See [PR 2915]. -- Remove default features. If you previously depended on `secp256k1` or `ecdsa` you need to enable these explicitly +- Remove default features. If you previously depended on `secp256k1` or `ecdsa` you need to enable these explicitly now. See [PR 2918]. +- Deprecate `StreamMuxerExt::next_{inbound,outbound}`. See [PR 3002]. + [PR 2915]: https://github.com/libp2p/rust-libp2p/pull/2915 [PR 2918]: https://github.com/libp2p/rust-libp2p/pull/2918 +[PR 3002]: https://github.com/libp2p/rust-libp2p/pull/3002 # 0.36.0 diff --git a/core/src/muxing.rs b/core/src/muxing.rs index 9763436e94a9..8d6f62fc022c 100644 --- a/core/src/muxing.rs +++ b/core/src/muxing.rs @@ -160,11 +160,19 @@ pub trait StreamMuxerExt: StreamMuxer + Sized { } /// Returns a future that resolves to the next inbound `Substream` opened by the remote. + #[deprecated( + since = "0.37.0", + note = "This future violates the `StreamMuxer` contract because it doesn't call `StreamMuxer::poll`." + )] fn next_inbound(&mut self) -> NextInbound<'_, Self> { NextInbound(self) } /// Returns a future that opens a new outbound `Substream` with the remote. + #[deprecated( + since = "0.37.0", + note = "This future violates the `StreamMuxer` contract because it doesn't call `StreamMuxer::poll`." + )] fn next_outbound(&mut self) -> NextOutbound<'_, Self> { NextOutbound(self) } diff --git a/misc/keygen/Cargo.toml b/misc/keygen/Cargo.toml index 13b1ff38216e..a5007fcb499e 100644 --- a/misc/keygen/Cargo.toml +++ b/misc/keygen/Cargo.toml @@ -7,9 +7,10 @@ license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" keywords = ["peer-to-peer", "libp2p", "networking"] categories = ["network-programming", "asynchronous"] +publish = false [dependencies] -clap = {version = "3.1.6", features = ["derive"]} +clap = { version = "4.0.13", features = ["derive"] } zeroize = "1" serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.79" diff --git a/misc/keygen/src/main.rs b/misc/keygen/src/main.rs index 7c2de2a181c9..4d2984775134 100644 --- a/misc/keygen/src/main.rs +++ b/misc/keygen/src/main.rs @@ -27,7 +27,7 @@ enum Command { /// Read from config file From { /// Provide a IPFS config file - #[clap(parse(from_os_str))] + #[clap(value_parser)] config: PathBuf, }, /// Generate random diff --git a/misc/metrics/CHANGELOG.md b/misc/metrics/CHANGELOG.md index fe428745d701..d76ef307e991 100644 --- a/misc/metrics/CHANGELOG.md +++ b/misc/metrics/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.10.0 [unreleased] +# 0.10.0 - Update to `libp2p-swarm` `v0.40.0`. diff --git a/misc/multistream-select/CHANGELOG.md b/misc/multistream-select/CHANGELOG.md index 4b15cc51ba1b..820d18449e5c 100644 --- a/misc/multistream-select/CHANGELOG.md +++ b/misc/multistream-select/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.12.0 [unreleased] +# 0.12.0 - Remove parallel dialing optimization, to avoid requiring the use of the `ls` command. See [PR 2934]. diff --git a/muxers/mplex/CHANGELOG.md b/muxers/mplex/CHANGELOG.md index 161cdbc9a64f..ed1c5c7382a2 100644 --- a/muxers/mplex/CHANGELOG.md +++ b/muxers/mplex/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.37.0 [unreleased] +# 0.37.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/muxers/mplex/benches/split_send_size.rs b/muxers/mplex/benches/split_send_size.rs index 8d6803880d65..3dc35c677a02 100644 --- a/muxers/mplex/benches/split_send_size.rs +++ b/muxers/mplex/benches/split_send_size.rs @@ -114,7 +114,10 @@ fn run( } transport::TransportEvent::Incoming { upgrade, .. } => { let (_peer, mut conn) = upgrade.await.unwrap(); - let mut s = conn.next_inbound().await.expect("unexpected error"); + // Just calling `poll_inbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut s = poll_fn(|cx| conn.poll_inbound_unpin(cx)) + .await + .expect("unexpected error"); let mut buf = vec![0u8; payload_len]; let mut off = 0; @@ -139,7 +142,8 @@ fn run( let sender = async move { let addr = addr_receiver.await.unwrap(); let (_peer, mut conn) = sender_trans.dial(addr).unwrap().await.unwrap(); - let mut stream = conn.next_outbound().await.unwrap(); + // Just calling `poll_outbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut stream = poll_fn(|cx| conn.poll_outbound_unpin(cx)).await.unwrap(); let mut off = 0; loop { let n = poll_fn(|cx| Pin::new(&mut stream).poll_write(cx, &payload[off..])) diff --git a/muxers/mplex/tests/async_write.rs b/muxers/mplex/tests/async_write.rs index 4f5bff1b5846..d4252ad20e41 100644 --- a/muxers/mplex/tests/async_write.rs +++ b/muxers/mplex/tests/async_write.rs @@ -18,6 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use futures::future::poll_fn; use futures::{channel::oneshot, prelude::*}; use libp2p::core::muxing::StreamMuxerExt; use libp2p::core::{upgrade, Transport}; @@ -59,7 +60,10 @@ fn async_write() { .await .unwrap(); - let mut outbound = client.next_outbound().await.unwrap(); + // Just calling `poll_outbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut outbound = poll_fn(|cx| client.poll_outbound_unpin(cx)) + .await + .expect("unexpected error"); let mut buf = Vec::new(); outbound.read_to_end(&mut buf).await.unwrap(); @@ -73,7 +77,10 @@ fn async_write() { let mut client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap(); - let mut inbound = client.next_inbound().await.unwrap(); + // Just calling `poll_inbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut inbound = poll_fn(|cx| client.poll_inbound_unpin(cx)) + .await + .expect("unexpected error"); inbound.write_all(b"hello world").await.unwrap(); // The test consists in making sure that this flushes the substream. diff --git a/muxers/mplex/tests/two_peers.rs b/muxers/mplex/tests/two_peers.rs index 27766c3abd55..70a10e8a0f70 100644 --- a/muxers/mplex/tests/two_peers.rs +++ b/muxers/mplex/tests/two_peers.rs @@ -18,6 +18,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +use futures::future::poll_fn; use futures::{channel::oneshot, prelude::*}; use libp2p::core::muxing::StreamMuxerExt; use libp2p::core::{upgrade, Transport}; @@ -59,7 +60,10 @@ fn client_to_server_outbound() { .await .unwrap(); - let mut outbound = client.next_outbound().await.unwrap(); + // Just calling `poll_outbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut outbound = poll_fn(|cx| client.poll_outbound_unpin(cx)) + .await + .expect("unexpected error"); let mut buf = Vec::new(); outbound.read_to_end(&mut buf).await.unwrap(); @@ -73,7 +77,10 @@ fn client_to_server_outbound() { .boxed(); let mut client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap(); - let mut inbound = client.next_inbound().await.unwrap(); + // Just calling `poll_inbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut inbound = poll_fn(|cx| client.poll_inbound_unpin(cx)) + .await + .expect("unexpected error"); inbound.write_all(b"hello world").await.unwrap(); inbound.close().await.unwrap(); @@ -117,7 +124,10 @@ fn client_to_server_inbound() { .await .unwrap(); - let mut inbound = client.next_inbound().await.unwrap(); + // Just calling `poll_inbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut inbound = poll_fn(|cx| client.poll_inbound_unpin(cx)) + .await + .expect("unexpected error"); let mut buf = Vec::new(); inbound.read_to_end(&mut buf).await.unwrap(); @@ -132,7 +142,10 @@ fn client_to_server_inbound() { let mut client = transport.dial(rx.await.unwrap()).unwrap().await.unwrap(); - let mut outbound = client.next_outbound().await.unwrap(); + // Just calling `poll_outbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut outbound = poll_fn(|cx| client.poll_outbound_unpin(cx)) + .await + .expect("unexpected error"); outbound.write_all(b"hello world").await.unwrap(); outbound.close().await.unwrap(); @@ -174,7 +187,10 @@ fn protocol_not_match() { .await .unwrap(); - let mut outbound = client.next_outbound().await.unwrap(); + // Just calling `poll_outbound` without `poll` is fine here because mplex makes progress through all `poll_` functions. It is hacky though. + let mut outbound = poll_fn(|cx| client.poll_outbound_unpin(cx)) + .await + .expect("unexpected error"); let mut buf = Vec::new(); outbound.read_to_end(&mut buf).await.unwrap(); diff --git a/muxers/yamux/CHANGELOG.md b/muxers/yamux/CHANGELOG.md index 41eff1045008..b3aa8dac0e1f 100644 --- a/muxers/yamux/CHANGELOG.md +++ b/muxers/yamux/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.41.0 [unreleased] +# 0.41.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/protocols/autonat/CHANGELOG.md b/protocols/autonat/CHANGELOG.md index 06809d78c29e..6f55afa4c06c 100644 --- a/protocols/autonat/CHANGELOG.md +++ b/protocols/autonat/CHANGELOG.md @@ -1,5 +1,5 @@ -# 0.8.0 [unreleased] - +# 0.8.0 + - Update to `libp2p-core` `v0.37.0`. - Update to `libp2p-swarm` `v0.40.0`. diff --git a/protocols/autonat/Cargo.toml b/protocols/autonat/Cargo.toml index ed117c9edf4a..c3b88583839a 100644 --- a/protocols/autonat/Cargo.toml +++ b/protocols/autonat/Cargo.toml @@ -28,5 +28,5 @@ prost = "0.11" [dev-dependencies] async-std = { version = "1.10", features = ["attributes"] } env_logger = "0.9" -clap = {version = "3.1.6", features = ["derive"]} +clap = { version = "4.0.13", features = ["derive"] } libp2p = { path = "../..", features = ["full"] } diff --git a/protocols/dcutr/CHANGELOG.md b/protocols/dcutr/CHANGELOG.md index 8f98e3257d6a..0d49f90d008b 100644 --- a/protocols/dcutr/CHANGELOG.md +++ b/protocols/dcutr/CHANGELOG.md @@ -1,9 +1,13 @@ -# 0.7.0 [unreleased] +# 0.7.0 - Update to `libp2p-core` `v0.37.0`. - Update to `libp2p-swarm` `v0.40.0`. +- Fix WASM compilation. See [PR 2991]. + +[PR 2991]: https://github.com/libp2p/rust-libp2p/pull/2991/ + # 0.6.0 - Update to `libp2p-swarm` `v0.39.0`. diff --git a/protocols/dcutr/Cargo.toml b/protocols/dcutr/Cargo.toml index dbdf9494d9b4..d9cc5861bc5f 100644 --- a/protocols/dcutr/Cargo.toml +++ b/protocols/dcutr/Cargo.toml @@ -32,4 +32,4 @@ prost-build = "0.11" env_logger = "0.9.0" libp2p = { path = "../..", features = ["full"] } rand = "0.8" -clap = {version = "3.1.6", features = ["derive"]} +clap = { version = "4.0.13", features = ["derive"] } diff --git a/protocols/dcutr/examples/dcutr.rs b/protocols/dcutr/examples/dcutr.rs index 925e03593b50..9e17539d269f 100644 --- a/protocols/dcutr/examples/dcutr.rs +++ b/protocols/dcutr/examples/dcutr.rs @@ -60,7 +60,7 @@ struct Opts { remote_peer_id: Option, } -#[derive(Debug, Parser, PartialEq)] +#[derive(Clone, Debug, PartialEq, Parser)] enum Mode { Dial, Listen, diff --git a/protocols/dcutr/src/protocol/outbound.rs b/protocols/dcutr/src/protocol/outbound.rs index dc55aa414d98..a0ea8449fe4c 100644 --- a/protocols/dcutr/src/protocol/outbound.rs +++ b/protocols/dcutr/src/protocol/outbound.rs @@ -22,11 +22,11 @@ use crate::message_proto::{hole_punch, HolePunch}; use asynchronous_codec::Framed; use futures::{future::BoxFuture, prelude::*}; use futures_timer::Delay; +use instant::Instant; use libp2p_core::{multiaddr::Protocol, upgrade, Multiaddr}; use libp2p_swarm::NegotiatedSubstream; use std::convert::TryFrom; use std::iter; -use std::time::Instant; use thiserror::Error; pub struct Upgrade { diff --git a/protocols/floodsub/CHANGELOG.md b/protocols/floodsub/CHANGELOG.md index e7c1392c642c..dd42387eda21 100644 --- a/protocols/floodsub/CHANGELOG.md +++ b/protocols/floodsub/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.40.0 [unreleased] +# 0.40.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/protocols/gossipsub/CHANGELOG.md b/protocols/gossipsub/CHANGELOG.md index 99d2ad3a1c3d..555c146af11f 100644 --- a/protocols/gossipsub/CHANGELOG.md +++ b/protocols/gossipsub/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.42.0 [unreleased] +# 0.42.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/protocols/identify/CHANGELOG.md b/protocols/identify/CHANGELOG.md index 00ed1e138e28..f60ace8ace0a 100644 --- a/protocols/identify/CHANGELOG.md +++ b/protocols/identify/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.40.0 [unreleased] +# 0.40.0 - Update dependencies. diff --git a/protocols/kad/CHANGELOG.md b/protocols/kad/CHANGELOG.md index dcf4eedf2fb7..9a76bb9c9dfa 100644 --- a/protocols/kad/CHANGELOG.md +++ b/protocols/kad/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.41.0 [unreleased] +# 0.41.0 - Remove deprecated `set_protocol_name()` from `KademliaConfig` & `KademliaProtocolConfig`. Use `set_protocol_names()` instead. See [PR 2866]. diff --git a/protocols/mdns/CHANGELOG.md b/protocols/mdns/CHANGELOG.md index 915564341ae8..66a2ee57394c 100644 --- a/protocols/mdns/CHANGELOG.md +++ b/protocols/mdns/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.41.0 [unreleased] +# 0.41.0 - Remove default features. If you previously depended on `async-io` you need to enable this explicitly now. See [PR 2918]. diff --git a/protocols/ping/CHANGELOG.md b/protocols/ping/CHANGELOG.md index 923dfa48c849..bcdcdf9ab0ed 100644 --- a/protocols/ping/CHANGELOG.md +++ b/protocols/ping/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.40.0 [unreleased] +# 0.40.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. - Deprecate types with `Ping` prefix. Prefer importing them via the `ping` namespace, i.e. `libp2p::ping::Event` instead diff --git a/protocols/relay/CHANGELOG.md b/protocols/relay/CHANGELOG.md index 9937fffec0e3..b21d4123b083 100644 --- a/protocols/relay/CHANGELOG.md +++ b/protocols/relay/CHANGELOG.md @@ -1,9 +1,13 @@ -# 0.13.0 [unreleased] +# 0.13.0 - Update to `libp2p-core` `v0.37.0`. - Update to `libp2p-swarm` `v0.40.0`. +- Fix WASM compilation. See [PR 2991]. + +[PR 2991]: https://github.com/libp2p/rust-libp2p/pull/2991/ + # 0.12.0 - Update to `libp2p-swarm` `v0.39.0`. diff --git a/protocols/relay/Cargo.toml b/protocols/relay/Cargo.toml index 052eb1127a89..19837380355b 100644 --- a/protocols/relay/Cargo.toml +++ b/protocols/relay/Cargo.toml @@ -36,4 +36,4 @@ prost-build = "0.11" env_logger = "0.9.0" libp2p = { path = "../..", features = ["full"] } quickcheck = { package = "quickcheck-ext", path = "../../misc/quickcheck-ext" } -clap = {version = "3.1.6", features = ["derive"]} +clap = { version = "4.0.13", features = ["derive"] } diff --git a/protocols/relay/src/v2/protocol/inbound_hop.rs b/protocols/relay/src/v2/protocol/inbound_hop.rs index 893ae916e1cb..2a6cf01c5654 100644 --- a/protocols/relay/src/v2/protocol/inbound_hop.rs +++ b/protocols/relay/src/v2/protocol/inbound_hop.rs @@ -23,11 +23,11 @@ use crate::v2::protocol::{HOP_PROTOCOL_NAME, MAX_MESSAGE_SIZE}; use asynchronous_codec::{Framed, FramedParts}; use bytes::Bytes; use futures::{future::BoxFuture, prelude::*}; +use instant::{Duration, SystemTime}; use libp2p_core::{upgrade, Multiaddr, PeerId}; use libp2p_swarm::NegotiatedSubstream; use std::convert::TryInto; use std::iter; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; use thiserror::Error; pub struct Upgrade { @@ -142,7 +142,7 @@ impl ReservationReq { reservation: Some(Reservation { addrs: addrs.into_iter().map(|a| a.to_vec()).collect(), expire: (SystemTime::now() + self.reservation_duration) - .duration_since(UNIX_EPOCH) + .duration_since(SystemTime::UNIX_EPOCH) .unwrap() .as_secs(), voucher: None, diff --git a/protocols/relay/src/v2/protocol/outbound_hop.rs b/protocols/relay/src/v2/protocol/outbound_hop.rs index 9a20a1aa0005..c8381df31a55 100644 --- a/protocols/relay/src/v2/protocol/outbound_hop.rs +++ b/protocols/relay/src/v2/protocol/outbound_hop.rs @@ -24,11 +24,11 @@ use asynchronous_codec::{Framed, FramedParts}; use bytes::Bytes; use futures::{future::BoxFuture, prelude::*}; use futures_timer::Delay; +use instant::{Duration, SystemTime}; use libp2p_core::{upgrade, Multiaddr, PeerId}; use libp2p_swarm::NegotiatedSubstream; use std::convert::TryFrom; use std::iter; -use std::time::{Duration, SystemTime, UNIX_EPOCH}; use thiserror::Error; pub enum Upgrade { @@ -134,7 +134,7 @@ impl upgrade::OutboundUpgrade for Upgrade { .expire .checked_sub( SystemTime::now() - .duration_since(UNIX_EPOCH) + .duration_since(SystemTime::UNIX_EPOCH) .unwrap() .as_secs(), ) diff --git a/protocols/rendezvous/CHANGELOG.md b/protocols/rendezvous/CHANGELOG.md index 3e04334ad50e..1b8588551082 100644 --- a/protocols/rendezvous/CHANGELOG.md +++ b/protocols/rendezvous/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.10.0 [unreleased] +# 0.10.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/protocols/request-response/CHANGELOG.md b/protocols/request-response/CHANGELOG.md index 7e4ba48044d6..a48d74ee82f0 100644 --- a/protocols/request-response/CHANGELOG.md +++ b/protocols/request-response/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.22.0 [unreleased] +# 0.22.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/src/lib.rs b/src/lib.rs index 96a197cf5160..a345a64deab7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,14 +54,31 @@ pub use libp2p_dcutr as dcutr; #[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))] #[doc(inline)] pub use libp2p_deflate as deflate; -#[cfg(any(feature = "dns-async-std", feature = "dns-tokio"))] +#[deprecated( + since = "0.49.0", + note = "The `dns-tokio` and `dns-async-std` features are deprecated. Use the new `dns` feature together with the `tokio` or `async-std` features." +)] +#[cfg(all( + any(feature = "dns-tokio", feature = "dns-async-std"), + not(feature = "dns") +))] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))] #[cfg_attr( docsrs, - doc(cfg(any(feature = "dns-async-std", feature = "dns-tokio"))) + doc(cfg(any(feature = "dns-tokio", feature = "dns-async-std"))) )] +pub mod dns { + #[doc(inline)] + pub use libp2p_dns::*; +} + +#[cfg(feature = "dns")] #[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))] -#[doc(inline)] -pub use libp2p_dns as dns; +#[cfg_attr(docsrs, doc(cfg(feature = "dns")))] +pub mod dns { + #[doc(inline)] + pub use libp2p_dns::*; +} #[cfg(feature = "floodsub")] #[cfg_attr(docsrs, doc(cfg(feature = "floodsub")))] #[doc(inline)] @@ -79,14 +96,31 @@ pub use libp2p_identify as identify; #[cfg_attr(docsrs, doc(cfg(feature = "kad")))] #[doc(inline)] pub use libp2p_kad as kad; -#[cfg(any(feature = "mdns-async-io", feature = "mdns-tokio"))] +#[deprecated( + since = "0.49.0", + note = "The `mdns-tokio` and `mdns-async-io` features are deprecated. Use the new `mdns` feature together with the `tokio` or `async-std` features." +)] +#[cfg(all( + any(feature = "mdns-async-io", feature = "mdns-tokio"), + not(feature = "mdns") +))] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))] #[cfg_attr( docsrs, doc(cfg(any(feature = "mdns-tokio", feature = "mdns-async-io"))) )] +pub mod mdns { + #[doc(inline)] + pub use libp2p_mdns::*; +} + +#[cfg(feature = "mdns")] #[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))] -#[doc(inline)] -pub use libp2p_mdns as mdns; +#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] +pub mod mdns { + #[doc(inline)] + pub use libp2p_mdns::*; +} #[cfg(feature = "metrics")] #[cfg_attr(docsrs, doc(cfg(feature = "metrics")))] #[doc(inline)] @@ -125,11 +159,28 @@ pub use libp2p_rendezvous as rendezvous; pub use libp2p_request_response as request_response; #[doc(inline)] pub use libp2p_swarm as swarm; -#[cfg(any(feature = "tcp-async-io", feature = "tcp-tokio"))] -#[cfg_attr(docsrs, doc(cfg(any(feature = "tcp-async-io", feature = "tcp-tokio"))))] +#[deprecated( + since = "0.49.0", + note = "The `tcp-tokio` and `tcp-async-io` features are deprecated. Use the new `tcp` feature together with the `tokio` or `async-std` features." +)] +#[cfg(all( + any(feature = "tcp-tokio", feature = "tcp-async-io"), + not(feature = "tcp") +))] #[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))] -#[doc(inline)] -pub use libp2p_tcp as tcp; +#[cfg_attr(docsrs, doc(cfg(any(feature = "tcp-tokio", feature = "tcp-async-io"))))] +pub mod tcp { + #[doc(inline)] + pub use libp2p_tcp::*; +} + +#[cfg(feature = "tcp")] +#[cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))] +#[cfg_attr(docsrs, doc(cfg(feature = "tcp")))] +pub mod tcp { + #[doc(inline)] + pub use libp2p_tcp::*; +} #[cfg(feature = "uds")] #[cfg_attr(docsrs, doc(cfg(feature = "uds")))] #[doc(inline)] @@ -181,8 +232,10 @@ pub use libp2p_swarm_derive::NetworkBehaviour; /// > reserves the right to support additional protocols or remove deprecated protocols. #[cfg(all( not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), - feature = "tcp-async-io", - feature = "dns-async-std", + any( + all(feature = "tcp-async-io", feature = "dns-async-std"), + all(feature = "tcp", feature = "dns", feature = "async-std") + ), feature = "websocket", feature = "noise", feature = "mplex", @@ -192,14 +245,26 @@ pub use libp2p_swarm_derive::NetworkBehaviour; docsrs, doc(cfg(all( not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), - feature = "tcp-async-io", - feature = "dns-async-std", + any( + all(feature = "tcp-async-io", feature = "dns-async-std"), + all(feature = "tcp", feature = "dns", feature = "async-std") + ), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux" ))) )] +#[cfg_attr( + all( + any(feature = "tcp-async-io", feature = "dns-async-std"), + not(feature = "async-std") + ), + deprecated( + since = "0.49.0", + note = "The `tcp-async-io` and `dns-async-std` features are deprecated. Use the new `tcp` and `dns` features together with the `async-std` feature." + ) +)] pub async fn development_transport( keypair: identity::Keypair, ) -> std::io::Result> { @@ -241,8 +306,10 @@ pub async fn development_transport( /// > reserves the right to support additional protocols or remove deprecated protocols. #[cfg(all( not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), - feature = "tcp-tokio", - feature = "dns-tokio", + any( + all(feature = "tcp-tokio", feature = "dns-tokio"), + all(feature = "tcp", feature = "dns", feature = "tokio") + ), feature = "websocket", feature = "noise", feature = "mplex", @@ -252,14 +319,26 @@ pub async fn development_transport( docsrs, doc(cfg(all( not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")), - feature = "tcp-tokio", - feature = "dns-tokio", + any( + all(feature = "tcp-tokio", feature = "dns-tokio"), + all(feature = "tcp", feature = "dns", feature = "tokio") + ), feature = "websocket", feature = "noise", feature = "mplex", feature = "yamux" ))) )] +#[cfg_attr( + all( + any(feature = "tcp-tokio", feature = "dns-tokio"), + not(feature = "tokio") + ), + deprecated( + since = "0.49.0", + note = "The `tcp-tokio` and `dns-tokio` features are deprecated. Use the new `tcp` and `dns` feature together with the `tokio` feature." + ) +)] pub fn tokio_development_transport( keypair: identity::Keypair, ) -> std::io::Result> { diff --git a/swarm-derive/CHANGELOG.md b/swarm-derive/CHANGELOG.md index 0c64fd352da9..722537e6b59a 100644 --- a/swarm-derive/CHANGELOG.md +++ b/swarm-derive/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.30.1 [unreleased] +# 0.30.1 - Fix an issue where the derive would generate bad code if the type parameters between the behaviour and a custom out event differed. See [PR 2907]. diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index ec7b8e83d4f0..1758579dc21e 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,10 +1,10 @@ -# 0.40.0 [unreleased] +# 0.40.0 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. - Update to `libp2p-core` `v0.37.0`. -- Introduce `libp2p_swarm::keep_alive::ConnectionHandler` in favor of removing `keep_alive` from +- Introduce `libp2p_swarm::keep_alive::ConnectionHandler` in favor of removing `keep_alive` from `libp2p_swarm::dummy::ConnectionHandler`. `dummy::ConnectionHandler` now literally does not do anything. In the same spirit, introduce `libp2p_swarm::keep_alive::Behaviour` and `libp2p_swarm::dummy::Behaviour`. See [PR 2859]. diff --git a/transports/deflate/CHANGELOG.md b/transports/deflate/CHANGELOG.md index d7c58a6e4a9d..941efc421f82 100644 --- a/transports/deflate/CHANGELOG.md +++ b/transports/deflate/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.37.0 [unreleased] +# 0.37.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/transports/dns/CHANGELOG.md b/transports/dns/CHANGELOG.md index e20c92f66e03..6d03b237a790 100644 --- a/transports/dns/CHANGELOG.md +++ b/transports/dns/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.37.0 [unreleased] +# 0.37.0 - Remove default features. If you previously depended on `async-std` you need to enable this explicitly now. See [PR 2918]. diff --git a/transports/dns/src/lib.rs b/transports/dns/src/lib.rs index 7f76a3789908..1b9bb1992004 100644 --- a/transports/dns/src/lib.rs +++ b/transports/dns/src/lib.rs @@ -65,7 +65,6 @@ use libp2p_core::{ }; use parking_lot::Mutex; use smallvec::SmallVec; -#[cfg(any(feature = "async-std", feature = "tokio"))] use std::io; use std::{ convert::TryFrom, diff --git a/transports/noise/CHANGELOG.md b/transports/noise/CHANGELOG.md index bae8fd51edb2..ec28bb3ff4d4 100644 --- a/transports/noise/CHANGELOG.md +++ b/transports/noise/CHANGELOG.md @@ -1,13 +1,17 @@ -# 0.40.0 [unreleased] +# 0.40.0 - Update to `libp2p-core` `v0.37.0`. - Introduce `NoiseAuthenticated::xx` constructor, assuming a X25519 DH key exchange. An XX key exchange and X25519 keys are the most common way of using noise in libp2p and thus deserve a convenience constructor. See [PR 2887]. - Add `NoiseConfig::with_prologue` which allows users to set the noise prologue of the handshake. See [PR 2903]. +- Remove `Deref` implementation on `AuthenticKeypair`. See [PR 2909]. +- Make `handshake` module private. See [PR 2909]. +- Deprecate `AuthenticKeypair::into_identity`. See [PR 2909]. [PR 2887]: https://github.com/libp2p/rust-libp2p/pull/2887 [PR 2903]: https://github.com/libp2p/rust-libp2p/pull/2903 +[PR 2909]: https://github.com/libp2p/rust-libp2p/pull/2909 # 0.39.0 diff --git a/transports/noise/src/io/handshake.rs b/transports/noise/src/io/handshake.rs index 35099ea84dc8..c32eef9690f0 100644 --- a/transports/noise/src/io/handshake.rs +++ b/transports/noise/src/io/handshake.rs @@ -31,10 +31,9 @@ use crate::protocol::{KeypairIdentity, Protocol, PublicKey}; use crate::LegacyConfig; use bytes::Bytes; use futures::prelude::*; -use futures::task; use libp2p_core::identity; use prost::Message; -use std::{io, pin::Pin, task::Context}; +use std::io; /// The identity of the remote established during a handshake. pub enum RemoteIdentity { @@ -63,199 +62,11 @@ pub enum RemoteIdentity { IdentityKey(identity::PublicKey), } -/// The options for identity exchange in an authenticated handshake. -/// -/// > **Note**: Even if a remote's public identity key is known a priori, -/// > unless the authenticity of the key is [linked](Protocol::linked) to -/// > the authenticity of a remote's static DH public key, an authenticated -/// > handshake will still send the associated signature of the provided -/// > local [`KeypairIdentity`] in order for the remote to verify that the static -/// > DH public key is authentic w.r.t. the known public identity key. -pub enum IdentityExchange { - /// Send the local public identity to the remote. - /// - /// The remote identity is unknown (i.e. expected to be received). - Mutual, - /// Send the local public identity to the remote. - /// - /// The remote identity is known. - Send { remote: identity::PublicKey }, - /// Don't send the local public identity to the remote. - /// - /// The remote identity is unknown, i.e. expected to be received. - Receive, - /// Don't send the local public identity to the remote. - /// - /// The remote identity is known, thus identities must be mutually known - /// in order for the handshake to succeed. - None { remote: identity::PublicKey }, -} - -/// A future performing a Noise handshake pattern. -pub struct Handshake( - Pin, NoiseOutput), NoiseError>> + Send>>, -); - -impl Future for Handshake { - type Output = Result<(RemoteIdentity, NoiseOutput), NoiseError>; - - fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> task::Poll { - Pin::new(&mut self.0).poll(ctx) - } -} - -/// Creates an authenticated Noise handshake for the initiator of a -/// single roundtrip (2 message) handshake pattern. -/// -/// Subject to the chosen [`IdentityExchange`], this message sequence -/// identifies the local node to the remote with the first message payload -/// (i.e. unencrypted) and expects the remote to identify itself in the -/// second message payload. -/// -/// This message sequence is suitable for authenticated 2-message Noise handshake -/// patterns where the static keys of the initiator and responder are either -/// known (i.e. appear in the pre-message pattern) or are sent with -/// the first and second message, respectively (e.g. `IK` or `IX`). -/// -/// ```raw -/// initiator -{id}-> responder -/// initiator <-{id}- responder -/// ``` -pub fn rt1_initiator( - io: T, - session: Result, - identity: KeypairIdentity, - identity_x: IdentityExchange, - legacy: LegacyConfig, -) -> Handshake -where - T: AsyncWrite + AsyncRead + Send + Unpin + 'static, - C: Protocol + AsRef<[u8]>, -{ - Handshake(Box::pin(async move { - let mut state = State::new(io, session, identity, identity_x, legacy)?; - send_identity(&mut state).await?; - recv_identity(&mut state).await?; - state.finish() - })) -} - -/// Creates an authenticated Noise handshake for the responder of a -/// single roundtrip (2 message) handshake pattern. -/// -/// Subject to the chosen [`IdentityExchange`], this message sequence expects the -/// remote to identify itself in the first message payload (i.e. unencrypted) -/// and identifies the local node to the remote in the second message payload. -/// -/// This message sequence is suitable for authenticated 2-message Noise handshake -/// patterns where the static keys of the initiator and responder are either -/// known (i.e. appear in the pre-message pattern) or are sent with the first -/// and second message, respectively (e.g. `IK` or `IX`). -/// -/// ```raw -/// initiator -{id}-> responder -/// initiator <-{id}- responder -/// ``` -pub fn rt1_responder( - io: T, - session: Result, - identity: KeypairIdentity, - identity_x: IdentityExchange, - legacy: LegacyConfig, -) -> Handshake -where - T: AsyncWrite + AsyncRead + Send + Unpin + 'static, - C: Protocol + AsRef<[u8]>, -{ - Handshake(Box::pin(async move { - let mut state = State::new(io, session, identity, identity_x, legacy)?; - recv_identity(&mut state).await?; - send_identity(&mut state).await?; - state.finish() - })) -} - -/// Creates an authenticated Noise handshake for the initiator of a -/// 1.5-roundtrip (3 message) handshake pattern. -/// -/// Subject to the chosen [`IdentityExchange`], this message sequence expects -/// the remote to identify itself in the second message payload and -/// identifies the local node to the remote in the third message payload. -/// The first (unencrypted) message payload is always empty. -/// -/// This message sequence is suitable for authenticated 3-message Noise handshake -/// patterns where the static keys of the responder and initiator are either known -/// (i.e. appear in the pre-message pattern) or are sent with the second and third -/// message, respectively (e.g. `XX`). -/// -/// ```raw -/// initiator --{}--> responder -/// initiator <-{id}- responder -/// initiator -{id}-> responder -/// ``` -pub fn rt15_initiator( - io: T, - session: Result, - identity: KeypairIdentity, - identity_x: IdentityExchange, - legacy: LegacyConfig, -) -> Handshake -where - T: AsyncWrite + AsyncRead + Unpin + Send + 'static, - C: Protocol + AsRef<[u8]>, -{ - Handshake(Box::pin(async move { - let mut state = State::new(io, session, identity, identity_x, legacy)?; - send_empty(&mut state).await?; - recv_identity(&mut state).await?; - send_identity(&mut state).await?; - state.finish() - })) -} - -/// Creates an authenticated Noise handshake for the responder of a -/// 1.5-roundtrip (3 message) handshake pattern. -/// -/// Subject to the chosen [`IdentityExchange`], this message sequence -/// identifies the local node in the second message payload and expects -/// the remote to identify itself in the third message payload. The first -/// (unencrypted) message payload is always empty. -/// -/// This message sequence is suitable for authenticated 3-message Noise handshake -/// patterns where the static keys of the responder and initiator are either known -/// (i.e. appear in the pre-message pattern) or are sent with the second and third -/// message, respectively (e.g. `XX`). -/// -/// ```raw -/// initiator --{}--> responder -/// initiator <-{id}- responder -/// initiator -{id}-> responder -/// ``` -pub fn rt15_responder( - io: T, - session: Result, - identity: KeypairIdentity, - identity_x: IdentityExchange, - legacy: LegacyConfig, -) -> Handshake -where - T: AsyncWrite + AsyncRead + Unpin + Send + 'static, - C: Protocol + AsRef<[u8]>, -{ - Handshake(Box::pin(async move { - let mut state = State::new(io, session, identity, identity_x, legacy)?; - recv_empty(&mut state).await?; - send_identity(&mut state).await?; - recv_identity(&mut state).await?; - state.finish() - })) -} - ////////////////////////////////////////////////////////////////////////////// // Internal /// Handshake state. -struct State { +pub struct State { /// The underlying I/O resource. io: NoiseFramed, /// The associated public identity of the local node's static DH keypair, @@ -265,8 +76,6 @@ struct State { dh_remote_pubkey_sig: Option>, /// The known or received public identity key of the remote, if any. id_remote_pubkey: Option, - /// Whether to send the public identity key of the local node to the remote. - send_identity: bool, /// Legacy configuration parameters. legacy: LegacyConfig, } @@ -277,34 +86,27 @@ impl State { /// will be sent and received on the given I/O resource and using the /// provided session for cryptographic operations according to the chosen /// Noise handshake pattern. - fn new( + pub fn new( io: T, - session: Result, + session: snow::HandshakeState, identity: KeypairIdentity, - identity_x: IdentityExchange, + expected_remote_key: Option, legacy: LegacyConfig, - ) -> Result { - let (id_remote_pubkey, send_identity) = match identity_x { - IdentityExchange::Mutual => (None, true), - IdentityExchange::Send { remote } => (Some(remote), true), - IdentityExchange::Receive => (None, false), - IdentityExchange::None { remote } => (Some(remote), false), - }; - session.map(|s| State { + ) -> Self { + Self { identity, - io: NoiseFramed::new(io, s), + io: NoiseFramed::new(io, session), dh_remote_pubkey_sig: None, - id_remote_pubkey, - send_identity, + id_remote_pubkey: expected_remote_key, legacy, - }) + } } } impl State { /// Finish a handshake, yielding the established remote identity and the /// [`NoiseOutput`] for communicating on the encrypted channel. - fn finish(self) -> Result<(RemoteIdentity, NoiseOutput), NoiseError> + pub fn finish(self) -> Result<(RemoteIdentity, NoiseOutput), NoiseError> where C: Protocol + AsRef<[u8]>, { @@ -340,7 +142,7 @@ where } /// A future for receiving a Noise handshake message with an empty payload. -async fn recv_empty(state: &mut State) -> Result<(), NoiseError> +pub async fn recv_empty(state: &mut State) -> Result<(), NoiseError> where T: AsyncRead + Unpin, { @@ -354,7 +156,7 @@ where } /// A future for sending a Noise handshake message with an empty payload. -async fn send_empty(state: &mut State) -> Result<(), NoiseError> +pub async fn send_empty(state: &mut State) -> Result<(), NoiseError> where T: AsyncWrite + Unpin, { @@ -364,7 +166,10 @@ where /// A future for receiving a Noise handshake message with a payload /// identifying the remote. -async fn recv_identity(state: &mut State) -> Result<(), NoiseError> +/// +/// In case `expected_key` is passed, this function will fail if the received key does not match the expected key. +/// In case the remote does not send us a key, the expected key is assumed to be the remote's key. +pub async fn recv_identity(state: &mut State) -> Result<(), NoiseError> where T: AsyncRead + Unpin, { @@ -421,16 +226,41 @@ where } /// Send a Noise handshake message with a payload identifying the local node to the remote. -async fn send_identity(state: &mut State) -> Result<(), NoiseError> +pub async fn send_identity(state: &mut State) -> Result<(), NoiseError> where T: AsyncWrite + Unpin, { - let mut pb = payload_proto::NoiseHandshakePayload::default(); + let mut pb = payload_proto::NoiseHandshakePayload { + identity_key: state.identity.public.to_protobuf_encoding(), + ..Default::default() + }; - if state.send_identity { - pb.identity_key = state.identity.public.to_protobuf_encoding() + if let Some(ref sig) = state.identity.signature { + pb.identity_sig = sig.clone() } + let mut msg = if state.legacy.send_legacy_handshake { + let mut msg = Vec::with_capacity(2 + pb.encoded_len()); + msg.extend_from_slice(&(pb.encoded_len() as u16).to_be_bytes()); + msg + } else { + Vec::with_capacity(pb.encoded_len()) + }; + + pb.encode(&mut msg) + .expect("Vec provides capacity as needed"); + state.io.send(&msg).await?; + + Ok(()) +} + +/// Send a Noise handshake message with a payload identifying the local node to the remote. +pub async fn send_signature_only(state: &mut State) -> Result<(), NoiseError> +where + T: AsyncWrite + Unpin, +{ + let mut pb = payload_proto::NoiseHandshakePayload::default(); + if let Some(ref sig) = state.identity.signature { pb.identity_sig = sig.clone() } diff --git a/transports/noise/src/lib.rs b/transports/noise/src/lib.rs index c1b55d2076ba..ac341c2802d2 100644 --- a/transports/noise/src/lib.rs +++ b/transports/noise/src/lib.rs @@ -58,16 +58,17 @@ mod io; mod protocol; pub use error::NoiseError; -pub use io::handshake; -pub use io::handshake::{Handshake, IdentityExchange, RemoteIdentity}; +pub use io::handshake::RemoteIdentity; pub use io::NoiseOutput; pub use protocol::{x25519::X25519, x25519_spec::X25519Spec}; pub use protocol::{AuthenticKeypair, Keypair, KeypairIdentity, PublicKey, SecretKey}; pub use protocol::{Protocol, ProtocolParams, IK, IX, XX}; +use crate::handshake::State; +use crate::io::handshake; +use futures::future::BoxFuture; use futures::prelude::*; use libp2p_core::{identity, InboundUpgrade, OutboundUpgrade, PeerId, UpgradeInfo}; -use snow::HandshakeState; use std::pin::Pin; use zeroize::Zeroize; @@ -108,30 +109,31 @@ impl NoiseConfig { } } -impl NoiseConfig +/// Implement `into_responder` and `into_initiator` for all configs where `R = ()`. +/// +/// This allows us to ignore the `remote` field. +impl NoiseConfig where - C: Zeroize + AsRef<[u8]>, + C: Zeroize + Protocol + AsRef<[u8]>, { - fn into_responder(self) -> Result { - let state = self + fn into_responder(self, socket: S) -> Result, NoiseError> { + let session = self .params - .into_builder() - .prologue(self.prologue.as_ref()) - .local_private_key(self.dh_keys.secret().as_ref()) - .build_responder() - .map_err(NoiseError::from)?; + .into_builder(&self.prologue, self.dh_keys.keypair.secret(), None) + .build_responder()?; + + let state = State::new(socket, session, self.dh_keys.identity, None, self.legacy); Ok(state) } - fn into_initiator(self) -> Result { - let state = self + fn into_initiator(self, socket: S) -> Result, NoiseError> { + let session = self .params - .into_builder() - .prologue(self.prologue.as_ref()) - .local_private_key(self.dh_keys.secret().as_ref()) - .build_initiator() - .map_err(NoiseError::from)?; + .into_builder(&self.prologue, self.dh_keys.keypair.secret(), None) + .build_initiator()?; + + let state = State::new(socket, session, self.dh_keys.identity, None, self.legacy); Ok(state) } @@ -193,7 +195,7 @@ where impl NoiseConfig, identity::PublicKey)> where - C: Protocol + Zeroize, + C: Protocol + Zeroize + AsRef<[u8]>, { /// Create a new `NoiseConfig` for the `IK` handshake pattern (initiator side). /// @@ -213,10 +215,38 @@ where prologue: Vec::default(), } } -} -// Handshake pattern IX ///////////////////////////////////////////////////// + /// Specialised implementation of `into_initiator` for the `IK` handshake where `R != ()`. + fn into_initiator(self, socket: S) -> Result, NoiseError> { + let session = self + .params + .into_builder( + &self.prologue, + self.dh_keys.keypair.secret(), + Some(&self.remote.0), + ) + .build_initiator()?; + + let state = State::new( + socket, + session, + self.dh_keys.identity, + Some(self.remote.1), + self.legacy, + ); + + Ok(state) + } +} +/// Implements the responder part of the `IX` noise handshake pattern. +/// +/// `IX` is a single round-trip (2 messages) handshake in which each party sends their identity over to the other party. +/// +/// ```raw +/// initiator -{id}-> responder +/// initiator <-{id}- responder +/// ``` impl InboundUpgrade for NoiseConfig where NoiseConfig: UpgradeInfo, @@ -225,22 +255,29 @@ where { type Output = (RemoteIdentity, NoiseOutput); type Error = NoiseError; - type Future = Handshake; + type Future = BoxFuture<'static, Result<(RemoteIdentity, NoiseOutput), NoiseError>>; fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future { - let config = self.legacy; - let identity = self.dh_keys.clone().into_identity(); + async move { + let mut state = self.into_responder(socket)?; - handshake::rt1_responder( - socket, - self.into_responder(), - identity, - IdentityExchange::Mutual, - config, - ) + handshake::recv_identity(&mut state).await?; + handshake::send_identity(&mut state).await?; + + state.finish() + } + .boxed() } } +/// Implements the initiator part of the `IX` noise handshake pattern. +/// +/// `IX` is a single round-trip (2 messages) handshake in which each party sends their identity over to the other party. +/// +/// ```raw +/// initiator -{id}-> responder +/// initiator <-{id}- responder +/// ``` impl OutboundUpgrade for NoiseConfig where NoiseConfig: UpgradeInfo, @@ -249,24 +286,33 @@ where { type Output = (RemoteIdentity, NoiseOutput); type Error = NoiseError; - type Future = Handshake; + type Future = BoxFuture<'static, Result<(RemoteIdentity, NoiseOutput), NoiseError>>; fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future { - let legacy = self.legacy; - let identity = self.dh_keys.clone().into_identity(); + async move { + let mut state = self.into_initiator(socket)?; - handshake::rt1_initiator( - socket, - self.into_initiator(), - identity, - IdentityExchange::Mutual, - legacy, - ) + handshake::send_identity(&mut state).await?; + handshake::recv_identity(&mut state).await?; + + state.finish() + } + .boxed() } } -// Handshake pattern XX ///////////////////////////////////////////////////// - +/// Implements the responder part of the `XX` noise handshake pattern. +/// +/// `XX` is a 1.5 round-trip (3 messages) handshake. +/// The first message in a noise handshake is unencrypted. In the `XX` handshake pattern, that message +/// is empty and thus does not leak any information. The identities are then exchanged in the second +/// and third message. +/// +/// ```raw +/// initiator --{}--> responder +/// initiator <-{id}- responder +/// initiator -{id}-> responder +/// ``` impl InboundUpgrade for NoiseConfig where NoiseConfig: UpgradeInfo, @@ -275,22 +321,34 @@ where { type Output = (RemoteIdentity, NoiseOutput); type Error = NoiseError; - type Future = Handshake; + type Future = BoxFuture<'static, Result<(RemoteIdentity, NoiseOutput), NoiseError>>; fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future { - let legacy = self.legacy; - let identity = self.dh_keys.clone().into_identity(); + async move { + let mut state = self.into_responder(socket)?; - handshake::rt15_responder( - socket, - self.into_responder(), - identity, - IdentityExchange::Mutual, - legacy, - ) + handshake::recv_empty(&mut state).await?; + handshake::send_identity(&mut state).await?; + handshake::recv_identity(&mut state).await?; + + state.finish() + } + .boxed() } } +/// Implements the initiator part of the `XX` noise handshake pattern. +/// +/// `XX` is a 1.5 round-trip (3 messages) handshake. +/// The first message in a noise handshake is unencrypted. In the `XX` handshake pattern, that message +/// is empty and thus does not leak any information. The identities are then exchanged in the second +/// and third message. +/// +/// ```raw +/// initiator --{}--> responder +/// initiator <-{id}- responder +/// initiator -{id}-> responder +/// ``` impl OutboundUpgrade for NoiseConfig where NoiseConfig: UpgradeInfo, @@ -299,48 +357,67 @@ where { type Output = (RemoteIdentity, NoiseOutput); type Error = NoiseError; - type Future = Handshake; + type Future = BoxFuture<'static, Result<(RemoteIdentity, NoiseOutput), NoiseError>>; fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future { - let legacy = self.legacy; - let identity = self.dh_keys.clone().into_identity(); + async move { + let mut state = self.into_initiator(socket)?; - handshake::rt15_initiator( - socket, - self.into_initiator(), - identity, - IdentityExchange::Mutual, - legacy, - ) + handshake::send_empty(&mut state).await?; + handshake::recv_identity(&mut state).await?; + handshake::send_identity(&mut state).await?; + + state.finish() + } + .boxed() } } -// Handshake pattern IK ///////////////////////////////////////////////////// - -impl InboundUpgrade for NoiseConfig +/// Implements the responder part of the `IK` handshake pattern. +/// +/// `IK` is a single round-trip (2 messages) handshake. +/// +/// In the `IK` handshake, the initiator is expected to know the responder's identity already, which +/// is why the responder does not send it in the second message. +/// +/// ```raw +/// initiator -{id}-> responder +/// initiator <-{id}- responder +/// ``` +impl InboundUpgrade for NoiseConfig where - NoiseConfig: UpgradeInfo, + NoiseConfig: UpgradeInfo, T: AsyncRead + AsyncWrite + Unpin + Send + 'static, C: Protocol + AsRef<[u8]> + Zeroize + Clone + Send + 'static, { type Output = (RemoteIdentity, NoiseOutput); type Error = NoiseError; - type Future = Handshake; + type Future = BoxFuture<'static, Result<(RemoteIdentity, NoiseOutput), NoiseError>>; fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future { - let legacy = self.legacy; - let identity = self.dh_keys.clone().into_identity(); + async move { + let mut state = self.into_responder(socket)?; - handshake::rt1_responder( - socket, - self.into_responder(), - identity, - IdentityExchange::Receive, - legacy, - ) + handshake::recv_identity(&mut state).await?; + handshake::send_signature_only(&mut state).await?; + + state.finish() + } + .boxed() } } +/// Implements the initiator part of the `IK` handshake pattern. +/// +/// `IK` is a single round-trip (2 messages) handshake. +/// +/// In the `IK` handshake, the initiator knows and pre-configures the remote's identity in the +/// [`HandshakeState`](snow::HandshakeState). +/// +/// ```raw +/// initiator -{id}-> responder +/// initiator <-{id}- responder +/// ``` impl OutboundUpgrade for NoiseConfig, identity::PublicKey)> where NoiseConfig, identity::PublicKey)>: UpgradeInfo, @@ -349,27 +426,18 @@ where { type Output = (RemoteIdentity, NoiseOutput); type Error = NoiseError; - type Future = Handshake; + type Future = BoxFuture<'static, Result<(RemoteIdentity, NoiseOutput), NoiseError>>; fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future { - let session = self - .params - .into_builder() - .prologue(self.prologue.as_ref()) - .local_private_key(self.dh_keys.secret().as_ref()) - .remote_public_key(self.remote.0.as_ref()) - .build_initiator() - .map_err(NoiseError::from); - - handshake::rt1_initiator( - socket, - session, - self.dh_keys.into_identity(), - IdentityExchange::Send { - remote: self.remote.1, - }, - self.legacy, - ) + async move { + let mut state = self.into_initiator(socket)?; + + handshake::send_identity(&mut state).await?; + handshake::recv_identity(&mut state).await?; + + state.finish() + } + .boxed() } } @@ -479,51 +547,3 @@ pub struct LegacyConfig { /// libp2p implementations. pub recv_legacy_handshake: bool, } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn handshake_hashes_disagree_if_prologue_differs() { - let alice = new_xx_config() - .with_prologue(b"alice prologue".to_vec()) - .into_initiator() - .unwrap(); - let bob = new_xx_config() - .with_prologue(b"bob prologue".to_vec()) - .into_responder() - .unwrap(); - - let alice_handshake_hash = alice.get_handshake_hash(); - let bob_handshake_hash = bob.get_handshake_hash(); - - assert_ne!(alice_handshake_hash, bob_handshake_hash) - } - - #[test] - fn handshake_hashes_agree_if_prologue_is_the_same() { - let alice = new_xx_config() - .with_prologue(b"shared knowledge".to_vec()) - .into_initiator() - .unwrap(); - let bob = new_xx_config() - .with_prologue(b"shared knowledge".to_vec()) - .into_responder() - .unwrap(); - - let alice_handshake_hash = alice.get_handshake_hash(); - let bob_handshake_hash = bob.get_handshake_hash(); - - assert_eq!(alice_handshake_hash, bob_handshake_hash) - } - - fn new_xx_config() -> NoiseConfig { - let dh_keys = Keypair::::new(); - let noise_keys = dh_keys - .into_authentic(&identity::Keypair::generate_ed25519()) - .unwrap(); - - NoiseConfig::xx(noise_keys) - } -} diff --git a/transports/noise/src/protocol.rs b/transports/noise/src/protocol.rs index aa2acb150a98..9b57f05d0ba0 100644 --- a/transports/noise/src/protocol.rs +++ b/transports/noise/src/protocol.rs @@ -34,9 +34,24 @@ use zeroize::Zeroize; pub struct ProtocolParams(snow::params::NoiseParams); impl ProtocolParams { - /// Turn the protocol parameters into a session builder. - pub(crate) fn into_builder(self) -> snow::Builder<'static> { - snow::Builder::with_resolver(self.0, Box::new(Resolver)) + pub(crate) fn into_builder<'b, C>( + self, + prologue: &'b [u8], + private_key: &'b SecretKey, + remote_public_key: Option<&'b PublicKey>, + ) -> snow::Builder<'b> + where + C: Zeroize + AsRef<[u8]> + Protocol, + { + let mut builder = snow::Builder::with_resolver(self.0, Box::new(Resolver)) + .prologue(prologue.as_ref()) + .local_private_key(private_key.as_ref()); + + if let Some(remote_public_key) = remote_public_key { + builder = builder.remote_public_key(remote_public_key.as_ref()); + } + + builder } } @@ -118,26 +133,27 @@ pub struct Keypair { /// A DH keypair that is authentic w.r.t. a [`identity::PublicKey`]. #[derive(Clone)] pub struct AuthenticKeypair { - keypair: Keypair, - identity: KeypairIdentity, + pub(crate) keypair: Keypair, + pub(crate) identity: KeypairIdentity, } impl AuthenticKeypair { + /// Returns the public DH key of this keypair. + pub fn public_dh_key(&self) -> &PublicKey { + &self.keypair.public + } + /// Extract the public [`KeypairIdentity`] from this `AuthenticKeypair`, /// dropping the DH `Keypair`. + #[deprecated( + since = "0.40.0", + note = "This function was only used internally and will be removed in the future unless more usecases come up." + )] pub fn into_identity(self) -> KeypairIdentity { self.identity } } -impl std::ops::Deref for AuthenticKeypair { - type Target = Keypair; - - fn deref(&self) -> &Self::Target { - &self.keypair - } -} - /// The associated public identity of a DH keypair. #[derive(Clone)] pub struct KeypairIdentity { @@ -288,3 +304,40 @@ impl rand::RngCore for Rng { impl rand::CryptoRng for Rng {} impl snow::types::Random for Rng {} + +#[cfg(test)] +mod tests { + use super::*; + use crate::X25519; + + #[test] + fn handshake_hashes_disagree_if_prologue_differs() { + let alice = xx_builder(b"alice prologue").build_initiator().unwrap(); + let bob = xx_builder(b"bob prologue").build_responder().unwrap(); + + let alice_handshake_hash = alice.get_handshake_hash(); + let bob_handshake_hash = bob.get_handshake_hash(); + + assert_ne!(alice_handshake_hash, bob_handshake_hash) + } + + #[test] + fn handshake_hashes_agree_if_prologue_is_the_same() { + let alice = xx_builder(b"shared knowledge").build_initiator().unwrap(); + let bob = xx_builder(b"shared knowledge").build_responder().unwrap(); + + let alice_handshake_hash = alice.get_handshake_hash(); + let bob_handshake_hash = bob.get_handshake_hash(); + + assert_eq!(alice_handshake_hash, bob_handshake_hash) + } + + fn xx_builder(prologue: &'static [u8]) -> snow::Builder<'static> { + X25519::params_xx().into_builder(prologue, TEST_KEY.secret(), None) + } + + // Hack to work around borrow-checker. + lazy_static::lazy_static! { + static ref TEST_KEY: Keypair = Keypair::::new(); + } +} diff --git a/transports/noise/tests/smoke.rs b/transports/noise/tests/smoke.rs index 16dcf4383d1c..c69ebe031327 100644 --- a/transports/noise/tests/smoke.rs +++ b/transports/noise/tests/smoke.rs @@ -197,7 +197,7 @@ fn ik_xx() { let client_id_public = client_id.public(); let server_dh = Keypair::::new().into_authentic(&server_id).unwrap(); - let server_dh_public = server_dh.public().clone(); + let server_dh_public = server_dh.public_dh_key().clone(); let server_transport = TcpTransport::default() .and_then(move |output, endpoint| { if endpoint.is_listener() { diff --git a/transports/plaintext/CHANGELOG.md b/transports/plaintext/CHANGELOG.md index a0d21b8d1f36..93162dfa26dc 100644 --- a/transports/plaintext/CHANGELOG.md +++ b/transports/plaintext/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.37.0 [unreleased] +# 0.37.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/transports/pnet/CHANGELOG.md b/transports/pnet/CHANGELOG.md index f2e40c03d8ff..e63f196c8696 100644 --- a/transports/pnet/CHANGELOG.md +++ b/transports/pnet/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.22.1 [unreleased] +# 0.22.1 - Bump rand to 0.8 and quickcheck to 1. See [PR 2857]. diff --git a/transports/tcp/CHANGELOG.md b/transports/tcp/CHANGELOG.md index 83ad2d3c1a34..54cbed563e11 100644 --- a/transports/tcp/CHANGELOG.md +++ b/transports/tcp/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.37.0 - [unreleased] +# 0.37.0 - Update to `if-watch` `v2.0.0`. Simplify `IfWatcher` integration. Use `if_watch::IfWatcher` for all runtimes. See [PR 2813]. diff --git a/transports/uds/CHANGELOG.md b/transports/uds/CHANGELOG.md index 6d7581890c99..97ae47216ace 100644 --- a/transports/uds/CHANGELOG.md +++ b/transports/uds/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.36.0 [unreleased] +# 0.36.0 - Remove default features. If you previously depended on `async-std` you need to enable this explicitly now. See [PR 2918]. diff --git a/transports/wasm-ext/CHANGELOG.md b/transports/wasm-ext/CHANGELOG.md index b778fb9a7cad..ea8ef1018510 100644 --- a/transports/wasm-ext/CHANGELOG.md +++ b/transports/wasm-ext/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.37.0 [unreleased] +# 0.37.0 - Update to `libp2p-core` `v0.37.0`. diff --git a/transports/websocket/CHANGELOG.md b/transports/websocket/CHANGELOG.md index 10fcf02e1834..dde9105483c2 100644 --- a/transports/websocket/CHANGELOG.md +++ b/transports/websocket/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.39.0 [unreleased] +# 0.39.0 - Update to `libp2p-core` `v0.37.0`.