Skip to content

Conversation

@oggy-dfin
Copy link
Member

@oggy-dfin oggy-dfin commented Nov 6, 2025

Adjusts the Rust tutorial and the inter-canister calls reference doc to reflect the state after anonymous cycle refunds for bounded-wait calls are merged on the mainnet.
DO NOT MERGE until that happens.

The corresponding examples repo PR should be merged first, also one should check that the permalinks for the code snippets still work (I don't know what happens when the pull request branch is deleted)

@github-actions github-actions bot added the documentation Changes to Developer Docs label Nov 6, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 6, 2025

🤖 Preview build failed.

A canister can attach [cycles](/docs/building-apps/getting-started/tokens-and-cycles) (Internet Computer "gas") to any call that they make, transferring cycles from the caller's to the callee's cycle balance. The callee must explicitly [accept](https://docs.rs/ic-cdk/latest/ic_cdk/api/call/fn.msg_cycles_accept128.html) such cycles; non-accepted cycles are refunded to the caller.
Cycle transfers are generally either used to pay for the callee's costs of processing the call or to move and store cycles as assets. An example where they are used to pay for call processing costs is the IC [threshold signature feature](/docs/building-apps/network-features/signatures/t-ecdsa), which allows a canister to hold a cryptographic key and sign messages with it. An example of cycles being used as assets is the [cycles ledger](/docs/defi/token-ledgers/cycles-ledger/).
Moreover, the management canister provides a special method called `deposit_cycles`, which takes a target canister as a parameter. When called, `deposit_cycles` simply accepts all the attached cycles and deposits them to the target canister's balance.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: A "parameter" is a part of the function's signature (e.g. target: CanisterId); the value passed in a function call is an "argument". I believe the latter is more appropriate here, as this description is from the point of view of the dev / client.

Suggested change
Moreover, the management canister provides a special method called `deposit_cycles`, which takes a target canister as a parameter. When called, `deposit_cycles` simply accepts all the attached cycles and deposits them to the target canister's balance.
Moreover, the management canister provides a special method called `deposit_cycles`, which takes a target canister as an argument. When called, `deposit_cycles` simply accepts all the attached cycles and deposits them to the target canister's balance.

```
Cycles can be attached to both bounded and unbounded wait messages. For unbounded wait messages, cycles that are not consumed by the callee are guaranteed to be refunded to the caller. As the example notes, refunds do not happen for bounded-wait calls that result in an error with the `SysUnknown` reject code, which is the code issued when the system decides to stop waiting for a response.
The balances you see will obviously differ. As you see, here the counter's balance has increased by a little less than 2 billion; the difference is used up by the running costs of the counter, which are continually charged while the canister is active.
Copy link
Contributor

Choose a reason for hiding this comment

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

"counter canister"?

Suggested change
The balances you see will obviously differ. As you see, here the counter's balance has increased by a little less than 2 billion; the difference is used up by the running costs of the counter, which are continually charged while the canister is active.
The balances you see will obviously differ. As you see, here the counter's balance has increased by a little less than 2 billion; the difference is used up by the running costs of the counter canister, which are continually charged while the canister is active.

:::info
To summarize, you can transfer cycles to the callee by attaching them to a bounded- or unbounded-wait call. Bounded-wait calls may drop the attached cycles, so avoid using them for large cycle amounts.
:::
In general, bounded-wait calls are sufficient and recommended for cycle deposits. However, since there isn't a bulletproof way to check whether `deposit_cycles` succeeded or not in case of a `SYS_UNKNOWN`, applications which need to do error handling on `deposit_cycles` calls (for examples, DEXes which trade wrapped cycles) may want to use unbounded-wait calls instead.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: "which" -> "that"

Suggested change
In general, bounded-wait calls are sufficient and recommended for cycle deposits. However, since there isn't a bulletproof way to check whether `deposit_cycles` succeeded or not in case of a `SYS_UNKNOWN`, applications which need to do error handling on `deposit_cycles` calls (for examples, DEXes which trade wrapped cycles) may want to use unbounded-wait calls instead.
In general, bounded-wait calls are sufficient and recommended for cycle deposits. However, since there isn't a bulletproof way to check whether `deposit_cycles` succeeded or not in case of a `SYS_UNKNOWN`, applications that need to do error handling on `deposit_cycles` calls (for examples, DEXes that trade wrapped cycles) may want to use unbounded-wait calls instead.

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

Labels

documentation Changes to Developer Docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants