From 9dff90b0991d2407d59046d4d580617b31eabd67 Mon Sep 17 00:00:00 2001 From: vedhavyas Date: Fri, 26 Jul 2024 17:48:01 +0530 Subject: [PATCH] add council and democracy to consensus runtime --- Cargo.lock | 79 +++++++- .../src/chain_spec.rs | 7 +- crates/subspace-node/src/chain_spec.rs | 9 +- crates/subspace-runtime/Cargo.toml | 9 + crates/subspace-runtime/src/lib.rs | 175 +++++++++++++++++- 5 files changed, 270 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be42f65e86..fb598f898b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1918,7 +1918,7 @@ dependencies = [ [[package]] name = "common" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", @@ -7747,6 +7747,41 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-collective" +version = "28.0.0" +source = "git+https://github.com/subspace/polkadot-sdk?rev=0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef#0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "pallet-democracy" +version = "28.0.0" +source = "git+https://github.com/subspace/polkadot-sdk?rev=0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef#0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-domain-id" version = "0.1.0" @@ -8009,6 +8044,23 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-preimage" +version = "28.0.0" +source = "git+https://github.com/subspace/polkadot-sdk?rev=0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef#0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-rewards" version = "0.1.0" @@ -8041,6 +8093,24 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-scheduler" +version = "29.0.0" +source = "git+https://github.com/subspace/polkadot-sdk?rev=0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef#0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" +dependencies = [ + "docify", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "scale-info", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", +] + [[package]] name = "pallet-subspace" version = "0.1.0" @@ -9520,13 +9590,14 @@ dependencies = [ [[package]] name = "ring" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#b273d33f9981e2bb3375ab45faeb537f7ee35224" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", "ark-poly", "ark-serialize", "ark-std", + "arrayvec", "blake2 0.10.6", "common", "fflonk", @@ -13079,12 +13150,16 @@ dependencies = [ "hex-literal", "orml-vesting", "pallet-balances", + "pallet-collective", + "pallet-democracy", "pallet-domains", "pallet-messenger", "pallet-mmr", "pallet-offences-subspace", + "pallet-preimage", "pallet-rewards", "pallet-runtime-configs", + "pallet-scheduler", "pallet-subspace", "pallet-subspace-mmr", "pallet-sudo", diff --git a/crates/subspace-malicious-operator/src/chain_spec.rs b/crates/subspace-malicious-operator/src/chain_spec.rs index 46b070f7ed..202d371bcf 100644 --- a/crates/subspace-malicious-operator/src/chain_spec.rs +++ b/crates/subspace-malicious-operator/src/chain_spec.rs @@ -13,8 +13,9 @@ use sp_runtime::{BuildStorage, MultiSigner, Percent}; use std::marker::PhantomData; use std::num::NonZeroU32; use subspace_runtime::{ - AllowAuthoringBy, DomainsConfig, EnableRewardsAt, MaxDomainBlockSize, MaxDomainBlockWeight, - RewardsConfig, RuntimeConfigsConfig, SubspaceConfig, VestingConfig, + AllowAuthoringBy, CouncilConfig, DemocracyConfig, DomainsConfig, EnableRewardsAt, + MaxDomainBlockSize, MaxDomainBlockWeight, RewardsConfig, RuntimeConfigsConfig, SubspaceConfig, + VestingConfig, }; use subspace_runtime_primitives::{AccountId, Balance, BlockNumber, SSC}; @@ -236,6 +237,8 @@ fn subspace_genesis_config( }, rewards: rewards_config, vesting: VestingConfig { vesting }, + council: CouncilConfig::default(), + democracy: DemocracyConfig::default(), runtime_configs: RuntimeConfigsConfig { enable_domains, enable_dynamic_cost_of_storage, diff --git a/crates/subspace-node/src/chain_spec.rs b/crates/subspace-node/src/chain_spec.rs index 402be7dc18..a11cbc0019 100644 --- a/crates/subspace-node/src/chain_spec.rs +++ b/crates/subspace-node/src/chain_spec.rs @@ -32,9 +32,10 @@ use std::marker::PhantomData; use std::num::NonZeroU32; use subspace_core_primitives::PotKey; use subspace_runtime::{ - AllowAuthoringBy, BalancesConfig, DomainsConfig, EnableRewardsAt, MaxDomainBlockSize, - MaxDomainBlockWeight, RewardsConfig, RuntimeConfigsConfig, RuntimeGenesisConfig, - SubspaceConfig, SudoConfig, SystemConfig, VestingConfig, MILLISECS_PER_BLOCK, WASM_BINARY, + AllowAuthoringBy, BalancesConfig, CouncilConfig, DemocracyConfig, DomainsConfig, + EnableRewardsAt, MaxDomainBlockSize, MaxDomainBlockWeight, RewardsConfig, RuntimeConfigsConfig, + RuntimeGenesisConfig, SubspaceConfig, SudoConfig, SystemConfig, VestingConfig, + MILLISECS_PER_BLOCK, WASM_BINARY, }; use subspace_runtime_primitives::{AccountId, Balance, BlockNumber, SSC}; @@ -447,6 +448,8 @@ fn subspace_genesis_config( }, rewards: rewards_config, vesting: VestingConfig { vesting }, + council: CouncilConfig::default(), + democracy: DemocracyConfig::default(), runtime_configs: RuntimeConfigsConfig { enable_domains, enable_dynamic_cost_of_storage, diff --git a/crates/subspace-runtime/Cargo.toml b/crates/subspace-runtime/Cargo.toml index a1b6e92422..0e22c90cd8 100644 --- a/crates/subspace-runtime/Cargo.toml +++ b/crates/subspace-runtime/Cargo.toml @@ -26,12 +26,16 @@ frame-system-benchmarking = { default-features = false, git = "https://github.co frame-system-rpc-runtime-api = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } orml-vesting = { version = "0.9.1", default-features = false, path = "../../orml/vesting" } pallet-balances = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } +pallet-collective = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } +pallet-democracy = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } pallet-domains = { version = "0.1.0", default-features = false, path = "../pallet-domains" } pallet-messenger = { version = "0.1.0", path = "../../domains/pallets/messenger", default-features = false } pallet-mmr = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } pallet-offences-subspace = { version = "0.1.0", default-features = false, path = "../pallet-offences-subspace" } +pallet-preimage = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } pallet-rewards = { version = "0.1.0", default-features = false, path = "../pallet-rewards" } pallet-runtime-configs = { version = "0.1.0", default-features = false, path = "../pallet-runtime-configs" } +pallet-scheduler = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } pallet-subspace = { version = "0.1.0", default-features = false, features = ["serde"], path = "../pallet-subspace" } pallet-subspace-mmr = { version = "0.1.0", default-features = false, path = "../pallet-subspace-mmr" } pallet-sudo = { default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "0cbfcb0232bbf71ac5b14cc8c99bf043cec420ef" } @@ -87,12 +91,16 @@ std = [ "frame-system-rpc-runtime-api/std", "orml-vesting/std", "pallet-balances/std", + "pallet-collective/std", + "pallet-democracy/std", "pallet-domains/std", "pallet-messenger/std", "pallet-mmr/std", "pallet-offences-subspace/std", + "pallet-preimage/std", "pallet-rewards/std", "pallet-runtime-configs/std", + "pallet-scheduler/std", "pallet-subspace/std", "pallet-subspace-mmr/std", "pallet-sudo/std", @@ -138,6 +146,7 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "orml-vesting/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", "pallet-domains/runtime-benchmarks", "pallet-mmr/runtime-benchmarks", "pallet-rewards/runtime-benchmarks", diff --git a/crates/subspace-runtime/src/lib.rs b/crates/subspace-runtime/src/lib.rs index ecf2be9111..d83f57cf18 100644 --- a/crates/subspace-runtime/src/lib.rs +++ b/crates/subspace-runtime/src/lib.rs @@ -41,14 +41,17 @@ use domain_runtime_primitives::{ use frame_support::genesis_builder_helper::{build_state, get_preset}; use frame_support::inherent::ProvideInherent; use frame_support::migrations::VersionedMigration; +use frame_support::traits::fungible::HoldConsideration; use frame_support::traits::{ - ConstU16, ConstU32, ConstU64, ConstU8, Currency, Everything, Get, VariantCount, + ConstU16, ConstU32, ConstU64, ConstU8, Currency, EitherOfDiverse, EqualPrivilegeOnly, + Everything, Get, LinearStoragePrice, OnUnbalanced, VariantCount, }; use frame_support::weights::constants::ParityDbWeight; use frame_support::weights::{ConstantMultiplier, Weight}; use frame_support::{construct_runtime, parameter_types, PalletId}; use frame_system::limits::{BlockLength, BlockWeights}; -use frame_system::EnsureNever; +use frame_system::{EnsureNever, EnsureRoot}; +use pallet_collective::{EnsureMember, EnsureProportionAtLeast}; pub use pallet_rewards::RewardPoint; pub use pallet_subspace::{AllowAuthoringBy, EnableRewardsAt}; use pallet_transporter::EndpointHandler; @@ -340,6 +343,7 @@ parameter_types! { pub enum HoldIdentifier { Domains(DomainsHoldIdentifier), Messenger(MessengerHoldIdentifier), + Preimage, } impl pallet_domains::HoldIdentifier for HoldIdentifier { @@ -439,6 +443,167 @@ impl pallet_sudo::Config for Runtime { type WeightInfo = pallet_sudo::weights::SubstrateWeight; } +pub type CouncilCollective = pallet_collective::Instance1; + +// TODO: update params for mainnnet +parameter_types! { + // approximately 1 day for council to vote on a motion + pub CouncilMotionDuration: BlockNumber = 14_400; + pub const CouncilMaxProposals: u32 = 100; + pub const CouncilMaxMembers: u32 = 100; + // maximum dispatch weight of a given council motion + // currently set to 50% of maximum block weight + pub MaxProposalWeight: Weight = Perbill::from_percent(50) * SubspaceBlockWeights::get().max_block; +} + +impl pallet_collective::Config for Runtime { + type DefaultVote = pallet_collective::PrimeDefaultVote; + type MaxMembers = CouncilMaxMembers; + type MaxProposalWeight = MaxProposalWeight; + type MaxProposals = CouncilMaxProposals; + type MotionDuration = CouncilMotionDuration; + type Proposal = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type SetMembersOrigin = EnsureRoot; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} + +// TODO: update params for mainnnet +parameter_types! { + pub const PreimageMaxSize: u32 = 4096 * 1024; + pub PreimageBaseDeposit: Balance = 100 * SSC; + pub PreimageByteDeposit: Balance = SSC; + pub const PreImageHoldReason: HoldIdentifier = HoldIdentifier::Preimage; +} + +impl pallet_preimage::Config for Runtime { + type Consideration = HoldConsideration< + AccountId, + Balances, + PreImageHoldReason, + LinearStoragePrice, + >; + type Currency = Balances; + type ManagerOrigin = EnsureRoot; + type RuntimeEvent = RuntimeEvent; + type WeightInfo = pallet_preimage::weights::SubstrateWeight; +} + +parameter_types! { + pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * SubspaceBlockWeights::get().max_block; + pub const MaxScheduledPerBlock: u32 = 50; + // Retry a scheduled item every 10 blocks (2 minutes) until the preimage exists. + pub const NoPreimagePostponement: Option = Some(10); +} + +impl pallet_scheduler::Config for Runtime { + type MaxScheduledPerBlock = MaxScheduledPerBlock; + type MaximumWeight = MaximumSchedulerWeight; + type OriginPrivilegeCmp = EqualPrivilegeOnly; + type PalletsOrigin = OriginCaller; + type Preimages = Preimage; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type RuntimeOrigin = RuntimeOrigin; + type ScheduleOrigin = EnsureRoot; + type WeightInfo = pallet_scheduler::weights::SubstrateWeight; +} + +// TODO: update params for mainnnet +pub type EnsureRootOr = EitherOfDiverse, O>; +pub type AllCouncil = EnsureProportionAtLeast; +pub type TwoThirdsCouncil = EnsureProportionAtLeast; +pub type HalfCouncil = EnsureProportionAtLeast; + +// TODO: update params for mainnnet +parameter_types! { + // launch period for public referendum. Currently set to 2 days + pub LaunchPeriod: BlockNumber = 28_800; + // Voting period for democracy. Currently set to 1 day + pub VotingPeriod: BlockNumber = 14_400; + // Voting period for fast track. Currently set to 2 hours. + pub FastTrackVotingPeriod: BlockNumber = 1_200; + // Allow instant execution of proposals. + pub const InstantAllowed: bool = true; + pub const MinimumDeposit: Balance = 1000 * SSC; + // Enactment period for referendum. Currently set to 1 day. + pub EnactmentPeriod: BlockNumber = 14_400; + // Cool off period for council if the previous proposal was vetoed. + // Currently set to 1 day + pub CooloffPeriod: BlockNumber = 14_400; + pub const MaxProposals: u32 = 100; + pub const MaxVotes: u32 = 100; +} + +type NegativeImbalance = >::NegativeImbalance; + +pub struct DemocracySlash; +impl OnUnbalanced for DemocracySlash { + fn on_nonzero_unbalanced(slashed: NegativeImbalance) { + Balances::resolve_creating(&TreasuryAccount::get(), slashed); + } +} + +impl pallet_democracy::Config for Runtime { + type BlacklistOrigin = EnsureRoot; + // To cancel a proposal before it has been passed, must be root. + type CancelProposalOrigin = EnsureRoot; + // To cancel a proposal which has been passed, 2/3 of the council must agree to + // it. + type CancellationOrigin = EnsureRootOr; + /// Period in blocks where an external proposal may not be re-submitted + /// after being vetoed. + type CooloffPeriod = CooloffPeriod; + type Currency = Balances; + /// The minimum period of locking and the period between a proposal being + /// approved and enacted. + type EnactmentPeriod = EnactmentPeriod; + /// A unanimous council can have the next scheduled referendum be a straight + /// default-carries (NTB) vote. + /// 100% council vote. + type ExternalDefaultOrigin = AllCouncil; + /// A simple-majority can have the next scheduled referendum be a straight + /// majority-carries vote. + /// 50% of council votes + type ExternalMajorityOrigin = HalfCouncil; + /// A straight majority of the council can decide what their next motion is. + /// 50% council + type ExternalOrigin = HalfCouncil; + /// Half of the council can have an ExternalMajority/ExternalDefault vote + /// be tabled immediately and with a shorter voting/enactment period. + type FastTrackOrigin = EnsureRootOr; + type FastTrackVotingPeriod = FastTrackVotingPeriod; + type InstantAllowed = InstantAllowed; + type InstantOrigin = EnsureRootOr; + // Same as EnactmentPeriod + /// How often (in blocks) new public referenda are launched. + type LaunchPeriod = LaunchPeriod; + type MaxBlacklisted = ConstU32<100>; + type MaxDeposits = ConstU32<100>; + type MaxProposals = MaxProposals; + type MaxVotes = MaxVotes; + /// The minimum amount to be used as a deposit for a public referendum + /// proposal. + type MinimumDeposit = MinimumDeposit; + type PalletsOrigin = OriginCaller; + type Preimages = Preimage; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + /// Handler for the unbalanced reduction when slashing a preimage deposit. + type Slash = DemocracySlash; + // Origin used to submit proposals. + // Currently set to Council member so that no one can submit new proposals except council through democracy + type SubmitOrigin = EnsureMember; + // Any single council member may veto a coming council proposal, however they + // can only do it once and it lasts only for the cooloff period. + type VetoOrigin = EnsureMember; + type VoteLockingPeriod = EnactmentPeriod; + /// How often (in blocks) to check for new votes. + type VotingPeriod = VotingPeriod; + type WeightInfo = pallet_democracy::weights::SubstrateWeight; +} + parameter_types! { pub const SelfChainId: ChainId = ChainId::Consensus; } @@ -811,6 +976,12 @@ construct_runtime!( Messenger: pallet_messenger exclude_parts { Inherent } = 60, Transporter: pallet_transporter = 61, + // council and democracy + Scheduler: pallet_scheduler = 81, + Council: pallet_collective:: = 82, + Democracy: pallet_democracy = 83, + Preimage: pallet_preimage = 84, + // Reserve some room for other pallets as we'll remove sudo pallet eventually. Sudo: pallet_sudo = 100, }