From ed77290a27a5df5b330889b068773d2ebec28206 Mon Sep 17 00:00:00 2001 From: Andre Popovitch Date: Fri, 24 May 2024 11:47:16 -0500 Subject: [PATCH 1/2] Support reinstalling canisters (SNS) --- CHANGELOG.md | 2 + Cargo.lock | 1 + Cargo.toml | 1 + ...ill-sns-make-upgrade-canister-proposal.mdx | 1 + .../sns/make_upgrade_canister_proposal.rs | 39 ++++++++++++++++--- .../default/sns/make_proposal/upgrade.txt | 6 +-- .../default/sns/make_proposal/upgrade_arg.txt | 6 +-- .../make_proposal/upgrade_summary_path.txt | 2 +- tests/output/sns.rs | 6 +-- 9 files changed, 48 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ea721b..50d1f06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Overhauled output format. All commands besides `quill sns` should have human-readable output instead of candid IDL. Candid IDL format can be forced with `--raw`. +- Added support for setting the install mode for UpgradeSnsControlledCanister proposals. + ## [0.4.4] - 2024-03-21 - Fixed `quill sns make-proposal` setting some fields to null. diff --git a/Cargo.lock b/Cargo.lock index 120493c..b8599e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4897,6 +4897,7 @@ dependencies = [ "ic-base-types", "ic-ckbtc-minter", "ic-identity-hsm", + "ic-management-canister-types", "ic-nervous-system-common", "ic-nns-common", "ic-nns-constants", diff --git a/Cargo.toml b/Cargo.toml index 4a395c2..f0a69ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ license = "Apache-2.0" [dependencies] ic-base-types = { git = "https://github.com/dfinity/ic", rev = "479fc39a7ee082a62ec070efeed224784a83eb1b" } ic-ckbtc-minter = { git = "https://github.com/dfinity/ic", rev = "479fc39a7ee082a62ec070efeed224784a83eb1b" } +ic-management-canister-types = { git = "https://github.com/dfinity/ic", rev = "479fc39a7ee082a62ec070efeed224784a83eb1b" } ic-nervous-system-common = { git = "https://github.com/dfinity/ic", rev = "479fc39a7ee082a62ec070efeed224784a83eb1b" } ic-nns-common = { git = "https://github.com/dfinity/ic", rev = "479fc39a7ee082a62ec070efeed224784a83eb1b" } ic-nns-constants = { git = "https://github.com/dfinity/ic", rev = "479fc39a7ee082a62ec070efeed224784a83eb1b" } diff --git a/docs/cli-reference/sns/quill-sns-make-upgrade-canister-proposal.mdx b/docs/cli-reference/sns/quill-sns-make-upgrade-canister-proposal.mdx index 275163a..1669437 100644 --- a/docs/cli-reference/sns/quill-sns-make-upgrade-canister-proposal.mdx +++ b/docs/cli-reference/sns/quill-sns-make-upgrade-canister-proposal.mdx @@ -36,6 +36,7 @@ quill sns make-upgrade-canister-proposal --target-canister- | `--title ` | Title of the proposal. | | `--url <URL>` | URL of the proposal. | | `--wasm-path <WASM_PATH>` | Path to the WASM file to be installed into the target canister. | +| `--mode <MODE>` | The install mode ("install", "reinstall", or "upgrade"). | ## Remarks diff --git a/src/commands/sns/make_upgrade_canister_proposal.rs b/src/commands/sns/make_upgrade_canister_proposal.rs index b817a12..d1333c3 100644 --- a/src/commands/sns/make_upgrade_canister_proposal.rs +++ b/src/commands/sns/make_upgrade_canister_proposal.rs @@ -12,6 +12,7 @@ use candid::Principal; use candid::{Encode, IDLArgs}; use candid_parser::parse_idl_args; use clap::Parser; +use ic_management_canister_types::CanisterInstallMode; use ic_sns_governance::pb::v1::{ manage_neuron, proposal, ManageNeuron, Proposal, UpgradeSnsControlledCanister, }; @@ -27,8 +28,8 @@ pub struct MakeUpgradeCanisterProposalOpts { proposer_neuron_id: ParsedSnsNeuron, /// Title of the proposal. - #[arg(long, default_value_t = String::from("Upgrade Canister"))] - title: String, + #[clap(long)] + title: Option<String>, /// URL of the proposal. #[arg(long, default_value_t = String::new())] @@ -62,6 +63,10 @@ pub struct MakeUpgradeCanisterProposalOpts { /// Path to the binary file containing argument to post-upgrade method of the new canister WASM. #[arg(long, conflicts_with = "canister_upgrade_arg")] canister_upgrade_arg_path: Option<String>, + + /// The install mode. + #[arg(long, short, value_parser = ["install", "reinstall", "upgrade"])] + mode: String, } pub fn exec( @@ -79,7 +84,23 @@ pub fn exec( wasm_path, canister_upgrade_arg, canister_upgrade_arg_path, + mode, } = opts; + let mode = match mode.as_str() { + "install" => CanisterInstallMode::Install, + "reinstall" => CanisterInstallMode::Reinstall, + "upgrade" => CanisterInstallMode::Upgrade, + _ => return Err(Error::msg("Invalid mode.")), + }; + + let title = title.unwrap_or_else(|| { + match mode { + CanisterInstallMode::Install => "Install Canister", + CanisterInstallMode::Reinstall => "Reinstall Canister", + CanisterInstallMode::Upgrade => "Upgrade Canister", + } + .to_string() + }); let wasm = std::fs::read(wasm_path).context("Unable to read --wasm-path.")?; let canister_upgrade_arg = match (canister_upgrade_arg, canister_upgrade_arg_path) { @@ -100,7 +121,7 @@ pub fn exec( String::from_utf8(std::fs::read(path).context("Unable to read --summary-path.")?) .context("Summary must be valid UTF-8.")? } - (None, None) => summarize(target_canister_id, &wasm), + (None, None) => summarize(target_canister_id, &wasm, mode), }; let proposal = Proposal { @@ -112,7 +133,7 @@ pub fn exec( canister_id: Some(target_canister_id.into()), new_canister_wasm: wasm, canister_upgrade_arg, - mode: None, + mode: Some(mode as i32), }, )), }; @@ -137,14 +158,20 @@ pub fn exec( Ok(vec![msg]) } -fn summarize(target_canister_id: Principal, wasm: &Vec<u8>) -> String { +fn summarize(target_canister_id: Principal, wasm: &Vec<u8>, mode: CanisterInstallMode) -> String { // Fingerprint wasm. let mut hasher = Sha256::new(); hasher.update(wasm); let wasm_fingerprint = hex::encode(hasher.finalize()); + let action = match mode { + CanisterInstallMode::Install => "Install", + CanisterInstallMode::Reinstall => "Reinstall", + CanisterInstallMode::Upgrade => "Upgrade", + }; + format!( - "Upgrade canister: + "{action} canister: ID: {} diff --git a/tests/output/default/sns/make_proposal/upgrade.txt b/tests/output/default/sns/make_proposal/upgrade.txt index aef88ef..5bba120 100644 --- a/tests/output/default/sns/make_proposal/upgrade.txt +++ b/tests/output/default/sns/make_proposal/upgrade.txt @@ -10,16 +10,16 @@ Sending message with command = opt variant { MakeProposal = record { url = ""; - title = "Upgrade Canister"; + title = "Install Canister"; action = opt variant { UpgradeSnsControlledCanister = record { new_canister_wasm = blob "\00\61\73\6d\01\00\00\00"; - mode = null; + mode = opt (1 : int32); canister_id = opt principal "pycv5-3jbbb-ccccc-ddddd-cai"; canister_upgrade_arg = null; } }; - summary = "Upgrade canister:\n\n ID: pycv5-3jbbb-ccccc-ddddd-cai\n\n WASM:\n length: 8\n fingerprint: 93a44bbb96c751218e4c00d479e4c14358122a389acca16205b1e4d0dc5f9476"; + summary = "Install canister:\n\n ID: pycv5-3jbbb-ccccc-ddddd-cai\n\n WASM:\n length: 8\n fingerprint: 93a44bbb96c751218e4c00d479e4c14358122a389acca16205b1e4d0dc5f9476"; } }; }, diff --git a/tests/output/default/sns/make_proposal/upgrade_arg.txt b/tests/output/default/sns/make_proposal/upgrade_arg.txt index a9c1b6e..1960113 100644 --- a/tests/output/default/sns/make_proposal/upgrade_arg.txt +++ b/tests/output/default/sns/make_proposal/upgrade_arg.txt @@ -10,16 +10,16 @@ Sending message with command = opt variant { MakeProposal = record { url = ""; - title = "Upgrade Canister"; + title = "Reinstall Canister"; action = opt variant { UpgradeSnsControlledCanister = record { new_canister_wasm = blob "\00\61\73\6d\01\00\00\00"; - mode = null; + mode = opt (2 : int32); canister_id = opt principal "pycv5-3jbbb-ccccc-ddddd-cai"; canister_upgrade_arg = opt blob "\44\49\44\4c\01\6c\02\b9\fa\ee\18\79\b5\f6\a1\43\79\01\00\02\00\00\00\03\00\00\00"; } }; - summary = "Upgrade canister:\n\n ID: pycv5-3jbbb-ccccc-ddddd-cai\n\n WASM:\n length: 8\n fingerprint: 93a44bbb96c751218e4c00d479e4c14358122a389acca16205b1e4d0dc5f9476"; + summary = "Reinstall canister:\n\n ID: pycv5-3jbbb-ccccc-ddddd-cai\n\n WASM:\n length: 8\n fingerprint: 93a44bbb96c751218e4c00d479e4c14358122a389acca16205b1e4d0dc5f9476"; } }; }, diff --git a/tests/output/default/sns/make_proposal/upgrade_summary_path.txt b/tests/output/default/sns/make_proposal/upgrade_summary_path.txt index 43c2371..31e1d54 100644 --- a/tests/output/default/sns/make_proposal/upgrade_summary_path.txt +++ b/tests/output/default/sns/make_proposal/upgrade_summary_path.txt @@ -14,7 +14,7 @@ Sending message with action = opt variant { UpgradeSnsControlledCanister = record { new_canister_wasm = blob "\00\61\73\6d\01\00\00\00"; - mode = null; + mode = opt (3 : int32); canister_id = opt principal "pycv5-3jbbb-ccccc-ddddd-cai"; canister_upgrade_arg = null; } diff --git a/tests/output/sns.rs b/tests/output/sns.rs index 8049ad7..55b2c34 100644 --- a/tests/output/sns.rs +++ b/tests/output/sns.rs @@ -134,16 +134,16 @@ fn make_proposal() { .diff("sns/make_proposal/from_file.txt"); let canister_wasm = asset("sns_canister.wasm"); - quill_sns_send(&format!("sns make-upgrade-canister-proposal {NEURON_ID} --wasm-path '{canister_wasm}' --target-canister-id pycv5-3jbbb-ccccc-ddddd-cai")) + quill_sns_send(&format!("sns make-upgrade-canister-proposal {NEURON_ID} --wasm-path '{canister_wasm}' --target-canister-id pycv5-3jbbb-ccccc-ddddd-cai --mode install")) .diff("sns/make_proposal/upgrade.txt"); quill_sns_send(&format!("sns make-upgrade-canister-proposal {NEURON_ID} --wasm-path '{canister_wasm}' - --canister-upgrade-arg '(record {{major=2:nat32; minor=3:nat32;}})' --target-canister-id pycv5-3jbbb-ccccc-ddddd-cai")) + --canister-upgrade-arg '(record {{major=2:nat32; minor=3:nat32;}})' --target-canister-id pycv5-3jbbb-ccccc-ddddd-cai --mode reinstall")) .diff("sns/make_proposal/upgrade_arg.txt"); let upgrade_summary = asset("upgrade_summary.txt"); quill_sns_send(&format!( "sns make-upgrade-canister-proposal {NEURON_ID} --wasm-path '{canister_wasm}' - --target-canister-id pycv5-3jbbb-ccccc-ddddd-cai --summary-path '{upgrade_summary}'" + --target-canister-id pycv5-3jbbb-ccccc-ddddd-cai --summary-path '{upgrade_summary}' --mode upgrade" )) .diff("sns/make_proposal/upgrade_summary_path.txt"); } From d6c574b9668d4a58010e763b67d636101d9a2fe5 Mon Sep 17 00:00:00 2001 From: Severin Siffert <severin.siffert@dfinity.org> Date: Wed, 29 May 2024 09:33:53 +0200 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Adam Spofford <93943719+adamspofford-dfinity@users.noreply.github.com> --- src/commands/sns/make_upgrade_canister_proposal.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/sns/make_upgrade_canister_proposal.rs b/src/commands/sns/make_upgrade_canister_proposal.rs index d1333c3..e4372c4 100644 --- a/src/commands/sns/make_upgrade_canister_proposal.rs +++ b/src/commands/sns/make_upgrade_canister_proposal.rs @@ -28,7 +28,7 @@ pub struct MakeUpgradeCanisterProposalOpts { proposer_neuron_id: ParsedSnsNeuron, /// Title of the proposal. - #[clap(long)] + #[arg(long)] title: Option<String>, /// URL of the proposal. @@ -65,7 +65,7 @@ pub struct MakeUpgradeCanisterProposalOpts { canister_upgrade_arg_path: Option<String>, /// The install mode. - #[arg(long, short, value_parser = ["install", "reinstall", "upgrade"])] + #[arg(long, value_parser = ["install", "reinstall", "upgrade"])] mode: String, }