From 1ccfbbb2c393bcccf49a8481bd56ac23aad3b338 Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Wed, 5 Jun 2024 16:06:15 +0200 Subject: [PATCH 1/7] feat: update agent and add log_visibility support --- CHANGELOG.md | 6 +++ Cargo.lock | 28 +++++++----- Cargo.toml | 6 +-- docs/cli-reference/dfx-canister.mdx | 2 + e2e/tests-dfx/create.bash | 2 + e2e/tests-dfx/update_settings.bash | 14 ++++++ src/dfx-core/src/config/model/dfinity.rs | 44 +++++++++++++++++-- src/dfx-core/src/error/dfx_config.rs | 6 +++ src/dfx-core/src/interface/builder.rs | 12 ++--- src/dfx/src/commands/canister/create.rs | 26 +++++++++-- src/dfx/src/commands/canister/delete.rs | 1 + src/dfx/src/commands/canister/status.rs | 7 ++- .../src/commands/canister/update_settings.rs | 22 ++++++++-- src/dfx/src/lib/ic_attributes/mod.rs | 19 ++++++++ src/dfx/src/lib/migrate.rs | 1 + .../operations/canister/create_canister.rs | 4 ++ .../operations/canister/deploy_canisters.rs | 2 + src/dfx/src/util/clap/parsers.rs | 9 ++++ 18 files changed, 178 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f985c8497..a3580554ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,12 @@ different replica version or different replica options. It doesn't apply to `--pocketic` because PocketIC does not yet persist any data. +### feat: `log_visibility` canister setting + +Adds support for the `log_visibility` canister setting, which configures which users are allowed to read a canister's logs. +Valid options are `controllers` and `public`. The setting can be used with the `--log-visibility` flag in `dfx canister create` +and `dfx canister update-settings`, or in `dfx.json` under `canisters[].initialization_values.log_visibility`. + ## Dependencies ### Frontend canister diff --git a/Cargo.lock b/Cargo.lock index 4f5d510735..17a9db84a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1530,7 +1530,7 @@ dependencies = [ "ic-asset", "ic-cdk", "ic-identity-hsm", - "ic-utils 0.35.0", + "ic-utils 0.36.0", "ic-wasm", "icrc-ledger-types", "idl2json", @@ -1605,7 +1605,7 @@ dependencies = [ "humantime-serde", "ic-agent", "ic-identity-hsm", - "ic-utils 0.35.0", + "ic-utils 0.36.0", "k256 0.11.6", "keyring", "lazy_static", @@ -2648,8 +2648,9 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.35.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba85280257d8663adef20bf5c043b287b3a283d4f916073eb3ca9166a4a59d4b" dependencies = [ "async-lock 3.3.0", "backoff", @@ -2700,7 +2701,7 @@ dependencies = [ "globset", "hex", "ic-agent", - "ic-utils 0.35.0", + "ic-utils 0.36.0", "itertools 0.10.5", "json5", "mime", @@ -3087,8 +3088,9 @@ dependencies = [ [[package]] name = "ic-identity-hsm" -version = "0.35.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163ac173f5fc62a4c082ecaa1467efe83fe8534fca9edbeef3895f6a3df9b13b" dependencies = [ "hex", "ic-agent", @@ -3187,8 +3189,9 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.35.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce14c068bd053c0f5ab525326f3f358f265cdfcae279fbf6461fb529e9682acd" dependencies = [ "candid", "hex", @@ -3256,8 +3259,9 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.35.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae2e0da151b7fab7b977fbca381db15da51b0e9af896c97a17de567858df548f" dependencies = [ "async-trait", "candid", @@ -3370,7 +3374,7 @@ dependencies = [ "humantime", "ic-agent", "ic-asset", - "ic-utils 0.35.0", + "ic-utils 0.36.0", "libflate 1.4.0", "num-traits", "pem 1.1.1", diff --git a/Cargo.toml b/Cargo.toml index d28caf354c..8639d025d4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,11 +21,11 @@ license = "Apache-2.0" [workspace.dependencies] candid = "0.10.4" candid_parser = "0.1.4" -ic-agent = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } +ic-agent = "0.36.0" ic-asset = { path = "src/canisters/frontend/ic-asset" } ic-cdk = "0.13.1" -ic-identity-hsm = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } -ic-utils = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } +ic-identity-hsm = "0.36.0" +ic-utils = "0.36.0" aes-gcm = "0.10.3" anyhow = "1.0.56" diff --git a/docs/cli-reference/dfx-canister.mdx b/docs/cli-reference/dfx-canister.mdx index c0a32ef956..44dba24062 100644 --- a/docs/cli-reference/dfx-canister.mdx +++ b/docs/cli-reference/dfx-canister.mdx @@ -255,6 +255,7 @@ 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". | | `--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 | @@ -993,6 +994,7 @@ You can specify the following options for the `dfx canister update-settings` com | `--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". | | `--remove-controller ` | Removes a principal from the list of controllers of the canister. | | `--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/e2e/tests-dfx/create.bash b/e2e/tests-dfx/create.bash index 5ee6abc172..bf4ac69514 100644 --- a/e2e/tests-dfx/create.bash +++ b/e2e/tests-dfx/create.bash @@ -328,6 +328,7 @@ teardown() { "memory_allocation": "2 GiB", "reserved_cycles_limit": 1000000000000, "wasm_memory_limit": "1 GiB", + "log_visibility": "public", }' dfx.json | sponge dfx.json dfx_start assert_command dfx deploy e2e_project_backend --no-wallet @@ -337,4 +338,5 @@ teardown() { 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 'Log visibility: public' } diff --git a/e2e/tests-dfx/update_settings.bash b/e2e/tests-dfx/update_settings.bash index 131f6f7117..7b297a65e9 100644 --- a/e2e/tests-dfx/update_settings.bash +++ b/e2e/tests-dfx/update_settings.bash @@ -61,6 +61,20 @@ teardown() { assert_contains "Canister exceeded its current Wasm memory limit of 8 bytes" } +@test "set log visibility" { + dfx_new + dfx_start + assert_command dfx deploy e2e_project_backend + assert_command dfx canister status e2e_project_backend + 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 + assert_contains "Log visibility: public" + 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 "set controller" { # Create two identities assert_command dfx identity new --storage-mode plaintext alice diff --git a/src/dfx-core/src/config/model/dfinity.rs b/src/dfx-core/src/config/model/dfinity.rs index 199250148f..160f64e0a5 100644 --- a/src/dfx-core/src/config/model/dfinity.rs +++ b/src/dfx-core/src/config/model/dfinity.rs @@ -9,6 +9,7 @@ use crate::error::dfx_config::AddDependenciesError::CanisterCircularDependency; use crate::error::dfx_config::GetCanisterNamesWithDependenciesError::AddDependenciesFailed; use crate::error::dfx_config::GetComputeAllocationError::GetComputeAllocationFailed; use crate::error::dfx_config::GetFreezingThresholdError::GetFreezingThresholdFailed; +use crate::error::dfx_config::GetLogVisibilityError::GetLogVisibilityFailed; use crate::error::dfx_config::GetMemoryAllocationError::GetMemoryAllocationFailed; use crate::error::dfx_config::GetPullCanistersError::PullCanistersSameId; use crate::error::dfx_config::GetRemoteCanisterIdError::GetRemoteCanisterIdFailed; @@ -17,9 +18,9 @@ use crate::error::dfx_config::GetSpecifiedIdError::GetSpecifiedIdFailed; use crate::error::dfx_config::GetWasmMemoryLimitError::GetWasmMemoryLimitFailed; use crate::error::dfx_config::{ AddDependenciesError, GetCanisterConfigError, GetCanisterNamesWithDependenciesError, - GetComputeAllocationError, GetFreezingThresholdError, GetMemoryAllocationError, - GetPullCanistersError, GetRemoteCanisterIdError, GetReservedCyclesLimitError, - GetSpecifiedIdError, GetWasmMemoryLimitError, + GetComputeAllocationError, GetFreezingThresholdError, GetLogVisibilityError, + GetMemoryAllocationError, GetPullCanistersError, GetRemoteCanisterIdError, + GetReservedCyclesLimitError, GetSpecifiedIdError, GetWasmMemoryLimitError, }; use crate::error::load_dfx_config::LoadDfxConfigError; use crate::error::load_dfx_config::LoadDfxConfigError::{ @@ -44,6 +45,7 @@ use crate::json::structure::{PossiblyStr, SerdeVec}; use crate::util::ByteSchema; use byte_unit::Byte; use candid::Principal; +use ic_utils::interfaces::management_canister::LogVisibility; use schemars::JsonSchema; use serde::de::{Error as _, MapAccess, Visitor}; use serde::{Deserialize, Deserializer, Serialize}; @@ -398,6 +400,23 @@ impl CanisterTypeProperties { } } +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "lowercase")] +pub enum CanisterLogVisibility { + #[default] + Controllers, + Public, +} + +impl Into for CanisterLogVisibility { + fn into(self) -> LogVisibility { + match self { + CanisterLogVisibility::Controllers => LogVisibility::Controllers, + CanisterLogVisibility::Public => LogVisibility::Public, + } + } +} + /// # Initial Resource Allocations #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] #[serde(default)] @@ -445,6 +464,13 @@ pub struct InitializationValues { /// Can be specified as an integer, or as an SI unit string (e.g. "4KB", "2 MiB") #[schemars(with = "Option")] pub wasm_memory_limit: Option, + + /// # Log Visibility + /// Specifies who is allowed to read the canister's logs. + /// + /// Can be "public" or "controllers". + #[schemars(with = "Option")] + pub log_visibility: Option, } /// # Declarations Configuration @@ -965,6 +991,18 @@ impl ConfigInterface { .wasm_memory_limit) } + pub fn get_log_visibility( + &self, + canister_name: &str, + ) -> Result, GetLogVisibilityError> { + Ok(self + .get_canister_config(canister_name) + .map_err(|e| GetLogVisibilityFailed(canister_name.to_string(), e))? + .initialization_values + .log_visibility + .map(|visibility| visibility.into())) + } + fn get_canister_config( &self, canister_name: &str, diff --git a/src/dfx-core/src/error/dfx_config.rs b/src/dfx-core/src/error/dfx_config.rs index c52158065b..94244a51b6 100644 --- a/src/dfx-core/src/error/dfx_config.rs +++ b/src/dfx-core/src/error/dfx_config.rs @@ -58,6 +58,12 @@ pub enum GetWasmMemoryLimitError { GetWasmMemoryLimitFailed(String, GetCanisterConfigError), } +#[derive(Error, Debug)] +pub enum GetLogVisibilityError { + #[error("Failed to get log visibility for canister '{0}': {1}")] + GetLogVisibilityFailed(String, GetCanisterConfigError), +} + #[derive(Error, Debug)] pub enum GetPullCanistersError { #[error("Pull dependencies '{0}' and '{1}' have the same canister ID: {2}")] diff --git a/src/dfx-core/src/interface/builder.rs b/src/dfx-core/src/interface/builder.rs index 3182d42212..4c833a2fef 100644 --- a/src/dfx-core/src/interface/builder.rs +++ b/src/dfx-core/src/interface/builder.rs @@ -15,9 +15,7 @@ use crate::{ DfxInterface, }; use ic_agent::{ - agent::http_transport::{ - reqwest_transport::ReqwestHttpReplicaV2Transport, route_provider::RoundRobinRouteProvider, - }, + agent::http_transport::{route_provider::RoundRobinRouteProvider, ReqwestTransport}, Agent, Identity, }; use reqwest::Client; @@ -122,11 +120,9 @@ impl DfxInterfaceBuilder { .use_rustls_tls() .build() .map_err(BuildAgentError::CreateHttpClient)?; - let transport = ReqwestHttpReplicaV2Transport::create_with_client_route( - Arc::new(route_provider), - client, - ) - .map_err(BuildAgentError::CreateTransport)?; + let transport = + ReqwestTransport::create_with_client_route(Arc::new(route_provider), client) + .map_err(BuildAgentError::CreateTransport)?; let agent = Agent::builder() .with_transport(transport) .with_arc_identity(identity) diff --git a/src/dfx/src/commands/canister/create.rs b/src/dfx/src/commands/canister/create.rs index a503d0b4fa..fdf180f2c2 100644 --- a/src/dfx/src/commands/canister/create.rs +++ b/src/dfx/src/commands/canister/create.rs @@ -2,14 +2,14 @@ use crate::lib::deps::get_pull_canisters_in_config; use crate::lib::environment::Environment; use crate::lib::error::{DfxError, DfxResult}; use crate::lib::ic_attributes::{ - get_compute_allocation, get_freezing_threshold, get_memory_allocation, + get_compute_allocation, get_freezing_threshold, get_log_visibility, get_memory_allocation, get_reserved_cycles_limit, get_wasm_memory_limit, CanisterSettings, }; 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, memory_allocation_parser, - reserved_cycles_limit_parser, wasm_memory_limit_parser, + compute_allocation_parser, freezing_threshold_parser, log_visibility_parser, + memory_allocation_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; @@ -20,6 +20,7 @@ use clap::{ArgAction, Parser}; use dfx_core::error::identity::instantiate_identity_from_name::InstantiateIdentityFromNameError::GetIdentityPrincipalFailed; use dfx_core::identity::CallSender; use ic_agent::Identity as _; +use ic_utils::interfaces::management_canister::LogVisibility; use icrc_ledger_types::icrc1::account::Subaccount; use slog::info; @@ -89,6 +90,11 @@ pub struct CanisterCreateOpts { #[arg(long, value_parser = wasm_memory_limit_parser, hide = true)] 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, + /// Performs the call with the user Identity as the Sender of messages. /// Bypasses the Wallet canister. #[arg(long)] @@ -195,6 +201,12 @@ pub async fn exec( Some(canister_name), ) .with_context(|| format!("Failed to read Wasm memory limit of {canister_name}."))?; + let log_visibility = get_log_visibility( + opts.log_visibility, + Some(config_interface), + Some(canister_name), + ) + .with_context(|| format!("Failed to read log visibility of {canister_name}."))?; create_canister( env, canister_name, @@ -210,6 +222,7 @@ pub async fn exec( freezing_threshold, reserved_cycles_limit, wasm_memory_limit, + log_visibility, }, opts.created_at_time, &mut subnet_selection, @@ -271,6 +284,12 @@ pub async fn exec( Some(canister_name), ) .with_context(|| format!("Failed to read Wasm memory limit of {canister_name}."))?; + let log_visibility = get_log_visibility( + opts.log_visibility, + Some(config_interface), + Some(canister_name), + ) + .with_context(|| format!("Failed to read log visibility of {canister_name}."))?; create_canister( env, canister_name, @@ -286,6 +305,7 @@ pub async fn exec( freezing_threshold, reserved_cycles_limit, wasm_memory_limit, + log_visibility, }, opts.created_at_time, &mut subnet_selection, diff --git a/src/dfx/src/commands/canister/delete.rs b/src/dfx/src/commands/canister/delete.rs index 4abbfbca09..bbb22b7c10 100644 --- a/src/dfx/src/commands/canister/delete.rs +++ b/src/dfx/src/commands/canister/delete.rs @@ -193,6 +193,7 @@ async fn delete_canister( freezing_threshold: Some(FreezingThreshold::try_from(0u8).unwrap()), reserved_cycles_limit: None, wasm_memory_limit: None, + log_visibility: None, }; info!(log, "Setting the controller to identity principal."); update_settings(env, canister_id, settings, call_sender).await?; diff --git a/src/dfx/src/commands/canister/status.rs b/src/dfx/src/commands/canister/status.rs index 8d71572999..51f7a929db 100644 --- a/src/dfx/src/commands/canister/status.rs +++ b/src/dfx/src/commands/canister/status.rs @@ -6,6 +6,7 @@ use candid::Principal; use clap::Parser; use dfx_core::identity::CallSender; use fn_error_context::context; +use ic_utils::interfaces::management_canister::LogVisibility; /// Returns the current status of a canister: Running, Stopping, or Stopped. Also carries information like balance, current settings, memory used and everything returned by 'info'. #[derive(Parser)] @@ -50,8 +51,12 @@ async fn canister_status( } else { "Not Set".to_string() }; + let log_visibility = match status.settings.log_visibility { + LogVisibility::Controllers => "controllers", + LogVisibility::Public => "public", + }; - 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}", + 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}", status = status.status, controllers = controllers.join(" "), memory_allocation = status.settings.memory_allocation, diff --git a/src/dfx/src/commands/canister/update_settings.rs b/src/dfx/src/commands/canister/update_settings.rs index c2893072e9..ca969d3d53 100644 --- a/src/dfx/src/commands/canister/update_settings.rs +++ b/src/dfx/src/commands/canister/update_settings.rs @@ -2,14 +2,14 @@ use crate::lib::diagnosis::DiagnosedError; use crate::lib::environment::Environment; use crate::lib::error::{DfxError, DfxResult}; use crate::lib::ic_attributes::{ - get_compute_allocation, get_freezing_threshold, get_memory_allocation, + get_compute_allocation, get_freezing_threshold, get_log_visibility, get_memory_allocation, get_reserved_cycles_limit, get_wasm_memory_limit, CanisterSettings, }; 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, memory_allocation_parser, - reserved_cycles_limit_parser, wasm_memory_limit_parser, + compute_allocation_parser, freezing_threshold_parser, log_visibility_parser, + memory_allocation_parser, reserved_cycles_limit_parser, wasm_memory_limit_parser, }; use anyhow::{bail, Context}; use byte_unit::Byte; @@ -20,6 +20,7 @@ use dfx_core::error::identity::instantiate_identity_from_name::InstantiateIdenti use dfx_core::identity::CallSender; use fn_error_context::context; use ic_agent::identity::Identity; +use ic_utils::interfaces::management_canister::LogVisibility; /// Update one or more of a canister's settings (i.e its controller, compute allocation, or memory allocation.) #[derive(Parser, Debug)] @@ -87,6 +88,11 @@ 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, + /// Freezing thresholds above ~1.5 years require this flag as confirmation. #[arg(long)] confirm_very_long_freezing_threshold: bool, @@ -151,6 +157,8 @@ 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, 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; @@ -184,6 +192,7 @@ pub async fn exec( freezing_threshold, reserved_cycles_limit, wasm_memory_limit, + log_visibility, }; update_settings(env, canister_id, settings, call_sender).await?; display_controller_update(&opts, canister_name_or_id); @@ -231,6 +240,12 @@ pub async fn exec( Some(canister_name), ) .with_context(|| format!("Failed to get Wasm memory limit for {canister_name}."))?; + let log_visibility = get_log_visibility( + opts.log_visibility, + 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; @@ -264,6 +279,7 @@ pub async fn exec( freezing_threshold, reserved_cycles_limit, wasm_memory_limit, + log_visibility, }; update_settings(env, canister_id, settings, call_sender).await?; display_controller_update(&opts, canister_name); diff --git a/src/dfx/src/lib/ic_attributes/mod.rs b/src/dfx/src/lib/ic_attributes/mod.rs index c1b700d7c3..7d93589811 100644 --- a/src/dfx/src/lib/ic_attributes/mod.rs +++ b/src/dfx/src/lib/ic_attributes/mod.rs @@ -7,6 +7,7 @@ use fn_error_context::context; use ic_utils::interfaces::management_canister::{ attributes::{ComputeAllocation, FreezingThreshold, MemoryAllocation, ReservedCyclesLimit}, builders::WasmMemoryLimit, + LogVisibility, }; use num_traits::ToPrimitive; use std::convert::TryFrom; @@ -19,6 +20,7 @@ pub struct CanisterSettings { pub freezing_threshold: Option, pub reserved_cycles_limit: Option, pub wasm_memory_limit: Option, + pub log_visibility: Option, } impl From @@ -47,6 +49,7 @@ impl From .wasm_memory_limit .map(u64::from) .map(candid::Nat::from), + log_visibility: value.log_visibility, } } } @@ -102,6 +105,7 @@ impl TryFrom, + 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), + (None, Some(config_interface), Some(canister_name)) => { + config_interface.get_log_visibility(canister_name)? + } + _ => None, + }; + Ok(log_visibility) +} diff --git a/src/dfx/src/lib/migrate.rs b/src/dfx/src/lib/migrate.rs index c6cea35236..e3042ad8dc 100644 --- a/src/dfx/src/lib/migrate.rs +++ b/src/dfx/src/lib/migrate.rs @@ -122,6 +122,7 @@ async fn migrate_canister( memory_allocation: None, reserved_cycles_limit: None, wasm_memory_limit: None, + log_visibility: None, }, },)), 0, diff --git a/src/dfx/src/lib/operations/canister/create_canister.rs b/src/dfx/src/lib/operations/canister/create_canister.rs index 2c3d3ef952..85364448cf 100644 --- a/src/dfx/src/lib/operations/canister/create_canister.rs +++ b/src/dfx/src/lib/operations/canister/create_canister.rs @@ -218,6 +218,7 @@ async fn create_with_management_canister( .with_optional_freezing_threshold(settings.freezing_threshold) .with_optional_reserved_cycles_limit(settings.reserved_cycles_limit) .with_optional_wasm_memory_limit(settings.wasm_memory_limit) + .with_optional_log_visibility(settings.log_visibility) .call_and_wait() .await; const NEEDS_WALLET: &str = "In order to create a canister on this network, you must use a wallet in order to allocate cycles to the new canister. \ @@ -304,6 +305,9 @@ async fn create_with_wallet( if settings.wasm_memory_limit.is_some() { bail!("Cannot create a canister using a wallet if the wasm_memory_limit is set. Please create with --no-wallet or use dfx canister update-settings instead.") } + if settings.log_visibility.is_some() { + bail!("Cannot create a canister using a wallet if log_visibility is set. Please create with --no-wallet or use dfx canister update-settings instead.") + } match wallet .wallet_create_canister( cycles, diff --git a/src/dfx/src/lib/operations/canister/deploy_canisters.rs b/src/dfx/src/lib/operations/canister/deploy_canisters.rs index e36e477b15..369ba1975f 100644 --- a/src/dfx/src/lib/operations/canister/deploy_canisters.rs +++ b/src/dfx/src/lib/operations/canister/deploy_canisters.rs @@ -259,6 +259,7 @@ async fn register_canisters( ) }, ).transpose()?; + let log_visibility = config_interface.get_log_visibility(canister_name)?; let controllers = None; create_canister( @@ -276,6 +277,7 @@ async fn register_canisters( freezing_threshold, reserved_cycles_limit, wasm_memory_limit, + log_visibility, }, created_at_time, subnet_selection, diff --git a/src/dfx/src/util/clap/parsers.rs b/src/dfx/src/util/clap/parsers.rs index e051f6d81d..443a599e0e 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 ic_utils::interfaces::management_canister::LogVisibility; use icrc_ledger_types::icrc1::account::Subaccount; use rust_decimal::Decimal; use std::{path::PathBuf, str::FromStr}; @@ -128,6 +129,14 @@ pub fn wasm_memory_limit_parser(memory_limit: &str) -> Result { Err("Must be a value between 0..256 TiB inclusive (e.g. `2GiB`).".to_string()) } +pub fn log_visibility_parser(log_visibility: &str) -> Result { + match log_visibility { + "public" => Ok(LogVisibility::Public), + "controllers" => Ok(LogVisibility::Controllers), + _ => Err("Must be `controllers` or `public`.".to_string()), + } +} + pub fn freezing_threshold_parser(freezing_threshold: &str) -> Result { freezing_threshold .parse::() From ddf3e75394d2fd4894bd151d7c4f2f3ca15f625a Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Wed, 5 Jun 2024 16:10:59 +0200 Subject: [PATCH 2/7] update schema --- docs/dfx-json-schema.json | 34 ++++++++++++++++++++++------------ docs/networks-json-schema.json | 1 - 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/docs/dfx-json-schema.json b/docs/dfx-json-schema.json index 1cbf3f3470..4f3c54afba 100644 --- a/docs/dfx-json-schema.json +++ b/docs/dfx-json-schema.json @@ -94,7 +94,7 @@ "integer", "string" ], - "pattern": "^[0-9]+( *([KkMmGgTtPpEeZzYy]i?)?B)?$" + "pattern": "^[0-9]+( *([KkMmGgTtPpEeZzYy]i?)?[Bb])?$" }, "CanisterDeclarationsConfig": { "title": "Declarations Configuration", @@ -136,6 +136,13 @@ } } }, + "CanisterLogVisibility": { + "type": "string", + "enum": [ + "controllers", + "public" + ] + }, "CanisterMetadataSection": { "title": "Canister Metadata Configuration", "description": "Configures a custom metadata section for the canister wasm. dfx uses the first definition of a given name matching the current network, ignoring any of the same name that follow.", @@ -209,7 +216,7 @@ }, "package": { "title": "Package Name", - "description": "Name of the rust package that compiles to this canister's Wasm binary.", + "description": "Name of the rust package that compiles to this canister's Wasm.", "type": "string" }, "type": { @@ -410,6 +417,7 @@ "default": { "compute_allocation": null, "freezing_threshold": null, + "log_visibility": null, "memory_allocation": null, "reserved_cycles_limit": null, "wasm_memory_limit": null @@ -440,7 +448,6 @@ "optimize": { "title": "Optimize Canister Wasm", "description": "Invoke wasm level optimizations after building the canister. Optimization level can be set to \"cycles\" to optimize for cycle usage, \"size\" to optimize for binary size, or any of \"O4, O3, O2, O1, O0, Oz, Os\". Disabled by default. If this option is specified, the `shrink` option will be ignored.", - "default": null, "anyOf": [ { "$ref": "#/definitions/WasmOptLevel" @@ -463,7 +470,6 @@ "pullable": { "title": "Pullable", "description": "Defines required properties so that this canister is ready for `dfx deps pull` by other projects.", - "default": null, "anyOf": [ { "$ref": "#/definitions/Pullable" @@ -476,7 +482,6 @@ "remote": { "title": "Remote Configuration", "description": "Used to mark the canister as 'remote' on certain networks.", - "default": null, "anyOf": [ { "$ref": "#/definitions/ConfigCanistersCanisterRemote" @@ -505,7 +510,6 @@ "tech_stack": { "title": "Tech Stack", "description": "Defines the tech stack used to build this canister.", - "default": null, "anyOf": [ { "$ref": "#/definitions/TechStack" @@ -637,7 +641,6 @@ "nodes": { "title": "Available Nodes", "description": "Addresses of nodes to connect to (in case discovery from seeds is not possible/sufficient).", - "default": null, "type": [ "array", "null" @@ -917,7 +920,6 @@ "compute_allocation": { "title": "Compute Allocation", "description": "Must be a number between 0 and 100, inclusively. It indicates how much compute power should be guaranteed to this canister, expressed as a percentage of the maximum compute power that a single canister can allocate.", - "default": null, "anyOf": [ { "$ref": "#/definitions/PossiblyStr_for_uint64" @@ -930,16 +932,26 @@ "freezing_threshold": { "title": "Freezing Threshold", "description": "Freezing threshould of the canister, measured in seconds. Valid inputs are numbers (seconds) or strings parsable by humantime (e.g. \"15days 2min 2s\").", - "default": null, "type": [ "string", "null" ] }, + "log_visibility": { + "title": "Log Visibility", + "description": "Specifies who is allowed to read the canister's logs.\n\nCan be \"public\" or \"controllers\".", + "anyOf": [ + { + "$ref": "#/definitions/CanisterLogVisibility" + }, + { + "type": "null" + } + ] + }, "memory_allocation": { "title": "Memory Allocation", "description": "Maximum memory (in bytes) this canister is allowed to occupy. Can be specified as an integer, or as an SI unit string (e.g. \"4KB\", \"2 MiB\")", - "default": null, "anyOf": [ { "$ref": "#/definitions/Byte" @@ -952,7 +964,6 @@ "reserved_cycles_limit": { "title": "Reserved Cycles Limit", "description": "Specifies the upper limit of the canister's reserved cycles balance.\n\nReserved cycles are cycles that the system sets aside for future use by the canister. If a subnet's storage exceeds 450 GiB, then every time a canister allocates new storage bytes, the system sets aside some amount of cycles from the main balance of the canister. These reserved cycles will be used to cover future payments for the newly allocated bytes. The reserved cycles are not transferable and the amount of reserved cycles depends on how full the subnet is.\n\nA setting of 0 means that the canister will trap if it tries to allocate new storage while the subnet's memory usage exceeds 450 GiB.", - "default": null, "type": [ "integer", "null" @@ -963,7 +974,6 @@ "wasm_memory_limit": { "title": "Wasm Memory Limit", "description": "Specifies a soft limit (in bytes) on the Wasm memory usage of the canister.\n\nUpdate calls, timers, heartbeats, installs, and post-upgrades fail if the Wasm memory usage exceeds this limit. The main purpose of this setting is to protect against the case when the canister reaches the hard 4GiB limit.\n\nMust be a number of bytes between 0 and 2^48 (i.e. 256 TiB), inclusive. Can be specified as an integer, or as an SI unit string (e.g. \"4KB\", \"2 MiB\")", - "default": null, "anyOf": [ { "$ref": "#/definitions/Byte" diff --git a/docs/networks-json-schema.json b/docs/networks-json-schema.json index dd7a239ef3..31b6802e55 100644 --- a/docs/networks-json-schema.json +++ b/docs/networks-json-schema.json @@ -46,7 +46,6 @@ "nodes": { "title": "Available Nodes", "description": "Addresses of nodes to connect to (in case discovery from seeds is not possible/sufficient).", - "default": null, "type": [ "array", "null" From b4363ba9cae5b5b6e9a70df4caaa34da416242ce Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Wed, 5 Jun 2024 16:20:02 +0200 Subject: [PATCH 3/7] clippy --- src/dfx-core/src/config/model/dfinity.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dfx-core/src/config/model/dfinity.rs b/src/dfx-core/src/config/model/dfinity.rs index 160f64e0a5..1dc43d1ac8 100644 --- a/src/dfx-core/src/config/model/dfinity.rs +++ b/src/dfx-core/src/config/model/dfinity.rs @@ -408,9 +408,9 @@ pub enum CanisterLogVisibility { Public, } -impl Into for CanisterLogVisibility { - fn into(self) -> LogVisibility { - match self { +impl From for LogVisibility { + fn from(value: CanisterLogVisibility) -> Self { + match value { CanisterLogVisibility::Controllers => LogVisibility::Controllers, CanisterLogVisibility::Public => LogVisibility::Public, } From 4fdd46c256d7379b1760a4969c16480a88a7723b Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Thu, 6 Jun 2024 14:19:23 +0200 Subject: [PATCH 4/7] rm .call_and_wait() --- .../ic-asset/src/canister_api/methods/batch.rs | 10 +--------- src/dfx-core/src/canister/mod.rs | 2 -- src/dfx/src/commands/canister/call.rs | 8 ++------ src/dfx/src/commands/canister/delete.rs | 2 -- src/dfx/src/commands/cycles/redeem_faucet_coupon.rs | 1 - src/dfx/src/commands/deps/deploy.rs | 1 - src/dfx/src/commands/ledger/show_subnet_types.rs | 1 - src/dfx/src/commands/quickstart.rs | 1 - src/dfx/src/commands/wallet/mod.rs | 7 +------ src/dfx/src/commands/wallet/redeem_faucet_coupon.rs | 2 -- src/dfx/src/lib/deps/deploy.rs | 1 - src/dfx/src/lib/identity/wallet.rs | 3 --- src/dfx/src/lib/integrations/mod.rs | 1 - src/dfx/src/lib/migrate.rs | 1 - src/dfx/src/lib/named_canister.rs | 2 -- src/dfx/src/lib/operations/canister/create_canister.rs | 2 -- .../src/lib/operations/canister/install_canister.rs | 3 --- src/dfx/src/lib/operations/canister/mod.rs | 2 -- .../src/lib/operations/canister/motoko_playground.rs | 3 --- src/dfx/src/lib/operations/cmc.rs | 3 --- src/dfx/src/lib/operations/cycles_ledger.rs | 6 ------ src/dfx/src/lib/operations/ledger.rs | 1 - 22 files changed, 4 insertions(+), 59 deletions(-) diff --git a/src/canisters/frontend/ic-asset/src/canister_api/methods/batch.rs b/src/canisters/frontend/ic-asset/src/canister_api/methods/batch.rs index db0296f75a..15b30379fd 100644 --- a/src/canisters/frontend/ic-asset/src/canister_api/methods/batch.rs +++ b/src/canisters/frontend/ic-asset/src/canister_api/methods/batch.rs @@ -28,7 +28,6 @@ pub(crate) async fn create_batch(canister: &Canister<'_>) -> Result break Ok(batch_id), @@ -57,13 +56,7 @@ pub(crate) async fn submit_commit_batch( .build(); loop { - match canister - .update(method_name) - .with_arg(&arg) - .build() - .call_and_wait() - .await - { + match canister.update(method_name).with_arg(&arg).build().await { Ok(()) => return Ok(()), Err(agent_err) if !retryable(&agent_err) => { return Err(agent_err); @@ -107,7 +100,6 @@ pub(crate) async fn compute_evidence( .with_arg(arg) .build() .map(|result: (Option,)| (result.0,)) - .call_and_wait() .await { Ok(x) => return Ok(x.0), diff --git a/src/dfx-core/src/canister/mod.rs b/src/dfx-core/src/canister/mod.rs index 5e9cd3fd64..5e386c338c 100644 --- a/src/dfx-core/src/canister/mod.rs +++ b/src/dfx-core/src/canister/mod.rs @@ -68,7 +68,6 @@ YOU WILL LOSE ALL DATA IN THE CANISTER. .with_raw_arg(args.to_vec()) .with_mode(mode); install_builder - .call_and_wait() .await .map_err(CanisterInstallError::InstallWasmError) } @@ -87,7 +86,6 @@ YOU WILL LOSE ALL DATA IN THE CANISTER. Argument::from_candid((install_args,)), 0, ) - .call_and_wait() .await .map_err(CanisterInstallError::InstallWasmError) } diff --git a/src/dfx/src/commands/canister/call.rs b/src/dfx/src/commands/canister/call.rs index a28985e4a3..9c81333fe1 100644 --- a/src/dfx/src/commands/canister/call.rs +++ b/src/dfx/src/commands/canister/call.rs @@ -112,11 +112,8 @@ async fn do_wallet_call(wallet: &WalletCanister<'_>, args: &CallIn) -> DfxResult }; wallet.update("wallet_call").with_arg(args64) }; - let (result,): (Result,) = builder - .build() - .call_and_wait() - .await - .context("Failed wallet call.")?; + let (result,): (Result,) = + builder.build().await.context("Failed wallet call.")?; Ok(result.map_err(|err| anyhow!(err))?.r#return) } @@ -418,7 +415,6 @@ To figure out the id of your wallet, run 'dfx identity get-wallet (--network ic) .update(&canister_id, method_name) .with_effective_canister_id(effective_canister_id) .with_arg(arg_value) - .call_and_wait() .await .context("Failed update call.")?, CallSender::Wallet(wallet_id) => { diff --git a/src/dfx/src/commands/canister/delete.rs b/src/dfx/src/commands/canister/delete.rs index bbb22b7c10..40561168e5 100644 --- a/src/dfx/src/commands/canister/delete.rs +++ b/src/dfx/src/commands/canister/delete.rs @@ -214,7 +214,6 @@ async fn delete_canister( let install_result = install_builder .build() .context("Failed to build InstallCode call.")? - .call_and_wait() .await; if install_result.is_ok() { start_canister(env, canister_id, &CallSender::SelectedId).await?; @@ -253,7 +252,6 @@ async fn delete_canister( Argument::from_candid((opt_principal,)), cycles_to_withdraw, ) - .call_and_wait() .await .context("Failed mint call.") } diff --git a/src/dfx/src/commands/cycles/redeem_faucet_coupon.rs b/src/dfx/src/commands/cycles/redeem_faucet_coupon.rs index fabd98467a..d552bfcdbe 100644 --- a/src/dfx/src/commands/cycles/redeem_faucet_coupon.rs +++ b/src/dfx/src/commands/cycles/redeem_faucet_coupon.rs @@ -60,7 +60,6 @@ pub async fn exec(env: &dyn Environment, opts: RedeemFaucetCouponOpts) -> DfxRes )) .context("Failed to serialize 'redeem_to_cycles_ledger' arguments.")?, ) - .call_and_wait() .await .context("Failed 'redeem_to_cycles_ledger' call.")?; #[derive(CandidType, Deserialize)] diff --git a/src/dfx/src/commands/deps/deploy.rs b/src/dfx/src/commands/deps/deploy.rs index 0a92a21b60..a4f60a244f 100644 --- a/src/dfx/src/commands/deps/deploy.rs +++ b/src/dfx/src/commands/deps/deploy.rs @@ -91,7 +91,6 @@ async fn install_pulled_canister( // always reinstall pulled canister .with_mode(InstallMode::Reinstall) .with_raw_arg(install_args) - .call_and_wait() .await?; Ok(()) } diff --git a/src/dfx/src/commands/ledger/show_subnet_types.rs b/src/dfx/src/commands/ledger/show_subnet_types.rs index 305f164c85..e35d2b8431 100644 --- a/src/dfx/src/commands/ledger/show_subnet_types.rs +++ b/src/dfx/src/commands/ledger/show_subnet_types.rs @@ -31,7 +31,6 @@ pub async fn exec(env: &dyn Environment, opts: ShowSubnetTypesOpts) -> DfxResult GET_SUBNET_TYPES_TO_SUBNETS_METHOD, ) .with_arg(Encode!(&()).context("Failed to encode get_subnet_types_to_subnets arguments.")?) - .call_and_wait() .await .context("get_subnet_types_to_subnets call failed.")?; let result = Decode!(&result, GetSubnetTypesToSubnetsResult) diff --git a/src/dfx/src/commands/quickstart.rs b/src/dfx/src/commands/quickstart.rs index daff1e9aad..20b552f119 100644 --- a/src/dfx/src/commands/quickstart.rs +++ b/src/dfx/src/commands/quickstart.rs @@ -110,7 +110,6 @@ async fn step_import_wallet(env: &dyn Environment, agent: &Agent, ident: &str) - let wasm = wallet_wasm(env.get_logger())?; mgmt.install_code(&id, &wasm) .with_mode(InstallMode::Install) - .call_and_wait() .await?; WalletCanister::create(agent, id).await? }; diff --git a/src/dfx/src/commands/wallet/mod.rs b/src/dfx/src/commands/wallet/mod.rs index bbc2538f4f..8b179faeef 100644 --- a/src/dfx/src/commands/wallet/mod.rs +++ b/src/dfx/src/commands/wallet/mod.rs @@ -108,12 +108,7 @@ where O: for<'de> ArgumentDecoder<'de> + Sync + Send, { let wallet = get_wallet(env).await?; - let out: O = wallet - .update(method) - .with_arg(arg) - .build() - .call_and_wait() - .await?; + let out: O = wallet.update(method).with_arg(arg).build().await?; Ok(out) } diff --git a/src/dfx/src/commands/wallet/redeem_faucet_coupon.rs b/src/dfx/src/commands/wallet/redeem_faucet_coupon.rs index a1d1964794..7396bce030 100644 --- a/src/dfx/src/commands/wallet/redeem_faucet_coupon.rs +++ b/src/dfx/src/commands/wallet/redeem_faucet_coupon.rs @@ -59,7 +59,6 @@ pub async fn exec(env: &dyn Environment, opts: RedeemFaucetCouponOpts) -> DfxRes encode_args((opts.coupon_code.clone(), wallet_principal)) .context("Failed to serialize redeem_to_wallet arguments.")?, ) - .call_and_wait() .await .context("Failed redeem_to_wallet call.")?; let redeemed_cycles = @@ -87,7 +86,6 @@ pub async fn exec(env: &dyn Environment, opts: RedeemFaucetCouponOpts) -> DfxRes encode_args((opts.coupon_code.clone(),)) .context("Failed to serialize 'redeem' arguments.")?, ) - .call_and_wait() .await .context("Failed 'redeem' call.")?; let new_wallet_address = diff --git a/src/dfx/src/lib/deps/deploy.rs b/src/dfx/src/lib/deps/deploy.rs index 876b709954..52c0f8c413 100644 --- a/src/dfx/src/lib/deps/deploy.rs +++ b/src/dfx/src/lib/deps/deploy.rs @@ -27,7 +27,6 @@ pub async fn try_create_canister( info!(logger, "Creating canister: {canister_prompt}"); mgr.create_canister() .as_provisional_create_with_specified_id(*canister_id) - .call_and_wait() .await?; Ok(()) } diff --git a/src/dfx/src/lib/identity/wallet.rs b/src/dfx/src/lib/identity/wallet.rs index 5408268720..7387268b60 100644 --- a/src/dfx/src/lib/identity/wallet.rs +++ b/src/dfx/src/lib/identity/wallet.rs @@ -113,7 +113,6 @@ pub async fn create_wallet( mgr.create_canister() .as_provisional_create_with_amount(None) .with_effective_canister_id(env.get_effective_canister_id()) - .call_and_wait() .await .context("Failed create canister call.")? .0 @@ -123,7 +122,6 @@ pub async fn create_wallet( match mgr .install_code(&canister_id, wasm.as_slice()) .with_mode(InstallMode::Install) - .call_and_wait() .await { Err(AgentError::CertifiedReject(RejectResponse { @@ -143,7 +141,6 @@ pub async fn create_wallet( wallet .wallet_store_wallet_wasm(wasm) - .call_and_wait() .await .context("Failed to store wallet wasm.")?; diff --git a/src/dfx/src/lib/integrations/mod.rs b/src/dfx/src/lib/integrations/mod.rs index 0edc4c77ae..27baa0eafc 100644 --- a/src/dfx/src/lib/integrations/mod.rs +++ b/src/dfx/src/lib/integrations/mod.rs @@ -68,7 +68,6 @@ async fn install_canister( // always reinstall pulled canister .with_mode(InstallMode::Reinstall) .with_raw_arg(install_args) - .call_and_wait() .await?; Ok(()) } diff --git a/src/dfx/src/lib/migrate.rs b/src/dfx/src/lib/migrate.rs index e3042ad8dc..94c31fa2c6 100644 --- a/src/dfx/src/lib/migrate.rs +++ b/src/dfx/src/lib/migrate.rs @@ -127,7 +127,6 @@ async fn migrate_canister( },)), 0, ) - .call_and_wait() .await .context("Could not update canister settings")?; } else { diff --git a/src/dfx/src/lib/named_canister.rs b/src/dfx/src/lib/named_canister.rs index 5161fd8d40..1dfdf7fc3b 100644 --- a/src/dfx/src/lib/named_canister.rs +++ b/src/dfx/src/lib/named_canister.rs @@ -61,7 +61,6 @@ pub async fn install_ui_canister( mgr.create_canister() .as_provisional_create_with_amount(None) .with_effective_canister_id(env.get_effective_canister_id()) - .call_and_wait() .await .context("Create canister call failed.")? .0 @@ -69,7 +68,6 @@ pub async fn install_ui_canister( }; mgr.install_code(&canister_id, wasm.as_slice()) .with_mode(InstallMode::Install) - .call_and_wait() .await .context("Install wasm call failed.")?; id_store.add(UI_CANISTER, &canister_id.to_text(), None)?; diff --git a/src/dfx/src/lib/operations/canister/create_canister.rs b/src/dfx/src/lib/operations/canister/create_canister.rs index 85364448cf..2a22516b25 100644 --- a/src/dfx/src/lib/operations/canister/create_canister.rs +++ b/src/dfx/src/lib/operations/canister/create_canister.rs @@ -219,7 +219,6 @@ async fn create_with_management_canister( .with_optional_reserved_cycles_limit(settings.reserved_cycles_limit) .with_optional_wasm_memory_limit(settings.wasm_memory_limit) .with_optional_log_visibility(settings.log_visibility) - .call_and_wait() .await; const NEEDS_WALLET: &str = "In order to create a canister on this network, you must use a wallet in order to allocate cycles to the new canister. \ To do this, remove the --no-wallet argument and try again. It is also possible to create a canister on this network \ @@ -286,7 +285,6 @@ async fn create_with_wallet( },)), cycles, ) - .call_and_wait() .await; match call_result { Ok((Ok(canister_id),)) => Ok(canister_id), diff --git a/src/dfx/src/lib/operations/canister/install_canister.rs b/src/dfx/src/lib/operations/canister/install_canister.rs index 3d3ff2a0e1..a5a32a5eaf 100644 --- a/src/dfx/src/lib/operations/canister/install_canister.rs +++ b/src/dfx/src/lib/operations/canister/install_canister.rs @@ -247,7 +247,6 @@ The command line value will be used.", Argument::from_candid((self_id,)), 0, ) - .call_and_wait() .await .context("Failed to authorize your principal with the canister. You can still control the canister by using your wallet with the --wallet flag.")?; }; @@ -482,14 +481,12 @@ pub async fn install_wallet( let wasm = wallet_wasm(env.get_logger())?; mgmt.install_code(&id, &wasm) .with_mode(mode) - .call_and_wait() .await .context("Failed to install wallet wasm.")?; wait_for_module_hash(env, agent, id, None, &Sha256::digest(&wasm)).await?; let wallet = build_wallet_canister(id, agent).await?; wallet .wallet_store_wallet_wasm(wasm) - .call_and_wait() .await .context("Failed to store wallet wasm in container.")?; Ok(()) diff --git a/src/dfx/src/lib/operations/canister/mod.rs b/src/dfx/src/lib/operations/canister/mod.rs index 9f455c790a..98548a77f5 100644 --- a/src/dfx/src/lib/operations/canister/mod.rs +++ b/src/dfx/src/lib/operations/canister/mod.rs @@ -55,7 +55,6 @@ where .with_arg(arg) .with_effective_canister_id(destination_canister) .build() - .call_and_wait() .await .context("Update call (without wallet) failed.")? } @@ -68,7 +67,6 @@ where Argument::from_candid((arg,)), cycles, ) - .call_and_wait() .await .context("Update call using wallet failed.")?; out diff --git a/src/dfx/src/lib/operations/canister/motoko_playground.rs b/src/dfx/src/lib/operations/canister/motoko_playground.rs index 41b0e5435d..c5da4ffc9d 100644 --- a/src/dfx/src/lib/operations/canister/motoko_playground.rs +++ b/src/dfx/src/lib/operations/canister/motoko_playground.rs @@ -122,7 +122,6 @@ pub async fn reserve_canister_with_playground( let result = agent .update(&playground_canister, "getCanisterId") .with_arg(get_can_arg) - .call_and_wait() .await .context("Failed to reserve canister at the playground.")?; let reserved_canister = Decode!(&result, CanisterInfo)?; @@ -167,7 +166,6 @@ pub async fn authorize_asset_uploader( let _ = agent .update(&playground_canister, "callForward") .with_arg(call_arg) - .call_and_wait() .await .context("Failed to call playground.")?; Ok(()) @@ -206,7 +204,6 @@ pub async fn playground_install_code( let result = agent .update(&playground_canister, "installCode") .with_arg(encoded_arg.as_slice()) - .call_and_wait() .await .context("install failed")?; let out = Decode!(&result, CanisterInfo)?; diff --git a/src/dfx/src/lib/operations/cmc.rs b/src/dfx/src/lib/operations/cmc.rs index 2242907b12..c91233d038 100644 --- a/src/dfx/src/lib/operations/cmc.rs +++ b/src/dfx/src/lib/operations/cmc.rs @@ -67,7 +67,6 @@ pub async fn notify_create( }) .map_err(NotifyCreateCanisterError::EncodeArguments)?, ) - .call_and_wait() .await .map_err(NotifyCreateCanisterError::Call)?; Decode!(&result, NotifyCreateCanisterResult) @@ -89,7 +88,6 @@ pub async fn notify_top_up( }) .map_err(NotifyTopUpError::EncodeArguments)?, ) - .call_and_wait() .await .map_err(NotifyTopUpError::Call)?; Decode!(&result, NotifyTopUpResult) @@ -113,7 +111,6 @@ pub async fn notify_mint_cycles( }) .map_err(NotifyMintCyclesError::EncodeArguments)?, ) - .call_and_wait() .await .map_err(NotifyMintCyclesError::Call)?; Decode!(&result, NotifyMintCyclesResult) diff --git a/src/dfx/src/lib/operations/cycles_ledger.rs b/src/dfx/src/lib/operations/cycles_ledger.rs index 02075b78fd..9ad5f2f6c7 100644 --- a/src/dfx/src/lib/operations/cycles_ledger.rs +++ b/src/dfx/src/lib/operations/cycles_ledger.rs @@ -111,7 +111,6 @@ pub async fn transfer( .with_arg(arg) .build() .map(|result: (Result,)| (result.0,)) - .call_and_wait() .await .map(|(result,)| result) { @@ -170,7 +169,6 @@ pub async fn transfer_from( .with_arg(arg) .build() .map(|result: (Result,)| (result.0,)) - .call_and_wait() .await .map(|(result,)| result) { @@ -234,7 +232,6 @@ pub async fn approve( .with_arg(arg) .build() .map(|result: (Result,)| (result.0,)) - .call_and_wait() .await .map(|(result,)| result) { @@ -283,7 +280,6 @@ pub async fn withdraw( .with_arg(arg) .build() .map(|result: (Result,)| (result.0,)) - .call_and_wait() .await .map(|(result,)| result) { @@ -355,7 +351,6 @@ pub async fn create_with_cycles_ledger( match agent .update(&CYCLES_LEDGER_CANISTER_ID, CREATE_CANISTER_METHOD) .with_arg(arg.clone()) - .call_and_wait() .await { Ok(result) => break result, @@ -409,7 +404,6 @@ pub async fn wallet_deposit_to_cycles_ledger( Argument::from_candid((DepositArg { to, memo: None },)), cycles_to_withdraw, ) - .call_and_wait() .await .context("Failed deposit call.") } diff --git a/src/dfx/src/lib/operations/ledger.rs b/src/dfx/src/lib/operations/ledger.rs index a79ab4c6bc..d48047ea66 100644 --- a/src/dfx/src/lib/operations/ledger.rs +++ b/src/dfx/src/lib/operations/ledger.rs @@ -131,7 +131,6 @@ pub async fn transfer( }) .context("Failed to encode arguments.")?, ) - .call_and_wait() .await { Ok(data) => { From db691cb5b7a24749ef63a948ec067429c5e0df9b Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Thu, 6 Jun 2024 14:25:18 +0200 Subject: [PATCH 5/7] clippy --- src/dfx/src/commands/canister/delete.rs | 1 - src/dfx/src/lib/identity/wallet.rs | 1 - src/dfx/src/lib/operations/canister/install_canister.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/src/dfx/src/commands/canister/delete.rs b/src/dfx/src/commands/canister/delete.rs index 40561168e5..065b71bb2e 100644 --- a/src/dfx/src/commands/canister/delete.rs +++ b/src/dfx/src/commands/canister/delete.rs @@ -20,7 +20,6 @@ use dfx_core::canister::build_wallet_canister; use dfx_core::cli::ask_for_consent; use dfx_core::identity::CallSender; use fn_error_context::context; -use ic_utils::call::AsyncCall; use ic_utils::interfaces::management_canister::attributes::FreezingThreshold; use ic_utils::interfaces::management_canister::builders::InstallMode; use ic_utils::interfaces::management_canister::CanisterStatus; diff --git a/src/dfx/src/lib/identity/wallet.rs b/src/dfx/src/lib/identity/wallet.rs index 7387268b60..a71a221622 100644 --- a/src/dfx/src/lib/identity/wallet.rs +++ b/src/dfx/src/lib/identity/wallet.rs @@ -16,7 +16,6 @@ use dfx_core::identity::{Identity, WalletGlobalConfig, WalletNetworkMap, WALLET_ use dfx_core::json::save_json_file; use ic_agent::agent::{RejectCode, RejectResponse}; use ic_agent::AgentError; -use ic_utils::call::AsyncCall; use ic_utils::interfaces::management_canister::builders::InstallMode; use ic_utils::interfaces::{ManagementCanister, WalletCanister}; use slog::info; diff --git a/src/dfx/src/lib/operations/canister/install_canister.rs b/src/dfx/src/lib/operations/canister/install_canister.rs index a5a32a5eaf..2f68de8b27 100644 --- a/src/dfx/src/lib/operations/canister/install_canister.rs +++ b/src/dfx/src/lib/operations/canister/install_canister.rs @@ -21,7 +21,6 @@ use dfx_core::config::model::network_descriptor::NetworkDescriptor; use dfx_core::identity::CallSender; use fn_error_context::context; use ic_agent::Agent; -use ic_utils::call::AsyncCall; use ic_utils::interfaces::management_canister::builders::InstallMode; use ic_utils::interfaces::ManagementCanister; use ic_utils::Argument; From 2e6f784e7524a98d69042598edce37fd76afc19f Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Fri, 7 Jun 2024 10:49:37 +0200 Subject: [PATCH 6/7] address feedback --- e2e/tests-dfx/create.bash | 12 ++++++++++++ src/dfx-core/src/error/dfx_config.rs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/e2e/tests-dfx/create.bash b/e2e/tests-dfx/create.bash index bf4ac69514..4e18650e38 100644 --- a/e2e/tests-dfx/create.bash +++ b/e2e/tests-dfx/create.bash @@ -340,3 +340,15 @@ teardown() { assert_contains 'Freezing threshold: 604_800' assert_contains 'Log visibility: public' } + +@test "create with default settings" { + dfx_start + assert_command dfx deploy e2e_project_backend + assert_command dfx canister status e2e_project_backend + assert_contains 'Memory allocation: 0' + assert_contains 'Compute allocation: 0' + assert_contains 'Reserved cycles limit: 5_000_000_000_000' + assert_contains 'Wasm memory limit: 0' + assert_contains 'Freezing threshold: 2_592_000' + assert_contains 'Log visibility: controllers' +} diff --git a/src/dfx-core/src/error/dfx_config.rs b/src/dfx-core/src/error/dfx_config.rs index 94244a51b6..3189c0adcb 100644 --- a/src/dfx-core/src/error/dfx_config.rs +++ b/src/dfx-core/src/error/dfx_config.rs @@ -60,7 +60,7 @@ pub enum GetWasmMemoryLimitError { #[derive(Error, Debug)] pub enum GetLogVisibilityError { - #[error("Failed to get log visibility for canister '{0}': {1}")] + #[error("Failed to get log visibility for canister '{0}'")] GetLogVisibilityFailed(String, GetCanisterConfigError), } From caf6b15009ddad9b7e1dd98c7cee9b27abc1d52b Mon Sep 17 00:00:00 2001 From: Severin Siffert Date: Mon, 10 Jun 2024 10:44:40 +0200 Subject: [PATCH 7/7] Update src/dfx-core/src/error/dfx_config.rs Co-authored-by: Eric Swanson <64809312+ericswanson-dfinity@users.noreply.github.com> --- src/dfx-core/src/error/dfx_config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dfx-core/src/error/dfx_config.rs b/src/dfx-core/src/error/dfx_config.rs index 871a69412f..fa2e59c051 100644 --- a/src/dfx-core/src/error/dfx_config.rs +++ b/src/dfx-core/src/error/dfx_config.rs @@ -61,7 +61,7 @@ pub enum GetWasmMemoryLimitError { #[derive(Error, Debug)] pub enum GetLogVisibilityError { #[error("Failed to get log visibility for canister '{0}'")] - GetLogVisibilityFailed(String, GetCanisterConfigError), + GetLogVisibilityFailed(String, #[source] GetCanisterConfigError), } #[derive(Error, Debug)]