From dbabec1fd1a45763cb0ad006877ce625fc3238e4 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Thu, 9 Oct 2025 08:28:07 +0200 Subject: [PATCH 1/7] feat: canister log memory limit in canister settings --- .../canister-management/settings.mdx | 9 +++-- docs/references/_attachments/ic.did | 2 + docs/references/ic-interface-spec.md | 37 ++++++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/docs/building-apps/canister-management/settings.mdx b/docs/building-apps/canister-management/settings.mdx index a691a6a265..dc34a735e1 100644 --- a/docs/building-apps/canister-management/settings.mdx +++ b/docs/building-apps/canister-management/settings.mdx @@ -13,7 +13,7 @@ import { GlossaryTooltip } from "/src/components/Tooltip/GlossaryTooltip"; Each canister has a group of possible settings that control its behavior. Only a controller of the canister can read and modify a canister's settings. -Currently, there are nine canister setting fields: +Currently, there are ten canister settings fields: 1. `controllers`: The list of controllers of the canister. 2. `compute_allocation`: Amount of compute that the canister has allocated. @@ -22,8 +22,9 @@ Currently, there are nine canister setting fields: 5. `reserved_cycles_limit`: A safety threshold to protect against spending too many cycles for resource reservation. 6. `wasm_memory_limit`: A safety threshold to protect against reaching the 4GiB hard limit of 32-bit Wasm memory. 7. `log_visibility`: Controls who can read the canister logs. -8. `wasm_memory_threshold`: A threshold that triggers the "on low wasm memory" hook when the canister's remaining wasm memory falls below the provided value. -9. `environment_variables`: A set of key-value pairs that configure canister behavior without code changes. +8. `log_memory_limit`: The maximum amount of memory used for canister logs. +9. `wasm_memory_threshold`: A threshold that triggers the "on low wasm memory" hook when the canister's remaining wasm memory falls below the provided value. +10. `environment_variables`: A set of key-value pairs that configure canister behavior without code changes. ## Viewing current settings @@ -211,4 +212,4 @@ The default value of the field is `controllers`. Common errors related to canister settings include: -- [Invalid settings](/docs/references/execution-errors#invalid-settings). \ No newline at end of file +- [Invalid settings](/docs/references/execution-errors#invalid-settings). diff --git a/docs/references/_attachments/ic.did b/docs/references/_attachments/ic.did index 4622a2f78c..558770112f 100644 --- a/docs/references/_attachments/ic.did +++ b/docs/references/_attachments/ic.did @@ -20,6 +20,7 @@ type canister_settings = record { freezing_threshold : opt nat; reserved_cycles_limit : opt nat; log_visibility : opt log_visibility; + log_memory_limit : opt nat; wasm_memory_limit : opt nat; wasm_memory_threshold : opt nat; environment_variables : opt vec environment_variable; @@ -32,6 +33,7 @@ type definite_canister_settings = record { freezing_threshold : nat; reserved_cycles_limit : nat; log_visibility : log_visibility; + log_memory_limit : nat; wasm_memory_limit : nat; wasm_memory_threshold : nat; environment_variables : vec environment_variable; diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md index 32edc73e9a..4d9669e0e5 100644 --- a/docs/references/ic-interface-spec.md +++ b/docs/references/ic-interface-spec.md @@ -2412,6 +2412,13 @@ The optional `settings` parameter can be used to set the following settings: Default value: `controllers`. +- `log_memory_limit` (`nat`) + + Must be equal to 4096 and indicates the maximum amount of memory used for canister logs. + Oldest canister logs are purged if the total memory used for canister logs exceeds this value. + + Default value: `4096`. + - `wasm_memory_threshold` (`nat`) Must be a number between 0 and 264-1, inclusively, and indicates the threshold on the remaining wasm memory size of the canister in bytes: @@ -3152,8 +3159,8 @@ This method can only be called by external users via non-replicated calls, i.e., Given a canister ID as input, this method returns a vector of logs of that canister including its trap messages. The canister logs are *not* collected in canister methods running in non-replicated mode (NRQ, CQ, CRy, CRt, CC, and F modes, as defined in [Overview of imports](#system-api-imports)) and the canister logs are *purged* when the canister is reinstalled or uninstalled. -The total size of all returned logs does not exceed 4KiB. -If new logs are added resulting in exceeding the maximum total log size of 4KiB, the oldest logs will be removed. +The total size of all returned logs does not exceed the value `log_memory_limit` in canister settings. +Oldest canister logs are purged if the total memory used for canister logs exceeds the value `log_memory_limit` in canister settings. Logs persist across canister upgrades and they are deleted if the canister is reinstalled or uninstalled. The log visibility is defined in the `log_visibility` field of `canister_settings` and can be one of the following variants: @@ -4035,6 +4042,7 @@ S = { certified_data: CanisterId ↦ Blob; canister_history: CanisterId ↦ CanisterHistory; canister_log_visibility: CanisterId ↦ CanisterLogVisibility; + canister_log_memory_limit: CanisterId ↦ Nat; canister_logs: CanisterId ↦ [CanisterLog]; query_stats: CanisterId ↦ [QueryStats]; system_time : Timestamp @@ -4143,6 +4151,7 @@ The initial state of the IC is certified_data = (); canister_history = (); canister_log_visibility = (); + canister_log_memory_limit = (); canister_logs = (); query_stats = (); system_time = T; @@ -5134,6 +5143,11 @@ if A.settings.log_visibility is not null: else: New_canister_log_visibility = Controllers +if A.settings.log_memory_limit is not null: + New_canister_log_memory_limit = A.settings.log_memory_limit +else: + New_canister_log_memory_limit = 4096 + ``` State after @@ -5161,6 +5175,7 @@ S' = S with query_stats[Canister_id] = [] canister_history[Canister_id] = New_canister_history canister_log_visibility[Canister_id] = New_canister_log_visibility + canister_log_memory_limit[Canister_id] = New_canister_log_memory_limit canister_logs[Canister_id] = [] messages = Older_messages · Younger_messages · ResponseMessage { @@ -5305,6 +5320,8 @@ S' = S with canister_version[A.canister_id] = S.canister_version[A.canister_id] + 1 if A.settings.log_visibility is not null: canister_log_visibility[A.canister_id] = A.settings.log_visibility + if A.settings.log_memory_limit is not null: + canister_log_memory_limit[A.canister_id] = A.settings.log_memory_limit messages = Older_messages · Younger_messages · ResponseMessage { origin = M.origin @@ -6182,6 +6199,7 @@ S with certified_data[A.canister_id] = (deleted) canister_history[A.canister_id] = (deleted) canister_log_visibility[A.canister_id] = (deleted) + canister_log_memory_limit[A.canister_id] = (deleted) canister_logs[A.canister_id] = (deleted) query_stats[A.canister_id] = (deleted) chunk_store[A.canister_id] = (deleted) @@ -6417,6 +6435,11 @@ if A.settings.log_visibility is not null: else: New_canister_log_visibility = Controllers +if A.settings.log_memory_limit is not null: + New_canister_log_memory_limit = A.settings.log_memory_limit +else: + New_canister_log_memory_limit = 4096 + ``` State after @@ -6442,6 +6465,7 @@ S' = S with certified_data[Canister_id] = "" canister_history[Canister_id] = New_canister_history canister_log_visibility[Canister_id] = New_canister_log_visibility + canister_log_memory_limit[Canister_id] = New_canister_log_memory_limit canister_logs[Canister_id] = [] query_stats[CanisterId] = [] messages = Older_messages · Younger_messages · @@ -7322,16 +7346,19 @@ S with ``` -#### Trimming canister logs +#### Purging canister logs + +Oldest canister logs are purged if the total memory used for canister logs exceeds the value `log_memory_limit` in canister settings. -Canister logs can be trimmed if their total length exceeds 4KiB. +The (unspecified) function `canister_log_memory_usage(logs)` models the total memory used by `logs`. Conditions ```html S.canister_logs[CanisterId] = Older_logs · Newer_logs -SUM { |l| | l <- Older_logs } > 4KiB +canister_log_memory_usage(Older_logs · Newer_logs) > S.canister_log_memory_limit[CanisterId] +canister_log_memory_usage(Newer_logs) ≤ S.canister_log_memory_limit[CanisterId] ``` From 53928c02b3acc2883a3ff92b1d83e49afcd4a847 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Fri, 6 Mar 2026 14:52:29 +0100 Subject: [PATCH 2/7] maximum log memory limit --- docs/references/ic-interface-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md index 2d469533f2..6a89c983aa 100644 --- a/docs/references/ic-interface-spec.md +++ b/docs/references/ic-interface-spec.md @@ -2437,7 +2437,7 @@ The optional `settings` parameter can be used to set the following settings: - `log_memory_limit` (`nat`) - Must be equal to 4096 and indicates the maximum amount of memory used for canister logs. + Must be at most `2097152` (`2 MiB`) and indicates the maximum amount of memory used for canister logs. Oldest canister logs are purged if the total memory used for canister logs exceeds this value. Default value: `4096`. From ee0f01f8595add230478cb96ea82efb6680f0917 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Fri, 6 Mar 2026 15:38:39 +0100 Subject: [PATCH 3/7] update call to fetch_canister_logs --- docs/references/_attachments/ic.did | 2 +- docs/references/ic-interface-spec.md | 145 +++++++++++++++++---------- 2 files changed, 91 insertions(+), 56 deletions(-) diff --git a/docs/references/_attachments/ic.did b/docs/references/_attachments/ic.did index ddaffc09b3..0651ae67bf 100644 --- a/docs/references/_attachments/ic.did +++ b/docs/references/_attachments/ic.did @@ -676,5 +676,5 @@ service ic : { delete_canister_snapshot : (delete_canister_snapshot_args) -> (); // canister logging - fetch_canister_logs : (fetch_canister_logs_args) -> (fetch_canister_logs_result) query; + fetch_canister_logs : (fetch_canister_logs_args) -> (fetch_canister_logs_result); }; diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md index 6a89c983aa..5bbceccd88 100644 --- a/docs/references/ic-interface-spec.md +++ b/docs/references/ic-interface-spec.md @@ -3221,7 +3221,7 @@ A snapshot may be deleted only by the controllers of the canister that the snaps ### IC method `fetch_canister_logs` {#ic-fetch_canister_logs} -This method can only be called by external users via non-replicated (query) calls, i.e., it cannot be called by canisters, cannot be called via replicated calls, and cannot be called from composite query calls. +This method can only be called by external users via non-replicated (query) calls or by canisters (via replicated calls), i.e., it cannot be called by external users via replicated (update) calls and it cannot be called from composite query calls. Given a canister ID as input, this method returns a vector of logs of that canister including its trap messages. The canister logs are *not* collected in canister methods running in non-replicated mode (NRQ, TQ, CQ, CRy, CRt, CC, and F modes, as defined in [Overview of imports](#system-api-imports)) and the canister logs are *purged* when the canister is reinstalled or uninstalled. @@ -7218,6 +7218,95 @@ S with ``` +#### IC Management Canister: Canister logs {#ic-mgmt-canister-fetch-canister-logs} + +Given a state `S`, `Canister_id`, and `Sender`, we define + +```html + +canister_logs(S, Canister_id) = S.canister_logs[A.canister_id] +fetch_canister_logs_cost(S, Canister_id) = +is_sender_authorized(S, Canister_id, Sender) = + (S[Canister_id].canister_log_visibility = Public) + or + (S[Canister_id].canister_log_visibility = Controllers and Sender in S[Canister_id].controllers) + or + (S[Canister_id].canister_log_visibility = AllowedViewers Principals and (Sender in S[Canister_id].controllers or Sender in Principals)) + +``` + +Conditions + +```html + +S.messages = Older_messages · CallMessage M · Younger_messages +(M.queue = Unordered) or (∀ CallMessage M' | FuncMessage M' ∈ Older_messages. M'.queue ≠ M.queue) +M.callee = ic_principal +M.method_name = 'fetch_canister_logs' +M.arg = candid(A) +fetch_canister_logs_cost(S, A.canister_id) <= M.transferred_cycles +is_sender_authorized(S, A.canister_id, M.caller) + +``` + +State after + +```html + +S with + messages = Older_messages · Younger_messages · + ResponseMessage { + origin = M.origin + response = candid(canister_logs(S, A.canister_id)) + refunded_cycles = M.transferred_cycles - fetch_canister_logs_cost(S, A.canister_id) + } + +``` + +The IC method `fetch_canister_logs` can also be invoked via management canister query calls. +They are calls to `/api/v3/canister//query` +with CBOR content `Q` such that `Q.canister_id = ic_principal`. + +Submitted request to `/api/v3/canister//query` + +```html + +E : Envelope + +``` + +Conditions + +```html + +E.content = CanisterQuery Q +Q.canister_id = ic_principal +Q.method_name = 'fetch_canister_logs' +|Q.nonce| <= 32 +is_effective_canister_id(E.content, ECID) +S.system_time <= Q.ingress_expiry or Q.sender = anonymous_id +Q.arg = candid(A) +A.canister_id ∈ verify_envelope(E, Q.sender, S.system_time) +is_sender_authorized(S, A.canister_id, Q.sender) + +``` + +Query response `R`: + +```html + +{status: "replied"; reply: {arg: candid(canister_logs(S, A.canister_id))}, signatures: Sigs} + +``` + +where the query `Q`, the response `R`, and a certificate `Cert` that is obtained by requesting the path `/subnet` in a **separate** read state request to `/api/v3/canister//read_state` satisfy the following: + +```html + +verify_response(Q, R, Cert) ∧ lookup(["time"], Cert) = Found S.system_time // or "recent enough" + +``` + #### Callback invocation When an inter-canister call has been responded to, we can queue the call to the callback. @@ -7692,60 +7781,6 @@ S with ``` -#### IC Management Canister: Canister logs (query call) {#ic-mgmt-canister-fetch-canister-logs} - -This section specifies management canister query calls. -They are calls to `/api/v3/canister//query` -with CBOR content `Q` such that `Q.canister_id = ic_principal`. - -The management canister offers the method `fetch_canister_logs` -that can be called as a query call and -returns logs of a requested canister. - -Submitted request to `/api/v3/canister//query` - -```html - -E : Envelope - -``` - -Conditions - -```html - -E.content = CanisterQuery Q -Q.canister_id = ic_principal -Q.method_name = 'fetch_canister_logs' -|Q.nonce| <= 32 -is_effective_canister_id(E.content, ECID) -S.system_time <= Q.ingress_expiry or Q.sender = anonymous_id -Q.arg = candid(A) -A.canister_id ∈ verify_envelope(E, Q.sender, S.system_time) -(S[A.canister_id].canister_log_visibility = Public) - or - (S[A.canister_id].canister_log_visibility = Controllers and Q.sender in S[A.canister_id].controllers) - or - (S[A.canister_id].canister_log_visibility = AllowedViewers Principals and (Q.sender in S[A.canister_id].controllers or Q.sender in Principals)) - -``` - -Query response `R`: - -```html - -{status: "replied"; reply: {arg: candid(S.canister_logs[A.canister_id])}, signatures: Sigs} - -``` - -where the query `Q`, the response `R`, and a certificate `Cert` that is obtained by requesting the path `/subnet` in a **separate** read state request to `/api/v3/canister//read_state` satisfy the following: - -```html - -verify_response(Q, R, Cert) ∧ lookup(["time"], Cert) = Found S.system_time // or "recent enough" - -``` - #### Query call {#query-call} This section specifies query calls `Q` whose `Q.canister_id` is a non-empty canister `S.canisters[Q.canister_id]`. Query calls to the management canister, i.e., `Q.canister_id = ic_principal`, are specified in Section [Canister logs](#ic-mgmt-canister-fetch-canister-logs). From 0f3a57e1b87c5299eb16f38fef77d4ea9c5d1c1d Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Fri, 6 Mar 2026 15:41:58 +0100 Subject: [PATCH 4/7] log_memory_store_size --- docs/references/_attachments/ic.did | 1 + docs/references/ic-interface-spec.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/references/_attachments/ic.did b/docs/references/_attachments/ic.did index 0651ae67bf..9a45fb5468 100644 --- a/docs/references/_attachments/ic.did +++ b/docs/references/_attachments/ic.did @@ -294,6 +294,7 @@ type canister_status_result = record { canister_history_size : nat; wasm_chunk_store_size : nat; snapshots_size : nat; + log_memory_store_size : nat; }; cycles : nat; reserved_cycles : nat; diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md index 5bbceccd88..aa21162876 100644 --- a/docs/references/ic-interface-spec.md +++ b/docs/references/ic-interface-spec.md @@ -2631,6 +2631,8 @@ Only the controllers of the canister or the canister itself can request its stat * `snapshots_size`: Represents the memory consumed by all snapshots that belong to this canister. + * `log_memory_store_size`: Represents the memory used by the canister log memory store of the canister. + All sizes are expressed in bytes. ### IC method `canister_info` {#ic-canister_info} From 56c93a0623931cf811237b8d386976a7e9ce6377 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Fri, 6 Mar 2026 15:43:18 +0100 Subject: [PATCH 5/7] formulation --- docs/references/ic-interface-spec.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md index aa21162876..7eb02e67c6 100644 --- a/docs/references/ic-interface-spec.md +++ b/docs/references/ic-interface-spec.md @@ -2631,7 +2631,7 @@ Only the controllers of the canister or the canister itself can request its stat * `snapshots_size`: Represents the memory consumed by all snapshots that belong to this canister. - * `log_memory_store_size`: Represents the memory used by the canister log memory store of the canister. + * `log_memory_store_size`: Represents the memory used by canister logs of the canister. All sizes are expressed in bytes. From 4cc2dede1763cdd2b4bb7a7df0b17a95f4d4f35a Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Wed, 6 May 2026 11:41:47 +0000 Subject: [PATCH 6/7] log_memory_limit and memory_allocation must not be set together --- docs/references/ic-interface-spec.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md index 041ca9f318..fe0395f371 100644 --- a/docs/references/ic-interface-spec.md +++ b/docs/references/ic-interface-spec.md @@ -2541,6 +2541,8 @@ The optional `settings` parameter can be used to set the following settings: Default value: `null` (i.e., no environment variables provided). +If `log_memory_limit` is set, `memory_allocation` may not be set in the same call. + The optional `sender_canister_version` parameter can contain the caller's canister version. If provided, its value must be equal to `ic0.canister_version`. Until code is installed, the canister is `Empty` and behaves like a canister that has no public methods. @@ -2555,6 +2557,8 @@ Only *controllers* of the canister can update settings. See [IC method](#ic-crea Not including a setting in the `settings` record means not changing that field. The defaults described above are only relevant during canister creation. +If `log_memory_limit` is set, `memory_allocation` may not be set in the same call. + The optional `sender_canister_version` parameter can contain the caller's canister version. If provided, its value must be equal to `ic0.canister_version`. ### IC method `upload_chunk` {#ic-upload_chunk} @@ -3497,6 +3501,8 @@ This method can be called by canisters as well as by external users via ingress As a provisional method on development instances, the `provisional_create_canister_with_cycles` method is provided. It behaves as `create_canister`, but initializes the canister's balance with `amount` fresh cycles (using `DEFAULT_PROVISIONAL_CYCLES_BALANCE` if `amount = null`). If `specified_id` is provided, the canister is created under this id. Note that canister creation using `create_canister` or `provisional_create_canister_with_cycles` with `specified_id = null` can fail after calling `provisional_create_canister_with_cycles` with provided `specified_id`. In that case, canister creation should be retried. +If `log_memory_limit` is set, `memory_allocation` may not be set in the same call. + The optional `sender_canister_version` parameter can contain the caller's canister version. If provided, its value must be equal to `ic0.canister_version`. Cycles added to this call via `ic0.call_cycles_add` and `ic0.call_cycles_add128` are returned to the caller. @@ -5401,6 +5407,7 @@ SubnetId ∈ Subnets |value| ≤ MAX_ENV_VAR_VALUE_LENGTH and is_valid_utf8(name) and is_valid_utf8(value))) +(A.settings.log_memory_limit is null or A.settings.memory_allocation is null) if A.settings.controllers is not null: New_controllers = A.settings.controllers @@ -5555,6 +5562,7 @@ M.caller ∈ S.controllers[A.canister_id] |value| ≤ MAX_ENV_VAR_VALUE_LENGTH and is_valid_utf8(name) and is_valid_utf8(value))) +(A.settings.log_memory_limit is null or A.settings.memory_allocation is null) if New_wasm_memory_limit > 0: |S.canisters[A.canister_id].wasm_state.wasm_memory| ≤ New_wasm_memory_limit @@ -6759,6 +6767,7 @@ Canister_id ∉ dom(S.canisters) |value| ≤ MAX_ENV_VAR_VALUE_LENGTH and is_valid_utf8(name) and is_valid_utf8(value))) +(A.settings.log_memory_limit is null or A.settings.memory_allocation is null) if A.specified_id is not null: Canister_id = A.specified_id From fc076f4ed94b1429317b461c4b11c8b18eb33246 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Thu, 7 May 2026 15:40:16 +0200 Subject: [PATCH 7/7] Revert "log_memory_limit and memory_allocation must not be set together" This reverts commit 4cc2dede1763cdd2b4bb7a7df0b17a95f4d4f35a. --- docs/references/ic-interface-spec.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/references/ic-interface-spec.md b/docs/references/ic-interface-spec.md index fe0395f371..041ca9f318 100644 --- a/docs/references/ic-interface-spec.md +++ b/docs/references/ic-interface-spec.md @@ -2541,8 +2541,6 @@ The optional `settings` parameter can be used to set the following settings: Default value: `null` (i.e., no environment variables provided). -If `log_memory_limit` is set, `memory_allocation` may not be set in the same call. - The optional `sender_canister_version` parameter can contain the caller's canister version. If provided, its value must be equal to `ic0.canister_version`. Until code is installed, the canister is `Empty` and behaves like a canister that has no public methods. @@ -2557,8 +2555,6 @@ Only *controllers* of the canister can update settings. See [IC method](#ic-crea Not including a setting in the `settings` record means not changing that field. The defaults described above are only relevant during canister creation. -If `log_memory_limit` is set, `memory_allocation` may not be set in the same call. - The optional `sender_canister_version` parameter can contain the caller's canister version. If provided, its value must be equal to `ic0.canister_version`. ### IC method `upload_chunk` {#ic-upload_chunk} @@ -3501,8 +3497,6 @@ This method can be called by canisters as well as by external users via ingress As a provisional method on development instances, the `provisional_create_canister_with_cycles` method is provided. It behaves as `create_canister`, but initializes the canister's balance with `amount` fresh cycles (using `DEFAULT_PROVISIONAL_CYCLES_BALANCE` if `amount = null`). If `specified_id` is provided, the canister is created under this id. Note that canister creation using `create_canister` or `provisional_create_canister_with_cycles` with `specified_id = null` can fail after calling `provisional_create_canister_with_cycles` with provided `specified_id`. In that case, canister creation should be retried. -If `log_memory_limit` is set, `memory_allocation` may not be set in the same call. - The optional `sender_canister_version` parameter can contain the caller's canister version. If provided, its value must be equal to `ic0.canister_version`. Cycles added to this call via `ic0.call_cycles_add` and `ic0.call_cycles_add128` are returned to the caller. @@ -5407,7 +5401,6 @@ SubnetId ∈ Subnets |value| ≤ MAX_ENV_VAR_VALUE_LENGTH and is_valid_utf8(name) and is_valid_utf8(value))) -(A.settings.log_memory_limit is null or A.settings.memory_allocation is null) if A.settings.controllers is not null: New_controllers = A.settings.controllers @@ -5562,7 +5555,6 @@ M.caller ∈ S.controllers[A.canister_id] |value| ≤ MAX_ENV_VAR_VALUE_LENGTH and is_valid_utf8(name) and is_valid_utf8(value))) -(A.settings.log_memory_limit is null or A.settings.memory_allocation is null) if New_wasm_memory_limit > 0: |S.canisters[A.canister_id].wasm_state.wasm_memory| ≤ New_wasm_memory_limit @@ -6767,7 +6759,6 @@ Canister_id ∉ dom(S.canisters) |value| ≤ MAX_ENV_VAR_VALUE_LENGTH and is_valid_utf8(name) and is_valid_utf8(value))) -(A.settings.log_memory_limit is null or A.settings.memory_allocation is null) if A.specified_id is not null: Canister_id = A.specified_id