Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tidy up inter-canister calls #3881

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/references/ic-interface-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -1110,9 +1110,9 @@ hash_of_map({ request_type: "call", sender: 0x04, ingress_expiry: 16855704000000

### Reject codes {#reject-codes}

An API request or inter-canister call that is pending in the IC will eventually result in either a *reply* (indicating success, and carrying data) or a *reject* (indicating an error of some sorts). A reject contains a *rejection code* that classifies the error and a hopefully helpful *reject message* string.
An API request or inter-canister call that is pending in the IC will eventually result in either a *reply* (indicating success, and carrying data) or a *reject* (indicating an error of some sorts). A reject contains a *reject code* that classifies the error and a hopefully helpful *reject message* string.

Rejection codes are member of the following enumeration:
Reject codes are member of the following enumeration:

- `SYS_FATAL` (1): Fatal system error, retry unlikely to be useful.

Expand Down Expand Up @@ -1755,9 +1755,9 @@ There must be at most one call to `ic0.call_on_cleanup` between `ic0.call_new` a

This deducts `MAX_CYCLES_PER_RESPONSE` cycles from the canister balance and sets them aside for response processing.

If the function returns `0` as the `err_code`, the IC was able to enqueue the call. In this case, the call will either be delivered, returned because the destination canister does not exist, returned due to a lack of resources within the IC, or returned because of an out of cycles condition. This also means that exactly one of the reply or reject callbacks will be executed.
The returned `err_code` is always one of `0`, `1`, `2`, and `3`. An `err_code` of `0` means that no error occurred and that the IC could enqueue the call. In this case, the call will either be delivered, returned because the destination canister does not exist, returned due to a lack of resources within the IC, or returned because of an out of cycles condition. This also means that exactly one of the reply or reject callbacks will be executed.
Copy link
Contributor

Choose a reason for hiding this comment

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

The returned err_code is always one of 0, 1, 2, and 3.

Are we sure that the implementation does not start producing the new code 6 for "unknown" in some cases in the future?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well we obviously can never be sure that the implementation won't start ignoring the spec but I can't think of a reason why a synchronous error would be raised for unknown reasons.

Copy link
Member

Choose a reason for hiding this comment

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

Discussion in the interface spec meeting:

  • Currently there is inconsistent behavior in messages sent to the IC management canister, where in case of an invalid candid payload, the canister would trap. (Which is inconsistent with what happens if invalid candid is sent to another canister.)
  • For the same case for ingress messages, we would fail with a 4.
  • If we ever wanted to clean up this behavior, this would mean we would want to return a 4 synchronously.

Copy link
Contributor

Choose a reason for hiding this comment

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

Currently there is inconsistent behavior in messages sent to the IC management canister, where in case of an invalid candid payload, the canister would trap. (Which is inconsistent with what happens if invalid candid is sent to another canister.)

This hypothesis of mine doesn't hold: if an invalid candid payload is sent to the IC management canister, then an asynchronous reject with reject code 4 is produced.

Nevertheless, if we include the reject code 3 as a possible reject code for synchronous routing errors in the future, we might also need to include the reject code 4 for synchronous routing errors to the IC management canister due to invalid candid payload.


If the function returns a non-zero value, the call cannot (and will not be) performed. This can happen due to a lack of resources within the IC, but also if it would reduce the current cycle balance to a level below where the canister would be frozen.
Non-``0` values of `err_code` indicate that the call could not be performed, and the semantics of the values are the same as for [reject codes](#reject-codes) (i.e., the `err_code` `1` has the semantics of `SYS_FATAL`, `2` of `SYS_TRANSIENT`, and `3` of `DESTINATION_INVALID`). A non-`0` code could arise due to a lack of resources within the IC, but also if the call would reduce the current cycle balance to a level below where the canister would be frozen. No callbacks are executed in this case.
oggy-dfin marked this conversation as resolved.
Show resolved Hide resolved

After `ic0.call_perform` and before the next call to `ic0.call_new`, all other `ic0.call_*` function calls trap.

Expand Down
Loading