Skip to content

Commit e9e76f7

Browse files
lwshangclaude
andauthored
chore: release 0.49.0 — ic-management-canister-types 0.8.0, query-default reads, list_canisters (#737)
* feat: bump ic-management-canister-types to 0.8.0 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> * feat: add list_canisters + bump pocket-ic to 15.0.0 for ref-tests 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> * feat(ic-utils): default canister_status/canister_metrics to query calls `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> * feat(ic-utils): add with_canister_settings to create/update builders `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> * chore: fmt * docs: changelog v0.49.0 * docs: note MgmtMethod new variants as a breaking change Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(ic-utils): inline settings resolution instead of &mut self helper 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> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3ac041c commit e9e76f7

11 files changed

Lines changed: 674 additions & 243 deletions

File tree

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## Unreleased
1010

11+
## [0.49.0] - 2026-07-13
12+
13+
* `ic-utils`: Bump `ic-management-canister-types` to 0.8.0.
14+
* Added `with_snapshot_visibility` setter to `CreateCanisterBuilder` and `UpdateSettingsBuilder`.
15+
* Added `canister_metrics()` to `ManagementCanister`.
16+
* Added `list_canisters()` method to `ManagementCanister`. This is a subnet-scoped, query-only management-canister method (callable only by subnet administrators); the request is routed to the subnet-scoped query endpoint via `Agent::query_signed` with an `EffectiveId::Subnet`.
17+
* Re-exported new types: `SnapshotVisibility`, `CanisterIdRange`, `ListCanistersResult`, `CyclesConsumed`, `CanisterMetricsArgs`, `CanisterMetricsResult`.
18+
* `ic-utils`: Added `with_canister_settings(CanisterSettings)` to `CreateCanisterBuilder` and `UpdateSettingsBuilder`, for callers that already hold a fully built `CanisterSettings` (e.g. decoded from config or forwarded from another call). It is currently mutually exclusive with the individual settings setters (`with_controller`, `with_compute_allocation`, …); building the call returns an error if the two are combined.
19+
* `ic-utils`: `ManagementCanister::canister_status` and `canister_metrics` now default to a cheap, non-replicated **query** call and return a `QueryOrUpdateCall` builder. Call `.call().await` for the query, or `.as_update().call().await` to issue a replicated update call instead (e.g. when a fully certified result is required). Query responses are replica-signed and verified by the agent unless query-signature verification is disabled. These are the only two management read methods the replica accepts as both query and update; `fetch_canister_logs` and `list_canisters` remain query-only per the interface spec.
20+
21+
### Breaking Changes
22+
23+
* `ic-utils`: The re-exported `CanisterSettings` and `DefiniteCanisterSettings` structs (from `ic-management-canister-types` 0.8.0) gained a `snapshot_visibility` field, controlling who may read a canister's snapshots. Neither struct is `#[non_exhaustive]`, so code that constructs them with a struct literal must add the new field (`snapshot_visibility: None` on `CanisterSettings`, or the desired `SnapshotVisibility`).
24+
* `ic-utils`: `ManagementCanister::canister_status` no longer returns an `impl AsyncCall` and no longer performs a replicated update call by default. It now returns a `QueryOrUpdateCall` that defaults to a query call.
25+
* Migration: replace `canister_status(&id).call_and_wait().await` with `canister_status(&id).call().await` to accept the (cheaper) query, or `canister_status(&id).as_update().call().await` to preserve the previous replicated-update behavior.
26+
* `ic-utils`: The `MgmtMethod` enum gained `CanisterMetrics` and `ListCanisters` variants. `MgmtMethod` is not `#[non_exhaustive]`, so exhaustive `match` expressions over it must add arms for the new variants.
27+
1128
## [0.48.1] - 2026-07-07
1229

1330
* `ic-transport-types`: `Delegation`, `SignedDelegation`, and `DelegationPermissions` now derive `candid::CandidType`, so they can be used directly in Candid interfaces (e.g. matching Internet Identity's `Delegation`/`SignedDelegation` types). The generated Candid maps the byte fields to `blob` and `DelegationPermissions` to `variant { queries; all }`; the added `permissions` field is `opt`, so the encoding stays subtype-compatible with delegation interfaces that omit it.

Cargo.lock

Lines changed: 54 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ members = [
1313
]
1414

1515
[workspace.package]
16-
version = "0.48.1"
16+
version = "0.49.0"
1717
authors = ["DFINITY Stiftung <sdk@dfinity.org>"]
1818
edition = "2021"
1919
repository = "https://github.com/dfinity/agent-rs"
@@ -30,10 +30,10 @@ license = "Apache-2.0"
3030
# a comment listing those crates). Otherwise, features are declared in the individual crate Cargo.toml.
3131
#
3232
# The path dependencies below ensure all workspace members use the same version of internal crates.
33-
ic-agent = { path = "ic-agent", version = "0.48.1", default-features = false }
34-
ic-identity-hsm = { path = "ic-identity-hsm", version = "0.48.1" }
35-
ic-transport-types = { path = "ic-transport-types", version = "0.48.1" }
36-
ic-utils = { path = "ic-utils", version = "0.48.1" }
33+
ic-agent = { path = "ic-agent", version = "0.49.0", default-features = false }
34+
ic-identity-hsm = { path = "ic-identity-hsm", version = "0.49.0" }
35+
ic-transport-types = { path = "ic-transport-types", version = "0.49.0" }
36+
ic-utils = { path = "ic-utils", version = "0.49.0" }
3737
ic-utils-bindgen = { path = "ic-utils-bindgen" }
3838
ref-tests = { path = "ref-tests" }
3939

@@ -64,7 +64,7 @@ http-body-util = "0.1.3"
6464
humantime = "2.0.1"
6565
ic-certification = "3"
6666
ic-ed25519 = "0.6.0"
67-
ic-management-canister-types = "0.7.1"
67+
ic-management-canister-types = "0.8.0"
6868
ic_principal = { version = "0.1.2", features = ["rangemap"] }
6969
ic-verify-bls-signature = "0.6"
7070
js-sys = "0.3"
@@ -83,7 +83,7 @@ pkcs8 = "0.10.2"
8383
# crates.io — crates.io rejects packages with git dependencies. Published
8484
# crates that need pocket-ic must depend on a released version directly (see
8585
# icx/Cargo.toml).
86-
pocket-ic = { git = "https://github.com/dfinity/ic", rev = "17524c56ef237c54b510a201ceb58da8d790d4d5" } # https://github.com/dfinity/ic/pull/10226
86+
pocket-ic = { git = "https://github.com/dfinity/ic", rev = "992628c4f26cc7320396b6b8be37133a666a4386" } # release-2026-07-09_04-35-base
8787
rand = "0.10.1"
8888
rangemap = "1.7"
8989
reqwest = { version = "0.13.2", default-features = false }

ic-utils/src/canister.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,6 @@ impl<'agent: 'canister, 'canister> AsyncCallBuilder<'agent, 'canister> {
387387
#[cfg(all(test, unix))] // pocket-ic
388388
mod tests {
389389
use super::*;
390-
use crate::call::AsyncCall;
391390
use crate::interfaces::ManagementCanister;
392391

393392
#[tokio::test]
@@ -411,7 +410,7 @@ mod tests {
411410

412411
let (status,) = management_canister
413412
.canister_status(&new_canister_id)
414-
.call_and_wait()
413+
.call()
415414
.await
416415
.unwrap();
417416

0 commit comments

Comments
 (0)