From 4adbf8f0abb15c0142d226a207569dd273420d31 Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:54:28 +0200 Subject: [PATCH 01/17] fix: create II subnet when using PocketIC (#3935) --- src/dfx/src/actors/pocketic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dfx/src/actors/pocketic.rs b/src/dfx/src/actors/pocketic.rs index 102f943d44..150e6f860f 100644 --- a/src/dfx/src/actors/pocketic.rs +++ b/src/dfx/src/actors/pocketic.rs @@ -326,7 +326,7 @@ async fn initialize_pocketic( let mut subnet_config_set = ExtendedSubnetConfigSet { nns: Some(SubnetSpec::default()), sns: Some(SubnetSpec::default()), - ii: None, + ii: Some(SubnetSpec::default()), fiduciary: None, bitcoin: None, system: vec![], From 5e57d0cbf244256d7f418a262717e36f81e66fee Mon Sep 17 00:00:00 2001 From: Vincent Zhang <118719397+vincent-dfinity@users.noreply.github.com> Date: Thu, 3 Oct 2024 20:16:17 +0800 Subject: [PATCH 02/17] feat: Supports the allowed viewer list for the canister log. (#3921) --- CHANGELOG.md | 8 + docs/cli-reference/dfx-canister.mdx | 8 +- docs/dfx-json-schema.json | 29 +++- e2e/tests-dfx/canister_logs.bash | 26 ++++ e2e/tests-dfx/create.bash | 45 ++++++ e2e/tests-dfx/update_settings.bash | 80 ++++++++++ src/dfx-core/src/config/model/dfinity.rs | 12 +- src/dfx/src/commands/canister/create.rs | 19 ++- src/dfx/src/commands/canister/status.rs | 10 +- .../src/commands/canister/update_settings.rs | 76 +++++++--- .../src/lib/canister_logs/log_visibility.rs | 142 ++++++++++++++++++ src/dfx/src/lib/canister_logs/mod.rs | 1 + src/dfx/src/lib/ic_attributes/mod.rs | 12 +- src/dfx/src/lib/mod.rs | 1 + src/dfx/src/util/clap/parsers.rs | 8 + 15 files changed, 439 insertions(+), 38 deletions(-) create mode 100644 src/dfx/src/lib/canister_logs/log_visibility.rs create mode 100644 src/dfx/src/lib/canister_logs/mod.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e48759880..19db6531da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ # UNRELEASED +### feat: Support canister log allowed viewer list + +Added support for the canister log allowed viewer list, enabling specified users to access a canister's logs without needing to be set as the canister's controller. +Valid settings are: +- `--add-log-viewer`, `--remove-log-viewer` and `--set-log-viewer` flags with `dfx canister update-settings` +- `--log-viewer` flag with `dfx canister create` +- `canisters[].initialization_values.log_visibility.allowed_viewers` in `dfx.json` + # 0.24.1 ### feat: More PocketIC flags supported diff --git a/docs/cli-reference/dfx-canister.mdx b/docs/cli-reference/dfx-canister.mdx index 39e606227a..fd306c111c 100644 --- a/docs/cli-reference/dfx-canister.mdx +++ b/docs/cli-reference/dfx-canister.mdx @@ -280,7 +280,8 @@ You can use the following options with the `dfx canister create` command. | `--memory-allocation ` | Specifies how much memory the canister is allowed to use in total. This should be a value in the range [0..12 GiB]. A setting of 0 means the canister will have access to memory on a “best-effort” basis: It will only be charged for the memory it uses, but at any point in time may stop running if it tries to allocate more memory when there isn’t space available on the subnet. | | `--reserved-cycles-limit ` | Specifies the upper limit for the canister's reserved cycles. | | `--wasm-memory-limit ` | Specifies a soft upper limit for the canister's heap memory. | -| `--log-visibility ` | Specifies who is allowed to read the canister's logs. Can be either "controllers" or "public". | +| `--log-viewer ` | Specifies the principal as an allowed viewers. Can be specified more than once. Cannot be used with `--log-visibility`. | +| `--log-visibility ` | Specifies who can read the canister's logs: "controllers" or "public". For custom allowed viewers, use `--log-viewer`. | | `--no-wallet` | Performs the call with the user Identity as the Sender of messages. Bypasses the Wallet canister. Enabled by default. | | `--with-cycles ` | Specifies the initial cycle balance to deposit into the newly created canister. The specified amount needs to take the canister create fee into account. This amount is deducted from the wallet's cycle balance. | | `--specified-id ` | Attempts to create the canister with this Canister ID | @@ -1137,14 +1138,17 @@ You can specify the following options for the `dfx canister update-settings` com | Option | Description | |-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `--add-controller ` | Add a principal to the list of controllers of the canister. | +| `--add-log-viewer ` | Add a principal to the list of log viewers of the canister. Can be specified more than once to add multiple log viewers. If current log visibility is `public` or `controllers`, it will be changed to the custom allowed viewer list. | | `-c`, `--compute-allocation ` | Specifies the canister's compute allocation. This should be a percent in the range [0..100]. | | `--confirm-very-long-freezing-threshold` | Freezing thresholds above ~1.5 years require this option as confirmation. | | `--set-controller ` | Specifies the identity name or the principal of the new controller. Can be specified more than once, indicating the canister will have multiple controllers. If any controllers are set with this parameter, any other controllers will be removed. | +| `--set-log-viewer ` | Specifies the the principal of the log viewer of the canister. Can be specified more than once, indicating the canister will have multiple log viewers. If any log viewers are set with this parameter, any other log viewers will be removed. If current log visibility is `public` or `controllers`, it will be changed to the custom allowed viewer list. | | `--memory-allocation ` | Specifies how much memory the canister is allowed to use in total. This should be a value in the range [0..12 GiB]. A setting of 0 means the canister will have access to memory on a “best-effort” basis: It will only be charged for the memory it uses, but at any point in time may stop running if it tries to allocate more memory when there isn’t space available on the subnet. | | `--reserved-cycles-limit ` | Specifies the upper limit of the canister's reserved cycles. | | `--wasm-memory-limit ` | Specifies a soft upper limit for the canister's heap memory. | -| `--log-visibility ` | Specifies who is allowed to read the canister's logs. Can be either "controllers" or "public". | +| `--log-visibility ` | Specifies who is allowed to read the canister's logs. Can be either "controllers" or "public". For custom allowed viewers, use `--set-log-viewer` or `--add-log-viewer`. | | `--remove-controller ` | Removes a principal from the list of controllers of the canister. | +| `--remove-log-viewer ` | Removes a principal from the list of log viewers of the canister. Can be specified more than once to remove multiple log viewers. | | `--freezing-threshold ` | Set the [freezing threshold](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-create_canister) in seconds for a canister. This should be a value in the range [0..2^64^-1]. Very long thresholds require the `--confirm-very-long-freezing-threshold` option. | | `-y`, `--yes` | Skips yes/no checks by answering 'yes'. Such checks can result in loss of control, so this is not recommended outside of CI. | diff --git a/docs/dfx-json-schema.json b/docs/dfx-json-schema.json index ec157b6e98..3e7240d3a4 100644 --- a/docs/dfx-json-schema.json +++ b/docs/dfx-json-schema.json @@ -137,10 +137,29 @@ } }, "CanisterLogVisibility": { - "type": "string", - "enum": [ - "controllers", - "public" + "oneOf": [ + { + "type": "string", + "enum": [ + "controllers", + "public" + ] + }, + { + "type": "object", + "required": [ + "allowed_viewers" + ], + "properties": { + "allowed_viewers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } ] }, "CanisterMetadataSection": { @@ -947,7 +966,7 @@ }, "log_visibility": { "title": "Log Visibility", - "description": "Specifies who is allowed to read the canister's logs.\n\nCan be \"public\" or \"controllers\".", + "description": "Specifies who is allowed to read the canister's logs.\n\nCan be \"public\", \"controllers\" or \"allowed_viewers\" with a list of principals.", "anyOf": [ { "$ref": "#/definitions/CanisterLogVisibility" diff --git a/e2e/tests-dfx/canister_logs.bash b/e2e/tests-dfx/canister_logs.bash index 27f6de53c6..367d10fcae 100644 --- a/e2e/tests-dfx/canister_logs.bash +++ b/e2e/tests-dfx/canister_logs.bash @@ -65,3 +65,29 @@ dfx_canister_logs_tail_n_1() { assert_not_contains "Alice" assert_contains "Bob" } + +@test "canister logs only visible to allowed viewers." { + install_asset logs + dfx_start + dfx canister create --all + dfx build + dfx canister install e2e_project + dfx canister call e2e_project hello Alice + sleep 2 + + assert_command dfx canister logs e2e_project + assert_contains "Hello, Alice!" + + # Create identity for viewers. + assert_command dfx identity new --storage-mode plaintext alice + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + + assert_command_fail dfx canister logs e2e_project --identity alice + + assert_command dfx canister update-settings --add-log-viewer="${ALICE_PRINCIPAL}" e2e_project + assert_command dfx canister status e2e_project + assert_contains "${ALICE_PRINCIPAL}" + + assert_command dfx canister logs e2e_project --identity alice + assert_contains "Hello, Alice!" +} diff --git a/e2e/tests-dfx/create.bash b/e2e/tests-dfx/create.bash index 9c15e48f77..58f54097c9 100644 --- a/e2e/tests-dfx/create.bash +++ b/e2e/tests-dfx/create.bash @@ -352,3 +352,48 @@ teardown() { assert_contains 'Freezing threshold: 2_592_000' assert_contains 'Log visibility: controllers' } + +@test "create with multiple log allowed viewer list in dfx.json" { + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + + jq '.canisters.e2e_project_backend.initialization_values={ + "compute_allocation": 5, + "freezing_threshold": "7days", + "memory_allocation": "2 GiB", + "reserved_cycles_limit": 1000000000000, + "wasm_memory_limit": "1 GiB", + "log_visibility": { + "allowed_viewers" : + ['\""$ALICE_PRINCIPAL"\"', '\""$BOB_PRINCIPAL"\"'] + } + }' dfx.json | sponge dfx.json + dfx_start + assert_command dfx deploy e2e_project_backend --no-wallet + assert_command dfx canister status e2e_project_backend + assert_contains 'Memory allocation: 2_147_483_648' + assert_contains 'Compute allocation: 5' + assert_contains 'Reserved cycles limit: 1_000_000_000_000' + assert_contains 'Wasm memory limit: 1_073_741_824' + assert_contains 'Freezing threshold: 604_800' + assert_contains "${ALICE_PRINCIPAL}" + assert_contains "${BOB_PRINCIPAL}" +} + +@test "create with multiple log allowed viewer list" { + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + + dfx_start + assert_command dfx canister create --all --log-viewer "${ALICE_PRINCIPAL}" --log-viewer "${BOB_PRINCIPAL}" --no-wallet + assert_command dfx deploy e2e_project_backend --no-wallet + assert_command dfx canister status e2e_project_backend + assert_contains "${ALICE_PRINCIPAL}" + assert_contains "${BOB_PRINCIPAL}" +} diff --git a/e2e/tests-dfx/update_settings.bash b/e2e/tests-dfx/update_settings.bash index 63af5cb86f..74d668cf61 100644 --- a/e2e/tests-dfx/update_settings.bash +++ b/e2e/tests-dfx/update_settings.bash @@ -66,6 +66,8 @@ teardown() { dfx_start assert_command dfx deploy e2e_project_backend assert_command dfx canister status e2e_project_backend + + # Test against a single canister. assert_contains "Log visibility: controllers" assert_command dfx canister update-settings e2e_project_backend --log-visibility public assert_command dfx canister status e2e_project_backend @@ -73,6 +75,84 @@ teardown() { assert_command dfx canister update-settings e2e_project_backend --log-visibility controllers assert_command dfx canister status e2e_project_backend assert_contains "Log visibility: controllers" + + # Test --all code path. + assert_command dfx canister update-settings --log-visibility public --all + assert_command dfx canister status e2e_project_backend + assert_contains "Log visibility: public" + assert_command dfx canister update-settings --log-visibility controllers --all + assert_command dfx canister status e2e_project_backend + assert_contains "Log visibility: controllers" +} + +@test "update log allowed viewer list" { + # Create two identities + assert_command dfx identity new --storage-mode plaintext alice + assert_command dfx identity new --storage-mode plaintext bob + ALICE_PRINCIPAL=$(dfx identity get-principal --identity alice) + BOB_PRINCIPAL=$(dfx identity get-principal --identity bob) + + dfx_new + dfx_start + assert_command dfx deploy e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "Log visibility: controllers" + + # Test against a single canister. + assert_command dfx canister update-settings --add-log-viewer="${ALICE_PRINCIPAL}" e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "${ALICE_PRINCIPAL}" + + assert_command dfx canister update-settings --remove-log-viewer="${BOB_PRINCIPAL}" e2e_project_backend + assert_contains "'${BOB_PRINCIPAL}' is not in the allowed list" + + assert_command dfx canister update-settings --add-log-viewer="${BOB_PRINCIPAL}" --remove-log-viewer="${ALICE_PRINCIPAL}" e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "${BOB_PRINCIPAL}" + assert_not_contains "${ALICE_PRINCIPAL}" + + assert_command dfx canister update-settings --set-log-viewer="${ALICE_PRINCIPAL}" e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "${ALICE_PRINCIPAL}" + assert_not_contains "${BOB_PRINCIPAL}" + + assert_command dfx canister update-settings --remove-log-viewer="${ALICE_PRINCIPAL}" e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "allowed viewers list is empty" + + assert_command dfx canister update-settings --add-log-viewer="${BOB_PRINCIPAL}" --add-log-viewer="${ALICE_PRINCIPAL}" e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "${ALICE_PRINCIPAL}" + assert_contains "${BOB_PRINCIPAL}" + + assert_command dfx canister update-settings --remove-log-viewer="${ALICE_PRINCIPAL}" --remove-log-viewer="${BOB_PRINCIPAL}" e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "allowed viewers list is empty" + + assert_command dfx canister update-settings --set-log-viewer="${BOB_PRINCIPAL}" --set-log-viewer="${ALICE_PRINCIPAL}" e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "${ALICE_PRINCIPAL}" + assert_contains "${BOB_PRINCIPAL}" + + assert_command dfx canister update-settings --log-visibility controllers e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains "Log visibility: controllers" + + assert_command_fail dfx canister update-settings --remove-log-viewer="${BOB_PRINCIPAL}" e2e_project_backend + assert_contains "Removing reviewers is not allowed with 'public' or 'controllers' log visibility." + + # Test --all code path. + assert_command dfx canister update-settings --add-log-viewer="${ALICE_PRINCIPAL}" --all + assert_command dfx canister status e2e_project_backend + assert_contains "${ALICE_PRINCIPAL}" + + assert_command dfx canister update-settings --remove-log-viewer="${ALICE_PRINCIPAL}" --all + assert_command dfx canister status e2e_project_backend + assert_contains "allowed viewers list is empty" + + assert_command dfx canister update-settings --set-log-viewer="${ALICE_PRINCIPAL}" --all + assert_command dfx canister status e2e_project_backend + assert_contains "${ALICE_PRINCIPAL}" } @test "set controller" { diff --git a/src/dfx-core/src/config/model/dfinity.rs b/src/dfx-core/src/config/model/dfinity.rs index 6fe142b1f6..e26edada97 100644 --- a/src/dfx-core/src/config/model/dfinity.rs +++ b/src/dfx-core/src/config/model/dfinity.rs @@ -407,12 +407,14 @@ impl CanisterTypeProperties { } } -#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "lowercase")] +#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] pub enum CanisterLogVisibility { #[default] Controllers, Public, + #[schemars(with = "Vec::")] + AllowedViewers(Vec), } impl From for LogVisibility { @@ -420,6 +422,9 @@ impl From for LogVisibility { match value { CanisterLogVisibility::Controllers => LogVisibility::Controllers, CanisterLogVisibility::Public => LogVisibility::Public, + CanisterLogVisibility::AllowedViewers(viewers) => { + LogVisibility::AllowedViewers(viewers) + } } } } @@ -475,7 +480,7 @@ pub struct InitializationValues { /// # Log Visibility /// Specifies who is allowed to read the canister's logs. /// - /// Can be "public" or "controllers". + /// Can be "public", "controllers" or "allowed_viewers" with a list of principals. #[schemars(with = "Option")] pub log_visibility: Option, } @@ -1008,6 +1013,7 @@ impl ConfigInterface { .map_err(|e| GetLogVisibilityFailed(canister_name.to_string(), e))? .initialization_values .log_visibility + .clone() .map(|visibility| visibility.into())) } diff --git a/src/dfx/src/commands/canister/create.rs b/src/dfx/src/commands/canister/create.rs index f949ef5fa5..a5293f0f1c 100644 --- a/src/dfx/src/commands/canister/create.rs +++ b/src/dfx/src/commands/canister/create.rs @@ -1,3 +1,4 @@ +use crate::lib::canister_logs::log_visibility::LogVisibilityOpt; use crate::lib::deps::get_pull_canisters_in_config; use crate::lib::environment::Environment; use crate::lib::error::{DfxError, DfxResult}; @@ -9,7 +10,8 @@ use crate::lib::operations::canister::create_canister; use crate::lib::root_key::fetch_root_key_if_needed; use crate::util::clap::parsers::{ compute_allocation_parser, freezing_threshold_parser, log_visibility_parser, - memory_allocation_parser, reserved_cycles_limit_parser, wasm_memory_limit_parser, + memory_allocation_parser, principal_parser, reserved_cycles_limit_parser, + wasm_memory_limit_parser, }; use crate::util::clap::parsers::{cycle_amount_parser, icrc_subaccount_parser}; use crate::util::clap::subnet_selection_opt::SubnetSelectionOpt; @@ -92,9 +94,14 @@ pub struct CanisterCreateOpts { /// Specifies who is allowed to read the canister's logs. /// Can be either "controllers" or "public". - #[arg(long, value_parser = log_visibility_parser)] + #[arg(long, value_parser = log_visibility_parser, conflicts_with("log_viewer"))] log_visibility: Option, + /// Specifies the the principal of the log viewer of the canister. + /// Can be specified more than once. + #[arg(long, action = ArgAction::Append, value_parser = principal_parser, conflicts_with("log_visibility"))] + log_viewer: Option>, + /// Performs the call with the user Identity as the Sender of messages. /// Bypasses the Wallet canister. #[arg(long)] @@ -202,7 +209,9 @@ pub async fn exec( ) .with_context(|| format!("Failed to read Wasm memory limit of {canister_name}."))?; let log_visibility = get_log_visibility( - opts.log_visibility, + env, + LogVisibilityOpt::from(&opts.log_visibility, &opts.log_viewer).as_ref(), + None, Some(config_interface), Some(canister_name), ) @@ -285,7 +294,9 @@ pub async fn exec( ) .with_context(|| format!("Failed to read Wasm memory limit of {canister_name}."))?; let log_visibility = get_log_visibility( - opts.log_visibility.clone(), + env, + LogVisibilityOpt::from(&opts.log_visibility, &opts.log_viewer).as_ref(), + None, Some(config_interface), Some(canister_name), ) diff --git a/src/dfx/src/commands/canister/status.rs b/src/dfx/src/commands/canister/status.rs index 8bac6b2eb8..2270d2e6ee 100644 --- a/src/dfx/src/commands/canister/status.rs +++ b/src/dfx/src/commands/canister/status.rs @@ -55,9 +55,13 @@ async fn canister_status( LogVisibility::Controllers => "controllers".to_string(), LogVisibility::Public => "public".to_string(), LogVisibility::AllowedViewers(viewers) => { - let mut viewers: Vec<_> = viewers.iter().map(Principal::to_text).collect(); - viewers.sort(); - format!("allowed viewers: {}", viewers.join(", ")) + if viewers.is_empty() { + "allowed viewers list is empty".to_string() + } else { + let mut viewers: Vec<_> = viewers.iter().map(Principal::to_text).collect(); + viewers.sort(); + format!("allowed viewers: {}", viewers.join(", ")) + } } }; diff --git a/src/dfx/src/commands/canister/update_settings.rs b/src/dfx/src/commands/canister/update_settings.rs index 8367e6ff39..f6867c58af 100644 --- a/src/dfx/src/commands/canister/update_settings.rs +++ b/src/dfx/src/commands/canister/update_settings.rs @@ -1,3 +1,4 @@ +use crate::lib::canister_logs::log_visibility::LogVisibilityOpt; use crate::lib::diagnosis::DiagnosedError; use crate::lib::environment::Environment; use crate::lib::error::{DfxError, DfxResult}; @@ -8,8 +9,8 @@ use crate::lib::ic_attributes::{ use crate::lib::operations::canister::{get_canister_status, update_settings}; use crate::lib::root_key::fetch_root_key_if_needed; use crate::util::clap::parsers::{ - compute_allocation_parser, freezing_threshold_parser, log_visibility_parser, - memory_allocation_parser, reserved_cycles_limit_parser, wasm_memory_limit_parser, + compute_allocation_parser, freezing_threshold_parser, memory_allocation_parser, + reserved_cycles_limit_parser, wasm_memory_limit_parser, }; use anyhow::{bail, Context}; use byte_unit::Byte; @@ -20,7 +21,7 @@ use dfx_core::error::identity::InstantiateIdentityFromNameError::GetIdentityPrin use dfx_core::identity::CallSender; use fn_error_context::context; use ic_agent::identity::Identity; -use ic_utils::interfaces::management_canister::LogVisibility; +use ic_utils::interfaces::management_canister::StatusCallResult; /// Update one or more of a canister's settings (i.e its controller, compute allocation, or memory allocation.) #[derive(Parser, Debug)] @@ -88,10 +89,8 @@ pub struct UpdateSettingsOpts { #[arg(long, value_parser = wasm_memory_limit_parser)] wasm_memory_limit: Option, - /// Specifies who is allowed to read the canister's logs. - /// Can be either "controllers" or "public". - #[arg(long, value_parser = log_visibility_parser)] - log_visibility: Option, + #[command(flatten)] + log_visibility_opt: Option, /// Freezing thresholds above ~1.5 years require this flag as confirmation. #[arg(long)] @@ -157,11 +156,29 @@ pub async fn exec( get_reserved_cycles_limit(opts.reserved_cycles_limit, config_interface, canister_name)?; let wasm_memory_limit = get_wasm_memory_limit(opts.wasm_memory_limit, config_interface, canister_name)?; - let log_visibility = - get_log_visibility(opts.log_visibility.clone(), config_interface, canister_name)?; + let mut current_status: Option = None; + if let Some(log_visibility) = &opts.log_visibility_opt { + if log_visibility.require_current_settings() { + current_status = Some(get_canister_status(env, canister_id, call_sender).await?); + } + } + let log_visibility = get_log_visibility( + env, + opts.log_visibility_opt.as_ref(), + current_status.as_ref(), + config_interface, + canister_name, + )?; if let Some(added) = &opts.add_controller { - let status = get_canister_status(env, canister_id, call_sender).await?; - let mut existing_controllers = status.settings.controllers; + if current_status.is_none() { + current_status = Some(get_canister_status(env, canister_id, call_sender).await?); + } + let mut existing_controllers = current_status + .as_ref() + .unwrap() + .settings + .controllers + .clone(); for s in added { existing_controllers.push(controller_to_principal(env, s)?); } @@ -171,8 +188,11 @@ pub async fn exec( let controllers = if opts.add_controller.is_some() { controllers.as_mut().unwrap() } else { - let status = get_canister_status(env, canister_id, call_sender).await?; - controllers.get_or_insert(status.settings.controllers) + if current_status.is_none() { + current_status = + Some(get_canister_status(env, canister_id, call_sender).await?); + } + controllers.get_or_insert(current_status.unwrap().settings.controllers) }; let removed = removed .iter() @@ -240,15 +260,32 @@ pub async fn exec( Some(canister_name), ) .with_context(|| format!("Failed to get Wasm memory limit for {canister_name}."))?; + let mut current_status: Option = None; + if let Some(log_visibility) = &opts.log_visibility_opt { + if log_visibility.require_current_settings() { + current_status = + Some(get_canister_status(env, canister_id, call_sender).await?); + } + } let log_visibility = get_log_visibility( - opts.log_visibility.clone(), + env, + opts.log_visibility_opt.as_ref(), + current_status.as_ref(), Some(config_interface), Some(canister_name), ) .with_context(|| format!("Failed to get log visibility for {canister_name}."))?; if let Some(added) = &opts.add_controller { - let status = get_canister_status(env, canister_id, call_sender).await?; - let mut existing_controllers = status.settings.controllers; + if current_status.is_none() { + current_status = + Some(get_canister_status(env, canister_id, call_sender).await?); + } + let mut existing_controllers = current_status + .as_ref() + .unwrap() + .settings + .controllers + .clone(); for s in added { existing_controllers.push(controller_to_principal(env, s)?); } @@ -258,8 +295,11 @@ pub async fn exec( let controllers = if opts.add_controller.is_some() { controllers.as_mut().unwrap() } else { - let status = get_canister_status(env, canister_id, call_sender).await?; - controllers.get_or_insert(status.settings.controllers) + if current_status.is_none() { + current_status = + Some(get_canister_status(env, canister_id, call_sender).await?); + } + controllers.get_or_insert(current_status.unwrap().settings.controllers) }; let removed = removed .iter() diff --git a/src/dfx/src/lib/canister_logs/log_visibility.rs b/src/dfx/src/lib/canister_logs/log_visibility.rs new file mode 100644 index 0000000000..02e1829cb7 --- /dev/null +++ b/src/dfx/src/lib/canister_logs/log_visibility.rs @@ -0,0 +1,142 @@ +use crate::lib::environment::Environment; +use crate::lib::error::DfxResult; +use crate::util::clap::parsers::{log_visibility_parser, principal_parser}; +use anyhow::anyhow; +use candid::Principal; +use clap::{ArgAction, Args}; +use dfx_core::cli::ask_for_consent; +use ic_utils::interfaces::management_canister::{LogVisibility, StatusCallResult}; + +#[derive(Args, Clone, Debug, Default)] +pub struct LogVisibilityOpt { + /// Specifies who is allowed to read the canister's logs. + /// Can be either "controllers" or "public". + #[arg( + long, + value_parser = log_visibility_parser, + conflicts_with("add_log_viewer"), + conflicts_with("remove_log_viewer"), + conflicts_with("set_log_viewer"), + )] + log_visibility: Option, + + /// Add a principal to the list of log viewers of the canister. + #[arg(long, action = ArgAction::Append, value_parser = principal_parser, conflicts_with("set_log_viewer"))] + add_log_viewer: Option>, + + /// Removes a principal from the list of log viewers of the canister. + #[arg(long, action = ArgAction::Append, value_parser = principal_parser, conflicts_with("set_log_viewer"))] + remove_log_viewer: Option>, + + /// Specifies the the principal of the log viewer of the canister. + /// Can be specified more than once. + #[arg( + long, + action = ArgAction::Append, + value_parser = principal_parser, + conflicts_with("add_log_viewer"), + conflicts_with("remove_log_viewer"), + )] + set_log_viewer: Option>, +} + +impl LogVisibilityOpt { + pub fn require_current_settings(&self) -> bool { + self.add_log_viewer.is_some() || self.remove_log_viewer.is_some() + } + + pub fn from( + log_visibility: &Option, + log_viewer: &Option>, + ) -> Option { + if let Some(log_visibility) = log_visibility { + return Some(LogVisibilityOpt { + log_visibility: Some(log_visibility.clone()), + add_log_viewer: None, + remove_log_viewer: None, + set_log_viewer: None, + }); + } + + if let Some(log_viewer) = log_viewer { + return Some(LogVisibilityOpt { + log_visibility: None, + add_log_viewer: None, + remove_log_viewer: None, + set_log_viewer: Some(log_viewer.clone()), + }); + } + + None + } + + pub fn to_log_visibility( + &self, + env: &dyn Environment, + current_status: Option<&StatusCallResult>, + ) -> DfxResult { + let logger = env.get_logger(); + + // For public and controllers. + if let Some(log_visibility) = self.log_visibility.as_ref() { + return Ok(log_visibility.clone()); + } + + // For setting viewers. + if let Some(principals) = self.set_log_viewer.as_ref() { + return Ok(LogVisibility::AllowedViewers(principals.clone())); + } + + // Get the current viewer list for adding and removing, only for update-settings. + let mut current_visibility: Option = None; + let mut viewers = match current_status { + Some(status) => { + current_visibility = Some(status.settings.log_visibility.clone()); + match &status.settings.log_visibility { + LogVisibility::AllowedViewers(viewers) => viewers.clone(), + _ => vec![], + } + } + None => vec![], + }; + + // Adding. + if let Some(added) = self.add_log_viewer.as_ref() { + if let Some(LogVisibility::Public) = current_visibility { + let msg = "Current log is public to everyone. Adding log reviewers will make the log only visible to the reviewers."; + ask_for_consent(msg)?; + } + + for principal in added { + if !viewers.iter().any(|x| x == principal) { + viewers.push(*principal); + } + } + } + + // Removing. + if let Some(removed) = self.remove_log_viewer.as_ref() { + if let Some(visibility) = ¤t_visibility { + match visibility { + LogVisibility::Public | LogVisibility::Controllers => { + return Err(anyhow!("Removing reviewers is not allowed with 'public' or 'controllers' log visibility.")); + } + _ => (), + } + } + for principal in removed { + if let Some(idx) = viewers.iter().position(|x| x == principal) { + viewers.swap_remove(idx); + } else { + slog::warn!( + logger, + "Principal '{}' is not in the allowed list.", + principal.to_text() + ); + } + } + } + + Ok(LogVisibility::AllowedViewers(viewers)) + } +} diff --git a/src/dfx/src/lib/canister_logs/mod.rs b/src/dfx/src/lib/canister_logs/mod.rs new file mode 100644 index 0000000000..befc0b7994 --- /dev/null +++ b/src/dfx/src/lib/canister_logs/mod.rs @@ -0,0 +1 @@ +pub mod log_visibility; diff --git a/src/dfx/src/lib/ic_attributes/mod.rs b/src/dfx/src/lib/ic_attributes/mod.rs index 7d93589811..a7cf379a02 100644 --- a/src/dfx/src/lib/ic_attributes/mod.rs +++ b/src/dfx/src/lib/ic_attributes/mod.rs @@ -1,3 +1,5 @@ +use crate::lib::canister_logs::log_visibility::LogVisibilityOpt; +use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use anyhow::{anyhow, Context, Error}; use byte_unit::Byte; @@ -7,7 +9,7 @@ use fn_error_context::context; use ic_utils::interfaces::management_canister::{ attributes::{ComputeAllocation, FreezingThreshold, MemoryAllocation, ReservedCyclesLimit}, builders::WasmMemoryLimit, - LogVisibility, + LogVisibility, StatusCallResult, }; use num_traits::ToPrimitive; use std::convert::TryFrom; @@ -218,12 +220,16 @@ pub fn get_wasm_memory_limit( } pub fn get_log_visibility( - log_visibility: Option, + env: &dyn Environment, + log_visibility: Option<&LogVisibilityOpt>, + current_settings: Option<&StatusCallResult>, config_interface: Option<&ConfigInterface>, canister_name: Option<&str>, ) -> DfxResult> { let log_visibility = match (log_visibility, config_interface, canister_name) { - (Some(log_visibility), _, _) => Some(log_visibility), + (Some(log_visibility), _, _) => { + Some(log_visibility.to_log_visibility(env, current_settings)?) + } (None, Some(config_interface), Some(canister_name)) => { config_interface.get_log_visibility(canister_name)? } diff --git a/src/dfx/src/lib/mod.rs b/src/dfx/src/lib/mod.rs index c1d33bc68f..8a93c56690 100644 --- a/src/dfx/src/lib/mod.rs +++ b/src/dfx/src/lib/mod.rs @@ -1,6 +1,7 @@ pub mod agent; pub mod builders; pub mod canister_info; +pub mod canister_logs; pub mod cycles_ledger_types; pub mod deps; pub mod dfxvm; diff --git a/src/dfx/src/util/clap/parsers.rs b/src/dfx/src/util/clap/parsers.rs index 443a599e0e..33f7c8fa21 100644 --- a/src/dfx/src/util/clap/parsers.rs +++ b/src/dfx/src/util/clap/parsers.rs @@ -1,4 +1,5 @@ use byte_unit::{Byte, ByteUnit}; +use candid::Principal; use ic_utils::interfaces::management_canister::LogVisibility; use icrc_ledger_types::icrc1::account::Subaccount; use rust_decimal::Decimal; @@ -137,6 +138,13 @@ pub fn log_visibility_parser(log_visibility: &str) -> Result Result { + match Principal::from_text(principal_text) { + Ok(principal) => Ok(principal), + _ => Err(("Failed to convert to a principal.").to_string()), + } +} + pub fn freezing_threshold_parser(freezing_threshold: &str) -> Result { freezing_threshold .parse::() From c21ff1ef47509de02acc15ad4af59eb4ad213996 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:31:51 -0500 Subject: [PATCH 03/17] Update dfx-envars.mdx (#3938) --- docs/cli-reference/dfx-envars.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/cli-reference/dfx-envars.mdx b/docs/cli-reference/dfx-envars.mdx index a4845569e7..4b9f0ea558 100644 --- a/docs/cli-reference/dfx-envars.mdx +++ b/docs/cli-reference/dfx-envars.mdx @@ -68,3 +68,11 @@ DFX_VERSION=0.13.1 dfx deploy --network ic ## DFX_DISABLE_QUERY_VERIFICATION Set this to a non-empty value to disable verification of replica-signed queries. + +## DFX_REPLICA_PATH + +Use the `DFX_REPLICA_PATH` environment variable to specify a file path to a local version of the replica. If this option is used, `canister_sandbox` and `sandbox_launcher` must be in the same directory with the desired replica version. + +## DFX_IC_STARTER_PATH + +Use the `DFX_IC_STARTER_PATH` environment variable to specify a file path to a local version of `ic-starter`. From ab9b342e608166502a3ab44092be8f23d1bff27d Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Fri, 4 Oct 2024 10:36:45 +0200 Subject: [PATCH 04/17] chore: promote 0.24.0 (#3936) --- Cargo.lock | 2 +- public/manifest.json | 7 ++++--- src/dfx/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0ad8de3c08..c9213a6ab9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1514,7 +1514,7 @@ checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" [[package]] name = "dfx" -version = "0.23.0-beta.3" +version = "0.24.0" dependencies = [ "actix", "aes-gcm", diff --git a/public/manifest.json b/public/manifest.json index 96ba0bf371..55593a164c 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,6 +1,6 @@ { "tags": { - "latest": "0.23.0" + "latest": "0.24.0" }, "versions": [ "0.5.0", @@ -71,6 +71,7 @@ "0.20.1", "0.21.0", "0.22.0", - "0.23.0" + "0.23.0", + "0.24.0" ] -} +} \ No newline at end of file diff --git a/src/dfx/Cargo.toml b/src/dfx/Cargo.toml index e337648599..b87d9dc9a8 100644 --- a/src/dfx/Cargo.toml +++ b/src/dfx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dfx" -version = "0.23.0-beta.3" +version = "0.24.0" authors.workspace = true edition.workspace = true repository.workspace = true From da094deb76c0e95733db69ffea2114a0255fd007 Mon Sep 17 00:00:00 2001 From: mraszyk <31483726+mraszyk@users.noreply.github.com> Date: Mon, 7 Oct 2024 18:38:22 +0200 Subject: [PATCH 05/17] fix: fetch effective canister id from PocketIC topology (#3942) * fix: fetch effective canister id from PocketIC topology * windows build * shellcheck * windows lint * new dynamic library * dynamic --- e2e/tests-dfx/create.bash | 37 ++++++++++++++ .../src/config/model/replica_config.rs | 16 ++++-- src/dfx/src/actors/mod.rs | 1 + src/dfx/src/actors/pocketic.rs | 49 ++++++++++++++++--- src/dfx/src/commands/start.rs | 2 +- src/dfx/src/lib/environment.rs | 4 +- 6 files changed, 95 insertions(+), 14 deletions(-) diff --git a/e2e/tests-dfx/create.bash b/e2e/tests-dfx/create.bash index 58f54097c9..881bee09fa 100644 --- a/e2e/tests-dfx/create.bash +++ b/e2e/tests-dfx/create.bash @@ -397,3 +397,40 @@ teardown() { assert_contains "${ALICE_PRINCIPAL}" assert_contains "${BOB_PRINCIPAL}" } + +# The following function decodes a canister id in the textual form into its binary form +# and is taken from the [IC Interface Specification](https://internetcomputer.org/docs/current/references/ic-interface-spec#principal). +function textual_decode() { + echo -n "$1" | tr -d - | tr "[:lower:]" "[:upper:]" | + fold -w 8 | xargs -n1 printf '%-8s' | tr ' ' = | + base32 -d | xxd -p | tr -d '\n' | cut -b9- | tr "[:lower:]" "[:upper:]" +} + +@test "create targets application subnet in PocketIC" { + [[ ! "$USE_POCKETIC" ]] && skip "skipped for replica: no support for multiple subnets" + dfx_start + # create the backend canister without a wallet canister so that the backend canister is the only canister ever created + assert_command dfx canister create e2e_project_backend --no-wallet + # actual canister id + CANISTER_ID="$(dfx canister id e2e_project_backend)" + # base64 encode the actual canister id + CANISTER_ID_BASE64="$(textual_decode "${CANISTER_ID}" | xxd -r -p | base64)" + # fetch topology from PocketIC server + TOPOLOGY="$(curl "http://127.0.0.1:$(dfx info replica-port)/instances/0/read/topology")" + # find application subnet id in the topology + for subnet_id in $(echo "${TOPOLOGY}" | jq keys[]) + do + SUBNET_KIND="$(echo "$TOPOLOGY" | jq -r ".${subnet_id}.\"subnet_kind\"")" + if [ "${SUBNET_KIND}" == "Application" ] + then + # find the expected canister id as the beginning of the first canister range of the app subnet + EXPECTED_CANISTER_ID_BASE64="$(echo "$TOPOLOGY" | jq -r ".${subnet_id}.\"canister_ranges\"[0].\"start\".\"canister_id\"")" + fi + done + # check if the actual canister id matches the expected canister id + if [ "${CANISTER_ID_BASE64}" != "${EXPECTED_CANISTER_ID_BASE64}" ] + then + echo "Canister id ${CANISTER_ID_BASE64} does not match expected canister id ${EXPECTED_CANISTER_ID_BASE64}" + exit 1 + fi +} diff --git a/src/dfx-core/src/config/model/replica_config.rs b/src/dfx-core/src/config/model/replica_config.rs index 389e6c3c86..ed4164b56d 100644 --- a/src/dfx-core/src/config/model/replica_config.rs +++ b/src/dfx-core/src/config/model/replica_config.rs @@ -1,4 +1,5 @@ use crate::config::model::dfinity::{ReplicaLogLevel, ReplicaSubnetType}; +use candid::Principal; use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::default::Default; @@ -192,6 +193,7 @@ pub enum CachedReplicaConfig<'a> { #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] pub struct CachedConfig<'a> { pub replica_rev: String, + pub effective_canister_id: Option, #[serde(flatten)] pub config: CachedReplicaConfig<'a>, } @@ -200,23 +202,29 @@ impl<'a> CachedConfig<'a> { pub fn replica(config: &'a ReplicaConfig, replica_rev: String) -> Self { Self { replica_rev, + effective_canister_id: None, config: CachedReplicaConfig::Replica { config: Cow::Borrowed(config), }, } } - pub fn pocketic(config: &'a ReplicaConfig, replica_rev: String) -> Self { + pub fn pocketic( + config: &'a ReplicaConfig, + replica_rev: String, + effective_canister_id: Option, + ) -> Self { Self { replica_rev, + effective_canister_id, config: CachedReplicaConfig::PocketIc { config: Cow::Borrowed(config), }, } } - pub fn is_pocketic(&self) -> bool { - matches!(self.config, CachedReplicaConfig::PocketIc { .. }) - } pub fn can_share_state(&self, other: &Self) -> bool { self == other } + pub fn get_effective_canister_id(&self) -> Option { + self.effective_canister_id + } } diff --git a/src/dfx/src/actors/mod.rs b/src/dfx/src/actors/mod.rs index ee44edd16b..721f35a73f 100644 --- a/src/dfx/src/actors/mod.rs +++ b/src/dfx/src/actors/mod.rs @@ -203,6 +203,7 @@ pub fn start_pocketic_actor( let actor_config = pocketic::Config { pocketic_path, + effective_config_path: local_server_descriptor.effective_config_path(), replica_config, port: local_server_descriptor.replica.port, port_file: pocketic_port_path, diff --git a/src/dfx/src/actors/pocketic.rs b/src/dfx/src/actors/pocketic.rs index 150e6f860f..3e8b2a8d3c 100644 --- a/src/dfx/src/actors/pocketic.rs +++ b/src/dfx/src/actors/pocketic.rs @@ -4,14 +4,21 @@ use crate::actors::shutdown_controller::signals::outbound::Shutdown; use crate::actors::shutdown_controller::signals::ShutdownSubscribe; use crate::actors::shutdown_controller::ShutdownController; use crate::lib::error::{DfxError, DfxResult}; +#[cfg(unix)] +use crate::lib::info::replica_rev; use actix::{ Actor, ActorContext, ActorFutureExt, Addr, AsyncContext, Context, Handler, Recipient, ResponseActFuture, Running, WrapFuture, }; use anyhow::{anyhow, bail}; +#[cfg(unix)] use candid::Principal; use crossbeam::channel::{unbounded, Receiver, Sender}; +#[cfg(unix)] +use dfx_core::config::model::replica_config::CachedConfig; use dfx_core::config::model::replica_config::ReplicaConfig; +#[cfg(unix)] +use dfx_core::json::save_json_file; use slog::{debug, error, info, warn, Logger}; use std::ops::ControlFlow::{self, *}; use std::path::{Path, PathBuf}; @@ -30,13 +37,11 @@ pub mod signals { } } -pub const POCKETIC_EFFECTIVE_CANISTER_ID: Principal = - Principal::from_slice(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01, 0x01]); - /// The configuration for the PocketIC actor. #[derive(Clone)] pub struct Config { pub pocketic_path: PathBuf, + pub effective_config_path: PathBuf, pub replica_config: ReplicaConfig, pub port: Option, pub port_file: PathBuf, @@ -257,7 +262,12 @@ fn pocketic_start_thread( } } }; - let instance = match initialize_pocketic(port, &config.replica_config, logger.clone()) { + let instance = match initialize_pocketic( + port, + &config.effective_config_path, + &config.replica_config, + logger.clone(), + ) { Err(e) => { error!(logger, "Failed to initialize PocketIC: {e:#}"); @@ -311,6 +321,7 @@ fn pocketic_start_thread( #[tokio::main(flavor = "current_thread")] async fn initialize_pocketic( port: u16, + effective_config_path: &Path, replica_config: &ReplicaConfig, logger: Logger, ) -> DfxResult { @@ -357,7 +368,33 @@ async fn initialize_pocketic( CreateInstanceResponse::Error { message } => { bail!("PocketIC init error: {message}"); } - CreateInstanceResponse::Created { instance_id, .. } => instance_id, + CreateInstanceResponse::Created { + instance_id, + topology, + } => { + let subnets = match replica_config.subnet_type { + ReplicaSubnetType::Application => topology.get_app_subnets(), + ReplicaSubnetType::System => topology.get_system_subnets(), + ReplicaSubnetType::VerifiedApplication => topology.get_verified_app_subnets(), + }; + if subnets.len() != 1 { + return Err(anyhow!("Internal error: PocketIC topology contains multiple subnets of the same subnet kind.")); + } + let subnet_id = subnets[0]; + let subnet_config = topology.0.get(&subnet_id).ok_or(anyhow!( + "Internal error: subnet id {} not found in PocketIC topology", + subnet_id + ))?; + let effective_canister_id = + Principal::from_slice(&subnet_config.canister_ranges[0].start.canister_id); + let effective_config = CachedConfig::pocketic( + replica_config, + replica_rev().into(), + Some(effective_canister_id), + ); + save_json_file(effective_config_path, &effective_config)?; + instance_id + } }; init_client .post(format!( @@ -387,7 +424,7 @@ async fn initialize_pocketic( } #[cfg(not(unix))] -fn initialize_pocketic(_: u16, _: &ReplicaConfig, _: Logger) -> DfxResult { +fn initialize_pocketic(_: u16, _: &Path, _: &ReplicaConfig, _: Logger) -> DfxResult { bail!("PocketIC not supported on this platform") } diff --git a/src/dfx/src/commands/start.rs b/src/dfx/src/commands/start.rs index b5f96855f5..4e556cbecd 100644 --- a/src/dfx/src/commands/start.rs +++ b/src/dfx/src/commands/start.rs @@ -323,7 +323,7 @@ pub fn exec( }; let effective_config = if pocketic { - CachedConfig::pocketic(&replica_config, replica_rev().into()) + CachedConfig::pocketic(&replica_config, replica_rev().into(), None) } else { CachedConfig::replica(&replica_config, replica_rev().into()) }; diff --git a/src/dfx/src/lib/environment.rs b/src/dfx/src/lib/environment.rs index 0433478eb4..5b9ecc4881 100644 --- a/src/dfx/src/lib/environment.rs +++ b/src/dfx/src/lib/environment.rs @@ -1,4 +1,3 @@ -use crate::actors::pocketic::POCKETIC_EFFECTIVE_CANISTER_ID; use crate::config::cache::DiskBasedCache; use crate::config::dfx_version; use crate::lib::error::DfxResult; @@ -298,8 +297,7 @@ impl<'a> AgentEnvironment<'a> { let url = network_descriptor.first_provider()?; let effective_canister_id = if let Some(d) = &network_descriptor.local_server_descriptor { d.effective_config()? - .is_some_and(|c| c.is_pocketic()) - .then_some(POCKETIC_EFFECTIVE_CANISTER_ID) + .and_then(|c| c.get_effective_canister_id()) } else { None }; From 7618065926b9b016bcd98af7c4fe74ed184d76a2 Mon Sep 17 00:00:00 2001 From: Andriy Berestovskyy Date: Tue, 8 Oct 2024 22:23:21 +0200 Subject: [PATCH 06/17] fix: Add `idle_cycles_burned_per_day` field (#3943) The field was missed in the canister status output. Co-authored-by: Linwei Shang --- src/dfx/src/commands/canister/status.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dfx/src/commands/canister/status.rs b/src/dfx/src/commands/canister/status.rs index 2270d2e6ee..d3183759b9 100644 --- a/src/dfx/src/commands/canister/status.rs +++ b/src/dfx/src/commands/canister/status.rs @@ -65,12 +65,13 @@ async fn canister_status( } }; - println!("Canister status call result for {canister}.\nStatus: {status}\nControllers: {controllers}\nMemory allocation: {memory_allocation}\nCompute allocation: {compute_allocation}\nFreezing threshold: {freezing_threshold}\nMemory Size: {memory_size:?}\nBalance: {balance} Cycles\nReserved: {reserved} Cycles\nReserved cycles limit: {reserved_cycles_limit}\nWasm memory limit: {wasm_memory_limit}\nModule hash: {module_hash}\nNumber of queries: {queries_total}\nInstructions spent in queries: {query_instructions_total}\nTotal query request payload size (bytes): {query_req_payload_total}\nTotal query response payload size (bytes): {query_resp_payload_total}\nLog visibility: {log_visibility}", + println!("Canister status call result for {canister}.\nStatus: {status}\nControllers: {controllers}\nMemory allocation: {memory_allocation}\nCompute allocation: {compute_allocation}\nFreezing threshold: {freezing_threshold}\nIdle cycles burned per day: {idle_cycles_burned_per_day}\nMemory Size: {memory_size:?}\nBalance: {balance} Cycles\nReserved: {reserved} Cycles\nReserved cycles limit: {reserved_cycles_limit}\nWasm memory limit: {wasm_memory_limit}\nModule hash: {module_hash}\nNumber of queries: {queries_total}\nInstructions spent in queries: {query_instructions_total}\nTotal query request payload size (bytes): {query_req_payload_total}\nTotal query response payload size (bytes): {query_resp_payload_total}\nLog visibility: {log_visibility}", status = status.status, controllers = controllers.join(" "), memory_allocation = status.settings.memory_allocation, compute_allocation = status.settings.compute_allocation, freezing_threshold = status.settings.freezing_threshold, + idle_cycles_burned_per_day = status.idle_cycles_burned_per_day, memory_size = status.memory_size, balance = status.cycles, reserved = status.reserved_cycles, From 499a2002d3d5814f2175e05b57b0fb70a4ad816b Mon Sep 17 00:00:00 2001 From: Adam Spofford <93943719+adamspofford-dfinity@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:59:10 -0700 Subject: [PATCH 07/17] feat: canister backtraces (#3929) * Preserve namesection in built canisters * Update replica to 0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a --- CHANGELOG.md | 8 +- nix/sources.json | 132 +++++++++++++------------- src/dfx/assets/dfx-asset-sources.toml | 90 +++++++++--------- src/dfx/src/lib/models/canister.rs | 10 +- 4 files changed, 119 insertions(+), 121 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19db6531da..77591d140a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,9 +32,13 @@ Updated Motoko to [0.13.0](https://github.com/dfinity/motoko/releases/tag/0.13.0 ### Replica -Updated replica to elected commit c43a4880199c00135c8415957851e823b3fb769e. -This incorporates the following executed proposals: +Updated replica to elected commit 0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a. + +This incorporates the following elected proposals: +- [133327](https://dashboard.internetcomputer.org/proposal/133327) +- [133310](https://dashboard.internetcomputer.org/proposal/133310) +- [133309](https://dashboard.internetcomputer.org/proposal/133309) - [133144](https://dashboard.internetcomputer.org/proposal/133144) - [133143](https://dashboard.internetcomputer.org/proposal/133143) - [133142](https://dashboard.internetcomputer.org/proposal/133142) diff --git a/nix/sources.json b/nix/sources.json index 102313e517..110ff7f922 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -2,71 +2,71 @@ "canister_sandbox-x86_64-darwin": { "builtin": false, "description": "The canister_sandbox binary. It must be updated together with the replica binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1xf645zynh6yhgppdr3z7f45b5476vzcx7b8l3j88ndm1a8qc805", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1a0b0xbpqr68p6zffc0di3f6i3zzap5n1xyl6gcjgrhklilnmfxj", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/canister_sandbox.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/canister_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/canister_sandbox.gz" }, "canister_sandbox-x86_64-linux": { "builtin": false, "description": "The canister_sandbox binary. It must be updated together with the replica binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0xdmks8yhrdgmp5wwmxc8xrqf0g9g8n1jpjdn4360fsdjqxk2kq9", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1rzy24mhrvx3whi130nifxwplpqh1k2r7ld00c5imkzcl4d1lcv4", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/canister_sandbox.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/canister_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/canister_sandbox.gz" }, "compiler_sandbox-x86_64-darwin": { "builtin": false, "description": "The compiler_sandbox binary. It must be updated together with the replica binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1bv9s4nb2j6ni416dpy9bfsx4vmk55aw1x1jy6143kc69wm2hns0", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0a24bc330ym0prlfkghgbxmndvyh13cwxdf76pgikw6804d6s5a6", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/compiler_sandbox.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/compiler_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/compiler_sandbox.gz" }, "compiler_sandbox-x86_64-linux": { "builtin": false, "description": "The compiler_sandbox binary. It must be updated together with the replica binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0jiqi2ij0wcbifz04gk0i60kq6s6bcx3dyrfnhx4mbxnv4m59rvx", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0wwwwvcyhyzcvril477bchbpif1a1s702fy4sv69ni9wz1vr25a6", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/compiler_sandbox.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/compiler_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/compiler_sandbox.gz" }, "ic-admin-x86_64-darwin": { "builtin": false, "description": "The ic-admin binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1mbn1xkpf44a4697njrr3gzgajyl13p0dyg0b7mdx57nhzkxm8z1", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "004wk976w6dw6cd1k08c5ca7ylbdkjgqa28f3cwr6nghafq8ik1m", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-admin.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-admin.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-admin.gz" }, "ic-admin-x86_64-linux": { "builtin": false, "description": "The ic-admin binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1337ya9szbz24svhw07r5iwyrn4mcgymm1pzql4fvqz9d35ksa0d", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1z5gnz7ydm86npbybcklcd0w0w7m3hniqln0rgqmr6frncj6d9kh", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-admin.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-admin.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-admin.gz" }, "ic-btc-adapter-x86_64-darwin": { "builtin": false, - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "06fjm0z8qqkqd21if9flrsmjdiqizb9xya9knhcm8i4jp99qpzwy", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0d85xfiwiffpsn1vdfid1bfb5qxss1n5kbj3fx8hhw3z34rgs65k", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-btc-adapter.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-btc-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-btc-adapter.gz" }, "ic-btc-adapter-x86_64-linux": { "builtin": false, - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "114a9ia0mic963barlswyhpsl7c821h98i7wyzar80d3c20397n7", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0f2kwbgksgc0hzpxahxsfqsqv949cma3y40p4zmaafvqwx2ndarv", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-btc-adapter.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-btc-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-btc-adapter.gz" }, "ic-btc-canister": { @@ -78,52 +78,52 @@ }, "ic-https-outcalls-adapter-x86_64-darwin": { "builtin": false, - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1ki7bz0jbiw00amgxd9gz9b2fyzmxfg6qwnlfrhxr8y1grgsks7a", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0mizw7q2mmv1n8lby63n4w9x4lnkdxxq48dwhp6fhs1mlq59nvc5", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-https-outcalls-adapter.gz" }, "ic-https-outcalls-adapter-x86_64-linux": { "builtin": false, - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0qansx4fjyr5ma2vjz4j0ifmqi5xvc69lhkfjnl0snj8lj81wyzl", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0xivhcq195n0jrd67hmpsf5ab9rdcnylfq05799ym6qxx6pkmr69", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-https-outcalls-adapter.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-https-outcalls-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-https-outcalls-adapter.gz" }, "ic-nns-init-x86_64-darwin": { "builtin": false, "description": "The ic-nns-init binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0cbg099b7pvqz7zr2b75l4s815l5xx9hc5h2ifabb0pg911cylwg", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0yg7mhcg98byxn69h32hb823r6sfm9nvz1i1gxl65w9516zsmppx", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-nns-init.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-nns-init.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-nns-init.gz" }, "ic-nns-init-x86_64-linux": { "builtin": false, "description": "The ic-nns-init binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "162gxjvhfrj3gpl2rjcmk6np1hvlq0m48y5zbyzfi3s9jx0v5jww", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "095x9k6adarikw91g6c6p6l3mc0x92gyabclwicp7y587hw68app", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-nns-init.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-nns-init.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-nns-init.gz" }, "ic-starter-x86_64-darwin": { "builtin": false, - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1jd3fvrsi2xqd071vciff1rn0f6briz3sq5h7k1rjm47mb5djpxm", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0a8mhbbsdgh2bs2hy3xawss6a4ig138hij5w1f2w4vwgagwfwj6w", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-starter.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-starter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-starter.gz" }, "ic-starter-x86_64-linux": { "builtin": false, - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0hrwiv8ggba0ymxqmhbg8jzbls0rcd8jsmnksr1xnag9zpac6ihj", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1m2p94hx12jxqby3s91k0aqb3iqy06xr6pdlkmi3dp7mq0bn0pny", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-starter.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-starter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-starter.gz" }, "motoko-base": { @@ -153,71 +153,71 @@ "version": "0.13.0" }, "pocket-ic-x86_64-darwin": { - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0rys3s9506wyj32dsm2ha0awvxchpmps04ax57wbiyq9fkwgfgp0", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "0h4a96v20vvr5wlj3jixd0bfj22sczxl6q0cvcdwfv2irs7jfjxa", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/pocket-ic.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/pocket-ic.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/pocket-ic.gz" }, "pocket-ic-x86_64-linux": { - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "06ll418ib57v6pfc7bn8c3gjvjjdvp8kkd558n6xhjmcnl8b0zmx", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1d7j76kv4zr8n58dhyrw5bvv945p9gkq7n9jxp2477rxg8932056", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/pocket-ic.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/pocket-ic.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/pocket-ic.gz" }, "replica-x86_64-darwin": { "builtin": false, "description": "The replica binary. It must be updated together with the canister_sandbox binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0cd55b3x7fz1rn1pz3nclkhrgyp3jmmpzdsy3kw9f9l6v0pxzznz", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "032c7nf0gdzqssbaxcp25f1fdgr9g7w49q5zl55by3rb0f7w227k", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/replica.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/replica.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/replica.gz" }, "replica-x86_64-linux": { "builtin": false, "description": "The replica binary. It must be updated together with the canister_sandbox binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0jlb85yrsbaiixmhfl39f85yd9irb5xilmxrhnapg3kyfrhzm2kb", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "11cs8p01q8zz19smbc030pj14wh2i7fw84s3lrgg86qbvkpj5jzw", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/replica.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/replica.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/replica.gz" }, "sandbox_launcher-x86_64-darwin": { "builtin": false, "description": "The sandbox_launcher binary. It must be updated together with the replica binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1fxpr28scfgv4lazjl0hqr0pjj15rph92q852sivw97pggv0bq40", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "080dfr3kf0yash63n6d588sklxalzijd1x3c61xjvjnhs7vkkck3", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/sandbox_launcher.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sandbox_launcher.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/sandbox_launcher.gz" }, "sandbox_launcher-x86_64-linux": { "builtin": false, "description": "The sandbox_launcher binary. It must be updated together with the replica binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1xr8kzvglzb4gankxvyvbv2wdkr5kska5mwjsdc5kshkrm2bhg1x", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1b3igk4xg0g65701ig25vi122pm7wb4577cyh2qi7362pqp10dwy", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/sandbox_launcher.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sandbox_launcher.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/sandbox_launcher.gz" }, "sns-x86_64-darwin": { "builtin": false, "description": "The sns binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "0l98m2zdlr1vyzs48zg058nn7abqby0v81xqykz9b5dg73y8x5wf", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1rrml0xr3r57ixgg0km6d0jvmp1p8bfir9jv16wl8x7p4254ifqs", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/sns.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sns.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/sns.gz" }, "sns-x86_64-linux": { "builtin": false, "description": "The sns binary.", - "rev": "c43a4880199c00135c8415957851e823b3fb769e", - "sha256": "1v1v5g5dd7zszb10h9fn3sj55x4y1bbkwb2cghml8ji7y7662ynp", + "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", + "sha256": "1m3vmb84hmwhxzpiik2rfdp70lr4id1jv9fip8p8ygxid4ira3yi", "type": "file", - "url": "https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/sns.gz", + "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sns.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/sns.gz" } } diff --git a/src/dfx/assets/dfx-asset-sources.toml b/src/dfx/assets/dfx-asset-sources.toml index 3a8eb39838..c0849da0bb 100644 --- a/src/dfx/assets/dfx-asset-sources.toml +++ b/src/dfx/assets/dfx-asset-sources.toml @@ -1,25 +1,25 @@ # generated by write-dfx-asset-sources.sh -replica-rev = 'c43a4880199c00135c8415957851e823b3fb769e' +replica-rev = '0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a' [x86_64-darwin.ic-admin] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-admin.gz' -sha256 = 'e1a3dae787f694deea59e0f906ee08d44bf5fe1b394b7b92218a1077670f76d5' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-admin.gz' +sha256 = '35cc88b053f05993391b0e09859f9c6d517f142b0c81191a33bc196e4e9a9c00' [x86_64-darwin.ic-btc-adapter] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-btc-adapter.gz' -sha256 = '9eff8b53ba92445419b43329dfd3fa11c726abced42517836878628c3ea8d219' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-btc-adapter.gz' +sha256 = 'b318fd32197f7008517743ae596cd0bae3b2dc0a2dbab683d5d7b9c8a3eb0535' [x86_64-darwin.ic-https-outcalls-adapter] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz' -sha256 = 'eae8a95f7ec1a3dc6176d4726c9eebf57b2756fa2fb5feaa0280c725c15f27ce' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz' +sha256 = '856d9b0aa63568e8cc85bc21827b6fd352d213277618bf28b261d72af0e13f56' [x86_64-darwin.ic-nns-init] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-nns-init.gz' -sha256 = '8f53cf4248ef82b5948b02160653ef85968034a1e52c91fff978dfb352026f31' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-nns-init.gz' +sha256 = 'fddeaabf0925f162687f2186bf6daa4e9b3c045a500c988ced7ea1f418ace779' [x86_64-darwin.ic-starter] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/ic-starter.gz' -sha256 = 'b55fd9caaa875499c33cb0603d7ecccb386073702eb21d0e68b88ba8f376a3c9' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-starter.gz' +sha256 = 'dc48eef8538f6fc2850bbcc808d1082f1265b4e6aa0f0f855e02bea6d7821529' [x86_64-darwin.motoko] url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-Darwin-x86_64-0.13.0.tar.gz' @@ -27,30 +27,30 @@ sha256 = '8c61abbd0fd14b4e1140dd582fca29652151ba29a88fd7436eda1302e1e676ae' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-darwin.replica] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/replica.gz' -sha256 = 'dffedf2fd8862697f81c5eb77f6b95e3fa97e1a4cc8e7f83cde1bbd3c72aa531' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/replica.gz' +sha256 = 'f308c18f032b0fbf4aa1bfe044f87929bfe6822be2b2ae96d6f8b7079c3d4c0c' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-darwin.canister_sandbox] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/canister_sandbox.gz' -sha256 = '052086910ab55984e4a0689dcefe36879455883b7fe476ef83de40eb7f21c6f5' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/canister_sandbox.gz' +sha256 = 'b2bb6a69a413e627d933d4f760cb55ff8f68dc880d30e7beb9c8647c57070ba8' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-darwin.compiler_sandbox] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/compiler_sandbox.gz' -sha256 = '405b282a4f86cd4182f132f4c05529b36ed2b55bc9df660289d648b12cd169af' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/compiler_sandbox.gz' +sha256 = '46156d1a01c8f019df35c7b5ced908d0ef666b5f0fbee968bea07a30065b4428' [x86_64-darwin.sandbox_launcher] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/sandbox_launcher.gz' -sha256 = '80e005f67bf724bea316056191e0cd25487941c61050f91525fb39a691c8b7bb' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sandbox_launcher.gz' +sha256 = '63b239f7d1d0ca2d7b306cf4d064fc54753a3542a5193b0cd4ca033747760d20' [x86_64-darwin.sns] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/sns.gz' -sha256 = '8e978efc38af9595fef4b807b4815f78a9632d2ae07d44f4f73b64dabea82851' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sns.gz' +sha256 = '1abb488a20f77444b9095ba61cdd4237dcba2568a64ef05e8fa7e4913ba035e7' [x86_64-darwin.pocket-ic] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-darwin/pocket-ic.gz' -sha256 = 'e03ef7f87409fbb8f8295d11a06fbd90f5cd15505054ddc4909e1b50921eda67' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/pocket-ic.gz' +sha256 = 'aa4b278fce516cc71bdb0c6043fb675a08e916683dca21292f796f20b6498a40' [x86_64-darwin.motoko-base] url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-base-library.tar.gz' @@ -61,24 +61,24 @@ url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2 sha256 = '09f5647a45ff6d5d05b2b0ed48613fb2365b5fe6573ba0e901509c39fb9564ac' [x86_64-linux.ic-admin] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-admin.gz' -sha256 = '0d283dcb68e9e3ed08c5ff865afd6395d8ec792cf9000eb726e2afaf93f2678c' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-admin.gz' +sha256 = '70a66624b3d9995cf1cbc0521c2d1cf570c0416374b2e5d7b506d5e6cfb7affc' [x86_64-linux.ic-btc-adapter] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-btc-adapter.gz' -sha256 = 'c79e348060a30194d5f7fc44946010881daa2ff45cd3acd63089c50a544c8a84' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-btc-adapter.gz' +sha256 = '3bab6645e7783ba5ea2717103f546589a48d3576ba43d5ef87803d3ddfe25338' [x86_64-linux.ic-https-outcalls-adapter] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-https-outcalls-adapter.gz' -sha256 = 'f47b1e90a4485a0da8956e429a0cdbbd445c5d04927cb985aa257be948d75661' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-https-outcalls-adapter.gz' +sha256 = 'c9e43aafe91d9bea533a056047bd652da7a58ad3b7c2635a96c0961430833b76' [x86_64-linux.ic-nns-init] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-nns-init.gz' -sha256 = '9ccbb24197498fe8be5fbf78442ac074c370ad9995c92ce87d436607b7ec4f98' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-nns-init.gz' +sha256 = 'f72a64383ca8f87359e4942de59f481db03aa8b9869917129f31aba6cc4cbd24' [x86_64-linux.ic-starter] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/ic-starter.gz' -sha256 = '1246c3d4fde929db43d6d3562d51631968babe446fc18a7bf540adf7d08e3c43' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-starter.gz' +sha256 = 'de5e6017c0f5dc36629db45d93bb011ec7b1b00233243dfcc25d8ad0214957d4' [x86_64-linux.motoko] url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-Linux-x86_64-0.13.0.tar.gz' @@ -86,30 +86,30 @@ sha256 = 'ae82aba73b868ac43547abccc99ada0e5c7cfb5d8b2eed6b1c433eaa3c4b56da' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-linux.replica] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/replica.gz' -sha256 = '6b8afa61767e8e779585b9571a7b5939a6e60b726950076b8f512d9d7d418b4a' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/replica.gz' +sha256 = 'fccb22efdc0b1bf45ea64313c4dd89027212e40503b055750aff231cc0459a85' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-linux.canister_sandbox] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/canister_sandbox.gz' -sha256 = '094f313b964d3b6006b14d5e192c7ae901877347ac57cecbadaf65e8919eb575' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/canister_sandbox.gz' +sha256 = '64331a1aa1eccf1a0b03a0d193c50c105f7a7977d1821122e4a3ef0c2b11fee7' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-linux.compiler_sandbox] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/compiler_sandbox.gz' -sha256 = '7de7542ad9b6af4a3ab42efb363a5b461b3c8189603e02be8b8b7120a388384a' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/compiler_sandbox.gz' +sha256 = '46159177f83c459bccd6c43b018e0e2ab8781764eb1c4263deec7be8d9e69c73' [x86_64-linux.sandbox_launcher] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/sandbox_launcher.gz' -sha256 = '3d3cb844cd13ea5958d392d7a2a69e25cfc6c55edbef3ead7a647dfaf69f28f7' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sandbox_launcher.gz' +sha256 = '9e37102ebec28c13b1809e9d53c8e2a75e2142dc45bc18c029e681d7c97c71ac' [x86_64-linux.sns] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/sns.gz' -sha256 = 'd77a61ccf1274a442b7c4c2c3ed70a9ef452a41ed62508c2fafa9fd6ca2b3bec' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sns.gz' +sha256 = 'd10f952369b13f8f2ebad1a52d438b2453706e7359cc18efef905748d0aa7bd4' [x86_64-linux.pocket-ic] -url = 'https://download.dfinity.systems/ic/c43a4880199c00135c8415957851e823b3fb769e/binaries/x86_64-linux/pocket-ic.gz' -sha256 = 'bd7eb010b5ac4ad88d45a5b439d1dd4dca2ddf60c8aec3dc35fb94155120941a' +url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/pocket-ic.gz' +sha256 = 'a60031127a3d9f43c4ed32d983e74bb790b4f72a3c7bd850b1287fb2a739f2b4' [x86_64-linux.motoko-base] url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-base-library.tar.gz' diff --git a/src/dfx/src/lib/models/canister.rs b/src/dfx/src/lib/models/canister.rs index 2fac1a62b6..c49e54c2d1 100644 --- a/src/dfx/src/lib/models/canister.rs +++ b/src/dfx/src/lib/models/canister.rs @@ -134,14 +134,8 @@ impl Canister { // optimize or shrink if let Some(level) = info.get_optimize() { trace!(logger, "Optimizing Wasm at level {}", level); - ic_wasm::optimize::optimize( - &mut m, - &wasm_opt_level_convert(level), - false, - &None, - false, - ) - .context("Failed to optimize the Wasm module.")?; + ic_wasm::optimize::optimize(&mut m, &wasm_opt_level_convert(level), false, &None, true) + .context("Failed to optimize the Wasm module.")?; modified = true; } else if info.get_shrink() == Some(true) || (info.get_shrink().is_none() && (info.is_rust() || info.is_motoko())) From 115a0772f39961c5f10fad18181ef43118f66c57 Mon Sep 17 00:00:00 2001 From: Adam Spofford <93943719+adamspofford-dfinity@users.noreply.github.com> Date: Thu, 10 Oct 2024 09:52:40 -0700 Subject: [PATCH 08/17] chore: Update Motoko to 0.13.1 (#3948) --- CHANGELOG.md | 2 +- nix/sources.json | 18 +++++++++--------- src/dfx/assets/dfx-asset-sources.toml | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77591d140a..46c66be06b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ Module hash: 2c9e30df9be951a6884c702a97bbb8c0b438f33d4208fa612b1de6fb1752db76 ### Motoko -Updated Motoko to [0.13.0](https://github.com/dfinity/motoko/releases/tag/0.13.0) +Updated Motoko to [0.13.1](https://github.com/dfinity/motoko/releases/tag/0.13.1) ### Replica diff --git a/nix/sources.json b/nix/sources.json index 110ff7f922..e14ac2bde3 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -130,27 +130,27 @@ "builtin": false, "description": "The Motoko base library", "owner": "dfinity", - "sha256": "02nf25bm21rmyh425arh0srb52bgsyrbqmnmy7r8zd1lfd6jnpfc", + "sha256": "096icqgg2ab713zjxw8v5kn30ickp0av632j38ympwll7rb3rjl5", "type": "tarball", - "url": "https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-base-library.tar.gz", + "url": "https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-base-library.tar.gz", "url_template": "https://github.com/dfinity/motoko/releases/download//motoko-base-library.tar.gz", - "version": "0.13.0" + "version": "0.13.1" }, "motoko-x86_64-darwin": { "builtin": false, - "sha256": "1bknwvhh44ysdr1xg3x856x528b55752yn6x808lwjyi1yysnqcc", + "sha256": "1gz7k5xnq7cifdvsbpi5ymfcfn61wk6av4xidal1w23xx0q90m4q", "type": "file", - "url": "https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-Darwin-x86_64-0.13.0.tar.gz", + "url": "https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-Darwin-x86_64-0.13.1.tar.gz", "url_template": "https://github.com/dfinity/motoko/releases/download//motoko-Darwin-x86_64-.tar.gz", - "version": "0.13.0" + "version": "0.13.1" }, "motoko-x86_64-linux": { "builtin": false, - "sha256": "1njn9cyalgj33imysblbbpxpqp0fvadckk5b8wsw92l67fksp0mf", + "sha256": "0yi6vxin5hyrzp3av66rzs4058d90dbjzi5kp0yi3xr4jki9rjb9", "type": "file", - "url": "https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-Linux-x86_64-0.13.0.tar.gz", + "url": "https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-Linux-x86_64-0.13.1.tar.gz", "url_template": "https://github.com/dfinity/motoko/releases/download//motoko-Linux-x86_64-.tar.gz", - "version": "0.13.0" + "version": "0.13.1" }, "pocket-ic-x86_64-darwin": { "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", diff --git a/src/dfx/assets/dfx-asset-sources.toml b/src/dfx/assets/dfx-asset-sources.toml index c0849da0bb..73de34fc13 100644 --- a/src/dfx/assets/dfx-asset-sources.toml +++ b/src/dfx/assets/dfx-asset-sources.toml @@ -22,8 +22,8 @@ url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8 sha256 = 'dc48eef8538f6fc2850bbcc808d1082f1265b4e6aa0f0f855e02bea6d7821529' [x86_64-darwin.motoko] -url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-Darwin-x86_64-0.13.0.tar.gz' -sha256 = '8c61abbd0fd14b4e1140dd582fca29652151ba29a88fd7436eda1302e1e676ae' +url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-Darwin-x86_64-0.13.1.tar.gz' +sha256 = '98549030e87d081ea86ab193adcce4c158c75cf525dea57773911d6c7b99e7bf' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-darwin.replica] @@ -53,8 +53,8 @@ url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8 sha256 = 'aa4b278fce516cc71bdb0c6043fb675a08e916683dca21292f796f20b6498a40' [x86_64-darwin.motoko-base] -url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-base-library.tar.gz' -sha256 = 'fcefaf998b0ddb75100f46cc23ac8a384ef4d7b26374a38f353055b2c8fa3fb6' +url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-base-library.tar.gz' +sha256 = '810edcae82dc1255edbf5dbd779aa7dbeb0ad79463be9fb502a23b7f13792f27' [x86_64-darwin.ic-btc-canister] url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-10-13/ic-btc-canister.wasm.gz' @@ -81,8 +81,8 @@ url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8 sha256 = 'de5e6017c0f5dc36629db45d93bb011ec7b1b00233243dfcc25d8ad0214957d4' [x86_64-linux.motoko] -url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-Linux-x86_64-0.13.0.tar.gz' -sha256 = 'ae82aba73b868ac43547abccc99ada0e5c7cfb5d8b2eed6b1c433eaa3c4b56da' +url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-Linux-x86_64-0.13.1.tar.gz' +sha256 = '69c99ce29424f7113db8b3c42f5703a9a10288fed998adc6fdd9c36263df267a' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-linux.replica] @@ -112,8 +112,8 @@ url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8 sha256 = 'a60031127a3d9f43c4ed32d983e74bb790b4f72a3c7bd850b1287fb2a739f2b4' [x86_64-linux.motoko-base] -url = 'https://github.com/dfinity/motoko/releases/download/0.13.0/motoko-base-library.tar.gz' -sha256 = 'fcefaf998b0ddb75100f46cc23ac8a384ef4d7b26374a38f353055b2c8fa3fb6' +url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-base-library.tar.gz' +sha256 = '810edcae82dc1255edbf5dbd779aa7dbeb0ad79463be9fb502a23b7f13792f27' [x86_64-linux.ic-btc-canister] url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2023-10-13/ic-btc-canister.wasm.gz' From f313af3a968900f4c84bcac00a85407b69391f98 Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Fri, 11 Oct 2024 15:08:35 +0200 Subject: [PATCH 09/17] feat: upload multiple asset chunks in the same call (#3947) --- CHANGELOG.md | 14 ++ .../ic-asset/src/batch_upload/operations.rs | 27 +++- .../ic-asset/src/batch_upload/plumbing.rs | 138 +++++++++++++++++- .../ic-asset/src/batch_upload/semaphores.rs | 15 +- .../src/canister_api/methods/chunk.rs | 63 +++++++- .../src/canister_api/methods/method_names.rs | 1 + .../canister_api/types/batch_upload/common.rs | 20 ++- .../ic-asset/src/error/create_chunk.rs | 4 + .../frontend/ic-asset/src/evidence/mod.rs | 4 +- src/canisters/frontend/ic-asset/src/sync.rs | 28 +++- src/canisters/frontend/ic-asset/src/upload.rs | 8 +- .../frontend/ic-certified-assets/src/lib.rs | 2 +- src/distributed/assetstorage.wasm.gz | Bin 399164 -> 399164 bytes 13 files changed, 291 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46c66be06b..3e37c6b50a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,20 @@ Valid settings are: - `--log-viewer` flag with `dfx canister create` - `canisters[].initialization_values.log_visibility.allowed_viewers` in `dfx.json` +### feat: batch upload assets + +The frontend canister sync now tries to batch multiple small content chunks into a single call using the `create_chunks` method added earlier. +This should lead to significantly faster upload times for frontends with many small files. + +## Dependencies + +### Frontend canister + +Bumped `api_version` to `2` for the previous addition of `create_chunks` since the improved file sync relies on it. + +- Module hash: 9e4485d4358dd910aebcc025843547d05604cf28c6dc7c2cc2f8c76d083112e8 +- https://github.com/dfinity/sdk/pull/3947 + # 0.24.1 ### feat: More PocketIC flags supported diff --git a/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs b/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs index b3363b6e39..518fb58330 100644 --- a/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs +++ b/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs @@ -10,9 +10,12 @@ use crate::canister_api::types::batch_upload::v1::{BatchOperationKind, CommitBat use candid::Nat; use std::collections::HashMap; +use super::plumbing::ChunkUploader; + pub(crate) const BATCH_UPLOAD_API_VERSION: u16 = 1; -pub(crate) fn assemble_batch_operations( +pub(crate) async fn assemble_batch_operations( + chunk_uploader: Option<&ChunkUploader<'_>>, project_assets: &HashMap, canister_assets: HashMap, asset_deletion_reason: AssetDeletionReason, @@ -30,13 +33,14 @@ pub(crate) fn assemble_batch_operations( ); create_new_assets(&mut operations, project_assets, &canister_assets); unset_obsolete_encodings(&mut operations, project_assets, &canister_assets); - set_encodings(&mut operations, project_assets); + set_encodings(&mut operations, chunk_uploader, project_assets).await; update_properties(&mut operations, project_assets, &canister_asset_properties); operations } -pub(crate) fn assemble_commit_batch_arguments( +pub(crate) async fn assemble_commit_batch_arguments( + chunk_uploader: &ChunkUploader<'_>, project_assets: HashMap, canister_assets: HashMap, asset_deletion_reason: AssetDeletionReason, @@ -44,11 +48,13 @@ pub(crate) fn assemble_commit_batch_arguments( batch_id: Nat, ) -> CommitBatchArguments { let operations = assemble_batch_operations( + Some(chunk_uploader), &project_assets, canister_assets, asset_deletion_reason, canister_asset_properties, - ); + ) + .await; CommitBatchArguments { operations, batch_id, @@ -153,8 +159,9 @@ pub(crate) fn unset_obsolete_encodings( } } -pub(crate) fn set_encodings( +pub(crate) async fn set_encodings( operations: &mut Vec, + chunk_uploader: Option<&ChunkUploader<'_>>, project_assets: &HashMap, ) { for (key, project_asset) in project_assets { @@ -162,12 +169,18 @@ pub(crate) fn set_encodings( if v.already_in_place { continue; } - + let chunk_ids = if let Some(uploader) = chunk_uploader { + uploader + .uploader_ids_to_canister_chunk_ids(&v.uploader_chunk_ids) + .await + } else { + vec![] + }; operations.push(BatchOperationKind::SetAssetContent( SetAssetContentArguments { key: key.clone(), content_encoding: content_encoding.clone(), - chunk_ids: v.chunk_ids.clone(), + chunk_ids, sha256: Some(v.sha256.clone()), }, )); diff --git a/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs b/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs index 661e1e0dd4..640b9d48e0 100644 --- a/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs +++ b/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs @@ -3,6 +3,7 @@ use crate::asset::content::Content; use crate::asset::content_encoder::ContentEncoder; use crate::batch_upload::semaphores::Semaphores; use crate::canister_api::methods::chunk::create_chunk; +use crate::canister_api::methods::chunk::create_chunks; use crate::canister_api::types::asset::AssetDetails; use crate::error::CreateChunkError; use crate::error::CreateEncodingError; @@ -14,10 +15,12 @@ use futures::TryFutureExt; use ic_utils::Canister; use mime::Mime; use slog::{debug, info, Logger}; +use std::collections::BTreeMap; use std::collections::HashMap; use std::path::PathBuf; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; +use tokio::sync::Mutex; const CONTENT_ENCODING_IDENTITY: &str = "identity"; @@ -35,7 +38,7 @@ pub(crate) struct AssetDescriptor { } pub(crate) struct ProjectAssetEncoding { - pub(crate) chunk_ids: Vec, + pub(crate) uploader_chunk_ids: Vec, pub(crate) sha256: Vec, pub(crate) already_in_place: bool, } @@ -46,30 +49,68 @@ pub(crate) struct ProjectAsset { pub(crate) encodings: HashMap, } +type IdMapping = BTreeMap; +type UploadQueue = Vec<(usize, Vec)>; pub(crate) struct ChunkUploader<'agent> { canister: Canister<'agent>, batch_id: Nat, + api_version: u16, chunks: Arc, bytes: Arc, + // maps uploader_chunk_id to canister_chunk_id + id_mapping: Arc>, + upload_queue: Arc>, } + impl<'agent> ChunkUploader<'agent> { - pub(crate) fn new(canister: Canister<'agent>, batch_id: Nat) -> Self { + pub(crate) fn new(canister: Canister<'agent>, api_version: u16, batch_id: Nat) -> Self { Self { canister, batch_id, + api_version, chunks: Arc::new(AtomicUsize::new(0)), bytes: Arc::new(AtomicUsize::new(0)), + id_mapping: Arc::new(Mutex::new(BTreeMap::new())), + upload_queue: Arc::new(Mutex::new(vec![])), } } + /// Returns an uploader_chunk_id, which is different from the chunk id on the asset canister. + /// uploader_chunk_id can be mapped to canister_chunk_id using `uploader_ids_to_canister_chunk_ids` + /// once `finalize_upload` has completed. pub(crate) async fn create_chunk( &self, contents: &[u8], semaphores: &Semaphores, - ) -> Result { - self.chunks.fetch_add(1, Ordering::SeqCst); + ) -> Result { + let uploader_chunk_id = self.chunks.fetch_add(1, Ordering::SeqCst); self.bytes.fetch_add(contents.len(), Ordering::SeqCst); - create_chunk(&self.canister, &self.batch_id, contents, semaphores).await + if contents.len() == MAX_CHUNK_SIZE || self.api_version < 2 { + let canister_chunk_id = + create_chunk(&self.canister, &self.batch_id, contents, semaphores).await?; + let mut map = self.id_mapping.lock().await; + map.insert(uploader_chunk_id, canister_chunk_id); + Ok(uploader_chunk_id) + } else { + self.add_to_upload_queue(uploader_chunk_id, contents).await; + // Larger `max_retained_bytes` leads to batches that are filled closer to the max size. + // `4 * MAX_CHUNK_SIZE` leads to a pretty small memory footprint but still offers solid fill rates. + // Mini experiment: + // - Tested with: `for i in $(seq 1 50); do dd if=/dev/urandom of="src/hello_frontend/assets/file_$i.bin" bs=$(shuf -i 1-2000000 -n 1) count=1; done && dfx deploy hello_frontend` + // - Result: Roughly 15% of batches under 90% full. + // With other byte ranges (e.g. `shuf -i 1-3000000 -n 1`) stats improve significantly + self.upload_chunks(4 * MAX_CHUNK_SIZE, usize::MAX, semaphores) + .await?; + Ok(uploader_chunk_id) + } + } + + pub(crate) async fn finalize_upload( + &self, + semaphores: &Semaphores, + ) -> Result<(), CreateChunkError> { + self.upload_chunks(0, 0, semaphores).await?; + Ok(()) } pub(crate) fn bytes(&self) -> usize { @@ -78,6 +119,80 @@ impl<'agent> ChunkUploader<'agent> { pub(crate) fn chunks(&self) -> usize { self.chunks.load(Ordering::SeqCst) } + + /// Call only after `finalize_upload` has completed + pub(crate) async fn uploader_ids_to_canister_chunk_ids( + &self, + uploader_ids: &[usize], + ) -> Vec { + let mapping = self.id_mapping.lock().await; + uploader_ids + .iter() + .map(|id| { + mapping + .get(id) + .expect("Chunk uploader did not upload all chunks. This is a bug.") + .clone() + }) + .collect() + } + + async fn add_to_upload_queue(&self, uploader_chunk_id: usize, contents: &[u8]) { + let mut queue = self.upload_queue.lock().await; + queue.push((uploader_chunk_id, contents.into())); + } + + /// Calls `upload_chunks` with batches of chunks from `self.upload_queue` until at most `max_retained_bytes` + /// bytes and at most `max_retained_chunks` chunks remain in the upload queue. Larger values + /// will lead to better batch fill rates but also leave a larger memory footprint. + async fn upload_chunks( + &self, + max_retained_bytes: usize, + max_retained_chunks: usize, + semaphores: &Semaphores, + ) -> Result<(), CreateChunkError> { + let mut queue = self.upload_queue.lock().await; + + let mut batches = vec![]; + while queue + .iter() + .map(|(_, content)| content.len()) + .sum::() + > max_retained_bytes + || queue.len() > max_retained_chunks + { + // Greedily fills batch with the largest chunk that fits + queue.sort_unstable_by_key(|(_, content)| content.len()); + let mut batch = vec![]; + let mut batch_size = 0; + for (uploader_chunk_id, content) in std::mem::take(&mut *queue).into_iter().rev() { + if content.len() <= MAX_CHUNK_SIZE - batch_size { + batch_size += content.len(); + batch.push((uploader_chunk_id, content)); + } else { + queue.push((uploader_chunk_id, content)); + } + } + batches.push(batch); + } + + try_join_all(batches.into_iter().map(|chunks| async move { + let (uploader_chunk_ids, chunks): (Vec<_>, Vec<_>) = chunks.into_iter().unzip(); + let canister_chunk_ids = + create_chunks(&self.canister, &self.batch_id, chunks, semaphores).await?; + let mut map = self.id_mapping.lock().await; + for (uploader_id, canister_id) in uploader_chunk_ids + .into_iter() + .zip(canister_chunk_ids.into_iter()) + { + map.insert(uploader_id, canister_id); + } + Ok(()) + })) + .await?; + + Ok(()) + } } #[allow(clippy::too_many_arguments)] @@ -110,7 +225,7 @@ async fn make_project_asset_encoding( false }; - let chunk_ids = if already_in_place { + let uploader_chunk_ids = if already_in_place { info!( logger, " {}{} ({} bytes) sha {} is already installed", @@ -144,7 +259,7 @@ async fn make_project_asset_encoding( }; Ok(ProjectAssetEncoding { - chunk_ids, + uploader_chunk_ids, sha256, already_in_place, }) @@ -305,6 +420,13 @@ pub(crate) async fn make_project_assets( }) .collect(); let project_assets = try_join_all(project_asset_futures).await?; + if let Some(uploader) = chunk_upload_target { + uploader.finalize_upload(&semaphores).await.map_err(|err| { + CreateProjectAssetError::CreateEncodingError(CreateEncodingError::CreateChunkFailed( + err, + )) + })?; + } let mut hm = HashMap::new(); for project_asset in project_assets { @@ -321,7 +443,7 @@ async fn upload_content_chunks( content_encoding: &str, semaphores: &Semaphores, logger: &Logger, -) -> Result, CreateChunkError> { +) -> Result, CreateChunkError> { if content.data.is_empty() { let empty = vec![]; let chunk_id = chunk_uploader.create_chunk(&empty, semaphores).await?; diff --git a/src/canisters/frontend/ic-asset/src/batch_upload/semaphores.rs b/src/canisters/frontend/ic-asset/src/batch_upload/semaphores.rs index 1f86278586..6661184d10 100644 --- a/src/canisters/frontend/ic-asset/src/batch_upload/semaphores.rs +++ b/src/canisters/frontend/ic-asset/src/batch_upload/semaphores.rs @@ -6,30 +6,31 @@ const MAX_SIMULTANEOUS_LOADED_MB: usize = 50; // How many simultaneous chunks being created at once const MAX_SIMULTANEOUS_CREATE_CHUNK: usize = 50; -// How many simultaneous Agent.call() to create_chunk +// How many simultaneous Agent.call() to create_chunk(s) const MAX_SIMULTANEOUS_CREATE_CHUNK_CALLS: usize = 25; -// How many simultaneous Agent.wait() on create_chunk result +// How many simultaneous Agent.wait() on create_chunk(s) result const MAX_SIMULTANEOUS_CREATE_CHUNK_WAITS: usize = 25; +#[derive(Debug)] pub(crate) struct Semaphores { // The "file" semaphore limits how much file data to load at once. A given loaded file's data // may be simultaneously encoded (gzip and so forth). pub file: SharedSemaphore, - // The create_chunk semaphore limits the number of chunks that can be in the process - // of being created at one time. Since each chunk creation can involve retries, - // this focuses those retries on a smaller number of chunks. + // The create_chunk semaphore limits the number of chunk creation calls + // that can be in progress at one time. Since each chunk creation can involve retries, + // this focuses those retries on a smaller number of calls. // Without this semaphore, every chunk would make its first attempt, before // any chunk made its second attempt. pub create_chunk: SharedSemaphore, // The create_chunk_call semaphore limits the number of simultaneous - // agent.call()s to create_chunk. + // agent.call()s to create_chunk(s). pub create_chunk_call: SharedSemaphore, // The create_chunk_wait semaphore limits the number of simultaneous - // agent.wait() calls for outstanding create_chunk requests. + // agent.wait() calls for outstanding create_chunk(s) requests. pub create_chunk_wait: SharedSemaphore, } diff --git a/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs b/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs index f63659c866..79c6ea1096 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/methods/chunk.rs @@ -1,7 +1,9 @@ use crate::batch_upload::retryable::retryable; use crate::batch_upload::semaphores::Semaphores; use crate::canister_api::methods::method_names::CREATE_CHUNK; -use crate::canister_api::types::batch_upload::common::{CreateChunkRequest, CreateChunkResponse}; +use crate::canister_api::types::batch_upload::common::{ + CreateChunkRequest, CreateChunkResponse, CreateChunksRequest, CreateChunksResponse, +}; use crate::error::CreateChunkError; use backoff::backoff::Backoff; use backoff::ExponentialBackoffBuilder; @@ -10,6 +12,8 @@ use ic_agent::agent::CallResponse; use ic_utils::Canister; use std::time::Duration; +use super::method_names::CREATE_CHUNKS; + pub(crate) async fn create_chunk( canister: &Canister<'_>, batch_id: &Nat, @@ -66,3 +70,60 @@ pub(crate) async fn create_chunk( } } } + +pub(crate) async fn create_chunks( + canister: &Canister<'_>, + batch_id: &Nat, + content: Vec>, + semaphores: &Semaphores, +) -> Result, CreateChunkError> { + let _chunk_releaser = semaphores.create_chunk.acquire(1).await; + let batch_id = batch_id.clone(); + let args = CreateChunksRequest { batch_id, content }; + let mut retry_policy = ExponentialBackoffBuilder::new() + .with_initial_interval(Duration::from_secs(1)) + .with_max_interval(Duration::from_secs(16)) + .with_multiplier(2.0) + .with_max_elapsed_time(Some(Duration::from_secs(300))) + .build(); + + loop { + let builder = canister.update(CREATE_CHUNKS); + let builder = builder.with_arg(&args); + let request_id_result = { + let _releaser = semaphores.create_chunk_call.acquire(1).await; + builder + .build() + .map(|result: (CreateChunksResponse,)| (result.0.chunk_ids,)) + .call() + .await + }; + + let wait_result = match request_id_result { + Ok(resp) => match resp { + CallResponse::Response(r) => Ok(r), + CallResponse::Poll(id) => { + let _releaser = semaphores.create_chunk_wait.acquire(1).await; + canister + .wait(&id) + .await + .and_then(|bytes| Ok((Decode!(&bytes, CreateChunksResponse)?.chunk_ids,))) + } + }, + Err(agent_err) => Err(agent_err), + }; + + match wait_result { + Ok((chunk_ids,)) => { + return Ok(chunk_ids); + } + Err(agent_err) if !retryable(&agent_err) => { + return Err(CreateChunkError::CreateChunks(agent_err)); + } + Err(agent_err) => match retry_policy.next_backoff() { + Some(duration) => tokio::time::sleep(duration).await, + None => return Err(CreateChunkError::CreateChunks(agent_err)), + }, + } + } +} diff --git a/src/canisters/frontend/ic-asset/src/canister_api/methods/method_names.rs b/src/canisters/frontend/ic-asset/src/canister_api/methods/method_names.rs index 5cfc36e910..d8fd4d83a2 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/methods/method_names.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/methods/method_names.rs @@ -3,6 +3,7 @@ pub(crate) const COMMIT_BATCH: &str = "commit_batch"; pub(crate) const COMPUTE_EVIDENCE: &str = "compute_evidence"; pub(crate) const CREATE_BATCH: &str = "create_batch"; pub(crate) const CREATE_CHUNK: &str = "create_chunk"; +pub(crate) const CREATE_CHUNKS: &str = "create_chunks"; pub(crate) const GET_ASSET_PROPERTIES: &str = "get_asset_properties"; pub(crate) const LIST: &str = "list"; pub(crate) const PROPOSE_COMMIT_BATCH: &str = "propose_commit_batch"; diff --git a/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs b/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs index 2c9b82468e..7e36d1d5ad 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs @@ -27,13 +27,31 @@ pub struct CreateChunkRequest<'a> { pub content: &'a [u8], } -/// The responst to a CreateChunkRequest. +/// The response to a CreateChunkRequest. #[derive(CandidType, Debug, Deserialize)] pub struct CreateChunkResponse { /// The ID of the created chunk. pub chunk_id: Nat, } +/// Upload multiple chunks of data that are part of asset content. +#[derive(CandidType, Debug, Deserialize)] +pub struct CreateChunksRequest { + /// The batch with which to associate the created chunks. + /// The chunk will be deleted if the batch expires before being committed. + pub batch_id: Nat, + + /// The data in this chunk. + pub content: Vec>, +} + +/// The response to a CreateChunksRequest. +#[derive(CandidType, Debug, Deserialize)] +pub struct CreateChunksResponse { + /// The IDs of the created chunks. + pub chunk_ids: Vec, +} + /// Create a new asset. Has no effect if the asset already exists and the content type matches. /// Traps if the asset already exists but with a different content type. #[derive(CandidType, Clone, Debug, PartialOrd, PartialEq, Eq, Ord)] diff --git a/src/canisters/frontend/ic-asset/src/error/create_chunk.rs b/src/canisters/frontend/ic-asset/src/error/create_chunk.rs index d982c0e453..539af922fa 100644 --- a/src/canisters/frontend/ic-asset/src/error/create_chunk.rs +++ b/src/canisters/frontend/ic-asset/src/error/create_chunk.rs @@ -8,6 +8,10 @@ pub enum CreateChunkError { #[error("Failed to create chunk: {0}")] CreateChunk(AgentError), + /// Failed in call to create_chunks, or in waiting for response. + #[error("Failed to create chunks: {0}")] + CreateChunks(AgentError), + /// Failed to decode the create chunk response. #[error("Failed to decode create chunk response: {0}")] DecodeCreateChunkResponse(candid::Error), diff --git a/src/canisters/frontend/ic-asset/src/evidence/mod.rs b/src/canisters/frontend/ic-asset/src/evidence/mod.rs index 71b22b3a27..18ee8fc390 100644 --- a/src/canisters/frontend/ic-asset/src/evidence/mod.rs +++ b/src/canisters/frontend/ic-asset/src/evidence/mod.rs @@ -59,11 +59,13 @@ pub async fn compute_evidence( make_project_assets(None, asset_descriptors, &canister_assets, logger).await?; let mut operations = assemble_batch_operations( + None, &project_assets, canister_assets, Obsolete, canister_asset_properties, - ); + ) + .await; operations.sort(); let mut sha = Sha256::new(); diff --git a/src/canisters/frontend/ic-asset/src/sync.rs b/src/canisters/frontend/ic-asset/src/sync.rs index c229416b3c..ca5be49869 100644 --- a/src/canisters/frontend/ic-asset/src/sync.rs +++ b/src/canisters/frontend/ic-asset/src/sync.rs @@ -45,6 +45,7 @@ const KNOWN_DIRECTORIES: [&str; 1] = [".well-known"]; /// Sets the contents of the asset canister to the contents of a directory, including deleting old assets. pub async fn upload_content_and_assemble_sync_operations( canister: &Canister<'_>, + canister_api_version: u16, dirs: &[&Path], no_delete: bool, logger: &Logger, @@ -74,7 +75,8 @@ pub async fn upload_content_and_assemble_sync_operations( "Staging contents of new and changed assets in batch {}:", batch_id ); - let chunk_uploader = ChunkUploader::new(canister.clone(), batch_id.clone()); + let chunk_uploader = + ChunkUploader::new(canister.clone(), canister_api_version, batch_id.clone()); let project_assets = make_project_assets( Some(&chunk_uploader), @@ -85,6 +87,7 @@ pub async fn upload_content_and_assemble_sync_operations( .await?; let commit_batch_args = batch_upload::operations::assemble_commit_batch_arguments( + &chunk_uploader, project_assets, canister_assets, match no_delete { @@ -93,7 +96,8 @@ pub async fn upload_content_and_assemble_sync_operations( }, canister_asset_properties, batch_id, - ); + ) + .await; // -v debug!( @@ -121,9 +125,15 @@ pub async fn sync( no_delete: bool, logger: &Logger, ) -> Result<(), SyncError> { - let commit_batch_args = - upload_content_and_assemble_sync_operations(canister, dirs, no_delete, logger).await?; let canister_api_version = api_version(canister).await; + let commit_batch_args = upload_content_and_assemble_sync_operations( + canister, + canister_api_version, + dirs, + no_delete, + logger, + ) + .await?; debug!(logger, "Canister API version: {canister_api_version}. ic-asset API version: {BATCH_UPLOAD_API_VERSION}"); info!(logger, "Committing batch."); match canister_api_version { @@ -196,7 +206,15 @@ pub async fn prepare_sync_for_proposal( dirs: &[&Path], logger: &Logger, ) -> Result<(Nat, ByteBuf), PrepareSyncForProposalError> { - let arg = upload_content_and_assemble_sync_operations(canister, dirs, false, logger).await?; + let canister_api_version = api_version(canister).await; + let arg = upload_content_and_assemble_sync_operations( + canister, + canister_api_version, + dirs, + false, + logger, + ) + .await?; let arg = sort_batch_operations(arg); let batch_id = arg.batch_id.clone(); diff --git a/src/canisters/frontend/ic-asset/src/upload.rs b/src/canisters/frontend/ic-asset/src/upload.rs index 7057a9f4b1..c987b49eb4 100644 --- a/src/canisters/frontend/ic-asset/src/upload.rs +++ b/src/canisters/frontend/ic-asset/src/upload.rs @@ -39,10 +39,12 @@ pub async fn upload( info!(logger, "Starting batch."); let batch_id = create_batch(canister).await.map_err(CreateBatchFailed)?; + let canister_api_version = api_version(canister).await; info!(logger, "Staging contents of new and changed assets:"); - let chunk_upload_target = ChunkUploader::new(canister.clone(), batch_id.clone()); + let chunk_upload_target = + ChunkUploader::new(canister.clone(), canister_api_version, batch_id.clone()); let project_assets = make_project_assets( Some(&chunk_upload_target), @@ -53,12 +55,14 @@ pub async fn upload( .await?; let commit_batch_args = batch_upload::operations::assemble_commit_batch_arguments( + &chunk_upload_target, project_assets, canister_assets, AssetDeletionReason::Incompatible, HashMap::new(), batch_id, - ); + ) + .await; let canister_api_version = api_version(canister).await; info!(logger, "Committing batch."); diff --git a/src/canisters/frontend/ic-certified-assets/src/lib.rs b/src/canisters/frontend/ic-certified-assets/src/lib.rs index 5f926ace06..44847a1e1c 100644 --- a/src/canisters/frontend/ic-certified-assets/src/lib.rs +++ b/src/canisters/frontend/ic-certified-assets/src/lib.rs @@ -35,7 +35,7 @@ thread_local! { #[query] #[candid_method(query)] fn api_version() -> u16 { - 1 + 2 } #[update(guard = "is_manager_or_controller")] diff --git a/src/distributed/assetstorage.wasm.gz b/src/distributed/assetstorage.wasm.gz index 1b691cb7ca8be4c7d7f440ccc521d041c2a33e98..082ae64e9b10657148f2e3306208e83a26c350ee 100755 GIT binary patch delta 48 zcmV-00MGxtt{A+o7=VNUgaU*Ev;_Q?0c*GYmITon1CSWmhtaVFx6!c$V`T_>#3|QA GY7zhnZWN;c delta 48 zcmV-00MGxtt{A+o7=VNUgaU*Ev;_Q?0Zh03mITon17L;UhtaVFx6!c$V`T`n4vgnS GY7zhol@z}K From f60661276522eb94c3bd322ed8ee470fd4307e66 Mon Sep 17 00:00:00 2001 From: Adam Spofford <93943719+adamspofford-dfinity@users.noreply.github.com> Date: Fri, 11 Oct 2024 13:11:12 -0700 Subject: [PATCH 10/17] fix: restore behavior of 'none' frontend (#3951) --- src/dfx/src/commands/new.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dfx/src/commands/new.rs b/src/dfx/src/commands/new.rs index 15c7a388b7..412d8269f3 100644 --- a/src/dfx/src/commands/new.rs +++ b/src/dfx/src/commands/new.rs @@ -765,7 +765,7 @@ fn get_opts_interactively(opts: NewOpts) -> DfxResult { let opts = NewOpts { extras, - frontend: frontend.map(|f| f.name.0.clone()), + frontend: Some(frontend.map_or_else(|| "none".to_string(), |f| f.name.0.clone())), r#type: Some(backend.name.0.clone()), ..opts }; From 064e4ff3e47006ec13b99b012a5e69f1a56577c4 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 14 Oct 2024 10:51:23 -0500 Subject: [PATCH 11/17] Update dfx-deploy.mdx (#3952) --- docs/cli-reference/dfx-deploy.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli-reference/dfx-deploy.mdx b/docs/cli-reference/dfx-deploy.mdx index 24ad93411a..6433710058 100644 --- a/docs/cli-reference/dfx-deploy.mdx +++ b/docs/cli-reference/dfx-deploy.mdx @@ -49,7 +49,7 @@ You can use the following options with the `dfx deploy` command. ### Specifies the argument to pass to the init entrypoint -With `--argument-type`, you can specify the data format for the argument when you install using the `--argument` option. The valid values are `idl` and `raw`. By default, you can specify arguments using the [Candid](/docs/current/developer-docs/smart-contracts/candid/index) (`idl`) syntax for data values. For information about using Candid and its supported types, see [Interact with a service in a terminal](/docs/current/developer-docs/smart-contracts/candid/candid-howto#idl-syntax) and [Supported types](/docs/current/references/candid-ref). You can use `raw` as the argument type if you want to pass raw bytes to a canister. +With `--argument-type`, you can specify the data format for the argument when you install using the `--argument` option. The valid values are `idl` and `raw`. By default, you can specify arguments using the [Candid](/docs/current/developer-docs/smart-contracts/candid/candid-concepts) (`idl`) syntax for data values. For information about using Candid and its supported types, see [Interact with a service in a terminal](/docs/current/developer-docs/smart-contracts/candid/candid-howto#idl-syntax) and [Supported types](/docs/current/references/candid-ref). You can use `raw` as the argument type if you want to pass raw bytes to a canister. ## Arguments From 1fa2e26de6454020be37ef0e95507276701c6977 Mon Sep 17 00:00:00 2001 From: DFINITY bot <58022693+dfinity-bot@users.noreply.github.com> Date: Tue, 22 Oct 2024 01:12:49 +0200 Subject: [PATCH 12/17] chore: update replica version to 3c76b914 (#3956) --- Cargo.lock | 164 ++++++++++++++++++++++---- e2e/tests-dfx/create.bash | 7 +- nix/sources.json | 132 ++++++++++----------- src/dfx/Cargo.toml | 2 +- src/dfx/assets/dfx-asset-sources.toml | 90 +++++++------- src/dfx/src/actors/pocketic.rs | 3 +- 6 files changed, 262 insertions(+), 136 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9213a6ab9..ae2d90d494 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,9 +1548,9 @@ dependencies = [ "hex", "humantime", "hyper-rustls 0.24.2", - "ic-agent", + "ic-agent 0.38.0", "ic-asset", - "ic-cdk", + "ic-cdk 0.13.5", "ic-identity-hsm", "ic-utils 0.38.0", "ic-wasm", @@ -1626,7 +1626,7 @@ dependencies = [ "handlebars", "hex", "humantime-serde", - "ic-agent", + "ic-agent 0.38.0", "ic-identity-hsm", "ic-utils 0.38.0", "itertools 0.10.5", @@ -2512,6 +2512,17 @@ dependencies = [ "http 1.1.0", ] +[[package]] +name = "http-body-to-bytes" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17a08236c6f51c2ee95d840f45acf8fa9e339390e00b4ef640857b2f2a534d70" +dependencies = [ + "bytes", + "http-body 1.0.0", + "http-body-util", +] + [[package]] name = "http-body-util" version = "0.1.1" @@ -2673,6 +2684,53 @@ dependencies = [ "cc", ] +[[package]] +name = "ic-agent" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd3fdf5e5c4f4a9fe5ca612f0febd22dcb161d2f2b75b0142326732be5e4978" +dependencies = [ + "async-lock 3.3.0", + "backoff", + "cached 0.52.0", + "candid", + "ed25519-consensus", + "futures-util", + "hex", + "http 1.1.0", + "http-body 1.0.0", + "http-body-to-bytes", + "http-body-util", + "hyper 1.3.1", + "hyper-rustls 0.27.2", + "hyper-util", + "ic-certification 2.5.0", + "ic-transport-types 0.37.1", + "ic-verify-bls-signature", + "k256 0.13.3", + "leb128", + "p256", + "pem 3.0.4", + "pkcs8 0.10.2", + "rand", + "rangemap", + "reqwest", + "ring 0.17.8", + "rustls-webpki 0.102.3", + "sec1 0.7.3", + "serde", + "serde_bytes", + "serde_cbor", + "serde_repr", + "sha2 0.10.8", + "simple_asn1", + "thiserror", + "time", + "tokio", + "tower", + "url", +] + [[package]] name = "ic-agent" version = "0.38.0" @@ -2689,7 +2747,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.0", "ic-certification 2.5.0", - "ic-transport-types", + "ic-transport-types 0.38.0", "ic-verify-bls-signature", "k256 0.13.3", "leb128", @@ -2728,7 +2786,7 @@ dependencies = [ "futures-intrusive", "globset", "hex", - "ic-agent", + "ic-agent 0.38.0", "ic-utils 0.38.0", "itertools 0.10.5", "json5", @@ -2811,8 +2869,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b1da6a25b045f9da3c9459c0cb2b0700ac368ee16382975a17185a23b9c18ab" dependencies = [ "candid", - "ic-cdk-macros", - "ic0", + "ic-cdk-macros 0.13.2", + "ic0 0.21.1", + "serde", + "serde_bytes", +] + +[[package]] +name = "ic-cdk" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8ecacd682fa05a985253592963306cb9799622d7b1cce4b1edb89c6ec85be1" +dependencies = [ + "candid", + "ic-cdk-macros 0.16.0", + "ic0 0.23.0", "serde", "serde_bytes", ] @@ -2827,10 +2898,24 @@ dependencies = [ "proc-macro2", "quote", "serde", - "serde_tokenstream", + "serde_tokenstream 0.1.7", "syn 1.0.109", ] +[[package]] +name = "ic-cdk-macros" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4d857135deef20cc7ea8f3869a30cd9cfeb1392b3a81043790b2cd82adc3e0" +dependencies = [ + "candid", + "proc-macro2", + "quote", + "serde", + "serde_tokenstream 0.2.2", + "syn 2.0.61", +] + [[package]] name = "ic-certificate-verification" version = "2.4.0" @@ -2906,7 +2991,7 @@ dependencies = [ "candid", "candid_parser", "hex", - "ic-cdk", + "ic-cdk 0.13.5", "ic-certification 2.5.0", "ic-certification-testing", "ic-crypto-tree-hash", @@ -3076,7 +3161,7 @@ name = "ic-frontend-canister" version = "0.2.5" dependencies = [ "candid", - "ic-cdk", + "ic-cdk 0.13.5", "ic-certified-assets", ] @@ -3121,7 +3206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe9975ba49e50ccf10d8268b168b9a35da165904f56725a333e8294d7e5f1d92" dependencies = [ "hex", - "ic-agent", + "ic-agent 0.38.0", "pkcs11", "sha2 0.10.8", "simple_asn1", @@ -3215,6 +3300,23 @@ dependencies = [ "wsl", ] +[[package]] +name = "ic-transport-types" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875dc4704780383112e8e8b5063a1b98de114321d0c7d3e7f635dcf360a57fba" +dependencies = [ + "candid", + "hex", + "ic-certification 2.5.0", + "leb128", + "serde", + "serde_bytes", + "serde_repr", + "sha2 0.10.8", + "thiserror", +] + [[package]] name = "ic-transport-types" version = "0.38.0" @@ -3294,7 +3396,7 @@ dependencies = [ "async-trait", "candid", "futures-util", - "ic-agent", + "ic-agent 0.38.0", "once_cell", "semver", "serde", @@ -3346,6 +3448,12 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a54b5297861c651551676e8c43df805dad175cc33bc97dbd992edbbb85dcbcdf" +[[package]] +name = "ic0" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de254dd67bbd58073e23dc1c8553ba12fa1dc610a19de94ad2bbcd0460c067f" + [[package]] name = "ic_bls12_381" version = "0.8.0" @@ -3416,7 +3524,7 @@ dependencies = [ "clap", "delay", "humantime", - "ic-agent", + "ic-agent 0.38.0", "ic-asset", "ic-utils 0.38.0", "libflate 1.4.0", @@ -4566,20 +4674,24 @@ dependencies = [ [[package]] name = "pocket-ic" -version = "4.0.0" -source = "git+https://github.com/dfinity/ic?rev=179973553248415fc85679d853b48b0e0ec231c6#179973553248415fc85679d853b48b0e0ec231c6" +version = "5.0.0" +source = "git+https://github.com/dfinity/ic?rev=3c76b9142f67da01393d9280c705f88b6e522a93#3c76b9142f67da01393d9280c705f88b6e522a93" dependencies = [ "base64 0.13.1", "candid", "hex", - "ic-cdk", + "ic-agent 0.37.1", + "ic-cdk 0.16.0", + "ic-transport-types 0.37.1", "reqwest", "schemars", "serde", "serde_bytes", + "serde_cbor", "serde_json", "sha2 0.10.8", "slog", + "thiserror", "tokio", "tracing", "tracing-appender", @@ -5613,6 +5725,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "serde_tokenstream" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64060d864397305347a78851c51588fd283767e7e7589829e8121d65512340f1" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.61", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -6113,18 +6237,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", diff --git a/e2e/tests-dfx/create.bash b/e2e/tests-dfx/create.bash index 881bee09fa..fbbe866d4d 100644 --- a/e2e/tests-dfx/create.bash +++ b/e2e/tests-dfx/create.bash @@ -417,14 +417,15 @@ function textual_decode() { CANISTER_ID_BASE64="$(textual_decode "${CANISTER_ID}" | xxd -r -p | base64)" # fetch topology from PocketIC server TOPOLOGY="$(curl "http://127.0.0.1:$(dfx info replica-port)/instances/0/read/topology")" + echo "${TOPOLOGY}" # find application subnet id in the topology - for subnet_id in $(echo "${TOPOLOGY}" | jq keys[]) + for subnet_id in $(echo "${TOPOLOGY}" | jq '.subnet_configs | keys[]') do - SUBNET_KIND="$(echo "$TOPOLOGY" | jq -r ".${subnet_id}.\"subnet_kind\"")" + SUBNET_KIND="$(echo "$TOPOLOGY" | jq -r ".subnet_configs.${subnet_id}.\"subnet_kind\"")" if [ "${SUBNET_KIND}" == "Application" ] then # find the expected canister id as the beginning of the first canister range of the app subnet - EXPECTED_CANISTER_ID_BASE64="$(echo "$TOPOLOGY" | jq -r ".${subnet_id}.\"canister_ranges\"[0].\"start\".\"canister_id\"")" + EXPECTED_CANISTER_ID_BASE64="$(echo "$TOPOLOGY" | jq -r ".subnet_configs.${subnet_id}.\"canister_ranges\"[0].\"start\".\"canister_id\"")" fi done # check if the actual canister id matches the expected canister id diff --git a/nix/sources.json b/nix/sources.json index e14ac2bde3..9a74c1c6f1 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -2,71 +2,71 @@ "canister_sandbox-x86_64-darwin": { "builtin": false, "description": "The canister_sandbox binary. It must be updated together with the replica binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1a0b0xbpqr68p6zffc0di3f6i3zzap5n1xyl6gcjgrhklilnmfxj", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "0y7zs1njdvzs971r0l1wjmbgwa4alc99mlqssd6lg67548g8pbdn", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/canister_sandbox.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/canister_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/canister_sandbox.gz" }, "canister_sandbox-x86_64-linux": { "builtin": false, "description": "The canister_sandbox binary. It must be updated together with the replica binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1rzy24mhrvx3whi130nifxwplpqh1k2r7ld00c5imkzcl4d1lcv4", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1rb3r9h2pfqsvbdr716s7k9gh3by3c1ap5ab6jgg0qci6fyh5ls0", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/canister_sandbox.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/canister_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/canister_sandbox.gz" }, "compiler_sandbox-x86_64-darwin": { "builtin": false, "description": "The compiler_sandbox binary. It must be updated together with the replica binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0a24bc330ym0prlfkghgbxmndvyh13cwxdf76pgikw6804d6s5a6", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "028vy5pz7m17rx10iqyj0qsnlns5qq6zxmplx0jc0gg9f8hdlmfd", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/compiler_sandbox.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/compiler_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/compiler_sandbox.gz" }, "compiler_sandbox-x86_64-linux": { "builtin": false, "description": "The compiler_sandbox binary. It must be updated together with the replica binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0wwwwvcyhyzcvril477bchbpif1a1s702fy4sv69ni9wz1vr25a6", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "0shc1l0k8b23rabln81vzfj17ah71dqji1dw44hhbm835gfz1sf9", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/compiler_sandbox.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/compiler_sandbox.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/compiler_sandbox.gz" }, "ic-admin-x86_64-darwin": { "builtin": false, "description": "The ic-admin binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "004wk976w6dw6cd1k08c5ca7ylbdkjgqa28f3cwr6nghafq8ik1m", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1r4rsmvj408l1cyb9ih59xf0dr0z708s9qwnlby0a1lcyfarbd0c", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-admin.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-admin.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-admin.gz" }, "ic-admin-x86_64-linux": { "builtin": false, "description": "The ic-admin binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1z5gnz7ydm86npbybcklcd0w0w7m3hniqln0rgqmr6frncj6d9kh", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1q96fmqd0l5vqmvp0a9cm2rw3bgjr1xhvmyib00n5gks9ijivrgd", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-admin.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-admin.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-admin.gz" }, "ic-btc-adapter-x86_64-darwin": { "builtin": false, - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0d85xfiwiffpsn1vdfid1bfb5qxss1n5kbj3fx8hhw3z34rgs65k", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "11z81llj7dk3p2xq4cdikic3gbpb25f4j1087fhdhwpsbjlrxiba", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-btc-adapter.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-btc-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-btc-adapter.gz" }, "ic-btc-adapter-x86_64-linux": { "builtin": false, - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0f2kwbgksgc0hzpxahxsfqsqv949cma3y40p4zmaafvqwx2ndarv", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1s4m93ngbqpp5ab1qgb2g51hnk94jj7zsi9i7zl1psb9dgnkh5nz", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-btc-adapter.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-btc-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-btc-adapter.gz" }, "ic-btc-canister": { @@ -78,52 +78,52 @@ }, "ic-https-outcalls-adapter-x86_64-darwin": { "builtin": false, - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0mizw7q2mmv1n8lby63n4w9x4lnkdxxq48dwhp6fhs1mlq59nvc5", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1vskby9drh0jwyxafbnk11qj3pmf8p24hkcalr5d2m9s5lpigjhi", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-https-outcalls-adapter.gz" }, "ic-https-outcalls-adapter-x86_64-linux": { "builtin": false, - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0xivhcq195n0jrd67hmpsf5ab9rdcnylfq05799ym6qxx6pkmr69", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1jcxr8lzgr77wm1d2ksfhv44nchqmx4dcgh2r0hbn4ck2zls1w6i", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-https-outcalls-adapter.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-https-outcalls-adapter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-https-outcalls-adapter.gz" }, "ic-nns-init-x86_64-darwin": { "builtin": false, "description": "The ic-nns-init binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0yg7mhcg98byxn69h32hb823r6sfm9nvz1i1gxl65w9516zsmppx", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "0pwm70vx0xbnv3kv4x64nszdihrx3kd7kwz9kid82v5xlpmlda0i", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-nns-init.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-nns-init.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-nns-init.gz" }, "ic-nns-init-x86_64-linux": { "builtin": false, "description": "The ic-nns-init binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "095x9k6adarikw91g6c6p6l3mc0x92gyabclwicp7y587hw68app", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "00gvrh7iiv8wilhc39sarcaf5f5dsr5rcd5wy4rh8as7k39ykjki", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-nns-init.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-nns-init.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-nns-init.gz" }, "ic-starter-x86_64-darwin": { "builtin": false, - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0a8mhbbsdgh2bs2hy3xawss6a4ig138hij5w1f2w4vwgagwfwj6w", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1w1r21g5wbh0klzm59y30rx46z4izxblvp7jckddmqjsp98wwshm", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-starter.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-starter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/ic-starter.gz" }, "ic-starter-x86_64-linux": { "builtin": false, - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1m2p94hx12jxqby3s91k0aqb3iqy06xr6pdlkmi3dp7mq0bn0pny", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1g0bvajccdaj3sjh9y28b7g6jlh841xs5n0xi76ffhzvxhkfvc1s", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-starter.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-starter.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/ic-starter.gz" }, "motoko-base": { @@ -153,71 +153,71 @@ "version": "0.13.1" }, "pocket-ic-x86_64-darwin": { - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "0h4a96v20vvr5wlj3jixd0bfj22sczxl6q0cvcdwfv2irs7jfjxa", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "0ybw08pghwgcw3lqxgd41q0jc4qdyga2grcnfnqbiynrjrbyx8w9", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/pocket-ic.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/pocket-ic.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/pocket-ic.gz" }, "pocket-ic-x86_64-linux": { - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1d7j76kv4zr8n58dhyrw5bvv945p9gkq7n9jxp2477rxg8932056", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "0a5s0vvyshg59h139lsxpikrvicml8az1rp5m1cwimh7djjc9acv", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/pocket-ic.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/pocket-ic.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/pocket-ic.gz" }, "replica-x86_64-darwin": { "builtin": false, "description": "The replica binary. It must be updated together with the canister_sandbox binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "032c7nf0gdzqssbaxcp25f1fdgr9g7w49q5zl55by3rb0f7w227k", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "1i4ab9yjamip4ys969qy7q32qhh4dn7dzdljwwzbis78vh4crrzr", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/replica.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/replica.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/replica.gz" }, "replica-x86_64-linux": { "builtin": false, "description": "The replica binary. It must be updated together with the canister_sandbox binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "11cs8p01q8zz19smbc030pj14wh2i7fw84s3lrgg86qbvkpj5jzw", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "0vg22spwl8kz0dmknj7v88hgndv1qlvqby6ayb5hs8446rn73psh", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/replica.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/replica.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/replica.gz" }, "sandbox_launcher-x86_64-darwin": { "builtin": false, "description": "The sandbox_launcher binary. It must be updated together with the replica binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "080dfr3kf0yash63n6d588sklxalzijd1x3c61xjvjnhs7vkkck3", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "01bzyx8faysx8mslvkiwcq21f3c5fbnhc73f703s22aav292afxv", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sandbox_launcher.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/sandbox_launcher.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/sandbox_launcher.gz" }, "sandbox_launcher-x86_64-linux": { "builtin": false, "description": "The sandbox_launcher binary. It must be updated together with the replica binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1b3igk4xg0g65701ig25vi122pm7wb4577cyh2qi7362pqp10dwy", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "128igib3yv995lznapd6x73lsnhnwpi0gf4vixia3413kr22kd1g", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sandbox_launcher.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/sandbox_launcher.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/sandbox_launcher.gz" }, "sns-x86_64-darwin": { "builtin": false, "description": "The sns binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1rrml0xr3r57ixgg0km6d0jvmp1p8bfir9jv16wl8x7p4254ifqs", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "08grpjrxn7zzs3xvvfnds4h1vpwi4k7zlhzvs2jjk4ma064x0rdp", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sns.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/sns.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-darwin/sns.gz" }, "sns-x86_64-linux": { "builtin": false, "description": "The sns binary.", - "rev": "0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a", - "sha256": "1m3vmb84hmwhxzpiik2rfdp70lr4id1jv9fip8p8ygxid4ira3yi", + "rev": "3c76b9142f67da01393d9280c705f88b6e522a93", + "sha256": "11lna989cdz371xy9ipgahdv4dsj4i9l44zagzjyvgq6rylfivi0", "type": "file", - "url": "https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sns.gz", + "url": "https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/sns.gz", "url_template": "https://download.dfinity.systems/ic//binaries/x86_64-linux/sns.gz" } } diff --git a/src/dfx/Cargo.toml b/src/dfx/Cargo.toml index b87d9dc9a8..c41f86f13b 100644 --- a/src/dfx/Cargo.toml +++ b/src/dfx/Cargo.toml @@ -127,7 +127,7 @@ ci_info = "0.14" junction = "1.0.0" [target.'cfg(unix)'.dependencies] -pocket-ic = { git = "https://github.com/dfinity/ic", rev = "179973553248415fc85679d853b48b0e0ec231c6" } +pocket-ic = { git = "https://github.com/dfinity/ic", rev = "3c76b9142f67da01393d9280c705f88b6e522a93" } [dev-dependencies] env_logger = "0.10" diff --git a/src/dfx/assets/dfx-asset-sources.toml b/src/dfx/assets/dfx-asset-sources.toml index 73de34fc13..9dd71f3a95 100644 --- a/src/dfx/assets/dfx-asset-sources.toml +++ b/src/dfx/assets/dfx-asset-sources.toml @@ -1,25 +1,25 @@ # generated by write-dfx-asset-sources.sh -replica-rev = '0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a' +replica-rev = '3c76b9142f67da01393d9280c705f88b6e522a93' [x86_64-darwin.ic-admin] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-admin.gz' -sha256 = '35cc88b053f05993391b0e09859f9c6d517f142b0c81191a33bc196e4e9a9c00' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-admin.gz' +sha256 = '0cb49595f38c0605fca296e3a411381fe4065c4f05c6b43c0b14012277d599e4' [x86_64-darwin.ic-btc-adapter] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-btc-adapter.gz' -sha256 = 'b318fd32197f7008517743ae596cd0bae3b2dc0a2dbab683d5d7b9c8a3eb0535' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-btc-adapter.gz' +sha256 = '6ac59ea95cfa72d8a03b0804495c11ebae37589cb13182bbb863b623290de887' [x86_64-darwin.ic-https-outcalls-adapter] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz' -sha256 = '856d9b0aa63568e8cc85bc21827b6fd352d213277618bf28b261d72af0e13f56' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-https-outcalls-adapter.gz' +sha256 = '11ca172f2d3a55d14aa68a4d48c445aede217108d32ea7bae712c0dc925f53ef' [x86_64-darwin.ic-nns-init] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-nns-init.gz' -sha256 = 'fddeaabf0925f162687f2186bf6daa4e9b3c045a500c988ced7ea1f418ace779' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-nns-init.gz' +sha256 = '11a846eba5bd6c815a9ce9f379da1c3dc3d8beb6c474b2e7d87675d03738955f' [x86_64-darwin.ic-starter] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/ic-starter.gz' -sha256 = 'dc48eef8538f6fc2850bbcc808d1082f1265b4e6aa0f0f855e02bea6d7821529' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/ic-starter.gz' +sha256 = '156ace51ba5ae2dada64f2dc4d57ff917c437a06c3a7523f9d002e5e5e1039f0' [x86_64-darwin.motoko] url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-Darwin-x86_64-0.13.1.tar.gz' @@ -27,30 +27,30 @@ sha256 = '98549030e87d081ea86ab193adcce4c158c75cf525dea57773911d6c7b99e7bf' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-darwin.replica] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/replica.gz' -sha256 = 'f308c18f032b0fbf4aa1bfe044f87929bfe6822be2b2ae96d6f8b7079c3d4c0c' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/replica.gz' +sha256 = 'f9e7cc08dce8e8b83ee792b6df8e6d04422c063e1e2793b4273756257d5a8ac4' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-darwin.canister_sandbox] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/canister_sandbox.gz' -sha256 = 'b2bb6a69a413e627d933d4f760cb55ff8f68dc880d30e7beb9c8647c57070ba8' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/canister_sandbox.gz' +sha256 = 'b6ad8b1e22e598474dd31ad39a12a38a28fe56953c5090c349faef266dd0ff78' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-darwin.compiler_sandbox] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/compiler_sandbox.gz' -sha256 = '46156d1a01c8f019df35c7b5ced908d0ef666b5f0fbee968bea07a30065b4428' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/compiler_sandbox.gz' +sha256 = 'cd55da2072e93dc024e8f4d6fe0dc6455b6a3506d2e30842cf27d4f36ff11b09' [x86_64-darwin.sandbox_launcher] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sandbox_launcher.gz' -sha256 = '63b239f7d1d0ca2d7b306cf4d064fc54753a3542a5193b0cd4ca033747760d20' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/sandbox_launcher.gz' +sha256 = 'bb3b2592d84a09a107386e1c06ed72850d1704663cce4d75455d7be550f77f05' [x86_64-darwin.sns] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/sns.gz' -sha256 = '1abb488a20f77444b9095ba61cdd4237dcba2568a64ef05e8fa7e4913ba035e7' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/sns.gz' +sha256 = 'b765d08901aa9229a5d0fb43facf2491df1d20d1cdbabdfbd0ff1fdbb3bcf921' [x86_64-darwin.pocket-ic] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-darwin/pocket-ic.gz' -sha256 = 'aa4b278fce516cc71bdb0c6043fb675a08e916683dca21292f796f20b6498a40' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-darwin/pocket-ic.gz' +sha256 = '89a3ee5796d9fab8b07596e527d4f30d1326010ea4bd8ee9e0ec71f82e027c79' [x86_64-darwin.motoko-base] url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-base-library.tar.gz' @@ -61,24 +61,24 @@ url = 'https://github.com/dfinity/bitcoin-canister/releases/download/release%2F2 sha256 = '09f5647a45ff6d5d05b2b0ed48613fb2365b5fe6573ba0e901509c39fb9564ac' [x86_64-linux.ic-admin] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-admin.gz' -sha256 = '70a66624b3d9995cf1cbc0521c2d1cf570c0416374b2e5d7b506d5e6cfb7affc' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-admin.gz' +sha256 = 'ede51d654c7abe620158d1d70d7bc8f2adc1b3a82c297077c5bb50d0707526e1' [x86_64-linux.ic-btc-adapter] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-btc-adapter.gz' -sha256 = '3bab6645e7783ba5ea2717103f546589a48d3576ba43d5ef87803d3ddfe25338' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-btc-adapter.gz' +sha256 = 'df1638ed6b69e91be83f3145fd8f94244d0b4379623d1c962af7e2f5ec4895e8' [x86_64-linux.ic-https-outcalls-adapter] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-https-outcalls-adapter.gz' -sha256 = 'c9e43aafe91d9bea533a056047bd652da7a58ad3b7c2635a96c0961430833b76' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-https-outcalls-adapter.gz' +sha256 = 'd1f0a0e9179311bb20c8023ed648af18324bc8864e4fd142e5e7e4f729ca9dc9' [x86_64-linux.ic-nns-init] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-nns-init.gz' -sha256 = 'f72a64383ca8f87359e4942de59f481db03aa8b9869917129f31aba6cc4cbd24' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-nns-init.gz' +sha256 = '71cae9d398472b0433f1bc34964bd6adb8e214cb4aa7c1208d1ced180fccfb01' [x86_64-linux.ic-starter] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/ic-starter.gz' -sha256 = 'de5e6017c0f5dc36629db45d93bb011ec7b1b00233243dfcc25d8ad0214957d4' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/ic-starter.gz' +sha256 = '3ab0ed26ecfb43e7cc891dd8a27b20085269de5948f804a51e5235c6a4da0bbc' [x86_64-linux.motoko] url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-Linux-x86_64-0.13.1.tar.gz' @@ -86,30 +86,30 @@ sha256 = '69c99ce29424f7113db8b3c42f5703a9a10288fed998adc6fdd9c36263df267a' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-linux.replica] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/replica.gz' -sha256 = 'fccb22efdc0b1bf45ea64313c4dd89027212e40503b055750aff231cc0459a85' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/replica.gz' +sha256 = '50df716c3684200dcbf2caf88537c56137fb2042fb483b6b037f22caaf16e26d' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-linux.canister_sandbox] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/canister_sandbox.gz' -sha256 = '64331a1aa1eccf1a0b03a0d193c50c105f7a7977d1821122e4a3ef0c2b11fee7' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/canister_sandbox.gz' +sha256 = '40d302bd339161f09e344b95ab021b7e0df8d23cda8493dbda1abb2b60ca63e5' # The replica, canister_sandbox and compiler_sandbox binaries must have the same revision. [x86_64-linux.compiler_sandbox] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/compiler_sandbox.gz' -sha256 = '46159177f83c459bccd6c43b018e0e2ab8781764eb1c4263deec7be8d9e69c73' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/compiler_sandbox.gz' +sha256 = 'c9e9f0dd2b03d5052121bc8528710b07aa13a4fb3b204b97ca432c34010d0c6a' [x86_64-linux.sandbox_launcher] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sandbox_launcher.gz' -sha256 = '9e37102ebec28c13b1809e9d53c8e2a75e2142dc45bc18c029e681d7c97c71ac' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/sandbox_launcher.gz' +sha256 = '2fb429449e2390a1628f9bb807e2e5165a4dc7e9a65d653f2d296d3f567c1189' [x86_64-linux.sns] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/sns.gz' -sha256 = 'd10f952369b13f8f2ebad1a52d438b2453706e7359cc18efef905748d0aa7bd4' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/sns.gz' +sha256 = '20eee8a8cf06bfede57fea134253245237b21b54efc6e47b38e3379650529686' [x86_64-linux.pocket-ic] -url = 'https://download.dfinity.systems/ic/0a6d829cddc1534c29e0d2c3c3ebd1024bff8d1a/binaries/x86_64-linux/pocket-ic.gz' -sha256 = 'a60031127a3d9f43c4ed32d983e74bb790b4f72a3c7bd850b1287fb2a739f2b4' +url = 'https://download.dfinity.systems/ic/3c76b9142f67da01393d9280c705f88b6e522a93/binaries/x86_64-linux/pocket-ic.gz' +sha256 = '9ba9c4a46c07d6c859a8e5e6f015a295c59d67bc5dd334024ce541edf706ba28' [x86_64-linux.motoko-base] url = 'https://github.com/dfinity/motoko/releases/download/0.13.1/motoko-base-library.tar.gz' diff --git a/src/dfx/src/actors/pocketic.rs b/src/dfx/src/actors/pocketic.rs index 3e8b2a8d3c..bac34f54ee 100644 --- a/src/dfx/src/actors/pocketic.rs +++ b/src/dfx/src/actors/pocketic.rs @@ -358,6 +358,7 @@ async fn initialize_pocketic( state_dir: Some(replica_config.state_manager.state_root.clone()), nonmainnet_features: true, log_level: Some(replica_config.log_level.to_ic_starter_string()), + bitcoind_addr: None, }) .send() .await? @@ -381,7 +382,7 @@ async fn initialize_pocketic( return Err(anyhow!("Internal error: PocketIC topology contains multiple subnets of the same subnet kind.")); } let subnet_id = subnets[0]; - let subnet_config = topology.0.get(&subnet_id).ok_or(anyhow!( + let subnet_config = topology.subnet_configs.get(&subnet_id).ok_or(anyhow!( "Internal error: subnet id {} not found in PocketIC topology", subnet_id ))?; From 705c34689a1e5cb2c8421404f3c120fff93e4612 Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Tue, 22 Oct 2024 11:22:46 +0200 Subject: [PATCH 13/17] feat(asset-canister): upload and commit in same message (#3954) --- CHANGELOG.md | 7 +- docs/design/asset-canister-interface.md | 3 + .../ic-asset/src/batch_upload/operations.rs | 34 +++++---- .../ic-asset/src/batch_upload/plumbing.rs | 43 ++++++----- .../canister_api/types/batch_upload/common.rs | 4 +- .../error/assemble_commit_batch_argument.rs | 11 +++ .../ic-asset/src/error/compute_evidence.rs | 6 ++ .../frontend/ic-asset/src/error/mod.rs | 4 + .../ic-asset/src/error/set_encoding.rs | 9 +++ .../frontend/ic-asset/src/error/upload.rs | 5 ++ .../ic-asset/src/error/upload_content.rs | 6 ++ .../frontend/ic-asset/src/evidence/mod.rs | 3 +- src/canisters/frontend/ic-asset/src/sync.rs | 6 +- src/canisters/frontend/ic-asset/src/upload.rs | 6 +- .../ic-certified-assets/src/evidence.rs | 6 ++ .../ic-certified-assets/src/state_machine.rs | 70 ++++++++++++++---- .../frontend/ic-certified-assets/src/tests.rs | 14 ++++ .../frontend/ic-certified-assets/src/types.rs | 2 + src/distributed/assetstorage.wasm.gz | Bin 399164 -> 399832 bytes 19 files changed, 184 insertions(+), 55 deletions(-) create mode 100644 src/canisters/frontend/ic-asset/src/error/assemble_commit_batch_argument.rs create mode 100644 src/canisters/frontend/ic-asset/src/error/set_encoding.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e37c6b50a..1a711244c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,15 +13,20 @@ Valid settings are: ### feat: batch upload assets The frontend canister sync now tries to batch multiple small content chunks into a single call using the `create_chunks` method added earlier. +And for small amounts of uploaded data the asset sync can now skip chunk creation entirely. This should lead to significantly faster upload times for frontends with many small files. ## Dependencies ### Frontend canister +`SetAssetContentArguments` has a new field `last_chunk: opt blob` which can be used in addition to `chunk_ids` so that small assets can be uploaded as part of `commit_batch`, +skipping the need to await a separate `create_chunk` call. + Bumped `api_version` to `2` for the previous addition of `create_chunks` since the improved file sync relies on it. -- Module hash: 9e4485d4358dd910aebcc025843547d05604cf28c6dc7c2cc2f8c76d083112e8 +- Module hash: 296d1ad1a7f8b15f90ff8b728658646b649cabd159f360f1b427297f4c76763e +- https://github.com/dfinity/sdk/pull/3954 - https://github.com/dfinity/sdk/pull/3947 # 0.24.1 diff --git a/docs/design/asset-canister-interface.md b/docs/design/asset-canister-interface.md index de2a4529fd..a761376823 100644 --- a/docs/design/asset-canister-interface.md +++ b/docs/design/asset-canister-interface.md @@ -483,11 +483,14 @@ type SetAssetContentArguments = record { key: Key; content_encoding: text; chunk_ids: vec ChunkId; + last_chunk: opt blob; sha256: opt blob; }; ``` This operation adds or changes a single content encoding for an asset. It also updates the modification time of the content encoding. +The content of the encoding can be specified with `chunk_ids` and `last_chunk`. +If `last_chunk` is not `null`, then its content is used as the last chunk of the encoding. If `sha256` is not passed, the asset canister will compute the hash of the content. diff --git a/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs b/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs index 518fb58330..76d5e03066 100644 --- a/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs +++ b/src/canisters/frontend/ic-asset/src/batch_upload/operations.rs @@ -7,6 +7,7 @@ use crate::canister_api::types::batch_upload::common::{ UnsetAssetContentArguments, }; use crate::canister_api::types::batch_upload::v1::{BatchOperationKind, CommitBatchArguments}; +use crate::error::{AssembleCommitBatchArgumentError, SetEncodingError}; use candid::Nat; use std::collections::HashMap; @@ -20,7 +21,7 @@ pub(crate) async fn assemble_batch_operations( canister_assets: HashMap, asset_deletion_reason: AssetDeletionReason, canister_asset_properties: HashMap, -) -> Vec { +) -> Result, AssembleCommitBatchArgumentError> { let mut canister_assets = canister_assets; let mut operations = vec![]; @@ -33,10 +34,12 @@ pub(crate) async fn assemble_batch_operations( ); create_new_assets(&mut operations, project_assets, &canister_assets); unset_obsolete_encodings(&mut operations, project_assets, &canister_assets); - set_encodings(&mut operations, chunk_uploader, project_assets).await; + set_encodings(&mut operations, chunk_uploader, project_assets) + .await + .map_err(AssembleCommitBatchArgumentError::SetEncodingFailed)?; update_properties(&mut operations, project_assets, &canister_asset_properties); - operations + Ok(operations) } pub(crate) async fn assemble_commit_batch_arguments( @@ -46,7 +49,7 @@ pub(crate) async fn assemble_commit_batch_arguments( asset_deletion_reason: AssetDeletionReason, canister_asset_properties: HashMap, batch_id: Nat, -) -> CommitBatchArguments { +) -> Result { let operations = assemble_batch_operations( Some(chunk_uploader), &project_assets, @@ -54,11 +57,11 @@ pub(crate) async fn assemble_commit_batch_arguments( asset_deletion_reason, canister_asset_properties, ) - .await; - CommitBatchArguments { + .await?; + Ok(CommitBatchArguments { operations, batch_id, - } + }) } pub(crate) enum AssetDeletionReason { @@ -163,29 +166,32 @@ pub(crate) async fn set_encodings( operations: &mut Vec, chunk_uploader: Option<&ChunkUploader<'_>>, project_assets: &HashMap, -) { +) -> Result<(), SetEncodingError> { for (key, project_asset) in project_assets { for (content_encoding, v) in &project_asset.encodings { if v.already_in_place { continue; } - let chunk_ids = if let Some(uploader) = chunk_uploader { - uploader - .uploader_ids_to_canister_chunk_ids(&v.uploader_chunk_ids) - .await - } else { - vec![] + let (chunk_ids, last_chunk) = match chunk_uploader { + Some(uploader) => { + uploader + .uploader_ids_to_canister_chunk_ids(&v.uploader_chunk_ids) + .await? + } + None => (vec![], None), }; operations.push(BatchOperationKind::SetAssetContent( SetAssetContentArguments { key: key.clone(), content_encoding: content_encoding.clone(), chunk_ids, + last_chunk, sha256: Some(v.sha256.clone()), }, )); } } + Ok(()) } pub(crate) fn update_properties( diff --git a/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs b/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs index 640b9d48e0..f0c4b449a4 100644 --- a/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs +++ b/src/canisters/frontend/ic-asset/src/batch_upload/plumbing.rs @@ -9,6 +9,7 @@ use crate::error::CreateChunkError; use crate::error::CreateEncodingError; use crate::error::CreateEncodingError::EncodeContentFailed; use crate::error::CreateProjectAssetError; +use crate::error::SetEncodingError; use candid::Nat; use futures::future::try_join_all; use futures::TryFutureExt; @@ -99,8 +100,7 @@ impl<'agent> ChunkUploader<'agent> { // - Tested with: `for i in $(seq 1 50); do dd if=/dev/urandom of="src/hello_frontend/assets/file_$i.bin" bs=$(shuf -i 1-2000000 -n 1) count=1; done && dfx deploy hello_frontend` // - Result: Roughly 15% of batches under 90% full. // With other byte ranges (e.g. `shuf -i 1-3000000 -n 1`) stats improve significantly - self.upload_chunks(4 * MAX_CHUNK_SIZE, usize::MAX, semaphores) - .await?; + self.upload_chunks(4 * MAX_CHUNK_SIZE, semaphores).await?; Ok(uploader_chunk_id) } } @@ -109,8 +109,8 @@ impl<'agent> ChunkUploader<'agent> { &self, semaphores: &Semaphores, ) -> Result<(), CreateChunkError> { - self.upload_chunks(0, 0, semaphores).await?; - Ok(()) + // Crude estimate: If `MAX_CHUNK_SIZE / 2` bytes are added as data to the `commit_batch` args the message won't be above the message size limit. + self.upload_chunks(MAX_CHUNK_SIZE / 2, semaphores).await } pub(crate) fn bytes(&self) -> usize { @@ -120,21 +120,32 @@ impl<'agent> ChunkUploader<'agent> { self.chunks.load(Ordering::SeqCst) } - /// Call only after `finalize_upload` has completed + /// Call only after `finalize_upload` has completed. pub(crate) async fn uploader_ids_to_canister_chunk_ids( &self, uploader_ids: &[usize], - ) -> Vec { + ) -> Result<(Vec, Option>), SetEncodingError> { + let mut chunk_ids = vec![]; + let mut last_chunk: Option> = None; let mapping = self.id_mapping.lock().await; - uploader_ids - .iter() - .map(|id| { - mapping - .get(id) - .expect("Chunk uploader did not upload all chunks. This is a bug.") - .clone() - }) - .collect() + let queue = self.upload_queue.lock().await; + for uploader_id in uploader_ids { + if let Some(item) = mapping.get(uploader_id) { + chunk_ids.push(item.clone()); + } else if let Some(last_chunk_data) = + queue + .iter() + .find_map(|(id, data)| if id == uploader_id { Some(data) } else { None }) + { + match last_chunk.as_mut() { + Some(existing_data) => existing_data.extend(last_chunk_data.iter()), + None => last_chunk = Some(last_chunk_data.clone()), + } + } else { + return Err(SetEncodingError::UnknownUploaderChunkId(*uploader_id)); + } + } + Ok((chunk_ids, last_chunk)) } async fn add_to_upload_queue(&self, uploader_chunk_id: usize, contents: &[u8]) { @@ -148,7 +159,6 @@ impl<'agent> ChunkUploader<'agent> { async fn upload_chunks( &self, max_retained_bytes: usize, - max_retained_chunks: usize, semaphores: &Semaphores, ) -> Result<(), CreateChunkError> { let mut queue = self.upload_queue.lock().await; @@ -159,7 +169,6 @@ impl<'agent> ChunkUploader<'agent> { .map(|(_, content)| content.len()) .sum::() > max_retained_bytes - || queue.len() > max_retained_chunks { // Greedily fills batch with the largest chunk that fits queue.sort_unstable_by_key(|(_, content)| content.len()); diff --git a/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs b/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs index 7e36d1d5ad..8b7d4e59b6 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/types/batch_upload/common.rs @@ -77,8 +77,10 @@ pub struct SetAssetContentArguments { pub key: String, /// The content encoding for which this content applies pub content_encoding: String, - /// The chunks to assign to this content + /// The chunks to assign to this content encoding pub chunk_ids: Vec, + /// Appends this chunk to the data supplied in `chunk_ids` + pub last_chunk: Option>, /// The sha256 of the entire content pub sha256: Option>, } diff --git a/src/canisters/frontend/ic-asset/src/error/assemble_commit_batch_argument.rs b/src/canisters/frontend/ic-asset/src/error/assemble_commit_batch_argument.rs new file mode 100644 index 0000000000..399246a150 --- /dev/null +++ b/src/canisters/frontend/ic-asset/src/error/assemble_commit_batch_argument.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +use super::SetEncodingError; + +/// Errors related to assembling commit_batch arguments for the asset canister. +#[derive(Error, Debug)] +pub enum AssembleCommitBatchArgumentError { + /// Failed to set encoding. + #[error("Failed to set encoding: {0}")] + SetEncodingFailed(#[from] SetEncodingError), +} diff --git a/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs b/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs index 17a224b8ed..4c127d1af1 100644 --- a/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs +++ b/src/canisters/frontend/ic-asset/src/error/compute_evidence.rs @@ -5,9 +5,15 @@ use crate::error::hash_content::HashContentError; use ic_agent::AgentError; use thiserror::Error; +use super::AssembleCommitBatchArgumentError; + /// Errors related to computing evidence for a proposed update. #[derive(Error, Debug)] pub enum ComputeEvidenceError { + /// Failed when assembling commit_batch argument. + #[error(transparent)] + AssembleCommitBatchArgumentFailed(#[from] AssembleCommitBatchArgumentError), + /// Failed when inspecting assets to be updated. #[error(transparent)] ProcessProjectAsset(#[from] CreateProjectAssetError), diff --git a/src/canisters/frontend/ic-asset/src/error/mod.rs b/src/canisters/frontend/ic-asset/src/error/mod.rs index 6162a8e0d1..bd2ac50c35 100644 --- a/src/canisters/frontend/ic-asset/src/error/mod.rs +++ b/src/canisters/frontend/ic-asset/src/error/mod.rs @@ -1,5 +1,6 @@ //! Error types +mod assemble_commit_batch_argument; mod compatibility; mod compute_evidence; mod create_chunk; @@ -13,10 +14,12 @@ mod hash_content; mod load_config; mod load_rule; mod prepare_sync_for_proposal; +mod set_encoding; mod sync; mod upload; mod upload_content; +pub use assemble_commit_batch_argument::AssembleCommitBatchArgumentError; pub use compatibility::CompatibilityError; pub use compute_evidence::ComputeEvidenceError; pub use create_chunk::CreateChunkError; @@ -30,6 +33,7 @@ pub use hash_content::HashContentError; pub use load_config::AssetLoadConfigError; pub use load_rule::LoadRuleError; pub use prepare_sync_for_proposal::PrepareSyncForProposalError; +pub use set_encoding::SetEncodingError; pub use sync::SyncError; pub use upload::UploadError; pub use upload_content::UploadContentError; diff --git a/src/canisters/frontend/ic-asset/src/error/set_encoding.rs b/src/canisters/frontend/ic-asset/src/error/set_encoding.rs new file mode 100644 index 0000000000..1e17cc75ca --- /dev/null +++ b/src/canisters/frontend/ic-asset/src/error/set_encoding.rs @@ -0,0 +1,9 @@ +use thiserror::Error; + +/// Errors encountered while setting the encodings. +#[derive(Error, Debug)] +pub enum SetEncodingError { + /// Failed when attempting to translate an uploader chunk id to a canister chunk id because the id is unknown. + #[error("Unknown uploader chunk id: {0}")] + UnknownUploaderChunkId(usize), +} diff --git a/src/canisters/frontend/ic-asset/src/error/upload.rs b/src/canisters/frontend/ic-asset/src/error/upload.rs index 0b53996d55..d427d15680 100644 --- a/src/canisters/frontend/ic-asset/src/error/upload.rs +++ b/src/canisters/frontend/ic-asset/src/error/upload.rs @@ -1,3 +1,4 @@ +use super::AssembleCommitBatchArgumentError; use crate::error::compatibility::CompatibilityError; use crate::error::create_project_asset::CreateProjectAssetError; use ic_agent::AgentError; @@ -18,6 +19,10 @@ pub enum UploadError { #[error("Create batch failed: {0}")] CreateBatchFailed(AgentError), + /// Failed when assembling commit_batch argument. + #[error("Failed to assemble commit_batch argument: {0}")] + AssembleCommitBatchArgumentFailed(#[from] AssembleCommitBatchArgumentError), + /// Failed when creating project assets. #[error("Failed to create project asset: {0}")] CreateProjectAssetFailed(#[from] CreateProjectAssetError), diff --git a/src/canisters/frontend/ic-asset/src/error/upload_content.rs b/src/canisters/frontend/ic-asset/src/error/upload_content.rs index e2cf694249..0af8864062 100644 --- a/src/canisters/frontend/ic-asset/src/error/upload_content.rs +++ b/src/canisters/frontend/ic-asset/src/error/upload_content.rs @@ -4,9 +4,15 @@ use crate::error::get_asset_properties::GetAssetPropertiesError; use ic_agent::AgentError; use thiserror::Error; +use super::AssembleCommitBatchArgumentError; + /// Errors related to uploading content to the asset canister. #[derive(Error, Debug)] pub enum UploadContentError { + /// Failed when assembling commit_batch argument. + #[error("Failed to assemble commit_batch argument: {0}")] + AssembleCommitBatchArgumentFailed(AssembleCommitBatchArgumentError), + /// Failed when calling create_batch. #[error("Failed to create batch: {0}")] CreateBatchFailed(AgentError), diff --git a/src/canisters/frontend/ic-asset/src/evidence/mod.rs b/src/canisters/frontend/ic-asset/src/evidence/mod.rs index 18ee8fc390..7d73dbbf1d 100644 --- a/src/canisters/frontend/ic-asset/src/evidence/mod.rs +++ b/src/canisters/frontend/ic-asset/src/evidence/mod.rs @@ -65,7 +65,8 @@ pub async fn compute_evidence( Obsolete, canister_asset_properties, ) - .await; + .await + .map_err(ComputeEvidenceError::AssembleCommitBatchArgumentFailed)?; operations.sort(); let mut sha = Sha256::new(); diff --git a/src/canisters/frontend/ic-asset/src/sync.rs b/src/canisters/frontend/ic-asset/src/sync.rs index ca5be49869..c5513f1bb4 100644 --- a/src/canisters/frontend/ic-asset/src/sync.rs +++ b/src/canisters/frontend/ic-asset/src/sync.rs @@ -84,7 +84,8 @@ pub async fn upload_content_and_assemble_sync_operations( &canister_assets, logger, ) - .await?; + .await + .map_err(UploadContentError::CreateProjectAssetError)?; let commit_batch_args = batch_upload::operations::assemble_commit_batch_arguments( &chunk_uploader, @@ -97,7 +98,8 @@ pub async fn upload_content_and_assemble_sync_operations( canister_asset_properties, batch_id, ) - .await; + .await + .map_err(UploadContentError::AssembleCommitBatchArgumentFailed)?; // -v debug!( diff --git a/src/canisters/frontend/ic-asset/src/upload.rs b/src/canisters/frontend/ic-asset/src/upload.rs index c987b49eb4..7aafee1b2e 100644 --- a/src/canisters/frontend/ic-asset/src/upload.rs +++ b/src/canisters/frontend/ic-asset/src/upload.rs @@ -12,8 +12,7 @@ use crate::canister_api::methods::{ }; use crate::canister_api::types::batch_upload::v0; use crate::error::CompatibilityError::DowngradeV1TOV0Failed; -use crate::error::UploadError; -use crate::error::UploadError::{CommitBatchFailed, CreateBatchFailed, ListAssetsFailed}; +use crate::error::UploadError::{self, CommitBatchFailed, CreateBatchFailed, ListAssetsFailed}; use ic_utils::Canister; use slog::{info, Logger}; use std::collections::HashMap; @@ -62,7 +61,8 @@ pub async fn upload( HashMap::new(), batch_id, ) - .await; + .await + .map_err(UploadError::AssembleCommitBatchArgumentFailed)?; let canister_api_version = api_version(canister).await; info!(logger, "Committing batch."); diff --git a/src/canisters/frontend/ic-certified-assets/src/evidence.rs b/src/canisters/frontend/ic-certified-assets/src/evidence.rs index 68d2e5bbdc..c62b504dcb 100644 --- a/src/canisters/frontend/ic-certified-assets/src/evidence.rs +++ b/src/canisters/frontend/ic-certified-assets/src/evidence.rs @@ -143,6 +143,8 @@ fn next_chunk_index( hasher, }; } + } else if let Some(chunk_content) = sac.last_chunk.as_ref() { + hash_chunk_by_content(&mut hasher, chunk_content); } } NextOperation { @@ -157,6 +159,10 @@ fn hash_chunk_by_id(hasher: &mut Sha256, chunk_id: &ChunkId, chunks: &HashMap Result<(), String> { - if arg.chunk_ids.is_empty() { - return Err("encoding must have at least one chunk".to_string()); + if arg.chunk_ids.is_empty() && arg.last_chunk.is_none() { + return Err("encoding must have at least one chunk or contain last_chunk".to_string()); } let dependent_keys = self.dependent_keys(&arg.key); @@ -399,6 +400,9 @@ impl State { let chunk = self.chunks.remove(chunk_id).expect("chunk not found"); content_chunks.push(chunk.content); } + if let Some(encoding_content) = arg.last_chunk { + content_chunks.push(encoding_content.into()); + } let sha256: [u8; 32] = match arg.sha256 { Some(bytes) => bytes @@ -606,20 +610,7 @@ impl State { chunks: Vec, now: u64, ) -> Result, String> { - if let Some(max_chunks) = self.configuration.max_chunks { - if self.chunks.len() + chunks.len() > max_chunks as usize { - return Err("chunk limit exceeded".to_string()); - } - } - if let Some(max_bytes) = self.configuration.max_bytes { - let current_total_bytes = &self.batches.iter().fold(0, |acc, (_batch_id, batch)| { - acc + batch.chunk_content_total_size - }); - let new_bytes: usize = chunks.iter().map(|chunk| chunk.len()).sum(); - if current_total_bytes + new_bytes > max_bytes as usize { - return Err("byte limit exceeded".to_string()); - } - } + self.check_batch_limits(chunks.len(), chunks.iter().map(|chunk| chunk.len()).sum())?; let batch = self .batches .get_mut(&batch_id) @@ -651,7 +642,54 @@ impl State { Ok(chunk_ids) } + fn check_batch_limits(&self, chunks_added: usize, bytes_added: usize) -> Result<(), String> { + if let Some(max_chunks) = self.configuration.max_chunks { + if self.chunks.len() + chunks_added > max_chunks as usize { + return Err("chunk limit exceeded".to_string()); + } + } + if let Some(max_bytes) = self.configuration.max_bytes { + let current_total_bytes = &self.batches.iter().fold(0, |acc, (_batch_id, batch)| { + acc + batch.chunk_content_total_size + }); + if current_total_bytes + bytes_added > max_bytes as usize { + return Err("byte limit exceeded".to_string()); + } + } + Ok(()) + } + + /// Computes the data required to perform `self.check_batch_limits` against + /// the data carried in `last_chunk` fields. + fn compute_last_chunk_data(&self, arg: &CommitBatchArguments) -> (usize, usize) { + fold( + arg.operations.iter().map(|op| { + if let BatchOperation::SetAssetContent(SetAssetContentArguments { + last_chunk: Some(content), + // Chunks defined in `chunk_ids` are already accounted for and can be ignored here + .. + }) = op + { + Some(content.len()) + } else { + None + } + }), + (0, 0), + |(chunks_added, bytes_added), asset_len| { + if let Some(len) = asset_len { + (chunks_added + 1, bytes_added + len) + } else { + (chunks_added, bytes_added) + } + }, + ) + } + pub fn commit_batch(&mut self, arg: CommitBatchArguments, now: u64) -> Result<(), String> { + let (chunks_added, bytes_added) = self.compute_last_chunk_data(&arg); + self.check_batch_limits(chunks_added, bytes_added)?; + let batch_id = arg.batch_id; for op in arg.operations { match op { diff --git a/src/canisters/frontend/ic-certified-assets/src/tests.rs b/src/canisters/frontend/ic-certified-assets/src/tests.rs index 1bc56d1b0c..c2a3904c76 100644 --- a/src/canisters/frontend/ic-certified-assets/src/tests.rs +++ b/src/canisters/frontend/ic-certified-assets/src/tests.rs @@ -297,6 +297,7 @@ fn assemble_create_assets_and_set_contents_operations( key: asset.name.clone(), content_encoding: enc, chunk_ids, + last_chunk: None, sha256: None, } })); @@ -1994,6 +1995,7 @@ mod evidence_computation { key: "/a/b/c".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![chunk_1], + last_chunk: None, sha256: None, }; let cba = CommitBatchArguments { @@ -2059,6 +2061,7 @@ mod evidence_computation { key: "/a/b/c".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![chunk_1, chunk_2], + last_chunk: None, sha256: None, }; let cba = CommitBatchArguments { @@ -2135,6 +2138,7 @@ mod evidence_computation { key: "/a/b/c".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![], + last_chunk: None, sha256: None, }; let cba = CommitBatchArguments { @@ -2757,6 +2761,7 @@ mod evidence_computation { key: "/1".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![], + last_chunk: None, sha256: None, })], }) @@ -2778,6 +2783,7 @@ mod evidence_computation { key: "/2".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![], + last_chunk: None, sha256: None, })], }) @@ -2806,6 +2812,7 @@ mod evidence_computation { key: "/1".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![], + last_chunk: None, sha256: None, })], }) @@ -2827,6 +2834,7 @@ mod evidence_computation { key: "/1".to_string(), content_encoding: "gzip".to_string(), chunk_ids: vec![], + last_chunk: None, sha256: None, })], }) @@ -2867,6 +2875,7 @@ mod evidence_computation { key: "/1".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![chunk_1], + last_chunk: None, sha256: None, })], }) @@ -2897,6 +2906,7 @@ mod evidence_computation { key: "/1".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![chunk_2], + last_chunk: None, sha256: None, })], }) @@ -2948,6 +2958,7 @@ mod evidence_computation { key: "/1".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![chunk_1, chunk_2], + last_chunk: None, sha256: None, })], }) @@ -2989,6 +3000,7 @@ mod evidence_computation { key: "/1".to_string(), content_encoding: "identity".to_string(), chunk_ids: vec![chunk_1, chunk_2], + last_chunk: None, sha256: None, })], }) @@ -3020,6 +3032,7 @@ mod evidence_computation { operations: vec![SetAssetContent(SetAssetContentArguments { key: "/1".to_string(), content_encoding: "identity".to_string(), + last_chunk: None, chunk_ids: vec![], sha256: Some(sha256_1), })], @@ -3041,6 +3054,7 @@ mod evidence_computation { operations: vec![SetAssetContent(SetAssetContentArguments { key: "/1".to_string(), content_encoding: "identity".to_string(), + last_chunk: None, chunk_ids: vec![], sha256: Some(sha256_2), })], diff --git a/src/canisters/frontend/ic-certified-assets/src/types.rs b/src/canisters/frontend/ic-certified-assets/src/types.rs index 112b4f9322..a164dc12c5 100644 --- a/src/canisters/frontend/ic-certified-assets/src/types.rs +++ b/src/canisters/frontend/ic-certified-assets/src/types.rs @@ -39,6 +39,8 @@ pub struct SetAssetContentArguments { pub key: AssetKey, pub content_encoding: String, pub chunk_ids: Vec, + /// If set: appended as the final chunk. + pub last_chunk: Option, pub sha256: Option, } diff --git a/src/distributed/assetstorage.wasm.gz b/src/distributed/assetstorage.wasm.gz index 082ae64e9b10657148f2e3306208e83a26c350ee..7f2c64e536245cfd704781f33548ba29334b4e98 100755 GIT binary patch literal 399832 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

o?dfV&#Mlmh$C&weW|;e+IdXoDZ$wG? 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 z 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 n-9_M_)d<*G3VRtE9`z*txfPi3k%jktt2$ z!Dh!C7;foQG;4_A_{#VC+|R0YC@^4rD%ROc(i^u8b5_F zJ4#LbZ0Ib_B>&d=l<(!*oT~qr7J{3Z6}~E)6~sJKzafvf(a;dWY%3-6i$a$>pj8(# z-&B{%+t-Njq@&4$+f)w{DyEF8X1q3BK9bBKD)bxr)Q;2pJ`3n6A(FDL`0VC*SiYhO zO#2jWFxNQPOvEuKHs45CzHdes4x=LspFUpjG>`bKnDuveC4ng=EPp}X^-pPR#$P6H z&DfP>rGv-NQw&XJUr@Z7QVQtIQX6B%!$6~#oe0j~LCcbwzg7e^qOdnG`Dew0GoEV9 zpxYzX6ZAUQGu$uhO!<7_w3Ww1Z1Q^YY>{5MUy!Gu^dy7c6CRv;{=O2sm4A-hSryA_ zqkCyk3D!ufT~=7S&RbsoQI1zwpVD$J*J2bTMoO<_s0hhwN{vm|UpvKbt&g2cwb!8f zf#-c?I6cempo#oNsiSGz(WYn59Upyp%xc-;rQ!aj^#O&*hMbs!Bu~qN_Z9F@Gi_wfJi6eD9$vR+I%V~m#Rk0fBNN2K*VV9btL)m20?B$xhc1##}JW#>9 zAwUOAt0D)cg{NiOKisDhz1Kq%>UNR$b8#*+XvA^~Yv9>lc?{zfLc|!-2R+urg3~Xw zANAtJ2Xj`3U}AYTFU>j!klS(2Fq)Qo+5C{7LdQG>bp<-L^;nd76`GXsau2JyI7Aj( z6gZT5ojRxC1wQUjY06I#xF{I@zA>d0V*ic@DXp!^IApk61!&)wHbs8CIp2Wz&d+Aw zk`owXU_b|?!W<#4r6W4WILQb)H>^SnmfgZMQbZEO<9Vmx^{1w0JvfWyn_TY>54^G_ zf}pLFh#rHug&dl})(1o*r&aYaZoiUkZnueo z$S!t1YeJ#$7*=xh1r+|9<5%>je>-Y*De4V+>xJ*(0{#Lb%I^jo(7ZdMkPsm7EnJ?j znF^eol1Cs&T9-6IvfB5){Z}^m4W5mmg|*H6AXBXke%4l&hn`h>E`^ zV4Lwe0IxKBxy>068Y6NUX)~$a^lBaGE~__)a^=_tJnyeL7iMq^zG*d!pYeX0KizGp z>FYL_t>FWwoui4Y)qqD>e&iImcwc@=)CXKjCUW{he#(|zG4z9)I)s?gXH7dvXWqBT zO{uy)W~?jmOvmkuj}CvI48Jsw?dJHkLywlUJF}M2>hLki9Z4RTxm9lA8v#@?+FyCs z|H^HVDhS}D4f)3l;C%!yDhF;&dQ32g{n5!IgOItM^ZQ^fpOsq)_koC5HKDp%q$85^ zrH`@tc?&-lpq$mqm83glZ|5Ih=dX2D=8CX~CU6a=J2uYVa`S*q*`8Jr&Zpx`UIIO+2 z@Y!Xt4k@EAMO>JILF#TYZm0FM4NVxx)TW~I%(L0bBVcC8@wJqdc0PLWMf`HI9r_i4 zx*D-=*_0Da!!@TRwElSdX<0GHg9jaJ5wOA2+OB}GYuTG7roBJWX zVBHXO!VOY-1}i`FmAgT@wTM)q?$5U5Abi|T=__ZiXIfKN@T$(PlVx0cqKkpAe{XDB-GUN} zdsz6r^Pv^rWAIho7dmXH+!@0>V1;e!L$Q;fa>2@UjqcU4GZx~%GGwG2G2vq=ivSEo zh{xHH#V(>n%tFZT3@F$uGHH61~n1j zpeB@=_KovC9eDi)J%pJ@AZd<`h+C@8ErWPRP8CynadiN-uqWgD1jcfe=UCyHbB)E%27hboe@?TB<2b9 zcU@6}-MNM3a?temdwil)kQE{T-%HfcN&opl<*;>{}YUGN8XlIW$Q)3SQoB zD%s`-jCR)E@x`TQxiodFRAa_ER`6`qv)Y|Xc6D^Z7+ zNwm0z4}%q{fdCBEns~WvdrF%CU4!qSqO&bvcbEAe_8r9=|Hq$N<_3aZM-z*gm+X_7 zc1q%h5u~G!Bb9A-HjJ;R@Oc96loEvEANX*fEV#5aYpGXx$?<|zJw$HAK7-Zi!+K6s zDp2=d?5TSAt`xl)h+O0kFvtIxi+lQ(OmiKogsP&ixKW`>QtqkHT zj{G|*3g48cidR3>uuie+V;M=r#NQl5_B1BOPFSe8Pp%(xEp+TW51&6#P4U zYJaULci8=wI?>6LnEMj*W;|J+J$j7ijch_SVS)hhT2P5kD)?>hSI(sA60X32_3(NPx>l#WtlyD3O6_qy3U;Qt#mtcy;qnrt-C4H${%h&lPu8Sc zRo>Df?;VkLUHoq6jBCL>dm9ZumlzunzR<9VJJlsXg&Mh?l$^{ma`x!I8Keq9 z_B6#h1s8#6yYtHB^o%_oarzENG$}wO=X|CF?sOT z{vR+TLI%G0^y<|SAb5nhjr<(b8fV5N|F-0CE{aRp0(2{uUz=^JsJD5EO3S3UZ?sp~ z23i-%tbciB{wPr#=nu#oh%n(&a|Ejln5bbBZ}H3;R6hB#VO-wqTPKw^-!$v|p3t zu6X2*De{)Yj?o=yng_tFQH+jU>usCllA%}&ntjzp`Rx&u5z1iW{OV#DpmzU}z@q=& z6Xqwg=s1*4b^Wg~gZ286zietFQ*GxXMLqs`20`_{#B7(JrRK>|VJj1PebPm*A`B`K zv3>IQif(Cmi0tu>Bj+|@nEdaXj}sm`#k-Vc9rb;&dSXRr^gt=CKgbQu98&I1nd5{d zecFzG&OEyUj$IpNGcnN=De!jw->-<5!X{C-zNM+_0`@wyRiTYPuxgK|6 z{e8iBm>QA8b_=i~Ay&!~YZ;<|mPP|m~vUx(ICWXl< z@y!xxS(VaIwcDjrZ5RNws*}n-H76LnTZfm5SJV=iinaAByhnYZOK_FL_#I+;ag?Hx zpF;@V@9M>o@!??QMFl#ZZtd0SYmyTN&7BzUoihxRXI{uT64|4Qd7_+k#wdG`Ilj{R z;jUG0VmRUtr`a>nx8AA#D9*b(0ID7g0U0h5*^!O+q=kM*%Qy3JqF(J$cA9Q@^13YN zWLqJaN6E(JXqBv3=*;Wv?HZK6V(M4Wc7(A9Q3#V}`HEtBr)GHI-qvZ);0VtVnAXBL zvGM0fk}h8>^FxR4RCZ*c@&ONt3S=JXytlSG`KW!kv1!Y>x_~%UGrO{itl%1gG_7)< zLJN>tyw``gkr7-*}Avgl3ZW zNjG=#+vG~w{t}umxe4fs-|%mrWoEo7bVt(DeUj`)NXX6uZ2=`3UMopkX`s$slQCsO6*7oH|<4qLaDk> z{ZD#6n-4Kjj$p(lFgD6(>mBOpXIAwh_P3S?XLOO|;2+q?FC9MDBPy{o1IV%yGkK+y zzmAFCaRnTbdQtM~W+CVI$9$f@>t+lyKa|Mx#;G5w&hK*F+qC{B|JovOL_SryKYydO z{ngQ=w90zg?5_YO3;0Lh*yvT)s+0D})64IcNBcw%SRN8!^uHw>DjW!kEYv3$W=2w8 z==?b8DQt<}>ir!%G*`0@^)Vl8zgzzFnbXisHEaIGt<86TYz#aJ`fGMtmSy>S4K|xS z+HkYv9U5S@hK*KcHEeEZnh&U4!g3sV5a!&Y-d}fK)v5j#|JKJpPa|5Qte$njpE3KB z{oScgx+iz4lZis+ON23zInBJn#KpOovJ^~L+hYPi_H=xw3Bn-cN%BDAV+o%}_R}Vq zbV#-G6`fLt^jUKZK+j>&cL~D**Lw_~qpBw1_v%!L;iZWdzLDtA(|B?)87(~XbER`Y zd~LwbB|r78=3OHW%Coj;1ioU#{@?t0 z7nF&C_`V1&p-G3Zpu?8~m7X>a(%JafU$D374vgrxSB~n!dAHf=M?#PFn-$Y2J_^-K zehtVi_1JZAszCWo&<-^Kals&n0Iv}tiH!?R88B?#$(%G#u(?zly@EQ$@*jVEFD3~} z9Us+?rcnR7j5458|6{LbClTg$OrT|aniqcU zxW;*BSlCET9p02obatm-9HQ;XlV z?l5V_Jq|SvbptgkbUgk6V=>g%)11l#{)HE4MZF%f8)X~!fM1eWS+E!u{F~Et1hj zr^#uv3hxag4jBiFq#U-GLaoO1H}*Z05eQQ^UOi`ZmKAJAPainr)HIPzJ#$rz4EF9S zyfc2K$NqE7N-*YWh_Wi?1;T%?aaYU&)l%ZH5F?xVflQdwY-7ySO7F~(4L{%Dmp3E} zsR@C1P_*pf&!tEiRJvKG56Vm=_HM@ett1b;5@7p}vUq#!s zHx`|FFDH&YIRSG0_36({w#!IwACGEM=3%R3D;qHn?hOyk8^APx9)$G zH2fuQg?T5*Fmg$aEbxTX`GbjZZZQQ-k(Te{QqVD-PE4)v-vbe$Xz_`_kOSRB1t1cI zH=Jw^MtW#JSNjJ#&YXkPDgt&?yL?obXQzn)s_t$81QOByL!A zb^cW*{rXe$K-J1k)hrsKQNZ^HTyDPpC33uplS-u64iOm#iP^ako%(#ayyg*SI_Fwc z;;RbvMhC_68h1JJHl&+-lw2?Pwu*HzoRjXm3k20pA3S(}vdnV$Q;{Z9!JNHqfZ|83 z_qPb_!&8I;n=Gl&p1k<7weawH1|#A~Nr zmtH@|wP&TNF=V1Y=j>bI!W?eYe5(7f>KXgYVGs$B3-r$c5geng4?vV{gKgxC$ninJ zG)}t6yT3OGVEhcFD4`-_eX3cRmLHT_QR&%=$Kz}W8er$U6NN#T53d@@qlR)Et10bP zh8!jT6-3&%WY#SdAP*FBAy<87jIq{=#B2mg)x#=lUtDkL4%3idsQLiia?xu}mXTdmh$ zAg?D?T@e8+Uz6T&LKD8dCqQ9k)YW?MNC`5o{1;zaeXDgFK9ys%DWY~zeU}}4 z_)LpPqno?x2ceCrZkA#Eqz zQ_u|M6KRoGs|@fbl(@AJI-(iR$)~Zc#TWH%=#>9JwM~t}lvT3BXjJ!;I*W7VT-v1= z&#Jk|G;i@ryX6(TY|-uXZ(JiXYf!n`;@WftKB5^ErtHQAP?DT1jNo=b51ZTTrEr~0M$v)J7$r$qm5P|b2= zA)rs+pmgns(}k&K;o|O9dwR&t8y9;8Q|p7dBKrJ+6MMy$soF6!`aJ7A__gZTneU@I zo%z7-)epU-L!F*7I+dK*g7}wSdI2P)Z3NlwF_rM|Be31DDn{;Tz93DnN*~Pg3B3ZO z7f5n$S%zjjRHR4&3ySsUzfk{(=YDd9EAA{deRcTlBlwOHvN@_F5m@LkL`K-i48-0O zc`~2exmO1ZbbpbGfJZj z)-V<*GDK_aDh<|jsO5#-9Er_1F+9$(rQf6EGpVUcOgTC4P!E1GAyu$)t_8bWOgbDhSDOsa%VJn@xs|`G(pI$hFm?1DZ`SA!Lu&1ZDYYm7tCbrWK`M|o)-~W<5 zOX_-^<%q}^#6mEIY5@4#IZZ5XxAXI)eEZ==G)eq~PTatZ zSQ-j{>!tsk*(tUFh9Dq-|C)bCGB=&9snfF~ppTi=)1aX=ray$5<|hAY>4z#-hHis$ zGfzUc(VWNjB!M@b!?Vk@zn;NDR=97v;2w#7+UR3aT#)hKjiT(XJU$b!K!4o#NRcma zMJ)=wTE-1Y(1-ml&(RiIA{L0D0bK8nol3vMH^o#k;~Qq&^pBgsx>4U~k5ZHiMH4m8 zIhp2!*!@gzy&m%8{A!9;(rwN$r116w;US7IT2`_$5#7S1AwjgHEAo=%4o4s2PLdC+ z8{}5IKO3*JYrpLU7-HT|@Tb+NX{8%>PM+swCijhx>>fzfZ(bMR2o_SfV!+Gx<@-H* zttCBmkrQGSdfioQ!BCz}g04q?F9W-dkhuxMX88{pcm`Z&N{zjb66)BOU*w$V zW>#{ndyZ0}*P}|8dB*Ebyrg-L5wshC=IE_e{pFkJaw-_q0kOAx0?Ebj{y;;SMY`#E zgT;*=vU2c8*aI(X+=Ka>#v4pdgbz_=oJ9C-9*^iF0!TSw_=;Wf<|A3O5#DUQN+b$G zKmIuRc2<~WM6y=+>9563YUQf&@p%bHDOV$7BGmLp9lB9x(I(mv|vwup2~ad=}Jbnz-A2xdd%uxK{=u*uIsu3`XsL%G;6kZ?<% zTvId8aDR}~Dr4OSjkhQ}_7UuKZfiO@VrDU`Y5gQfvOq6Q7+7bJDkt}Mj=i#>mnYLd?;>0{_zU)%t~Px<{XYy z1zv@G9%4gZSs`|_;AV`%H5^zAKnz6?lMbWYb5?tOj@02+w;zbhvS8-;ITewd$yZpW zm$`M8ru%m%SNHAv8_4(w14j^47jB2eTv`o}`Muz6w$$}{sd1#Vv)m3c*yZ_A8D@%B zC+|9Xgl6Hcia@B4{B4XUJ@D^EPcskaa8#bNs?pTNn33Tu!=Q1kc%yocY z^dVe0>&qi!WvEg8qnwp`Gk1e>MTS&tt%n%>=RaMYV@tsoGNe?m%#C`bNVZ^LrK5V} zMA=vPZ)>eaMEau(HP+>Fa*~3b$e0+O2BDSgs$q|xK~!Wa7K|DejA|BD1(^}8dnkVkNsnnnY4CPEJc@0?P8GG-B{(_7YdbTI89?MX z2cC2p#edr1etRpwM`osxs(g=D*d(l3Tk;?hdb9|hJ^u}TGM2c*Xk4O{nq#bs9_Fey z{QXO~ui7N8Q%)#{(4p2Ou2N3;M{V$E2??NhiIQd$Ze-ph&R`Q>krtVQ6^Q6vCo_au z*Kkw6@{bAzE$b43s-RjbpMK>KGt&H4!7Z9*_bVp?X)_x9{XLM%6j**0So zSFynbD>c{IvwMBD!JQ`X)GW$U{{GRBwat^$KVx33)MuA4S*4@myP~eO8DNp|F>oOs z_B-P-b;Ik!ohL~t<>e}jiVUGG=?+RqC6=YqiM0Rw0SIZw>(h^m9FGjY`vC!E#P)js z*5jSsMqM~i`|-k*u;YhrG3~I68>dg(dR#_p@b=q_7CUN%s6aT$6@RH6wQqd7$ub5) z+L6v1&%@c0n8DqigGeBui_H(j`SCT&!d^(nRr_uu`#3F&%^vK9C5e0k-@7wl}SiyP6)fQBKq&Nq{jt2Z$+@HH&zz>G)XB-`biyH`k)#4=-tufHL3G zlqW)5Jl^Tt0R?bui}~W>zKQ*N8LA;lbuFT)3hL`tD9{!65NU)my|&unF{@7o9ScYqt{!Xm@a3dW_Jr8 z^Hl1iin~0N`3?)T<&iTlBk;{YSd){g<_DW2pC=5mS{LnXz?exC3i`7Fws`r<;FYLiwJhu!2M(Nyu`RU;Fk07AFD3Z7E0#>zJqz|!q&~4rFe9Pd{ z)4fVsdZX70zn=Gh7xSms?qYP#U`o!AE&p<4(fCLe8p-WGni%|Fd1(|y3&+!RK57honBOb$;(#7(WR(*O~lH<;p?*PF@}?ZxmYaDDeGKQ zV}5yM5ayRWs~m?XshJ!!i?SFfgHArQqsk4D;xN%{+e`F;k;3y;*>%&39X<3$B)HU2 z1a*xW3Qu@)QW|IWN3i(7BKr|X)zO{~IXqUA3&o2|fdO@mOBG;oSzENlrF=QnAPQyv zB8r9WZjcV9zGPcBtn`SYk z2BNS6)}SY|Hkj|^@>ddoG@9$?{@bEcP?ITX@V!FW_}L6 z7dl3M5Bh6n9QM1FXM8+7ceH??_JcV$&{9GG!x6+j3#9onS?3*M*e{s8#a*)T@GAJ8h@2%c(YuC#p99`*3 z*i!Q=9dT3DQN3D?OY7g~CA>^&fp7E*L!H0RQ8Y$fVtL-Qqe}d{R^S@XYq^&UpI@a0 z1+pjYY^Gn17;uV@Ow_I0Jpb6VsmMQU&6Y$S?JG?KN!A#Q+B0sIahLYWhfhLne6bca z0KLS6EUFyi+3K5mQxX7OMU2SpicA_Me)J)+DTzc41ytsjhC=*kNo(+ukDUG_K_=b2 z5sCAAnyN8J=*;O~Cxb^O=&CXmw815_f7=}xG!W1hN355n#nH`UQDZgn$P4FjSPeO) zvWZM%cr@9ivT0&b;ca4gFm5`aRS$Om)O~DT5hG+byZ7OdALrCBf49=HsHNZQsIE4v zRAUb7ezr~7Of+j@-69UaH->e;Gv2I*MaosBy<8P>=D21--#07=X^{Fh;rrm!6wZX> z^g6IOf>(*VpZ6CJ5cu(@`}hQPC)gdWQ4D)3!_OV`ID=d^DffMVF(x4@2tAu#u^yaR`gIBfr?%}NTZqrqZ(V}f?cHlw#cszb;Zvt2E_aF~m2KnmsI`1#0 z-41k_<>=T;V%U>W|6oe`L6|2lBtpE`4Xhk56kPs-^@?K_LC=_r#t@l;`c2k=zGkcn zDE-I^|HVtFv7B4iVlu;{zRr$i14IDR-O2^fH~|sD@*I%765Rt-u0j{){kMsO_-7<{ zmA1gIR?&7q*){YoG}Y+s`mn$H4!RRsy$s7karqanxjD(^P{<0#?JkH_Ev}azK$NoV zgHH0Nx_-R%%0ta_lO0RsZJ~W(KT^pJwNPPMW^us*0E=5v?w)3Nmkh9oB~%ox*RJ_Z zn(6n(K=tmJ4PA5J0za|IA6{Jye)0Dj9M6gpk8?>x4Z03n>u9>+IdG}9O_H8J>$ld) z%s8g8>hhamiV@}QQSXs zdzxZfK(o?+doAHfjfSa0!ODzkR!x9NlKY=44x+hFunoond9OO#0d zFkp!iL9L8zOqF(*g0T0C@M;wtq(>Lk3&3uCOtd=3cNa^fImgb`SH06mu)g7^? z*)eu5z^AJe_sMqGq6rtyg^OU^ueW(ojllWsK=mRstR9DkZvF+P;K8r>3YQY%*Ckj$ zko$L1aIJpH?~q2?&qqSLOOQfCNY}x~)6v(5OV?ITgNF>oG@t?L#d zVH%0AHBM|f1~-(1IZh`vo#duHl(dAyYSz}3c&3CSA*oI=fBJj>muE)?ZqXbd1qW7x zV6D7t5M}m-xbO1@U%#iQ43nZ5Y|5L5xQx^m{y%WgRMy{ehbI_wo>Gl>0yiPw&VX4PG{T?rw;x{fb-AHnMkqoEWyX~ z=;s`~irpN_!oI%vA5pozT^qHRS{z~RC1uLSp2*qHk}%*~nHj6KmiQYY_0(O3EKQ8S z%VI*qGoGTN8C1?*{yEvl9W5cuQGLPPo_~re}93zDnGFw2{D`_)kT|l`?Pp&QGTHJax&rk>(@9*HXMKWf0}P zp2g8boTo5LXu-7?v@PZrB5$-U$BRwGtYUpv;qPm>6-uzYlK^$F|Kc;h+adC)fX9=N zH!G5~#&Ofxx1xea<}&xOE}S+0Y#e*F;vRQ(;{JbCq3TxsqPM1;qPMpHZ|xc}zSaN1 zjfKtMCCuhAWi3z%9;U$gP!|_z|P7dc9+(My3fH0*rme*BYB{NWs zIRyM#JZ4SQHEZZMo3|mt29JlGWr?ie&K{wpMGpzhMhtzTvjiAsjuy-Fa~#q{HGcPo zI1tNb-?HbJ_Aqog>{2*%XcOf_xIH>HZ9))S18J)5Jk-~&axm3fag_G@<47H%(KWm0 zF_>aCFCW-`MbEjy)@{tkCSowT%Ol5_iH%)c18{;Mn7LF2LwF2i?ejB?)$t{Ik=PkN z_qwv(hU|*m^pZC6EgLF*3p{?Y0hv2rv2}-m-H~KX8t<6HJSfBbD8oE|Q>b6tqZfs! zGc`+*_b!I{;uj^(Dhz>+jWQp@^d8A| z$<*G+*hA^qpUKHMuY+%(B@{o!46l{T9)_SyU?N-&|ch)R8L`Zpr ztgL8M_SsOJ8bQLYe`zJ>f2of+%D;qVCld@n?&zkP?O8Jmf+u?FT-0)Mavt}qz@Jsh zo~gssKC_?^J|$u^Lgir}{Lbi#=Vi8|e&5jO0tNeh&egcH85I#$UK+!~A^>Ldx({^u} zwFQhMj3C*n%SRn@T!+Y>^|^s-6iY^jc3BV$Avwf& znHJYT+{x(4;?1BfC6`vLI9R=>Wu5Qaklnjj#V|Ph8m7X|*!XP=Ptme)YrLb>XHjRr zCPVC^AmuRmiRor@q0muiM zrnLX;AF_HY!UifziV_u73t0_lz1S!XIPa+DTlPOlru-2M_x$b{T8^hYY6oW_Vn|5P zK8=24$%Kf_`;YSWeka9f^3-H8lULC^_RXJh97yL$lsoEm;6Od3q;v6|?mxGQVc z$}?7uz~LQyNv`uxIwiJzNtclPb<&OAaox!42IIUU|Nj1iCd^L{k8hWQS6yv-Hh&Xo zU-q^9Z!E7Zu@(8dL>m;l26}gzeQHV;)Dw>wWeQ?nCf8pQiZZ2W=G6~GRw}?)rqjZM z(=K`=IsF8*mv_fg&I5JUqeYNbi_aH!K0_;ELt-`F`|idb5uGZ%YSYNVPlSZPAOBd| zw%)=YEKQc*pdU)TI-Wd84V=T{=QT%>9Zab#4piPo8%{dTP_4M8y?4XJgRT&rz>>ra z3|NCsB7>X}6*=tYclKSa5(Q8wkfXo@o?)f#dP#Xpbyn}C^HeBGlXZO^(T$_1C~#x` z_@pJ8N~j$qwEfA4f;vt*6EF-T7)~;z|L1Xkaa7ESTBo%&8ZCw%=q&RbhoZyNVnp&A z;SVEtMYJ)tf1_#WsumcA4Xq0J+wG0ZBl%zh-v>Kk!&u zq;p6SjC+Ba`+EUv0E#jG(eg zx4J!=)qd6avsvv}3ywCcJ#*Yz@Tm34wOb|ok+O>WhEi`5aK6t9OzTVOS12P__~9*( zm)@mn_tSy;S|gd8N?$q|Nm2=zY!gOs8j_p?^0-iUG#)`t{Ly#>Ic4`Duc2=|KeeM9 z`1Mud@eNFUop^+UR(+*-jDv98S|t_(22p*nggQ3rtF=+fZ8n$S!5|s8UWy6js?mCJ z^6%rNI)Q%OY2U-RZ?iuz-kWRV-GK38oaO5npnDwybFX7SH`fNVK?ZbbWIzsq7Cfu3 z;3Olw9_);)1?qq0Z?pBV;^A$T&_$H4}hs zqSr&IA9{AWjvNtA*zSosFGI=J&p+Dk2P-G$zG-jdJKIAf{v zLX+4kZ`?0`Zl*s6KZ_a65cOr>cH~6V`UWkqdJwKr?;~dJ60wPp5iy4BbHvp1sKMkK z%hcg93~!wq>*&CJ`Ela2a@xhk|147g3%SA+R4`vUgJW-K2FyxvrX^nE7-M~i{+#As z@fjOft^M2HrDybE92C4OhQe6~1y<<9#cRJKJnyQZU<3;C-c>@u*8JgAV)tqR1x%{z zdxoX31vx$tcWd`Hw@piQZLKYn*x_26Mh-i=AR*QF*WguxsJ!~?@S}C(&jl=Z3%KqQ zuxt`oY?MDU0+K2yElA7=NKk8jny>O9*1+U45P}HN9MF?*z`So$?@*pXh9;BcbRqB-Z2#KbKtL=b)HCQEL{;M==&R z%Fpcm+?8Oh$4*Lgx)xHONaL}a=@;6jjT1Q=6N;VtqDG|;N20FT`HtgzDUH@l5fZ+gXS8w(VTDq*43>sJ)Y-fx)v@gFev_27ub&@I$XW%__)7@zldy z_9`jb&&b2U$io31ru&o66mxSIyzNiZXy)dQd-t+uTS!maII>3ZlkvTrw-fhiYmtkph-8z+z<(44D@FmPPLMVcw^zilKoQtdFx;}r` z;aZ|D0v$e@%18!5KvjUAlO6D1}VaZnCPN#mp>*#_AWj+0=A*0?3M5)+5SxK?bO z(1e)px$ozF-M=3i z(ZratF{VugCXkHbDNOOCz*DT61P|mc9=T(+(PImxH&&ENg$ewuQ!s_$Lnpne$zll~ zCHofoMENlq&E#x>0@BOG$WmpulA!T&Ae#Chu!WhLt)x81gMIx}gXNHv4l!a$M3bOD z86P-wnN+(BIxattE<>cT#B`ZJ>nWz)A-hb>Lf)bR(V+#>lCZ>fnShbmWkB+XE|YR> zjYifk6SumIEq+)fWVP11%a*IVOzSSom)4s+_?;hwI~V9T3HUik_SM1e9*hR--?@9q zBcGI+Kw(9(%0EdIB{U&gXa@7d^b$(U68ZuaO}{zp>%=FO2Q2$nNDD+5Rv&ghfL1;r zeeTG+Kk6C$E3_I!<#3DHGe_bqK%C(gE|~i$%S`tuSZn>qsPd!s?Zk|mEAabBc&pqz zCNs_9V~-u$eGAA~6V*9sNy^Ve^$#Yt506htES-%9U6H@9>cK**M@dZAu&H@Y@(Y1* zUZ1{e(JTL=&=4>w)gN&obQ6vogFI4i7Iioc%OUW+(?RO+KgPU#c@%^K-BTbi%Wwws zG!Lw|uz`o3SnBNlCuRRtDpa?Ml^DY_lwmQXSRX|kU*bqWL~$@pd3B;C;x7G`v3oO& z!NmmGUsk^u?&+-nsLBp6)jRdwouD`JUzYZ|y}Y^iqqvv!Wa=!WEBb}kgL7$5Jxpx@ zXH5Y=dfH@Of{G2O{P>#QI`lyzuKqU@NU@7;!&M;cr^DxLSe@M1IYf+6h`>U6B&DF)) zCHXJNfU+e2GewVrHSPRN&@++XkHmKC&A5)ERn#Y>K@)N<%UKe%8UgNo5^M_K1 z^xU6WJ?S%xPc)CE!++W%;Ejotnn<62(lu>btUC9XR!#cSlTS8}O@W?Ed!>svZQ_06 zN!OoKY5jA4teo_*Uwxu^tP)qR{5dTSkS=@E+Fv&77#PpOW9_%?!zo)CzvuFo6w~L< z-?S;M+#U6MQ{xk3Xqwbb*u7M zxp?K$!ezz8X8bS;7LGLIXM%P!N}Q936SyXH&x)mEsQ?X;eV&g#%Zn*H6Q<>FhBCz# zP2A4Xv^w&9LXMl!SQsTbJ>1=l+8SM*qT96A1AY%Q78Az9ogZ&?QQ51sKGw`~sZq4h z2xVf7*v7#AKQy$Ww5!uQg3oARFj5h|iDGoYX0e05x8(6{vTA^&2EM8_{j7<9ovTGzw-g_bIg}TAeN(xWYj0dimG9b`P9RB-o;d?O7I37yus;I5xmLO*`h0%3$paTNkiw*oo{SZo5IzumE2 zHu4b;{bAKnt2V`{X&_fuXv=tVTgI*}W40x_EMW&cY<|s&=aBN$S~B%3xGOzI_jWbG zH}anH#Y{0IvxY5rg@~Yu~abB+@R6g1CbSM&U(ynw7^hbF4XIO#lzVws6VM}l! zAFx=`t~UkjO+SL}gtHQ6qho~VG9!q2EFbZKm4~m%g!fv9;zi>_QIfFY=OyD1;gbd; z!Y7SHgs(6Zck58R(hR;H**+AvWY#fv={Shm!=oK+hezbPD*z+3)%;uF+G%R*=TMuG zf`#2==U8bcW5CEW={MI}xfVxT3RbvdjfG%Dcu&qmsMJ8(M60Ik7iKBEV^{91dis?$I&5d&Uwwx&C zqEDNjT1IVs?8{GhK4|_MZ@~OyJX`uQ@#@0;&2-jbCtPZ50n0w<`R+C|_Bo7cC>#`(oykU=8 z_*@G^Io7-1uJ_2+JNx2T#fPrWGa2T~R=7V>;n7Hiqt;xVhg#=80iu`GxuRLMDw#PP ztLU&bO0riOpXp=5458eSGVJK*mO_cB(ZI~qga?+wnZ#LQcs_V?5F0fp3p0WUS zG=FK+s_oEZd?jlOl@)11YVoTqLzLSn^TG8xakSrVcSIaeWM-DWNT!r+G@O%_>CI|4 zxZdP@yO6i^bn#(duW9JYm@UcG%MWhjes0(}TU@NNs~^)hMBf zId;+Zuu>`qMVb1g)WE9E!{T>7xV`*x*UmSk6)0tVJ~Qym9GofERKZbeXq!qi&C>8R zbcUyqUiqN)9|_RNGR1~hfkSO$#&^pg+e-tlm2zQJPTDVftp_SY^i@Mg)!z( z!^*R|54)M=z(m5reE^4H-x>Cir((00|5-2Sj4yqQD=d8kRdfqqd*{6Z{bB0)_%HC6 z&P#vg_X5M^c)R0rB&WtAEez_HX=h~U9B)uMM?>Ivy<;E5&t*;ZTx(uO2dV!aj?qfg z!^YbZ+^qFo86Kk+8zb6arpWVFCA110EnTPo%3rchONrRHaxVvj@-Iv;;XGQbyi!+g zq2A;c>T+zMM)us9!*|Z1t@ZjQ9k(~?-P>$g&gj-7o?EUOYZJf0R-PQu4Y{If~`#WtCB*fzg-Dt?ukZ4?GZUH%~>1Mi6 zho0*kRTt0}xdv?<%KYr(Y9LD!V)Ewix7L1EG2-8>Yt1Uo>Hg~4?P@)E)S>W(9On55 zp7ms!Nl0tkU|VhpF1MzhI^BPAbm^b5Z*ZGXns)wlXyz=e?jx-@GhuZ%-8*&hu(~&c z-8HeSRbS{N8hnM58c!!yznAGEx2mZ8PkP#K|du)~ct12jxZenQzHTgz_Y9pS=gRh?K7%Zp)evdF7*1UGzEA|KoiAfV zU&dHYuhyS2RDp?eh6>?b6OTGW#mYSq5ZY1hq$3+YD>|id;)Z_{J+b=h;M_zFai+c~ zQMGP+SZYMCd@=!b@64cEWf);OzE=$ES5#yKJyLIMAr3)7GaO7^ZIp6T&XX%P_#vA4 zu3Xy8cSkZmy%Sag(^Z$5@0Umfj)PSw=T-%UsKfnq3tY_^6;Mg?b8vrujfBA@Xtk85 ztOCrW@w^^RhJzWo+J7;fn4;leZM7CpW>lzW!n0O*)(S6NN;A4q*l$Tdj(y=$duwsko=p%NRq^2n^-SEL8pz29qIrTF@>~xc)JU3S$2{&EI0ev z^moa|Z9O{&@xml)IN(cg1OVRkNBZmYYW>11{y&vIz5WEG5QL(em7k7+WhOGwT32WF zgHZwfoa|$1!g<(okta|W%{XlBf%f^NR>*~>&&S&5X-OE5SP>@lS5B%KxdXtuOp*nU z3DM9@jdfc7r1F|WHHNJ;r^-luq(hyi4j;OuuP#Oe`9WR+0*PP~Tz<*uh9LE)S0B`- z3VT0<1je%oO`&C{m7g~^OvaYwYFcX>ZdL$12CZ*odH9YOjQ@+r>ri(&+6(8_?f9TZKo0I06%jC*2C3C zC;8h@<>qR(>Y1zc)wH=R+bPz5xY4vzq_v-EbCud$tF*aR zYjds9=JK?;+O5-dt&_XfDO~IHT`+#>fBdXCl(VHnIa95x3}!+ww#RW-E7vx?8NIgE3vCkH;5}_E+tyRskalQJ zYa6efJW|)SM(X<3NS$qs)D5kXy0JA<=O&F*d&(=d=~rpfuhyntqfI}fO}}BV~7jeghOlX-Z@=_okRW|{y{y?OdwZtfDG!29@YOqkMz=616Ywm-3lvWUsW7_ zg&2c)4#&DG-q+`12P4wYdqm&ILLMz~2}pKQVXF?@*hUm;*Pew9yPNdOy@0AiVqHS7 zO8b3YZhqRBss5p_=Em-8)*z?ybmL)Ynlk9xu?`p9deWvh+hv)6qVm64TVCaK;+TmH zh#u*}OT#c;<_3h7dq#Te7K#rdTLlm?oIGXCT$>E2=?y)l+kv#@iF5sO1_KP422_X~ zedO}}AN*IHYu?+v?58gG_}}sG{iz=x^vuoKUw>QAGcqFV@N97X|8c>Di0%EXs`G>9 zbQ-izr~T%T7f5s*EM&_vnD)_;si9=LX4c&KYvh!0Z}b z!&Gs$$YEo2^p{DA@iG8%u-Cz}im0e{v44;g=pv}QH?g&cyr{__W3GeNb;xU?Cq+Zz zM!D8?qqeqh_n5q4s9B!y?Ncc$S~8f|o`;7;pY3Yao=ao9t)7{!5sUk`H$Q!Chg+D1kBC5wa&juke_=c#z7 zE(tu#N8D%|uoW7B(DRc*VP`0j9n~HXNHy$cb{Tl&`4%o!3EVD?v{5C-Cb>3c*THN-*ND+5eVB&JjiWQ*xC!K3l{u)Mk4G5 zc-?HZ9-E%^LjvAan|?sHHInYZYLg@&+bY@nOPyRu%-GqXWMH4v|4oApI2@`ioMCY* zpYCbbo~rop;Lvh9OD1M8r0A8)B*Xgb9n{I77ZG_NDE|rS8V}c0tIPLswp;NHzx*fY zMTk?MB?TH}7i+7Mh)N?3IS8dG**T`E6B}zV)-IYTa7`4PXA=czBFtoKUsD6|%hEvK zFNHminjdUH-A}4{-4{qjPi|&x5!Z6di)O~2FR=BbecUtEEN#b6OsZ`Pqfl?M7Ll3f zk0O~d3UyYWf-z1m`|hbBg&3O=MsL$ft~QOqB7=%L2lpGBue>Y5Sh^o3!b}-=5BP)G z^8Gn3@AU_3@q5f4tiwo@YMzx}3T1LER}T=}vizMcV%?`gcw8Q3iqa?6RoK7d-NB6J zZLMaEwA8$tmCBoKpuvisCrz_ftwkKQQ-~1gv^X{;S2L`{nf_Xg9Xma=`WO7tVxC+L-A_5-wGXYcBBIq=NS63%3$nI?tX#v zt!9=%_nU2vb8lqEz^1yaW?9Fh)oU6JU3GTSj8JvUe_~%{xBAfzX9U)=eLc62+MDAX zMiOWmXe<3(@7GY1lN+3n2YPCaZg997CkRCseD8wr!uuM2bj#b36IJj zkxx=U?HLRO(-5tm;;WpUU%SYC?V?;8u=2_WW7i6@SU7#PHrC-*h_>lV&KMY-$-8;G zx5H-Jn4br4^sZAkCb~BGU<102n^aZUP&u?sO}D^vKbn&r@ThI|xq-#EkJ`O%khsun z*o=|PNe4A+-iV7utG);cy$wH-H|cDq&zYH9}$7I%U!p#6<{mP=1nUtU_Byh^!2%DX@=NJgVAiUod%aP~CyQWegg}VIk4PFe9~4cX4+;rY$ypzy#D%s|v+Lnb<1ekD9H=z=gPJr`k6R3!@kT1ARi zoS`DXCK69#6In_al#(zgIv0&dq;k*+gh6OqB@9aCz_#JGL054}+Qc(mWfzHTX(LA% zl&imdj*&-*xLgT?7(l|H9E3q#4Ip7qu7p7hAYo9Xg4ak1gCcwl+6xi}60*s zkt2l1Hk^b(4380>*l-dCF+4$dYQsqw#PHM*?y%g^Qo^0+JP3CrFCzpy(I~-AXbE-* z`p{9Nmz_p=PJF2y2Z(f05C!}>qXOv)vqh4W>BPH00 zlwc=XfnbM<2N;6cuGtw5I8rzqrdK4?iIxn3{Co*@@=-#a)=0>g83~q9Cx^^`+7aqR zhEOMO2z7GT<)xF@v2IjVC91z1CC|w%c}_S=o+B+E4eNiY&;QqyqpR><;4!$QYV@RS>tkR=}76PI>VagAPDP5ZIZ6NtEKxK=BMYrp;z% zaz2{P)MPVUDVtZ1WHa5zw8pcUjb<|)%Vu`2Y#MR_o^Iveo~^$^50!4|5tOCWL~oK%76B1@=y5) zFkrJibNkc~qsj?+PhK+%d!M6k6tw|1m0QWRjfDDg-6Kc$h%sNk=I)_f0nA)MWf;r` z5>3#=XJlXd(joRGlte0~n{!S)_QImkHILp&cdyTWY0+?HKm~Ca&wfg^(vjZr85Y9h z?mcj9JmT(Fde%dQ&%yq&$~E)dZDuwo0iDpF`({`nwZS0aznWUJp@#_pu7QjfI$unXcq{Yg8n8b#mZA1DK;$x z<)Bd?{Y7gTK>!|FO!`w0(BWJ|BP*ybL1q9|OK494tB||>{nf@|PeNb>dB^_# z%!1U_$-x^Is(S_(yrX|%D|Mt?Wsu3cB2HPWVIN-q)2g3^jpJ~zPO*Mtl5GrSaYR8X zz)fMc?VPN7ClB`f(q`*n?rF|$_y3~RF&~m5KIDqnI|)<9&dDQ#e$}tuaCk7N-f+h| z`u%EfqQ4%)y1#&8O#f5K%!P7O-E*+24)!aVR;ucPgM+GCf3n(i$NwRjT#sg3k5mp0 z`cCV}z0O+Xeytj9u7#cr(rX&wPFJ(T{su{;Uzw7xQIZRORf^&DH>$dRqYbJ`Si6!z zB9^bkj^3iG?sx}*J8zH-e2+EJokOmVR&#BlizP7;1$HplOvQFDx2oC*OQVex>aOMy zYXgD~3}Q@WeM5O6-D!n1F$Vi5WQN7WuT>YXuyxo-8}KEm514sP6(zu9 zlu2XEX_+RLWM<_e03lOyH{@63dPqKp9O|3(3f?`1jadl=Ygw&R<>Xpeb>JW%4O)K$ zJqfPgs``y;uYT!K)46DTTA8jRxd2cRC7E>APXIWk*cXHsi!=dEXa}} zb7pK^0b;q`Xtc%1!$vZ4v`mXTbXy?hm#3*xfUwb`Z8K}WZunC(2hk?P&K{Dflm%?hxfu_9zf>79XLL?#6kIoD!Ps)~86)8B}FofgOP zjL0fMy(%7NTI5VGu>fpT6?i_veM!+j>Ct9}Rxm72zz1@F&jQswWvzDK=-mXUTA26T zL~lPxEL!FVD*@Wrjl6Xfq#znNx^ekXpzP?^s^RigD)aNP9$lp`5%a0O6NiWI8n@bYy%lg|VQNWSsnmCZ~{;7>dvk|gkTPA>ezI|iK-RR^RCb3{_CGTDyT zi$A@Hy-1Odr5R(Hv1tyn`ZP=pm}ERRNLp_u28nHX^f`ld#2{|Dl}7cf z6#Nal=ce8egi)NNS*M#9y{YMP!z$nRS8rT1vv!@oe%3d#@2!>riP^GPB%Tt)c*Xys zumKC6^T6FIKM(%J$>i2_UpjUqofOQyGPeW10tIr0-g?jacptwMu1*KV>fCv_9{ul+d*#u9{uR7b`I&KXoNaq18z;Jq&&$trb*v>TmNtV=(zm0u;rW$T z^0SYn<;%ts+|Fa=T^&;k>`*%uI%2E(S?FXd+cE7&N~ET9qnQ}w)!o>p?*e2jccCVI zp$(d*LQ9f`hZc-J`W-tH!A}DlaTJ)_y ziCRHSkpvSHeu%MJ(UJSGZ-$sGHQ(r{>my;W21)rfU)M2ZGBY5kE39KxX4bE3%?`}I zQW=!<2dqT;yEapP?`3VSmIOUmZLf2&~Yses0sY zIqa)~Zz;p22$cw}jWBlCYR{)Is$Oo#M}U&QBGA&wEBH$UDyY z$9=2g4%>d%$NjdCs|6QeaMrlKW<)6f0vk5PQs^5s=f{2cerm1ZWdaRg+~TB%O!bZF zH+&4y`s)6PA#vQ7EuX<1f{Q)6?&-r%SS$hwx}g;$`@DKJ9qlA+bqkLmRXhUtr+P0O zek;8u=x_BV@8!d9y@a=bC)nb>s80c~ZUC|7g9rVAxd$eRD@GkSXaJW@%pI5b$9xxU zn{Csed@@yhsN+bEq-epLB&u>5@-u9$%`V@b;tE8X?{CR)uH^x#I3E z<-qNzI{8ihgTB_ZRtIh8-{gPDSJ04$Ai$L0hk>*oja6)b1u!ljiGb70W5_n?uNN7` zq+9~|S zQm*B7c>vJiuY~(=QHBA7pC==EV8$3OLo*mUs;DpR=4FS$w3cwR-n!RU*N!~Xt9KP>f#Rv-LDw5;Ohs9k*W0sD9O%L5XGU{ zL_X-ZHZ&OEc1KhA=ZcZr`g$#yQfv`ss$JRAuE%>AAnm|`+Cyu1#F8e9ZTVZ>2`~B+ zQsZPp6Ran?L3}8YTIOQ_GZldc54JWW1kp9+l~eTnmYH(U5+jBE&&J23n^+HKHZSbf=e_1OcjRAPM7Ks^J=8URI;zo1gz6xOQXKgLo~rTYNK zvR`dHpaBV-mWeOOw6H)AAi|m++&}Q?i;!ut;l8(D)|c5^PTs=`eY39Xdh46pjJLc# ziPA%{&}9WO|J9JVKnI6Fs{~a6C=BYeUwm9eYG8S(&$zpeN;JX)w1Ci5>mB=7J+*2)nb z=mvi&IHWqUj0-n*!7ds~*oiywu>P0BsjlZ2Mgme$5X;qv&hPrWOPK{CTK*ZQcxM7x zzAu*@2VLCtVe@j_KH_5NfG1B_aU#Mz&|poIG>~9MLKuspwk91mstF zw`g659dn^<+S%@2Y-_zVop#1_*3$g)zWkj8kZ7KI9MODPpKdb0m5C)?J6^UOqe<-; zO=`z?wc62?*aOT0q5~gVpN$n5wtvRHKQ&`6LSSYBGdEBbpC&aqBpH*oteW#>q@L3D zq(sPYP0`p+>#*|Bp3(${*=163gGt2=CKdPIjyCV?ATniEd&UqeKl?6U9PPVJzfHB@ zPRM<%v^4CEk@iNrRw}wadtizAhnwGQNR)Q@QJ=O+(`z(Ic6@~a|A`gyYcqGZ`|}^| z`59*I!wv}XS&w~tGh8uvusxUH`g$w4_Enw(K8Da95^iXn5uWvy%0YskK_YRJ?!xlB+Zf3Qu|iv8a6Diz?_!f9f^-&&N9J<$ zbSp>KuAHN%S~=PaYM$|m1a(EA9hlskjTWeRZXoqi&E0I1yV*h5^Q~(8n6$H+B`^KP z)JXZ}n-u2TDSXnUz+>?yNNY{$T)*`Vq^le@%X^uz8+25fjv9?OgO1XPFxE4BU~yH2 z2kLhoe%#xyQor-4NAvl=0%ZPIGX>Xt-gBs@0ef2g*q=Ub5Is8<>GWx+Uf#ybMT_cr z+9K38n5PhTPzkYDMaaGpAzw)pWg_*?2U~4_NNsu3k^WE(UAL~#i6X_FUZGoCTxK_z zcIaTb^i>Te2*d1$w<(k-5q`h<@st^x515sz(Mi);t=zT?9%p?k)auX)c49=AlawqX zhO2O|>26_pj}iP`uQOnK$_pJB?&!?Noh9O3-*QoTw&fipm2A8F*|WC0^NqJDt97VK z-N=xln7Gfnq2Vpub=drONNMP8oEMtmWBVt@En2oo=x{3%2i0pTWpJ)i`b#pJt1Nso z71A%}L2@XfQ+8mNrge*~Nry6_M##vp>uTHm8sW%I@b&4y(S z(60%@9?&@LRla??DB=4C#Bo$1eYM~pWL04wRaP9k$YP8=(G5e%*Jb+~Oj+Pd-e_V( z_2waqu(SZ7D?m7*0O5oJgcAx7un6+OBAQT!=-g$9mX^U3K_&XyY(F#FY(H;rcTnE` zkuOr-9@H~h@-=A15uO>lH6O(FKiFeIF(Spvl!loZTCNKO*IP9gvNE(XEWtRE#P!yF zpzz!eaRHb&iLMY!fp_W8O0pu@RC9Z50pizt#e~agt=sS4VWJ zf8g%k+dTN;(Ks1E!OSqGL)I%^dmKlj>qIoVibSJp46&Z?0;r3bCc>L}ZI%?delsAk z4J4MV5+)Dj(1m@}vw^cs;FB(}Y63sy0_U5+&oc11--MiD$O-408tIG_>4HZeGa1xd zB%BjgB&qcc&b3ZY5eZTZ5+(47)i*FAxH(kq;2xsM!m|cZ9baO=)1L7`w*jB@j0d_6 zIOXY4+6L%=ij=}4xD?YOhnBAsUQl0aMn2Tn(qla#d zrMvEIv*sH8pS!pEKkJ`bG37`X(#R~NW;{n2kvP!T&k&wyfW3fhk?7R3B|PR2x(oh2 zFl~8h`mU{D?8__v;>8@^i4yBkf`6_T=}7uK=q@p`4~z;a+H5XAc1Q^&8>-Iy-O+l()C>POfHe zyXBUPy-g&WmsnX7D|4|j6Kj@0g%T@iVkItCVq(ou2Qv#DrHhriSgDCssv#bzw_U8j z#R^QUf*^~tpzC(AVizkmv3Qn1tgwj{x>%u!g`jE3k{=F_Kaz^gvIYL@QHaL2m@suz+B4zQIcX3Tz+W;Pzk?vgpp0XD}WKh%s z*T1fAk-MJ(v@G`$KXGU%CwSQkTti-RNnrw)K^D-CqU*BM4*h0aS7|_uJ0uYPV0!l^!&;7 z^a@ldIYI;V$-Bf`h12g_q`7_0A#}O}aAC}ry@R$z1h*npr$-L+egjvP(3?y_2ThT4 z6gg#)b6PlSk<)s5kHWYGh@RW%K~tfKZYwlLbQ)=;sH6NAFbXJ2BFYa>Tghd{TppBH zZ7w65%aDBm{OR)Py#P2cA55DjNwIr1AB;xxmrlrEN@ZNDILu#!{H2n=)m0|>%A0)s zz|iI@vAK%-p5{u9VI%!2YCZ!|aMQ1BuDp>#c!=(~=w7=J0TqJ*6~&UZNU{dZbtl^T zxb^#35&+V{mw&_9>eu&yWOcrNZ29<00(>>(K6fX}X>DVct@6_W4h$EmXm>~7W4ue1 z*&S{}K9D0YZv{j3=d1$DSszrM!+YH-eUadqw7(hBOiwzD?la^Zt$Sz*yl_8dF2+J3+kJ%QBizd9MH(&SmY3q<@xFZlDD(oevJibd+y*1 zp!Na$0N>ln=|x69MC~{1=FiQ$6|DhZX2vw%_$d9o%{MR*+;@~myHAmTq13J-VtZCe z`9ldRlmv}5u0+MlDW(3pcd=32fF>#2&YO?>Fi&NDUj+#{Y+C*LlfQ9_UR-Dv+H7CW z%NZK0`rK?>OrR5_4d*YW`T}~=k9DP6XiMcPyo7`$|8m|?_4J^x73FH+VPk6O0v`3XmR!JNzShxL4c+c)=z)f`^)x_{0;&t?Zig(K z#*UNIBK$qP!VQhiRP1}62kD&Dz}9}OMp&lE!Gt0Q6N(&6C~`1fnSsCGD}aB-CyT7ZQMu5C4HziHHpik^q>z5FdkE{>La z@ZOO&e&F7bHoouPrj75tceIUmY~9FEjCD#nIBs89dkDFWJ4LX7WZ z-@}|3e#S~Ah93`1U7N08{Bly&BZrnSR{KOX(kFJ9E>VqliE4WYKdcwLb|t*cRl*Hg z2?ts9mr!&%mq>c#(xga|bz*AbI<1N8T}@m&sb5^CdA?M~{SMR%XxPaMmr*8S+&tfe z`RR?`|5=xE)*$`C&9Ite&nlEvsDAnbr!2?zXast$3`}Z4^RN}_ukZ>EwTS{VP^2E3 z4MVC-BhtlQ@$Z7|ZhVpgz38NLwrs&C?1wEZU4PT>ambYh*T*FryHrx?kCFhuItVF| z7;!%rjz8!IvxY%6;=)mT2D7-9wIqUYP%S`>-X+pA5D(ny^<;wn?SSc8w;t>oZtcoulf%v;AyAUNZgnYWLbg#^kmvqvlv9y5D5 z%@w!wb3JBKuTqR0Gl|Ke$4o$^;h350F>@rc9szsJ@o$iuQ=d6*5?1vv(Z#xosMJMp zmlkW_(5*TK$sXooQ;M!Jt(Ij>K!tzB5OD1MRa)IQ5Bsa@$Kw7P*_-rdfEQgQefhB8 zUuW@qDV_QWINEUm+qj!nXnU1;q5}Yqv>q~hIl)8-;_20!s~Nz|bnDG~<_6swJ7J$! z8|7-_?m5!!K-ATRk<8|*v#(zu6M#3)tEnq!!Uq_&L62YWG+*zvzMjb4kkB%WFzB7E zij#wlcMRs>sNDmd+S~~^*K~Iy#TxxpGgf)aWUO2D_7D~vrIAc-MrYV4S?umRDe0ad zyMQE%4*=6X$!*cmo?YZ+JwU#^YW?n7&Uit!j-pb3IGBC=pgSDQRO@yR)=T(IefW{^ z*81?xQk<_m;qB2N)97LS3PUzjGu8UJ{syxdg7Nh1P5TDL)kM`;JFE%<=*XjDUmZ#f z>{JA$Y8C6!GnS|3yl@bO>7mTSL6>&gA@Ho^RJNf{TYm^DR{$p0$=BszqR7 z{_kvJ^eK8i7C{yh<`4I*WR;*eso`TF^15n!FY&iJ&uB|sjqS&0zY<>Jy%`ta zAa`bKm0=+d%SDnT@0FC_qj(OXMUt%_@rUJ?y4Fq7zF5B3*Nvu$ADL3ToavD&avqYi zx>9a3`gL7Y=ldPqh;+F}0W1&*`#f55c?Nb=>Hu237(Qv5`umZsHxv3@iu*CJt;1Ea zez)vHjw>_y{gU0sBj_m}R2^fYSgZ*)V&DX<-)qSN10$+A?zbJRCB^N*!+825YSjir zf%+kzW^IWU{)>h${mtC+nVeK6BRB`YxAiJ(S>G?embsm5Y59q09hJNKDs`hXqpI=0 zc;8#qW+LIb0}B9!&L1{8+2zA*3bMR*k)89^cQ$@9U_is+xd4=%ayhZF6|gwtMb<^6;m# z#z1--0C9DLd>`L4-wXh84mxh>v_G9{+=u)oGU8zQ>&VmQ84bau43GG-MNs!u?I~M= z9U5{Gh3WU1ET(jJlRP=4jh*l^mz{_bTM}p=W zo7rjELETTroTnBIlyd#pPd(w)Zz%t;kn3mVy8K|rGu+Wrrhm?uf~Zf18|~L_4<7Z^ zCYDt{wLO$iKmF^_(wH}o9h1Z#Io8lvKjfQp)3%Xw(?h;FIBgq0IBi=d(c?DJ`oFwK zo_*Xv4Al33Kpvhwc1j<5hFV$^e`pkZK#K5?zdgLN{>+Evo%JT>S=>DRvnKT)>;}oJ z^r0PbGYv-_9i40B>^(;Y`BIlfdb!D#5zdN72E|gBL^@6uOI;X8JR-AuoZDmfO5lUuWEc(Wrg2{+nh#3s4qC(;OGEUh&$-NI>9Tp+xCjBE9O`d+K0sY zMXuW>exg9yeRh(rb%6!`W#a-HEPMwK;@u@KuyXk6))%n5$W9gXbg6CeY^kGbY97SH zr4F)LeH#ka1;(0nf(3A|(XO#!sxmp0ldMOMM|Vp~ zhwiSXmnG|&ri5TxA+lFht0t0pbqQS|m8+tw=^yB?mRAlPtfnOaWEn)s)oS8Z%RH3r z-#5tXv))ZGSX1Y|c#O;oD5i*D$ay@4B$WZrL&c);5g6(FVf`mxkToYS-40aejBIF3f|V`^u;mlSx6g7<5ococJyQ*hZlnW$a;d-8RFqN{+)FGWMCm zZq~v^OA4F8D`iq)X)xL<=zO0xbz5ygJGPh^lls4;M;0AZ$`11FlIl>T5h+!-O-`mF z{A{)*?3sG|zsQJb>TOEvE!PxNTW=kj=c3=4#5QTY&B}Hx?RT}_y0+frvt6yXO|IUi zV8k+3r9F29X;o=Qs}wT3+6gn7V^*Qn8X7p3uB%=}#EoGWWouP3ju~xRyHYPg#mJaO zV|Q)MhRx^AK`0}(igs&4TJcERA%$RCB_J+^aTPErN7%*mjG7}f0zMkVtKIUmF~?9> z^#~a?4HlQGFh;{+Mi_+B(L%I6xU`0DPylhjvS2tHG1pT*;Z;S72wDI%V2ZoHa51_lC-D?B7Z&FZEkaclH`$FSkex zXrC)vj4R0G$;HidO6Hs>^#G(G$JFAW3nM5a*pp@6gytO2sLl)bvoDwk@30XH7hzf> z5SkkhgI`k+YI)~e|>#WSNzg{);a~Aq;Fk2tm)!(2v;gzDMS96Aek7eCJ`6QY6$rNj*fl48=8o zF^GV^uv)G#2qhzfv=5@dSQ3(r4TRr@|Iwtd&ZNK!0ykqTq4?YhNfpR`s)vjaDA?V} zzjX~f%(VP(9scc}tE7Zi3^u|z7sSWa)HR$(!kv_`(||WcxO^Y8r-CZT)QR6KR6O33 zn$^#Q)kb-bzDdw~PUG`oH6!PYY5dzWhup7{+^jXsAu$aXQb^vAkKVK?bupbo=8Mw` zcm#<0Ew5(y;gpTZxdYjF0Z1|6s2D9zL6JFg)~nXZJxfbt-fJ>~8qmK6zB;hs78Zn#Ilu6fbjan_nL zzq`>JFUOzD2H`%S6QE!roJBn@P$_I*4{_*Vroe{Wj-!ok1f~5RXSK`wq1NT)XcJAY zH|!H}EYd08tUo1mj6W(f)MVht-s=ba_^pO~?EN)BKKA~)As>6^0r?mi$j7dMe9R5x zW6^?qObz5?3-s~uol8I;O%T*86G0z4EzrjY?;HVreDux{(8q`QR9$!-x?|Qr^BFiq z8bwUPcFc(FxCGr1o;rPE(48CI@ju)-g6{aA?;JsQ{OvnO&>cU1=Lovvuig2&qdT^n z<_c{CEzlUQql%~{sQ0?SIhJN%dGII8^yKIfWnmP~(dJJTZ>dr=knAGTRAT48o?UEh zE;|Zs?<*LkLOZ5Qp&ipPXvg&2(2l9XPb`6UOcnCcqp=P5Dn1E>{M=571?n)Lh@?mm z#i)g(=)fI)f;$r1QCU1Oauv7Hn12MY=QIxcAyFVBvq72){D=@>od#ervH*+cPAzxr zAzIn5KL0Ho$j%sC965`QZR( z8u^)WVbyQ|S`hguUD)h!u!`RNgVipq91hmdn}0Cl!ZNaP;Afo;t73CS50(Q;cG&>!I)>7>m-P z+Kiv6>O1gLRs;O3uKM_ysVe-et1hGhvAO_1Zy-}2t~QaW3|Dhi&s=S+rp?ucYL&T~ zt=5>U_0?K)m0;fVl(tmn1^N}L>?uWarngFKNOQ*cmFAS+6k@NKtr$;k#i(h;sNITP zZN~g-(e`66n$h-SFI%ha$6mNj z+Yf*bJGAv#ecFCqZNEa>Z%W&*)b?Ag?dNOzt*1x6wnk>I*19&GaU*k$8=0OPnTZ>j zv1>o>(jaj`?<6wC;X452jT1eRyokUM|_Pw}j!RJ;Sv^yOLS`DGQZ_Tn0&r zZ!oVUvROHP&LG&kbGP)I@+&DfXA0U+j4xv^OM#1;Pn=O03~WSpP%xd8znGbf=%GDP zRWo+<;Q{n6E=f1?rn3(c?nL*a2KD5vvxgDhvtQQ5E#-lirX(Fmjxv?vz`H<}GI_#2JI>ph9nf%mE3zSbB}LY=;| z$&fKrVS<~LT&15vchf8X9rjSz3tg&bj2$W=yhwg>M~QHyvp~LFS8^CpDW-rF@fw@? ztMo(HGWIr!y;r03jN5x+O#d&Y`LndnO^o>z)6=3FDv}%B2j9lc!!~Q<`_aTq5AJ>= z_kfr86H`6QE6ew~T;k^@&BBeE=hnC1W~x~~@KWY7eO2q&qekjoEo^?VwZCd5+N5Sm za>H1D13nOj4?~EcTZO2`b@CMo!E38-0fB6Jh)V%%_nE^rK=xqBlrFV|YUp8j+J;TPNX3EobX9&r4m(xstO-1+7VlYM1 zY}67Ox>LnNt(p$~6Hz;B#<*9vhc{4;t(9{s)hQsZZ#U!9n&}kW8w0rv-o|)VRK?h# zJ(5Wi+B@*CN%hib2=Zr$_&tiGNOqOv_S|8~O~<|w7%@dfSFW(cIhFoNdyq{PDnW7|~*&c%29TT9*8^i#GiUADpmh~Ne>W7T)u$TX8?kDgG zJtLd#WHXjKvZEwUPdBfVjLJufn<_a8%Uqbk$UB8G+#f+n7ZTNzXw1X9qo>~l3ju$C zQ6~%K=e}TA7c%-?eDMne*h&ceRX)Xb-#Q5JvuyygP;3UM{GwPX1KrBSG%YuH#~p(( zxQ*MVI&`0%l{2gSY{H@YP2L}U!H59@e)f;~StS&o59W9EGz)SLHd*Lv7BFc7Fj?}U zxLVk+waQlNM`rY7Z_1XfR5mSHmnBQJWT`R`q^g5TZOOW{$lTV{d}4ahprdKJK9<0v za9*Yg=!Vtr0;m1fQ|ZCs4lL_*AXYIzzssGd(v?U|$F8_73yZoN*F21XUrG18-#dKfOV+^$&AdWk>%lfq< zL9o%GN;Jl|+KEF}#jEO=(v1Q&d*FW6^J)F#FnKuGRyCkKyx-8E`e;i?k~R;L*`QW1 zauB1}bcQxf5x^ujbZFzI2_lnJXoAWimB0>@JbIJoU*hk@)fTTrPmJchi0~|4M#ZRC z^mAykb64^~wxsOyI*~N>9GMF6A(iBz;!XbEOQZsPbTrg)SEmd*O#0gH0rsik&=tt! zlCVBWv2dGd?hT>BJUjwqw(7K>p(C z!a)hG8uEnU?l%m1%CPN*iGH(}|6wGl3?mS!s`^n5_iAbhY5Z!MUuk)vkrB4$bgJTe$~mz@%1oy{%{am^3eAy5{Xo zY+fGsI{T_=`E#qhfm-wN9Vrm@o*j6opv}8#n0Pyqt$J+puC8|Q)`Bba;vJepxsb|% zUU>>2PN^o70)tD2vYAM`IvGctdU`;K&6UvaEfh9P%ZJQoOju7%7umN8)1$b+Yxbfg z?*Y(8nsZu#W~MOG`cS*ayNq#3R)zay;xDXly=Z7sySh&8Ri|2s6z9>)xHX2LZ4%>Uri?D5t#%R(OiTQ|)fADL#4>oohk znP#6`cA9TK>L1nILO-f<#5nx-($M9xbO^YFuDT^A0OVV>IKZQ4p8f}9yHCd(|LZ% zqt3wHKk1Pw%-w&Kwn3S@|8A%YJMQ+)L#I2pd=G|*f-o<@I%#7~rz1eq2BP}A8&G?y$s@(N2C_Z$y5A4b21T|9oC$@E z;V80w2>9)=;Ts4Evy53{0w+WZnqHx-gBFx^WT32RAU7ylP}W5Y%DQk+)&-!f3x%@o z0m^y`P}W5?MJVf{fwC?dDC=Sb%DS*n)`pUtP}Z?RS<6It#8@9TP}Xz^t_s()8Yt`5 zEo|y6Xm!v)SqBZ2btOGz<(_Q+Y+PfY0 zm5S_$AzwC7*1@+N%KF?O)idV>cwL?sNOeKG9f=h+u_6~MdOe`5jTZ;DkiLc2xVbVt zpgd{#63Uk|$KSA{#ozFhH%8!a+8bkVShN8R@4+|nAXCE$*gA(6h%c`X|KE#Vos_2m zMs~ly1c+^vBXd5u-&ZKE5T>{NLLH|n zL!klT!kn-Uz_TGIA6Nt^SQ?BsLIVl8s2E(5sgL*r{yyd_3YT0yO7p%*3B%_BG-hZF zf1eqcmu*Q1R;n04Tx7bts2|{GTc1g7ru6_zT_^}i8^A3q-zw{|U!-);&t$S7%Gc~* z3hIRrAZHiJkAj?SgE2Z3K4DdyP=k?>*7n*2MP2n1El&NRpOVI?>Qj$P3k2ndWOA$@ ze)$Pz?`E0J=E}RKdWI?`s;lxz;0F7b_;1q$udhNPv@FKk!NH|A1Yy0E^@%iQz^`_L zrI_N+mHMRA+RtpgzQVf5aNgnb0`?A53)#^VGL6ysulx+jB;Vqpyb0`qjVDY7lo#@9 zCZy3JS(?w*D~~WSz`=w-H7IPax=hYY1W2|Oya*V~4v6qN$R&OX?LD1~rMW?Ac(JrG zPfzSSkMZ-hzegMMBe2nBH;`N;@I6jyLc52TP0ms5a^&)3`o-niA+BX30hr}4;eL`3 z+#-aI{2}~G?vDFfr4RV_%Qh#40>o=DM-RJjRDRq>0XUWH!Qnhds{-sG3)N_mc``J6 zKok_aU4>;DEvF7o&AGG|N2n}Xa!iyG6eoa$B%2gpd;SA3s!nM1AY+8X7)9-@P}Im2 zwWCEeMV|D5T%T^!$eZEihwdKY>WrFj zVC5-jIBs1H*{pt*OJIu$?exnA`@_^seDVm;Z8V#@_?Gb51b_>%^?=6bEXoT4I+|I( z;Fb9t1|-4Y7A@P^VkbxyJtMT}8HM`z2j^y>cPIsfCYXSdpkx5SZOgNd7s@`KOky9; z>+-!?6es;1H%b7R4m`_b%w)lcn_U0bWr0 z_kv~=UC_S={cel?z4Pkn-wV>e7ft@Fp{7l5{s}-A`3U{HqJd4Ke=m^gDE<3Ll%~wo9zUY_-KQOE>U5b2BDDp)*j(mZ^cN1QKE02S{ zki*g#?8Q%agLN{4o!e#Er$x^ouq-bAt!iO$k(pHK{v7M}TfUbWIc-3$sw#lPZbx~S ztivu{A0tADpItmOdO00@19kA7y$fiP#faM_U7 zS}p%uhktwKsu{TRuAdvkN>>BsF5}S)QZ9NCcPdUyFl<(8^nl|{c36SRy;k=FiZ-XJ zU^g9fQE<6O+U#m5K&~>dhB1|1V$-=XCBtW9$VH6vaOghUb{_U&L%FG1CEJK;=`-tl zNkJgqHQ@b{UBf2KLe+YB;KqOsm84|U=DiGu4|vu-^J}M^3vP^$1?<8~OYx@yKbW~SQns`}rcsqH1`dV81AK!d9jTY2 zuQqi!5m;acz4mlp@2bw%4N}CB7Vnvpl25mCA|Kn=qEp#v)GK61i?DT(QHzYWuN;-GS}l4M2lozE1lM$mgQL&#Pbl%HzgwIed#p$5PpQANKW)d(H3d zjcGsq_AXZZJ>>n^S0DH4b>-LnUeHE|UmWp?MphPm$qU%CFo%GpnXV(Z>;y=SG8BC* zvn4EX9`%$4U1pH-bH-BN&_>^Egf>rP1k#4ZamPBHcCh`wR=r80R+0vzgRmVEXN4p? zCdt@3w8l7D?X}HP{;w*o0~!V7zJq)r{r+AH8b4_}gU_ojs_jWSPYF)icEp|^D)`Op zNKl2KY9t6Yl7>Rk25m#ow#FfXlq1BVr(`>v$6Pisb2cgw6lnS{%W<674}Rkbuih^2 z{Ejr@eP^Y8Kk|yjGW59tq>&}+v~jDqzVfi%f4Ws~*Q(pVW-qy&bOq49Te8omJ8Z8w6*1eb_{K8xu8XFXsgSGowi}E zs#3%D&8l6+B(P~I(fHT?*2)*}#?y7Jw~-G?LS8N9c1^XONl1*f zcMsM}lxn>^k~i1k;jDcqUz^37vwTk0_#%_B!X{&94G{s01SwV8Dc%k8CoPKT%2)Z&-_d`CkM&1JO zoh0DHwE;TB4C`&)??6Q9jl3~P0NfJO%Qif)PkrPEQ&$jLjR0FoeJ7TQ@1qI$I~5L^ zBR9rcHO-xSj%hTe__ms^B_E|Rt)Euy({z3NewuJV51rSa_irMx<4~_^D$?vt(7p-V zH&Od0Zr>#Bo0K+68S;O0-qlF00TkI2e^uE9JMRT}s<7 zQ)rhdw#&5a|3`DcXudYzAvPb360|I34nMnt)fyQRl{6}kQiMl>?`nN;h>fb3-FJ7-sv)3(w+?j45cd|*4JJ|^2PG%r?Uh+mDcQOOH^O83Lxs#dw@k`z~ z8BUfIHkgnG=HD{9cdmK0AW8 zb6qP4Xgd+Sj9bv}hWRHNOx1tzxnKPPpx?Q9r!TI}Pwg8#6!XEr0f5gB%O43H3VLQZ zh2H2r>?^m9ximE~Gjy2SASm}tM}aI>!+VYCL$Jj=>2LSmf!0%mqD&7cN_Y=6@vl;c zPW?qmzS zoK2&j3DDiP- ze6OY3?S`g%z}?TjDh9o=w+n0>SI$8eB4-qz+O13%0_i;E&t>PC#bk086PLw=Sp?KC zd(p2!-S{F%M5H0^?u;PaMms6=Q6^5Mz#r81?Tb$s)c32cBWLtvAEe%*@f|Fso4AMbPix1i5SmnLwrzihuF18Qi9>|X2!s}0GLXLh?JlOz@) z+59{hLmF)oRPhS8!TVl@WJ%lU={SAi$A^SDReLmG_I3Um(?mcB3%!QVd8?)OyUOf z3xtmFnx0>Oo-Y~^Z{;MsB!GmS(@P&;Yy`Yls(g2c#=cyCwmAwYn)VVe2C|{BzOekd zte!zjA_$4^Z!ESYg3K-qou=z|02IX-a!m!H?=8tyU~_f)r(R>OS_0<~6pkCPyPG40 z<7!Hn`ZEZbmE*TBm7c<&BfVv3FKwMpxIe?Gq^x`uPr@c!ngv>_vg+-g+lMV1Djq;U zC7OJi_VR<0KX`o=vcC#D0R&}(HEK+K>tIzK?v_)fzYBcgYw*ERcQG`N0mIo~6)o`F zsZ^z!2Dt&fRR**i3A>U9Bcjf#X_}l#En<8@QCdC}z{K2~!>UwEr(Op%dgB37N(b}y z>8cAHu2oQhbtvjsu4svp!cq0TimUjNLMA9=vSJ|}LDz)zSX^Genj%YMMksQKBJVYw zw0sB*dD0W!SWUqzLV5xT!!SOs7_6G>udaRch^>`em(>h9$u?Zi=y|}N$Y#eB7U8U( zy<{)=nXdGW>^4a$kS-;sm)^LbTzd4GpIRIhl=o2d9(MZ;q7Rx1C;iyA9hoDw3s%!6 zQi-qbks5x20xN4>9XA zksid=-08iq-rQ-#MrG7|Wf@DTb6PyXcx8e$j*`JlGUQp=;wfJyy+qTSXoRE|Ps^A! zb(S%M8nxHyo}al>$CPSfCeO#*Y2>3L7EjBRduoMpPmh%QbuxE4uP!se-03y+iL{@AnqxQJ=1F zNr$$0;-M}1Ydf^H+CmTQlN%%bHdMmjjKg~LZEN(u#*_Maw))7?`l*g3%K=O`e40Y8 z+i;nw=gJTH&Y#EFe#Xrim|(EGRGI6SibnAzTuh{Up(h`a=&M7qWEN# zD1Ic?5{7tP4H6o~CAsp|lgTV4D(ormiaCiA+9x<18`xCV%_d`i8gtz>#;jfXWRY)X zpKRy5U?f>3VVjMJA_Tt-&U^6uucqJu9$9g|9M)v-G6U+F5az0zz)H5O4^Hkbn9#u| zPkS>gK&uFU4#UYrmVC*^Dmutq(}x-8^sv7{e%8?Vbt7;VhW$Cyz8$sFTvyHB0{C0A z0mydYz+G*UxOroZD)rr?aezFSYeJ3f=^F5jSDig`gRE~Ay|N8Zd(uSGLH>v;K*P>L zf1z~hlJI?yt3Bx&XxPbKp6}*@*}(*sD+WUs{4Tk1|AEb@O%8>!cA^`kTb9c3mRB2x zYR~{df~}>L8D?Rb%~|e4q|n)dZ;O0Swdt<@8?aZBhi`x>LNHS7z!dupdwZE0cB0Z+ zRR*)$UaHIg8rFj=n%2f{hGd1o(i^E3vbi(w=y4+z#01x4Rb4CPv`OYtRfn{ykUEK@ zP}D$*oxoy#HSE}XtVhyDk{hRoPj*`M27)?C1|or|n(61z7j_sIW2dP>MO**|ZDUhg zV6$0NQ|b`U(Gj2px-E0snAt%ZRla9VUT^Gfm0V1+Y>*gFj#PTnaofADxk52> z-RPyb+*hT*Es>30hK(NZA<$bP11Ny7Y9uUKJu4C3uzPOMsk-FgCe@pLoXg{!k28o5 zU-74N9nPSe0L#LzUcB6PRMP#I!>MkV_tGSeWWnpvIIZ4Qd8$#b?hWk>e?QJjtO=p(ke;y$^hSmKT@z% zxh2zHAs^Y~GP7wkGs?%*GYfMjQS~Y}`LQQB$&Gxx?5%3$C{y8Yt{AE2$d}_MXY=vU zRUQdsilqdW+2QPsEO8Q+U($L>4mO)#-j^TDNKq!~d_ZkeT$Rf2jEP#BU-g&$1eDY{ zUimS7rE8mN}h30n7d>mSwpXXh;Pufhx- zOo{dT^_BGeUP987B99p?nT(|zW#>7ZF zQsHtnlG{P%8mcw!J38(=9QRlDAmQ-P3{(kBc+-w(j%9fjm@xWPVDBOsVP&`&Yf%F+E7%GZxQa|*>DYx&QA68!ZGl3o!=XqGv z>#c)C8F?>Ka$d@?J(%mUSiagjJ$cHjOXw03x=N^Iz}oj?pNTh&Z;PA>w;Chzoju>A z@DNhiz!bQZo0K+^!C^bHpFr9XtHGa?tFPkClo}3o3z-z@zavscyLo#y z=~bzN*CwO1q;oF=;G`AOab}+ynMHsOvavS7B7jG49#=Lwp!=;FKW60IfstclYwE-| z#@kTe8FMe+n0OQGxD`|yIOJB40m8OHmCvhr6zOX0*9rE7e9&v-X`Ynkho)X=+NL#f zHN!>E4e$E6SWs1)s5T2Z(FHW0(fM0)j3757_L=p&ync<_}uh~D=Jf*?TI=VQ`| ziiv&h{huIO#n=5_>&UEAg)=j7NL8FNVon)4peb&zKV}AWOq0*dxa-rz#(qt{^c$aY z8REw|6wBZBX#;Wy%3S+de6ShYvCV8;fByGu<%Ejt6`10-=CW&eKGV7B>mDtaI2~c8 zQQiFVmGJ>oMx>R&yup&iSDfZ5%Ae>2T|F>YBo60^*AQzMz=vdywa{}W67b@Ja9CaS zQgu<0qZ$-ZkP#yg4=bRF$7)I}YkK#)0`Fjz%inhlrr?~8b$kFYo$vj@3OiFiFZg^K z&!^>qq=I$6kHbO6Jy_deG@}h>jGzO99KMrN@Tu37x-O+0T;u;+j|bo201f)&Cnru= z4$t2h$A+%kSg1Wnj@~;1tQ>;O`IwZV`pid8c}fiY$kVtg2{Kl{B*Ep6b*WRsM~3}I zYMCftxzw5O>I@XweWPoazH|+b({fRMBr%P^>c`GNGKU1KjM=8?TnKO;U5{{bf}JvH zUB11w-#g#hPn5Kq)HnNh0OIa}w)gpXiRo(FF(uBM5_fRm^Oay%n)83>8Y=VC9;%a* zU9yWnqv|wQ5v(KDrjU$D^A@ZWRb6y#g@CF4pwWmzxOfRJ8dpuO~lAR=F#)(pDJlxX*Pd$lEK(%TFU8y;D8~p<1I9+uZhX(Q> zN>G>*Km|fLOXMOUzyJ>CohrFneiC*UK)*$LjI|8)9kv|02|IhlY?i+skc1^~$VK87 zOE(bxRkizvU8;6v5W) zW>ZKnwme@q!Z2quHU;H>jC#gqzSE+B4V4Yd2ln5wR~D2mL3vp2e`Vn<2CJ*?I3F|L zv4I+^WFNgD<`QAQ@uG#t3E=pPx_{)A$F=%vW1LSbHdTb7u&A`+_bzx|nUvf*+aeWGh^jAAZlUM&r zOndz;!Oi`So5)&`n*7-wpvEk%p1*lmo=IRQ20L)H6>jAqD!1y}xtSw_o3Y>bS}qa< z@Qdn2=_>L71Ud>FBscEcq3eCx4`~TEyFH+B+%YOwKGh8(1&n*dO|!~?z1%c=*l*@p z#x(P+4fiLeF#6_em}!r+`C;$%n>O*)wd-3t&2DP*fVZdFBfic7Qk3>YyTcH2bE5sC znP{(TO|;kBiS}M!XWFB_PK!s3n>*az(Mk{MWGf#pFEMlN^?g&NTJ~p_%(XXc509GH zkC1BrDNvZV#%EXi*5>A| z`R1)n?HRRGerc4h`dd4hO3!FbrmS6^O^GXDc=pV6dL5_JXK;!7g9cLT>$g%{ds~O) zH@Z5X9=1+7#mId60O!+9!_S?>~U4NVcrMW%PPC*AWJuF0#6Z>QU%fWdR~t;WzSEuCvkx8F1@ z|Eyr+$*<0=n>Z3Uv)=2Q4LVy#d(Ar+?XV;tHT#I>w&^40)98mt<`GV*@9z59Aw7H( zfD_u~hNU!sxlhcawiI#3bgEApQlg&+))9ex1plhA7Ov;hk-V+Qcgz_*&Hk%8es2L{uz9voEe$HA$RqKKyj=1})RgASy`0fc2S zjk9)2hGPhUJH*)0gAz|}zESkj6RKPJ!+t=v?1Q9CGgEOufyyqFV$U1}9TXWIs-fDH z@s;eFqX@+sCWU!ZXR+oexrXN;Q(+xF5_M5w9W6=V>aE*gP6l$rY9svNCN)-=)w>yM zm@qR`0b*RfKQQ952nv5CSd|9rSeJvi`95v)e16}3*f$@>fxAnX^SP4cl$Y>E}xVs)Ak*m1=QM~W431OhA76{|B+tj=h$(khc;=~Up# zgHoQmCF56HzR--~s6nDxZi)$7Q%o>E#n40`a#M^{TD(s`zI3vo4{Q13T~85%X}{yg zm=Di-`v&o5B8@``5);Z#AK2h@{LwWZM@Agtd3Q1g)UU#NImiS#-G zAyDY$RW$z&hl6aNRuM#nod%8z*3Mdp5P)5t)xrktD0i4BSrg@su_*6Y8s!~hQ4Wqo zk$`_aRO*Cq*bliIvzAak>IH(l@Ct=dMhR?E38bpwJ`z~&>@_C^mePj}RiHLhzOkV~ zJzcn;&{h9js+)Z2m3NDAWY*;YOw_*gZNi($W8d0Td6b6Stj&_prpnhHg2qyts-&^0 z;_((RU$N;kOc;>g2JDO14(!V}U|-Bii2bjE!a?K!K6cr8EX3Q%8TW(seFNdtH{sK0jUyqaO_P zPO}whwj%xd^Dmt1>o>TsYd#8>k8DXkqzdZCq&($M!B}1ORq~9=D$iK!=)CZI-5^s| zi$!;6CVqvw{6$Mn&IS`8a>xjl1S8-!5EwBrp(Sww^^8*5gK#%i*FpG((=GT~hX>iP zR}(5Y)woaDxCshM@XLf=5y}E%ICvd;N!CEh7>D|l@_hY9c^561>kobPabt?jQ{J%_ zm>UmHkBo!4eZ+vdJ!DR|kDA}(=J$TxRv*Q-`eEN79y|r_x}1u)u<>ugF=Pw~?Dfe+ zs@W(%-ovThpkx@Nx=}c}qyF~rc9{Uu`opZ4++;ITn1h$Rad)oUL6}X%kDC-T;zl}P z?(9W&3*M4}MD?s}M_>XHDY?YDD=1U>4_`&uZmv^x+?7L#35fbeKJOs}7J2WAu+Rc>nT%fU`tb>;C? zQ5mGmU%@~EejV}0z%0Q10cA7990Z*xe@!tuH2#C5@gE?c0ORnyRjt@W8k1VoQ1&F} z=u!&n;`pqs5c__NdoA9Fy5$2VW)+qX2JK<3GSGA6*>Cb3o1tisWin$Lu!-mGZX3qM z;=Gy`+osmmntY7dxe}=OTY{MZ!N>!Q{fo49A>_`tQ$8hcZpNXjNeEDHDzGTF)AiNN zVcwvT-I*d9xt&M64F{MZWor;Kw4d2?d!-J0_>L*Mr(Y(#TGe`Q-l1$*tctrpVnJW( zGrl7Y(yak(xDAtrbQ)Tj9R7pOcKRrKn9wOGDgT|^m9I#)F+;v$NzwuuBhx)uW=ew< zN0qn*liR@?gEqH~HwIT{o;ODBR+-PdA6?_kW`_Ck&pqK83C{^1Gm25FOMfUIj|QRc z3#D2fFD9J!}Vi6fg(el@SJG)&1QPjOgv&U!71>) zt=AvnhcuD$Ynk&5n3auwNEs+ZZn={)mx@k51Mi?M-WT6}IjMr`R8EKU-k0Bfx#H#I z7YC<|;BnE&H(h2w)a^&*$3pJf#U)rQq0C?AXE?2otXDsP-H0cycLxtXL ziN^KBuj&42JKZ;V|NY&UU&3^|W9fEA(~Wsplf>1TA?BGA{Wa5o6z85$VfaHkq#o0` zHEiyzs4`f9M0&^eb{h^zNzsU)*@%lxBR*yuQSzzcX}l;i&)2eQ>{avlK|X#Tq{jFx z*STYCa1|aNm+$^`*6c`*wIun+*_q5YI8j5gBE7%-utB4FtQ8xP^f3h9A5KZe*Ef zFiY0nbY366UpA@VQ6K-P;g_gC`9Zn*V8>G&snd23^VldnnN;>;z$L3c^I=&M*PEDU zar5-gnkDh0T{{U^&Ng%M{~C);wQma5R+CWJ2KK6lXL!` zf9(xbdRwhP6Et@6dOi(m3TOW0(O7|I&0hV{CyjxX8ZCQjtdiCb{njbgCRn6Dsh1iF ziX@Bnhy8Lvm)IA>J-rnQ#x3)&9~w^01aU9wr9JbX?|WVl_FUF7wakL!?&1^H@@tmX zhu8GhI`gwndb{KfH9~t*ZsaSkJRRZqS@wtkH#_L;m5qF{Hg`r}S*>7YA9YEulWaZZ zL7NrSUqDUJ-fmryjoXSL!jn(B*VLw$wrp!zwvT!|j*OVU{qd8={H?d%#Fw`pz}qg` zj7j|})oTnW5_=%JcA-nC(=rO2J(cXCSkG0>n57(H7jfve%v1Zb@ zzx1TFk(;sQ{_&u<#&y=D-C3`JBcyguHdA6c?n=$nTRq{cUwP7+DcY}Ao$|$`x29Na zbMfsJ&q&u(PYGAxS(2Q^b;XI5iR*dUPOj2GBaJpE06lUuDS({*G=92?|gMwnT3 z37D#u<)qdupX6e_X`sl@gMub|vEuW2SJFqq9~w$8i7_kNti!sIHFgcMcgiuiF@g7- zGTBM83&}A1O+mrAoITW-Cs*qpHRsWj!K@s|>i9PKbK(B-U4de<_jFsDtA$&P)HG)_ zqi;Tl1WQe@$gT8ys_FqDPtMlLVhTDKi^&?-k%B55+}~eSD-ldd9Ef6Q%mu0(*Q@2~ z78OcG!@-(r4W6u4A1o7|wZgMjc$3m|i$Y;}VOtpDLy%nst z6>6+njY0=R%gn3pV&7Og6-*uILhL5qKPIU_juojR8^`M%jz99U zeos*&&UnUCe8&iVqyeuF)s&%4AGrfqv^aIO*yAF{9_J~0+;wD(d)gc7iHzx8OkTta zry=Ey+pM&4^NuyHT7foFw&iNM<0BI{0_}r5gwW!Bh=Q^bV8`DR7*0aZutGwxz^e@N zE}`3~J}&?)L!S}J&&PwNjw(|}^;UyY8LBWu4z#4J>uA00Fx6I#RND?yYt?wIRmx5I z!U*Z!+g!EXpw)Jeb@h@*rGYjqpln%_T8XCWuG6Z!-c{YTD^{JMQM?Ss#Ph+W{apRT zO?`IZ=LcJGet~> zlMF*4%$3@)S12js&0y<V)Pe`ixQYi+afWd`w`7SDdBL#Ib}dDs zG|iO0y2(gom|Vw@m6J1ZMw2s~i9ICaDTkx7j2eK6-|hs{hdOtRL-qiBJfcmlu~Lx= zr{bmjY^+v&+c>hzVf{N^`AWt~pGbf*Yp#Kz&y^5Oz0unZv;>(T`ZM?``)dv2Wa!BT zPvI!#ay=cVo(cQ2x~i1V=hZB@4>pW*A8f2VT72Wo8%CbrySw`mA@;us)_NUb-KT%x0G)K8aq*S68b@e%lb6XU`b#%5bUmA+}inqt@t@Pz|djLmy+|*EP+h)i7A46=8t|G|BSmp8BwGF0@ffaIT-R zgzPqlk*%esXia^Mm1?ZaqgAt{=9bj$lG<+-dQzQCs=Aa$)|`G9g6~%n;F}f4#z^1H z{9XQgx-#umFsKSFGv!Nh+m5?1XioKvN}=iT#EGu}ru7!@r;ol>p`c3&&VTXfTQBA< zt*pG0`cx)CwWf*Gnx<cOql4B7eY0r>xMBX>M7fI0OE_(v}o z$R3bq$>bIVPfJwYg>BtQAZw`!o8k3Dkoa=k5i z`w@FP%iBeJD=&TkFW$`S@F5#6jS4=`Hde0;?HG;D`%i%^qDtKTlO9eRsk{HE+^1FM z?!OzzD;;CB;&TWB#BgvoKEIFHPT7^%ka&%Js|XT}R~lLb?7%h|tbG5^cxP zBS%0baB?ucaLGL~+fFZp_Z*Q2h_o<&4_@KB3$yp|5=ky(_sCm4YP!DnR#jR1GRXp= zue@_=BWCR>Mqrd3w<_~V2&yDq`?V+u>OsemyG2h7hPIy_Z7vTtmoNG5@@#YYyt~BD z8DFW{?+;wPo$*=m+@0R6B+v)c1n+ibi9V?Nm&1m5`v{>#VcFg%WYv6duRrM2vj?!3 z{6@IH&JKVsFuRR+ay5I~Ew^0kZ35c@Vr5ON%*Dz~tXT@MC05$RN?okf#G0Y!vc!s; zSh0&0n^+~?h$U9k#EM+3$iymW10}JNCRXBNB_>uzdpL>ZH?e#d%QvwiJ)gqVz{Lt& ztiZ%Vs~it7JAJg{_bldv&Q04mfkdi$j@7I;sV}$*IF4mA1gQERWJ;yh3S0-Xi?qIg zfj+f!oRAo28@Xuz9(vTFTdVj@elkdhl6Lt{88)$T2))Elbdt(+!m%6nl3y%z3b7&b zxt`1-zWJ66vTfVLQmulgs8)awq>is~mOeD?A^FJ^WM^uPDOrgIAinY?Pqbsb)EwBk z`@aZ7wmkd68PKZqrZs<$WOyqp)qdj)$yQpUzVpa!5@!xOaxS`P2Nt%T+U- zN~R~|HXZp&%&$Pgw@hxoq;vzX{%w~>PxBb$s@}cMq;{>ozn3${bvj2}E3;)the{T} zH88l8P#kHMh-RTQs%qv&b>c;o2t3eL^xAuXtTbJUuUhR-KVE;N0(`B2t~S!NRzT-s z$2FmFXQM5E?*JQAdH{sowbu*vaGPmOl@IddSQyLYLE7UXJTeX1&P8`57wJedoNq3^ z6qsD-QNNvqNV6bKK>vjtR@~V91C5mi(qXAif-!_%9?WzSJuq$_qHS@tPF5o`ruEE7 z0iLm{&dp7z5DWQ{&Wc*YHi$|6&gklK9V5(G-Wk>Deo*x!eh@}+;^p;EJax*er|PHv z=y6r%8awESMzBolh{9Ra;Q?rY-ss&KfgvVkh#X;LBX($5d2g4PfAz12H&wxKI_F!v zd+X0L`tsil4jBC8_NTM$TKFbW0tN)I;71U-|pfqc24=yk1j1=+}~wTokSFm2=S> zeMwtm**+nI2qF^<48ZNxhaZC`v3}}{W~BTN9MCHKbh|xx7|MHA4a@f!uzBB@%g z;Pb(JKem2Ckz(elB`Xc<xTlPZ?#RXxh6S`qf{ByvoL*1SW7-pzkNR{9(= zlw1-p8J8W5toIb7#6!u$J~;v(_iut|Br-0wDnhwGR}o55X@vUh9STKN&-4|O+sX~7 zcgxf&j&g%9ylX^m@U?f1$PK=vPctjcPPzJe#>U&%tw*ND6%nMwd@yQfPN8cA+wn}v zf1ps8|Go6CC(K~G_a}@=QT>mY-G9`ww9C}ej(I)$Lng0pVqSmghfH26>hT`2PbmoU z9Q%`32=#kD&*HXYI%FR3eXRz-S^EL zG#nzvbgWV~VP^c4H644(nvQL?mSbBfOlt%`BlK}Fo>m!{u~-Xj4qVxd)!OU+X;v5M z7~2MGhnEQ`+-v0H|ib6z`&!=Rp!cEOA}V#$1x7i$kYSD6q_s(8U}aoQlT7)ZZ9e zuDD)rShmMZV`(o1&YJq5?7%=blK~RUH*jK|D(T0tSHkY110YFYZXbf>4dL@~q~LKq zotHao!EWD=ElVAdyCX%Z>1|3ZT*CUr$fJ!Kr~wwJOcYMG%7#r!J7H*^&}f*d>6B37 zxP#Ac=n&*3b<}daILOT*$GXMZ@B;q37%CU;=c;dFyrYTHvoWSM2B#4|#UVdAQ1$47 z3P)0c{+l~m6Ulv!ds(2~^Kz(&wu!cgx}O@bgM{YMqw@4w7CVCJDWMD*@!GrYEvg; zYt|w-%Dgensm1K%>I)!7_LcKXw=E@z_y#f0Mdh!Q7{=WKJN8Y>b6p z`mZC8!$#pv{-#U3PRsKhMnW>7#USeHm=D5ZRkc}4IUMVJ(p8j`L~&4L6FI9i(XV+5 z&@GqDLPwz|q>2BrV3eV~n8eV2cATO8aByA>?dRlWR}`u9<7J;8s_h2s+bl1;dbgY% z#I!%U-Ex-&tQhzkpB_sH;~;q1ICR&5qHs7Y!}@Qcm_3A^WUBhk?R0auLd* z!*3d-Ejo4+nl+TzJS1GDZ0tADFOQC+lHtR?zJ8TWvX9|tf{nDNfkWJewSNf zH)yg3woR@U0<}3(2J=+y4hGgv0lFz#C73RkQc~PDTTleCQTp=3zHH^`E~+-64f4^< zuw4RURbU6lgF*Xc|J*Oj{IC#cmC{$O>zb1m1wqrCaYH_Cc+0PXvMN;G@-QDUnL6KO zw6IsH*2`yaVEr44dzq6BJNYr{1iz5kndm8}6{Hz=a{wrsrtz*K>}mV4TLltD^FcPc zn%#?3ov}?1U0bQnNUk;(o;8f${)Bp?t*SoSrX)HS^}D)c5gJBOal4@Pkj{7!!Em#E zb+E@I0|r8qjC-GeLh?ca567SU{N;ljK8^|GhLYJ2NbHF`ePyhtTX&I`6%rYs~)F=gp0M!rezJWEx%;#A}1$VanJ zVi#6$s+^BFN9y@OhD%)jHos7+YJUd%F`#u9H{l~0MoEJ91C~!}NUY%c+A$t%GXU(# zHHCm%p+Fr5{M#_2$}R*Xk{QTjAefX@2k6aJW>(>ZN@*o7>5_^Q#1Nc1vZ{v|g;KH_ z5<gaJa!n>y1|^%&zQ{%V$ISOBfSZFd3K= zJU;hEH91k8BPwE>-fcCtOLvTpq@hE@bciceN@LPY88;l;r{<0}`vD__ z$`_lzoCS$-EBCBF&b;DRuAspq!)@q*JGhU*aq_{#Pk80gz-(>ywt{*sUg1b;*@wo- zg9Ukmn8e-TBKw73zxavY|6qEt=M_CA1y&fzUy1DLG;}bM#enXVQGE!!KxV^qokHZ? zBpX@6z(4DmlbpeA1JyUd>E)%93;*zrL3X0b7OJBs=19v?rPzU!1Kc+PlY)qo^9FD- z8^@b0b;INXY$Zglr@sEU<`DtcHo(7xEjDmIW)nG2!*7M3U>~7r zV0l+ZpM9naVG6qv2P_8#J0cn=P#`pew3`hr8buoiLryq*jcgc+nYT z+f5d<_9b?xb#gCHa9_)+v6swaYHZ5)b&$kCwHSKYXqDLF*X!h{ZpobNokmNSgBu2c z0a@llp3^=l2c%%cU%%(stSortgZ$btUmNINA1Tm}bPK>32*_h2`{#^osYt4jYrd)* zJzW6G2RhoxmVchRGC<=diQcHv`?vK&zS<6OMWh#TWYgmzwMw^-c7Z^<0Ca_r13?Mq z!+!}OdaS*OIxvbjaLfT54|HH44C0b(la?t$?zgt?uhK)YQNQ^nJCP=Pudl5I9o)C! z^V%w`zMS9H9mTzE2ne>;y>jF(t#*wON40A*(@jgbg4+H@78Gi1uxO19q`J2am0c)O z>&rs)@Tio%vom#0*nkjS|{=%}-9s?NFz_DHAH<`7#ZIw5=_aff*+vPW>vaHay50Ln!-+}{8WbBXqA_r&XmKl{*x~}0kpCAU)oi)VZiQu|Dd~1jyrS*NsSdlI_3ycR2o6f--mr}FpH{- z5c&5nu+Pa*gem#XSdP>|sDS1aPCK$$Unb(eLd0QB`x6iDJWi;1aiCO+)H=S!(=(M` zd2sPD5!EUnqO(e>D~2geKc?6QBF-sCHSy3PauMT@GNqm%0bI*6hs&j03eQ+md+UvH zof-*P#kcO0;Vc3rxekII>X@OM`tq@8@<@m{60#LWLez|eZhIueV@^`2$y^)g|fl*tdB(tL= z8yO{7tvNer{V2HCk7SCDU5=@~XtX4Y`UOPjq@8qqh#uGuO*Di?AR$?7Tp1k|Sp_p2 z0wobu2)E)SLDR%P{HP+rz*PQLwm+3x?zjlCB;iX#)n`ROF~tEsRaF3~k@VNs-<3Wv z_|`pOUL#a*Vyage^c?D8q~>CPr}&e^;BuRO1%SCjq*FMDy8!w+zY;4Z4t4bLzA98B zKX}7cp-o1rj!u+fzSGbh^nm2J%PSR&H&}CDs7=r zh3>XI)qxx$Y{#Qx@GRVNsi%=vr>G%Qbz&7OiqNksicr0AcO4(7l3P@V;t%_ATWAt# zvu2?5OPbfyvDZ`gI%biTVg%=m5uP&!)t07NEw4MbwKKA*iTa)vUAgQAejTeR9w_<} zX@FH7Piv;}s71TMw6_B>N{W*-PMijNIL5nmY~Q8&{EfIPSEU{|o&S2+hn!O?PQiJ< z4+A5WV0nh^_u+>ObMeSmO@F~Xz6)JrtR~`bsLz~`H+~{BrzL{S0$Mq)&z>+zQ85BI z==@7r5b4qAu!B>5#+xLWQCbZLGxp3xKBwzmEz3y9h%Byei7b@;U{q$&8D|$sN7+S^ z71%|B7Q4v2%la6*$o0yJah-CDgblYyIYuo~wx~sBEVann^z3qjo@B1q`Qkb~Gasx> zeU(2g zjz;7%_s-?+ogL$}Oom6~{79KPZQ&cqB$T#6En6D;kmp9Yn67v1A=fE+$W;w_$d#1C z5N`MetK&o6fEPktGQZJP=(uMr5!3t#amb65tnL^m4v~}P^?J2KDVf-Mfy&BS-}zzR zb_KsR9CW)%4Rwoc3^sFatq}j`Wb^Hu zY<@icpOekshRNo~<0X^L>2pmsSN_k*CjZ?DDyJPQshoIroS<$phBsk(G-+v^D%?*{ zH+5H3H~qmgzxv(;>ZZ=$D0S1071T|aY1h2ePEzJ<{Z&pcY~f2=ePPGau8_Vi>ZYg0 z)lJu_y6H-deXW~d)Y;Lho31jwV5z!k{@bN)IyEx&T*dBCeMlvAXRBcUgu#D7Ibd;qh)D`Pe?Mgce z+oqQ_C+Z#AdA#z!sSrm=7B5wBr^~eaf)8CPJRPb43AZ3;BBz0%!9Wa6jp%!n_ zFex%Aq`}j*YRAp&my$AsM&}N)Ni|5*R`vAfnMLM3?lehROOte?{C@N+(A~TZPIU5n z)0j`{b4I7+)JQik(IOqC(E5c@Ez;Yzt2)SNkq#Q&gi#`$^+uIQ2V6dGHu<={(I6c( zst%h%`L(RPKVG6psUNp0C{5|0N$H4Fr@ZW~s7`s#s8fvgejP_?lI`tSu;Gj2}uYAz%h2~C(0 z1bTpPfb5x4y#P|Z%+w<{Luiz5#IEMR8b<=7gkY1I=8on(QlZ!NDNDQ-*jA=Zj4B9K zZ5skD+#%~C)rp6V&gUR?j?}dnoeP_;P@T(GqjT9|R4y}CGdcBuk_2p@9tuG(>gN{y|)tyQ^j=gfyj&?kq2G-PWTvv zm)X^9c36J7qtl;Hq7}9H@wrkPUg(N9%CZq=OA}{DwHq0F)nP2;$P>tXJL+!Rt+Xh^ zK~erlcTkq^%LXzK$`kd5+Xg+=Ti-scI{T}Ht;rx5pdY%mp1ldMK7hsp0IS{?4fqhJ zv!X#J@~c9xm@`k!&OJ45^9=Ywl~v(BAUBf%NOI0KvJ0Qg^4Gesw@qmOFLM^`u~_Xr zU|T?eW|}xwG@l-%!9DXuKd06SfdE;_IbrnRtZU7|0aA>Y00;*|wZlHfe-B6|ELne= zu)C2~n}oBvP7M70gJPfDM-}TXsfvBKR?&Xs0k0=gC5m(m^L43HUsXi61LVwL#34vw zk6{d4-zdeF7wa44qq(|z(N#%0B2t2~D#u;dnCN%a0+ApdKI#@Yy07?(MVB>LbSA7v z)S0I7rpH=ry4_;arvA8FN=MrU``4*fp+-JdDbPj6>AULGH$o%IsT1AR8*ntFM;n#o zT{1vk`G!#}dPfd&t^k;{Zzf^epEuFXtNh8XLzb=l{0pg{9&)Jv3fiN7E7R&*9kiq$ zK87~Qj69WIjEAEYylLkVxRhI<{+Gk4uIG1xAO%iFM}6sL+DCbt21&7vzqn`5`@0A? zQJDDp>y>v+?Q}29xEE&hh190vWCrF1CO~qE0v_CP?jklh8Wl2pJ{Zea)Z~jSlUTIX z9c5?FWstV*g;Nl7t56x|82!a2O&8LE6hAP-Jlfrh?dLWb*-)rgyRg%!V*Q9J9DL4x zxbk$rjLl5w2ptk_+Ds|_vLQ`Y%YUm5eK_{^(Q6{~8cy($oHVdWsiIwGH^Mo6ztVo{ zLT2fHXpXJFyf5FKjWtKsG)HJF&!BDMDll~yhh|0@@XVT3*);^MfbZqNnwLOi#ba!y z33|-F%8&FnmiFzbMHUAEw@ExrLdaG=55#xOhe&-Sn{kuPpsC-|)o=N_)i3K-J3d>q zuS==r0y|f?`4n7PP_h^MMt=Bqvop1ph$s1BKkcUo`m z4(!1}3z^kCu@jBF-z}(+>YCfs92eDlZ0nHiAv;aDE_PXtRIMEj7^{aH&F}TvL59Pj zDi*gX3dO-86r2QEr$nY(7dKTMh2*!1#rj4uqHoTfx3#a1iSej&X)LGJE}R!@_0v(v zZgrCll!yqHGqM*3M1^WZB{y_>F+w^VLJ3KgTw~xNX^yWa(HSM#nMM6~QQ?`f)DP$) ziIeOsk?IM)aX^cy;Ks3Q)O}TIxCknG60$eI?7+6}AnAv+QF51SkV`Zo6_2YFD6%nS|TW=m34j!3E!17;DCMo&69l(~`9pi=%EyB1JQ|23Sp zMl0V|Jt{tS6(7>}zH*`lQ*xugHJ@|7fp=w!sIaJ{y_4jW-XJk=s^vxUCjXxSDdRxD zQy-FEmgtTf&azbAcL}AUnEUxWy(2oZi;?l$#f00X^He{t4*{)F+6&$hg8~=3=VX2! zFiiG;bF%aGcFA_vyAqe!$bqVWvOFm{Jy+;}oDy;chu0U3j8Zo?M70UZ1DH!Op42VV zP;w3uH?go#$Zw9a{Rf{WYg)KT1>^wn#vYUF55@^R@q{i+ElO? zLvXkmB&i=;%now=Y=U5q&py+ov_ryX z93g^3t95qdlC2>Q={Wc2b)e2_Mu?w-u_acX4x4=?yBg%J&0$A2haIZS-aed){V)uJ z&^DVd&E`lId}V;qEaT{9-0|dB*SSCOHN%x;MV;=dc#HR)+dZ?o<3)@>&%2o3wecIh z&E%1xCk~UA5J+u$3e=#hKB3Gz?CJKC>?WpHw!lj!Z$LwI=#Xn$KUi*qA2b_$&ur*D zv%xo#E31*P8~mm@vZgu0*7EAv&9kYy>}=+8s9!B279+Te$iH~56i59|g%Ty}%s zWHWBE88r1DcJ_hs&>d!y(1bv6S`VZyzQd8X*HKegj~&wc%6#Qo=s5y?ZJf@OFPg^}SvFI2c1!R| zVmhi&X22V<#XIpH61)b6;PwA`4+&m95WHTi^}bhq;9J$7mhX*$<4s+&OE**Da-r$| zd^_DO-Y@H|WMw4X&Pci)qzmPH(^qh!p%^?s=lH;T3}deLl?TT9ib*sdNi^VGTHY6{ z8ZO{rncU49(7}NX<6hAVe6=9=o$UmjpE5YvVWZ|-nw3w|V4{wjyUZGEkgWC@Z+oi) z4SeORx7sxh*u8GRUS$UCwW@a0ruEUZWAB;Abi382J?l}d2<_&(jA{4?oMq)Z)EkIH zcB_9OA%~1Skg!Pp)Lm)yaRlHz_Y%`>7E)h+2twxO!P+2ufKOc z125dqlYCtN^F4HRP7YMzEj*0}L)FQJ2$NR=0tt0sB0a>%U? zvrA-ou=;@P(aw5A98!d#fXigx01c(wuEK74BapV@`t#lu`~_?4hCRJVg%*2dNUHn$ z=UHJgH0;l>zuVYwzJWDVs4}B!P{hKHXI8 zdrOu2v0evEU6sYTx)9W)LaYIdMT2w-Q=h|Oxa*sipQtlNg=v%d1f zsVx?w->zkH`6wUhsHucU-`F}`At`I-(E75sd~}=Pmal!JrrwI9IHRCR6d;8yGz{V& zad3wX@KI>Q9U0}1lt~-ovrv(8W`+)=$k|L)A*O;)WODL24;#&MT4{beZ8W1-W1|_h zY&5r?pN*#BzP_|&qxtD?-bV9}f^U(H=B3)4-OYA*=-q>zl z9{%QR%Z@+>5Ar{e-w zU&Sh((w3EH=&7mhVOx2t?sYnA{l3?N8dlQFdQs{`9_WORt2T&~H8LAD!u&~q3k9_J zJ|CE~GvhF4ihFiWn6vW)JEPIlHw|`nW&+sRS$`R@voj6Y8F0_OrC?{u4mApOW*DNz zpw0|W)VZO~Zq}F75&lur)oz9@qqdnuxt&D63U2&O;+1LrJG?UF(&Cko2SPElddgSm zIk1eCkjUiJotvb_(Z~oDJqd~|GN^qHfXqOVWeP>6I*8W>L#AeSfFV;b>(s0zrYk;Z zYgiw63LFL?V5RqF>um`RY_}k30j!K1k*#-*D7hJrdI*bNJrJ3%KxEuo6CdfD!ytnI zq=i3rnD}G=E(JEkq+A(V>qi;PZNx5ixxzb?yqs`h;_L8I-f+k3HEiX zJdZQ_&-+Mu9=_;_W2o!L7AKqoV_v5OW4OE}+}5Z3x%`#L*e5Fes8*z+%7^6(vDPO$ zW@>TB)f8-NzhhB*4%LUM{Dj2105nj0<_0jL9dw~|q@h{hZp;{%*L90Fqtu<9EWea$ zv%uXl+GXt0*iWA8=rvZR=Q?JoGvwz+|Fwy#kO*8B33PS^>7C!`N$dRsC3^NR@wVum zLbrRc*>R{zf1DJZ^FvMQ8t7t}g9l^Vvuq_)ru6*M$3{@PriFi+(M`J1A26tgpq{l_ z!iT+hyZ1&d(N^srqaSXp+h@nE+dcKcz_gxgrzqGYi)O*uK@5EstANFKlWa)r{jGf# zYd*M0cLBLNiKIrqagGw}E`ehC#5&QAwrF6G!+s&N))3=6i2Pf-gZNhO9`aYadl+=T z`Taxwt=T_J+C40@cgUCQ9cW+-&`d7W##f`SQwVd0g}QY_JnO^Dh49*5kbgV&78W8) zSM}Je>WL{KSnsQ(S=D2r=S^PK8#0U7DmisAcK!aWH;yW5m;Tm!;mYqBL}IAQq%t~_ zmfsZR&sJD|<^Dxf#7n+4oVF*1v%Ui=?&^tz81rU(fx3dNQvRwxKGFh_O!^Imb`?zp ze&Cs083CvKe^qE4R5X_ZWcX#x@NacZ5qx__881+?r8txN*&(2n1Y;W0u%3m7ysS(X zGsiwjay=f0sPqVvvJ*P4nq*hr3 zD#a?>J?P94Ny(@qonq4IvU&tvk-^rR#tXap0qTbavH_%!9#v@+vL=e%7#a8uAYJdm zpWRB00L_!Ekwz%~6dGyach{H{~; zr8Y)WDJ+B2^@UE?m)K^3MOQ>AUx$uXteG&EoKNSv;ST_^pw$y;^#FuI2QxuZjs#j# zQ#UMhcSPHl;J6X1M(2uNhK)j8|EOj^J7;l!HDYn!Z}@@EH~#yq&oRG!pS~TBYR6&f zLB(RLYd0M@GU~?V`ZqjIw4!2bBq95_C2IL4y8A%_VY1rHKw_WltD-sR;da5*=E}M0 zT>I*T7kAU5D=@-ne9ZW06iaOi&i$Dx$e&LA{7~cC*)~rsAhkC8da{=QW^H>=LPcy0 z5~(9lVLr$vygh{F2oFdt0W)y~W;juoZp8#*LMkdJEYNGt01p5Z@zCm=g zQhDt&ybgr8!T06sbezF<8-!Nj0mG3%6Iy_(O2_~Pb}_H~eXwu44eM2SwT1bL%dZ%G z7!`;Q!2Ae#;vn63wT14fy8FP*TowBU>D3Cevk$JIWDyAuSV>w+J1CgJ9H9Fgyc)s- zBx|J&WNBvI0v}kD+7>&Xfi)@FLC7rREHw2egb1RA$E3k6f?YB=s5Ifp6&61xuF&_Cyx; z8nzkrc%c{(DzjNSFrcN8JLSlQJb_zui2gF__segjhI&T5Wqf64gBhh?WmhywCaON< zbmZ%4EOBY+sMWMIrLBNrHjd-=OgSbK-r+>CR=k{Qxw3Xa_u73Xq?2DujQNpPV@JiX znaW-B#z%8Wk}j=LPgyRNtVHY{ARJSNYW{IQy$1J_S(n4RHrE$wAmT8U#+G%~{zQlmMXeqJj1zO#>y_+Ha$n_6@7a&f`KF$)s8 zsA>FCG z$6!yQ5a-fCGE_75orKgUuOi5OWHhCajLNv_U>wmj-cv*UL}`RV%N=x(+(DW~u6R|l z#wo#6f)S8VJ8HBJZnNIl<=3;e+xZTg^VrG8b_}|dGSGBVWdz*@wnF+t`D>}e z^Zf|+_tuvqRKMWp7S;Mj#<6b-dIjvHtzUdaFVMvYmI9rYr2w3| zU@6dPTMBd~&{zs|T9yJ`wFd}*1<19vZ7I-YWSR(cjfsFU9vF!nF0mBoSS}*96v&Kn zAI=VyKHFthAC|+jrO0S;AxYgp47U1aBJ62)%*Rj|G|kWBm{yi!p~)Di1O=)zHi9JZQTUzo6y}z8j-I3 zMfF+)`oxu z4v^k_aOT51c_c`2EG+Mys{LF0)?yUqOfiIQh67JmGMT+#Y&`mEB(L^p9-l7ImMe7@ zA1TE5m&?xspF8Dge&>fK)4u{k8D{Wut%S?!r+*y|;`+RP>fbDS_2CaJ>KfVd(-e?Ts(O>=9f^JkHe4HTQVPqkCac#EG-eB)X772@m$mOQdxxLrF&!NZ+Hc^l9Jw2L z<0xjs<1~8@p^zX>2>j#^)5AU765j6*(gpt>oP=JQzDs7Y>7#P}a(dShxxP@YzY!v| zbB{#ZarDR$?D0N^StD+u+^)n!N)$+YWDVc8fo_10XTX)d2> zE}v>HPY3PlT7=+AzV%Yz8f#IiRK9@ENmo3B7Wjy~bKF6Fk(BBYycpIGfehp9u!!e|k0;1e6}l2d9I9-PrCU22y~~r-DIp6P%QZ14Dv( z-IRpJvltk}L4!dYI1J)IF^G{XxP>wwbyPonR{N(9!cO1reOl-;w)?qW1(1WZ-A!HZ z!;`FeGCOp=6i+&Qg06Nnz}EkHU#S#3#?o8POL_&6abC%JfTsS3LyY+sQa?6O*3o7a zR?K1q!C%`3C);F;2~FsncCN#XgDfDfcfIUN;wmC z6VTHHIriFV_C4LTs!J=Cyjq)jXi2W=DN>74VL^uFscewu>t47#Hxj^orlwbUT|WrR zC{DU*)>*wu_s@za!74z7M3mPUSqyz{zL2V{Y@{Hprd^gDFIm2xvhjMNen*ofyO4aS z=Js{}9M4}U7WC)lD&r3KR=JwaEpG&Th-j248_TU%_llyo+@oAo{GKx7jy&p`kK-fY zVQ2Ve>QxN$G6d#_hV||H?YgTcQu-asc2=qjixY{z4;kGs$-q<@h2`oR<54uoR9Ft` zFb4lH2AxQe)PhtL_ZqbR;m^M(&r6;$yGVC_ZzC8OCSscwNUa+h^Lg$~Qfd&)o4p>QFxG{aqW%?|GF& z8Qf2HDC61)3|`YvmRJ88hca2LmJH?hyiP;;*da5Nj~#klhceq|+P2C!J(NLL_IeKG zdmZ!lBmQ|f=bZJ%OluFHpK0wm4Qr42-wL-JwNf25tUbJ(Th7hSs`l`=+AHUnztpPs zn7`Dj_Lv&|rswp@Ip*tI$7oo4zwtUe21q310CCK3yj@bo@{kz!0igG_n$L!cAKsYH z8q?Vk@0e8Q7@cv{sy4I^I-#-qjnwWpHg><9(eL-09BL0yryMH2AMkY^OGnh=nK7SL zlilu^BTjeB5vRMv5r=)une4hM?6$0S@AF&cx2{T^*{=3dHQTjs`sa8vH;6yd0*`>D zaDweDU1q{1o;RU--bi(N3wIqh{~e;U?)j!Q!3bDaH#P0;(D@G~Q(CadD2?Pev7w;v%jGNG zMm*HKoV63tcpU=)VW~1<$C-?U?dqwM#yQgaqgc{Q&NH4OffKNt7A&@Qh{qWX-L42` zc7AhR{zAw0&KU*wpH(D5m==cE6zRw@F7J_HWmEW~sDUp^m%tY#*SH**Dqq+Y} z?#zTeg`l)%!j2R5cM?)jv>R~{Hq98C!Wu~yeO>D4z#tsjS{slic38d(wotK_+t+eu z*ASg3I$)5=S!{!ON1zF81tJGFWEzDyievnlAR3KmHe48-sMK7g^s?t%2AklY^$Dm1 zjgYZA?&~H%@|0Zz0~kUkNQo6GYvqpcJBg|CkR7hnu27;AQkl+mI;6a81faJ))Y`7{ z?V-jhw}^oNoZFv&IP;@J#*Hp!AeHJdbn6*7;ON|-x^=?tm8w(^B&I6Wt1+c|OcXOk zsoO!FdQ4;=UgXg^+$hnC5?KloF=Nmc3)D3`i_xIRCH9+ zoyV9yeR3kFUqvGRa*3!i{k#&PCU&zy@{FOV^;A*o8AWZP_V|fW)Ot=)>lsCDN)>G~ zs!R8rF5TwPpdbdC!xvpK|B)WhoGLwWU5wQONK9rMEIv|e;hU%8^%tJfLYHWuA zbz6GK_EaHS;hJNII&ZwVKFZfAcLwd!&KQ}KlW_wZ+yM+<(xlpC3X(A(HOIW!Pe*t4$)~QzY*UG*(*HVl=#V>=DTuXW~a z2_EJOBA zc)wno24-y@Zv~l?-9z?`ZPMk<<8AJR(+pX=J$!~2()XU?h4jUOFh5~ zSqJa`u*q#Dr8l{)TyCGYWs#aVtTDCou$LUQ@5)MauX$=7-S^?0JTvd5J%<9?lz&PJ zutoUh)z3@I3N2C`ZdwimnR6hR9PxE2ZLo4_b0aj& za!N>;G$67f&#*sl8qg-l`i9LK z&cK%=t^A1KD2@_@GiqgVLb%Ds