Skip to content

Commit

Permalink
add identity and canister
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyan-dfinity committed Jan 28, 2024
1 parent b4e2dd9 commit dc5037a
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 10 deletions.
33 changes: 33 additions & 0 deletions src/dfx-core/src/config/model/canister_id_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,39 @@ impl CanisterIdStore {
.or_else(|| self.find_in(canister_name, &self.ids))
.or_else(|| self.pull_ids.get(canister_name).copied())
}
pub fn get_name_id_map(&self) -> BTreeMap<String, String> {
let mut ids: BTreeMap<_, _> = self
.ids
.iter()
.map(|(name, network_to_id)| {
(
name.clone(),
network_to_id.get(&self.network_descriptor.name).cloned(),
)
})
.filter_map(|(name, id)| id.map(|id| (name, id)))
.collect();
if let Some(remote_ids) = &self.remote_ids {
let mut remote = remote_ids
.iter()
.map(|(name, network_to_id)| {
(
name.clone(),
network_to_id.get(&self.network_descriptor.name).cloned(),
)
})
.filter_map(|(name, id)| id.map(|id| (name, id)))
.collect();
ids.append(&mut remote);
}
let mut pull_ids = self
.pull_ids
.iter()
.map(|(name, id)| (name.clone(), id.to_text()))
.collect();
ids.append(&mut pull_ids);
ids
}

fn find_in(&self, canister_name: &str, canister_ids: &CanisterIds) -> Option<CanisterId> {
canister_ids
Expand Down
6 changes: 5 additions & 1 deletion src/dfx-core/src/identity/identity_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,11 @@ impl IdentityManager {
Ok(identity)
}

fn load_identity(&self, name: &str, log: &Logger) -> Result<DfxIdentity, LoadIdentityError> {
pub fn load_identity(
&self,
name: &str,
log: &Logger,
) -> Result<DfxIdentity, LoadIdentityError> {
let config = self
.get_identity_config_or_default(name)
.map_err(LoadIdentityError::GetIdentityConfigOrDefaultFailed)?;
Expand Down
8 changes: 7 additions & 1 deletion src/dfx/src/commands/canister/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,13 @@ pub async fn exec(

// Get the argument, get the type, convert the argument to the type and return
// an error if any of it doesn't work.
let arg_value = blob_from_arguments(arguments, opts.random.as_deref(), arg_type, &method_type)?;
let arg_value = blob_from_arguments(
Some(env),
arguments,
opts.random.as_deref(),
arg_type,
&method_type,
)?;

// amount has been validated by cycle_amount_validator
let cycles = opts.with_cycles.unwrap_or(0);
Expand Down
2 changes: 1 addition & 1 deletion src/dfx/src/commands/canister/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ async fn delete_canister(
"Installing temporary wallet in canister {} to enable transfer of cycles.",
canister
);
let args = blob_from_arguments(None, None, None, &None)?;
let args = blob_from_arguments(None, None, None, None, &None)?;
let mode = InstallMode::Reinstall;
let install_builder = mgr
.install_code(&canister_id, &wasm_module)
Expand Down
7 changes: 4 additions & 3 deletions src/dfx/src/commands/canister/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ pub async fn exec(
if let Some(wasm_path) = opts.wasm {
// streamlined version, we can ignore most of the environment
let mode = mode.context("The install mode cannot be auto when using --wasm")?;
let install_args = || blob_from_arguments(arguments, None, arg_type, &None);
let install_args = || blob_from_arguments(Some(env), arguments, None, arg_type, &None);
install_canister(
env,
&mut canister_id_store,
Expand All @@ -158,7 +158,8 @@ pub async fn exec(
let env_file = config.get_output_env_file(opts.output_env_file)?;
let idl_path = canister_info.get_constructor_idl_path();
let init_type = get_candid_init_type(&idl_path);
let install_args = || blob_from_arguments(arguments, None, arg_type, &init_type);
let install_args =
|| blob_from_arguments(Some(env), arguments, None, arg_type, &init_type);
install_canister(
env,
&mut canister_id_store,
Expand Down Expand Up @@ -205,7 +206,7 @@ pub async fn exec(

let idl_path = canister_info.get_constructor_idl_path();
let init_type = get_candid_init_type(&idl_path);
let install_args = || blob_from_arguments(None, None, None, &init_type);
let install_args = || blob_from_arguments(Some(env), None, None, None, &init_type);

install_canister(
env,
Expand Down
8 changes: 7 additions & 1 deletion src/dfx/src/commands/canister/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,13 @@ pub async fn exec(

// Get the argument, get the type, convert the argument to the type and return
// an error if any of it doesn't work.
let arg_value = blob_from_arguments(arguments, opts.random.as_deref(), arg_type, &method_type)?;
let arg_value = blob_from_arguments(
Some(env),
arguments,
opts.random.as_deref(),
arg_type,
&method_type,
)?;
let agent = env.get_agent();

let network = env
Expand Down
2 changes: 1 addition & 1 deletion src/dfx/src/lib/integrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub async fn initialize_integration_canister(
};
try_create_canister(agent, logger, &canister_id, &pulled_canister).await?;

let install_arg = blob_from_arguments(Some(init_arg), None, None, &None)?;
let install_arg = blob_from_arguments(None, Some(init_arg), None, None, &None)?;
install_canister(agent, logger, &canister_id, wasm, install_arg, name).await
}

Expand Down
3 changes: 2 additions & 1 deletion src/dfx/src/lib/operations/canister/deploy_canisters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,8 @@ async fn install_canisters(

let idl_path = canister_info.get_constructor_idl_path();
let init_type = get_candid_init_type(&idl_path);
let install_args = || blob_from_arguments(argument, None, argument_type, &init_type);
let install_args =
|| blob_from_arguments(Some(env), argument, None, argument_type, &init_type);

install_canister(
env,
Expand Down
46 changes: 45 additions & 1 deletion src/dfx/src/util/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::lib::environment::Environment;
use crate::lib::error::DfxResult;
use crate::{error_invalid_argument, error_invalid_data, error_unknown};
use anyhow::{bail, Context};
Expand All @@ -16,6 +17,7 @@ use net2::{TcpBuilder, TcpListenerExt};
use num_traits::FromPrimitive;
use reqwest::{Client, StatusCode, Url};
use rust_decimal::Decimal;
use std::collections::BTreeMap;
use std::io::{stdin, IsTerminal, Read};
use std::net::{IpAddr, SocketAddr};
use std::path::Path;
Expand Down Expand Up @@ -149,6 +151,7 @@ pub fn arguments_from_file(file_name: &Path) -> DfxResult<String> {

#[context("Failed to create argument blob.")]
pub fn blob_from_arguments(
dfx_env: Option<&dyn Environment>,
arguments: Option<&str>,
random: Option<&str>,
arg_type: Option<&str>,
Expand All @@ -174,6 +177,20 @@ pub fn blob_from_arguments(
Some((env, func)) => {
if let Some(arguments) = arguments {
fuzzy_parse_argument(arguments, env, &func.args)
} else if func.args.is_empty() {
use candid::Encode;
Encode!()
} else if func
.args
.iter()
.all(|t| matches!(t.as_ref(), TypeInner::Opt(_)))
&& !stdin().is_terminal()
{
// If the user provided no arguments, and if all the expected arguments are
// optional, then use null values.
let nulls = vec![IDLValue::Null; func.args.len()];
let args = IDLArgs::new(&nulls);
args.to_bytes_with_types(env, &func.args)
} else if let Some(random) = random {
let random = if random.is_empty() {
eprintln!("Random schema is empty, using any random value instead.");
Expand All @@ -193,7 +210,14 @@ pub fn blob_from_arguments(
} else if stdin().is_terminal() {
use candid_parser::assist::{input_args, Context};
let mut ctx = Context::new(env.clone());
let args = input_args(&mut ctx, &func.args)?;
if let Some(env) = dfx_env {
if let Some(principals) = gather_principals_from_env(env) {
let mut map = BTreeMap::new();
map.insert("principal".to_string(), principals);
ctx.set_completion(map);
}
}
let args = input_args(&ctx, &func.args)?;
eprintln!("Sending the following argument:\n{}\n", args);
eprintln!("Do you want to send this message? [y/N]");
let mut input = String::new();
Expand All @@ -214,6 +238,26 @@ pub fn blob_from_arguments(
}
}

pub fn gather_principals_from_env(env: &dyn Environment) -> Option<BTreeMap<String, String>> {
use ic_agent::Identity;
let mgr = env.new_identity_manager().ok()?;
let logger = env.get_logger();
let names = mgr.get_identity_names(logger).ok()?;
let mut map: BTreeMap<String, String> = names
.iter()
.filter_map(|name| {
let id = mgr.load_identity(name, logger).ok()?;
let sender = id.sender().ok()?;
Some((name.clone(), sender.to_text()))
})
.collect();
let canisters = env.get_canister_id_store().ok()?;
let mut canisters = canisters.get_name_id_map();
map.append(&mut canisters);
//println!("{}", serde_json::to_string_pretty(&map).ok()?);
Some(map)
}

pub fn fuzzy_parse_argument(
arg_str: &str,
env: &TypeEnv,
Expand Down

0 comments on commit dc5037a

Please sign in to comment.