diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 8c1349f4bc03..000000000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,3 +0,0 @@ -[alias] -# Temporary solution to have clippy config in a single place until https://github.com/rust-lang/rust-clippy/blob/master/doc/roadmap-2021.md#lintstoml-configuration is shipped. -custom-clippy = "clippy --workspace --all-features --all-targets -- -A clippy::type_complexity -A clippy::pedantic -W clippy::used_underscore_binding -W unreachable_pub" diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index b225bdd9a1c0..000000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -name: Bug Report -about: Create a bug report for rust-libp2p. ---- - - - - - -## Summary - - - -## Expected behaviour - - - -## Actual behaviour - - - - -
Debug Output -

- -``` - -``` -

-
- -## Possible Solution - - -## Version - - -- libp2p version (version number, commit, or branch): - - -## Would you like to work on fixing this bug? - - - -Yes / No / Maybe. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000000..1a531e3646c9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,55 @@ +name: Bug Report +description: Create a bug report for rust-libp2p + +body: + - type: markdown + attributes: + value: | + Thank you for filing a bug report! + - type: textarea + attributes: + label: Summary + description: Please provide a short summary of the bug, along with any information you feel relevant to replicate the bug. + validations: + required: true + - type: textarea + attributes: + label: Expected behavior + description: Describe what you expect to happen. + validations: + required: true + - type: textarea + attributes: + label: Actual behavior + description: Describe what actually happens. + validations: + required: true + - type: textarea + attributes: + label: Relevant log output + description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. + render: shell + validations: + required: false + - type: textarea + attributes: + label: Possible Solution + description: Suggest a fix/reason for the bug, or ideas how to implement the addition or change. + validations: + required: false + - type: textarea + attributes: + label: Version + description: Which version of libp2p are you using? libp2p version (version number, commit, or branch) + validations: + required: false + - type: dropdown + attributes: + label: Would you like to work on fixing this bug ? + description: Any contribution towards fixing the bug is greatly appreciated. We are more than happy to provide help on the process. + options: + - "Yes" + - "No" + - Maybe + validations: + required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 5fdf7ed9da47..29c54c335a4d 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,5 @@ blank_issues_enabled: true contact_links: - - name: Report a vulnerability - url: https://github.com/libp2p/rust-libp2p/security/advisories/new - about: For security related issues please file a private security vulnerability report. - name: Question url: https://github.com/libp2p/rust-libp2p/discussions/new?category=q-a about: Please ask questions in the rust-libp2p GitHub Discussions forum. diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md deleted file mode 100644 index b3a3dd30115c..000000000000 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: Enhancement -about: Suggest an improvement to an existing rust-libp2p feature. ---- - -## Description - - - -## Motivation - - - -## Current Implementation - - - -## Are you planning to do it yourself in a pull request? - - - -Yes / No / Maybe. diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml new file mode 100644 index 000000000000..ed7aeb644b31 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -0,0 +1,31 @@ +name: Enhancement +description: Suggest an improvement to an existing rust-libp2p feature. +body: + - type: textarea + attributes: + label: Description + description: Describe the enhancement that you are proposing. + validations: + required: true + - type: textarea + attributes: + label: Motivation + description: Explain why this enhancement is beneficial. + validations: + required: true + - type: textarea + attributes: + label: Current Implementation + description: Describe the current implementation. + validations: + required: true + - type: dropdown + attributes: + label: Are you planning to do it yourself in a pull request ? + description: Any contribution is greatly appreciated. We are more than happy to provide help on the process. + options: + - "Yes" + - "No" + - Maybe + validations: + required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 822aa0631472..000000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: Feature request -about: Suggest a new feature in rust-libp2p. ---- - - - -## Description - - - -## Motivation - - - -## Requirements - - - -1. -2. -3. - -## Open questions - - - -## Are you planning to do it yourself in a pull request? - - - -Yes / No / Maybe. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000000..6fa3e638be85 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,42 @@ +name: Feature request +description: Suggest a new feature in rust-libp2p +body: + - type: markdown + attributes: + value: | + If you'd like to suggest a feature related to libp2p but not specifically related to the rust implementation, please file an issue at https://github.com/libp2p/specs instead. + - type: textarea + attributes: + label: Description + description: Briefly describe the feature that you are requesting. + validations: + required: true + - type: textarea + attributes: + label: Motivation + description: Explain why this feature is needed. + validations: + required: true + - type: textarea + attributes: + label: Requirements + description: Write a list of what you want this feature to do. + placeholder: "1." + validations: + required: true + - type: textarea + attributes: + label: Open questions + description: Use this section to ask any questions that are related to the feature. + validations: + required: false + - type: dropdown + attributes: + label: Are you planning to do it yourself in a pull request ? + description: Any contribution is greatly appreciated. We are more than happy to provide help on the process. + options: + - "Yes" + - "No" + - Maybe + validations: + required: true \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b12596bb6c2..429511175165 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -200,8 +200,9 @@ jobs: fail-fast: false matrix: rust-version: [ - 1.72.0, # current stable - beta + # 1.72.0, # current stable + # beta, + nightly-2023-09-10 ] steps: - uses: actions/checkout@v4 @@ -218,7 +219,7 @@ jobs: save-if: ${{ github.ref == 'refs/heads/master' }} - name: Run cargo clippy - run: cargo custom-clippy # cargo alias to allow reuse of config locally + run: cargo clippy ipfs-integration-test: name: IPFS Integration tests @@ -234,8 +235,11 @@ jobs: with: save-if: ${{ github.ref == 'refs/heads/master' }} - - name: Run ipfs-kad example - run: cd ./examples/ipfs-kad/ && RUST_LOG=libp2p_swarm=debug,libp2p_kad=trace,libp2p_tcp=debug cargo run + - name: Run ipfs-kad example - get peers + run: cd ./examples/ipfs-kad/ && RUST_LOG=libp2p_swarm=debug,libp2p_kad=trace,libp2p_tcp=debug cargo run -- get-peers + + - name: Run ipfs-kad example - put PK record + run: cd ./examples/ipfs-kad/ && RUST_LOG=libp2p_swarm=debug,libp2p_kad=trace,libp2p_tcp=debug cargo run -- put-pk-record examples: runs-on: ubuntu-latest @@ -263,9 +267,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - run: wget -q -O- https://github.com/obi1kenobi/cargo-semver-checks/releases/download/v0.23.0/cargo-semver-checks-x86_64-unknown-linux-gnu.tar.gz | tar -xz -C ~/.cargo/bin + - run: wget -q -O- https://github.com/obi1kenobi/cargo-semver-checks/releases/download/v0.24.0/cargo-semver-checks-x86_64-unknown-linux-gnu.tar.gz | tar -xz -C ~/.cargo/bin shell: bash - - uses: obi1kenobi/cargo-semver-checks-action@v2 + - uses: obi1kenobi/cargo-semver-checks-action@e275dda72e250d4df5b564e969e1348d67fefa52 # v2 rustfmt: runs-on: ubuntu-latest diff --git a/.github/workflows/interop-test.yml b/.github/workflows/interop-test.yml index e3485f25dc60..8fa00f0a8f60 100644 --- a/.github/workflows/interop-test.yml +++ b/.github/workflows/interop-test.yml @@ -18,9 +18,16 @@ jobs: flavour: [chromium, native] steps: - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + - name: Build ${{ matrix.flavour }} image - run: docker buildx build --load -t ${{ matrix.flavour }}-rust-libp2p-head . -f interop-tests/Dockerfile.${{ matrix.flavour }} + run: ./scripts/build-interop-image.sh + env: + AWS_ACCESS_KEY_ID: ${{ vars.TEST_PLANS_BUILD_CACHE_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.TEST_PLANS_BUILD_CACHE_KEY }} + FLAVOUR: ${{ matrix.flavour }} + - name: Run ${{ matrix.flavour }} tests uses: libp2p/test-plans/.github/actions/run-interop-ping-test@master with: diff --git a/Cargo.lock b/Cargo.lock index 89d3b70ba8c2..7a913d157a54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -430,7 +430,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -473,11 +473,11 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" name = "autonat-example" version = "0.1.0" dependencies = [ - "async-std", "clap", "env_logger 0.10.0", "futures", "libp2p", + "tokio", ] [[package]] @@ -889,7 +889,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1197,7 +1197,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1312,7 +1312,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1366,7 +1366,7 @@ dependencies = [ "ed25519", "rand_core 0.6.4", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "zeroize", ] @@ -1415,7 +1415,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -1662,7 +1662,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -2252,23 +2252,25 @@ dependencies = [ name = "ipfs-kad-example" version = "0.1.0" dependencies = [ - "async-std", + "anyhow", "async-trait", + "clap", "env_logger 0.10.0", "futures", "libp2p", + "tokio", ] [[package]] name = "ipfs-private-example" version = "0.1.0" dependencies = [ - "async-std", "async-trait", "either", "env_logger 0.10.0", "futures", "libp2p", + "tokio", ] [[package]] @@ -2351,9 +2353,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libp2p" @@ -2602,7 +2604,7 @@ dependencies = [ "rand 0.8.5", "regex", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "smallvec", "unsigned-varint", "void", @@ -2617,6 +2619,7 @@ dependencies = [ "either", "env_logger 0.10.0", "futures", + "futures-bounded", "futures-timer", "libp2p-core", "libp2p-identity", @@ -2633,7 +2636,7 @@ dependencies = [ [[package]] name = "libp2p-identity" -version = "0.2.3" +version = "0.2.5" dependencies = [ "asn1_der", "base64 0.21.4", @@ -2641,6 +2644,7 @@ dependencies = [ "criterion", "ed25519-dalek", "hex-literal", + "hkdf", "libsecp256k1", "log", "multihash", @@ -2653,7 +2657,7 @@ dependencies = [ "sec1", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", "void", "zeroize", @@ -2686,7 +2690,7 @@ dependencies = [ "quickcheck-ext", "rand 0.8.5", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "smallvec", "thiserror", "uint", @@ -2809,7 +2813,7 @@ dependencies = [ "quick-protobuf", "quickcheck-ext", "rand 0.8.5", - "sha2 0.10.7", + "sha2 0.10.8", "snow", "static_assertions", "thiserror", @@ -2927,6 +2931,7 @@ dependencies = [ "quickcheck", "quinn", "rand 0.8.5", + "ring", "rustls 0.21.7", "socket2 0.5.4", "thiserror", @@ -3078,7 +3083,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -3222,7 +3227,7 @@ dependencies = [ "quick-protobuf-codec", "rand 0.8.5", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", "tinytemplate", "unsigned-varint", @@ -3396,9 +3401,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" +checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" dependencies = [ "hashbrown 0.14.0", ] @@ -3760,9 +3765,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -3836,7 +3841,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -3872,7 +3877,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -3884,7 +3889,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -3983,7 +3988,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -4008,11 +4013,10 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" name = "ping-example" version = "0.1.0" dependencies = [ - "async-std", - "async-trait", "env_logger 0.10.0", "futures", "libp2p", + "tokio", ] [[package]] @@ -4163,14 +4167,14 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -4481,13 +4485,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ "aho-corasick 1.0.2", "memchr", - "regex-automata 0.3.8", + "regex-automata 0.3.9", "regex-syntax 0.7.5", ] @@ -4502,9 +4506,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick 1.0.2", "memchr", @@ -4550,9 +4554,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "base64 0.21.4", "bytes", @@ -4575,6 +4579,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -4712,7 +4717,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.37", + "syn 2.0.38", "walkdir", ] @@ -4723,7 +4728,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "873feff8cb7bf86fdf0a71bb21c95159f4e4a37dd7a4bd1855a940909b583ada" dependencies = [ "globset", - "sha2 0.10.7", + "sha2 0.10.8", "walkdir", ] @@ -4997,7 +5002,7 @@ checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -5030,7 +5035,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -5084,9 +5089,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -5204,7 +5209,7 @@ dependencies = [ "rand_core 0.6.4", "ring", "rustc_version", - "sha2 0.10.7", + "sha2 0.10.8", "subtle", ] @@ -5327,9 +5332,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.37" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -5452,22 +5457,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -5559,7 +5564,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -5682,7 +5687,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] [[package]] @@ -6050,7 +6055,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", "wasm-bindgen-shared", ] @@ -6084,7 +6089,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6161,9 +6166,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.1" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" +checksum = "07ecc0cd7cac091bf682ec5efa18b1cff79d617b84181f38b3951dbe135f607f" dependencies = [ "ring", "untrusted", @@ -6200,7 +6205,7 @@ dependencies = [ "sdp", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "smol_str", "stun", "thiserror", @@ -6261,7 +6266,7 @@ dependencies = [ "sec1", "serde", "sha1", - "sha2 0.10.7", + "sha2 0.10.8", "subtle", "thiserror", "tokio", @@ -6652,5 +6657,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.37", + "syn 2.0.38", ] diff --git a/Cargo.toml b/Cargo.toml index 73ae23d70ffe..55129a8ea965 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,7 +82,7 @@ libp2p-dns = { version = "0.40.1", path = "transports/dns" } libp2p-floodsub = { version = "0.43.0", path = "protocols/floodsub" } libp2p-gossipsub = { version = "0.45.1", path = "protocols/gossipsub" } libp2p-identify = { version = "0.43.1", path = "protocols/identify" } -libp2p-identity = { version = "0.2.3" } +libp2p-identity = { version = "0.2.5" } libp2p-kad = { version = "0.44.6", path = "protocols/kad" } libp2p-mdns = { version = "0.44.0", path = "protocols/mdns" } libp2p-memory-connection-limits = { version = "0.1.0", path = "misc/memory-connection-limits" } @@ -128,3 +128,9 @@ multihash = "0.19.1" # we import via `rust-multiaddr`. # This is expected to stay here until we move `libp2p-identity` to a separate repository which makes the dependency relationship more obvious. libp2p-identity = { path = "identity" } + +[workspace.lints] +rust.unreachable_pub = "warn" +clippy.used_underscore_binding = "warn" +clippy.pedantic = "allow" +clippy.type_complexity = "allow" diff --git a/core/Cargo.toml b/core/Cargo.toml index ecf3c1533129..15288a48d1cb 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -35,9 +35,9 @@ void = "1" [dev-dependencies] async-std = { version = "1.6.2", features = ["attributes"] } -libp2p-mplex = { path = "../muxers/mplex" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. -libp2p-noise = { path = "../transports/noise" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. -multihash = { workspace = true , features = ["arb"] } +libp2p-mplex = { path = "../muxers/mplex" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-noise = { path = "../transports/noise" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +multihash = { workspace = true, features = ["arb"] } quickcheck = { workspace = true } libp2p-identity = { workspace = true, features = ["ed25519"] } @@ -50,3 +50,6 @@ serde = ["multihash/serde-codec", "dep:serde", "libp2p-identity/serde"] all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/core/src/transport.rs b/core/src/transport.rs index c98612971db4..9aeddb72ad08 100644 --- a/core/src/transport.rs +++ b/core/src/transport.rs @@ -135,7 +135,7 @@ pub trait Transport { /// /// This option is needed for NAT and firewall hole punching. /// - /// See [`ConnectedPoint::Dialer`](crate::connection::ConnectedPoint::Dialer) for related option. + /// See [`ConnectedPoint::Dialer`] for related option. fn dial_as_listener( &mut self, addr: Multiaddr, @@ -235,8 +235,7 @@ pub trait Transport { and_then::AndThen::new(self, f) } - /// Begins a series of protocol upgrades via an - /// [`upgrade::Builder`](upgrade::Builder). + /// Begins a series of protocol upgrades via an [`upgrade::Builder`]. fn upgrade(self, version: upgrade::Version) -> upgrade::Builder where Self: Sized, diff --git a/examples/autonat/Cargo.toml b/examples/autonat/Cargo.toml index 741c29de0a06..332f77f04a7f 100644 --- a/examples/autonat/Cargo.toml +++ b/examples/autonat/Cargo.toml @@ -6,8 +6,11 @@ publish = false license = "MIT" [dependencies] -async-std = { version = "1.12", features = ["attributes"] } +tokio = { version = "1.32", features = ["full"] } clap = { version = "4.3.23", features = ["derive"] } env_logger = "0.10.0" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "tcp", "noise", "yamux", "autonat", "identify", "macros"] } +libp2p = { path = "../../libp2p", features = ["tokio", "tcp", "noise", "yamux", "autonat", "identify", "macros"] } + +[lints] +workspace = true diff --git a/examples/autonat/src/bin/autonat_client.rs b/examples/autonat/src/bin/autonat_client.rs index 9436bed030fd..eeb39ec52dea 100644 --- a/examples/autonat/src/bin/autonat_client.rs +++ b/examples/autonat/src/bin/autonat_client.rs @@ -43,7 +43,7 @@ struct Opt { server_peer_id: PeerId, } -#[async_std::main] +#[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); @@ -52,7 +52,7 @@ async fn main() -> Result<(), Box> { let local_key = identity::Keypair::generate_ed25519(); let local_peer_id = PeerId::from(local_key.public()); - let transport = tcp::async_io::Transport::default() + let transport = tcp::tokio::Transport::default() .upgrade(Version::V1Lazy) .authenticate(noise::Config::new(&local_key)?) .multiplex(yamux::Config::default()) @@ -60,8 +60,7 @@ async fn main() -> Result<(), Box> { let behaviour = Behaviour::new(local_key.public()); - let mut swarm = - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); + let mut swarm = SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id).build(); swarm.listen_on( Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED)) diff --git a/examples/autonat/src/bin/autonat_server.rs b/examples/autonat/src/bin/autonat_server.rs index 736edbe893d5..065708f745f5 100644 --- a/examples/autonat/src/bin/autonat_server.rs +++ b/examples/autonat/src/bin/autonat_server.rs @@ -35,7 +35,7 @@ struct Opt { listen_port: Option, } -#[async_std::main] +#[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); @@ -44,7 +44,7 @@ async fn main() -> Result<(), Box> { let local_key = identity::Keypair::generate_ed25519(); let local_peer_id = PeerId::from(local_key.public()); - let transport = tcp::async_io::Transport::default() + let transport = tcp::tokio::Transport::default() .upgrade(Version::V1Lazy) .authenticate(noise::Config::new(&local_key)?) .multiplex(yamux::Config::default()) @@ -52,8 +52,7 @@ async fn main() -> Result<(), Box> { let behaviour = Behaviour::new(local_key.public()); - let mut swarm = - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build(); + let mut swarm = SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id).build(); swarm.listen_on( Multiaddr::empty() .with(Protocol::Ip4(Ipv4Addr::UNSPECIFIED)) diff --git a/examples/browser-webrtc/Cargo.toml b/examples/browser-webrtc/Cargo.toml index 99263dde2b3f..f6b47d4ded9f 100644 --- a/examples/browser-webrtc/Cargo.toml +++ b/examples/browser-webrtc/Cargo.toml @@ -21,7 +21,7 @@ rand = "0.8" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] axum = "0.6.19" -libp2p = { path = "../../libp2p", features = ["ed25519", "macros", "ping", "wasm-bindgen", "tokio"] } +libp2p = { path = "../../libp2p", features = [ "ed25519", "macros", "ping", "wasm-bindgen", "tokio"] } libp2p-webrtc = { workspace = true, features = ["tokio"] } rust-embed = { version = "8.0.0", features = ["include-exclude", "interpolate-folder-path"] } tokio = { version = "1.29", features = ["macros", "net", "rt", "signal"] } @@ -32,9 +32,12 @@ mime_guess = "2.0.4" [target.'cfg(target_arch = "wasm32")'.dependencies] js-sys = "0.3.64" -libp2p = { path = "../../libp2p", features = ["ed25519", "macros", "ping", "wasm-bindgen"] } +libp2p = { path = "../../libp2p", features = [ "ed25519", "macros", "ping", "wasm-bindgen"] } libp2p-webrtc-websys = { workspace = true } wasm-bindgen = "0.2.84" wasm-bindgen-futures = "0.4.37" wasm-logger = { version = "0.2.0" } web-sys = { version = "0.3", features = ['Document', 'Element', 'HtmlElement', 'Node', 'Response', 'Window'] } + +[lints] +workspace = true diff --git a/examples/chat/Cargo.toml b/examples/chat/Cargo.toml index 9c539c851d73..cee9e553e279 100644 --- a/examples/chat/Cargo.toml +++ b/examples/chat/Cargo.toml @@ -10,4 +10,7 @@ tokio = { version = "1.32", features = ["full"] } async-trait = "0.1" env_logger = "0.10.0" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["tokio", "gossipsub", "mdns", "noise", "macros", "tcp", "yamux", "quic"] } +libp2p = { path = "../../libp2p", features = [ "tokio", "gossipsub", "mdns", "noise", "macros", "tcp", "yamux", "quic"] } + +[lints] +workspace = true diff --git a/examples/dcutr/Cargo.toml b/examples/dcutr/Cargo.toml index 852083d09775..49e1ada2e968 100644 --- a/examples/dcutr/Cargo.toml +++ b/examples/dcutr/Cargo.toml @@ -10,5 +10,8 @@ clap = { version = "4.3.23", features = ["derive"] } env_logger = "0.10.0" futures = "0.3.28" futures-timer = "3.0" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "dcutr", "identify", "macros", "noise", "ping", "quic", "relay", "rendezvous", "tcp", "tokio", "yamux"] } +libp2p = { path = "../../libp2p", features = [ "async-std", "dns", "dcutr", "identify", "macros", "noise", "ping", "quic", "relay", "rendezvous", "tcp", "tokio", "yamux"] } log = "0.4" + +[lints] +workspace = true diff --git a/examples/dcutr/src/main.rs b/examples/dcutr/src/main.rs index ec3085218748..099867df7444 100644 --- a/examples/dcutr/src/main.rs +++ b/examples/dcutr/src/main.rs @@ -110,7 +110,6 @@ fn main() -> Result<(), Box> { }; #[derive(NetworkBehaviour)] - #[behaviour(to_swarm = "Event")] struct Behaviour { relay_client: relay::client::Behaviour, ping: ping::Behaviour, @@ -118,39 +117,6 @@ fn main() -> Result<(), Box> { dcutr: dcutr::Behaviour, } - #[derive(Debug)] - #[allow(clippy::large_enum_variant)] - enum Event { - Ping(ping::Event), - Identify(identify::Event), - Relay(relay::client::Event), - Dcutr(dcutr::Event), - } - - impl From for Event { - fn from(e: ping::Event) -> Self { - Event::Ping(e) - } - } - - impl From for Event { - fn from(e: identify::Event) -> Self { - Event::Identify(e) - } - } - - impl From for Event { - fn from(e: relay::client::Event) -> Self { - Event::Relay(e) - } - } - - impl From for Event { - fn from(e: dcutr::Event) -> Self { - Event::Dcutr(e) - } - } - let behaviour = Behaviour { relay_client: client, ping: ping::Behaviour::new(ping::Config::new()), @@ -207,12 +173,14 @@ fn main() -> Result<(), Box> { SwarmEvent::NewListenAddr { .. } => {} SwarmEvent::Dialing { .. } => {} SwarmEvent::ConnectionEstablished { .. } => {} - SwarmEvent::Behaviour(Event::Ping(_)) => {} - SwarmEvent::Behaviour(Event::Identify(identify::Event::Sent { .. })) => { + SwarmEvent::Behaviour(BehaviourEvent::Ping(_)) => {} + SwarmEvent::Behaviour(BehaviourEvent::Identify(identify::Event::Sent { + .. + })) => { info!("Told relay its public address."); told_relay_observed_addr = true; } - SwarmEvent::Behaviour(Event::Identify(identify::Event::Received { + SwarmEvent::Behaviour(BehaviourEvent::Identify(identify::Event::Received { info: identify::Info { observed_addr, .. }, .. })) => { @@ -252,22 +220,22 @@ fn main() -> Result<(), Box> { SwarmEvent::NewListenAddr { address, .. } => { info!("Listening on {:?}", address); } - SwarmEvent::Behaviour(Event::Relay( + SwarmEvent::Behaviour(BehaviourEvent::RelayClient( relay::client::Event::ReservationReqAccepted { .. }, )) => { assert!(opts.mode == Mode::Listen); info!("Relay accepted our reservation request."); } - SwarmEvent::Behaviour(Event::Relay(event)) => { + SwarmEvent::Behaviour(BehaviourEvent::RelayClient(event)) => { info!("{:?}", event) } - SwarmEvent::Behaviour(Event::Dcutr(event)) => { + SwarmEvent::Behaviour(BehaviourEvent::Dcutr(event)) => { info!("{:?}", event) } - SwarmEvent::Behaviour(Event::Identify(event)) => { + SwarmEvent::Behaviour(BehaviourEvent::Identify(event)) => { info!("{:?}", event) } - SwarmEvent::Behaviour(Event::Ping(_)) => {} + SwarmEvent::Behaviour(BehaviourEvent::Ping(_)) => {} SwarmEvent::ConnectionEstablished { peer_id, endpoint, .. } => { diff --git a/examples/distributed-key-value-store/Cargo.toml b/examples/distributed-key-value-store/Cargo.toml index d128d6bbc519..aa9a875be5ad 100644 --- a/examples/distributed-key-value-store/Cargo.toml +++ b/examples/distributed-key-value-store/Cargo.toml @@ -10,4 +10,7 @@ async-std = { version = "1.12", features = ["attributes"] } async-trait = "0.1" env_logger = "0.10" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "mdns", "noise", "macros", "tcp", "websocket", "yamux"] } +libp2p = { path = "../../libp2p", features = [ "async-std", "dns", "kad", "mdns", "noise", "macros", "tcp", "websocket", "yamux"] } + +[lints] +workspace = true diff --git a/examples/distributed-key-value-store/src/main.rs b/examples/distributed-key-value-store/src/main.rs index d1eec92203ce..cd9857b1482e 100644 --- a/examples/distributed-key-value-store/src/main.rs +++ b/examples/distributed-key-value-store/src/main.rs @@ -49,37 +49,18 @@ async fn main() -> Result<(), Box> { // We create a custom network behaviour that combines Kademlia and mDNS. #[derive(NetworkBehaviour)] - #[behaviour(to_swarm = "MyBehaviourEvent")] - struct MyBehaviour { + struct Behaviour { kademlia: kad::Behaviour, mdns: mdns::async_io::Behaviour, } - #[allow(clippy::large_enum_variant)] - enum MyBehaviourEvent { - Kademlia(kad::Event), - Mdns(mdns::Event), - } - - impl From for MyBehaviourEvent { - fn from(event: kad::Event) -> Self { - MyBehaviourEvent::Kademlia(event) - } - } - - impl From for MyBehaviourEvent { - fn from(event: mdns::Event) -> Self { - MyBehaviourEvent::Mdns(event) - } - } - // Create a swarm to manage peers and events. let mut swarm = { // Create a Kademlia behaviour. let store = MemoryStore::new(local_peer_id); let kademlia = kad::Behaviour::new(local_peer_id, store); let mdns = mdns::async_io::Behaviour::new(mdns::Config::default(), local_peer_id)?; - let behaviour = MyBehaviour { kademlia, mdns }; + let behaviour = Behaviour { kademlia, mdns }; SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build() }; @@ -99,12 +80,12 @@ async fn main() -> Result<(), Box> { SwarmEvent::NewListenAddr { address, .. } => { println!("Listening in {address:?}"); }, - SwarmEvent::Behaviour(MyBehaviourEvent::Mdns(mdns::Event::Discovered(list))) => { + SwarmEvent::Behaviour(BehaviourEvent::Mdns(mdns::Event::Discovered(list))) => { for (peer_id, multiaddr) in list { swarm.behaviour_mut().kademlia.add_address(&peer_id, multiaddr); } } - SwarmEvent::Behaviour(MyBehaviourEvent::Kademlia(kad::Event::OutboundQueryProgressed { result, ..})) => { + SwarmEvent::Behaviour(BehaviourEvent::Kademlia(kad::Event::OutboundQueryProgressed { result, ..})) => { match result { kad::QueryResult::GetProviders(Ok(kad::GetProvidersOk::FoundProviders { key, providers, .. })) => { for peer in providers { diff --git a/examples/file-sharing/Cargo.toml b/examples/file-sharing/Cargo.toml index 03745aacb009..90462790c115 100644 --- a/examples/file-sharing/Cargo.toml +++ b/examples/file-sharing/Cargo.toml @@ -12,5 +12,8 @@ clap = { version = "4.3.23", features = ["derive"] } either = "1.9" env_logger = "0.10" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "cbor", "dns", "kad", "noise", "macros", "request-response", "tcp", "websocket", "yamux"] } +libp2p = { path = "../../libp2p", features = [ "async-std", "cbor", "dns", "kad", "noise", "macros", "request-response", "tcp", "websocket", "yamux"] } void = "1.0.2" + +[lints] +workspace = true diff --git a/examples/file-sharing/src/network.rs b/examples/file-sharing/src/network.rs index 675f69a03d82..f13e72f0000c 100644 --- a/examples/file-sharing/src/network.rs +++ b/examples/file-sharing/src/network.rs @@ -51,7 +51,7 @@ pub(crate) async fn new( // higher layer network behaviour logic. let mut swarm = SwarmBuilder::with_async_std_executor( transport, - ComposedBehaviour { + Behaviour { kademlia: kad::Behaviour::new(peer_id, kad::record::store::MemoryStore::new(peer_id)), request_response: request_response::cbor::Behaviour::new( [( @@ -171,7 +171,7 @@ impl Client { } pub(crate) struct EventLoop { - swarm: Swarm, + swarm: Swarm, command_receiver: mpsc::Receiver, event_sender: mpsc::Sender, pending_dial: HashMap>>>, @@ -183,7 +183,7 @@ pub(crate) struct EventLoop { impl EventLoop { fn new( - swarm: Swarm, + swarm: Swarm, command_receiver: mpsc::Receiver, event_sender: mpsc::Sender, ) -> Self { @@ -213,10 +213,10 @@ impl EventLoop { async fn handle_event( &mut self, - event: SwarmEvent>, + event: SwarmEvent>, ) { match event { - SwarmEvent::Behaviour(ComposedEvent::Kademlia( + SwarmEvent::Behaviour(BehaviourEvent::Kademlia( kad::Event::OutboundQueryProgressed { id, result: kad::QueryResult::StartProviding(_), @@ -229,7 +229,7 @@ impl EventLoop { .expect("Completed query to be previously pending."); let _ = sender.send(()); } - SwarmEvent::Behaviour(ComposedEvent::Kademlia( + SwarmEvent::Behaviour(BehaviourEvent::Kademlia( kad::Event::OutboundQueryProgressed { id, result: @@ -252,7 +252,7 @@ impl EventLoop { .finish(); } } - SwarmEvent::Behaviour(ComposedEvent::Kademlia( + SwarmEvent::Behaviour(BehaviourEvent::Kademlia( kad::Event::OutboundQueryProgressed { result: kad::QueryResult::GetProviders(Ok( @@ -261,8 +261,8 @@ impl EventLoop { .. }, )) => {} - SwarmEvent::Behaviour(ComposedEvent::Kademlia(_)) => {} - SwarmEvent::Behaviour(ComposedEvent::RequestResponse( + SwarmEvent::Behaviour(BehaviourEvent::Kademlia(_)) => {} + SwarmEvent::Behaviour(BehaviourEvent::RequestResponse( request_response::Event::Message { message, .. }, )) => match message { request_response::Message::Request { @@ -287,7 +287,7 @@ impl EventLoop { .send(Ok(response.0)); } }, - SwarmEvent::Behaviour(ComposedEvent::RequestResponse( + SwarmEvent::Behaviour(BehaviourEvent::RequestResponse( request_response::Event::OutboundFailure { request_id, error, .. }, @@ -298,7 +298,7 @@ impl EventLoop { .expect("Request to still be pending.") .send(Err(Box::new(error))); } - SwarmEvent::Behaviour(ComposedEvent::RequestResponse( + SwarmEvent::Behaviour(BehaviourEvent::RequestResponse( request_response::Event::ResponseSent { .. }, )) => {} SwarmEvent::NewListenAddr { address, .. } => { @@ -406,30 +406,11 @@ impl EventLoop { } #[derive(NetworkBehaviour)] -#[behaviour(to_swarm = "ComposedEvent")] -struct ComposedBehaviour { +struct Behaviour { request_response: request_response::cbor::Behaviour, kademlia: kad::Behaviour, } -#[derive(Debug)] -enum ComposedEvent { - RequestResponse(request_response::Event), - Kademlia(kad::Event), -} - -impl From> for ComposedEvent { - fn from(event: request_response::Event) -> Self { - ComposedEvent::RequestResponse(event) - } -} - -impl From for ComposedEvent { - fn from(event: kad::Event) -> Self { - ComposedEvent::Kademlia(event) - } -} - #[derive(Debug)] enum Command { StartListening { diff --git a/examples/identify/Cargo.toml b/examples/identify/Cargo.toml index fb14aeba4a5a..cc30a0c614ca 100644 --- a/examples/identify/Cargo.toml +++ b/examples/identify/Cargo.toml @@ -10,4 +10,7 @@ async-std = { version = "1.12", features = ["attributes"] } async-trait = "0.1" env_logger = "0.10" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "dcutr", "identify", "macros", "noise", "ping", "relay", "rendezvous", "tcp", "tokio", "yamux"] } +libp2p = { path = "../../libp2p", features = ["async-std", "dns", "dcutr", "identify", "macros", "noise", "ping", "relay", "rendezvous", "tcp", "tokio","yamux"] } + +[lints] +workspace = true diff --git a/examples/ipfs-kad/Cargo.toml b/examples/ipfs-kad/Cargo.toml index 0526060eaa6b..ae524e3857b6 100644 --- a/examples/ipfs-kad/Cargo.toml +++ b/examples/ipfs-kad/Cargo.toml @@ -6,8 +6,13 @@ publish = false license = "MIT" [dependencies] -async-std = { version = "1.12", features = ["attributes"] } +tokio = { version = "1.12", features = ["rt-multi-thread", "macros"] } async-trait = "0.1" +clap = { version = "4.3.23", features = ["derive"] } env_logger = "0.10" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "noise", "tcp", "websocket", "yamux", "rsa"] } +anyhow = "1.0.75" +libp2p = { path = "../../libp2p", features = [ "tokio", "dns", "kad", "noise", "tcp", "websocket", "yamux", "rsa"] } + +[lints] +workspace = true diff --git a/examples/ipfs-kad/README.md b/examples/ipfs-kad/README.md index 771e0d9ea14f..ccefb6b1d9fd 100644 --- a/examples/ipfs-kad/README.md +++ b/examples/ipfs-kad/README.md @@ -1,31 +1,37 @@ ## Description This example showcases the usage of **libp2p** to interact with the Kademlia protocol on the IPFS network. -The code demonstrates how to perform Kademlia queries to find the closest peers to a specific peer ID. -By running this example, users can gain a better understanding of how the Kademlia protocol operates and performs queries on the IPFS network. +The code demonstrates how to: + - perform Kademlia queries to find the closest peers to a specific peer ID + - insert PK records into the Kademlia DHT + +By running this example, users can gain a better understanding of how the Kademlia protocol operates and performs operations on the IPFS network. ## Usage The example code demonstrates how to perform Kademlia queries on the IPFS network using the Rust P2P Library. + +### Getting closes peers + By specifying a peer ID as a parameter, the code will search for the closest peers to the given peer ID. -### Parameters +#### Parameters Run the example code: ```sh -cargo run [PEER_ID] +cargo run -- get-peers [PEER_ID] ``` Replace `[PEER_ID]` with the base58-encoded peer ID you want to search for. If no peer ID is provided, a random peer ID will be generated. -## Example Output +#### Example Output Upon running the example code, you will see the output in the console. The output will display the result of the Kademlia query, including the closest peers to the specified peer ID. -### Successful Query Output +#### Successful Query Output If the Kademlia query successfully finds closest peers, the output will be: @@ -34,7 +40,7 @@ Searching for the closest peers to [PEER_ID] Query finished with closest peers: [peer1, peer2, peer3] ``` -### Failed Query Output +#### Failed Query Output If the Kademlia query times out or there are no reachable peers, the output will indicate the failure: @@ -43,8 +49,43 @@ Searching for the closest peers to [PEER_ID] Query finished with no closest peers. ``` +### Inserting PK records into the DHT + +By specifying `put-pk-record` as a subcommand, the code will insert the generated public key as a PK record into the DHT. + +#### Parameters + +Run the example code: + +```sh +cargo run -- put-pk-record +``` + +#### Example Output + +Upon running the example code, you will see the output in the console. +The output will display the result of the Kademlia operation. + +#### Successful Operation Output + +If the Kademlia query successfully finds closest peers, the output will be: + +```sh +Putting PK record into the DHT +Successfully inserted the PK record +``` + +#### Failed Query Output + +If the Kademlia operation times out or there are no reachable peers, the output will indicate the failure: + +```sh +Putting PK record into the DHT +Failed to insert the PK record +``` + ## Conclusion In conclusion, this example provides a practical demonstration of using the Rust P2P Library to interact with the Kademlia protocol on the IPFS network. -By examining the code and running the example, users can gain insights into the inner workings of Kademlia and how it performs queries to find the closest peers. +By examining the code and running the example, users can gain insights into the inner workings of Kademlia and how it performs various basic actions like getting the closes peers or inserting records into the DHT. This knowledge can be valuable when developing peer-to-peer applications or understanding decentralized networks. diff --git a/examples/ipfs-kad/src/main.rs b/examples/ipfs-kad/src/main.rs index 6897cf63d4e4..f912bd0565af 100644 --- a/examples/ipfs-kad/src/main.rs +++ b/examples/ipfs-kad/src/main.rs @@ -20,15 +20,19 @@ #![doc = include_str!("../README.md")] +use std::num::NonZeroUsize; +use std::ops::Add; +use std::time::{Duration, Instant}; + +use anyhow::{bail, Result}; +use clap::Parser; use futures::StreamExt; -use libp2p::kad; -use libp2p::kad::record::store::MemoryStore; use libp2p::{ - development_transport, identity, + bytes::BufMut, + identity, kad, swarm::{SwarmBuilder, SwarmEvent}, - PeerId, + tokio_development_transport, PeerId, }; -use std::{env, error::Error, time::Duration}; const BOOTNODES: [&str; 4] = [ "QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", @@ -37,8 +41,8 @@ const BOOTNODES: [&str; 4] = [ "QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", ]; -#[async_std::main] -async fn main() -> Result<(), Box> { +#[tokio::main] +async fn main() -> Result<()> { env_logger::init(); // Create a random key for ourselves. @@ -46,14 +50,14 @@ async fn main() -> Result<(), Box> { let local_peer_id = PeerId::from(local_key.public()); // Set up a an encrypted DNS-enabled TCP Transport over the yamux protocol - let transport = development_transport(local_key).await?; + let transport = tokio_development_transport(local_key.clone())?; // Create a swarm to manage peers and events. let mut swarm = { // Create a Kademlia behaviour. let mut cfg = kad::Config::default(); cfg.set_query_timeout(Duration::from_secs(5 * 60)); - let store = MemoryStore::new(local_peer_id); + let store = kad::store::MemoryStore::new(local_peer_id); let mut behaviour = kad::Behaviour::with_config(local_peer_id, store, cfg); // Add the bootnodes to the local routing table. `libp2p-dns` built @@ -63,50 +67,93 @@ async fn main() -> Result<(), Box> { behaviour.add_address(&peer.parse()?, "/dnsaddr/bootstrap.libp2p.io".parse()?); } - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build() + SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id).build() }; - // Order Kademlia to search for a peer. - let to_search = env::args() - .nth(1) - .map(|p| p.parse()) - .transpose()? - .unwrap_or_else(PeerId::random); + let cli_opt = Opt::parse(); + + match cli_opt.argument { + CliArgument::GetPeers { peer_id } => { + let peer_id = peer_id.unwrap_or(PeerId::random()); + println!("Searching for the closest peers to {peer_id}"); + swarm.behaviour_mut().get_closest_peers(peer_id); + } + CliArgument::PutPkRecord {} => { + println!("Putting PK record into the DHT"); + + let mut pk_record_key = vec![]; + pk_record_key.put_slice("/pk/".as_bytes()); + pk_record_key.put_slice(local_peer_id.to_bytes().as_slice()); - println!("Searching for the closest peers to {to_search}"); - swarm.behaviour_mut().get_closest_peers(to_search); + let mut pk_record = + kad::Record::new(pk_record_key, local_key.public().encode_protobuf()); + pk_record.publisher = Some(local_peer_id); + pk_record.expires = Some(Instant::now().add(Duration::from_secs(60))); + + swarm + .behaviour_mut() + .put_record(pk_record, kad::Quorum::N(NonZeroUsize::new(3).unwrap()))?; + } + } loop { let event = swarm.select_next_some().await; - if let SwarmEvent::Behaviour(kad::Event::OutboundQueryProgressed { - result: kad::QueryResult::GetClosestPeers(result), - .. - }) = event - { - match result { - Ok(ok) => { - if !ok.peers.is_empty() { - println!("Query finished with closest peers: {:#?}", ok.peers) - } else { - // The example is considered failed as there - // should always be at least 1 reachable peer. - println!("Query finished with no closest peers.") - } - } - Err(kad::GetClosestPeersError::Timeout { peers, .. }) => { - if !peers.is_empty() { - println!("Query timed out with closest peers: {peers:#?}") - } else { - // The example is considered failed as there - // should always be at least 1 reachable peer. - println!("Query timed out with no closest peers."); - } + + match event { + SwarmEvent::Behaviour(kad::Event::OutboundQueryProgressed { + result: kad::QueryResult::GetClosestPeers(Ok(ok)), + .. + }) => { + // The example is considered failed as there + // should always be at least 1 reachable peer. + if ok.peers.is_empty() { + bail!("Query finished with no closest peers.") } - }; - break; + println!("Query finished with closest peers: {:#?}", ok.peers); + + return Ok(()); + } + SwarmEvent::Behaviour(kad::Event::OutboundQueryProgressed { + result: + kad::QueryResult::GetClosestPeers(Err(kad::GetClosestPeersError::Timeout { + .. + })), + .. + }) => { + bail!("Query for closest peers timed out") + } + SwarmEvent::Behaviour(kad::Event::OutboundQueryProgressed { + result: kad::QueryResult::PutRecord(Ok(_)), + .. + }) => { + println!("Successfully inserted the PK record"); + + return Ok(()); + } + SwarmEvent::Behaviour(kad::Event::OutboundQueryProgressed { + result: kad::QueryResult::PutRecord(Err(err)), + .. + }) => { + bail!(anyhow::Error::new(err).context("Failed to insert the PK record")); + } + _ => {} } } +} + +#[derive(Parser, Debug)] +#[clap(name = "libp2p Kademlia DHT example")] +struct Opt { + #[clap(subcommand)] + argument: CliArgument, +} - Ok(()) +#[derive(Debug, Parser)] +enum CliArgument { + GetPeers { + #[clap(long)] + peer_id: Option, + }, + PutPkRecord {}, } diff --git a/examples/ipfs-private/Cargo.toml b/examples/ipfs-private/Cargo.toml index 278611e6aa13..4bf501886dbf 100644 --- a/examples/ipfs-private/Cargo.toml +++ b/examples/ipfs-private/Cargo.toml @@ -6,9 +6,12 @@ publish = false license = "MIT" [dependencies] -async-std = { version = "1.12", features = ["attributes"] } +tokio = { version = "1.32", features = ["rt-multi-thread", "macros", "io-std"] } async-trait = "0.1" either = "1.9" env_logger = "0.10" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "gossipsub", "dns", "identify", "kad", "macros", "noise", "ping", "pnet", "tcp", "websocket", "yamux"] } +libp2p = { path = "../../libp2p", features = [ "tokio", "gossipsub", "dns", "identify", "kad", "macros", "noise", "ping", "pnet", "tcp", "websocket", "yamux"] } + +[lints] +workspace = true diff --git a/examples/ipfs-private/src/main.rs b/examples/ipfs-private/src/main.rs index 172131751d7d..fe83e891cfc6 100644 --- a/examples/ipfs-private/src/main.rs +++ b/examples/ipfs-private/src/main.rs @@ -20,9 +20,8 @@ #![doc = include_str!("../README.md")] -use async_std::io; use either::Either; -use futures::{prelude::*, select}; +use futures::prelude::*; use libp2p::{ core::{muxing::StreamMuxerBox, transport, transport::upgrade::Version}, gossipsub, identify, identity, @@ -33,6 +32,7 @@ use libp2p::{ tcp, yamux, Multiaddr, PeerId, Transport, }; use std::{env, error::Error, fs, path::Path, str::FromStr, time::Duration}; +use tokio::{io, io::AsyncBufReadExt, select}; /// Builds the transport that serves as a common ground for all connections. pub fn build_transport( @@ -42,7 +42,7 @@ pub fn build_transport( let noise_config = noise::Config::new(&key_pair).unwrap(); let yamux_config = yamux::Config::default(); - let base_transport = tcp::async_io::Transport::new(tcp::Config::default().nodelay(true)); + let base_transport = tcp::tokio::Transport::new(tcp::Config::default().nodelay(true)); let maybe_encrypted = match psk { Some(psk) => Either::Left( base_transport.and_then(move |socket, _| PnetConfig::new(psk).handshake(socket)), @@ -108,7 +108,7 @@ fn parse_legacy_multiaddr(text: &str) -> Result> { Ok(res) } -#[async_std::main] +#[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); @@ -186,7 +186,7 @@ async fn main() -> Result<(), Box> { println!("Subscribing to {gossipsub_topic:?}"); behaviour.gossipsub.subscribe(&gossipsub_topic).unwrap(); - SwarmBuilder::with_async_std_executor(transport, behaviour, local_peer_id).build() + SwarmBuilder::with_tokio_executor(transport, behaviour, local_peer_id).build() }; // Reach out to other nodes if specified @@ -197,7 +197,7 @@ async fn main() -> Result<(), Box> { } // Read full lines from stdin - let mut stdin = io::BufReader::new(io::stdin()).lines().fuse(); + let mut stdin = io::BufReader::new(io::stdin()).lines(); // Listen on all interfaces and whatever port the OS assigns swarm.listen_on("/ip4/0.0.0.0/tcp/0".parse()?)?; @@ -205,11 +205,11 @@ async fn main() -> Result<(), Box> { // Kick it off loop { select! { - line = stdin.select_next_some() => { + Ok(Some(line)) = stdin.next_line() => { if let Err(e) = swarm .behaviour_mut() .gossipsub - .publish(gossipsub_topic.clone(), line.expect("Stdin not to close").as_bytes()) + .publish(gossipsub_topic.clone(), line.as_bytes()) { println!("Publish error: {e:?}"); } diff --git a/examples/metrics/Cargo.toml b/examples/metrics/Cargo.toml index b81c0142fd9e..8cf7e1fc4068 100644 --- a/examples/metrics/Cargo.toml +++ b/examples/metrics/Cargo.toml @@ -13,3 +13,6 @@ libp2p = { path = "../../libp2p", features = ["async-std", "metrics", "ping", "n log = "0.4.20" tokio = { version = "1", features = ["rt-multi-thread"] } prometheus-client = "0.21.2" + +[lints] +workspace = true diff --git a/examples/ping/Cargo.toml b/examples/ping/Cargo.toml index 33c9e56b45c9..b39df505b4ac 100644 --- a/examples/ping/Cargo.toml +++ b/examples/ping/Cargo.toml @@ -6,8 +6,10 @@ publish = false license = "MIT" [dependencies] -async-std = { version = "1.12", features = ["attributes"] } -async-trait = "0.1" env_logger = "0.10.0" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "dns", "macros", "noise", "ping", "tcp", "websocket", "yamux"] } +libp2p = { path = "../../libp2p", features = ["noise", "ping", "tcp", "tokio", "yamux"] } +tokio = { version = "1.32.0", features = ["full"] } + +[lints] +workspace = true diff --git a/examples/ping/src/main.rs b/examples/ping/src/main.rs index 898a25813e05..25939a132c1b 100644 --- a/examples/ping/src/main.rs +++ b/examples/ping/src/main.rs @@ -30,20 +30,20 @@ use libp2p::{ use std::error::Error; use std::time::Duration; -#[async_std::main] +#[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); let local_key = identity::Keypair::generate_ed25519(); let local_peer_id = PeerId::from(local_key.public()); - let transport = tcp::async_io::Transport::default() + let transport = tcp::tokio::Transport::default() .upgrade(Version::V1Lazy) .authenticate(noise::Config::new(&local_key)?) .multiplex(yamux::Config::default()) .boxed(); let mut swarm = - SwarmBuilder::with_async_std_executor(transport, ping::Behaviour::default(), local_peer_id) + SwarmBuilder::with_tokio_executor(transport, ping::Behaviour::default(), local_peer_id) .idle_connection_timeout(Duration::from_secs(60)) // For illustrative purposes, keep idle connections alive for a minute so we can observe a few pings. .build(); diff --git a/examples/relay-server/Cargo.toml b/examples/relay-server/Cargo.toml index 49c32cd3b504..39d899f5573d 100644 --- a/examples/relay-server/Cargo.toml +++ b/examples/relay-server/Cargo.toml @@ -11,4 +11,7 @@ async-std = { version = "1.12", features = ["attributes"] } async-trait = "0.1" env_logger = "0.10.0" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "noise", "macros", "ping", "tcp", "identify", "yamux", "relay", "quic"] } +libp2p = { path = "../../libp2p", features = [ "async-std", "noise", "macros", "ping", "tcp", "identify", "yamux", "relay", "quic"] } + +[lints] +workspace = true diff --git a/examples/rendezvous/Cargo.toml b/examples/rendezvous/Cargo.toml index a66c758e0180..e98f465bc3bd 100644 --- a/examples/rendezvous/Cargo.toml +++ b/examples/rendezvous/Cargo.toml @@ -10,6 +10,9 @@ async-std = { version = "1.12", features = ["attributes"] } async-trait = "0.1" env_logger = "0.10.0" futures = "0.3.28" -libp2p = { path = "../../libp2p", features = ["async-std", "identify", "macros", "noise", "ping", "rendezvous", "tcp", "tokio", "yamux"] } +libp2p = { path = "../../libp2p", features = [ "async-std", "identify", "macros", "noise", "ping", "rendezvous", "tcp", "tokio", "yamux"] } log = "0.4" -tokio = { version = "1.32", features = [ "rt-multi-thread", "macros", "time" ] } +tokio = { version = "1.32", features = ["rt-multi-thread", "macros", "time"] } + +[lints] +workspace = true diff --git a/examples/upnp/Cargo.toml b/examples/upnp/Cargo.toml index afb8f61d2a2f..74e88bf82bd6 100644 --- a/examples/upnp/Cargo.toml +++ b/examples/upnp/Cargo.toml @@ -6,6 +6,9 @@ publish = false license = "MIT" [dependencies] -tokio = { version = "1", features = [ "rt-multi-thread", "macros"] } +tokio = { version = "1", features = ["rt-multi-thread", "macros"] } futures = "0.3.28" libp2p = { path = "../../libp2p", features = ["tokio", "dns", "macros", "noise", "ping", "tcp", "websocket", "yamux", "upnp"] } + +[lints] +workspace = true diff --git a/identity/CHANGELOG.md b/identity/CHANGELOG.md index b52f001827fa..27873e88e016 100644 --- a/identity/CHANGELOG.md +++ b/identity/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.2.5 + +- Fix usage of HKDF within `Keypair::derive_secret`. + See [PR 4554](https://github.com/libp2p/rust-libp2p/pull/4554). + +## 0.2.4 + +- Implement `Keypair::derive_secret`, to deterministically derive a new secret from the embedded secret key. + See [PR 4554]. + +[PR 4554]: https://github.com/libp2p/rust-libp2p/pull/4554 + ## 0.2.3 - Fix [RUSTSEC-2022-0093] by updating `ed25519-dalek` to `2.0`. diff --git a/identity/Cargo.toml b/identity/Cargo.toml index d8f4d9ef3cec..69f8bf55f02a 100644 --- a/identity/Cargo.toml +++ b/identity/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libp2p-identity" -version = "0.2.3" +version = "0.2.5" edition = "2021" description = "Data structures and algorithms for identifying peers in libp2p." rust-version = { workspace = true } @@ -15,28 +15,29 @@ categories = ["cryptography"] asn1_der = { version = "0.7.6", optional = true } bs58 = { version = "0.5.0", optional = true } ed25519-dalek = { version = "2.0", optional = true, features = ["rand_core"] } +hkdf = { version = "0.12.3", optional = true } libsecp256k1 = { version = "0.7.0", optional = true } log = "0.4" multihash = { version = "0.19.1", optional = true } -p256 = { version = "0.13", default-features = false, features = ["ecdsa", "std", "pem"], optional = true } +p256 = { version = "0.13", default-features = false, features = [ "ecdsa", "std", "pem"], optional = true } quick-protobuf = "0.8.1" rand = { version = "0.8", optional = true } sec1 = { version = "0.7", default-features = false, optional = true } serde = { version = "1", optional = true, features = ["derive"] } -sha2 = { version = "0.10.7", optional = true } +sha2 = { version = "0.10.8", optional = true } thiserror = { version = "1.0", optional = true } void = { version = "1.0", optional = true } zeroize = { version = "1.6", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -ring = { version = "0.16.9", features = ["alloc", "std"], default-features = false, optional = true} +ring = { version = "0.16.9", features = [ "alloc", "std"], default-features = false, optional = true } [features] -secp256k1 = [ "dep:libsecp256k1", "dep:asn1_der", "dep:rand", "dep:sha2", "dep:zeroize" ] -ecdsa = [ "dep:p256", "dep:rand", "dep:void", "dep:zeroize", "dep:sec1" ] -rsa = [ "dep:ring", "dep:asn1_der", "dep:rand", "dep:zeroize" ] -ed25519 = [ "dep:ed25519-dalek", "dep:rand", "dep:zeroize" ] -peerid = [ "dep:multihash", "dep:bs58", "dep:rand", "dep:thiserror", "dep:sha2" ] +secp256k1 = ["dep:libsecp256k1", "dep:asn1_der", "dep:rand", "dep:sha2", "dep:hkdf", "dep:zeroize"] +ecdsa = ["dep:p256", "dep:rand", "dep:void", "dep:zeroize", "dep:sec1", "dep:sha2", "dep:hkdf"] +rsa = ["dep:ring", "dep:asn1_der", "dep:rand", "dep:zeroize"] +ed25519 = ["dep:ed25519-dalek", "dep:rand", "dep:zeroize", "dep:sha2", "dep:hkdf"] +peerid = ["dep:multihash", "dep:bs58", "dep:rand", "dep:thiserror", "dep:sha2", "dep:hkdf" ] [dev-dependencies] quickcheck = { workspace = true } @@ -56,3 +57,6 @@ harness = false all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/identity/src/ed25519.rs b/identity/src/ed25519.rs index 06708ce63711..8b6b9e0d1e0b 100644 --- a/identity/src/ed25519.rs +++ b/identity/src/ed25519.rs @@ -197,6 +197,10 @@ impl SecretKey { sk_bytes.zeroize(); Ok(SecretKey(secret)) } + + pub(crate) fn to_bytes(&self) -> [u8; 32] { + self.0 + } } #[cfg(test)] diff --git a/identity/src/keypair.rs b/identity/src/keypair.rs index ac6edec89369..198296fa4fad 100644 --- a/identity/src/keypair.rs +++ b/identity/src/keypair.rs @@ -342,6 +342,69 @@ impl Keypair { KeyPairInner::Ecdsa(_) => KeyType::Ecdsa, } } + + /// Deterministically derive a new secret from this [`Keypair`], taking into account the provided domain. + /// + /// This works for all key types except RSA where it returns `None`. + /// + /// # Example + /// + /// ``` + /// # fn main() { + /// # use libp2p_identity as identity; + /// + /// let key = identity::Keypair::generate_ed25519(); + /// + /// let new_key = key.derive_secret(b"my encryption key").expect("can derive secret for ed25519"); + /// # } + /// ``` + /// + #[cfg(any( + feature = "ecdsa", + feature = "secp256k1", + feature = "ed25519", + feature = "rsa" + ))] + pub fn derive_secret(&self, domain: &[u8]) -> Option<[u8; 32]> { + let mut okm = [0u8; 32]; + hkdf::Hkdf::::new(None, &self.secret()?) + .expand(domain, &mut okm) + .expect("okm.len() == 32"); + + Some(okm) + } + + // We build docs with all features so this doesn't need to have any docs. + #[cfg(not(any( + feature = "ecdsa", + feature = "secp256k1", + feature = "ed25519", + feature = "rsa" + )))] + pub fn derive_secret(&self, _: &[u8]) -> Option<[u8; 32]> { + None + } + + /// Return the secret key of the [`Keypair`]. + #[allow(dead_code)] + pub(crate) fn secret(&self) -> Option<[u8; 32]> { + match self.keypair { + #[cfg(feature = "ed25519")] + KeyPairInner::Ed25519(ref inner) => Some(inner.secret().to_bytes()), + #[cfg(all(feature = "rsa", not(target_arch = "wasm32")))] + KeyPairInner::Rsa(_) => None, + #[cfg(feature = "secp256k1")] + KeyPairInner::Secp256k1(ref inner) => Some(inner.secret().to_bytes()), + #[cfg(feature = "ecdsa")] + KeyPairInner::Ecdsa(ref inner) => Some( + inner + .secret() + .to_bytes() + .try_into() + .expect("Ecdsa's private key should be 32 bytes"), + ), + } + } } #[cfg(feature = "ecdsa")] @@ -901,4 +964,11 @@ mod tests { assert_eq!(converted_pubkey, pubkey); assert_eq!(converted_pubkey.key_type(), KeyType::Ecdsa) } + + #[test] + #[cfg(feature = "ecdsa")] + fn test_secret_from_ecdsa_private_key() { + let keypair = Keypair::generate_ecdsa(); + assert!(keypair.derive_secret(b"domain separator!").is_some()) + } } diff --git a/identity/tests/keypair_api.rs b/identity/tests/keypair_api.rs index c1102278a63b..862abda6ec80 100644 --- a/identity/tests/keypair_api.rs +++ b/identity/tests/keypair_api.rs @@ -10,4 +10,5 @@ fn using_keypair(kp: Keypair) { let _ = kp.to_protobuf_encoding(); let _ = kp.sign(&[]); let _ = kp.public(); + let _: Option<[u8; 32]> = kp.derive_secret(b"foobar"); } diff --git a/interop-tests/Cargo.toml b/interop-tests/Cargo.toml index 1966aee414df..ac046da69cdf 100644 --- a/interop-tests/Cargo.toml +++ b/interop-tests/Cargo.toml @@ -19,11 +19,13 @@ rand = "0.8.5" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] axum = "0.6" -libp2p = { path = "../libp2p", features = ["ping", "noise", "tls", "rsa", "macros", "websocket", "tokio", "yamux", "tcp", "dns", "identify", "quic"] } +libp2p = { path = "../libp2p", features = [ "ping", "noise", "tls", "rsa", "macros", "websocket", "tokio", "yamux", "tcp", "dns", "identify", "quic"] } libp2p-webrtc = { workspace = true, features = ["tokio"] } libp2p-mplex = { path = "../muxers/mplex" } mime_guess = "2.0" -redis = { version = "0.23.3", default-features = false, features = ["tokio-comp"] } +redis = { version = "0.23.3", default-features = false, features = [ + "tokio-comp", +] } rust-embed = "8.0" serde_json = "1" thirtyfour = "=0.32.0-rc.8" # https://github.com/stevepryde/thirtyfour/issues/169 @@ -33,7 +35,7 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -libp2p = { path = "../libp2p", features = ["ping", "macros", "webtransport-websys", "wasm-bindgen", "identify"] } +libp2p = { path = "../libp2p", features = [ "ping", "macros", "webtransport-websys", "wasm-bindgen", "identify"] } libp2p-webrtc-websys = { workspace = true } wasm-bindgen = { version = "0.2" } wasm-bindgen-futures = { version = "0.4" } @@ -42,3 +44,6 @@ instant = "0.1.12" reqwest = { version = "0.11", features = ["json"] } console_error_panic_hook = { version = "0.1.7" } futures-timer = "3.0.2" + +[lints] +workspace = true diff --git a/interop-tests/Dockerfile.chromium b/interop-tests/Dockerfile.chromium index 33e0a0bf6378..ab720c4d3175 100644 --- a/interop-tests/Dockerfile.chromium +++ b/interop-tests/Dockerfile.chromium @@ -1,28 +1,26 @@ -FROM rust:1.67.0 as builder - -# Run with access to the target cache to speed up builds -WORKDIR /workspace -ADD . . - +# syntax=docker/dockerfile:1.5-labs +FROM rust:1.67.0 as chef RUN rustup target add wasm32-unknown-unknown - RUN wget -q -O- https://github.com/rustwasm/wasm-pack/releases/download/v0.12.1/wasm-pack-v0.12.1-x86_64-unknown-linux-musl.tar.gz | tar -zx -C /usr/local/bin --strip-components 1 --wildcards "wasm-pack-*/wasm-pack" RUN wget -q -O- https://github.com/WebAssembly/binaryen/releases/download/version_115/binaryen-version_115-x86_64-linux.tar.gz | tar -zx -C /usr/local/bin --strip-components 2 --wildcards "binaryen-version_*/bin/wasm-opt" - -RUN --mount=type=cache,target=./target \ - --mount=type=cache,target=/usr/local/cargo/registry \ - wasm-pack build --target web interop-tests - -RUN --mount=type=cache,target=./target \ - --mount=type=cache,target=/usr/local/cargo/registry \ - cargo build --release --package interop-tests --bin wasm_ping - -RUN --mount=type=cache,target=./target \ - mv ./target/release/wasm_ping /usr/local/bin/testplan +RUN wget -q -O- https://github.com/LukeMathWalker/cargo-chef/releases/download/v0.1.62/cargo-chef-x86_64-unknown-linux-gnu.tar.gz | tar -zx -C /usr/local/bin +WORKDIR /app + +FROM chef AS planner +COPY . . +RUN cargo chef prepare --recipe-path recipe.json + +FROM chef AS builder +COPY --from=planner /app/recipe.json recipe.json +# Build dependencies - this is the caching Docker layer! +RUN cargo chef cook --release --package interop-tests --target wasm32-unknown-unknown --recipe-path recipe.json +RUN cargo chef cook --release --package interop-tests --bin wasm_ping --recipe-path recipe.json +# Build application +COPY . . +RUN wasm-pack build --target web interop-tests +RUN cargo build --release --package interop-tests --bin wasm_ping FROM selenium/standalone-chrome:115.0 -COPY --from=builder /usr/local/bin/testplan /usr/local/bin/testplan - +COPY --from=builder /app/target/release/wasm_ping /usr/local/bin/testplan ENV RUST_BACKTRACE=1 - ENTRYPOINT ["testplan"] diff --git a/interop-tests/Dockerfile.native b/interop-tests/Dockerfile.native index f78b85e424c7..df5eb9a1240c 100644 --- a/interop-tests/Dockerfile.native +++ b/interop-tests/Dockerfile.native @@ -1,17 +1,21 @@ # syntax=docker/dockerfile:1.5-labs -FROM rust:1.67.0 as builder +FROM rust:1.67.0 as chef +RUN wget -q -O- https://github.com/LukeMathWalker/cargo-chef/releases/download/v0.1.62/cargo-chef-x86_64-unknown-linux-gnu.tar.gz | tar -zx -C /usr/local/bin +WORKDIR /app -# Run with access to the target cache to speed up builds -WORKDIR /workspace -ADD . . -RUN --mount=type=cache,target=./target \ - --mount=type=cache,target=/usr/local/cargo/registry \ - cargo build --release --package interop-tests --bin native_ping +FROM chef AS planner +COPY . . +RUN cargo chef prepare --recipe-path recipe.json -RUN --mount=type=cache,target=./target \ - mv ./target/release/native_ping /usr/local/bin/testplan +FROM chef AS builder +COPY --from=planner /app/recipe.json recipe.json +# Build dependencies - this is the caching Docker layer! +RUN cargo chef cook --release --package interop-tests --bin native_ping --recipe-path recipe.json +# Build application +COPY . . +RUN cargo build --release --package interop-tests --bin native_ping FROM gcr.io/distroless/cc -COPY --from=builder /usr/local/bin/testplan /usr/local/bin/testplan +COPY --from=builder /app/target/release/native_ping /usr/local/bin/testplan ENV RUST_BACKTRACE=1 ENTRYPOINT ["testplan"] diff --git a/libp2p/Cargo.toml b/libp2p/Cargo.toml index 6b11d7deec46..1264a0505618 100644 --- a/libp2p/Cargo.toml +++ b/libp2p/Cargo.toml @@ -50,10 +50,10 @@ full = [ "websocket", "webtransport-websys", "yamux", - "upnp" + "upnp", ] -async-std = ["libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std", "libp2p-quic?/async-std"] +async-std = [ "libp2p-swarm/async-std", "libp2p-mdns?/async-io", "libp2p-tcp?/async-io", "libp2p-dns?/async-std", "libp2p-quic?/async-std",] autonat = ["dep:libp2p-autonat"] cbor = ["libp2p-request-response?/cbor"] dcutr = ["dep:libp2p-dcutr", "libp2p-metrics?/dcutr"] @@ -83,9 +83,9 @@ secp256k1 = ["libp2p-identity/secp256k1"] serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] tcp = ["dep:libp2p-tcp"] tls = ["dep:libp2p-tls"] -tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-quic?/tokio", "libp2p-upnp?/tokio"] +tokio = [ "libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-quic?/tokio", "libp2p-upnp?/tokio"] uds = ["dep:libp2p-uds"] -wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen", "libp2p-gossipsub?/wasm-bindgen"] +wasm-bindgen = [ "futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen", "libp2p-gossipsub?/wasm-bindgen",] wasm-ext = ["dep:libp2p-wasm-ext"] wasm-ext-websocket = ["wasm-ext", "libp2p-wasm-ext?/websocket"] websocket = ["dep:libp2p-websocket"] @@ -97,8 +97,8 @@ upnp = ["dep:libp2p-upnp"] bytes = "1" futures = "0.3.26" futures-timer = "3.0.2" # Explicit dependency to be used in `wasm-bindgen` feature -getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature -instant = "0.1.12" # Explicit dependency to be used in `wasm-bindgen` feature +getrandom = "0.2.3" # Explicit dependency to be used in `wasm-bindgen` feature +instant = "0.1.12" # Explicit dependency to be used in `wasm-bindgen` feature libp2p-allow-block-list = { workspace = true } libp2p-autonat = { workspace = true, optional = true } @@ -144,7 +144,7 @@ async-trait = "0.1" either = "1.8.0" env_logger = "0.10.0" clap = { version = "4.1.6", features = ["derive"] } -tokio = { version = "1.15", features = ["io-util", "io-std", "macros", "rt", "rt-multi-thread"] } +tokio = { version = "1.15", features = [ "io-util", "io-std", "macros", "rt", "rt-multi-thread"] } libp2p-noise = { workspace = true } libp2p-tcp = { workspace = true, features = ["tokio"] } @@ -155,3 +155,6 @@ libp2p-tcp = { workspace = true, features = ["tokio"] } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/libp2p/src/lib.rs b/libp2p/src/lib.rs index d1e151cc3c9d..e3934e6bc349 100644 --- a/libp2p/src/lib.rs +++ b/libp2p/src/lib.rs @@ -20,12 +20,10 @@ //! libp2p is a modular peer-to-peer networking framework. //! -//! To learn more about the general libp2p multi-language framework visit -//! [libp2p.io](https://libp2p.io/). +//! To learn more about the general libp2p multi-language framework visit . //! -//! To get started with this libp2p implementation in Rust, please take a look -//! at the [`tutorials`](crate::tutorials). Further examples can be found in the -//! [examples] directory. +//! To get started with this libp2p implementation in Rust, please take a look at the [`tutorials`]. +//! Further examples can be found in the [examples] directory. //! //! [examples]: https://github.com/libp2p/rust-libp2p/tree/master/examples diff --git a/misc/allow-block-list/Cargo.toml b/misc/allow-block-list/Cargo.toml index 42a6f6342721..84125f0c0a75 100644 --- a/misc/allow-block-list/Cargo.toml +++ b/misc/allow-block-list/Cargo.toml @@ -19,3 +19,6 @@ void = "1" async-std = { version = "1.12.0", features = ["attributes"] } libp2p-swarm-derive = { path = "../../swarm-derive" } libp2p-swarm-test = { path = "../../swarm-test" } + +[lints] +workspace = true diff --git a/misc/connection-limits/Cargo.toml b/misc/connection-limits/Cargo.toml index 25347e29b16d..1ba551470a00 100644 --- a/misc/connection-limits/Cargo.toml +++ b/misc/connection-limits/Cargo.toml @@ -23,3 +23,6 @@ libp2p-swarm-derive = { path = "../../swarm-derive" } libp2p-swarm-test = { path = "../../swarm-test" } quickcheck = { workspace = true } rand = "0.8.5" + +[lints] +workspace = true diff --git a/misc/connection-limits/src/lib.rs b/misc/connection-limits/src/lib.rs index 7de96cc17363..880904f7c170 100644 --- a/misc/connection-limits/src/lib.rs +++ b/misc/connection-limits/src/lib.rs @@ -37,7 +37,7 @@ use void::Void; /// If a connection is denied due to a limit, either a [`SwarmEvent::IncomingConnectionError`](libp2p_swarm::SwarmEvent::IncomingConnectionError) /// or [`SwarmEvent::OutgoingConnectionError`](libp2p_swarm::SwarmEvent::OutgoingConnectionError) will be emitted. /// The [`ListenError::Denied`](libp2p_swarm::ListenError::Denied) and respectively the [`DialError::Denied`](libp2p_swarm::DialError::Denied) variant -/// contain a [`ConnectionDenied`](libp2p_swarm::ConnectionDenied) type that can be downcast to [`Exceeded`] error if (and only if) **this** +/// contain a [`ConnectionDenied`] type that can be downcast to [`Exceeded`] error if (and only if) **this** /// behaviour denied the connection. /// /// If you employ multiple [`NetworkBehaviour`]s that manage connections, it may also be a different error. diff --git a/misc/futures-bounded/Cargo.toml b/misc/futures-bounded/Cargo.toml index fae7528ad9c6..4d70779e282d 100644 --- a/misc/futures-bounded/Cargo.toml +++ b/misc/futures-bounded/Cargo.toml @@ -18,3 +18,6 @@ futures-timer = "3.0.2" [dev-dependencies] tokio = { version = "1.29.1", features = ["macros", "rt"] } + +[lints] +workspace = true diff --git a/misc/keygen/Cargo.toml b/misc/keygen/Cargo.toml index b695915011db..da3e4a143958 100644 --- a/misc/keygen/Cargo.toml +++ b/misc/keygen/Cargo.toml @@ -17,3 +17,6 @@ serde_json = "1.0.107" libp2p-core = { workspace = true } base64 = "0.21.4" libp2p-identity = { workspace = true } + +[lints] +workspace = true diff --git a/misc/memory-connection-limits/Cargo.toml b/misc/memory-connection-limits/Cargo.toml index 6bfecfd2b0e5..eb65d26ac660 100644 --- a/misc/memory-connection-limits/Cargo.toml +++ b/misc/memory-connection-limits/Cargo.toml @@ -24,3 +24,6 @@ libp2p-identify = { workspace = true } libp2p-swarm-derive = { path = "../../swarm-derive" } libp2p-swarm-test = { path = "../../swarm-test" } rand = "0.8.5" + +[lints] +workspace = true diff --git a/misc/memory-connection-limits/src/lib.rs b/misc/memory-connection-limits/src/lib.rs index 33e40b11843e..36f0d1648d72 100644 --- a/misc/memory-connection-limits/src/lib.rs +++ b/misc/memory-connection-limits/src/lib.rs @@ -39,7 +39,7 @@ use std::{ /// If a connection is denied due to a limit, either a [`SwarmEvent::IncomingConnectionError`](libp2p_swarm::SwarmEvent::IncomingConnectionError) /// or [`SwarmEvent::OutgoingConnectionError`](libp2p_swarm::SwarmEvent::OutgoingConnectionError) will be emitted. /// The [`ListenError::Denied`](libp2p_swarm::ListenError::Denied) and respectively the [`DialError::Denied`](libp2p_swarm::DialError::Denied) variant -/// contain a [`ConnectionDenied`](libp2p_swarm::ConnectionDenied) type that can be downcast to [`MemoryUsageLimitExceeded`] error if (and only if) **this** +/// contain a [`ConnectionDenied`] type that can be downcast to [`MemoryUsageLimitExceeded`] error if (and only if) **this** /// behaviour denied the connection. /// /// If you employ multiple [`NetworkBehaviour`]s that manage connections, it may also be a different error. diff --git a/misc/metrics/Cargo.toml b/misc/metrics/Cargo.toml index 1ea026a92023..0cb9840955bc 100644 --- a/misc/metrics/Cargo.toml +++ b/misc/metrics/Cargo.toml @@ -38,3 +38,6 @@ prometheus-client = { version = "0.21.2"} all-features = true rustc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/misc/multistream-select/Cargo.toml b/misc/multistream-select/Cargo.toml index 8d19e3e5b5ce..6bd072070e79 100644 --- a/misc/multistream-select/Cargo.toml +++ b/misc/multistream-select/Cargo.toml @@ -32,3 +32,6 @@ rw-stream-sink = { workspace = true } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/misc/multistream-select/src/lib.rs b/misc/multistream-select/src/lib.rs index ec62023a861b..e85fae0f9777 100644 --- a/misc/multistream-select/src/lib.rs +++ b/misc/multistream-select/src/lib.rs @@ -40,13 +40,12 @@ //! echoing the same protocol) or reject (by responding with a message stating //! "not available"). If a suggested protocol is not available, the dialer may //! suggest another protocol. This process continues until a protocol is agreed upon, -//! yielding a [`Negotiated`](self::Negotiated) stream, or the dialer has run out of +//! yielding a [`Negotiated`] stream, or the dialer has run out of //! alternatives. //! -//! See [`dialer_select_proto`](self::dialer_select_proto) and -//! [`listener_select_proto`](self::listener_select_proto). +//! See [`dialer_select_proto`] and [`listener_select_proto`]. //! -//! ## [`Negotiated`](self::Negotiated) +//! ## [`Negotiated`] //! //! A `Negotiated` represents an I/O stream that has settled on a protocol //! to use. By default, with [`Version::V1`], protocol negotiation is always @@ -55,7 +54,7 @@ //! a variant [`Version::V1Lazy`] that permits 0-RTT negotiation if the //! dialer only supports a single protocol. In that case, when a dialer //! settles on a protocol to use, the [`DialerSelectFuture`] yields a -//! [`Negotiated`](self::Negotiated) I/O stream before the negotiation +//! [`Negotiated`] I/O stream before the negotiation //! data has been flushed. It is then expecting confirmation for that protocol //! as the first messages read from the stream. This behaviour allows the dialer //! to immediately send data relating to the negotiated protocol together with the @@ -63,8 +62,7 @@ //! multiple 0-RTT negotiations in sequence for different protocols layered on //! top of each other may trigger undesirable behaviour for a listener not //! supporting one of the intermediate protocols. See -//! [`dialer_select_proto`](self::dialer_select_proto) and the documentation -//! of [`Version::V1Lazy`] for further details. +//! [`dialer_select_proto`] and the documentation of [`Version::V1Lazy`] for further details. //! //! ## Examples //! diff --git a/misc/quick-protobuf-codec/Cargo.toml b/misc/quick-protobuf-codec/Cargo.toml index 37cdd07f2255..0f793d1f1851 100644 --- a/misc/quick-protobuf-codec/Cargo.toml +++ b/misc/quick-protobuf-codec/Cargo.toml @@ -23,3 +23,6 @@ quick-protobuf = "0.8" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/misc/quickcheck-ext/Cargo.toml b/misc/quickcheck-ext/Cargo.toml index 0c427dc4fc96..65e45e47ab8e 100644 --- a/misc/quickcheck-ext/Cargo.toml +++ b/misc/quickcheck-ext/Cargo.toml @@ -8,3 +8,6 @@ license = "Unlicense/MIT" [dependencies] quickcheck = "1" num-traits = "0.2" + +[lints] +workspace = true diff --git a/misc/rw-stream-sink/Cargo.toml b/misc/rw-stream-sink/Cargo.toml index b6d02c28201f..f1537e9e7ac7 100644 --- a/misc/rw-stream-sink/Cargo.toml +++ b/misc/rw-stream-sink/Cargo.toml @@ -24,3 +24,6 @@ async-std = "1.0" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/misc/server/Cargo.toml b/misc/server/Cargo.toml index aa259ce82148..e0d7af3a823a 100644 --- a/misc/server/Cargo.toml +++ b/misc/server/Cargo.toml @@ -25,3 +25,6 @@ serde_derive = "1.0.125" serde_json = "1.0" tokio = { version = "1", features = ["rt-multi-thread", "macros"] } zeroize = "1" + +[lints] +workspace = true diff --git a/misc/webrtc-utils/Cargo.toml b/misc/webrtc-utils/Cargo.toml index a3a5bef9ce22..4401ef9bc449 100644 --- a/misc/webrtc-utils/Cargo.toml +++ b/misc/webrtc-utils/Cargo.toml @@ -22,7 +22,7 @@ quick-protobuf = "0.8" quick-protobuf-codec = { workspace = true } rand = "0.8" serde = { version = "1.0", features = ["derive"] } -sha2 = "0.10.7" +sha2 = "0.10.8" thiserror = "1" tinytemplate = "1.2" asynchronous-codec = "0.6" @@ -30,3 +30,6 @@ asynchronous-codec = "0.6" [dev-dependencies] hex-literal = "0.4" unsigned-varint = { version = "0.7", features = ["asynchronous_codec"] } + +[lints] +workspace = true diff --git a/muxers/mplex/Cargo.toml b/muxers/mplex/Cargo.toml index 50a2d10571ec..aca3ec6eadf5 100644 --- a/muxers/mplex/Cargo.toml +++ b/muxers/mplex/Cargo.toml @@ -43,3 +43,6 @@ harness = false all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/muxers/test-harness/Cargo.toml b/muxers/test-harness/Cargo.toml index af73de33f8cb..5304509b9cc8 100644 --- a/muxers/test-harness/Cargo.toml +++ b/muxers/test-harness/Cargo.toml @@ -13,3 +13,6 @@ futures = "0.3.28" log = "0.4" futures-timer = "3.0.2" futures_ringbuf = "0.4.0" + +[lints] +workspace = true diff --git a/muxers/yamux/Cargo.toml b/muxers/yamux/Cargo.toml index 11b94ac97388..3073c040ff30 100644 --- a/muxers/yamux/Cargo.toml +++ b/muxers/yamux/Cargo.toml @@ -27,3 +27,6 @@ libp2p-muxer-test-harness = { path = "../test-harness" } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/autonat/Cargo.toml b/protocols/autonat/Cargo.toml index 4a8c9fe71d67..3b81d62b516b 100644 --- a/protocols/autonat/Cargo.toml +++ b/protocols/autonat/Cargo.toml @@ -34,3 +34,6 @@ libp2p-swarm-test = { path = "../../swarm-test" } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/dcutr/Cargo.toml b/protocols/dcutr/Cargo.toml index acade64cae89..f12684816c68 100644 --- a/protocols/dcutr/Cargo.toml +++ b/protocols/dcutr/Cargo.toml @@ -47,3 +47,6 @@ rand = "0.8" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/dcutr/src/behaviour_impl.rs b/protocols/dcutr/src/behaviour_impl.rs index 4993da655d33..748e163429db 100644 --- a/protocols/dcutr/src/behaviour_impl.rs +++ b/protocols/dcutr/src/behaviour_impl.rs @@ -103,8 +103,8 @@ impl Behaviour { fn observed_addresses(&self) -> Vec { self.external_addresses .iter() - .cloned() .filter(|a| !a.iter().any(|p| p == Protocol::P2pCircuit)) + .cloned() .map(|a| a.with(Protocol::P2p(self.local_peer_id))) .collect() } diff --git a/protocols/dcutr/tests/lib.rs b/protocols/dcutr/tests/lib.rs index a47f413f2685..162b4a5ec789 100644 --- a/protocols/dcutr/tests/lib.rs +++ b/protocols/dcutr/tests/lib.rs @@ -135,30 +135,12 @@ fn build_client() -> Swarm { } #[derive(NetworkBehaviour)] -#[behaviour(to_swarm = "ClientEvent", prelude = "libp2p_swarm::derive_prelude")] +#[behaviour(prelude = "libp2p_swarm::derive_prelude")] struct Client { relay: relay::client::Behaviour, dcutr: dcutr::Behaviour, } -#[derive(Debug)] -enum ClientEvent { - Relay(relay::client::Event), - Dcutr(dcutr::Event), -} - -impl From for ClientEvent { - fn from(event: relay::client::Event) -> Self { - ClientEvent::Relay(event) - } -} - -impl From for ClientEvent { - fn from(event: dcutr::Event) -> Self { - ClientEvent::Dcutr(event) - } -} - async fn wait_for_reservation( client: &mut Swarm, client_addr: Multiaddr, diff --git a/protocols/floodsub/Cargo.toml b/protocols/floodsub/Cargo.toml index 2484624da8e6..dfa9ad63bd2f 100644 --- a/protocols/floodsub/Cargo.toml +++ b/protocols/floodsub/Cargo.toml @@ -23,7 +23,7 @@ quick-protobuf = "0.8" quick-protobuf-codec = { workspace = true } rand = "0.8" smallvec = "1.11.1" -thiserror = "1.0.48" +thiserror = "1.0.49" # Passing arguments to the docsrs builder in order to properly document cfg's. # More information: https://docs.rs/about/builds#cross-compiling @@ -31,3 +31,6 @@ thiserror = "1.0.48" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/gossipsub/Cargo.toml b/protocols/gossipsub/Cargo.toml index e4ed4e565b81..684cc8786542 100644 --- a/protocols/gossipsub/Cargo.toml +++ b/protocols/gossipsub/Cargo.toml @@ -32,9 +32,9 @@ log = "0.4.20" quick-protobuf = "0.8" quick-protobuf-codec = { workspace = true } rand = "0.8" -regex = "1.9.5" +regex = "1.9.6" serde = { version = "1", optional = true, features = ["derive"] } -sha2 = "0.10.7" +sha2 = "0.10.8" smallvec = "1.11.1" unsigned-varint = { version = "0.7.2", features = ["asynchronous_codec"] } void = "1.0.2" @@ -58,3 +58,6 @@ quickcheck = { workspace = true } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/gossipsub/src/types.rs b/protocols/gossipsub/src/types.rs index 9c9cd3f97f17..f18656354541 100644 --- a/protocols/gossipsub/src/types.rs +++ b/protocols/gossipsub/src/types.rs @@ -330,7 +330,7 @@ impl From for proto::RPC { .into_iter() .map(|info| proto::PeerInfo { peer_id: info.peer_id.map(|id| id.to_bytes()), - /// TODO, see https://github.com/libp2p/specs/pull/217 + // TODO, see https://github.com/libp2p/specs/pull/217 signed_peer_record: None, }) .collect(), diff --git a/protocols/identify/Cargo.toml b/protocols/identify/Cargo.toml index 4b56e6c1237f..43421811c5dc 100644 --- a/protocols/identify/Cargo.toml +++ b/protocols/identify/Cargo.toml @@ -14,11 +14,12 @@ categories = ["network-programming", "asynchronous"] asynchronous-codec = "0.6" futures = "0.3.28" futures-timer = "3.0.2" +futures-bounded = { workspace = true } libp2p-core = { workspace = true } libp2p-swarm = { workspace = true } libp2p-identity = { workspace = true } log = "0.4.20" -lru = "0.11.1" +lru = "0.12.0" quick-protobuf-codec = { workspace = true } quick-protobuf = "0.8" smallvec = "1.11.1" @@ -38,3 +39,6 @@ libp2p-swarm = { workspace = true, features = ["macros"] } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/identify/src/handler.rs b/protocols/identify/src/handler.rs index 162a1e8fb069..50b9882f2c5d 100644 --- a/protocols/identify/src/handler.rs +++ b/protocols/identify/src/handler.rs @@ -18,14 +18,13 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -use crate::protocol::{Identify, InboundPush, OutboundPush, Push, UpgradeError}; -use crate::protocol::{Info, PushInfo}; +use crate::protocol::{Info, PushInfo, UpgradeError}; +use crate::{protocol, PROTOCOL_NAME, PUSH_PROTOCOL_NAME}; use either::Either; -use futures::future::BoxFuture; use futures::prelude::*; -use futures::stream::FuturesUnordered; +use futures_bounded::Timeout; use futures_timer::Delay; -use libp2p_core::upgrade::SelectUpgrade; +use libp2p_core::upgrade::{ReadyUpgrade, SelectUpgrade}; use libp2p_core::Multiaddr; use libp2p_identity::PeerId; use libp2p_identity::PublicKey; @@ -42,6 +41,9 @@ use smallvec::SmallVec; use std::collections::HashSet; use std::{io, task::Context, task::Poll, time::Duration}; +const STREAM_TIMEOUT: Duration = Duration::from_secs(60); +const MAX_CONCURRENT_STREAMS_PER_CONNECTION: usize = 10; + /// Protocol handler for sending and receiving identification requests. /// /// Outbound requests are sent periodically. The handler performs expects @@ -49,14 +51,17 @@ use std::{io, task::Context, task::Poll, time::Duration}; /// permitting the underlying connection to be closed. pub struct Handler { remote_peer_id: PeerId, - inbound_identify_push: Option>>, /// Pending events to yield. events: SmallVec< - [ConnectionHandlerEvent>, (), Event, io::Error>; 4], + [ConnectionHandlerEvent< + Either, ReadyUpgrade>, + (), + Event, + io::Error, + >; 4], >, - /// Pending identification replies, awaiting being sent. - pending_replies: FuturesUnordered>>, + active_streams: futures_bounded::FuturesSet>, /// Future that fires when we need to identify the node again. trigger_next_identify: Delay, @@ -125,9 +130,11 @@ impl Handler { ) -> Self { Self { remote_peer_id, - inbound_identify_push: Default::default(), events: SmallVec::new(), - pending_replies: FuturesUnordered::new(), + active_streams: futures_bounded::FuturesSet::new( + STREAM_TIMEOUT, + MAX_CONCURRENT_STREAMS_PER_CONNECTION, + ), trigger_next_identify: Delay::new(initial_delay), exchanged_one_periodic_identify: false, interval, @@ -152,19 +159,28 @@ impl Handler { >, ) { match output { - future::Either::Left(substream) => { + future::Either::Left(stream) => { let info = self.build_info(); - self.pending_replies - .push(crate::protocol::send(substream, info).boxed()); + if self + .active_streams + .try_push( + protocol::send_identify(stream, info).map_ok(|_| Success::SentIdentify), + ) + .is_err() + { + warn!("Dropping inbound stream because we are at capacity"); + } else { + self.exchanged_one_periodic_identify = true; + } } - future::Either::Right(fut) => { - if self.inbound_identify_push.replace(fut).is_some() { - warn!( - "New inbound identify push stream from {} while still \ - upgrading previous one. Replacing previous with new.", - self.remote_peer_id, - ); + future::Either::Right(stream) => { + if self + .active_streams + .try_push(protocol::recv_push(stream).map_ok(Success::ReceivedIdentifyPush)) + .is_err() + { + warn!("Dropping inbound identify push stream because we are at capacity"); } } } @@ -180,34 +196,31 @@ impl Handler { >, ) { match output { - future::Either::Left(remote_info) => { - self.handle_incoming_info(&remote_info); + future::Either::Left(stream) => { + if self + .active_streams + .try_push(protocol::recv_identify(stream).map_ok(Success::ReceivedIdentify)) + .is_err() + { + warn!("Dropping outbound identify stream because we are at capacity"); + } + } + future::Either::Right(stream) => { + let info = self.build_info(); - self.events - .push(ConnectionHandlerEvent::NotifyBehaviour(Event::Identified( - remote_info, - ))); + if self + .active_streams + .try_push( + protocol::send_identify(stream, info).map_ok(|_| Success::SentIdentifyPush), + ) + .is_err() + { + warn!("Dropping outbound identify push stream because we are at capacity"); + } } - future::Either::Right(()) => self.events.push(ConnectionHandlerEvent::NotifyBehaviour( - Event::IdentificationPushed, - )), } } - fn on_dial_upgrade_error( - &mut self, - DialUpgradeError { error: err, .. }: DialUpgradeError< - ::OutboundOpenInfo, - ::OutboundProtocol, - >, - ) { - let err = err.map_upgrade_err(|e| e.into_inner()); - self.events.push(ConnectionHandlerEvent::NotifyBehaviour( - Event::IdentificationError(err), - )); - self.trigger_next_identify.reset(self.interval); - } - fn build_info(&mut self) -> Info { Info { public_key: self.public_key.clone(), @@ -268,13 +281,20 @@ impl ConnectionHandler for Handler { type FromBehaviour = InEvent; type ToBehaviour = Event; type Error = io::Error; - type InboundProtocol = SelectUpgrade>; - type OutboundProtocol = Either>; + type InboundProtocol = + SelectUpgrade, ReadyUpgrade>; + type OutboundProtocol = Either, ReadyUpgrade>; type OutboundOpenInfo = (); type InboundOpenInfo = (); fn listen_protocol(&self) -> SubstreamProtocol { - SubstreamProtocol::new(SelectUpgrade::new(Identify, Push::inbound()), ()) + SubstreamProtocol::new( + SelectUpgrade::new( + ReadyUpgrade::new(PROTOCOL_NAME), + ReadyUpgrade::new(PUSH_PROTOCOL_NAME), + ), + (), + ) } fn on_behaviour_event(&mut self, event: Self::FromBehaviour) { @@ -283,21 +303,19 @@ impl ConnectionHandler for Handler { self.external_addresses = addresses; } InEvent::Push => { - let info = self.build_info(); self.events .push(ConnectionHandlerEvent::OutboundSubstreamRequest { - protocol: SubstreamProtocol::new(Either::Right(Push::outbound(info)), ()), + protocol: SubstreamProtocol::new( + Either::Right(ReadyUpgrade::new(PUSH_PROTOCOL_NAME)), + (), + ), }); } } } fn connection_keep_alive(&self) -> KeepAlive { - if self.inbound_identify_push.is_some() { - return KeepAlive::Yes; - } - - if !self.pending_replies.is_empty() { + if !self.active_streams.is_empty() { return KeepAlive::Yes; } @@ -317,20 +335,34 @@ impl ConnectionHandler for Handler { // Poll the future that fires when we need to identify the node again. if let Poll::Ready(()) = self.trigger_next_identify.poll_unpin(cx) { self.trigger_next_identify.reset(self.interval); - let ev = ConnectionHandlerEvent::OutboundSubstreamRequest { - protocol: SubstreamProtocol::new(Either::Left(Identify), ()), + let event = ConnectionHandlerEvent::OutboundSubstreamRequest { + protocol: SubstreamProtocol::new( + Either::Left(ReadyUpgrade::new(PROTOCOL_NAME)), + (), + ), }; - return Poll::Ready(ev); + return Poll::Ready(event); } - if let Some(Poll::Ready(res)) = self - .inbound_identify_push - .as_mut() - .map(|f| f.poll_unpin(cx)) - { - self.inbound_identify_push.take(); + match self.active_streams.poll_unpin(cx) { + Poll::Ready(Ok(Ok(Success::ReceivedIdentify(remote_info)))) => { + self.handle_incoming_info(&remote_info); - if let Ok(remote_push_info) = res { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(Event::Identified( + remote_info, + ))); + } + Poll::Ready(Ok(Ok(Success::SentIdentifyPush))) => { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + Event::IdentificationPushed, + )); + } + Poll::Ready(Ok(Ok(Success::SentIdentify))) => { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + Event::Identification, + )); + } + Poll::Ready(Ok(Ok(Success::ReceivedIdentifyPush(remote_push_info)))) => { if let Some(mut info) = self.remote_info.clone() { info.merge(remote_push_info); self.handle_incoming_info(&info); @@ -340,16 +372,17 @@ impl ConnectionHandler for Handler { )); }; } - } - - // Check for pending replies to send. - if let Poll::Ready(Some(result)) = self.pending_replies.poll_next_unpin(cx) { - let event = result - .map(|()| Event::Identification) - .unwrap_or_else(|err| Event::IdentificationError(StreamUpgradeError::Apply(err))); - self.exchanged_one_periodic_identify = true; - - return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour(event)); + Poll::Ready(Ok(Err(e))) => { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + Event::IdentificationError(StreamUpgradeError::Apply(e)), + )); + } + Poll::Ready(Err(Timeout { .. })) => { + return Poll::Ready(ConnectionHandlerEvent::NotifyBehaviour( + Event::IdentificationError(StreamUpgradeError::Timeout), + )); + } + Poll::Pending => {} } Poll::Pending @@ -371,8 +404,13 @@ impl ConnectionHandler for Handler { ConnectionEvent::FullyNegotiatedOutbound(fully_negotiated_outbound) => { self.on_fully_negotiated_outbound(fully_negotiated_outbound) } - ConnectionEvent::DialUpgradeError(dial_upgrade_error) => { - self.on_dial_upgrade_error(dial_upgrade_error) + ConnectionEvent::DialUpgradeError(DialUpgradeError { error, .. }) => { + self.events.push(ConnectionHandlerEvent::NotifyBehaviour( + Event::IdentificationError( + error.map_upgrade_err(|e| void::unreachable(e.into_inner())), + ), + )); + self.trigger_next_identify.reset(self.interval); } ConnectionEvent::AddressChange(_) | ConnectionEvent::ListenUpgradeError(_) @@ -392,11 +430,10 @@ impl ConnectionHandler for Handler { self.remote_peer_id ); - let info = self.build_info(); self.events .push(ConnectionHandlerEvent::OutboundSubstreamRequest { protocol: SubstreamProtocol::new( - Either::Right(Push::outbound(info)), + Either::Right(ReadyUpgrade::new(PUSH_PROTOCOL_NAME)), (), ), }); @@ -405,3 +442,10 @@ impl ConnectionHandler for Handler { } } } + +enum Success { + SentIdentify, + ReceivedIdentify(Info), + SentIdentifyPush, + ReceivedIdentifyPush(PushInfo), +} diff --git a/protocols/identify/src/protocol.rs b/protocols/identify/src/protocol.rs index 989c94a4d67c..5e2891e04e40 100644 --- a/protocols/identify/src/protocol.rs +++ b/protocols/identify/src/protocol.rs @@ -20,20 +20,15 @@ use crate::proto; use asynchronous_codec::{FramedRead, FramedWrite}; -use futures::{future::BoxFuture, prelude::*}; -use libp2p_core::{ - multiaddr, - upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}, - Multiaddr, -}; +use futures::prelude::*; +use libp2p_core::{multiaddr, Multiaddr}; use libp2p_identity as identity; use libp2p_identity::PublicKey; use libp2p_swarm::StreamProtocol; use log::{debug, trace}; use std::convert::TryFrom; -use std::{io, iter, pin::Pin}; +use std::io; use thiserror::Error; -use void::Void; const MAX_MESSAGE_SIZE_BYTES: usize = 4096; @@ -41,28 +36,6 @@ pub const PROTOCOL_NAME: StreamProtocol = StreamProtocol::new("/ipfs/id/1.0.0"); pub const PUSH_PROTOCOL_NAME: StreamProtocol = StreamProtocol::new("/ipfs/id/push/1.0.0"); -/// Substream upgrade protocol for `/ipfs/id/1.0.0`. -#[derive(Debug, Clone)] -pub struct Identify; - -/// Substream upgrade protocol for `/ipfs/id/push/1.0.0`. -#[derive(Debug, Clone)] -pub struct Push(T); -pub struct InboundPush(); -pub struct OutboundPush(Info); - -impl Push { - pub fn inbound() -> Self { - Push(InboundPush()) - } -} - -impl Push { - pub fn outbound(info: Info) -> Self { - Push(OutboundPush(info)) - } -} - /// Identify information of a peer sent in protocol messages. #[derive(Debug, Clone)] pub struct Info { @@ -117,75 +90,7 @@ pub struct PushInfo { pub observed_addr: Option, } -impl UpgradeInfo for Identify { - type Info = StreamProtocol; - type InfoIter = iter::Once; - - fn protocol_info(&self) -> Self::InfoIter { - iter::once(PROTOCOL_NAME) - } -} - -impl InboundUpgrade for Identify { - type Output = C; - type Error = UpgradeError; - type Future = future::Ready>; - - fn upgrade_inbound(self, socket: C, _: Self::Info) -> Self::Future { - future::ok(socket) - } -} - -impl OutboundUpgrade for Identify -where - C: AsyncRead + AsyncWrite + Unpin + Send + 'static, -{ - type Output = Info; - type Error = UpgradeError; - type Future = Pin> + Send>>; - - fn upgrade_outbound(self, socket: C, _: Self::Info) -> Self::Future { - recv_identify(socket).boxed() - } -} - -impl UpgradeInfo for Push { - type Info = StreamProtocol; - type InfoIter = iter::Once; - - fn protocol_info(&self) -> Self::InfoIter { - iter::once(PUSH_PROTOCOL_NAME) - } -} - -impl InboundUpgrade for Push -where - C: AsyncRead + AsyncWrite + Unpin + Send + 'static, -{ - type Output = BoxFuture<'static, Result>; - type Error = Void; - type Future = future::Ready>; - - fn upgrade_inbound(self, socket: C, _: Self::Info) -> Self::Future { - // Lazily upgrade stream, thus allowing upgrade to happen within identify's handler. - future::ok(recv_push(socket).boxed()) - } -} - -impl OutboundUpgrade for Push -where - C: AsyncWrite + Unpin + Send + 'static, -{ - type Output = (); - type Error = UpgradeError; - type Future = Pin> + Send>>; - - fn upgrade_outbound(self, socket: C, _: Self::Info) -> Self::Future { - send(socket, self.0 .0).boxed() - } -} - -pub(crate) async fn send(io: T, info: Info) -> Result<(), UpgradeError> +pub(crate) async fn send_identify(io: T, info: Info) -> Result<(), UpgradeError> where T: AsyncWrite + Unpin, { @@ -219,7 +124,7 @@ where Ok(()) } -async fn recv_push(socket: T) -> Result +pub(crate) async fn recv_push(socket: T) -> Result where T: AsyncRead + AsyncWrite + Unpin, { @@ -230,7 +135,7 @@ where Ok(info) } -async fn recv_identify(socket: T) -> Result +pub(crate) async fn recv_identify(socket: T) -> Result where T: AsyncRead + AsyncWrite + Unpin, { diff --git a/protocols/kad/Cargo.toml b/protocols/kad/Cargo.toml index 5b2a74080b35..f97f4ba03adb 100644 --- a/protocols/kad/Cargo.toml +++ b/protocols/kad/Cargo.toml @@ -24,7 +24,7 @@ quick-protobuf = "0.8" quick-protobuf-codec = { workspace = true } libp2p-identity = { workspace = true } rand = "0.8" -sha2 = "0.10.7" +sha2 = "0.10.8" smallvec = "1.11.1" uint = "0.9" unsigned-varint = { version = "0.7", features = ["asynchronous_codec"] } @@ -54,3 +54,6 @@ serde = ["dep:serde", "bytes/serde"] all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/mdns/Cargo.toml b/protocols/mdns/Cargo.toml index c200c4783211..da2c0c932410 100644 --- a/protocols/mdns/Cargo.toml +++ b/protocols/mdns/Cargo.toml @@ -55,3 +55,6 @@ required-features = ["tokio"] all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/perf/Cargo.toml b/protocols/perf/Cargo.toml index 41b91ea12094..50ca36a99e24 100644 --- a/protocols/perf/Cargo.toml +++ b/protocols/perf/Cargo.toml @@ -43,3 +43,6 @@ libp2p-swarm-test = { path = "../../swarm-test" } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/perf/src/bin/perf.rs b/protocols/perf/src/bin/perf.rs index 316443245719..4205cc3843bd 100644 --- a/protocols/perf/src/bin/perf.rs +++ b/protocols/perf/src/bin/perf.rs @@ -428,14 +428,12 @@ async fn connect( let start = Instant::now(); swarm.dial(server_address.clone()).unwrap(); - let server_peer_id = loop { - match swarm.next().await.unwrap() { - SwarmEvent::ConnectionEstablished { peer_id, .. } => break peer_id, - SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => { - bail!("Outgoing connection error to {:?}: {:?}", peer_id, error); - } - e => panic!("{e:?}"), + let server_peer_id = match swarm.next().await.unwrap() { + SwarmEvent::ConnectionEstablished { peer_id, .. } => peer_id, + SwarmEvent::OutgoingConnectionError { peer_id, error, .. } => { + bail!("Outgoing connection error to {:?}: {:?}", peer_id, error); } + e => panic!("{e:?}"), }; let duration = start.elapsed(); diff --git a/protocols/ping/Cargo.toml b/protocols/ping/Cargo.toml index 29cf5985b76a..a15407b28401 100644 --- a/protocols/ping/Cargo.toml +++ b/protocols/ping/Cargo.toml @@ -35,3 +35,6 @@ quickcheck = { workspace = true } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/relay/Cargo.toml b/protocols/relay/Cargo.toml index a13ba2bb229f..03799a8c77cf 100644 --- a/protocols/relay/Cargo.toml +++ b/protocols/relay/Cargo.toml @@ -43,3 +43,6 @@ quickcheck = { workspace = true } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/rendezvous/Cargo.toml b/protocols/rendezvous/Cargo.toml index b231f9d7c249..c3912b78ddf3 100644 --- a/protocols/rendezvous/Cargo.toml +++ b/protocols/rendezvous/Cargo.toml @@ -46,3 +46,6 @@ libp2p-swarm-test = { path = "../../swarm-test" } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/request-response/Cargo.toml b/protocols/request-response/Cargo.toml index 3b228fe20b33..b87048bb6298 100644 --- a/protocols/request-response/Cargo.toml +++ b/protocols/request-response/Cargo.toml @@ -46,3 +46,6 @@ serde = { version = "1.0", features = ["derive"]} all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/protocols/upnp/CHANGELOG.md b/protocols/upnp/CHANGELOG.md index 13b2f88e8534..8ebea5e728ec 100644 --- a/protocols/upnp/CHANGELOG.md +++ b/protocols/upnp/CHANGELOG.md @@ -1,5 +1,8 @@ ## 0.1.1 - unreleased +- Fix high CPU usage due to repeated generation of failure events. + See [PR 4569](https://github.com/libp2p/rust-libp2p/pull/4569). + - Fix port mapping protocol used for a UDP multiaddress. See [PR 4542](https://github.com/libp2p/rust-libp2p/pull/4542). diff --git a/protocols/upnp/Cargo.toml b/protocols/upnp/Cargo.toml index 4121745de42b..8a3c5e0ee902 100644 --- a/protocols/upnp/Cargo.toml +++ b/protocols/upnp/Cargo.toml @@ -22,3 +22,13 @@ tokio = { version = "1.29", default-features = false, features = ["rt"], optiona [features] tokio = ["igd-next/aio_tokio", "dep:tokio"] + +[lints] +workspace = true + +# Passing arguments to the docsrs builder in order to properly document cfg's. +# More information: https://docs.rs/about/builds#cross-compiling +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/protocols/upnp/src/behaviour.rs b/protocols/upnp/src/behaviour.rs index 063734d9b5b9..45b82edc562a 100644 --- a/protocols/upnp/src/behaviour.rs +++ b/protocols/upnp/src/behaviour.rs @@ -513,12 +513,7 @@ impl NetworkBehaviour for Behaviour { self.mappings.renew(gateway, cx); return Poll::Pending; } - GatewayState::GatewayNotFound => { - return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound)); - } - GatewayState::NonRoutableGateway(_) => { - return Poll::Ready(ToSwarm::GenerateEvent(Event::NonRoutableGateway)); - } + _ => return Poll::Pending, } } } diff --git a/scripts/build-interop-image.sh b/scripts/build-interop-image.sh new file mode 100755 index 000000000000..28a8db9188d1 --- /dev/null +++ b/scripts/build-interop-image.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# This uses the same S3 cache as all test-plans images. Because we use `cargo-chef` in the Dockerfile, we have a layer available with all dependencies built. + +CACHE_TO="" + +# If we have credentials, write to cache +if [[ -n "${AWS_SECRET_ACCESS_KEY}" ]]; then + CACHE_TO="--cache-to type=s3,mode=max,bucket=libp2p-by-tf-aws-bootstrap,region=us-east-1,prefix=buildCache,name=${FLAVOUR}-rust-libp2p-head" +fi + +docker buildx build \ + --load \ + $CACHE_TO \ + --cache-from type=s3,mode=max,bucket=libp2p-by-tf-aws-bootstrap,region=us-east-1,prefix=buildCache,name=${FLAVOUR}-rust-libp2p-head \ + -t ${FLAVOUR}-rust-libp2p-head \ + . \ + -f interop-tests/Dockerfile.${FLAVOUR} diff --git a/swarm-derive/Cargo.toml b/swarm-derive/Cargo.toml index 75a3ac29eee9..77589a1956b9 100644 --- a/swarm-derive/Cargo.toml +++ b/swarm-derive/Cargo.toml @@ -16,7 +16,7 @@ proc-macro = true [dependencies] heck = "0.4" quote = "1.0" -syn = { version = "2.0.37", default-features = false, features = ["clone-impls", "derive", "parsing", "printing", "proc-macro"] } +syn = { version = "2.0.38", default-features = false, features = ["clone-impls", "derive", "parsing", "printing", "proc-macro"] } proc-macro-warning = "0.4.2" proc-macro2 = "1.0" @@ -26,3 +26,6 @@ proc-macro2 = "1.0" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/swarm-test/Cargo.toml b/swarm-test/Cargo.toml index 67753b1c522f..8c953b2b52f8 100644 --- a/swarm-test/Cargo.toml +++ b/swarm-test/Cargo.toml @@ -23,3 +23,6 @@ futures = "0.3.28" log = "0.4.20" rand = "0.8.5" futures-timer = "3.0.2" + +[lints] +workspace = true diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index a991bacd53e4..038041c536f7 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -43,14 +43,14 @@ async-std = { version = "1.6.2", features = ["attributes"] } either = "1.9.0" env_logger = "0.10" futures = "0.3.28" -libp2p-identify = { path = "../protocols/identify" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-identify = { path = "../protocols/identify" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. libp2p-identity = { workspace = true, features = ["ed25519"] } -libp2p-kad = { path = "../protocols/kad" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. -libp2p-ping = { path = "../protocols/ping" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. -libp2p-plaintext = { path = "../transports/plaintext" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. -libp2p-swarm-derive = { path = "../swarm-derive" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. -libp2p-swarm-test = { path = "../swarm-test" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. -libp2p-yamux = { path = "../muxers/yamux" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-kad = { path = "../protocols/kad" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-ping = { path = "../protocols/ping" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-plaintext = { path = "../transports/plaintext" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-swarm-derive = { path = "../swarm-derive" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-swarm-test = { path = "../swarm-test" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. +libp2p-yamux = { path = "../muxers/yamux" } # Using `path` here because this is a cyclic dev-dependency which otherwise breaks releasing. quickcheck = { workspace = true } void = "1" once_cell = "1.18.0" @@ -67,3 +67,6 @@ required-features = ["macros"] all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/swarm/src/behaviour.rs b/swarm/src/behaviour.rs index d80f5f0c9a42..3662bf5c48d2 100644 --- a/swarm/src/behaviour.rs +++ b/swarm/src/behaviour.rs @@ -144,7 +144,7 @@ pub trait NetworkBehaviour: 'static { /// This is invoked once another peer has successfully dialed us. /// /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial. - /// In order to actually use this connection, this function must return a [`ConnectionHandler`](crate::ConnectionHandler). + /// In order to actually use this connection, this function must return a [`ConnectionHandler`]. /// Returning an error will immediately close the connection. fn handle_established_inbound_connection( &mut self, @@ -180,7 +180,7 @@ pub trait NetworkBehaviour: 'static { /// /// This is invoked once we have successfully dialed a peer. /// At this point, we have verified their [`PeerId`] and we know, which particular [`Multiaddr`] succeeded in the dial. - /// In order to actually use this connection, this function must return a [`ConnectionHandler`](crate::ConnectionHandler). + /// In order to actually use this connection, this function must return a [`ConnectionHandler`]. /// Returning an error will immediately close the connection. fn handle_established_outbound_connection( &mut self, @@ -193,7 +193,7 @@ pub trait NetworkBehaviour: 'static { /// Informs the behaviour about an event from the [`Swarm`](crate::Swarm). fn on_swarm_event(&mut self, event: FromSwarm); - /// Informs the behaviour about an event generated by the [`ConnectionHandler`](crate::ConnectionHandler) + /// Informs the behaviour about an event generated by the [`ConnectionHandler`] /// dedicated to the peer identified by `peer_id`. for the behaviour. /// /// The [`PeerId`] is guaranteed to be in a connected state. In other words, @@ -260,20 +260,20 @@ pub enum ToSwarm { /// Instructs the `Swarm` to send an event to the handler dedicated to a /// connection with a peer. /// - /// If the `Swarm` is connected to the peer, the message is delivered to the - /// [`ConnectionHandler`](crate::ConnectionHandler) instance identified by the peer ID and connection ID. + /// If the `Swarm` is connected to the peer, the message is delivered to the [`ConnectionHandler`] + /// instance identified by the peer ID and connection ID. /// /// If the specified connection no longer exists, the event is silently dropped. /// /// Typically the connection ID given is the same as the one passed to /// [`NetworkBehaviour::on_connection_handler_event`], i.e. whenever the behaviour wishes to /// respond to a request on the same connection (and possibly the same - /// substream, as per the implementation of [`ConnectionHandler`](crate::ConnectionHandler)). + /// substream, as per the implementation of [`ConnectionHandler`]). /// /// Note that even if the peer is currently connected, connections can get closed /// at any time and thus the event may not reach a handler. NotifyHandler { - /// The peer for whom a [`ConnectionHandler`](crate::ConnectionHandler) should be notified. + /// The peer for whom a [`ConnectionHandler`] should be notified. peer_id: PeerId, /// The options w.r.t. which connection handler to notify of the event. handler: NotifyHandler, @@ -309,10 +309,10 @@ pub enum ToSwarm { /// /// Note: Closing a connection via /// [`ToSwarm::CloseConnection`] does not inform the - /// corresponding [`ConnectionHandler`](crate::ConnectionHandler). - /// Closing a connection via a [`ConnectionHandler`](crate::ConnectionHandler) can be done - /// either in a collaborative manner across [`ConnectionHandler`](crate::ConnectionHandler)s - /// with [`ConnectionHandler::connection_keep_alive`](crate::ConnectionHandler::connection_keep_alive) or directly with + /// corresponding [`ConnectionHandler`]. + /// Closing a connection via a [`ConnectionHandler`] can be done + /// either in a collaborative manner across [`ConnectionHandler`]s + /// with [`ConnectionHandler::connection_keep_alive`] or directly with /// [`ConnectionHandlerEvent::Close`](crate::ConnectionHandlerEvent::Close). CloseConnection { /// The peer to disconnect. diff --git a/swarm/src/connection.rs b/swarm/src/connection.rs index d99319cf2cb4..97251039abb2 100644 --- a/swarm/src/connection.rs +++ b/swarm/src/connection.rs @@ -144,8 +144,7 @@ where /// Note: This only enforces a limit on the number of concurrently /// negotiating inbound streams. The total number of inbound streams on a /// connection is the sum of negotiating and negotiated streams. A limit on - /// the total number of streams can be enforced at the - /// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level. + /// the total number of streams can be enforced at the [`StreamMuxerBox`] level. max_negotiating_inbound_streams: usize, /// Contains all upgrades that are waiting for a new outbound substream. /// diff --git a/swarm/src/connection/pool.rs b/swarm/src/connection/pool.rs index 07fc9075806c..b6100989a04e 100644 --- a/swarm/src/connection/pool.rs +++ b/swarm/src/connection/pool.rs @@ -981,7 +981,7 @@ impl PoolConfig { /// delivery to the connection handler. /// /// When the buffer for a particular connection is full, `notify_handler` will no - /// longer be able to deliver events to the associated [`Connection`](super::Connection), + /// longer be able to deliver events to the associated [`Connection`], /// thus exerting back-pressure on the connection and peer API. pub(crate) fn with_notify_handler_buffer_size(mut self, n: NonZeroUsize) -> Self { self.task_command_buffer_size = n.get() - 1; diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 44dc3c8da663..b81dcff802c2 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -159,8 +159,7 @@ use std::{ /// Substream for which a protocol has been chosen. /// -/// Implements the [`AsyncRead`](futures::io::AsyncRead) and -/// [`AsyncWrite`](futures::io::AsyncWrite) traits. +/// Implements the [`AsyncRead`] and [`AsyncWrite`] traits. #[deprecated(note = "The 'substream' terminology is deprecated. Use 'Stream' instead")] pub type NegotiatedSubstream = Stream; @@ -1515,8 +1514,7 @@ where /// Note: This only enforces a limit on the number of concurrently /// negotiating inbound streams. The total number of inbound streams on a /// connection is the sum of negotiating and negotiated streams. A limit on - /// the total number of streams can be enforced at the - /// [`StreamMuxerBox`](libp2p_core::muxing::StreamMuxerBox) level. + /// the total number of streams can be enforced at the [`StreamMuxerBox`] level. pub fn max_negotiating_inbound_streams(mut self, v: usize) -> Self { self.pool_config = self.pool_config.with_max_negotiating_inbound_streams(v); self @@ -2153,19 +2151,14 @@ mod tests { ) .unwrap(); for mut transport in transports.into_iter() { - loop { - match futures::future::select(transport.select_next_some(), swarm.next()) - .await - { - future::Either::Left((TransportEvent::Incoming { .. }, _)) => { - break; - } - future::Either::Left(_) => { - panic!("Unexpected transport event.") - } - future::Either::Right((e, _)) => { - panic!("Expect swarm to not emit any event {e:?}") - } + match futures::future::select(transport.select_next_some(), swarm.next()).await + { + future::Either::Left((TransportEvent::Incoming { .. }, _)) => {} + future::Either::Left(_) => { + panic!("Unexpected transport event.") + } + future::Either::Right((e, _)) => { + panic!("Expect swarm to not emit any event {e:?}") } } } diff --git a/transports/deflate/Cargo.toml b/transports/deflate/Cargo.toml index 95f552f63c8e..9e2e1f4e0292 100644 --- a/transports/deflate/Cargo.toml +++ b/transports/deflate/Cargo.toml @@ -28,3 +28,6 @@ futures_ringbuf = "0.4.0" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/dns/Cargo.toml b/transports/dns/Cargo.toml index 81ee2312089c..1d5fb1bc7f9a 100644 --- a/transports/dns/Cargo.toml +++ b/transports/dns/Cargo.toml @@ -41,3 +41,6 @@ tokio-dns-over-https-rustls = ["tokio", "trust-dns-resolver/dns-over-https-rustl all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/noise/Cargo.toml b/transports/noise/Cargo.toml index 3ebf0364a1b7..876a3cd34d50 100644 --- a/transports/noise/Cargo.toml +++ b/transports/noise/Cargo.toml @@ -20,9 +20,9 @@ multihash = { workspace = true } once_cell = "1.18.0" quick-protobuf = "0.8" rand = "0.8.3" -sha2 = "0.10.7" +sha2 = "0.10.8" static_assertions = "1" -thiserror = "1.0.48" +thiserror = "1.0.49" x25519-dalek = "1.1.0" zeroize = "1" @@ -43,3 +43,6 @@ quickcheck = { workspace = true } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/plaintext/Cargo.toml b/transports/plaintext/Cargo.toml index 573114672dac..f58fefb44ca8 100644 --- a/transports/plaintext/Cargo.toml +++ b/transports/plaintext/Cargo.toml @@ -33,3 +33,6 @@ futures_ringbuf = "0.4.0" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/pnet/Cargo.toml b/transports/pnet/Cargo.toml index 5861bf2d9870..1a3a1224fbbe 100644 --- a/transports/pnet/Cargo.toml +++ b/transports/pnet/Cargo.toml @@ -20,7 +20,7 @@ pin-project = "1.1.3" [dev-dependencies] libp2p-core = { workspace = true } -libp2p-identity = { workspace = true, features = ["ed25519", "rsa", "ecdsa", "secp256k1"] } +libp2p-identity = { workspace = true, features = ["ed25519", "rsa", "ecdsa","secp256k1"] } libp2p-noise = { workspace = true } libp2p-swarm = { workspace = true, features = ["tokio"] } libp2p-tcp = { workspace = true, features = ["tokio"] } @@ -35,3 +35,6 @@ tokio = { version = "1.32.0", features = ["full"] } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/quic/CHANGELOG.md b/transports/quic/CHANGELOG.md index 7cf54e89b663..a7ad810bdb61 100644 --- a/transports/quic/CHANGELOG.md +++ b/transports/quic/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.9.3 - unreleased + +- Support QUIC stateless resets for supported `libp2p_identity::Keypair`s. See [PR 4554]. + +[PR 4554]: https://github.com/libp2p/rust-libp2p/pull/4554 + ## 0.9.2 - Cut stable release. diff --git a/transports/quic/Cargo.toml b/transports/quic/Cargo.toml index 671032a845d8..697c257fa52c 100644 --- a/transports/quic/Cargo.toml +++ b/transports/quic/Cargo.toml @@ -22,9 +22,10 @@ parking_lot = "0.12.0" quinn = { version = "0.10.2", default-features = false, features = ["tls-rustls", "futures-io"] } rand = "0.8.5" rustls = { version = "0.21.7", default-features = false } -thiserror = "1.0.48" +thiserror = "1.0.49" tokio = { version = "1.32.0", default-features = false, features = ["net", "rt", "time"], optional = true } socket2 = "0.5.4" +ring = "0.16.20" [features] tokio = ["dep:tokio", "if-watch/tokio", "quinn/runtime-tokio"] @@ -50,3 +51,6 @@ tokio = { version = "1.32.0", features = ["macros", "rt-multi-thread", "time"] } [[test]] name = "stream_compliance" required-features = ["async-std"] + +[lints] +workspace = true diff --git a/transports/quic/src/config.rs b/transports/quic/src/config.rs index 201594e247c4..5351a537c763 100644 --- a/transports/quic/src/config.rs +++ b/transports/quic/src/config.rs @@ -61,6 +61,8 @@ pub struct Config { client_tls_config: Arc, /// TLS server config for the inner [`quinn::ServerConfig`]. server_tls_config: Arc, + /// Libp2p identity of the node. + keypair: libp2p_identity::Keypair, } impl Config { @@ -80,6 +82,7 @@ impl Config { // Ensure that one stream is not consuming the whole connection. max_stream_data: 10_000_000, + keypair: keypair.clone(), } } } @@ -104,6 +107,7 @@ impl From for QuinnConfig { max_stream_data, support_draft_29, handshake_timeout: _, + keypair, } = config; let mut transport = quinn::TransportConfig::default(); // Disable uni-directional streams. @@ -128,7 +132,14 @@ impl From for QuinnConfig { let mut client_config = quinn::ClientConfig::new(client_tls_config); client_config.transport_config(transport); - let mut endpoint_config = quinn::EndpointConfig::default(); + let mut endpoint_config = keypair + .derive_secret(b"libp2p quic stateless reset key") + .map(|secret| { + let reset_key = Arc::new(ring::hmac::Key::new(ring::hmac::HMAC_SHA256, &secret)); + quinn::EndpointConfig::new(reset_key) + }) + .unwrap_or_default(); + if !support_draft_29 { endpoint_config.supported_versions(vec![1]); } diff --git a/transports/tcp/Cargo.toml b/transports/tcp/Cargo.toml index ffee29c54c65..14eec8c4caad 100644 --- a/transports/tcp/Cargo.toml +++ b/transports/tcp/Cargo.toml @@ -15,7 +15,7 @@ async-io = { version = "1.13.0", optional = true } futures = "0.3.28" futures-timer = "3.0" if-watch = "3.0.1" -libc = "0.2.148" +libc = "0.2.149" libp2p-core = { workspace = true } libp2p-identity = { workspace = true } log = "0.4.20" @@ -38,3 +38,6 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/tls/Cargo.toml b/transports/tls/Cargo.toml index ba60164cd3ea..b2ca28784f76 100644 --- a/transports/tls/Cargo.toml +++ b/transports/tls/Cargo.toml @@ -15,7 +15,7 @@ libp2p-core = { workspace = true } libp2p-identity = { workspace = true } rcgen = "0.10.0" ring = "0.16.20" -thiserror = "1.0.48" +thiserror = "1.0.49" webpki = { version = "0.101.4", package = "rustls-webpki", features = ["std"] } x509-parser = "0.15.1" yasna = "0.5.2" @@ -41,3 +41,6 @@ tokio = { version = "1.32.0", features = ["full"] } all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/uds/Cargo.toml b/transports/uds/Cargo.toml index d776ac3366de..1bc78ff35a96 100644 --- a/transports/uds/Cargo.toml +++ b/transports/uds/Cargo.toml @@ -26,3 +26,6 @@ tempfile = "3.8" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/wasm-ext/Cargo.toml b/transports/wasm-ext/Cargo.toml index d7deba525e08..6d5ed8e229c9 100644 --- a/transports/wasm-ext/Cargo.toml +++ b/transports/wasm-ext/Cargo.toml @@ -27,3 +27,6 @@ websocket = [] all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/webrtc-websys/Cargo.toml b/transports/webrtc-websys/Cargo.toml index 19148068fce0..cb90573b1fe4 100644 --- a/transports/webrtc-websys/Cargo.toml +++ b/transports/webrtc-websys/Cargo.toml @@ -34,3 +34,6 @@ web-sys = { version = "0.3.64", features = ["Document", "Location", "MessageEven hex-literal = "0.4" libp2p-ping = { workspace = true } libp2p-swarm = { workspace = true, features = ["wasm-bindgen"] } + +[lints] +workspace = true diff --git a/transports/webrtc/Cargo.toml b/transports/webrtc/Cargo.toml index 7cd16f2ceb20..1c5d23b46528 100644 --- a/transports/webrtc/Cargo.toml +++ b/transports/webrtc/Cargo.toml @@ -29,7 +29,7 @@ serde = { version = "1.0", features = ["derive"] } stun = "0.5" thiserror = "1" tinytemplate = "1.2" -tokio = { version = "1.32", features = ["net"], optional = true} +tokio = { version = "1.32", features = ["net"], optional = true } tokio-util = { version = "0.7", features = ["compat"], optional = true } webrtc = { version = "0.9.0", optional = true } @@ -45,3 +45,13 @@ quickcheck = "1.0.3" [[test]] name = "smoke" required-features = ["tokio"] + +[lints] +workspace = true + +# Passing arguments to the docsrs builder in order to properly document cfg's. +# More information: https://docs.rs/about/builds#cross-compiling +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] +rustc-args = ["--cfg", "docsrs"] diff --git a/transports/webrtc/src/lib.rs b/transports/webrtc/src/lib.rs index f71203cc2f7e..ea1e6a4d6465 100644 --- a/transports/webrtc/src/lib.rs +++ b/transports/webrtc/src/lib.rs @@ -79,5 +79,8 @@ //! hand-crate the SDP answer generated by the remote, this is problematic. A way to solve this //! is to make the hash a part of the remote's multiaddr. On the server side, we turn //! certificate verification off. + +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + #[cfg(feature = "tokio")] pub mod tokio; diff --git a/transports/websocket/Cargo.toml b/transports/websocket/Cargo.toml index f3ebf5af000c..62a5129cbfa0 100644 --- a/transports/websocket/Cargo.toml +++ b/transports/websocket/Cargo.toml @@ -36,3 +36,6 @@ rcgen = "0.10.0" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/transports/webtransport-websys/Cargo.toml b/transports/webtransport-websys/Cargo.toml index 7825f64a8ab2..54ecc5b9b405 100644 --- a/transports/webtransport-websys/Cargo.toml +++ b/transports/webtransport-websys/Cargo.toml @@ -23,7 +23,7 @@ log = "0.4.20" multiaddr = { workspace = true } multihash = { workspace = true } send_wrapper = { version = "0.6.0", features = ["futures"] } -thiserror = "1.0.48" +thiserror = "1.0.49" wasm-bindgen = "0.2.87" wasm-bindgen-futures = "0.4.37" web-sys = { version = "0.3.64", features = [ @@ -46,3 +46,6 @@ multibase = "0.9.1" all-features = true rustdoc-args = ["--cfg", "docsrs"] rustc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true diff --git a/wasm-tests/webtransport-tests/Cargo.toml b/wasm-tests/webtransport-tests/Cargo.toml index 6c564281274b..8d3f756ecb78 100644 --- a/wasm-tests/webtransport-tests/Cargo.toml +++ b/wasm-tests/webtransport-tests/Cargo.toml @@ -18,3 +18,6 @@ wasm-bindgen = "0.2.87" wasm-bindgen-futures = "0.4.37" wasm-bindgen-test = "0.3.37" web-sys = { version = "0.3.64", features = ["Response", "Window"] } + +[lints] +workspace = true