Skip to content

Commit

Permalink
feat: use create_canister with settings & remove set_controller (dfin…
Browse files Browse the repository at this point in the history
  • Loading branch information
p-shahi authored Apr 29, 2021
1 parent 974eb8f commit b5e38e1
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Install DFINITY SDK
run: |
DFX_VERSION=0.7.0-beta.0
DFX_VERSION=0.7.0-beta.4
pushd /tmp
wget -q https://sdk.dfinity.org/install.sh
yes Y | DFX_VERSION=$DFX_VERSION bash install.sh
Expand Down
2 changes: 1 addition & 1 deletion demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ echo
echo == Create a new canister with Alice as controller using 1000000000001 cycles.
echo

CREATE_RES=$(dfx --identity id_alice canister call alice wallet_create_canister "(record { cycles = 1000000000001; controller = null })")
CREATE_RES=$(dfx --identity id_alice canister call alice wallet_create_canister "(record { cycles = 1000000000001; settings = record {null; null; null;}; })")
echo New canister id = $(echo "${CREATE_RES}" | tr '\n' ' ' | cut -d'"' -f 2)

echo
Expand Down
22 changes: 14 additions & 8 deletions wallet/src/lib.did
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ type ResultCall = variant {
Err : text;
};

type CanisterSettings = record {
controller: opt principal;
compute_allocation: opt nat;
memory_allocation: opt nat;
freezing_threshold: opt nat;
};

type CreateCanisterArgs = record {
cycles: nat64;
settings: CanisterSettings;
};

service : {
// Wallet Name
name: () -> (opt text) query;
Expand All @@ -92,15 +104,9 @@ service : {
wallet_receive: () -> (); // Endpoint for receiving cycles.

// Managing canister
wallet_create_canister: (record {
cycles: nat64;
controller: opt principal; // If omitted, set the controller to this wallet.
}) -> (ResultCreate);
wallet_create_canister: (CreateCanisterArgs) -> (ResultCreate);

wallet_create_wallet: (record {
cycles: nat64;
controller: opt principal; // If omitted, set the controller to this wallet.
}) -> (ResultCreate);
wallet_create_wallet: (CreateCanisterArgs) -> (ResultCreate);

wallet_store_wallet_wasm: (record {
wasm_module: blob;
Expand Down
95 changes: 53 additions & 42 deletions wallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,24 @@ mod wallet {
/***************************************************************************************************
* Managing Canister
**************************************************************************************************/
#[derive(CandidType, Deserialize)]
#[derive(CandidType, Clone, Deserialize)]
struct CanisterSettings {
controller: Option<Principal>,
compute_allocation: Option<Nat>,
memory_allocation: Option<Nat>,
freezing_threshold: Option<Nat>,
}

#[derive(CandidType, Clone, Deserialize)]
struct CreateCanisterArgs {
cycles: u64,
controller: Option<Principal>,
settings: CanisterSettings,
}

#[derive(CandidType, Deserialize)]
struct UpdateSettingsArgs {
canister_id: Principal,
settings: CanisterSettings,
}

#[derive(CandidType, Deserialize)]
Expand All @@ -264,22 +278,26 @@ mod wallet {

#[update(guard = "is_custodian", name = "wallet_create_canister")]
async fn create_canister(args: CreateCanisterArgs) -> Result<CreateResult, String> {
let create_result = create_canister_call(args.cycles).await?;

if let Some(new_controller) = args.controller {
set_controller_call(create_result.canister_id.clone(), new_controller, false).await?;
}
let create_result = create_canister_call(args).await?;

super::update_chart();
Ok(create_result)
}

async fn create_canister_call(cycles: u64) -> Result<CreateResult, String> {
async fn create_canister_call(args: CreateCanisterArgs) -> Result<CreateResult, String> {
#[derive(CandidType)]
struct In {
settings: Option<CanisterSettings>,
}
let in_arg = In {
settings: Some(args.settings),
};

let (create_result,): (CreateResult,) = match api::call::call_with_payment(
Principal::management_canister(),
"create_canister",
(),
cycles as i64,
(in_arg,),
args.cycles as i64,
)
.await
{
Expand All @@ -294,21 +312,20 @@ mod wallet {

events::record(events::EventKind::CanisterCreated {
canister: create_result.canister_id.clone(),
cycles,
cycles: args.cycles,
});
Ok(create_result)
}

async fn set_controller_call(
canister_id: Principal,
new_controller: Principal,
async fn update_settings_call(
args: UpdateSettingsArgs,
update_acl: bool,
) -> Result<(), String> {
if update_acl {
match api::call::call(
canister_id.clone(),
args.canister_id.clone(),
"add_controller",
(new_controller.clone(),),
(args.settings.controller.clone().unwrap().clone(),),
)
.await
{
Expand All @@ -321,7 +338,7 @@ mod wallet {
}
};

match api::call::call(canister_id.clone(), "remove_controller", (id(),)).await {
match api::call::call(args.canister_id.clone(), "remove_controller", (id(),)).await {
Ok(x) => x,
Err((code, msg)) => {
return Err(format!(
Expand All @@ -332,24 +349,7 @@ mod wallet {
};
}

#[derive(CandidType)]
struct In {
canister_id: Principal,
new_controller: Principal,
}

let controller_cfg = In {
canister_id,
new_controller,
};

match api::call::call(
Principal::management_canister(),
"set_controller",
(controller_cfg,),
)
.await
{
match api::call::call(Principal::management_canister(), "update_settings", (args,)).await {
Ok(x) => x,
Err((code, msg)) => {
return Err(format!(
Expand Down Expand Up @@ -380,17 +380,13 @@ mod wallet {
#[serde(with = "serde_bytes")]
wasm_module: Vec<u8>,
arg: Vec<u8>,
compute_allocation: Option<Nat>,
memory_allocation: Option<Nat>,
}

let install_config = CanisterInstall {
mode: InstallMode::Install,
canister_id: canister_id.clone(),
wasm_module: wasm_module.clone(),
arg: b" ".to_vec(),
compute_allocation: None,
memory_allocation: None,
};

match api::call::call(
Expand Down Expand Up @@ -443,13 +439,28 @@ mod wallet {
Some(o) => o,
};

let create_result = create_canister_call(args.cycles).await?;
let args_without_controller = CreateCanisterArgs {
cycles: args.cycles,
settings: CanisterSettings {
controller: None,
..args.clone().settings
},
};

let create_result = create_canister_call(args_without_controller).await?;

install_wallet(&create_result.canister_id, wasm_module.clone().into_vec()).await?;

// Set controller
if let Some(new_controller) = args.controller {
set_controller_call(create_result.canister_id.clone(), new_controller, true).await?;
if args.settings.controller.is_some() {
update_settings_call(
UpdateSettingsArgs {
canister_id: create_result.canister_id.clone(),
settings: args.settings,
},
true,
)
.await?;
}
super::update_chart();
Ok(create_result)
Expand Down

0 comments on commit b5e38e1

Please sign in to comment.