Skip to content
Open
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

14 changes: 14 additions & 0 deletions rs/nervous_system/string/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::fmt::Debug;
/// More precisely, middle characters are removed such that the return value has at most `max_len`
/// characters. Some examples:
/// ```
/// use ic_nervous_system_string::clamp_string_len;
/// println!("{}", clamp_string_len("abcdef", 5)); // a...f
/// println!("{}", clamp_string_len("abcde", 5)); // abcde
/// println!("{}", clamp_string_len("abcd", 5)); // abcd
Expand Down Expand Up @@ -41,5 +42,18 @@ pub fn clamp_debug_len(object: &impl Debug, max_len: usize) -> String {
clamp_string_len(&format!("{object:#?}"), max_len)
}

/// Hex-encodes bytes, truncating with a summary if longer than `max_bytes`.
pub fn humanize_blob(bytes: &[u8], max_bytes: usize) -> String {
if bytes.len() <= max_bytes {
bytes.iter().map(|b| format!("{b:02x}")).collect()
} else {
let hex: String = bytes[..max_bytes]
.iter()
.map(|b| format!("{b:02x}"))
.collect();
format!("{hex}... ({} bytes total)", bytes.len())
}
}

#[cfg(test)]
mod tests;
18 changes: 18 additions & 0 deletions rs/nervous_system/string/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,21 @@ fn test_clamp_debug_len() {

assert_eq!(&clamp_debug_len(&S { i: 42 }, 100), "S {\n i: 42,\n}");
}

#[test]
fn test_humanize_blob() {
// Short blob: fully hex-encoded.
assert_eq!(humanize_blob(&[0x00, 0x61, 0x73, 0x6d], 10), "0061736d");

// Exact boundary.
assert_eq!(humanize_blob(&[0xab, 0xcd], 2), "abcd");

// Truncated.
assert_eq!(
humanize_blob(&[0xab, 0xcd, 0xef], 2),
"abcd... (3 bytes total)",
);

// Empty.
assert_eq!(humanize_blob(&[], 10), "");
}
1 change: 1 addition & 0 deletions rs/nns/governance/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ DEPENDENCIES = [
"//rs/nervous_system/rate_limits",
"//rs/nervous_system/root",
"//rs/nervous_system/runtime",
"//rs/nervous_system/string",
"//rs/nervous_system/temporary",
"//rs/nervous_system/time_helpers",
"//rs/nervous_system/timer_task",
Expand Down
1 change: 1 addition & 0 deletions rs/nns/governance/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ ic-metrics-encoder = "1"
ic-nervous-system-canisters = { path = "../../nervous_system/canisters" }
ic-nervous-system-clients = { path = "../../nervous_system/clients" }
ic-nervous-system-common = { path = "../../nervous_system/common" }
ic-nervous-system-string = { path = "../../nervous_system/string" }
ic-nervous-system-common-build-metadata = { path = "../../nervous_system/common/build_metadata" }
ic-nervous-system-common-validation = { path = "../../nervous_system/common/validation" }
ic-nervous-system-governance = { path = "../../nervous_system/governance" }
Expand Down
15 changes: 15 additions & 0 deletions rs/nns/governance/api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2053,6 +2053,21 @@ pub struct ProposalInfo {
pub deadline_timestamp_seconds: Option<u64>,
pub derived_proposal_information: Option<DerivedProposalInformation>,
pub total_potential_voting_power: ::core::option::Option<u64>,
/// When an adopted proposal has been executed successfully, this may contain
/// a value produced by the execution. This is the dual of failure_reason.
pub success_value: Option<SuccessfulProposalExecutionValue>,
}

/// A value produced by successfully executing a proposal.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, Clone, PartialEq, Debug)]
pub enum SuccessfulProposalExecutionValue {
CreateCanisterAndInstallCode(CreateCanisterAndInstallCodeOk),
}

/// The result of a successful CreateCanisterAndInstallCode proposal execution.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, Clone, PartialEq, Debug)]
pub struct CreateCanisterAndInstallCodeOk {
pub canister_id: Option<PrincipalId>,
}

/// Network economics contains the parameters for several operations related
Expand Down
10 changes: 10 additions & 0 deletions rs/nns/governance/canister/governance.did
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,14 @@ type CreateCanisterAndInstallCodeRequest = record {
install_arg : opt blob;
};

type CreateCanisterAndInstallCodeOk = record {
canister_id : opt principal;
};

type SuccessfulProposalExecutionValue = variant {
CreateCanisterAndInstallCode : CreateCanisterAndInstallCodeOk;
};

type CreateServiceNervousSystem = record {
url : opt text;
governance_parameters : opt GovernanceParameters;
Expand Down Expand Up @@ -1163,6 +1171,7 @@ type ProposalData = record {
original_total_community_fund_maturity_e8s_equivalent : opt nat64;
total_potential_voting_power : opt nat64;
topic: opt int32;
success_value : opt SuccessfulProposalExecutionValue;
};

type ProposalInfo = record {
Expand All @@ -1184,6 +1193,7 @@ type ProposalInfo = record {
proposer : opt NeuronId;
executed_timestamp_seconds : nat64;
total_potential_voting_power : opt nat64;
success_value : opt SuccessfulProposalExecutionValue;
};

type RegisterVote = record {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,25 @@ message ProposalData {
// field should not be set in normal circumstances, and if it is set, it is an indicator that a
// bug might have caused the voting power spike.
optional uint64 previous_ballots_timestamp_seconds = 24;

// When an adopted proposal has been executed successfully, this may contain
// a value produced by the execution (e.g. the ID of a newly created canister).
// This is the dual of failure_reason: that field is populated on failure,
// this field is populated on success.
optional SuccessfulProposalExecutionValue success_value = 25;
}

// A value produced by successfully executing a proposal.
// Not all proposal types produce a value; for those that don't, this field
// is simply not set.
message SuccessfulProposalExecutionValue {
oneof proposal_type {
CreateCanisterAndInstallCodeOk create_canister_and_install_code = 1;
}
}

message CreateCanisterAndInstallCodeOk {
ic_base_types.pb.v1.PrincipalId canister_id = 1;
}

// This structure contains data for settling the Neurons' Fund participation in an SNS token swap.
Expand Down
4 changes: 2 additions & 2 deletions rs/nns/governance/src/canister_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ impl Environment for CanisterEnv {
execute_nns_function: &ValidExecuteNnsFunction,
) -> Result<(), crate::pb::v1::GovernanceError> {
let reply = move || {
governance_mut().set_proposal_execution_status(proposal_id, Ok(()));
governance_mut().set_proposal_execution_status::<()>(proposal_id, Ok(vec![]));
};
let reject = move |(code, msg): (i32, String)| {
let mut msg = msg;
Expand All @@ -209,7 +209,7 @@ impl Environment for CanisterEnv {
.collect();
}

governance_mut().set_proposal_execution_status(
governance_mut().set_proposal_execution_status::<()>(
proposal_id,
Err(GovernanceError::new_with_message(
ErrorType::External,
Expand Down
54 changes: 54 additions & 0 deletions rs/nns/governance/src/gen/ic_nns_governance.pb.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,60 @@ pub struct ProposalData {
/// bug might have caused the voting power spike.
#[prost(uint64, optional, tag = "24")]
pub previous_ballots_timestamp_seconds: ::core::option::Option<u64>,
/// When an adopted proposal has been executed successfully, this may contain
/// a value produced by the execution (e.g. the ID of a newly created canister).
/// This is the dual of failure_reason: that field is populated on failure,
/// this field is populated on success.
#[prost(message, optional, tag = "25")]
pub success_value: ::core::option::Option<SuccessfulProposalExecutionValue>,
}
/// A value produced by successfully executing a proposal.
/// Not all proposal types produce a value; for those that don't, this field
/// is simply not set.
#[derive(
candid::CandidType,
candid::Deserialize,
serde::Serialize,
comparable::Comparable,
Clone,
PartialEq,
::prost::Message,
)]
pub struct SuccessfulProposalExecutionValue {
#[prost(
oneof = "successful_proposal_execution_value::ProposalType",
tags = "1"
)]
pub proposal_type: ::core::option::Option<successful_proposal_execution_value::ProposalType>,
}
/// Nested message and enum types in `SuccessfulProposalExecutionValue`.
pub mod successful_proposal_execution_value {
#[derive(
candid::CandidType,
candid::Deserialize,
serde::Serialize,
comparable::Comparable,
Clone,
PartialEq,
::prost::Oneof,
)]
pub enum ProposalType {
#[prost(message, tag = "1")]
CreateCanisterAndInstallCode(super::CreateCanisterAndInstallCodeOk),
}
}
#[derive(
candid::CandidType,
candid::Deserialize,
serde::Serialize,
comparable::Comparable,
Clone,
PartialEq,
::prost::Message,
)]
pub struct CreateCanisterAndInstallCodeOk {
#[prost(message, optional, tag = "1")]
pub canister_id: ::core::option::Option<::ic_base_types::PrincipalId>,
}
/// This structure contains data for settling the Neurons' Fund participation in an SNS token swap.
#[derive(
Expand Down
Loading
Loading