Skip to content

Commit

Permalink
Support reinstalling canisters (SNS)
Browse files Browse the repository at this point in the history
  • Loading branch information
anchpop committed May 23, 2024
1 parent fbb0958 commit c751dcf
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 23 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ quill sns make-upgrade-canister-proposal <PROPOSER_NEURON_ID> --target-canister-

## Options

| Option | Description |
|---------------------------------------------|---------------------------------------------------------------------------------------|
| `--canister-upgrade-arg-path <PATH>` | Path to the file containing argument to post-upgrade method of the new canister WASM. |
| `--summary <SUMMARY>` | Summary of the proposal. |
| `--target-canister-id <TARGET_CANISTER_ID>` | Canister to be upgraded. |
| `--title <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. |
| Option | Description |
|---------------------------------------------|----------------------------------------------------------------------------------------|
| `--canister-upgrade-arg-path <PATH>` | Path to the file containing argument to post-upgrade method of the new canister WASM. |
| `--summary <SUMMARY>` | Summary of the proposal. |
| `--target-canister-id <TARGET_CANISTER_ID>` | Canister to be upgraded. |
| `--title <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"). "install" is used by default. |

## Remarks

Expand Down
40 changes: 34 additions & 6 deletions src/commands/sns/make_upgrade_canister_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand All @@ -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())]
Expand Down Expand Up @@ -62,6 +63,11 @@ 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, default_value("install"),
value_parser = ["install", "reinstall", "upgrade"])]
mode: String,
}

pub fn exec(
Expand All @@ -79,7 +85,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) {
Expand All @@ -100,7 +122,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 {
Expand All @@ -112,7 +134,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),
},
)),
};
Expand All @@ -137,14 +159,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: {}
Expand Down
6 changes: 3 additions & 3 deletions tests/output/default/sns/make_proposal/upgrade.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
};
},
Expand Down
6 changes: 3 additions & 3 deletions tests/output/default/sns/make_proposal/upgrade_arg.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
};
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/output/sns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ fn make_proposal() {
quill_sns_send(&format!("sns make-upgrade-canister-proposal {NEURON_ID} --wasm-path '{canister_wasm}' --target-canister-id pycv5-3jbbb-ccccc-ddddd-cai"))
.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");
}
Expand Down

0 comments on commit c751dcf

Please sign in to comment.