From 58c293d307a4d0f1a8d47a3bc18e7e1966d2a7ba Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Wed, 14 Aug 2024 13:15:17 +0200 Subject: [PATCH 01/12] adding defaults --- Cargo.toml | 3 +- src/dfx-core/Cargo.toml | 4 +++ src/dfx-core/src/build.rs | 35 +++++++++++++++++++ .../src/config/model/canister_id_store.rs | 14 ++++++-- src/dfx/src/lib/operations/canister/mod.rs | 5 +++ 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 src/dfx-core/src/build.rs diff --git a/Cargo.toml b/Cargo.toml index c15e5e5881..4e7b67fd38 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ pem = "1.0.2" proptest = "1.0.0" reqwest = { version = "0.12.4", default-features = false, features = [ "rustls-tls", + "blocking", ] } ring = "0.16.11" schemars = "0.8" @@ -72,7 +73,7 @@ tempfile = "3.3.0" thiserror = "1.0.24" time = "0.3.9" tokio = "1.35" -url = { version="2.1.0", features=["serde"] } +url = { version = "2.1.0", features = ["serde"] } walkdir = "2.3.2" [profile.release] diff --git a/src/dfx-core/Cargo.toml b/src/dfx-core/Cargo.toml index 008b3c11ee..8749ea29d0 100644 --- a/src/dfx-core/Cargo.toml +++ b/src/dfx-core/Cargo.toml @@ -6,6 +6,10 @@ edition.workspace = true repository.workspace = true license.workspace = true rust-version.workspace = true +build = "src/build.rs" + +[build-dependencies] +reqwest.workspace = true [dependencies] aes-gcm.workspace = true diff --git a/src/dfx-core/src/build.rs b/src/dfx-core/src/build.rs new file mode 100644 index 0000000000..55417348f6 --- /dev/null +++ b/src/dfx-core/src/build.rs @@ -0,0 +1,35 @@ +use std::{env, fs::File, io::Write, path::Path}; + +const CANISTER_IDS_URL: &str = "https://raw.githubusercontent.com/dfinity/ic/1402bf35308ec9bd87356c26f7c430f49b49423a/rs/nns/canister_ids.json"; +fn define_well_known_canisters() { + let well_known_canisters = reqwest::blocking::get(CANISTER_IDS_URL) + .unwrap() + .error_for_status() + .unwrap() + .text() + .unwrap(); + + let out_dir = env::var("OUT_DIR").unwrap(); + let loader_path = Path::new(&out_dir).join("well_known_canisters.rs"); + let mut f = File::create(loader_path).unwrap(); + f.write_all( + format!( + " +const WELL_KNOWN_CANISTERS: &str = r#\" +{} +\"#; + +pub fn map_wellknown_canisters() -> CanisterIds {{ + serde_json::from_str(WELL_KNOWN_CANISTERS).unwrap_or(CanisterIds::new()) +}} +", + well_known_canisters.replace("mainnet", "ic") + ) + .as_bytes(), + ) + .unwrap() +} + +fn main() { + define_well_known_canisters(); +} diff --git a/src/dfx-core/src/config/model/canister_id_store.rs b/src/dfx-core/src/config/model/canister_id_store.rs index 4053497c1c..e7862714d4 100644 --- a/src/dfx-core/src/config/model/canister_id_store.rs +++ b/src/dfx-core/src/config/model/canister_id_store.rs @@ -17,6 +17,8 @@ use std::time::{Duration, SystemTime}; use time::format_description::well_known::Rfc3339; use time::OffsetDateTime; +include!(concat!(env!("OUT_DIR"), "/well_known_canisters.rs")); + pub type CanisterName = String; pub type NetworkName = String; pub type CanisterIdString = String; @@ -152,7 +154,7 @@ impl CanisterIdStore { }; let ids = match &canister_ids_path { Some(path) if path.is_file() => crate::json::load_json_file(path)?, - _ => CanisterIds::new(), + _ => map_wellknown_canisters(), }; let acquisition_timestamps = match &canister_timestamps_path { Some(path) if path.is_file() => crate::json::load_json_file(path)?, @@ -179,6 +181,10 @@ impl CanisterIdStore { Ok(store) } + pub fn get_ids(&self) -> &CanisterIds { + &self.ids + } + pub fn get_timestamp(&self, canister_name: &str) -> Option<&AcquisitionDateTime> { self.acquisition_timestamps .get(canister_name) @@ -245,7 +251,7 @@ impl CanisterIdStore { self.remote_ids .as_ref() .and_then(|remote_ids| self.find_in(canister_name, remote_ids)) - .or_else(|| self.find_in(canister_name, &self.ids)) + .or_else(|| self.find_in_ids(canister_name)) .or_else(|| self.pull_ids.get(canister_name).copied()) } pub fn get_name_id_map(&self) -> BTreeMap { @@ -293,6 +299,10 @@ impl CanisterIdStore { .and_then(|s| CanisterId::from_text(s).ok()) } + pub fn find_in_ids(&self, canister_name: &str) -> Option { + self.find_in(canister_name, &self.ids) + } + pub fn get(&self, canister_name: &str) -> Result { self.find(canister_name).ok_or_else(|| { let network = if self.network_descriptor.name == "local" { diff --git a/src/dfx/src/lib/operations/canister/mod.rs b/src/dfx/src/lib/operations/canister/mod.rs index 501dc9284d..ba65deae84 100644 --- a/src/dfx/src/lib/operations/canister/mod.rs +++ b/src/dfx/src/lib/operations/canister/mod.rs @@ -363,6 +363,11 @@ pub fn get_canister_id_and_candid_path( return Ok((id, None)); } } else { + if env.get_network_descriptor().is_ic { + if let Some(id) = canister_id_store.find_in_ids(canister) { + return Ok((id, None)); + } + } (canister.to_string(), canister_id_store.get(canister)?) }; let config = env.get_config_or_anyhow()?; From 158ccc435cc8a338d3b349215e4b63e6f6812ae4 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Wed, 14 Aug 2024 14:45:59 +0200 Subject: [PATCH 02/12] adapt logic for sign --- .../src/config/model/canister_id_store.rs | 21 ++++++++++++------- src/dfx/src/commands/canister/sign.rs | 17 ++++++++++++--- src/dfx/src/lib/operations/canister/mod.rs | 13 +++++++----- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/dfx-core/src/config/model/canister_id_store.rs b/src/dfx-core/src/config/model/canister_id_store.rs index e7862714d4..db8d55af59 100644 --- a/src/dfx-core/src/config/model/canister_id_store.rs +++ b/src/dfx-core/src/config/model/canister_id_store.rs @@ -96,6 +96,8 @@ pub struct CanisterIdStore { // which does not include remote canister ids ids: CanisterIds, + well_known_ids: CanisterIds, + // Only canisters that will time out at some point have their timestamp of acquisition saved acquisition_timestamps: CanisterTimestamps, @@ -154,7 +156,7 @@ impl CanisterIdStore { }; let ids = match &canister_ids_path { Some(path) if path.is_file() => crate::json::load_json_file(path)?, - _ => map_wellknown_canisters(), + _ => CanisterIds::new(), }; let acquisition_timestamps = match &canister_timestamps_path { Some(path) if path.is_file() => crate::json::load_json_file(path)?, @@ -168,6 +170,7 @@ impl CanisterIdStore { acquisition_timestamps, remote_ids, pull_ids, + well_known_ids: map_wellknown_canisters(), }; if let NetworkTypeDescriptor::Playground { @@ -181,10 +184,6 @@ impl CanisterIdStore { Ok(store) } - pub fn get_ids(&self) -> &CanisterIds { - &self.ids - } - pub fn get_timestamp(&self, canister_name: &str) -> Option<&AcquisitionDateTime> { self.acquisition_timestamps .get(canister_name) @@ -195,6 +194,7 @@ impl CanisterIdStore { self.remote_ids .as_ref() .and_then(|remote_ids| self.get_name_in(canister_id, remote_ids)) + .or_else(|| self.get_name_in(canister_id, &self.well_known_ids)) .or_else(|| self.get_name_in_project(canister_id)) .or_else(|| self.get_name_in_pull_ids(canister_id)) } @@ -251,7 +251,8 @@ impl CanisterIdStore { self.remote_ids .as_ref() .and_then(|remote_ids| self.find_in(canister_name, remote_ids)) - .or_else(|| self.find_in_ids(canister_name)) + .or_else(|| self.find_in(canister_name, &self.ids)) + .or_else(|| self.find_in(canister_name, &self.well_known_ids)) .or_else(|| self.pull_ids.get(canister_name).copied()) } pub fn get_name_id_map(&self) -> BTreeMap { @@ -299,8 +300,12 @@ impl CanisterIdStore { .and_then(|s| CanisterId::from_text(s).ok()) } - pub fn find_in_ids(&self, canister_name: &str) -> Option { - self.find_in(canister_name, &self.ids) + pub fn is_well_known(&self, canister_id: &CanisterId) -> bool { + let canister_str = canister_id.to_string(); + self.well_known_ids + .values() + .find(|val| val.values().find(|k| &&canister_str == k).is_some()) + .is_some() } pub fn get(&self, canister_name: &str) -> Result { diff --git a/src/dfx/src/commands/canister/sign.rs b/src/dfx/src/commands/canister/sign.rs index 4bcf45e453..5fe1af4559 100644 --- a/src/dfx/src/commands/canister/sign.rs +++ b/src/dfx/src/commands/canister/sign.rs @@ -2,10 +2,11 @@ use crate::commands::canister::call::get_effective_canister_id; use crate::lib::environment::Environment; use crate::lib::error::DfxResult; use crate::lib::operations::canister::get_canister_id_and_candid_path; +use crate::lib::root_key::fetch_root_key_if_needed; use crate::lib::sign::sign_transport::SignTransport; use crate::lib::sign::signed_message::SignedMessageV1; use crate::util::clap::argument_from_cli::ArgumentFromCliPositionalOpt; -use crate::util::{blob_from_arguments, get_candid_type}; +use crate::util::{blob_from_arguments, fetch_remote_did_file, get_candid_type}; use anyhow::{anyhow, bail, Context}; use candid::Principal; use candid_parser::utils::CandidSource; @@ -75,6 +76,9 @@ pub async fn exec( opts: CanisterSignOpts, call_sender: &CallSender, ) -> DfxResult { + let agent = env.get_agent(); + fetch_root_key_if_needed(env).await?; + let log = env.get_logger(); if *call_sender != CallSender::SelectedId { bail!("`sign` currently doesn't support proxying through the wallet canister, please use `dfx canister sign --no-wallet ...`."); @@ -85,8 +89,15 @@ pub async fn exec( let (canister_id, maybe_candid_path) = get_canister_id_and_candid_path(env, opts.canister_name.as_str())?; - let method_type = - maybe_candid_path.and_then(|path| get_candid_type(CandidSource::File(&path), method_name)); + let method_type = match maybe_candid_path + .and_then(|path| get_candid_type(CandidSource::File(&path), method_name)) + { + Some(mt) => Some(mt), + None => fetch_remote_did_file(&agent, canister_id) + .await + .and_then(|did| get_candid_type(CandidSource::Text(&did), method_name)), + }; + let is_query_method = method_type.as_ref().map(|(_, f)| f.is_query()); let (argument_from_cli, argument_type) = opts.argument_from_cli.get_argument_and_type()?; diff --git a/src/dfx/src/lib/operations/canister/mod.rs b/src/dfx/src/lib/operations/canister/mod.rs index ba65deae84..e5831300a8 100644 --- a/src/dfx/src/lib/operations/canister/mod.rs +++ b/src/dfx/src/lib/operations/canister/mod.rs @@ -357,18 +357,21 @@ pub fn get_canister_id_and_candid_path( ) -> DfxResult<(CanisterId, Option)> { let canister_id_store = env.get_canister_id_store()?; let (canister_name, canister_id) = if let Ok(id) = Principal::from_text(canister) { + if canister_id_store.is_well_known(&id) { + return Ok((id, None)); + } + if let Some(canister_name) = canister_id_store.get_name(canister) { (canister_name.to_string(), id) } else { return Ok((id, None)); } } else { - if env.get_network_descriptor().is_ic { - if let Some(id) = canister_id_store.find_in_ids(canister) { - return Ok((id, None)); - } + let canister_id = canister_id_store.get(canister)?; + if canister_id_store.is_well_known(&canister_id) { + return Ok((canister_id, None)); } - (canister.to_string(), canister_id_store.get(canister)?) + (canister.to_string(), canister_id) }; let config = env.get_config_or_anyhow()?; let candid_path = match CanisterInfo::load(&config, &canister_name, Some(canister_id)) { From 20dca9fa19625b25d148ddd2ee300eb216f0c851 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Wed, 14 Aug 2024 14:55:26 +0200 Subject: [PATCH 03/12] linting --- src/dfx-core/src/config/model/canister_id_store.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dfx-core/src/config/model/canister_id_store.rs b/src/dfx-core/src/config/model/canister_id_store.rs index db8d55af59..07b4b7883f 100644 --- a/src/dfx-core/src/config/model/canister_id_store.rs +++ b/src/dfx-core/src/config/model/canister_id_store.rs @@ -304,8 +304,7 @@ impl CanisterIdStore { let canister_str = canister_id.to_string(); self.well_known_ids .values() - .find(|val| val.values().find(|k| &&canister_str == k).is_some()) - .is_some() + .any(|val| val.values().any(|k| &canister_str == k)) } pub fn get(&self, canister_name: &str) -> Result { From 199dc6db0b559519f67ec2d4ce33203cf0094ceb Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Wed, 14 Aug 2024 15:17:27 +0200 Subject: [PATCH 04/12] linting --- src/dfx/src/commands/canister/sign.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dfx/src/commands/canister/sign.rs b/src/dfx/src/commands/canister/sign.rs index 5fe1af4559..4c79e75a88 100644 --- a/src/dfx/src/commands/canister/sign.rs +++ b/src/dfx/src/commands/canister/sign.rs @@ -93,7 +93,7 @@ pub async fn exec( .and_then(|path| get_candid_type(CandidSource::File(&path), method_name)) { Some(mt) => Some(mt), - None => fetch_remote_did_file(&agent, canister_id) + None => fetch_remote_did_file(agent, canister_id) .await .and_then(|did| get_candid_type(CandidSource::Text(&did), method_name)), }; From 646318de2e3a90c70a288e851b619594fd8b6201 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Thu, 15 Aug 2024 00:51:33 +0200 Subject: [PATCH 05/12] addressing suggestions --- Cargo.lock | 1 + src/dfx-core/Cargo.toml | 3 +- src/dfx-core/src/assets/canister_ids.json | 62 +++++++++++++++++++ src/dfx-core/src/build.rs | 42 +++++++++---- .../src/config/model/canister_id_store.rs | 27 +++++--- src/dfx/src/commands/canister/sign.rs | 13 ++-- 6 files changed, 121 insertions(+), 27 deletions(-) create mode 100644 src/dfx-core/src/assets/canister_ids.json diff --git a/Cargo.lock b/Cargo.lock index 54bf18f984..e270a61ddf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1629,6 +1629,7 @@ dependencies = [ "ic-agent", "ic-identity-hsm", "ic-utils 0.37.1", + "itertools 0.10.5", "k256 0.11.6", "keyring", "lazy_static", diff --git a/src/dfx-core/Cargo.toml b/src/dfx-core/Cargo.toml index 8749ea29d0..302f8a0e1e 100644 --- a/src/dfx-core/Cargo.toml +++ b/src/dfx-core/Cargo.toml @@ -9,7 +9,8 @@ rust-version.workspace = true build = "src/build.rs" [build-dependencies] -reqwest.workspace = true +serde_json.workspace = true +itertools.workspace = true [dependencies] aes-gcm.workspace = true diff --git a/src/dfx-core/src/assets/canister_ids.json b/src/dfx-core/src/assets/canister_ids.json new file mode 100644 index 0000000000..70b41a1ca5 --- /dev/null +++ b/src/dfx-core/src/assets/canister_ids.json @@ -0,0 +1,62 @@ +{ + "registry": { + "local": "rwlgt-iiaaa-aaaaa-aaaaa-cai", + "mainnet": "rwlgt-iiaaa-aaaaa-aaaaa-cai", + "small01": "rwlgt-iiaaa-aaaaa-aaaaa-cai" + }, + "governance": { + "local": "rrkah-fqaaa-aaaaa-aaaaq-cai", + "mainnet": "rrkah-fqaaa-aaaaa-aaaaq-cai", + "small01": "rrkah-fqaaa-aaaaa-aaaaq-cai" + }, + "ledger": { + "local": "ryjl3-tyaaa-aaaaa-aaaba-cai", + "mainnet": "ryjl3-tyaaa-aaaaa-aaaba-cai", + "small01": "ryjl3-tyaaa-aaaaa-aaaba-cai" + }, + "icp-ledger-archive": { + "local": "qjdve-lqaaa-aaaaa-aaaeq-cai", + "mainnet": "qjdve-lqaaa-aaaaa-aaaeq-cai", + "small01": "qjdve-lqaaa-aaaaa-aaaeq-cai" + }, + "icp-ledger-archive-1": { + "local": "qsgjb-riaaa-aaaaa-aaaga-cai", + "mainnet": "qsgjb-riaaa-aaaaa-aaaga-cai", + "small01": "qsgjb-riaaa-aaaaa-aaaga-cai" + }, + "root": { + "local": "r7inp-6aaaa-aaaaa-aaabq-cai", + "mainnet": "r7inp-6aaaa-aaaaa-aaabq-cai", + "small01": "r7inp-6aaaa-aaaaa-aaabq-cai" + }, + "cycles-minting": { + "local": "rkp4c-7iaaa-aaaaa-aaaca-cai", + "mainnet": "rkp4c-7iaaa-aaaaa-aaaca-cai", + "small01": "rkp4c-7iaaa-aaaaa-aaaca-cai" + }, + "lifeline": { + "local": "rno2w-sqaaa-aaaaa-aaacq-cai", + "mainnet": "rno2w-sqaaa-aaaaa-aaacq-cai", + "small01": "rno2w-sqaaa-aaaaa-aaacq-cai" + }, + "genesis-token": { + "local": "renrk-eyaaa-aaaaa-aaada-cai", + "mainnet": "renrk-eyaaa-aaaaa-aaada-cai", + "small01": "renrk-eyaaa-aaaaa-aaada-cai" + }, + "sns-wasm": { + "local": "qaa6y-5yaaa-aaaaa-aaafa-cai", + "mainnet": "qaa6y-5yaaa-aaaaa-aaafa-cai", + "small01": "qaa6y-5yaaa-aaaaa-aaafa-cai" + }, + "identity": { + "local": "rdmx6-jaaaa-aaaaa-aaadq-cai", + "mainnet": "rdmx6-jaaaa-aaaaa-aaadq-cai", + "small01": "rdmx6-jaaaa-aaaaa-aaadq-cai" + }, + "nns-ui": { + "local": "qoctq-giaaa-aaaaa-aaaea-cai", + "mainnet": "qoctq-giaaa-aaaaa-aaaea-cai", + "small01": "qoctq-giaaa-aaaaa-aaaea-cai" + } +} diff --git a/src/dfx-core/src/build.rs b/src/dfx-core/src/build.rs index 55417348f6..b8ac4a635a 100644 --- a/src/dfx-core/src/build.rs +++ b/src/dfx-core/src/build.rs @@ -1,13 +1,29 @@ use std::{env, fs::File, io::Write, path::Path}; -const CANISTER_IDS_URL: &str = "https://raw.githubusercontent.com/dfinity/ic/1402bf35308ec9bd87356c26f7c430f49b49423a/rs/nns/canister_ids.json"; +use itertools::Itertools; +use serde_json::Value; + fn define_well_known_canisters() { - let well_known_canisters = reqwest::blocking::get(CANISTER_IDS_URL) - .unwrap() - .error_for_status() - .unwrap() - .text() - .unwrap(); + let well_known_canisters = std::fs::read_to_string(format!( + "{}/src/assets/canister_ids.json", + env!("CARGO_MANIFEST_DIR") + )) + .unwrap(); + let well_known_canisters = serde_json::from_str::(&well_known_canisters).unwrap(); + let well_known_canisters = well_known_canisters.as_object().unwrap(); + + let well_known_canisters = well_known_canisters.iter().map(|(key, val)| { + ( + key.as_str(), + val.as_object() + .unwrap() + .values() + .last() + .unwrap() + .as_str() + .unwrap(), + ) + }); let out_dir = env::var("OUT_DIR").unwrap(); let loader_path = Path::new(&out_dir).join("well_known_canisters.rs"); @@ -15,15 +31,17 @@ fn define_well_known_canisters() { f.write_all( format!( " -const WELL_KNOWN_CANISTERS: &str = r#\" +const WELL_KNOWN_CANISTERS: &[(&str, &str)] = &[ {} -\"#; +]; -pub fn map_wellknown_canisters() -> CanisterIds {{ - serde_json::from_str(WELL_KNOWN_CANISTERS).unwrap_or(CanisterIds::new()) +pub fn map_wellknown_canisters() -> HashMap {{ + WELL_KNOWN_CANISTERS.iter().map(|(key, value)| (key.to_string(), (*value).try_into().unwrap())).collect() }} ", - well_known_canisters.replace("mainnet", "ic") + well_known_canisters + .map(|(key, val)| format!("(\"{}\", \"{}\")", key, val)) + .join(",\n") ) .as_bytes(), ) diff --git a/src/dfx-core/src/config/model/canister_id_store.rs b/src/dfx-core/src/config/model/canister_id_store.rs index 07b4b7883f..bb3a14efc7 100644 --- a/src/dfx-core/src/config/model/canister_id_store.rs +++ b/src/dfx-core/src/config/model/canister_id_store.rs @@ -9,9 +9,10 @@ use candid::Principal as CanisterId; use ic_agent::export::Principal; use serde::{Deserialize, Serialize, Serializer}; use slog::{warn, Logger}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashMap}; use std::ops::{Deref, DerefMut, Sub}; use std::path::PathBuf; +use std::str::FromStr; use std::sync::Arc; use std::time::{Duration, SystemTime}; use time::format_description::well_known::Rfc3339; @@ -96,7 +97,7 @@ pub struct CanisterIdStore { // which does not include remote canister ids ids: CanisterIds, - well_known_ids: CanisterIds, + well_known_ids: HashMap, // Only canisters that will time out at some point have their timestamp of acquisition saved acquisition_timestamps: CanisterTimestamps, @@ -194,7 +195,16 @@ impl CanisterIdStore { self.remote_ids .as_ref() .and_then(|remote_ids| self.get_name_in(canister_id, remote_ids)) - .or_else(|| self.get_name_in(canister_id, &self.well_known_ids)) + .or_else(|| { + let principal = match Principal::from_str(canister_id) { + Ok(p) => p, + Err(_) => return None, + }; + self.well_known_ids + .iter() + .find(|(_, id)| &&principal == id) + .and_then(|(name, _)| Some(name)) + }) .or_else(|| self.get_name_in_project(canister_id)) .or_else(|| self.get_name_in_pull_ids(canister_id)) } @@ -252,7 +262,11 @@ impl CanisterIdStore { .as_ref() .and_then(|remote_ids| self.find_in(canister_name, remote_ids)) .or_else(|| self.find_in(canister_name, &self.ids)) - .or_else(|| self.find_in(canister_name, &self.well_known_ids)) + .or_else(|| { + self.well_known_ids + .get(canister_name) + .map(|c| CanisterId::from(*c)) + }) .or_else(|| self.pull_ids.get(canister_name).copied()) } pub fn get_name_id_map(&self) -> BTreeMap { @@ -301,10 +315,7 @@ impl CanisterIdStore { } pub fn is_well_known(&self, canister_id: &CanisterId) -> bool { - let canister_str = canister_id.to_string(); - self.well_known_ids - .values() - .any(|val| val.values().any(|k| &canister_str == k)) + self.well_known_ids.values().any(|val| val == canister_id) } pub fn get(&self, canister_name: &str) -> Result { diff --git a/src/dfx/src/commands/canister/sign.rs b/src/dfx/src/commands/canister/sign.rs index 4c79e75a88..bbec327cc6 100644 --- a/src/dfx/src/commands/canister/sign.rs +++ b/src/dfx/src/commands/canister/sign.rs @@ -76,9 +76,6 @@ pub async fn exec( opts: CanisterSignOpts, call_sender: &CallSender, ) -> DfxResult { - let agent = env.get_agent(); - fetch_root_key_if_needed(env).await?; - let log = env.get_logger(); if *call_sender != CallSender::SelectedId { bail!("`sign` currently doesn't support proxying through the wallet canister, please use `dfx canister sign --no-wallet ...`."); @@ -93,9 +90,13 @@ pub async fn exec( .and_then(|path| get_candid_type(CandidSource::File(&path), method_name)) { Some(mt) => Some(mt), - None => fetch_remote_did_file(agent, canister_id) - .await - .and_then(|did| get_candid_type(CandidSource::Text(&did), method_name)), + None => { + let agent = env.get_agent(); + fetch_root_key_if_needed(env).await?; + fetch_remote_did_file(agent, canister_id) + .await + .and_then(|did| get_candid_type(CandidSource::Text(&did), method_name)) + } }; let is_query_method = method_type.as_ref().map(|(_, f)| f.is_query()); From 61719206cc1ef324731f3000cb0c0bfece9cfd54 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Thu, 15 Aug 2024 00:54:19 +0200 Subject: [PATCH 06/12] clippy --- src/dfx-core/src/config/model/canister_id_store.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/dfx-core/src/config/model/canister_id_store.rs b/src/dfx-core/src/config/model/canister_id_store.rs index bb3a14efc7..e977e0ff40 100644 --- a/src/dfx-core/src/config/model/canister_id_store.rs +++ b/src/dfx-core/src/config/model/canister_id_store.rs @@ -203,7 +203,7 @@ impl CanisterIdStore { self.well_known_ids .iter() .find(|(_, id)| &&principal == id) - .and_then(|(name, _)| Some(name)) + .map(|(name, _)| name) }) .or_else(|| self.get_name_in_project(canister_id)) .or_else(|| self.get_name_in_pull_ids(canister_id)) @@ -262,11 +262,7 @@ impl CanisterIdStore { .as_ref() .and_then(|remote_ids| self.find_in(canister_name, remote_ids)) .or_else(|| self.find_in(canister_name, &self.ids)) - .or_else(|| { - self.well_known_ids - .get(canister_name) - .map(|c| CanisterId::from(*c)) - }) + .or_else(|| self.well_known_ids.get(canister_name).copied()) .or_else(|| self.pull_ids.get(canister_name).copied()) } pub fn get_name_id_map(&self) -> BTreeMap { From 2467889b76bfe7c3c0cc421dfdac307c757fc1aa Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Thu, 15 Aug 2024 00:57:13 +0200 Subject: [PATCH 07/12] moving files --- src/dfx-core/Cargo.toml | 2 +- src/dfx-core/{src => assets}/build.rs | 13 +++++++------ src/dfx-core/{src => }/assets/canister_ids.json | 0 3 files changed, 8 insertions(+), 7 deletions(-) rename src/dfx-core/{src => assets}/build.rs (83%) rename src/dfx-core/{src => }/assets/canister_ids.json (100%) diff --git a/src/dfx-core/Cargo.toml b/src/dfx-core/Cargo.toml index 302f8a0e1e..473ec3e505 100644 --- a/src/dfx-core/Cargo.toml +++ b/src/dfx-core/Cargo.toml @@ -6,7 +6,7 @@ edition.workspace = true repository.workspace = true license.workspace = true rust-version.workspace = true -build = "src/build.rs" +build = "assets/build.rs" [build-dependencies] serde_json.workspace = true diff --git a/src/dfx-core/src/build.rs b/src/dfx-core/assets/build.rs similarity index 83% rename from src/dfx-core/src/build.rs rename to src/dfx-core/assets/build.rs index b8ac4a635a..b4fdc35457 100644 --- a/src/dfx-core/src/build.rs +++ b/src/dfx-core/assets/build.rs @@ -4,14 +4,15 @@ use itertools::Itertools; use serde_json::Value; fn define_well_known_canisters() { - let well_known_canisters = std::fs::read_to_string(format!( - "{}/src/assets/canister_ids.json", - env!("CARGO_MANIFEST_DIR") - )) + let well_known_canisters = serde_json::from_str::( + &std::fs::read_to_string(format!( + "{}/assets/canister_ids.json", + env!("CARGO_MANIFEST_DIR") + )) + .unwrap(), + ) .unwrap(); - let well_known_canisters = serde_json::from_str::(&well_known_canisters).unwrap(); let well_known_canisters = well_known_canisters.as_object().unwrap(); - let well_known_canisters = well_known_canisters.iter().map(|(key, val)| { ( key.as_str(), diff --git a/src/dfx-core/src/assets/canister_ids.json b/src/dfx-core/assets/canister_ids.json similarity index 100% rename from src/dfx-core/src/assets/canister_ids.json rename to src/dfx-core/assets/canister_ids.json From f5844aca588ef902aa3581012cd630118e5afc27 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Thu, 15 Aug 2024 01:07:36 +0200 Subject: [PATCH 08/12] adding tests --- e2e/tests-dfx/call.bash | 14 ++++++++++++++ e2e/tests-dfx/sign_send.bash | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/e2e/tests-dfx/call.bash b/e2e/tests-dfx/call.bash index 0454cb68ad..b24eb48da6 100644 --- a/e2e/tests-dfx/call.bash +++ b/e2e/tests-dfx/call.bash @@ -297,3 +297,17 @@ teardown() { assert_command dfx canister call inter2_mo read assert_match '(8 : nat)' } + +@test "call well known canisters" { + assert_command dfx canister --ic call governance list_proposals '( + record { + include_reward_status = vec {}; + omit_large_fields = null; + before_proposal = null; + limit = 1 : nat32; + exclude_topic = vec {}; + include_all_manage_neuron_proposals = null; + include_status = vec {}; + }, + )' +} diff --git a/e2e/tests-dfx/sign_send.bash b/e2e/tests-dfx/sign_send.bash index a0b848c6fd..5393cdeb69 100644 --- a/e2e/tests-dfx/sign_send.bash +++ b/e2e/tests-dfx/sign_send.bash @@ -81,3 +81,12 @@ Signed request_status append to update message in [message-inc.json]" rm "$TMP_NAME_FILE" } + +@test "sign query message for a well known canister" { + cd "$E2E_TEMP_DIR" + mkdir not-a-project-dir + cd not-a-project-dir + + assert_command dfx canister sign --query registry read --network ic + assert_match "Query message generated at \[message.json\]" +} From dd5303a2bda728feed645bef65f2ba581bc44026 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Thu, 15 Aug 2024 01:51:10 +0200 Subject: [PATCH 09/12] removing unneeded reqwest feature --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4e7b67fd38..a5d18a6c0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,6 @@ pem = "1.0.2" proptest = "1.0.0" reqwest = { version = "0.12.4", default-features = false, features = [ "rustls-tls", - "blocking", ] } ring = "0.16.11" schemars = "0.8" From c9bf2704c4f49128289daa31299c56622e2e3507 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Sat, 31 Aug 2024 23:45:25 +0200 Subject: [PATCH 10/12] looking up mainnet instead of last --- src/dfx-core/assets/build.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dfx-core/assets/build.rs b/src/dfx-core/assets/build.rs index b4fdc35457..e0d89e759d 100644 --- a/src/dfx-core/assets/build.rs +++ b/src/dfx-core/assets/build.rs @@ -18,8 +18,7 @@ fn define_well_known_canisters() { key.as_str(), val.as_object() .unwrap() - .values() - .last() + .get("mainnet") .unwrap() .as_str() .unwrap(), From 8ee4815e00e197bf236e7c2f08d5fa10bf0534ce Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Sat, 31 Aug 2024 23:55:36 +0200 Subject: [PATCH 11/12] moving checking for well known canisters to the back so it does not break previous functionallity --- src/dfx-core/src/config/model/canister_id_store.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dfx-core/src/config/model/canister_id_store.rs b/src/dfx-core/src/config/model/canister_id_store.rs index e977e0ff40..be97b60042 100644 --- a/src/dfx-core/src/config/model/canister_id_store.rs +++ b/src/dfx-core/src/config/model/canister_id_store.rs @@ -195,6 +195,8 @@ impl CanisterIdStore { self.remote_ids .as_ref() .and_then(|remote_ids| self.get_name_in(canister_id, remote_ids)) + .or_else(|| self.get_name_in_project(canister_id)) + .or_else(|| self.get_name_in_pull_ids(canister_id)) .or_else(|| { let principal = match Principal::from_str(canister_id) { Ok(p) => p, @@ -205,8 +207,6 @@ impl CanisterIdStore { .find(|(_, id)| &&principal == id) .map(|(name, _)| name) }) - .or_else(|| self.get_name_in_project(canister_id)) - .or_else(|| self.get_name_in_pull_ids(canister_id)) } pub fn get_name_in_project(&self, canister_id: &str) -> Option<&String> { @@ -262,8 +262,8 @@ impl CanisterIdStore { .as_ref() .and_then(|remote_ids| self.find_in(canister_name, remote_ids)) .or_else(|| self.find_in(canister_name, &self.ids)) - .or_else(|| self.well_known_ids.get(canister_name).copied()) .or_else(|| self.pull_ids.get(canister_name).copied()) + .or_else(|| self.well_known_ids.get(canister_name).copied()) } pub fn get_name_id_map(&self) -> BTreeMap { let mut ids: BTreeMap<_, _> = self From f414f825480c6672c84d8bd9623c832e861cb768 Mon Sep 17 00:00:00 2001 From: NikolaMilosa Date: Sun, 1 Sep 2024 00:02:26 +0200 Subject: [PATCH 12/12] adding to changelog --- CHANGELOG.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6498416b8a..605d9aa78d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ # UNRELEASED +### feat: embedding well known canisters at build time + +From this feature onwards, dfx doesn't require `canister_ids.json` to contain information about all the well known canisters on nns. The list of well known canister's can be found [here](https://github.com/dfinity/ic/blob/master/rs/nns/canister_ids.json). This means that `dfx canister call ` will automatically map to the correct canister id. + ### feat: Also report Motoko stable compatibility warnings Report upgrade compatibility warnings for Motoko, such as deleted stable variables, in addition to compatibility errors. @@ -702,7 +706,7 @@ For reference, these formats were removed (any '-' characters were replaced by ' ### feat: add `dfx canister logs ` for fetching canister's logs (preview) -There is a new subcommand `logs` to fetch canister's logs. +There is a new subcommand `logs` to fetch canister's logs. When printing the log entries it tries to guess if the content can be converted to UTF-8 text and prints an array of hex bytes if it fails. **Note** @@ -718,7 +722,7 @@ The query parameter format is not removed because Safari does not support localh ### fix: .env files sometimes missing some canister ids -Made it so `dfx deploy` and `dfx canister install` will always write +Made it so `dfx deploy` and `dfx canister install` will always write environment variables for all canisters in the project that have canister ids to the .env file, even if they aren't being deployed/installed or a dependency of a canister being deployed/installed. @@ -728,7 +732,7 @@ or a dependency of a canister being deployed/installed. There are a few subcommands that take `--argument`/`--argument-file` options to set canister call/init arguments. We unify the related logic to provide consistent user experience. - + The notable changes are: - `dfx deploy` now accepts `--argument-file`. @@ -736,7 +740,7 @@ The notable changes are: ### feat: candid assist feature -Ask for user input when Candid argument is not provided in `dfx canister call`, `dfx canister install` and `dfx deploy`. +Ask for user input when Candid argument is not provided in `dfx canister call`, `dfx canister install` and `dfx deploy`. Previously, we cannot call `dfx deploy --all` when multiple canisters require init args, unless the init args are specified in `dfx.json`. With the Candid assist feature, dfx now asks for init args in terminal when a canister requires init args. ### fix: restored access to URLs like http://localhost:8080/api/v2/status through icx-proxy @@ -885,7 +889,7 @@ If you build with custom canister type, add the following into `dfx.json`: ``` "metadata": [ - { + { "name": "candid:service" } ] @@ -920,7 +924,7 @@ Fix the bug that when parsing `vec \{1;2;3\}` with `blob` type, dfx silently ign ### fix: support `import` for local did file If the local did file contains `import` or init args, dfx will rewrite the did file when storing in canister metadata. -Due to current limitations of the Candid parser, comments will be dropped during rewriting. +Due to current limitations of the Candid parser, comments will be dropped during rewriting. If the local did file doesn't contain `import` or init args, we will not perform the rewriting, thus preserving the comments. ### fix: subtyping check reports the special opt rule as error @@ -1309,7 +1313,7 @@ This incorporates the following executed proposals: - [124537](https://dashboard.internetcomputer.org/proposal/124537) - [124488](https://dashboard.internetcomputer.org/proposal/124488) - [124487](https://dashboard.internetcomputer.org/proposal/124487) - + # 0.15.0 ## DFX