Skip to content

Commit

Permalink
chore(sns): Duplicate ClaimSwapNeuronsRequest into Swap, so the versi…
Browse files Browse the repository at this point in the history
…on in SNS Governance can be changed independently (#1295)

This will allow us to remove the `NeuronParameters` field from
Governance. This extra rigamarole is required because the field is not
optional, so we need to make sure the callee is not expecting it before
the caller stops providing it in the request.

Once #1297 is released, this PR should be reverted. With that in mind,
I've implemented it optimizing for revert-ability. This means avoiding
doing refactors that would potentially be painful to revert, if the code
continued to change between now and then.

[Next PR →](#1297)
  • Loading branch information
anchpop authored Sep 4, 2024
1 parent cee5114 commit edd826b
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 61 deletions.
108 changes: 108 additions & 0 deletions rs/sns/swap/proto/ic_sns_swap/pb/v1/swap.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1547,3 +1547,111 @@ message NotifyPaymentFailureRequest {}
message NotifyPaymentFailureResponse {
optional Ticket ticket = 1;
}

// TODO(NNS1-3306): Remove this message once SNS Governance uses the same request type.
// A sequence of NeuronIds, which is used to get prost to generate a type isomorphic to Option<Vec<NeuronId>>.
message NeuronIds {
repeated NeuronId neuron_ids = 1;
}

// The request for the `claim_swap_neurons` method.
// Copied from sns governance.proto. TODO(NNS1-3306): Remove this message once
// SNS Governance uses the same request type.
message ClaimSwapNeuronsRequest {
// This type has been replaced by NeuronRecipe and should not be used.
// TODO(NNS1-3198): Remove this message once `NeuronRecipe` is used systematically.
message NeuronParameters {
reserved "memo";
reserved 4;

// The PrincipalId that will have permissions when the neuron is created.
// The permissions that are granted are controlled my
// `NervousSystemParameters::neuron_claimer_permissions`. This field
// is required.
ic_base_types.pb.v1.PrincipalId controller = 1;

// For Community Fund participants, in addition to the controller (that is
// set to the NNS governance), this is another PrincipalId with permissions.
// Specifically, the PrincipalId who is the controller of the NNS neuron
// that invested in the decentralization sale via the Community Fund will
// be granted the following permissions:
// - NeuronPermissionType::SubmitProposal
// - NeuronPermissionType::Vote
// This field is not set for other types of participants, therefore it is optional.
ic_base_types.pb.v1.PrincipalId hotkey = 2;

// The stake of the neuron in e8s (10E-8 of a token) that the neuron will be
// created with. This field is required.
optional uint64 stake_e8s = 3;

// The duration in seconds that the neuron's dissolve delay will be set to. Neurons
// that are for Community Fund investors will be automatically set to dissolving,
// while direct investors will be automatically set to non-dissolving.
optional uint64 dissolve_delay_seconds = 5;

// The ID of the NNS neuron whose Community Fund participation resulted in the
// creation of this SNS neuron.
optional uint64 source_nns_neuron_id = 6;

// The ID of the SNS Neuron to be created for the participant. If a Neuron with
// this NeuronId already exists in SNS Governance, the `ClaimSwapNeuronsResponse`
// will return a`ClaimedSwapNeuronStatus::AlreadyExists` for this NeuronId.
// This field is required.
optional NeuronId neuron_id = 7;

// The list of NeuronIds that the created Neuron will follow on all SNS Proposal
// Actions known to governance at the time. Additional followees and following
// relations can be added after neuron creation.
repeated NeuronId followees = 8;
}

// Replacement for NeuronParameters. Contains the information needed to set up
// a neuron for a swap participant.
message NeuronRecipe {
// The info that for a participant in the Neurons' Fund
message NeuronsFund {
// The neuron ID of the NNS neuron that participated in the Neurons' Fund.
optional uint64 nns_neuron_id = 1;
// The controller of the NNS neuron that participated in the Neurons' Fund.
optional ic_base_types.pb.v1.PrincipalId nns_neuron_controller = 2;
// The hotkeys of the NNS neuron that participated in the Neurons' Fund.
optional ic_nervous_system.pb.v1.Principals nns_neuron_hotkeys = 3;
}

// The info that for a direct participant
message Direct {}

// The principal that should be the controller of the SNS neuron
optional ic_base_types.pb.v1.PrincipalId controller = 1;
// The ID of the SNS neuron
optional NeuronId neuron_id = 2;

// The SNS neuron's stake in e8s (10E-8 of a token)
optional uint64 stake_e8s = 3;

// The duration in seconds that the neuron's dissolve delay will be set to.
optional uint64 dissolve_delay_seconds = 4;
// The neurons this neuron should follow
optional NeuronIds followees = 5;

oneof participant {
Direct direct = 6;
NeuronsFund neurons_fund = 7;
}
}

// Needed to cause prost to generate a type isomorphic to
// Optional<Vec<NeuronRecipe>>.
message NeuronRecipes {
repeated NeuronRecipe neuron_recipes = 1;
}

// The set of parameters that define the neurons created in `claim_swap_neurons`. For
// each NeuronRecipe, one neuron will be created.
optional NeuronRecipes neuron_recipes = 2;

// The set of parameters that define the neurons created in `claim_swap_neurons`. For
// each NeuronParameter, one neuron will be created.
// Deprecated. Use [`neuron_recipes`] instead.
repeated NeuronParameters neuron_parameters = 1 [deprecated = true];
}
4 changes: 4 additions & 0 deletions rs/sns/swap/protobuf_generator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ pub fn generate_prost_files(proto: ProtoPaths<'_>, out: &Path) {
".ic_sns_swap.pb.v1.IdealMatchedParticipationFunction",
"#[derive(Eq)]",
);
config.type_attribute(
".ic_sns_swap.pb.v1.NeuronId",
"#[derive(Eq, Ord, PartialOrd)]",
);

// Add serde_bytes for efficiently parsing blobs.
let blob_fields = vec!["NeuronId.id"];
Expand Down
8 changes: 4 additions & 4 deletions rs/sns/swap/src/clients.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::pb::v1::{
CanisterCallError, SetDappControllersRequest, SetDappControllersResponse,
SettleNeuronsFundParticipationRequest, SettleNeuronsFundParticipationResponse,
CanisterCallError, ClaimSwapNeuronsRequest, SetDappControllersRequest,
SetDappControllersResponse, SettleNeuronsFundParticipationRequest,
SettleNeuronsFundParticipationResponse,
};
use async_trait::async_trait;
use ic_base_types::CanisterId;
use ic_sns_governance::pb::v1::{
ClaimSwapNeuronsRequest, ClaimSwapNeuronsResponse, ManageNeuron, ManageNeuronResponse, SetMode,
SetModeResponse,
ClaimSwapNeuronsResponse, ManageNeuron, ManageNeuronResponse, SetMode, SetModeResponse,
};

#[async_trait]
Expand Down
159 changes: 158 additions & 1 deletion rs/sns/swap/src/gen/ic_sns_swap.pb.v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1541,7 +1541,15 @@ pub mod settle_neurons_fund_participation_response {
}
/// The id of a specific neuron, which equals the neuron's subaccount on
/// the ledger canister (the account that holds the neuron's staked tokens).
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable)]
#[derive(
candid::CandidType,
candid::Deserialize,
serde::Serialize,
comparable::Comparable,
Eq,
Ord,
PartialOrd,
)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct NeuronId {
Expand Down Expand Up @@ -2142,6 +2150,155 @@ pub struct NotifyPaymentFailureResponse {
#[prost(message, optional, tag = "1")]
pub ticket: ::core::option::Option<Ticket>,
}
/// TODO(NNS1-3306): Remove this message once SNS Governance uses the same request type.
/// A sequence of NeuronIds, which is used to get prost to generate a type isomorphic to Option<Vec<NeuronId>>.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct NeuronIds {
#[prost(message, repeated, tag = "1")]
pub neuron_ids: ::prost::alloc::vec::Vec<NeuronId>,
}
/// The request for the `claim_swap_neurons` method.
/// Copied from sns governance.proto. TODO(NNS1-3306): Remove this message once
/// SNS Governance uses the same request type.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ClaimSwapNeuronsRequest {
/// The set of parameters that define the neurons created in `claim_swap_neurons`. For
/// each NeuronRecipe, one neuron will be created.
#[prost(message, optional, tag = "2")]
pub neuron_recipes: ::core::option::Option<claim_swap_neurons_request::NeuronRecipes>,
/// The set of parameters that define the neurons created in `claim_swap_neurons`. For
/// each NeuronParameter, one neuron will be created.
/// Deprecated. Use \[`neuron_recipes`\] instead.
#[deprecated]
#[prost(message, repeated, tag = "1")]
pub neuron_parameters: ::prost::alloc::vec::Vec<claim_swap_neurons_request::NeuronParameters>,
}
/// Nested message and enum types in `ClaimSwapNeuronsRequest`.
pub mod claim_swap_neurons_request {
/// This type has been replaced by NeuronRecipe and should not be used.
/// TODO(NNS1-3198): Remove this message once `NeuronRecipe` is used systematically.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct NeuronParameters {
/// The PrincipalId that will have permissions when the neuron is created.
/// The permissions that are granted are controlled my
/// `NervousSystemParameters::neuron_claimer_permissions`. This field
/// is required.
#[prost(message, optional, tag = "1")]
pub controller: ::core::option::Option<::ic_base_types::PrincipalId>,
/// For Community Fund participants, in addition to the controller (that is
/// set to the NNS governance), this is another PrincipalId with permissions.
/// Specifically, the PrincipalId who is the controller of the NNS neuron
/// that invested in the decentralization sale via the Community Fund will
/// be granted the following permissions:
/// - NeuronPermissionType::SubmitProposal
/// - NeuronPermissionType::Vote
/// This field is not set for other types of participants, therefore it is optional.
#[prost(message, optional, tag = "2")]
pub hotkey: ::core::option::Option<::ic_base_types::PrincipalId>,
/// The stake of the neuron in e8s (10E-8 of a token) that the neuron will be
/// created with. This field is required.
#[prost(uint64, optional, tag = "3")]
pub stake_e8s: ::core::option::Option<u64>,
/// The duration in seconds that the neuron's dissolve delay will be set to. Neurons
/// that are for Community Fund investors will be automatically set to dissolving,
/// while direct investors will be automatically set to non-dissolving.
#[prost(uint64, optional, tag = "5")]
pub dissolve_delay_seconds: ::core::option::Option<u64>,
/// The ID of the NNS neuron whose Community Fund participation resulted in the
/// creation of this SNS neuron.
#[prost(uint64, optional, tag = "6")]
pub source_nns_neuron_id: ::core::option::Option<u64>,
/// The ID of the SNS Neuron to be created for the participant. If a Neuron with
/// this NeuronId already exists in SNS Governance, the `ClaimSwapNeuronsResponse`
/// will return a`ClaimedSwapNeuronStatus::AlreadyExists` for this NeuronId.
/// This field is required.
#[prost(message, optional, tag = "7")]
pub neuron_id: ::core::option::Option<super::NeuronId>,
/// The list of NeuronIds that the created Neuron will follow on all SNS Proposal
/// Actions known to governance at the time. Additional followees and following
/// relations can be added after neuron creation.
#[prost(message, repeated, tag = "8")]
pub followees: ::prost::alloc::vec::Vec<super::NeuronId>,
}
/// Replacement for NeuronParameters. Contains the information needed to set up
/// a neuron for a swap participant.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct NeuronRecipe {
/// The principal that should be the controller of the SNS neuron
#[prost(message, optional, tag = "1")]
pub controller: ::core::option::Option<::ic_base_types::PrincipalId>,
/// The ID of the SNS neuron
#[prost(message, optional, tag = "2")]
pub neuron_id: ::core::option::Option<super::NeuronId>,
/// The SNS neuron's stake in e8s (10E-8 of a token)
#[prost(uint64, optional, tag = "3")]
pub stake_e8s: ::core::option::Option<u64>,
/// The duration in seconds that the neuron's dissolve delay will be set to.
#[prost(uint64, optional, tag = "4")]
pub dissolve_delay_seconds: ::core::option::Option<u64>,
/// The neurons this neuron should follow
#[prost(message, optional, tag = "5")]
pub followees: ::core::option::Option<super::NeuronIds>,
#[prost(oneof = "neuron_recipe::Participant", tags = "6, 7")]
pub participant: ::core::option::Option<neuron_recipe::Participant>,
}
/// Nested message and enum types in `NeuronRecipe`.
pub mod neuron_recipe {
/// The info that for a participant in the Neurons' Fund
#[derive(
candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable,
)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct NeuronsFund {
/// The neuron ID of the NNS neuron that participated in the Neurons' Fund.
#[prost(uint64, optional, tag = "1")]
pub nns_neuron_id: ::core::option::Option<u64>,
/// The controller of the NNS neuron that participated in the Neurons' Fund.
#[prost(message, optional, tag = "2")]
pub nns_neuron_controller: ::core::option::Option<::ic_base_types::PrincipalId>,
/// The hotkeys of the NNS neuron that participated in the Neurons' Fund.
#[prost(message, optional, tag = "3")]
pub nns_neuron_hotkeys:
::core::option::Option<::ic_nervous_system_proto::pb::v1::Principals>,
}
/// The info that for a direct participant
#[derive(
candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable,
)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Direct {}
#[derive(
candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable,
)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum Participant {
#[prost(message, tag = "6")]
Direct(Direct),
#[prost(message, tag = "7")]
NeuronsFund(NeuronsFund),
}
}
/// Needed to cause prost to generate a type isomorphic to
/// Optional<Vec<NeuronRecipe>>.
#[derive(candid::CandidType, candid::Deserialize, serde::Serialize, comparable::Comparable)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct NeuronRecipes {
#[prost(message, repeated, tag = "1")]
pub neuron_recipes: ::prost::alloc::vec::Vec<NeuronRecipe>,
}
}
/// Lifecycle states of the swap canister. The details of their meanings
/// are provided in the documentation of the `Swap` message.
#[derive(
Expand Down
Loading

0 comments on commit edd826b

Please sign in to comment.