Skip to content

chore(deps): bump quinn to 0.11.9 / quinn-proto 0.11.14 (self-healing)#10207

Draft
tmu0 wants to merge 7 commits into
masterfrom
tmu/bump-quinn-with-postprocess
Draft

chore(deps): bump quinn to 0.11.9 / quinn-proto 0.11.14 (self-healing)#10207
tmu0 wants to merge 7 commits into
masterfrom
tmu/bump-quinn-with-postprocess

Conversation

@tmu0
Copy link
Copy Markdown
Contributor

@tmu0 tmu0 commented May 12, 2026

Summary

Why the previous attempt was reverted

quinn-proto 0.11.14 declares wasm32-unknown-unknown deps that activate ring's wasm32_unknown_unknown_js feature. Through cargo's feature unification, that feature pulls getrandom/js on getrandom 0.2.10, which links wasm-bindgen and js-sys into 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.py strips the wasm-bindgen leak from getrandom 0.2.10 in both cargo-bazel lockfiles 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.

The bazel/quinn-proto.patch and matching crate.annotation are 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 --force reproduces the exact committed lockfiles (verified with diff against 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_module succeeds.
  • Full CI run.

🤖 Generated with Claude Code

tmu0 and others added 5 commits May 11, 2026 17:53
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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 quinn to 0.11.9 and quinn-proto to 0.11.14 (plus related lockfile updates).
  • Adds bin/strip-quinn-wasm-leak.py and wires it into bin/bazel-pin.sh to post-process cargo-bazel lockfiles and re-digest them.
  • Retains a quinn-proto patch + crate.annotation documenting/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 thread bazel/rust.MODULE.bazel
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants