From 623521a2580afa4aa1800db41b54da2650792932 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Wed, 28 Jun 2023 13:20:15 +0000 Subject: [PATCH 01/23] feat: Add metrics about subnet usage on the state tree --- spec/index.md | 64 +++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/spec/index.md b/spec/index.md index 9b9457129..18955fde9 100644 --- a/spec/index.md +++ b/spec/index.md @@ -427,6 +427,10 @@ The state tree contains information about the topology of the Internet Computer. principal = bytes .size (0..29) tagged = #6.55799(t) ; the CBOR tag +- `/subnet//metrics` (blob) + + A list of subnet wide metrics related to this subnet's current usage and/or performance. It can be a CBOR encoded struct containing a set of metrics, like number of canisters on subnet, memory used by the subnet, cycles burned by the subnet etc. + :::note Because this uses the lexicographic ordering of princpials, and the byte distinguishing the various classes of ids is at the *end*, this range by construction conceptually includes principals of various classes. This specification needs to take care that the fact that principals that are not canisters may appear in these ranges does not cause confusion. @@ -497,17 +501,17 @@ Users have the ability to learn about the hash of the canister's module, its cur The concrete mechanism that users use to send requests to the Internet Computer is via an HTTPS API, which exposes three endpoints to handle interactions, plus one for diagnostics: -- At `/api/v2/canister//call` the user can submit (asynchronous, potentially state-changing) calls. +- At `/api/v2/canister//call` the user can submit (asynchronous, potentially state-changing) calls. -- At `/api/v2/canister//read_state` the user can read various information about the state of the Internet Computer. In particular, they can poll for the status of a call here. +- At `/api/v2/canister//read_state` the user can read various information about the state of the Internet Computer. In particular, they can poll for the status of a call here. -- At `/api/v2/canister//query` the user can perform (synchronous, non-state-changing) query calls. +- At `/api/v2/canister//query` the user can perform (synchronous, non-state-changing) query calls. - At `/api/v2/status` the user can retrieve status information about the Internet Computer. -In these paths, the `` is the [textual representation](#textual-ids) of the [*effective* canister id](#http-effective-canister-id). +In these paths, the `` is the [textual representation](#textual-ids) of the [*effective* canister id](#http-effective-canister-id). -Requests to `/api/v2/canister//call`, `/api/v2/canister//read_state` and `/api/v2/canister//query` are POST requests with a CBOR-encoded request body, which consists of a authentication envelope (as per [Authentication](#authentication)) and request-specific content as described below. +Requests to `/api/v2/canister//call`, `/api/v2/canister//read_state` and `/api/v2/canister//query` are POST requests with a CBOR-encoded request body, which consists of a authentication envelope (as per [Authentication](#authentication)) and request-specific content as described below. :::note @@ -578,7 +582,7 @@ When asking the IC about the state or call of a request, the user uses the reque ### Request: Call {#http-call} -In order to call a canister, the user makes a POST request to `/api/v2/canister//call`. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to call a canister, the user makes a POST request to `/api/v2/canister//call`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `call` @@ -616,7 +620,7 @@ The functionality exposed via the [The IC management canister](#ic-management-ca ### Request: Read state {#http-read-state} -In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state`. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `read_state` @@ -628,7 +632,7 @@ The HTTP response to this request consists of a CBOR (see [CBOR](#cbor)) map wit - `certificate` (`blob`): A certificate (see [Certification](#certification)). - If this `certificate` includes subnet delegations (possibly nested), then the `effective_canister_id` must be included in each delegation's canister id range (see [Delegation](#certification-delegation)). + If this `certificate` includes subnet delegations (possibly nested), then the `effective_principal_id` must be included in each delegation's canister id range (see [Delegation](#certification-delegation)). The returned certificate reveals all values whose path is a suffix of a requested path. It also always reveals `/time`, even if not explicitly requested. @@ -642,13 +646,13 @@ All requested paths must have one of the following paths as prefix: - the sender of the original request referenced by `` is the same as the sender of the read state request and - - the effective canister id of the original request referenced by `` matches ``. + - the effective principal id of the original request referenced by `` matches ``. -- `/canisters//module_hash`. Can be requested if `` matches ``. +- `/canisters//module_hash`. Can be requested if `` matches ``. -- `/canisters//controllers`. Can be requested if `` matches ``. The order of controllers in the value at this path may vary depending on the implementation. +- `/canisters//controllers`. Can be requested if `` matches ``. The order of controllers in the value at this path may vary depending on the implementation. -- `/canisters//metadata/`. Can be requested if `` matches ``, `` is encoded in UTF-8, and +- `/canisters//metadata/`. Can be requested if `` matches ``, `` is encoded in UTF-8, and - canister with canister id `` does not exist or @@ -672,7 +676,7 @@ See [The system state tree](#state-tree) for details on the state tree. A query call is a fast, but less secure way to call a canister. Only methods that are explicitly marked as "query methods" by the canister can be called this way. -In order to make a query call to canister, the user makes a POST request to `/api/v2/canister//query`. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to make a query call to canister, the user makes a POST request to `/api/v2/canister//query`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `query` @@ -702,29 +706,29 @@ If the call resulted in a reject, the response is a CBOR map with the following Canister methods that do not change the canister state can be executed more efficiently. This method provides that ability, and returns the canister's response directly within the HTTP response. -### Effective canister id {#http-effective-canister-id} +### effective principal id {#http-effective-canister-id} -The `` in the URL paths of requests is the *effective* destination of the request. +The `` in the URL paths of requests is the *effective* destination of the request. - If the request is an update call to the Management Canister (`aaaaa-aa`), then: - - If the call is to the `provisional_create_canister_with_cycles` method, then any principal can be used as the effective canister id for this call. + - If the call is to the `provisional_create_canister_with_cycles` method, then any principal can be used as the effective principal id for this call. - - Otherwise, if the `arg` is a Candid-encoded record with a `canister_id` field of type `principal`, then the effective canister id must be that principal. + - Otherwise, if the `arg` is a Candid-encoded record with a `canister_id` field of type `principal`, then the effective principal id must be that principal. - - Otherwise, the call is rejected by the system independently of the effective canister id. + - Otherwise, the call is rejected by the system independently of the effective principal id. -- If the request is an update call to a canister that is not the Management Canister (`aaaaa-aa`) or if the request is a query call, then the effective canister id must be the `canister_id` in the request. +- If the request is an update call to a canister that is not the Management Canister (`aaaaa-aa`) or if the request is a query call, then the effective principal id must be the `canister_id` in the request. :::note -The expectation is that user-side agent code shields users and developers from the notion of effective canister ID, in analogy to how the System API interface shields canister developers from worrying about routing. +The expectation is that user-side agent code shields users and developers from the notion of effective principal id, in analogy to how the System API interface shields canister developers from worrying about routing. -The Internet Computer blockchain mainnet rejects all requests whose effective canister id is in no subnet's canister ranges, independently of whether the remaining conditions on the effective canister id are satisfied. +The Internet Computer blockchain mainnet rejects all requests whose effective principal id is in no subnet's canister ranges, independently of whether the remaining conditions on the effective principal id are satisfied. -The Internet Computer blockchain mainnet does not support `provisional_create_canister_with_cycles` and thus all calls to this method are rejected independently of the effective canister id. +The Internet Computer blockchain mainnet does not support `provisional_create_canister_with_cycles` and thus all calls to this method are rejected independently of the effective principal id. -In development instances of the Internet Computer Protocol (e.g. testnets), the effective canister id of a request submitted to a node must be a canister id from the canister ranges of the subnet to which the node belongs. +In development instances of the Internet Computer Protocol (e.g. testnets), the effective principal id of a request submitted to a node must be a canister id from the canister ranges of the subnet to which the node belongs. ::: @@ -2818,13 +2822,13 @@ The following predicate describes when an envelope `E` correctly signs the enclo then { p : p is Principal } else D.senders -#### Effective canister ids +#### effective principal ids -A `Request` has an effective canister id according to the rules in [Effective canister id](#http-effective-canister-id): +A `Request` has an effective principal id according to the rules in [effective principal id](#http-effective-canister-id): - is_effective_canister_id(Request {canister_id = ic_principal, method = provisional_create_canister_with_cycles, …}, p) - is_effective_canister_id(Request {canister_id = ic_principal, arg = candid({canister_id = p, …}), …}, p) - is_effective_canister_id(Request {canister_id = p, …}, p), if p ≠ ic_principal + is_effective_principal_id(Request {canister_id = ic_principal, method = provisional_create_canister_with_cycles, …}, p) + is_effective_principal_id(Request {canister_id = ic_principal, arg = candid({canister_id = p, …}), …}, p) + is_effective_principal_id(Request {canister_id = p, …}, p), if p ≠ ic_principal #### API Request submission @@ -2850,7 +2854,7 @@ Conditions E.content.canister_id ∈ verify_envelope(E, E.content.sender, S.system_time) E.content ∉ dom(S.requests) S.system_time <= E.content.ingress_expiry -is_effective_canister_id(E.content, ECID) +is_effective_principal_id(E.content, ECID) ( E.content.canister_id = ic_principal E.content.arg = candid({canister_id = CanisterId, …}) E.content.sender ∈ S.controllers[CanisterId] @@ -4487,7 +4491,7 @@ Conditions E.content = CanisterQuery Q Q.canister_id ∈ verify_envelope(E, Q.sender, S.system_time) -is_effective_canister_id(E.content, ECID) +is_effective_principal_id(E.content, ECID) S.system_time <= Q.ingress_expiry S.canisters[Q.canister_id] ≠ EmptyCanister S.canister_status[Q.canister_id] = Running ∧ S.balances[Q.canister_id] >= freezing_limit(S, Q.canister_id) From 4738cccff8e5784d105fcc667c8e24f82830e525 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 17 Jul 2023 12:07:03 +0000 Subject: [PATCH 02/23] Use a subnet endpoint --- spec/index.md | 118 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 76 insertions(+), 42 deletions(-) diff --git a/spec/index.md b/spec/index.md index 18955fde9..61a45696c 100644 --- a/spec/index.md +++ b/spec/index.md @@ -429,7 +429,13 @@ The state tree contains information about the topology of the Internet Computer. - `/subnet//metrics` (blob) - A list of subnet wide metrics related to this subnet's current usage and/or performance. It can be a CBOR encoded struct containing a set of metrics, like number of canisters on subnet, memory used by the subnet, cycles burned by the subnet etc. + A list of subnet wide metrics related to this subnet's current usage and/or performance. The metrics are a CBOR map with the following fields: + + - `num_canisters` (`nat`): The number of canisters on this subnet. + - `canister_state` (`nat`): The total state taken by canisters on this subnet in bytes. + - `consumed_cycles` (`nat`): The total number of cycles consumed by canisters on this subnet. + - `update_transactions` (`nat`): The total number of transactions processed on this subnet. + :::note @@ -501,17 +507,17 @@ Users have the ability to learn about the hash of the canister's module, its cur The concrete mechanism that users use to send requests to the Internet Computer is via an HTTPS API, which exposes three endpoints to handle interactions, plus one for diagnostics: -- At `/api/v2/canister//call` the user can submit (asynchronous, potentially state-changing) calls. +- At `/api/v2/canister//call` the user can submit (asynchronous, potentially state-changing) calls. -- At `/api/v2/canister//read_state` the user can read various information about the state of the Internet Computer. In particular, they can poll for the status of a call here. +- At `/api/v2/canister//read_state` or `/api/v2/subnet//read_state` the user can read various information about the state of the Internet Computer. In particular, they can poll for the status of a call here. -- At `/api/v2/canister//query` the user can perform (synchronous, non-state-changing) query calls. +- At `/api/v2/canister//query` the user can perform (synchronous, non-state-changing) query calls. - At `/api/v2/status` the user can retrieve status information about the Internet Computer. -In these paths, the `` is the [textual representation](#textual-ids) of the [*effective* canister id](#http-effective-canister-id). +In these paths, the `` is the [textual representation](#textual-ids) of the [*effective* canister id](#http-effective-canister-id). -Requests to `/api/v2/canister//call`, `/api/v2/canister//read_state` and `/api/v2/canister//query` are POST requests with a CBOR-encoded request body, which consists of a authentication envelope (as per [Authentication](#authentication)) and request-specific content as described below. +Requests to `/api/v2/canister//call`, `/api/v2/canister//read_state`, `/api/v2/subnet//read_state` and `/api/v2/canister//query` are POST requests with a CBOR-encoded request body, which consists of a authentication envelope (as per [Authentication](#authentication)) and request-specific content as described below. :::note @@ -582,7 +588,7 @@ When asking the IC about the state or call of a request, the user uses the reque ### Request: Call {#http-call} -In order to call a canister, the user makes a POST request to `/api/v2/canister//call`. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to call a canister, the user makes a POST request to `/api/v2/canister//call`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `call` @@ -620,7 +626,7 @@ The functionality exposed via the [The IC management canister](#ic-management-ca ### Request: Read state {#http-read-state} -In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state`. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `read_state` @@ -632,7 +638,7 @@ The HTTP response to this request consists of a CBOR (see [CBOR](#cbor)) map wit - `certificate` (`blob`): A certificate (see [Certification](#certification)). - If this `certificate` includes subnet delegations (possibly nested), then the `effective_principal_id` must be included in each delegation's canister id range (see [Delegation](#certification-delegation)). + If this `certificate` includes subnet delegations (possibly nested), then the `effective_canister_id` must be included in each delegation's canister id range (see [Delegation](#certification-delegation)). The returned certificate reveals all values whose path is a suffix of a requested path. It also always reveals `/time`, even if not explicitly requested. @@ -646,13 +652,13 @@ All requested paths must have one of the following paths as prefix: - the sender of the original request referenced by `` is the same as the sender of the read state request and - - the effective principal id of the original request referenced by `` matches ``. + - the effective canister id of the original request referenced by `` matches ``. -- `/canisters//module_hash`. Can be requested if `` matches ``. +- `/canisters//module_hash`. Can be requested if `` matches ``. -- `/canisters//controllers`. Can be requested if `` matches ``. The order of controllers in the value at this path may vary depending on the implementation. +- `/canisters//controllers`. Can be requested if `` matches ``. The order of controllers in the value at this path may vary depending on the implementation. -- `/canisters//metadata/`. Can be requested if `` matches ``, `` is encoded in UTF-8, and +- `/canisters//metadata/`. Can be requested if `` matches ``, `` is encoded in UTF-8, and - canister with canister id `` does not exist or @@ -676,7 +682,7 @@ See [The system state tree](#state-tree) for details on the state tree. A query call is a fast, but less secure way to call a canister. Only methods that are explicitly marked as "query methods" by the canister can be called this way. -In order to make a query call to canister, the user makes a POST request to `/api/v2/canister//query`. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to make a query call to canister, the user makes a POST request to `/api/v2/canister//query`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `query` @@ -706,29 +712,29 @@ If the call resulted in a reject, the response is a CBOR map with the following Canister methods that do not change the canister state can be executed more efficiently. This method provides that ability, and returns the canister's response directly within the HTTP response. -### effective principal id {#http-effective-canister-id} +### effective canister id {#http-effective-canister-id} -The `` in the URL paths of requests is the *effective* destination of the request. +The `` in the URL paths of requests is the *effective* destination of the request. - If the request is an update call to the Management Canister (`aaaaa-aa`), then: - - If the call is to the `provisional_create_canister_with_cycles` method, then any principal can be used as the effective principal id for this call. + - If the call is to the `provisional_create_canister_with_cycles` method, then any principal can be used as the effective canister id for this call. - - Otherwise, if the `arg` is a Candid-encoded record with a `canister_id` field of type `principal`, then the effective principal id must be that principal. + - Otherwise, if the `arg` is a Candid-encoded record with a `canister_id` field of type `principal`, then the effective canister id must be that principal. - - Otherwise, the call is rejected by the system independently of the effective principal id. + - Otherwise, the call is rejected by the system independently of the effective canister id. -- If the request is an update call to a canister that is not the Management Canister (`aaaaa-aa`) or if the request is a query call, then the effective principal id must be the `canister_id` in the request. +- If the request is an update call to a canister that is not the Management Canister (`aaaaa-aa`) or if the request is a query call, then the effective canister id must be the `canister_id` in the request. :::note -The expectation is that user-side agent code shields users and developers from the notion of effective principal id, in analogy to how the System API interface shields canister developers from worrying about routing. +The expectation is that user-side agent code shields users and developers from the notion of effective canister id, in analogy to how the System API interface shields canister developers from worrying about routing. -The Internet Computer blockchain mainnet rejects all requests whose effective principal id is in no subnet's canister ranges, independently of whether the remaining conditions on the effective principal id are satisfied. +The Internet Computer blockchain mainnet rejects all requests whose effective canister id is in no subnet's canister ranges, independently of whether the remaining conditions on the effective canister id are satisfied. -The Internet Computer blockchain mainnet does not support `provisional_create_canister_with_cycles` and thus all calls to this method are rejected independently of the effective principal id. +The Internet Computer blockchain mainnet does not support `provisional_create_canister_with_cycles` and thus all calls to this method are rejected independently of the effective canister id. -In development instances of the Internet Computer Protocol (e.g. testnets), the effective principal id of a request submitted to a node must be a canister id from the canister ranges of the subnet to which the node belongs. +In development instances of the Internet Computer Protocol (e.g. testnets), the effective canister id of a request submitted to a node must be a canister id from the canister ranges of the subnet to which the node belongs. ::: @@ -2822,13 +2828,13 @@ The following predicate describes when an envelope `E` correctly signs the enclo then { p : p is Principal } else D.senders -#### effective principal ids +#### effective canister ids -A `Request` has an effective principal id according to the rules in [effective principal id](#http-effective-canister-id): +A `Request` has an effective canister id according to the rules in [effective canister id](#http-effective-canister-id): - is_effective_principal_id(Request {canister_id = ic_principal, method = provisional_create_canister_with_cycles, …}, p) - is_effective_principal_id(Request {canister_id = ic_principal, arg = candid({canister_id = p, …}), …}, p) - is_effective_principal_id(Request {canister_id = p, …}, p), if p ≠ ic_principal + is_effective_canister_id(Request {canister_id = ic_principal, method = provisional_create_canister_with_cycles, …}, p) + is_effective_canister_id(Request {canister_id = ic_principal, arg = candid({canister_id = p, …}), …}, p) + is_effective_canister_id(Request {canister_id = p, …}, p), if p ≠ ic_principal #### API Request submission @@ -2854,7 +2860,7 @@ Conditions E.content.canister_id ∈ verify_envelope(E, E.content.sender, S.system_time) E.content ∉ dom(S.requests) S.system_time <= E.content.ingress_expiry -is_effective_principal_id(E.content, ECID) +is_effective_canister_id(E.content, ECID) ( E.content.canister_id = ic_principal E.content.arg = candid({canister_id = CanisterId, …}) E.content.sender ∈ S.controllers[CanisterId] @@ -4491,7 +4497,7 @@ Conditions E.content = CanisterQuery Q Q.canister_id ∈ verify_envelope(E, Q.sender, S.system_time) -is_effective_principal_id(E.content, ECID) +is_effective_canister_id(E.content, ECID) S.system_time <= Q.ingress_expiry S.canisters[Q.canister_id] ≠ EmptyCanister S.canister_status[Q.canister_id] = Running ∧ S.balances[Q.canister_id] >= freezing_limit(S, Q.canister_id) @@ -4528,9 +4534,9 @@ Read response #### Certified state reads -The user can read elements of the *state tree*, using a `read_state` request to `/api/v2/canister//read_state`. +The user can read elements of the *state tree*, using a `read_state` request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. -Submitted request +Submitted request to `/api/v2/canister//read_state` `E` Conditions @@ -4540,7 +4546,7 @@ Conditions E.content = ReadState RS TS = verify_envelope(E, RS.sender, S.system_time) S.system_time <= RS.ingress_expiry -∀ path ∈ RS.paths. may_read_path(S, R.sender, path) +∀ path ∈ RS.paths. may_read_path_for_canister(S, R.sender, path) ∀ ["request_status", Rid] · _ ∈ RS.paths. ∀ R ∈ dom(S.requests). hash_of_map(R) = Rid => R.canister_id ∈ TS ``` @@ -4550,22 +4556,50 @@ A record with - `{certificate: C}` -The predicate `may_read_path` is defined as follows, implementing the access control outlined in [Request: Read state](#http-read-state): +Submitted request to `/api/v2/subnet//read_state` +`E` + +Conditions + +```html + +E.content = ReadState RS +TS = verify_envelope(E, RS.sender, S.system_time) +S.system_time <= RS.ingress_expiry +∀ path ∈ RS.paths. may_read_path_for_subnet(S, R.sender, path) + +``` - may_read_path(S, _, ["time"] · _) = True - may_read_path(S, _, ["subnet"] · _) = True - may_read_path(S, _, ["request_status", Rid] · _) = +Read response +A record with + +- `{certificate: C}` + + +The predicate `may_read_path_for_canister` is defined as follows, implementing the access control outlined in [Request: Read state](#http-read-state): + + may_read_path_for_canister(S, _, ["time"] · _) = False + may_read_path_for_canister(S, _, ["subnet"] · _) = False + may_read_path_for_canister(S, _, ["request_status", Rid] · _) = ∀ (R ↦ (_, ECID')) ∈ dom(S.requests). hash_of_map(R) = Rid => RS.sender == R.sender ∧ ECID == ECID' - may_read_path(S, _, ["canister", cid, "module_hash"] · _) = cid == ECID - may_read_path(S, _, ["canister", cid, "controllers"] · _) = cid == ECID - may_read_path(S, _, ["canister", cid, "metadata", name] · _) = cid == ECID ∧ UTF8(name) ∧ + may_read_path_for_canister(S, _, ["canister", cid, "module_hash"] · _) = cid == ECID + may_read_path_for_canister(S, _, ["canister", cid, "controllers"] · _) = cid == ECID + may_read_path_for_canister(S, _, ["canister", cid, "metadata", name] · _) = cid == ECID ∧ UTF8(name) ∧ (cid ∉ dom(S.canisters[cid]) ∨ S.canisters[cid] = EmptyCanister ∨ name ∉ (dom(S.canisters[cid].public_custom_sections) ∪ dom(S.canisters[cid].private_custom_sections)) ∨ name ∈ dom(S.canisters[cid].public_custom_sections) ∨ (name ∈ dom(S.canisters[cid].private_custom_sections) ∧ RS.sender ∈ S.controllers[cid]) ) - may_read_path(S, _, _) = False + may_read_path_for_canister(S, _, _) = False + +where `UTF8(name)` holds if `name` is encoded in UTF-8. + +The predicate `may_read_path_for_subnet` is defined as follows, implementing the access control outlined in [Request: Read state](#http-read-state): + + may_read_path_for_canister(S, _, ["time"] · _) = True + may_read_path_for_canister(S, _, ["subnet"] · _) = True + may_read_path_for_canister(S, _, _) = False where `UTF8(name)` holds if `name` is encoded in UTF-8. From fff992a645ca55ce73311ac93ff246ba29ca6174 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 17 Jul 2023 12:11:17 +0000 Subject: [PATCH 03/23] Fix capitalization --- spec/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index 61a45696c..f6b7d68ad 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2828,7 +2828,7 @@ The following predicate describes when an envelope `E` correctly signs the enclo then { p : p is Principal } else D.senders -#### effective canister ids +#### Effective canister ids A `Request` has an effective canister id according to the rules in [effective canister id](#http-effective-canister-id): From 81ec8584371894c6b025c93727dc58c2faa0faf8 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 17 Jul 2023 12:11:46 +0000 Subject: [PATCH 04/23] One more --- spec/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index f6b7d68ad..8ab8c7f33 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2830,7 +2830,7 @@ The following predicate describes when an envelope `E` correctly signs the enclo #### Effective canister ids -A `Request` has an effective canister id according to the rules in [effective canister id](#http-effective-canister-id): +A `Request` has an effective canister id according to the rules in [Effective canister id](#http-effective-canister-id): is_effective_canister_id(Request {canister_id = ic_principal, method = provisional_create_canister_with_cycles, …}, p) is_effective_canister_id(Request {canister_id = ic_principal, arg = candid({canister_id = p, …}), …}, p) From cd5140804d3f6dc4ffd97038938024ccdf075001 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 17 Jul 2023 12:15:04 +0000 Subject: [PATCH 05/23] Reorganize certified state reads section --- spec/index.md | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/spec/index.md b/spec/index.md index 8ab8c7f33..c1109cae4 100644 --- a/spec/index.md +++ b/spec/index.md @@ -4556,25 +4556,6 @@ A record with - `{certificate: C}` -Submitted request to `/api/v2/subnet//read_state` -`E` - -Conditions - -```html - -E.content = ReadState RS -TS = verify_envelope(E, RS.sender, S.system_time) -S.system_time <= RS.ingress_expiry -∀ path ∈ RS.paths. may_read_path_for_subnet(S, R.sender, path) - -``` - -Read response -A record with - -- `{certificate: C}` - The predicate `may_read_path_for_canister` is defined as follows, implementing the access control outlined in [Request: Read state](#http-read-state): @@ -4595,11 +4576,32 @@ The predicate `may_read_path_for_canister` is defined as follows, implementing t where `UTF8(name)` holds if `name` is encoded in UTF-8. + +Submitted request to `/api/v2/subnet//read_state` +`E` + +Conditions + +```html + +E.content = ReadState RS +TS = verify_envelope(E, RS.sender, S.system_time) +S.system_time <= RS.ingress_expiry +∀ path ∈ RS.paths. may_read_path_for_subnet(S, R.sender, path) + +``` + +Read response +A record with + +- `{certificate: C}` + + The predicate `may_read_path_for_subnet` is defined as follows, implementing the access control outlined in [Request: Read state](#http-read-state): - may_read_path_for_canister(S, _, ["time"] · _) = True - may_read_path_for_canister(S, _, ["subnet"] · _) = True - may_read_path_for_canister(S, _, _) = False + may_read_path_for_subnet(S, _, ["time"] · _) = True + may_read_path_for_subnet(S, _, ["subnet"] · _) = True + may_read_path_for_subnet(S, _, _) = False where `UTF8(name)` holds if `name` is encoded in UTF-8. From de4c34ac95971b30cc3b4f52f629dab22533cd8a Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 17 Jul 2023 12:16:58 +0000 Subject: [PATCH 06/23] One more capital --- spec/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index c1109cae4..12797ff8a 100644 --- a/spec/index.md +++ b/spec/index.md @@ -712,7 +712,7 @@ If the call resulted in a reject, the response is a CBOR map with the following Canister methods that do not change the canister state can be executed more efficiently. This method provides that ability, and returns the canister's response directly within the HTTP response. -### effective canister id {#http-effective-canister-id} +### Effective canister id {#http-effective-canister-id} The `` in the URL paths of requests is the *effective* destination of the request. From b3aa932f8c0c07d2be8bbe6c5ca7426e674cd029 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Tue, 18 Jul 2023 11:35:00 +0200 Subject: [PATCH 07/23] Apply suggestions from code review Co-authored-by: mraszyk <31483726+mraszyk@users.noreply.github.com> --- spec/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/index.md b/spec/index.md index 12797ff8a..59b0c4c7d 100644 --- a/spec/index.md +++ b/spec/index.md @@ -429,10 +429,10 @@ The state tree contains information about the topology of the Internet Computer. - `/subnet//metrics` (blob) - A list of subnet wide metrics related to this subnet's current usage and/or performance. The metrics are a CBOR map with the following fields: + A collection of subnet-wide metrics related to this subnet's current resource usage and/or performance. The metrics are a CBOR map with the following fields: - `num_canisters` (`nat`): The number of canisters on this subnet. - - `canister_state` (`nat`): The total state taken by canisters on this subnet in bytes. + - `canister_state` (`nat`): The total size of the state taken by canisters on this subnet in bytes. - `consumed_cycles` (`nat`): The total number of cycles consumed by canisters on this subnet. - `update_transactions` (`nat`): The total number of transactions processed on this subnet. @@ -4546,7 +4546,7 @@ Conditions E.content = ReadState RS TS = verify_envelope(E, RS.sender, S.system_time) S.system_time <= RS.ingress_expiry -∀ path ∈ RS.paths. may_read_path_for_canister(S, R.sender, path) +∀ path ∈ RS.paths. may_read_path_for_canister(S, RS.sender, path) ∀ ["request_status", Rid] · _ ∈ RS.paths. ∀ R ∈ dom(S.requests). hash_of_map(R) = Rid => R.canister_id ∈ TS ``` @@ -4587,7 +4587,7 @@ Conditions E.content = ReadState RS TS = verify_envelope(E, RS.sender, S.system_time) S.system_time <= RS.ingress_expiry -∀ path ∈ RS.paths. may_read_path_for_subnet(S, R.sender, path) +∀ path ∈ RS.paths. may_read_path_for_subnet(S, RS.sender, path) ``` From 207bbee944aef4c8ab52df6bdbdfdb715bfa5445 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Tue, 18 Jul 2023 09:42:16 +0000 Subject: [PATCH 08/23] Some more fixes after review --- spec/index.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/spec/index.md b/spec/index.md index 59b0c4c7d..72a42f3fb 100644 --- a/spec/index.md +++ b/spec/index.md @@ -626,7 +626,7 @@ The functionality exposed via the [The IC management canister](#ic-management-ca ### Request: Read state {#http-read-state} -In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific, i.e. information under the `/time` and `/subnet` sub-trees. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `read_state` @@ -4559,8 +4559,6 @@ A record with The predicate `may_read_path_for_canister` is defined as follows, implementing the access control outlined in [Request: Read state](#http-read-state): - may_read_path_for_canister(S, _, ["time"] · _) = False - may_read_path_for_canister(S, _, ["subnet"] · _) = False may_read_path_for_canister(S, _, ["request_status", Rid] · _) = ∀ (R ↦ (_, ECID')) ∈ dom(S.requests). hash_of_map(R) = Rid => RS.sender == R.sender ∧ ECID == ECID' may_read_path_for_canister(S, _, ["canister", cid, "module_hash"] · _) = cid == ECID @@ -4603,8 +4601,6 @@ The predicate `may_read_path_for_subnet` is defined as follows, implementing the may_read_path_for_subnet(S, _, ["subnet"] · _) = True may_read_path_for_subnet(S, _, _) = False -where `UTF8(name)` holds if `name` is encoded in UTF-8. - The response is a certificate `cert`, as specified in [Certification](#certification), which passes `verify_cert` (assuming `S.root_key` as the root of trust), and where for every `path` documented in [The system state tree](#state-tree) that is a suffix of a path in `RS.paths` or of `["time"]`, we have lookup(path, cert) = lookup_in_tree(path, state_tree(S)) From ec99c44d77b39874219582dea5e3333fbc45acf7 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 25 Jul 2023 14:44:17 +0200 Subject: [PATCH 09/23] define the meaning of total --- spec/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/index.md b/spec/index.md index 72a42f3fb..b11989912 100644 --- a/spec/index.md +++ b/spec/index.md @@ -432,9 +432,9 @@ The state tree contains information about the topology of the Internet Computer. A collection of subnet-wide metrics related to this subnet's current resource usage and/or performance. The metrics are a CBOR map with the following fields: - `num_canisters` (`nat`): The number of canisters on this subnet. - - `canister_state` (`nat`): The total size of the state taken by canisters on this subnet in bytes. - - `consumed_cycles` (`nat`): The total number of cycles consumed by canisters on this subnet. - - `update_transactions` (`nat`): The total number of transactions processed on this subnet. + - `canister_state` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. + - `consumed_cycles` (`nat`): The total number of cycles consumed by canisters on this subnet since this subnet was created. + - `update_transactions` (`nat`): The total number of transactions processed on this subnet since this subnet was created. :::note From 60fcd411771142232e9adb11271c9d4c4b2850d3 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 25 Jul 2023 14:45:37 +0200 Subject: [PATCH 10/23] rephrase --- spec/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index b11989912..9bd297dc0 100644 --- a/spec/index.md +++ b/spec/index.md @@ -626,7 +626,7 @@ The functionality exposed via the [The IC management canister](#ic-management-ca ### Request: Read state {#http-read-state} -In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific, i.e. information under the `/time` and `/subnet` sub-trees. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific, i.e., when requesting paths with the prefix `/time` or `/subnet`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `read_state` From 41ae5bf1ea8bef6079332bda0fedf8b6786573ab Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 25 Jul 2023 16:48:38 +0200 Subject: [PATCH 11/23] update may_read_path_for_canister --- spec/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/index.md b/spec/index.md index c6cb0d3b5..22d956e50 100644 --- a/spec/index.md +++ b/spec/index.md @@ -4666,6 +4666,8 @@ A record with The predicate `may_read_path_for_canister` is defined as follows, implementing the access control outlined in [Request: Read state](#http-read-state): + may_read_path_for_canister(S, _, ["time"] · _) = True + may_read_path_for_canister(S, _, ["subnet"] · _) = True may_read_path_for_canister(S, _, ["request_status", Rid] · _) = ∀ (R ↦ (_, ECID')) ∈ dom(S.requests). hash_of_map(R) = Rid => RS.sender == R.sender ∧ ECID == ECID' may_read_path_for_canister(S, _, ["canister", cid, "module_hash"] · _) = cid == ECID From 39f7a812ae4339f7d1527e457f9bb64edf4e41bb Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Tue, 29 Aug 2023 11:08:10 +0000 Subject: [PATCH 12/23] More specific names for the metrics --- spec/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/index.md b/spec/index.md index da6543459..58f4718a8 100644 --- a/spec/index.md +++ b/spec/index.md @@ -444,9 +444,9 @@ The state tree contains information about the topology of the Internet Computer. A collection of subnet-wide metrics related to this subnet's current resource usage and/or performance. The metrics are a CBOR map with the following fields: - `num_canisters` (`nat`): The number of canisters on this subnet. - - `canister_state` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. - - `consumed_cycles` (`nat`): The total number of cycles consumed by canisters on this subnet since this subnet was created. - - `update_transactions` (`nat`): The total number of transactions processed on this subnet since this subnet was created. + - `total_canister_state` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. + - `total_consumed_cycles` (`nat`): The total number of cycles consumed by canisters on this subnet since this subnet was created. + - `num_update_transactions` (`nat`): The total number of transactions processed on this subnet since this subnet was created. :::note From 7847f9f63997a8d208c55ec4362bc79f221c1b9a Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Fri, 1 Sep 2023 08:56:37 +0000 Subject: [PATCH 13/23] Updates to type of metrics --- spec/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/index.md b/spec/index.md index 58f4718a8..b7ec30fb0 100644 --- a/spec/index.md +++ b/spec/index.md @@ -443,10 +443,10 @@ The state tree contains information about the topology of the Internet Computer. A collection of subnet-wide metrics related to this subnet's current resource usage and/or performance. The metrics are a CBOR map with the following fields: - - `num_canisters` (`nat`): The number of canisters on this subnet. - - `total_canister_state` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. - - `total_consumed_cycles` (`nat`): The total number of cycles consumed by canisters on this subnet since this subnet was created. - - `num_update_transactions` (`nat`): The total number of transactions processed on this subnet since this subnet was created. + - `num_canisters` (`nat64`): The number of canisters on this subnet. + - `total_canister_state` (`nat64`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. + - `total_consumed_cycles` (`map`): The total number of cycles consumed by canisters on this subnet since this subnet was created. It's a map of two values, a low and high part, both of type `nat64`. + - `num_update_transactions` (`nat64`): The total number of transactions processed on this subnet since this subnet was created. :::note From b738b9c6adb6128a655b189b78bdc22ee761f2d3 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Fri, 1 Sep 2023 08:58:06 +0000 Subject: [PATCH 14/23] Update --- spec/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index b7ec30fb0..2a333a3e6 100644 --- a/spec/index.md +++ b/spec/index.md @@ -445,7 +445,7 @@ The state tree contains information about the topology of the Internet Computer. - `num_canisters` (`nat64`): The number of canisters on this subnet. - `total_canister_state` (`nat64`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. - - `total_consumed_cycles` (`map`): The total number of cycles consumed by canisters on this subnet since this subnet was created. It's a map of two values, a low and high part, both of type `nat64`. + - `total_consumed_cycles` (`map`): The total number of cycles consumed by canisters on this subnet since this subnet was created. It's a map of two values, a low part of type `nat64` and a high part of type `opt nat64`. - `num_update_transactions` (`nat64`): The total number of transactions processed on this subnet since this subnet was created. From 05d7cc4962fe0babbbfabbfc0835fe9837ac5877 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Fri, 1 Sep 2023 09:00:16 +0000 Subject: [PATCH 15/23] Use nat --- spec/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/index.md b/spec/index.md index 2a333a3e6..b63471209 100644 --- a/spec/index.md +++ b/spec/index.md @@ -443,10 +443,10 @@ The state tree contains information about the topology of the Internet Computer. A collection of subnet-wide metrics related to this subnet's current resource usage and/or performance. The metrics are a CBOR map with the following fields: - - `num_canisters` (`nat64`): The number of canisters on this subnet. - - `total_canister_state` (`nat64`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. - - `total_consumed_cycles` (`map`): The total number of cycles consumed by canisters on this subnet since this subnet was created. It's a map of two values, a low part of type `nat64` and a high part of type `opt nat64`. - - `num_update_transactions` (`nat64`): The total number of transactions processed on this subnet since this subnet was created. + - `num_canisters` (`nat`): The number of canisters on this subnet. + - `total_canister_state` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. + - `total_consumed_cycles` (`map`): The total number of cycles consumed by canisters on this subnet since this subnet was created. It's a map of two values, a low part of type `nat` and a high part of type `opt nat`. + - `num_update_transactions` (`nat`): The total number of transactions processed on this subnet since this subnet was created. :::note From e56404f65eedc123dac2b1487f770dd267c6bbd4 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Mon, 4 Sep 2023 07:52:52 +0200 Subject: [PATCH 16/23] add metrics to the formal semantics --- spec/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index b63471209..5d15b5d34 100644 --- a/spec/index.md +++ b/spec/index.md @@ -4741,7 +4741,7 @@ where `state_tree` constructs a labeled tree from the IC state `S` and the (so f state_tree(S) = { "time": S.system_time; - "subnet": { subnet_id : { "public_key" : subnet_pk, "canister_ranges" : subnet_ranges } | (subnet_id, subnet_pk, subnet_ranges) ∈ subnets }; + "subnet": { subnet_id : { "public_key" : subnet_pk; "canister_ranges" : subnet_ranges; "metrics" : } | (subnet_id, subnet_pk, subnet_ranges) ∈ subnets }; "request_status": { request_id(R): request_status_tree(T) | (R ↦ (T, _)) ∈ S.requests }; "canister": { canister_id : From b8f1f98d033147fe6f778d277ebdac600826bc84 Mon Sep 17 00:00:00 2001 From: Dimitris Sarlis Date: Mon, 4 Sep 2023 08:09:01 +0000 Subject: [PATCH 17/23] Review comments --- spec/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/index.md b/spec/index.md index 5d15b5d34..3c0e616c7 100644 --- a/spec/index.md +++ b/spec/index.md @@ -444,9 +444,9 @@ The state tree contains information about the topology of the Internet Computer. A collection of subnet-wide metrics related to this subnet's current resource usage and/or performance. The metrics are a CBOR map with the following fields: - `num_canisters` (`nat`): The number of canisters on this subnet. - - `total_canister_state` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. - - `total_consumed_cycles` (`map`): The total number of cycles consumed by canisters on this subnet since this subnet was created. It's a map of two values, a low part of type `nat` and a high part of type `opt nat`. - - `num_update_transactions` (`nat`): The total number of transactions processed on this subnet since this subnet was created. + - `canister_state_bytes` (`nat`): The total size of the state in bytes taken by canisters on this subnet since this subnet was created. + - `consumed_cycles_total` (`map`): The total number of cycles consumed by all current and deleted canisters on this subnet. It's a map of two values, a low part of type `nat` and a high part of type `opt nat`. + - `update_transactions_total` (`nat`): The total number of transactions processed on this subnet since this subnet was created. :::note From e0efbc7489e159bfa06db9e18cadbbe7111700dd Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Mon, 4 Sep 2023 12:38:15 +0200 Subject: [PATCH 18/23] update read_state access restrictions --- spec/index.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index 3c0e616c7..cdbec4e45 100644 --- a/spec/index.md +++ b/spec/index.md @@ -669,7 +669,7 @@ All requested paths must have the following form: - `/time`. Can always be requested. -- `/subnet`, `/subnet/`, `/subnet//public_key`, `/subnet//canister_ranges`. Can always be requested. +- `/subnet`, `/subnet/`, `/subnet//public_key`, `/subnet//canister_ranges`, `/subnet//metrics`. Can always be requested. - `/request_status/`, `/request_status//status`, `/request_status//reply`, `/request_status//reject_code`, `/request_status//reject_message`, `/request_status//error_code`. Can be requested if no path with such a prefix exists in the state tree or @@ -4683,6 +4683,7 @@ The predicate `may_read_path_for_canister` is defined as follows, implementing t may_read_path_for_canister(S, _, ["subnet", sid]) = True may_read_path_for_canister(S, _, ["subnet", sid, "public_key"]) = True may_read_path_for_canister(S, _, ["subnet", sid, "canister_ranges"]) = True + may_read_path_for_canister(S, _, ["subnet", sid, "metrics"]) = True may_read_path_for_canister(S, _, ["request_status", Rid]) = may_read_path_for_canister(S, _, ["request_status", Rid, "status"]) = may_read_path_for_canister(S, _, ["request_status", Rid, "reply"]) = @@ -4731,6 +4732,7 @@ The predicate `may_read_path_for_subnet` is defined as follows, implementing the may_read_path_for_subnet(S, _, ["subnet", sid]) = True may_read_path_for_subnet(S, _, ["subnet", sid, "public_key"]) = True may_read_path_for_subnet(S, _, ["subnet", sid, "canister_ranges"]) = True + may_read_path_for_subnet(S, _, ["subnet", sid, "metrics"]) = True may_read_path_for_subnet(S, _, _) = False The response is a certificate `cert`, as specified in [Certification](#certification), which passes `verify_cert` (assuming `S.root_key` as the root of trust), and where for every `path` documented in [The system state tree](#state-tree) that is a suffix of a path in `RS.paths` or of `["time"]`, we have From ff4ee7fd322fe6836aeb3ed5ddbf05b43126cfaf Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Sun, 10 Sep 2023 15:38:09 +0200 Subject: [PATCH 19/23] do not allow reading metrics with canister read state --- spec/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/index.md b/spec/index.md index d3990235a..9afad1311 100644 --- a/spec/index.md +++ b/spec/index.md @@ -638,7 +638,7 @@ The functionality exposed via the [The IC management canister](#ic-management-ca ### Request: Read state {#http-read-state} -In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific, i.e., when requesting paths with the prefix `/time` or `/subnet`. The request body consists of an authentication envelope with a `content` map with the following fields: +In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific, i.e., when requesting paths with the prefix `/time` or `/subnet`, and the subnet form must be used when requesting paths of the form `/subnet//metrics`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `read_state` @@ -4688,7 +4688,6 @@ The predicate `may_read_path_for_canister` is defined as follows, implementing t may_read_path_for_canister(S, _, ["subnet", sid]) = True may_read_path_for_canister(S, _, ["subnet", sid, "public_key"]) = True may_read_path_for_canister(S, _, ["subnet", sid, "canister_ranges"]) = True - may_read_path_for_canister(S, _, ["subnet", sid, "metrics"]) = True may_read_path_for_canister(S, _, ["request_status", Rid]) = may_read_path_for_canister(S, _, ["request_status", Rid, "status"]) = may_read_path_for_canister(S, _, ["request_status", Rid, "reply"]) = From e38777d32e21c419c5a4fe652ba500e7cdeb6e05 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 12 Sep 2023 10:55:24 +0200 Subject: [PATCH 20/23] add a deprecation announcement --- spec/index.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/index.md b/spec/index.md index c724a90a2..6303d154e 100644 --- a/spec/index.md +++ b/spec/index.md @@ -638,6 +638,14 @@ The functionality exposed via the [The IC management canister](#ic-management-ca ### Request: Read state {#http-read-state} +:::note + +Requesting paths with the prefix `/subnet` at `/api/v2/canister//read_state` will be deprecated in a future release of the Interface specification. Hence, users are advised to point their requests for paths with the prefix `/subnet` to `/api/v2/subnet//read_state`. + +On the IC mainnet, the root subnet ID `tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe` can be used to retrieve the list of all IC mainnet's subnets by requesting the prefix `/subnet` at `/api/v2/subnet/tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe/read_state`. + +::: + In order to read parts of the [The system state tree](#state-tree), the user makes a POST request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. The subnet form should be used when the information to be retrieved is subnet specific, i.e., when requesting paths with the prefix `/time` or `/subnet`, and the subnet form must be used when requesting paths of the form `/subnet//metrics`. The request body consists of an authentication envelope with a `content` map with the following fields: - `request_type` (`text`): Always `read_state` From c35966bcdce64af51ad0cdbbb986d9c00b7e7766 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 12 Sep 2023 10:56:45 +0200 Subject: [PATCH 21/23] add note to formal semantics --- spec/index.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/index.md b/spec/index.md index 6303d154e..867b84b70 100644 --- a/spec/index.md +++ b/spec/index.md @@ -4698,6 +4698,14 @@ Query response #### Certified state reads +:::note + +Requesting paths with the prefix `/subnet` at `/api/v2/canister//read_state` will be deprecated in a future release of the Interface specification. Hence, users are advised to point their requests for paths with the prefix `/subnet` to `/api/v2/subnet//read_state`. + +On the IC mainnet, the root subnet ID `tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe` can be used to retrieve the list of all IC mainnet's subnets by requesting the prefix `/subnet` at `/api/v2/subnet/tdb26-jop6k-aogll-7ltgs-eruif-6kk7m-qpktf-gdiqx-mxtrf-vb5e6-eqe/read_state`. + +::: + The user can read elements of the *state tree*, using a `read_state` request to `/api/v2/canister//read_state` or `/api/v2/subnet//read_state`. Submitted request to `/api/v2/canister//read_state` From b8afd4ba74e62fcc8a70ad1b90009dd5c592f5b0 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Sun, 24 Sep 2023 19:30:55 +0200 Subject: [PATCH 22/23] update conditions of read state certificate validity --- spec/index.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index 6c63c6c8d..fc069a722 100644 --- a/spec/index.md +++ b/spec/index.md @@ -662,7 +662,11 @@ The HTTP response to this request consists of a CBOR (see [CBOR](#cbor)) map wit - `certificate` (`blob`): A certificate (see [Certification](#certification)). - If this `certificate` includes subnet delegations (possibly nested), then the `effective_canister_id` must be included in each delegation's canister id range (see [Delegation](#certification-delegation)). + If this `certificate` includes (possibly nested) subnet delegations (see [Delegation](#certification-delegation)), then + + - for requests to `/api/v2/canister//read_state`, the `` must be included in each delegation's canister id range, + + - for requests to `/api/v2/subnet//read_state`, the `` must match each delegation's subnet id. The returned certificate reveals all values whose path has a requested path as a prefix except for From 777e584385e494b904841e8c07eae07f1a7706b3 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Wed, 4 Oct 2023 10:41:48 +0200 Subject: [PATCH 23/23] update changelog --- spec/_attachments/interface-spec-changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/_attachments/interface-spec-changelog.md b/spec/_attachments/interface-spec-changelog.md index 5d45a9761..3d4cc6c82 100644 --- a/spec/_attachments/interface-spec-changelog.md +++ b/spec/_attachments/interface-spec-changelog.md @@ -1,6 +1,9 @@ ## Changelog {#changelog} ### ∞ (unreleased) +* Add metrics on subnet usage into the certified state tree and a new HTTP endpoint `/api/v2/subnet//read_state` for retrieving them. + +### 0.21.0 (2023-09-18) {#0_21_0} * Canister cycle balance cannot decrease below the freezing limit after executing `install_code` on the management canister. * System API calls `ic0.msg_caller_size` and `ic0.msg_caller_copy` can be called in all contexts except for (start) function. * Added note on confidentiality of values in the certified state tree.