ci(DEFI-2487): add ic-wasm check-endpoints to DeFi-team canisters#10147
Draft
gregorydemay wants to merge 9 commits intomasterfrom
Draft
ci(DEFI-2487): add ic-wasm check-endpoints to DeFi-team canisters#10147gregorydemay wants to merge 9 commits intomasterfrom
gregorydemay wants to merge 9 commits intomasterfrom
Conversation
Extends rust_canister and finalize_wasm in bazel/canisters.bzl with an optional hidden_endpoints kwarg pointing at a hidden_endpoints.conf file. When provided, ic-wasm check-endpoints --hidden <conf> runs between the metadata-stamping and gzip steps of the existing finalize_wasm cmd_bash chain, failing the build if the wasm exports a method that is neither in the candid service nor allowlisted in the conf. The kwarg defaults to None, so existing canisters that don't opt in see no behavior change. The rust_ledger_canister wrapper in rs/ledger_suite/icp/ledger/ledger_canisters.bzl threads the kwarg through to rust_canister. Mirrors the pattern already shipped in dfinity/bitcoin-canister and dfinity/dogecoin-canister, where hidden_endpoints.conf lists legitimate non-candid exports (lifecycle hooks, http_request, canister_global_timer, ic_cdk_timers' timer_executor, vendored FFI symbols, and Rust's main). Per-canister opt-in lands in subsequent commits (DEFI-2501, 2502, 2503, 2504, 2511).
…eature ic-wasm 0.9.x introduces a `check-endpoints` subcommand that fails the canister build if the wasm exports a method that is neither in the candid `service` nor allowlisted in a `hidden_endpoints.conf` file. The IC repo previously pinned ^0.8.4 (predates the subcommand) with `default_features = False` and only the `exe` feature enabled — `check-endpoints` lives behind its own cargo feature, so opting in requires both bumping the version and adding the feature flag. Verified the existing `shrink` and `metadata` invocations in `bazel/canisters.bzl`'s `finalize_wasm` rule still work unchanged (the BTC checker rebuild succeeds end-to-end on 0.9.11 with the existing pipeline). Subsequent commits opt individual canisters into the new check (DEFI-2501, 2502, 2503, 2504, 2511).
Adds rs/bitcoin/checker/hidden_endpoints.conf and threads it into the rust_canister rule via the new optional `hidden_endpoints` kwarg. The conf lists the legitimate non-candid exports of the BTC checker: the metrics http_request, the HTTP-outcall transform query, the two lifecycle hooks, and Rust's `main` symbol. `bazel build //rs/bitcoin/checker:btc_checker_canister.wasm.gz` now reports `Canister WASM and Candid interface match!` as part of finalization and fails the build if a future change exports an unlisted method.
Both variants (`ledger_suite_orchestrator_canister` and `..._getblocksdisabled`) now go through `ic-wasm check-endpoints` during finalization. The shared hidden_endpoints.conf lists canister_global_timer, the metrics http_request, lifecycle hooks, and Rust's main symbol.
Two confs because the ckbtc_minter_debug variant compiles in three extra endpoints behind the `self_check` cargo feature (canister_query:self_check, canister_update:refresh_fee_percentiles, canister_update:upload_events) that are not present in the production ckbtc_minter wasm. ic-wasm check-endpoints is strict in both directions (extra entries in --hidden are also flagged), so a single permissive conf can't satisfy both variants. Both confs share the timer, http_request metrics endpoint, the __get_candid_interface_tmp_hack candid-extraction helper (declared #[query(hidden = true)] in main.rs), the lifecycle hooks, and the Rust main symbol.
Two confs because the cketh_minter_debug variant exports an extra `check_audit_log` query gated behind the `debug_checks` cargo feature, which is absent from cketh_minter.did. Both confs share the IC system-level `canister_global_timer` plus the ic-cdk-timers dispatcher `<ic-cdk internal> timer_executor`, the metrics http_request, the lifecycle hooks (init, pre_upgrade, post_upgrade), and the Rust main symbol. No FFI symbols from ic_secp256k1 / ic_sha3 leaked into the WASM exports — the IC's ic_secp256k1 wrapper appears to keep them internal.
Wires the production-shape variants (`ledger_canister`, `_u256`, `_nextledgerversion`, `_u256_nextledgerversion`) of the ICRC1 ledger through ic-wasm check-endpoints, against a single hidden_endpoints.conf listing the lifecycle hooks, the #[query(hidden = true)] http_request metrics endpoint, the __get_candid_interface_tmp_hack helper (declared #[query] but absent from ledger.did), and Rust's main symbol. The `_getblocksdisabled` and `_canbench` variants are deliberately opted out of the check (hidden_endpoints = None) because they ship with a wasm shape that diverges from `ledger.did`: the former disables `get_blocks` in code while the .did still declares it, and the latter compiles in canbench-rs's `__canbench__*` / `__tracing__*` benchmark exports and replaces `canister_init` with the canbench harness's own. Both are test-only variants; gating them on check-endpoints would either require a separate .did or upstream changes to canbench-rs / the get-blocks-disabled feature itself.
All 4 variants of the ICP ledger now go through ic-wasm check-endpoints during finalization. The base hidden_endpoints.conf covers the 12 legacy `_pb` protobuf endpoints (declared via #[unsafe(export_name = "canister_query <name>")] / #[unsafe(export_name = "canister_update <name>")]), the metrics http_request, the candid-extraction __get_candid_interface_tmp_hack helper (declared #[query] but absent from ledger.did), the lifecycle hooks, and Rust's main symbol. The `_allowance-getter` variant gets a separate hidden_endpoints_allowance_getter.conf because the `icp-allowance-getter` cargo feature compiles in an extra `canister_query:allowance` endpoint not present in ledger.did.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an opt-in ic-wasm check-endpoints validation step to the Bazel canister finalization pipeline and enables it for selected DeFi-team canisters, using per-canister allowlists to prevent accidental public exports from shipping.
Changes:
- Extend
bazel/canisters.bzlfinalize_wasmto optionally runic-wasm check-endpointsusing ahidden_endpoints.confallowlist. - Add
hidden_endpoints.confallowlists and Bazel wiring for the ICP/ICRC1 ledgers and DeFi canisters (ckBTC minter, ckETH minter, ledger-suite orchestrator, BTC checker). - Bump
ic-wasm(and Bazel crate metadata/locks) to a version that supports thecheck-endpointsfeature.
Reviewed changes
Copilot reviewed 18 out of 20 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| rs/ledger_suite/icrc1/ledger/hidden_endpoints.conf | Adds allowlist of lifecycle/hidden exports for ic-wasm check-endpoints. |
| rs/ledger_suite/icrc1/ledger/BUILD.bazel | Enables hidden_endpoints for production variants; opts test-only variants out. |
| rs/ledger_suite/icp/ledger/ledger_canisters.bzl | Adds hidden_endpoints parameter pass-through to rust_canister. |
| rs/ledger_suite/icp/ledger/hidden_endpoints.conf | Adds allowlist for ICP ledger hidden/system/legacy exports. |
| rs/ledger_suite/icp/ledger/hidden_endpoints_allowance_getter.conf | Adds allowlist variant for the allowance-getter build that exports allowance. |
| rs/ledger_suite/icp/ledger/BUILD.bazel | Opts ICP ledger wasm targets into endpoint checking with the appropriate allowlist. |
| rs/ethereum/ledger-suite-orchestrator/hidden_endpoints.conf | Adds allowlist for orchestrator hidden/system exports. |
| rs/ethereum/ledger-suite-orchestrator/BUILD.bazel | Opts orchestrator canister into endpoint checking. |
| rs/ethereum/cketh/minter/hidden_endpoints.conf | Adds allowlist for ckETH minter hidden/system exports (timers, metrics, lifecycle). |
| rs/ethereum/cketh/minter/hidden_endpoints_debug.conf | Adds debug-variant allowlist for extra debug-only exported endpoints. |
| rs/ethereum/cketh/minter/BUILD.bazel | Wires allowlists into both prod and debug ckETH minter builds. |
| rs/bitcoin/ckbtc/minter/hidden_endpoints.conf | Adds allowlist for ckBTC minter hidden/system exports. |
| rs/bitcoin/ckbtc/minter/hidden_endpoints_debug.conf | Adds debug-variant allowlist for self-check/debug-only endpoints. |
| rs/bitcoin/ckbtc/minter/BUILD.bazel | Wires allowlists into both prod and debug ckBTC minter builds. |
| rs/bitcoin/checker/hidden_endpoints.conf | Adds allowlist for BTC checker hidden/system exports (metrics, transform, lifecycle). |
| rs/bitcoin/checker/BUILD.bazel | Opts BTC checker canister into endpoint checking. |
| Cargo.Bazel.toml.lock | Updates locked Rust dependencies for the ic-wasm bump (incl. new transitive deps). |
| Cargo.Bazel.json.lock | Updates Bazel crate universe lock for the ic-wasm bump and new dependencies. |
| bazel/rust.MODULE.bazel | Enables ic-wasm check-endpoints feature and bumps the allowed ic-wasm version range. |
| bazel/canisters.bzl | Adds hidden_endpoints plumbing and optional check-endpoints genrule step. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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
Wraps the existing
ic-wasminvocation inbazel/canisters.bzl'sfinalize_wasmrule with an optionalcheck-endpointsstep, then opts the five DeFi-team canisters indfinity/icinto it. The check fails the build if a canister WASM exports a method that is neither in the candidservicedeclaration nor explicitly allowlisted in a per-canisterhidden_endpoints.conf— catching accidental public exports (a dropped#[query(hidden = true)], a leaked FFI symbol, etc.) before they ship.Mirrors the pattern in
dfinity/bitcoin-canister,dfinity/dogecoin-canister,dfinity/exchange-rate-canister, and the rest of the standalone DeFi-team repos.The five DEFI-2487 sub-tasks (ICP & ICRC1 ledgers, ckBTC minter, ckETH/ckERC20 minter, LSO, BTC checker) all close together when this lands.
Closes DEFI-2501.
Closes DEFI-2502.
Closes DEFI-2503.
Closes DEFI-2504.
Closes DEFI-2511.