Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
295 changes: 153 additions & 142 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ members = [
]

[patch.crates-io]
ic-types = { git = "ssh://git@github.com/dfinity-lab/agent-rust.git", branch = "next", version = "0.1.1" }
ic-types = { git = "ssh://git@github.com/dfinity-lab/agent-rust.git", branch = "pshahi/ingress-expiry-two", version = "0.1.1" }
8 changes: 4 additions & 4 deletions nix/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@
},
"dfinity": {
"repo": "ssh://git@github.com/dfinity-lab/dfinity",
"rev": "70434f1ecac5227dc8e5d30635f7aceb7c257e3f",
"tag": "release-2020-09-04.RC00",
"rev": "d0856d8d60b5a2d2a7b6f50fa0fa1d68db9264dc",
"branch": "akhi3030/expiry-time",
"type": "git"
},
"ic-ref": {
"repo": "ssh://git@github.com/dfinity-lab/ic-ref",
"rev": "493f0862ddd9970b8fb09e4e97f95fab1764b18e",
"tag": "release-0.9",
"rev": "7c1e8bae654588790374ec1a23f40f579405b31c",
"tag": "0.10.2",
"type": "git"
},
"motoko": {
Expand Down
9 changes: 5 additions & 4 deletions src/dfx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dialoguer = "0.6.2"
erased-serde = "0.3.10"
flate2 = "1.0.11"
futures = "0.1.28"
humanize-rs = "0.1.5"
hex = "0.4.2"
indicatif = "0.13.0"
lazy-init = "0.3.0"
Expand Down Expand Up @@ -68,14 +69,14 @@ wasmparser = "0.45.0"
[dependencies.ic-agent]
version = "0.1.0"
git = "ssh://git@github.com/dfinity-lab/agent-rust.git"
branch = "next"
rev = "35a0f9851cf8cceea34acf405ba50c84ab5fbc5e"
branch = "pshahi/ingress-expiry-two"
rev = "b57f659d431198feaca98f7ef9adf9b1fdff7807"

[dependencies.ic-types]
version = "0.1.1"
git = "ssh://git@github.com/dfinity-lab/agent-rust.git"
branch = "next"
rev = "35a0f9851cf8cceea34acf405ba50c84ab5fbc5e"
branch = "pshahi/ingress-expiry-two"
rev = "b57f659d431198feaca98f7ef9adf9b1fdff7807"

[dev-dependencies]
env_logger = "0.6"
Expand Down
27 changes: 18 additions & 9 deletions src/dfx/src/commands/canister/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::models::canister_id_store::CanisterIdStore;
use crate::lib::waiter::create_waiter;
use crate::util::{blob_from_arguments, get_candid_type, print_idl_blob};
use crate::lib::waiter::waiter_with_timeout;
use crate::util::{blob_from_arguments, expiry_duration, get_candid_type, print_idl_blob};
use clap::{App, Arg, ArgMatches, SubCommand};
use ic_types::principal::Principal as CanisterId;
use std::option::Option;
Expand Down Expand Up @@ -125,26 +125,35 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
// 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, arg_type, &method_type)?;
let client = env
let agent = env
.get_agent()
.ok_or(DfxError::CommandMustBeRunInAProject)?;
let mut runtime = Runtime::new().expect("Unable to create a runtime");

let timeout = args.value_of("expiry_duration");
let duration = expiry_duration(timeout)?;

if is_query {
let blob = runtime.block_on(client.query_raw(&canister_id, method_name, &arg_value))?;
let blob =
runtime.block_on(agent.query_raw(&canister_id, method_name, &arg_value, None))?;
print_idl_blob(&blob, output_type, &method_type)
.map_err(|e| DfxError::InvalidData(format!("Invalid IDL blob: {}", e)))?;
} else if args.is_present("async") {
let request_id =
runtime.block_on(client.update_raw(&canister_id, method_name, &arg_value))?;

let request_id = runtime.block_on(
agent
.update(&canister_id, &method_name)
.with_arg(&arg_value)
.call(),
)?;
eprint!("Request ID: ");
println!("0x{}", String::from(request_id));
} else {
let blob = runtime.block_on(
client
agent
.update(&canister_id, &method_name)
.with_arg(&arg_value)
.call_and_wait(create_waiter()),
.expire_after(duration)
.call_and_wait(waiter_with_timeout(duration)),
)?;

print_idl_blob(&blob, output_type, &method_type)
Expand Down
6 changes: 4 additions & 2 deletions src/dfx/src/commands/canister/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,16 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
.get_config()
.ok_or(DfxError::CommandMustBeRunInAProject)?;

let timeout = args.value_of("expiry_duration");

if let Some(canister_name) = args.value_of("canister_name") {
create_canister(env, canister_name)?;
create_canister(env, canister_name, timeout)?;
Ok(())
} else if args.is_present("all") {
// Create all canisters.
if let Some(canisters) = &config.get_config().canisters {
for canister_name in canisters.keys() {
create_canister(env, canister_name)?;
create_canister(env, canister_name, timeout)?;
}
}
Ok(())
Expand Down
19 changes: 14 additions & 5 deletions src/dfx/src/commands/canister/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::models::canister_id_store::CanisterIdStore;
use crate::lib::waiter::create_waiter;
use crate::lib::waiter::waiter_with_timeout;
use crate::util::expiry_duration;

use clap::{App, Arg, ArgMatches, SubCommand};
use ic_agent::{Agent, ManagementCanister};
Expand All @@ -28,7 +29,12 @@ pub fn construct() -> App<'static, 'static> {
)
}

async fn delete_canister(env: &dyn Environment, agent: &Agent, canister_name: &str) -> DfxResult {
async fn delete_canister(
env: &dyn Environment,
agent: &Agent,
canister_name: &str,
timeout: Option<&str>,
) -> DfxResult {
let mgr = ManagementCanister::new(agent);
let log = env.get_logger();
let mut canister_id_store = CanisterIdStore::for_env(env)?;
Expand All @@ -39,8 +45,9 @@ async fn delete_canister(env: &dyn Environment, agent: &Agent, canister_name: &s
canister_name,
canister_id.to_text(),
);
let duration = expiry_duration(timeout)?;

mgr.delete_canister(create_waiter(), &canister_id)
mgr.delete_canister(waiter_with_timeout(duration), &canister_id)
.await
.map_err(DfxError::from)?;

Expand All @@ -57,15 +64,17 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
.get_agent()
.ok_or(DfxError::CommandMustBeRunInAProject)?;

let timeout = args.value_of("expiry_duration");

let mut runtime = Runtime::new().expect("Unable to create a runtime");

if let Some(canister_name) = args.value_of("canister_name") {
runtime.block_on(delete_canister(env, &agent, &canister_name))?;
runtime.block_on(delete_canister(env, &agent, &canister_name, timeout))?;
Ok(())
} else if args.is_present("all") {
if let Some(canisters) = &config.get_config().canisters {
for canister_name in canisters.keys() {
runtime.block_on(delete_canister(env, &agent, &canister_name))?;
runtime.block_on(delete_canister(env, &agent, &canister_name, timeout))?;
}
}
Ok(())
Expand Down
35 changes: 34 additions & 1 deletion src/dfx/src/commands/canister/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use crate::lib::models::canister_id_store::CanisterIdStore;
use crate::lib::operations::canister::install_canister;

use clap::{App, Arg, ArgMatches, SubCommand};
use ic_agent::{ComputeAllocation, InstallMode};
use humanize_rs::bytes::{Bytes, Unit};
use ic_agent::{ComputeAllocation, InstallMode, MemoryAllocation};

use std::convert::TryFrom;
use std::str::FromStr;
use tokio::runtime::Runtime;
Expand Down Expand Up @@ -51,6 +53,13 @@ pub fn construct() -> App<'static, 'static> {
.takes_value(true)
.validator(compute_allocation_validator),
)
.arg(
Arg::with_name("memory-allocation")
.help(UserMessage::InstallMemoryAllocation.to_str())
.long("memory-allocation")
.takes_value(true)
.validator(memory_allocation_validator),
)
}

fn compute_allocation_validator(compute_allocation: String) -> Result<(), String> {
Expand All @@ -62,18 +71,38 @@ fn compute_allocation_validator(compute_allocation: String) -> Result<(), String
Err("Must be a percent between 0 and 100".to_string())
}

fn memory_allocation_validator(memory_allocation: String) -> Result<(), String> {
let limit = Bytes::new(256, Unit::TByte).map_err(|_| "Parse Overflow.")?;
if let Ok(bytes) = memory_allocation.parse::<Bytes>() {
if bytes.size() <= limit.size() {
return Ok(());
}
}
Err("Must be a value between 0..256 TB inclusive.".to_string())
}

pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
let config = env
.get_config()
.ok_or(DfxError::CommandMustBeRunInAProject)?;

let timeout = args.value_of("expiry_duration");

let agent = env
.get_agent()
.ok_or(DfxError::CommandMustBeRunInAProject)?;

let compute_allocation = args.value_of("compute-allocation").map(|arg| {
ComputeAllocation::try_from(arg.parse::<u64>().unwrap())
.expect("Compute Allocation must be a percentage.")
});

let memory_allocation: Option<MemoryAllocation> =
args.value_of("memory_allocation").map(|arg| {
MemoryAllocation::try_from(u64::try_from(arg.parse::<Bytes>().unwrap().size()).unwrap())
.expect("Memory allocation must be between 0 and 2^48 (i.e 256TB), inclusively.")
});

let mode = InstallMode::from_str(args.value_of("mode").unwrap())?;

let mut runtime = Runtime::new().expect("Unable to create a runtime");
Expand All @@ -90,6 +119,8 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
&canister_info,
compute_allocation,
mode,
memory_allocation,
timeout,
))?;
Ok(())
} else if args.is_present("all") {
Expand All @@ -105,6 +136,8 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
&canister_info,
compute_allocation,
mode.clone(),
memory_allocation,
timeout,
))?;
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/dfx/src/commands/canister/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::provider::create_agent_environment;
use clap::{App, Arg, ArgMatches, SubCommand};
use humanize_rs::duration::parse;

mod call;
mod create;
Expand Down Expand Up @@ -38,9 +39,28 @@ pub fn construct() -> App<'static, 'static> {
.long("network")
.takes_value(true),
)
.arg(
Arg::with_name("expiry-duration")
.long("expiry-duration")
.help(UserMessage::CanisterCallExpiryDuration.to_str())
.takes_value(true)
.default_value("5m")
.validator(expiry_duration_validator),
)
.subcommands(builtins().into_iter().map(|x| x.get_subcommand().clone()))
}

fn expiry_duration_validator(expiry_duration: String) -> Result<(), String> {
if let Ok(_ed) = parse(&expiry_duration) {
return Ok(());
}
let err = format!(
r#""Invalid input: {}. Expected a duration-type string e.g. "1h", "1h 30m""#,
expiry_duration
);
Err(err)
}

pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
let subcommand = args.subcommand();

Expand Down
13 changes: 9 additions & 4 deletions src/dfx/src/commands/canister/request_status.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::waiter::create_waiter;
use crate::lib::waiter::waiter_with_timeout;
use crate::util::clap::validators;
use crate::util::print_idl_blob;
use crate::util::{expiry_duration, print_idl_blob};
use clap::{App, Arg, ArgMatches, SubCommand};
use delay::Waiter;
use ic_agent::{AgentError, Replied, RequestId, RequestStatusResponse};
Expand Down Expand Up @@ -35,13 +35,17 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
.ok_or(DfxError::CommandMustBeRunInAProject)?;
let mut runtime = Runtime::new().expect("Unable to create a runtime");

let mut waiter = create_waiter();
let timeout = args.value_of("expiry_duration");

let duration = expiry_duration(timeout)?;

let mut waiter = waiter_with_timeout(duration);

let Replied::CallReplied(blob) = runtime
.block_on(async {
waiter.start();
loop {
match agent.request_status_raw(&request_id).await? {
match agent.request_status_raw(&request_id, None).await? {
RequestStatusResponse::Replied { reply } => return Ok(reply),
RequestStatusResponse::Rejected {
reject_code,
Expand All @@ -55,6 +59,7 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {
RequestStatusResponse::Unknown => (),
RequestStatusResponse::Received => (),
RequestStatusResponse::Processing => (),
RequestStatusResponse::Done => (),
};

waiter
Expand Down
20 changes: 15 additions & 5 deletions src/dfx/src/commands/canister/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use crate::lib::environment::Environment;
use crate::lib::error::{DfxError, DfxResult};
use crate::lib::message::UserMessage;
use crate::lib::models::canister_id_store::CanisterIdStore;
use crate::lib::waiter::create_waiter;
use crate::lib::waiter::waiter_with_timeout;
use crate::util::expiry_duration;

use clap::{App, Arg, ArgMatches, SubCommand};
use ic_agent::{Agent, ManagementCanister};
Expand All @@ -28,20 +29,27 @@ pub fn construct() -> App<'static, 'static> {
)
}

async fn start_canister(env: &dyn Environment, agent: &Agent, canister_name: &str) -> DfxResult {
async fn start_canister(
env: &dyn Environment,
agent: &Agent,
canister_name: &str,
timeout: Option<&str>,
) -> DfxResult {
let mgr = ManagementCanister::new(agent);
let log = env.get_logger();
let canister_id_store = CanisterIdStore::for_env(env)?;
let canister_id = canister_id_store.get(canister_name)?;

let duration = expiry_duration(timeout)?;

info!(
log,
"Starting code for canister {}, with canister_id {}",
canister_name,
canister_id.to_text(),
);

mgr.start_canister(create_waiter(), &canister_id)
mgr.start_canister(waiter_with_timeout(duration), &canister_id)
.await
.map_err(DfxError::from)?;

Expand All @@ -58,13 +66,15 @@ pub fn exec(env: &dyn Environment, args: &ArgMatches<'_>) -> DfxResult {

let mut runtime = Runtime::new().expect("Unable to create a runtime");

let timeout = args.value_of("expiry_duration");

if let Some(canister_name) = args.value_of("canister_name") {
runtime.block_on(start_canister(env, &agent, &canister_name))?;
runtime.block_on(start_canister(env, &agent, &canister_name, timeout))?;
Ok(())
} else if args.is_present("all") {
if let Some(canisters) = &config.get_config().canisters {
for canister_name in canisters.keys() {
runtime.block_on(start_canister(env, &agent, &canister_name))?;
runtime.block_on(start_canister(env, &agent, &canister_name, timeout))?;
}
}
Ok(())
Expand Down
Loading