-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2e0a7b0
commit f096246
Showing
8 changed files
with
438 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use anyhow::Context; | ||
use candid::Decode; | ||
use ic_sns_governance::pb::v1::{ | ||
manage_neuron_response::Command, GovernanceError, ManageNeuronResponse, | ||
}; | ||
|
||
use crate::lib::{e8s_to_tokens, AnyhowResult}; | ||
|
||
pub fn display_manage_neuron(blob: &[u8]) -> AnyhowResult<String> { | ||
let response = Decode!(blob, ManageNeuronResponse)?; | ||
let command = response.command.context("command was null")?; | ||
let fmt = match command { | ||
Command::Error(error) => display_governance_error(error), | ||
Command::Configure(_) => "Neuron successfully configured".to_string(), | ||
Command::RegisterVote(_) => "Successfully voted".to_string(), | ||
Command::Follow(_) => "Successfully set following relationship".to_string(), | ||
Command::AddNeuronPermission(_) => "Successfully added neuron permissions".to_string(), | ||
Command::RemoveNeuronPermission(_) => "Successfully removed neuron permissions".to_string(), | ||
Command::Disburse(c) => format!( | ||
"Successfully disbursed ICP at block index {}", | ||
c.transfer_block_height | ||
), | ||
Command::ClaimOrRefresh(c) => { | ||
if let Some(id) = c.refreshed_neuron_id { | ||
format!("Successfully updated the stake of neuron {id}") | ||
} else { | ||
"Successfully updated the stake of unknown neuron".to_string() | ||
} | ||
} | ||
Command::DisburseMaturity(c) => format!( | ||
"Successfully disbursed {} maturity", | ||
c.amount_deducted_e8s() | ||
), | ||
Command::MakeProposal(c) => { | ||
if let Some(id) = c.proposal_id { | ||
format!("Successfully created new proposal with ID {id}", id = id.id) | ||
} else { | ||
"Successfully created new proposal with unknown ID".to_string() | ||
} | ||
} | ||
Command::MergeMaturity(c) => format!( | ||
"Successfully merged {merged} maturity (total stake now {total})", | ||
merged = e8s_to_tokens(c.merged_maturity_e8s.into()), | ||
total = e8s_to_tokens(c.new_stake_e8s.into()) | ||
), | ||
Command::Split(c) => { | ||
if let Some(id) = c.created_neuron_id { | ||
format!("Neuron successfully split off to new neuron {id}") | ||
} else { | ||
"Neuron successfully split off to unknown new neuron".to_string() | ||
} | ||
} | ||
Command::StakeMaturity(c) => format!( | ||
"Successfully staked maturity ({staked} staked maturity total, {remaining} unstaked)", | ||
staked = e8s_to_tokens(c.staked_maturity_e8s.into()), | ||
remaining = e8s_to_tokens(c.maturity_e8s.into()) | ||
), | ||
}; | ||
Ok(fmt) | ||
} | ||
|
||
pub fn display_governance_error(err: GovernanceError) -> String { | ||
format!("SNS governance error: {}", err.error_message) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
use candid::{Decode, Principal}; | ||
use ic_sns_root::{CanisterSummary, GetSnsCanistersSummaryResponse}; | ||
use indicatif::HumanBytes; | ||
use itertools::Itertools; | ||
use std::fmt::Write; | ||
|
||
use crate::lib::{format::format_n_cycles, AnyhowResult}; | ||
|
||
use super::format_t_cycles; | ||
|
||
pub fn display_canisters_summary(blob: &[u8]) -> AnyhowResult<String> { | ||
let response = Decode!(blob, GetSnsCanistersSummaryResponse)?; | ||
let root = response.root_canister_summary().canister_id().0; | ||
let governance = response.governance_canister_summary().canister_id().0; | ||
let mut fmt = format!( | ||
"\ | ||
System canisters: | ||
Root: | ||
{root} | ||
Governance: | ||
{governance} | ||
Ledger: | ||
{ledger} | ||
Index: | ||
{index} | ||
Swap: | ||
{swap}", | ||
root = display_canister_summary(response.root_canister_summary(), root, governance)?, | ||
governance = | ||
display_canister_summary(response.governance_canister_summary(), root, governance)?, | ||
ledger = display_canister_summary(response.ledger_canister_summary(), root, governance)?, | ||
index = display_canister_summary(response.index_canister_summary(), root, governance)?, | ||
swap = display_canister_summary(response.swap_canister_summary(), root, governance)?, | ||
); | ||
if !response.dapps.is_empty() { | ||
fmt.push_str("\n\nDapp canisters:"); | ||
for dapp in &response.dapps { | ||
write!( | ||
fmt, | ||
"\n\n{}", | ||
display_canister_summary(dapp, root, governance)? | ||
)?; | ||
} | ||
} | ||
if !response.archives.is_empty() { | ||
fmt.push_str("\n\nArchive canisters:"); | ||
for archive in &response.archives { | ||
write!( | ||
fmt, | ||
"\n\n{}", | ||
display_canister_summary(archive, root, governance)? | ||
)?; | ||
} | ||
} | ||
Ok(fmt) | ||
} | ||
|
||
fn display_canister_summary( | ||
summary: &CanisterSummary, | ||
root: Principal, | ||
governance: Principal, | ||
) -> AnyhowResult<String> { | ||
const NNS_ROOT: Principal = | ||
Principal::from_slice(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01]); | ||
let status = summary.status(); | ||
let canister_id = summary.canister_id(); | ||
let mut fmt = format!( | ||
"\ | ||
Canister ID: {canister_id}, status: {status:?} | ||
Cycles: {cycles}, memory usage: {memory}", | ||
status = status.status(), | ||
cycles = format_t_cycles(status.cycles.clone()), | ||
memory = HumanBytes(status.memory_size().get()) | ||
); | ||
if let Some(hash) = &status.module_hash { | ||
write!(fmt, "\nInstalled module: hash {}", hex::encode(hash))?; | ||
} | ||
let freezing = &status.settings.freezing_threshold; | ||
let idle = &status.idle_cycles_burned_per_day; | ||
let freezing_time = freezing.clone() / idle.clone(); | ||
write!( | ||
fmt, | ||
" | ||
Freezing threshold: {freezing} cycles ({freezing_time} days at current idle usage of {idle}/day) | ||
Memory allocation: {memory}%, compute allocation: {compute}% | ||
Controllers: {controllers}", | ||
freezing = format_t_cycles(freezing.clone()), | ||
idle = format_n_cycles(idle.clone()), | ||
memory = status.settings.memory_allocation, | ||
compute = status.settings.compute_allocation, | ||
controllers = status | ||
.settings | ||
.controllers | ||
.iter() | ||
.format_with(", ", |c, f| if c.0 == NNS_ROOT { | ||
f(&"NNS root") | ||
} else if c.0 == governance { | ||
f(&"SNS governance") | ||
} else if c.0 == root { | ||
f(&"SNS root") | ||
} else if *c == canister_id { | ||
f(&"self") | ||
} else { | ||
f(c) | ||
}) | ||
)?; | ||
|
||
Ok(fmt) | ||
} |
Oops, something went wrong.