chore(deps): bump quinn to 0.11.9 / quinn-proto 0.11.14 (self-healing)#10207
Draft
tmu0 wants to merge 7 commits into
Draft
chore(deps): bump quinn to 0.11.9 / quinn-proto 0.11.14 (self-healing)#10207tmu0 wants to merge 7 commits into
tmu0 wants to merge 7 commits into
Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous quinn 0.11.5 → 0.11.9 / quinn-proto 0.11.7 → 0.11.14 bump
broke the universal canister wasm build with:
panicked at rs/embedders/bin/instrument_wasm.rs:87:49:
Error compiling Wasm: InvalidWasm(InvalidImportSection(
"Module imports function '__wbindgen_describe' from
'__wbindgen_placeholder__' that is not exported by the runtime."))
Root cause: quinn-proto 0.11.14 declares four wasm-target deps to support
its own browser-targeted builds:
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies.getrandom]
features = ["wasm_js"]
[target.'cfg(...)'.dependencies.ring]
features = ["wasm32_unknown_unknown_js"]
[target.'cfg(...)'.dependencies.rustls-pki-types]
features = ["web"]
[target.'cfg(...)'.dependencies.web-time]
The IC canister target is also `wasm32-unknown-unknown`. Cargo/cargo-bazel
feature unification then activates ring's `wasm32_unknown_unknown_js`
feature, which is defined as `wasm32_unknown_unknown_js = ["getrandom/js"]`
in ring 0.17.14. That enables the `js` feature on getrandom 0.2.10
workspace-wide, pulling `wasm-bindgen` + `js-sys` into getrandom 0.2.10's
wasm32-unknown-unknown deps — and into canister wasm output.
IC never compiles quinn-proto for wasm (it's used only by the replica P2P
stack on Linux), so removing these deps is a no-op for the actual build.
Two-part fix:
1. bazel/quinn-proto.patch + crate.annotation: drop the four wasm-target
dep stanzas from quinn-proto's Cargo.toml. Documents the intent and
takes effect for any rebuild of quinn-proto sources.
2. Cargo.Bazel.{toml,json}.lock: revert getrandom 0.2.10's spurious
wasm32-unknown-unknown crate_features (`js`, `js-sys`, `wasm-bindgen`)
and deps (`js-sys 0.3.77`, `wasm-bindgen 0.2.100`) to their master
state. This is the load-bearing fix — rules_rust uses the JSON lock's
feature set when invoking rustc, so the manual revert is what actually
stops `--cfg feature="js"` from reaching getrandom 0.2.10's
wasm-bindgen import paths in the canister wasm build.
Verified locally: `bazel build --config=local
//rs/universal_canister/impl:universal_canister_serialized_module`
succeeds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…essing
`./bin/bazel-pin.sh --force` would otherwise re-introduce the
wasm-bindgen leak from getrandom 0.2.10 that quinn-proto 0.11.14
activates via ring's wasm32_unknown_unknown_js feature, breaking the
canister wasm build. `crate.annotation(patches = ...)` cannot prevent
this because patches are applied to crate sources after cargo metadata
has resolved features.
bin/strip-quinn-wasm-leak.py removes the leak from
Cargo.Bazel.{json,toml}.lock and updates the cargo-bazel digest by
parsing the expected value from `bazel query @crate_index//:all`. The
script is idempotent and bin/bazel-pin.sh always calls it after a
repin, so the committed lockfiles converge to the same clean state
regardless of who runs the repin.
Verified locally: a fresh `./bin/bazel-pin.sh --force` reproduces the
exact committed lockfiles, and `//rs/universal_canister/impl:universal_canister_serialized_module`
builds successfully.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR re-applies the quinn / quinn-proto version bump while adding a repo-local “self-healing” step to prevent a previously observed wasm-bindgen import leak from reappearing when cargo-bazel lockfiles are regenerated.
Changes:
- Bumps
quinnto0.11.9andquinn-prototo0.11.14(plus related lockfile updates). - Adds
bin/strip-quinn-wasm-leak.pyand wires it intobin/bazel-pin.shto post-process cargo-bazel lockfiles and re-digest them. - Retains a
quinn-protopatch +crate.annotationdocumenting/removing upstream wasm-target deps (for source consistency in Bazel’s extracted crate).
Reviewed changes
Copilot reviewed 3 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| Cargo.toml | Updates quinn / quinn-udp dependency versions. |
| Cargo.lock | Captures the transitive dependency resolution changes from the bump. |
| Cargo.Bazel.toml.lock | Updates cargo-bazel TOML lock state for the new dependency graph. |
| Cargo.Bazel.json.lock | Updates cargo-bazel JSON lock state + checksum for Bazel/rules_rust. |
| bin/strip-quinn-wasm-leak.py | New post-processing script to remove the wasm leak and refresh the cargo-bazel digest. |
| bin/bazel-pin.sh | Calls the new “strip leak” script after repinning. |
| bazel/rust.MODULE.bazel | Adds crate.annotation to apply the quinn-proto patch in Bazel. |
| bazel/quinn-proto.patch | Patch removing quinn-proto’s wasm-target dependency block (documentation + source consistency). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+2065
to
+2068
| # Drop quinn-proto's wasm-target `getrandom` dep so its `wasm_js` feature | ||
| # doesn't leak into the canister wasm build via Cargo feature unification. | ||
| # IC compiles quinn-proto only for the Linux replica, so this is a no-op | ||
| # for the real build graph. See bazel/quinn-proto.patch. |
Use tomllib (stdlib) to identify the getrandom 0.2.10 package and its dependencies instead of pattern-matching the entire [[package]] block with a regex. The splice back into the original text is kept so we preserve cargo's exact 1-space-indented array formatting (stdlib has no TOML writer that matches it). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bin/bazel-pin.shso the wasm-bindgen leak that broke the canister build last time cannot be re-introduced by repinning.Why the previous attempt was reverted
quinn-proto 0.11.14 declares
wasm32-unknown-unknowndeps that activate ring'swasm32_unknown_unknown_jsfeature. Through cargo's feature unification, that feature pullsgetrandom/jsongetrandom 0.2.10, which linkswasm-bindgenandjs-sysinto the canister wasm output. The IC embedder rejects those imports and the universal canister fails to build.The previous PR fixed this by manually editing
Cargo.Bazel.{json,toml}.lock. The fix was load-bearing — but running./bin/bazel-pin.sh(e.g. as part of another dep bump) would re-run cargo-bazel and overwrite the manual edits, silently re-introducing the regression.crate.annotation(patches = ...)cannot prevent this because patches are applied to crate sources after cargo metadata has resolved the workspace.What's new in this PR
bin/strip-quinn-wasm-leak.pystrips the wasm-bindgen leak fromgetrandom 0.2.10in both cargo-bazel lockfiles and updates the cargo-bazel digest by parsing the expected value frombazel query @crate_index//:all. The script is idempotent andbin/bazel-pin.shalways calls it after a repin, so the committed lockfiles converge to the same clean state regardless of who runs the repin.The
bazel/quinn-proto.patchand matchingcrate.annotationare retained so the extracted quinn-proto source in the bazel cache stays consistent with the lockfiles' view of its deps. They are no longer load-bearing but document the upstream issue.Test plan
./bin/bazel-pin.sh --forcereproduces the exact committed lockfiles (verified withdiffagainst a backup)../bin/bazel-pin.sh(no--force) is a no-op against the committed lockfiles.bazel build --config=local //rs/universal_canister/impl:universal_canister_serialized_modulesucceeds.🤖 Generated with Claude Code