There are parts that usually change in a proposal:
- A new
Action
variant. - A new proposal topic.
- A new
nnsFunction
or changes in one.
The change is not always just in one section. Many times you need to fix two sections simulataneously. For example, a new topic comes with a new nnsFunction
.
The Action
is a type in the Governance candid interface and it's used in the Proposal type:
type Action = variant {
RegisterKnownNeuron : KnownNeuron;
ManageNeuron : ManageNeuron;
ExecuteNnsFunction : ExecuteNnsFunction;
RewardNodeProvider : RewardNodeProvider;
OpenSnsTokenSwap : OpenSnsTokenSwap;
SetSnsTokenSwapOpenTimeWindow : SetSnsTokenSwapOpenTimeWindow;
SetDefaultFollowees : SetDefaultFollowees;
RewardNodeProviders : RewardNodeProviders;
ManageNetworkEconomics : NetworkEconomics;
ApproveGenesisKyc : ApproveGenesisKyc;
AddOrRemoveNodeProvider : AddOrRemoveNodeProvider;
Motion : Motion;
};
type Proposal = record {
url : text;
title : opt text;
action : opt Action;
summary : text;
};
Adding a new Action
variant breaks backwards compatibility.
This means that we need to upgrade the candid files and related, and synchronize the release with the Governance canister.
- Upgrade candid file.
- Add the i18n label in
en.governance.json
.
The topic is a property of the ProposalInfo
and it's of type integer.
type ProposalInfo = record {
id : opt NeuronId;
status : int32;
topic : int32;
failure_reason : opt GovernanceError;
ballots : vec record { nat64; Ballot };
proposal_timestamp_seconds : nat64;
reward_event_round : nat64;
deadline_timestamp_seconds : opt nat64;
failed_timestamp_seconds : nat64;
reject_cost_e8s : nat64;
latest_tally : opt Tally;
reward_status : int32;
decided_timestamp_seconds : nat64;
proposal : opt Proposal;
proposer : opt NeuronId;
executed_timestamp_seconds : nat64;
};
A new topic does not break backwards compatibility. Therefore, there is no need to synchronize releases.
Yet, a proposal of that topic won't be rendered properly until the changes are made and release.
Changes in nns-js:
- Add to topic entry in the governance enum.
- Add topic entry in the
Topic
for proto files. You can search forTOPIC_NEURON_MANAGEMENT
to better see where to add them.
Changes in nns-dapp:
- Add i18n labels in
en.governance.json
. "topics" and "topics_description". - Add i18n labels in
en.json
: "follow_neurons.topic_XX_title" and "follow_neurons.topic_XX_description"
The topic descriptions can be found in governance.proto in IC repo.
The nnsFunction
is a property of the Action
variant ExecuteNnsFunction
. Find it here.
type ExecuteNnsFunction = record { nns_function : int32; payload : vec nat8 };
A new nnsFunction
does not break backwards compatibility. Therefore, there is no need to synchronize releases.
Yet, a proposal of with that nnsFunction
won't be rendered properly until the changes are made and release.
- add
NnsFunction
id inhttps://github.com/dfinity/ic-js/blob/main/packages/nns/src/enums/governance.enums.ts
- update labels in
nns_functions
inen.governance.json
(could be managed by dashboard team)nns_functions
nns_functions_description
- In
Cargo.toml
update the rev using the latest Elect Replica Version - In case of new payload type
- If needed add the dependency (e.g. "ic-sns-swap") in the Cargo.toml (because the new proposal type is executed by new canister)
- Add new payload type (e.g.
AddWasmRequest
) inproposals.rs
- If the payload needs to be transformed for display (e.g. if it is too large), define the type into which the payload must be transformed, then implement
From<OriginalPayloadType
for this new type. (seeNNS function 3 - AddNNSCanister
) (useTrimmed
suffix to define transformed version) - Update the
match nns_function
expression to include the new function (use either identity or transform depending on if the payload needs to be transformed).
- In case the payload uses
transform
instead ofidentity
update the related types andtransform
function. - Build:
cargo build
- Deploy and test on available proposals
- Search for the new nnsFunction ID
- Find its request type definition
- type
UpdateSnsWasmSnsSubnetIds
:-
https://github.com/dfinity/ic/blob/72b96bc88f8d76c16ade62189a6ff81dee9e58e/rs/nns/governance/src/governance.rs#L509e
NnsFunction::UpdateSnsWasmSnsSubnetIds => { (SNS_WASM_CANISTER_ID, "update_sns_subnet_list") }
-
- type
update_sns_subnet_list
:-
https://github.com/dfinity/ic/blob/72b96bc88f8d76c16ade62189a6ff81dee9e58ee/rs/nns/sns-wasm/canister/sns-wasm.did#L126
update_sns_subnet_list : (UpdateSnsSubnetListRequest) -> ( UpdateSnsSubnetListResponse, );
-
- Request type
UpdateSnsSubnetListRequest
:-
https://github.com/dfinity/ic/blob/72b96bc88f8d76c16ade62189a6ff81dee9e58ee/rs/nns/sns-wasm/canister/sns-wasm.did#L107
type UpdateSnsSubnetListRequest = record { sns_subnet_ids_to_add : vec principal; sns_subnet_ids_to_remove : vec principal; };
-
- type
By the request definition we can decide what kind of transformation should be applied (e.g. identity
(34 => identity...
) or custom implementation (e.g. 30 => transform::<AddWasmRequest...
))