Skip to content

feat: new canister settings minimum_msg_cycles_available#10398

Draft
mraszyk wants to merge 15 commits into
masterfrom
mraszyk/minimum-msg-cycles-available
Draft

feat: new canister settings minimum_msg_cycles_available#10398
mraszyk wants to merge 15 commits into
masterfrom
mraszyk/minimum-msg-cycles-available

Conversation

@mraszyk

@mraszyk mraszyk commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

This PR introduces a new canister setting minimum_msg_cycles_available specifying the minimum amount of cycles that must be available as transferred cycles in an incoming inter-canister call (i.e., ignoring ingress messages).

@github-actions github-actions Bot added the feat label Jun 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 adds a new canister setting, minimum_msg_cycles_available, to enforce a minimum attached-cycles threshold on incoming inter-canister requests (ingress unaffected), and wires it through the management canister types, replica execution, and checkpoint persistence.

Changes:

  • Extends management canister Candid/Rust types and builders to include minimum_msg_cycles_available.
  • Enforces the minimum in replicated execution for incoming inter-canister Requests, rejecting and refunding when insufficient cycles are attached.
  • Persists the setting in canister state (checkpoint/protobuf) and adds execution environment tests covering status/defaulting and admission behavior.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
rs/types/management_canister_types/tests/ic.did Adds the setting to canister_settings / definite_canister_settings DID test definitions.
rs/types/management_canister_types/src/lib.rs Adds field + builder/getter plumbing for minimum_msg_cycles_available in management types.
rs/state_manager/src/tip.rs Serializes minimum_msg_cycles_available into checkpoint canister state bits.
rs/state_manager/src/checkpoint.rs Loads minimum_msg_cycles_available from checkpoint into system state.
rs/state_layout/src/state_layout.rs Adds minimum_msg_cycles_available to CanisterStateBits.
rs/state_layout/src/state_layout/proto.rs Adds protobuf (de)serialization for the new state bit (with backward-compatible default).
rs/state_layout/src/state_layout/tests.rs Updates default CanisterStateBits used in tests to include the new field.
rs/replicated_state/src/canister_state/system_state.rs Adds minimum_msg_cycles_available to SystemState and initializes it to zero.
rs/execution_environment/src/canister_settings.rs Parses/validates the new setting from CanisterSettingsArgs and adds an out-of-range error.
rs/execution_environment/src/canister_manager.rs Applies setting on update; exposes it via canister_status output.
rs/execution_environment/src/execution_environment.rs Enforces minimum cycles for incoming inter-canister requests (reject + refund).
rs/execution_environment/tests/canister_settings.rs Adds range validation and behavioral tests for the setting (status, ingress unaffected, accept/reject, DTS slicing).
rs/protobuf/def/state/canister_state_bits/v1/canister_state_bits.proto Adds protobuf field minimum_msg_cycles_available = 68.
rs/protobuf/src/gen/state/state.canister_state_bits.v1.rs Regenerates protobuf Rust bindings for the new field.
rs/replica_tests/tests/canister_lifecycle.rs Updates canister status expectations to include the new setting value.
rs/cycles_account_manager/src/cycles_account_manager.rs Bumps max payload size constant due to Candid arg size increase.
rs/pocket_ic_server/src/pocket_ic.rs Extends CanisterSettingsArgs literals to include the new field.
rs/nervous_system/clients/src/update_settings.rs Extends CanisterSettingsArgs conversion to include the new field (set to None).
packages/ic-management-canister-types/tests/ic.did Updates public package DID test definitions with the new setting.
packages/ic-management-canister-types/src/lib.rs Documents and adds minimum_msg_cycles_available to the public types crate.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rs/execution_environment/tests/canister_settings.rs
Comment thread rs/execution_environment/tests/canister_settings.rs
Comment thread rs/execution_environment/src/execution_environment.rs
mraszyk and others added 4 commits June 5, 2026 15:44
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Comment thread rs/state_layout/src/state_layout/tests.rs
Comment thread rs/types/management_canister_types/src/lib.rs
mraszyk and others added 4 commits June 8, 2026 09:46
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Comment thread rs/cycles_account_manager/src/cycles_account_manager.rs
@mraszyk mraszyk marked this pull request as ready for review June 8, 2026 12:09
@mraszyk mraszyk requested review from a team as code owners June 8, 2026 12:09

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This pull request changes code owned by the Governance team. Therefore, make sure that
you have considered the following (for Governance-owned code):

  1. Update unreleased_changelog.md (if there are behavior changes, even if they are
    non-breaking).

  2. Are there BREAKING changes?

  3. Is a data migration needed?

  4. Security review?

How to Satisfy This Automatic Review

  1. Go to the bottom of the pull request page.

  2. Look for where it says this bot is requesting changes.

  3. Click the three dots to the right.

  4. Select "Dismiss review".

  5. In the text entry box, respond to each of the numbered items in the previous
    section, declare one of the following:

  • Done.

  • $REASON_WHY_NO_NEED. E.g. for unreleased_changelog.md, "No
    canister behavior changes.", or for item 2, "Existing APIs
    behave as before.".

Brief Guide to "Externally Visible" Changes

"Externally visible behavior change" is very often due to some NEW canister API.

Changes to EXISTING APIs are more likely to be "breaking".

If these changes are breaking, make sure that clients know how to migrate, how to
maintain their continuity of operations.

If your changes are behind a feature flag, then, do NOT add entrie(s) to
unreleased_changelog.md in this PR! But rather, add entrie(s) later, in the PR
that enables these changes in production.

Reference(s)

For a more comprehensive checklist, see here.

GOVERNANCE_CHECKLIST_REMINDER_DEDUP

@mraszyk mraszyk dismissed github-actions[bot]’s stale review June 8, 2026 13:31

No canister behavior changes.

@alin-at-dfinity alin-at-dfinity left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Dropping this one comment early. In case you agree with it, it will require a lot of renaming and it's probably best to get it out of the way.

pub environment_variables: Option<Vec<EnvironmentVariable>>,
/// Indicates the minimum number of cycles required for an incoming message
/// from another canister. Messages with fewer cycles are rejected with a
/// `CanisterError`. Ingress messages are not affected.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ingress messages are not affected.

I was thinking this kind of defeats the purpose. Took me a while to realize that there's [whatever the single-replica ingress message filtering mechanism is called]. Maybe mention that, just in case someone is looking at the implementation, trying to figure out how to deal with call spam.

///
/// Default value: `0` (i.e., no minimum enforced).
pub minimum_msg_cycles_available: Option<Nat>,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When I first read the name I thought this was some sort of freezing threshold for cycles reserved for outgoing calls. Maybe we should call it something like "minimum [call] payment"? Or, if you think "pauyment" is only used in the implementation, not the spec, and is thus potentially confusing, then "attached cycles"?

"Available" sounds too much like "balance" or "reservation".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The motivation for this name was the system API ic0.msg_cycles_available which returns how many cycles have been transferred by the caller (and not yet accepted by the callee) so the new setting is a lower bound for the value of that system API at the very beginning of the call.

But I see your confusion: how does minimum_incoming_call_cycles or minimum_canister_call_cycles sound? (Focus on either incoming/outgoing and ingress/inter-canister, respectively, the combined minimum_incoming_canister_call_cycles is the most precise, but pretty long.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

minimum_canister_call_cycles sounds more obvious.

I understand now where it comes from, but I suppose msg_cycles_available is both somewhat more specific and somewhat unfortunate too. (o:

@mraszyk mraszyk marked this pull request as draft June 9, 2026 14:43

@alin-at-dfinity alin-at-dfinity left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Only one more nitpick, otherwise LGTM.

wasm_memory_limit: candid::Nat,
wasm_memory_threshold: candid::Nat,
environment_variables: Vec<EnvironmentVariable>,
minimum_msg_cycles_available: candid::Nat,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Personal opinion: I would put this somewhere next to the other fields that have to do with cycles, rather than tack it onto the end. Same with SystemState / CanisterStateBits / CanisterStateBits proto.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants