chore: release 0.49.0 — ic-management-canister-types 0.8.0, query-default reads, list_canisters - #737
Merged
Merged
Conversation
Bump `ic-management-canister-types` 0.7.1 -> 0.8.0 and adjust ic-utils for the new types/fields: - `CanisterSettings`/`DefiniteCanisterSettings` gained a `snapshot_visibility` field; add `with_snapshot_visibility` to `CreateCanisterBuilder` and `UpdateSettingsBuilder` and thread it through every settings literal. - Add `ManagementCanister::canister_metrics()` (ingress-callable per the IC interface spec) plus the `MgmtMethod::CanisterMetrics` variant. - Re-export the new types: `SnapshotVisibility`, `CanisterIdRange`, `ListCanistersResult`, `CyclesConsumed`, `CanisterMetricsArgs`, `CanisterMetricsResult`. Bump all workspace crates 0.48.1 -> 0.49.0 (the re-exported settings structs are not `#[non_exhaustive]`, so the new field is a breaking change). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add `ManagementCanister::list_canisters`, the subnet-scoped, query-only management-canister method. Per the IC interface spec it may only be called by subnet administrators via non-replicated queries, so it is signed and routed to the subnet-scoped `/api/v3/subnet/<id>/query` endpoint via `Agent::query_signed(EffectiveId::Subnet(_), _)` — reusing the existing agent mechanism rather than adding a `QueryBuilder::with_effective_subnet_id`, keeping update/query API symmetry (there is no `UpdateBuilder::with_effective_subnet_id` either). Adds the `MgmtMethod::ListCanisters` variant and an `icx` arm that bails, since it can't be routed by effective canister id. Bump the ref-tests pocket-ic git rev to release-2026-07-09_04-35-base (pocket-ic 13.0.0 -> 15.0.0) and the `icx` crates.io pin to 15.0.0 to keep the major version in sync. Re-tune `provisional_create_canister_with_cycles` for pocket-ic 15's stricter memory reserved-cycles floor. Add (non-ignored) ref-tests for `canister_metrics` and `list_canisters`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`ManagementCanister::canister_status` and `canister_metrics` are the only two management read methods the replica accepts as both a query and an update. They now return a `QueryOrUpdateCall` builder that issues a cheap, non-replicated query by default (`.call().await`), with `.as_update().call().await` to opt into a replicated, certified update call. Query responses are replica-signed and verified by the agent unless verification is disabled, which addresses the "single replica" trust caveat for callers that don't need full replication. `fetch_canister_logs` and `list_canisters` stay query-only (the interface spec forbids replicated calls), so they don't get the update toggle. BREAKING: `canister_status` previously returned `impl AsyncCall` and performed a replicated update. Callers migrate `.call_and_wait().await` to `.call().await` (query) or `.as_update().call().await` (previous behavior). The `provisional_create_canister_with_cycles` ref-test uses `.as_update()` for its cycle-balance reads, which need a certified read at a definite round rather than a query whose auto-advancing timestamp reflects extra idle burn. The `canister_metrics` ref-test exercises both call styles. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`CreateCanisterBuilder` and `UpdateSettingsBuilder` can now accept a fully built `CanisterSettings` via `with_canister_settings(...)`, for callers that already hold one (decoded from config, forwarded from another call, etc.) instead of decomposing it into individual `with_*` setters. This lets downstream code (e.g. icp-cli's create_mgmt) route a ready-made settings struct through the builder — combined with `with_effective_subnet_id`, that replaces a hand-rolled management-canister update call. The whole-struct setter is currently mutually exclusive with the individual settings setters: `build()`/`prepare()` returns an error if both are used. This keeps the semantics unambiguous; the restriction can be loosened later to a merge/override model without breaking callers. Both builders' settings resolution is factored into a `resolve_settings` helper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Release prep for 0.49.0, updating workspace versions and extending ic-utils’ management-canister interface to match ic-management-canister-types 0.8.0 (new settings/type fields, new methods, and query-default reads).
Changes:
- Bump workspace + dependency versions (notably
ic-management-canister-types→0.8.0, pocket-ic pins, and crate versions →0.49.0). - Extend
ic-utilsmanagement canister support:snapshot_visibilitysettings,canister_metrics,list_canisters, andQueryOrUpdateCall(query-by-default) for reads. - Update ref-tests to cover new functionality and adapt existing tests to the query-default
canister_statusbehavior.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| ref-tests/tests/integration.rs | Adjust struct literal to include new snapshot_visibility field. |
| ref-tests/tests/ic-ref.rs | Migrate canister_status calls to query-default .call(), add .as_update() where certification is needed, add new tests for metrics/list_canisters/settings API. |
| icx/src/main.rs | Add routing/argument handling for CanisterMetrics; explicitly reject unsupported subnet-scoped ListCanisters. |
| icx/Cargo.toml | Bump crates.io pocket-ic pin to 15.0.0. |
| ic-utils/src/interfaces/wallet.rs | Update wallet create args to include snapshot_visibility. |
| ic-utils/src/interfaces/management_canister/builders.rs | Add snapshot_visibility + whole-struct with_canister_settings, and factor settings construction via resolve_settings. |
| ic-utils/src/interfaces/management_canister.rs | Add re-exports/types, new management methods, and introduce QueryOrUpdateCall + subnet-scoped list_canisters query routing. |
| ic-utils/src/canister.rs | Update canister-status test to use query-default .call(). |
| CHANGELOG.md | Add 0.49.0 release notes and breaking-change guidance. |
| Cargo.toml | Bump workspace version to 0.49.0, update dependency pins (including ic-management-canister-types and pocket-ic git rev). |
| Cargo.lock | Lockfile updates for the version bumps (candid, pocket-ic, workspace crates, etc.). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
lwshang
marked this pull request as ready for review
July 13, 2026 17:38
|
✅ No security or compliance issues detected. Reviewed everything up to 0553f32. Security Overview
Detected Code Changes
|
…elper Address review feedback: the `resolve_settings(&mut self)` helper cleared the builder's settings via `.take()`, gutting the receiver — an undocumented footgun, even though `prepare()`/`build()` owned and immediately dropped `self`. Inline the resolution into `prepare()` (create) and `build()` (update) instead, so `self` is consumed naturally by value with no `&mut`/`take`. The shared mutual-exclusivity error message is factored into a small `reject_mixed_settings` helper to avoid duplicating the string. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
adamspofford
approved these changes
Jul 13, 2026
lwshang
enabled auto-merge (squash)
July 13, 2026 18:02
lwshang
added a commit
to dfinity/icp-cli
that referenced
this pull request
Jul 23, 2026
* refactor: adopt ic-utils with_canister_settings in create_mgmt Bump the agent-rs crates (ic-agent, ic-utils, ic-identity-hsm) to 0.49.1 and ic-management-canister-types to 0.8.0 so create_mgmt can use the new CreateCanisterBuilder API from dfinity/agent-rs#737. create_mgmt now builds the call via ManagementCanister::create_canister().with_canister_settings(...), and routes to the target subnet with with_effective_subnet_id(subnet) instead of resolving a canister id from the subnet's ranges. This drops the manual Encode!/update/Decode! dance and the canister-range lookup; the function now takes the subnet Principal directly. Validated end-to-end by the canister_create_cloud_engine integration test. Also handle the breaking changes the bump introduces: - CanisterSettings/DefiniteCanisterSettings gained snapshot_visibility; add it to the two exhaustive settings literals (left None with a TODO to make it configurable like log_visibility in a follow-up PR). - ic_agent::identity::Delegation gained permissions; add permissions: None to the three literal constructions. - ManagementCanister::canister_status now returns QueryOrUpdateCall; use .call() in the canister top-up test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: explain why imported delegations use permissions: None The wire DelegationChain from the cli-backend canister has no permissions field and the CLI only ever signs unrestricted delegations, so every delegation reconstructed here was signed with permissions absent. Because the field is skip_serializing_if'd out of the signable hash when None, reproducing it as None yields the exact signed bytes and the chain still verifies in DelegatedIdentity::new. Documents this to preempt the concern that None drops a signed field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (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.
Release 0.49.0. Bumps
ic-management-canister-types0.7.1 → 0.8.0 and builds on the new types/methods, plus a couple of relatedic-utilsergonomics. All workspace crates go 0.48.1 → 0.49.0.ic-utils— management canisteric-management-canister-types0.8.0. Picks up thesnapshot_visibilitycanister setting and thelist_canisters/canister_metricstypes.with_snapshot_visibilitysetter onCreateCanisterBuilderandUpdateSettingsBuilder.SnapshotVisibility,CanisterIdRange,ListCanistersResult,CyclesConsumed,CanisterMetricsArgs,CanisterMetricsResult.canister_metrics()— newManagementCanisterread.list_canisters()— subnet-scoped, query-only management method (subnet-administrators only per the interface spec). Routed to the subnet-scoped query endpoint viaAgent::query_signedwithEffectiveId::Subnet— reusing the existing agent mechanism rather than adding aQueryBuilder::with_effective_subnet_id, keeping update/query API symmetry.canister_statusandcanister_metrics— the only two management reads the replica accepts as both query and update — now return aQueryOrUpdateCallthat issues a cheap, non-replicated query by default (.call().await), with.as_update().call().awaitto opt into a replicated, certified call. Query responses are replica-signed and verified by the agent unless verification is disabled.fetch_canister_logsandlist_canistersstay query-only per spec.with_canister_settings(CanisterSettings)onCreateCanisterBuilderandUpdateSettingsBuilder, for callers that already hold a full settings struct (e.g. forwarding one, as icp-cli'screate_mgmtdoes). Currently mutually exclusive with the individualwith_*setters (building errors if combined); can be loosened to a merge model later without breaking callers.Breaking changes
CanisterSettings/DefiniteCanisterSettingsgained asnapshot_visibilityfield; neither is#[non_exhaustive], so struct-literal construction must add it.canister_statusnow returnsQueryOrUpdateCall(query by default) instead ofimpl AsyncCall(replicated update). Migrate.call_and_wait().await→.call().await, or.as_update().call().awaitto keep the old behavior.MgmtMethodgainedCanisterMetricsandListCanistersvariants; it is not#[non_exhaustive], so exhaustive matches must add arms.See CHANGELOG.md for the full list.
Testing / infra
pocket-icgit rev torelease-2026-07-09_04-35-base(pocket-ic 13.0.0 → 15.0.0) and theicxcrates.io pin to 15.0.0 to keep the major in sync. Re-tunedprovisional_create_canister_with_cyclesfor pocket-ic 15's stricter memory reserved-cycles floor.canister_metrics,list_canisters(subnet-admin harness), andwith_canister_settings(happy path + mutual-exclusion error). Thecanister_metricstest exercises both the query and.as_update()paths.clippy --all-targetsandfmt --checkclean.🤖 Generated with Claude Code