Skip to content

Commit

Permalink
Merge pull request #524 from yral-dapp/rupansh/sns-update
Browse files Browse the repository at this point in the history
Updates for new SNS canisters
  • Loading branch information
rupansh-sekar-yral authored Nov 11, 2024
2 parents 1c02bf3 + a476a1a commit 490a580
Show file tree
Hide file tree
Showing 19 changed files with 640 additions and 611 deletions.
150 changes: 64 additions & 86 deletions Cargo.lock

Large diffs are not rendered by default.

71 changes: 31 additions & 40 deletions sns-validation/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ use crate::{
humanize,
pbs::{
gov_pb::CreateServiceNervousSystem,
nns_pb::{self, GlobalTimeOfDay, Image},
nns_pb::{self, Image},
sns_pb::SnsInitPayload,
ExecutedCreateServiceNervousSystemProposal,
},
};
use web_time::{SystemTime, UNIX_EPOCH};

// Alias CreateServiceNervousSystem-related types, but since we have many
// related types in this module, put these aliases in their own module to avoid
Expand All @@ -32,7 +30,7 @@ mod nns_governance_pb {
// the format that we are trying to implement here.
//
// (Thanks to the magic of serde, all the code here is declarative.)
#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize)]
#[serde(deny_unknown_fields)]
pub struct SnsConfigurationFile {
pub name: String,
Expand Down Expand Up @@ -68,15 +66,15 @@ pub struct SnsConfigurationFile {
pub nns_proposal: NnsProposal,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct PrincipalAlias {
id: String, // PrincipalId
name: Option<String>,
email: Option<String>,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Token {
pub name: String,
Expand All @@ -86,7 +84,7 @@ pub struct Token {
pub logo_b64: String,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Proposals {
#[serde(with = "humanize::ser_de::tokens")]
Expand All @@ -99,14 +97,14 @@ pub struct Proposals {
pub maximum_wait_for_quiet_deadline_extension: nns_pb::Duration,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Neurons {
#[serde(with = "humanize::ser_de::tokens")]
pub minimum_creation_stake: nns_pb::Tokens,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Voting {
#[serde(with = "humanize::ser_de::duration")]
Expand All @@ -119,7 +117,7 @@ pub struct Voting {
pub reward_rate: RewardRate,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct MaximumVotingPowerBonuses {
#[serde(rename = "DissolveDelay")]
Expand All @@ -129,7 +127,7 @@ pub struct MaximumVotingPowerBonuses {
pub age: Bonus,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Bonus {
#[serde(with = "humanize::ser_de::duration")]
Expand All @@ -139,7 +137,7 @@ pub struct Bonus {
pub bonus: nns_pb::Percentage,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct RewardRate {
#[serde(with = "humanize::ser_de::percentage")]
Expand All @@ -152,7 +150,7 @@ pub struct RewardRate {
pub transition_duration: nns_pb::Duration,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Swap {
pub minimum_participants: u64,
Expand Down Expand Up @@ -196,7 +194,7 @@ pub struct Swap {
pub neurons_fund_participation: Option<bool>,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct VestingSchedule {
pub events: u64,
Expand All @@ -205,7 +203,7 @@ pub struct VestingSchedule {
pub interval: nns_pb::Duration,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Distribution {
#[serde(rename = "Neurons")]
Expand All @@ -218,7 +216,7 @@ pub struct Distribution {
pub total: nns_pb::Tokens,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Neuron {
pub principal: String, // Principal (alias)
Expand All @@ -236,7 +234,7 @@ pub struct Neuron {
pub vesting_period: nns_pb::Duration,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct InitialBalances {
#[serde(with = "humanize::ser_de::tokens")]
Expand All @@ -246,7 +244,7 @@ pub struct InitialBalances {
pub swap: nns_pb::Tokens,
}

#[derive(serde::Deserialize, serde::Serialize, Debug, PartialEq, Eq, Clone)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone)]
pub struct NnsProposal {
pub title: String,
pub summary: String,
Expand All @@ -257,7 +255,7 @@ struct AliasToPrincipalId<'a> {
#[allow(unused)]
source: &'a Vec<PrincipalAlias>,
/* TODO
#[derive(Debug, PartialEq, Eq, Hash)]
#[derive(Eq, PartialEq, Hash, Debug)]
enum Key { // TODO: This name is just a placeholder.
Name(String),
Email(String),
Expand Down Expand Up @@ -410,24 +408,19 @@ impl SnsConfigurationFile {
Ok(result)
}

pub fn try_convert_to_executed_sns_init(&self) -> Result<SnsInitPayload, String> {
let create_sns = self.try_convert_to_create_service_nervous_system()?;
let executed_create_sns = ExecutedCreateServiceNervousSystemProposal {
current_timestamp_seconds: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs(),
create_service_nervous_system: create_sns,
random_swap_start_time: GlobalTimeOfDay {
seconds_after_utc_midnight: Some(0),
},
neurons_fund_participation_constraints: None,
// `proposal_id` only exists to be exposed to the user for audit purposes, which don't apply here.
// But it's required, so we can just use any arbitrary value.
proposal_id: 10,
};

SnsInitPayload::try_from(executed_create_sns)
pub fn try_convert_to_sns_init_payload(&self) -> Result<SnsInitPayload, String> {
let create_nervous_system = self.try_convert_to_create_service_nervous_system()?;
let now = web_time::SystemTime::now()
.duration_since(web_time::UNIX_EPOCH)
.unwrap()
.as_secs();
let mut sns_init = SnsInitPayload::try_from(create_nervous_system)?;
sns_init.nns_proposal_id = Some(1);
sns_init.swap_start_timestamp_seconds = Some(now - 1000);
sns_init.swap_due_timestamp_seconds = Some(now + 300);
sns_init.validate_post_execution()?;

Ok(sns_init)
}
}

Expand Down Expand Up @@ -580,14 +573,12 @@ impl Token {
let token_symbol = Some(symbol.clone());
let transaction_fee = Some(*transaction_fee);

let token_logo = logo_b64.clone();

nns_governance_pb::LedgerParameters {
token_name,
token_symbol,
transaction_fee,
token_logo: Some(Image {
base64_encoding: Some(token_logo),
base64_encoding: Some(logo_b64.clone()),
}),
}
}
Expand Down
127 changes: 105 additions & 22 deletions sns-validation/src/pbs/gov_pb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,131 @@ pub struct NeuronId {
pub id: Vec<u8>,
}

#[derive(candid::CandidType, candid::Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq)]
/// The nervous system's parameters, which are parameters that can be changed, via proposals,
/// by each nervous system community.
/// For some of the values there are specified minimum values (floor) or maximum values
/// (ceiling). The motivation for this is a) to prevent that the nervous system accidentally
/// chooses parameters that result in an un-upgradable (and thus stuck) governance canister
/// and b) to prevent the canister from growing too big (which could harm the other canisters
/// on the subnet).
///
/// Required invariant: the canister code assumes that all system parameters are always set.
#[derive(candid::CandidType, candid::Deserialize, Clone, PartialEq)]
pub struct NervousSystemParameters {
/// The number of e8s (10E-8 of a token) that a rejected
/// proposal costs the proposer.
pub reject_cost_e8s: ::core::option::Option<u64>,

/// The minimum number of e8s (10E-8 of a token) that can be staked in a neuron.
///
/// To ensure that staking and disbursing of the neuron work, the chosen value
/// must be larger than the transaction_fee_e8s.
pub neuron_minimum_stake_e8s: ::core::option::Option<u64>,

/// The transaction fee that must be paid for ledger transactions (except
/// minting and burning governance tokens).
pub transaction_fee_e8s: ::core::option::Option<u64>,

/// The maximum number of proposals to keep, per action. When the
/// total number of proposals for a given action is greater than this
/// number, the oldest proposals that have reached final decision state
/// (rejected, executed, or failed) and final rewards status state
/// (settled) may be deleted.
///
/// The number must be larger than zero and at most be as large as the
/// defined ceiling MAX_PROPOSALS_TO_KEEP_PER_ACTION_CEILING.
pub max_proposals_to_keep_per_action: ::core::option::Option<u32>,

/// The initial voting period of a newly created proposal.
/// A proposal's voting period may then be further increased during
/// a proposal's lifecycle due to the wait-for-quiet algorithm.
///
/// The voting period must be between (inclusive) the defined floor
/// INITIAL_VOTING_PERIOD_SECONDS_FLOOR and ceiling
/// INITIAL_VOTING_PERIOD_SECONDS_CEILING.
pub initial_voting_period_seconds: ::core::option::Option<u64>,

/// The wait for quiet algorithm extends the voting period of a proposal when
/// there is a flip in the majority vote during the proposal's voting period.
/// This parameter determines the maximum time period that the voting period
/// may be extended after a flip. If there is a flip at the very end of the
/// original proposal deadline, the remaining time will be set to this parameter.
/// If there is a flip before or after the original deadline, the deadline will
/// extended by somewhat less than this parameter.
/// The maximum total voting period extension is 2 * wait_for_quiet_deadline_increase_seconds.
/// For more information, see the wiki page on the wait-for-quiet algorithm:
/// <https://wiki.internetcomputer.org/wiki/Network_Nervous_System#Proposal_decision_and_wait-for-quiet>
pub wait_for_quiet_deadline_increase_seconds: ::core::option::Option<u64>,

/// TODO NNS1-2169: This field currently has no effect.
/// TODO NNS1-2169: Design and implement this feature.
///
/// The set of default followees that every newly created neuron will follow
/// per function. This is specified as a mapping of proposal functions to followees.
///
/// If unset, neurons will have no followees by default.
/// The set of followees for each function can be at most of size
/// max_followees_per_function.
pub default_followees: ::core::option::Option<DefaultFollowees>,

/// The maximum number of allowed neurons. When this maximum is reached, no new
/// neurons will be created until some are removed.
///
/// This number must be larger than zero and at most as large as the defined
/// ceiling MAX_NUMBER_OF_NEURONS_CEILING.
pub max_number_of_neurons: ::core::option::Option<u64>,

/// The minimum dissolve delay a neuron must have to be eligible to vote.
///
/// The chosen value must be smaller than max_dissolve_delay_seconds.
pub neuron_minimum_dissolve_delay_to_vote_seconds: ::core::option::Option<u64>,

/// The maximum number of followees each neuron can establish for each nervous system function.
///
/// This number can be at most as large as the defined ceiling
/// MAX_FOLLOWEES_PER_FUNCTION_CEILING.
pub max_followees_per_function: ::core::option::Option<u64>,

/// The maximum dissolve delay that a neuron can have. That is, the maximum
/// that a neuron's dissolve delay can be increased to. The maximum is also enforced
/// when saturating the dissolve delay bonus in the voting power computation.
pub max_dissolve_delay_seconds: ::core::option::Option<u64>,

/// The age of a neuron that saturates the age bonus for the voting power computation.
pub max_neuron_age_for_age_bonus: ::core::option::Option<u64>,

/// The max number of proposals for which ballots are still stored, i.e.,
/// unsettled proposals. If this number of proposals is reached, new proposals
/// can only be added in exceptional cases (for few proposals it is defined
/// that they are allowed even if resources are low to guarantee that the relevant
/// canisters can be upgraded).
///
/// This number must be larger than zero and at most as large as the defined
/// ceiling MAX_NUMBER_OF_PROPOSALS_WITH_BALLOTS_CEILING.
pub max_number_of_proposals_with_ballots: ::core::option::Option<u64>,

/// The default set of neuron permissions granted to the principal claiming a neuron.
pub neuron_claimer_permissions: ::core::option::Option<NeuronPermissionList>,

/// The superset of neuron permissions a principal with permission
/// `NeuronPermissionType::ManagePrincipals` for a given neuron can grant to another
/// principal for this same neuron.
/// If this set changes via a ManageNervousSystemParameters proposal, previous
/// neurons' permissions will be unchanged and only newly granted permissions will be affected.
pub neuron_grantable_permissions: ::core::option::Option<NeuronPermissionList>,

/// The maximum number of principals that can have permissions for a neuron
pub max_number_of_principals_per_neuron: ::core::option::Option<u64>,

/// When this field is not populated, voting rewards are "disabled". Once this
/// is set, it probably should not be changed, because the results would
/// probably be pretty confusing.
pub voting_rewards_parameters: ::core::option::Option<VotingRewardsParameters>,

/// E.g. if a large dissolve delay can double the voting power of a neuron,
/// then this field would have a value of 100, indicating a maximum of
/// 100% additional voting power.
///
/// For no bonus, this should be set to 0.
///
/// To achieve functionality equivalent to NNS, this should be set to 100.
pub max_dissolve_delay_bonus_percentage: ::core::option::Option<u64>,

/// Analogous to the previous field (see the previous comment),
/// but this one relates to neuron age instead of dissolve delay.
///
/// To achieve functionality equivalent to NNS, this should be set to 25.
pub max_age_bonus_percentage: ::core::option::Option<u64>,

/// By default, maturity modulation is enabled; however, an SNS can use this
/// field to disable it. When disabled, this canister will still poll the
/// Cycles Minting Canister (CMC), and store the value received therefrom.
/// However, the fetched value does not get used when this is set to true.
///
/// The reason we call this "disabled" instead of (positive) "enabled" is so
/// that the PB default (bool fields are false) and our application default
/// (enabled) agree.
pub maturity_modulation_disabled: ::core::option::Option<bool>,
}

Expand Down
Loading

0 comments on commit 490a580

Please sign in to comment.