Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 11 additions & 0 deletions docs/references/ic-interface-spec/abstract-behavior.md
Original file line number Diff line number Diff line change
Expand Up @@ -5711,6 +5711,10 @@ ic0.subnet_self_copy<es>(dst : I, offset : I, size : I) =
if es.context = s then Trap {cycles_used = es.cycles_used;}
copy_to_canister<es>(dst, offset, size, es.params.sysenv.subnet_id)

ic0.subnet_self_node_count<es>() : i32 =
if es.context = s then Trap {cycles_used = es.cycles_used;}
return es.params.sysenv.subnet_size

ic0.canister_cycle_balance<es>() : i64 =
if es.context = s then Trap {cycles_used = es.cycles_used;}
if es.balance >= 2^64 then Trap {cycles_used = es.cycles_used;}
Expand Down Expand Up @@ -5972,6 +5976,13 @@ I ∈ {i32, i64}
ic0.cost_http_request<es>(request_size: i64, max_res_bytes: i64, dst: I) : () =
copy_cycles_to_canister<es>(dst, arbitrary())

I ∈ {i32, i64}
ic0.cost_http_request_v2<es>(params_src : I, params_size : I, dst : I) : ()=
params = copy_from_canister<es>(params_src, params_size)
if params is not a valid Candid encoding of an HTTP outcall cost parameter record then
Trap {cycles_used = es.cycles_used;}
copy_cycles_to_canister<es>(dst, arbitrary())

I ∈ {i32, i64}
ic0.cost_sign_with_ecdsa<es>(src: I, size: I, ecdsa_curve: i32, dst: I) : i32 =
known_keys = arbitrary()
Expand Down
61 changes: 58 additions & 3 deletions docs/references/ic-interface-spec/canister-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ The 32-bit stable memory System API (`ic0.stable_size`, `ic0.stable_grow`, `ic0.

:::

:::note

The `ic0.cost_http_request` System API call is DEPRECATED. Canister developers are advised to use the `ic0.cost_http_request_v2` call instead.

:::

The following sections describe various System API functions, also referred to as system calls, which we summarize here.

All the following functions belong to the `ic0` module (denoted by the prefix `ic0.`).
Expand Down Expand Up @@ -261,6 +267,7 @@ defaulting to `I = i32` if the canister declares no memory.

ic0.subnet_self_size : () -> I; // *
ic0.subnet_self_copy : (dst : I, offset : I, size : I) -> (); // *
ic0.subnet_self_node_count : () -> i32; // *

ic0.msg_method_name_size : () -> I; // F
ic0.msg_method_name_copy : (dst : I, offset : I, size : I) -> (); // F
Expand Down Expand Up @@ -303,6 +310,7 @@ defaulting to `I = i32` if the canister declares no memory.
ic0.cost_call : (method_name_size: i64, payload_size : i64, dst : I) -> (); // * s
ic0.cost_create_canister : (dst : I) -> (); // * s
ic0.cost_http_request : (request_size : i64, max_res_bytes : i64, dst : I) -> (); // * s
ic0.cost_http_request_v2 : (params_src : I, params_size : I, dst : I) -> (); // * s
ic0.cost_sign_with_ecdsa : (src : I, size : I, ecdsa_curve: i32, dst : I) -> i32; // * s
ic0.cost_sign_with_schnorr : (src : I, size : I, algorithm: i32, dst : I) -> i32; // * s
ic0.cost_vetkd_derive_key : (src : I, size : I, vetkd_curve: i32, dst : I) -> i32; // * s
Expand Down Expand Up @@ -505,9 +513,9 @@ A canister can learn about its own identity:

A canister can learn about the subnet it is running on:

- `ic0.subnet_self_size : () → I` and `ic0.subnet_self_copy: (dst : I, offset : I, size : I) → ()`; `I ∈ {i32, i64}`
- `ic0.subnet_self_size : () → I`, `ic0.subnet_self_copy: (dst : I, offset : I, size : I) → ()`; `I ∈ {i32, i64}`, and `ic0.subnet_self_node_count : () -> i32`

These functions allow the canister to query the subnet id (as a blob) of the subnet on which the canister is running.
These functions allow the canister to query the subnet id (as a blob) of the subnet on which the canister is running, and to retrieve the number of nodes that are currently on the subnet.

### Canister status {#system-api-canister-status}

Expand Down Expand Up @@ -912,14 +920,61 @@ These system calls return costs in Cycles, represented by 128 bits, which will b

- `ic0.cost_http_request(request_size : i64, max_res_bytes : i64, dst : I) -> ()`; `I ∈ {i32, i64}`

The cost of a canister http outcall via [`http_request`](./management-canister.md#ic-http_request). `request_size` is the sum of the byte lengths of the following components of an http request:
:::note

The `ic0.cost_http_request` System API call is DEPRECATED. Canister developers are advised to use the `ic0.cost_http_request_v2` call instead.

:::

The cost of a canister HTTP outcall via [`http_request`](./management-canister.md#ic-http_request) with the pricing version set to `1` (currently the default). `request_size` is the sum of the byte lengths of the following components of an http request:
- url
- headers - i.e., the sum of the lengths of all keys and values
- body
- transform - i.e., the sum of the transform method name length and the length of the transform context

`max_res_bytes` is the maximum response length the caller wishes to accept (the caller should provide the default value of `2,000,000` if no maximum response length is provided in the actual request to the management canister).

- `ic0.cost_http_request_v2(params_src: I, params_size: I, dst : I) -> (); I ∈ {i32, i64}`

The cost of a canister HTTP outcall, either via [`http_request`](./management-canister.md#ic-http_request) with the pricing version set to `2`, or via [`flexible_http_request`](./management-canister.md#ic-flexible_http_request), which takes no pricing version argument and is priced this way. The blob described by `params_src` and `params_size` must be a valid Candid encoding of a value of the following type:
```
record {
request_bytes : nat64;
http_roundtrip_time_ms : nat64;
raw_response_bytes : nat64;
transformed_response_bytes : nat64;
transform_instructions: nat64;
outcall_type : opt variant {
fully_replicated: reserved;
non_replicated: reserved;
flexible: opt record {
min_responses: nat32;
max_responses: nat32;
total_requests: nat32;
}
}
}
```

The function traps if `params_src` and `params_size` do not describe a valid Candid encoding of a value of the above type. Beyond that type, decoding may skip only a very small, fixed amount of data, so the payload of the `fully_replicated` and `non_replicated` variants must be encoded as `null` and the encoding must not carry record fields other than the ones above; an encoding that violates either of these may trap. Similarly, the function also traps if the given blob is too large.

The function returns the amount of cycles to attach to an HTTP outcall in which every participating node consumes exactly the amount of resources specified by the individual fields. Part of this amount is a _reservation_ rather than a charge: every node the outcall is assigned to is assumed to attempt it, and enough is reserved to fund whichever result ends up being delivered, including a reject delivered in place of the response that was asked for. Whatever is not spent is refunded (see [`http_request`](./management-canister.md#ic-http_request)), so the actual cost of such an outcall may be less than this system call predicts, but assuming parameters are accurate, it cannot be more. The individual fields are:
- `request_bytes` is the sum of the byte lengths of the following components of an HTTP request:
- `url`
- `headers` - i.e., the sum of the lengths of all keys and values
- `body`
- `transform` - i.e., the sum of the transform method name length and the length of the transform context.

- `http_roundtrip_time_ms` is the amount of time between the time when the HTTP request starts being sent to the remote server and the time that the HTTP response is fully received (in milliseconds).

- `raw_response_bytes` is the length of the HTTP response.

- `transformed_response_bytes` is the length of the HTTP response after transformation.

- `transform_instructions` is the number of instructions the transform function takes.

- `outcall_type` is the type of HTTP outcall issued: a fully replicated call (made through the `http_request` endpoint with `is_replicated` set to `null` or `opt true`), non-replicated (made through `http_request` with `is_replicated` set to `opt false`), or flexible (made through the [`flexible_http_request`](./management-canister.md#ic-flexible_http_request) endpoint). If `outcall_type` is absent, the cost of a fully replicated call is returned. When the `flexible` outcall variant is selected, it can optionally be supplemented with the `min_responses`, `max_responses`, and `total_requests` parameters provided to the endpoint; if that record is omitted, the endpoint's own defaults of `floor(2 / 3 * N) + 1`, `N` and `N` are used, where `N` is the number of the nodes on the caller's subnet. Unlike the endpoint, this System API call does not validate the counts: a combination that `flexible_http_request` would reject simply yields a price that no outcall will ever be charged.

- `ic0.cost_sign_with_ecdsa(src : I, size : I, ecdsa_curve: i32, dst : I) -> i32`; `I ∈ {i32, i64}`

- `ic0.cost_sign_with_schnorr(src : I, size : I, algorithm: i32, dst : I) -> i32`; `I ∈ {i32, i64}`
Expand Down
Loading
Loading