Skip to content
Merged
106 changes: 88 additions & 18 deletions rs/nns/governance/api/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
// Some Conventions
// ================
//
// One of the patterns you might notice here is pairs of super similar types. In
// fact, it might be hard to spot the difference(s)! One type will be named
// something like Widget, while the other is named WidgetRequest. Depending on
// where you come from, WidgetRequest is a misnomer, because it does not imply
// that the Governance canister has a method named widget (whose argument is of
// type WidgetRequest). Rather, what's really going on in such cases is this:
// Widget is nested (deeply) within responses, while WidgetRequest is nested
// (deeply) within requests. The reason for split is usually that WidgetRequest
// contains some large blob, such as a wasm, while Widget only has the hash of
// that blob. So yes, they are super similar to one another, but they are NOT
// interchangeable! In some cases, the large blob is buried deep within the
// type), and so, it is not obvious why the pair of types exists. Nevertheless,
// even in such cases, this request vs. response distinction is still
// needed. This is, of course, pretty confusing and unfortunate; it came about
// exactly as you would imagine: it growed organically. Sigh.

#![allow(clippy::all)]
use candid::{Int, Nat};
use ic_base_types::{CanisterId, PrincipalId};
Expand Down Expand Up @@ -669,6 +688,8 @@ pub mod proposal {
TakeCanisterSnapshot(super::TakeCanisterSnapshot),
/// Load a canister snapshot.
LoadCanisterSnapshot(super::LoadCanisterSnapshot),
/// Create a canister in a (possibly non-NNS) subnet and install code into it.
CreateCanisterAndInstallCode(super::CreateCanisterAndInstallCode),
}
}
/// Empty message to use in oneof fields that represent empty
Expand Down Expand Up @@ -1429,6 +1450,7 @@ pub enum ProposalActionRequest {
BlessAlternativeGuestOsVersion(BlessAlternativeGuestOsVersion),
TakeCanisterSnapshot(TakeCanisterSnapshot),
LoadCanisterSnapshot(LoadCanisterSnapshot),
CreateCanisterAndInstallCode(CreateCanisterAndInstallCodeRequest),
}

#[derive(
Expand Down Expand Up @@ -2567,6 +2589,9 @@ pub mod install_code {
pub struct InstallCodeRequest {
pub canister_id: ::core::option::Option<PrincipalId>,
pub install_mode: ::core::option::Option<i32>,
// If we add support for chunked WASMs later, the WasmModule type should
// probably be used in place of this field in order to be consistent with
// CreateCanisterAndInstallCodeRequest.
#[serde(deserialize_with = "ic_utils::deserialize::deserialize_option_blob")]
pub wasm_module: ::core::option::Option<::prost::alloc::vec::Vec<u8>>,
#[serde(deserialize_with = "ic_utils::deserialize::deserialize_option_blob")]
Expand Down Expand Up @@ -2635,10 +2660,27 @@ pub struct UpdateCanisterSettings {
/// The target canister ID to call update_settings on. Required.
pub canister_id: Option<PrincipalId>,
/// The settings to update. Required.
pub settings: Option<update_canister_settings::CanisterSettings>,
pub settings: Option<CanisterSettings>,
}
/// Nested message and enum types in `UpdateCanisterSettings`.
pub mod update_canister_settings {

/// The CanisterSettings struct as defined in the ic-interface-spec
/// <https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-candid.>
#[derive(
candid::CandidType, candid::Deserialize, serde::Serialize, Clone, PartialEq, Debug, Default,
)]
pub struct CanisterSettings {
pub controllers: Option<canister_settings::Controllers>,
pub compute_allocation: Option<u64>,
pub memory_allocation: Option<u64>,
pub freezing_threshold: Option<u64>,
pub log_visibility: Option<i32>,
pub snapshot_visibility: Option<i32>,
pub wasm_memory_limit: Option<u64>,
pub wasm_memory_threshold: Option<u64>,
}

/// Nested message and enum types in `CanisterSettings`.
pub mod canister_settings {
use super::*;

/// The controllers of the canister. We use a message to wrap the repeated field because prost does
Expand All @@ -2650,21 +2692,7 @@ pub mod update_canister_settings {
/// The controllers of the canister.
pub controllers: Vec<PrincipalId>,
}
/// The CanisterSettings struct as defined in the ic-interface-spec
/// <https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-candid.>
#[derive(
candid::CandidType, candid::Deserialize, serde::Serialize, Clone, PartialEq, Debug, Default,
)]
pub struct CanisterSettings {
pub controllers: Option<Controllers>,
pub compute_allocation: Option<u64>,
pub memory_allocation: Option<u64>,
pub freezing_threshold: Option<u64>,
pub log_visibility: Option<i32>,
pub wasm_memory_limit: Option<u64>,
pub wasm_memory_threshold: Option<u64>,
pub snapshot_visibility: Option<i32>,
}

/// Log visibility of a canister.
#[derive(
candid::CandidType,
Expand Down Expand Up @@ -2812,6 +2840,48 @@ pub struct LoadCanisterSnapshot {
pub snapshot_id: Option<Vec<u8>>,
}

/// A WASM module. Currently only supports inlined WASMs.
/// This type is only used in requests (proposal submission), not in responses.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, Clone, PartialEq, Debug)]
pub enum WasmModule {
Inlined(Vec<u8>),
}

/// Create a canister in a (possibly non-NNS) subnet and install code into it.
/// This is the response type: only hashes are included, not the full WASM or install_arg.
#[derive(
candid::CandidType, candid::Deserialize, serde::Serialize, Clone, PartialEq, Debug, Default,
)]
pub struct CreateCanisterAndInstallCode {
/// The subnet where the canister will be created.
pub host_subnet_id: Option<PrincipalId>,
/// Settings for the new canister.
pub canister_settings: Option<CanisterSettings>,
/// Derived from the WASM content in the proposal. Cached to speed up
/// responses by avoiding re-calculation.
#[serde(deserialize_with = "ic_utils::deserialize::deserialize_option_blob")]
pub wasm_module_hash: Option<Vec<u8>>,
/// Derived from the install_arg in the proposal. Cached to speed up
/// responses by avoiding re-calculation.
#[serde(deserialize_with = "ic_utils::deserialize::deserialize_option_blob")]
pub install_arg_hash: Option<Vec<u8>>,
}

/// Create a canister in a (possibly non-NNS) subnet and install code into it.
/// This is the submission type: includes the full WASM and install_arg.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, Clone, PartialEq, Debug)]
pub struct CreateCanisterAndInstallCodeRequest {
/// The subnet where the canister will be created.
pub host_subnet_id: Option<PrincipalId>,
/// Settings for the new canister.
pub canister_settings: Option<CanisterSettings>,
/// The WASM module to install.
pub wasm_module: Option<WasmModule>,
/// The argument to pass to the canister's install handler.
#[serde(deserialize_with = "ic_utils::deserialize::deserialize_option_blob")]
pub install_arg: Option<Vec<u8>>,
}

/// This represents the whole NNS governance system. It contains all
/// information about the NNS governance system that must be kept
/// across upgrades of the NNS governance system.
Expand Down
23 changes: 23 additions & 0 deletions rs/nns/governance/canister/governance.did
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type Action = variant {
BlessAlternativeGuestOsVersion : BlessAlternativeGuestOsVersion;
TakeCanisterSnapshot : TakeCanisterSnapshot;
LoadCanisterSnapshot : LoadCanisterSnapshot;
CreateCanisterAndInstallCode : CreateCanisterAndInstallCode;
};

type AddHotKey = record {
Expand Down Expand Up @@ -232,6 +233,20 @@ type Countries = record {
iso_codes : vec text;
};

type CreateCanisterAndInstallCode = record {
host_subnet_id : opt principal;
canister_settings : opt CanisterSettings;
wasm_module_hash : opt blob;
install_arg_hash : opt blob;
};

type CreateCanisterAndInstallCodeRequest = record {
host_subnet_id : opt principal;
canister_settings : opt CanisterSettings;
wasm_module : opt WasmModule;
install_arg : opt blob;
};

type CreateServiceNervousSystem = record {
url : opt text;
governance_parameters : opt GovernanceParameters;
Expand Down Expand Up @@ -436,6 +451,9 @@ type InstallCode = record {

type InstallCodeRequest = record {
arg : opt blob;
// If we add support for chunked WASMs later, the WasmModule type should
// probably be used in place of this field in order to be consistent with
// CreateCanisterAndInstallCodeRequest.
wasm_module : opt blob;
skip_stopping_before_installing : opt bool;
canister_id : opt principal;
Expand Down Expand Up @@ -1051,6 +1069,7 @@ type ProposalActionRequest = variant {
BlessAlternativeGuestOsVersion : BlessAlternativeGuestOsVersion;
TakeCanisterSnapshot : TakeCanisterSnapshot;
LoadCanisterSnapshot : LoadCanisterSnapshot;
CreateCanisterAndInstallCode : CreateCanisterAndInstallCodeRequest;
};

// Creates a rented subnet from a rental request (in the Subnet Rental
Expand Down Expand Up @@ -1413,6 +1432,10 @@ type CustomProposalCriticality = record {
additional_critical_native_action_ids : opt vec nat64;
};

type WasmModule = variant {
Inlined : blob;
};

type WaitForQuietState = record {
current_deadline_timestamp_seconds : nat64;
};
Expand Down
72 changes: 55 additions & 17 deletions rs/nns/governance/proto/ic_nns_governance/pb/v1/governance.proto
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,8 @@ message Proposal {
TakeCanisterSnapshot take_canister_snapshot = 32;
// Load a canister snapshot.
LoadCanisterSnapshot load_canister_snapshot = 33;
// Create a canister in a (possibly non-NNS) subnet and install code into it.
CreateCanisterAndInstallCode create_canister_and_install_code = 34;
}
}

Expand Down Expand Up @@ -1888,6 +1890,9 @@ message InstallCode {
optional CanisterInstallMode install_mode = 2;

// The wasm module to install. required.
// If we add support for chunked WASMs later, the WasmModule type should
// probably be used in place of this field in order to be consistent with
// CreateCanisterAndInstallCode.
optional bytes wasm_module = 3;
// The arg to pass to the canister. Optional.
optional bytes arg = 4;
Expand All @@ -1913,10 +1918,9 @@ message StopOrStartCanister {
optional CanisterAction action = 2;
}

message UpdateCanisterSettings {
// The target canister ID to call update_settings on. Required.
optional ic_base_types.pb.v1.PrincipalId canister_id = 1;

// The CanisterSettings struct as defined in the ic-interface-spec
// https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-candid.
message CanisterSettings {
// Log visibility of a canister.
enum LogVisibility {
LOG_VISIBILITY_UNSPECIFIED = 0;
Expand All @@ -1935,25 +1939,26 @@ message UpdateCanisterSettings {
SNAPSHOT_VISIBILITY_PUBLIC = 2;
}

// The controllers of the canister. We use a message to wrap the repeated field because prost does
// We used a message to wrap the repeated field because prost does
// not generate `Option<Vec<T>>` for repeated fields.
message Controllers {
// The controllers of the canister.
repeated ic_base_types.pb.v1.PrincipalId controllers = 1;
}

// The CanisterSettings struct as defined in the ic-interface-spec
// https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-candid.
message CanisterSettings {
optional Controllers controllers = 1;
optional uint64 compute_allocation = 2;
optional uint64 memory_allocation = 3;
optional uint64 freezing_threshold = 4;
optional LogVisibility log_visibility = 5;
optional uint64 wasm_memory_limit = 6;
optional uint64 wasm_memory_threshold = 7;
optional SnapshotVisibility snapshot_visibility = 8;
}
optional Controllers controllers = 1;
optional uint64 compute_allocation = 2;
optional uint64 memory_allocation = 3;
optional uint64 freezing_threshold = 4;
optional LogVisibility log_visibility = 5;
optional uint64 wasm_memory_limit = 6;
optional uint64 wasm_memory_threshold = 7;
optional SnapshotVisibility snapshot_visibility = 8;
}

message UpdateCanisterSettings {
// The target canister ID to call update_settings on. Required.
optional ic_base_types.pb.v1.PrincipalId canister_id = 1;

// The settings to update. Required.
optional CanisterSettings settings = 2;
Expand All @@ -1979,6 +1984,39 @@ message LoadCanisterSnapshot {
bytes snapshot_id = 2;
}

// A WASM module. Currently only supports inlined WASMs.
message WasmModule {
oneof content {
bytes inlined = 1;
// Chunked WASMs could be added here as another oneof variant.
}
// Derived from the `content` field. Cached here to speed up responses by
// avoiding re-calculation.
optional bytes hash = 10;
}

// Create a canister in a (possibly non-NNS) subnet and install code into it.
// The canister is created by the NNS Root canister, which becomes its default
// controller.
message CreateCanisterAndInstallCode {
// The subnet where the canister will be created.
optional ic_base_types.pb.v1.PrincipalId host_subnet_id = 1;

// Settings for the new canister.
// If not specified, defaults are used (Root becomes the sole controller).
optional CanisterSettings canister_settings = 2;

// The WASM module to install.
optional WasmModule wasm_module = 3;

// The argument to pass to the canister's install handler.
optional bytes install_arg = 4;

// Derived from the `install_arg` field. Cached here to speed up responses by
// avoiding re-calculation.
optional bytes install_arg_hash = 6;
}

// Snapshot of a neuron's dissolve state, recorded before clamping to the
// Mission 70 maximum. Used to restore the original dissolve state if the
// maximum dissolve delay is ever increased again.
Expand Down
Loading
Loading