diff --git a/Cargo.lock b/Cargo.lock
index 902ba1736c2..dd6ed372488 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5049,6 +5049,7 @@ dependencies = [
"pallet-balances",
"pallet-base-fee",
"pallet-collective",
+ "pallet-conviction-voting",
"pallet-crowdloan-rewards",
"pallet-democracy",
"pallet-ethereum",
@@ -5081,10 +5082,12 @@ dependencies = [
"pallet-migrations",
"pallet-moonbeam-orbiters",
"pallet-parachain-staking",
+ "pallet-preimage",
"pallet-proxy",
"pallet-proxy-genesis-companion",
"pallet-randomness",
"pallet-randomness-collective-flip",
+ "pallet-referenda",
"pallet-scheduler",
"pallet-society",
"pallet-sudo",
@@ -5093,6 +5096,7 @@ dependencies = [
"pallet-transaction-payment-rpc-runtime-api",
"pallet-treasury",
"pallet-utility",
+ "pallet-whitelist",
"pallet-xcm",
"pallet-xcm-transactor",
"parachain-info",
@@ -6747,6 +6751,23 @@ dependencies = [
"sp-std",
]
+[[package]]
+name = "pallet-conviction-voting"
+version = "4.0.0-dev"
+source = "git+https://github.com/purestake/substrate?branch=moonbeam-polkadot-v0.9.29#047da514445b644ccd50f7ab8bc11b7f388025a3"
+dependencies = [
+ "assert_matches",
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
[[package]]
name = "pallet-crowdloan-rewards"
version = "0.6.0"
@@ -7781,6 +7802,24 @@ dependencies = [
"sp-std",
]
+[[package]]
+name = "pallet-referenda"
+version = "4.0.0-dev"
+source = "git+https://github.com/purestake/substrate?branch=moonbeam-polkadot-v0.9.29#047da514445b644ccd50f7ab8bc11b7f388025a3"
+dependencies = [
+ "assert_matches",
+ "frame-benchmarking",
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-arithmetic",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
[[package]]
name = "pallet-scheduler"
version = "4.0.0-dev"
@@ -8010,6 +8049,20 @@ dependencies = [
"sp-std",
]
+[[package]]
+name = "pallet-whitelist"
+version = "4.0.0-dev"
+source = "git+https://github.com/purestake/substrate?branch=moonbeam-polkadot-v0.9.29#047da514445b644ccd50f7ab8bc11b7f388025a3"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "scale-info",
+ "sp-api",
+ "sp-runtime",
+ "sp-std",
+]
+
[[package]]
name = "pallet-xcm"
version = "0.9.29"
@@ -13609,9 +13662,9 @@ version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"digest 0.10.3",
- "rand 0.7.3",
+ "rand 0.8.5",
"static_assertions",
]
diff --git a/runtime/moonbase/Cargo.toml b/runtime/moonbase/Cargo.toml
index d9003496f60..75b37884df3 100644
--- a/runtime/moonbase/Cargo.toml
+++ b/runtime/moonbase/Cargo.toml
@@ -70,10 +70,13 @@ frame-system-rpc-runtime-api = { git = "https://github.com/purestake/substrate",
pallet-assets = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-balances = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-collective = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
+pallet-conviction-voting = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-democracy = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-identity = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
+pallet-preimage = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-proxy = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-randomness-collective-flip = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
+pallet-referenda = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-scheduler = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-society = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-sudo = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
@@ -82,6 +85,7 @@ pallet-transaction-payment = { git = "https://github.com/purestake/substrate", b
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-treasury = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
pallet-utility = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
+pallet-whitelist = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
parity-scale-codec = { version = "3.0.0", default-features = false, features = [ "derive", "max-encoded-len" ] }
scale-info = { version = "2.0", default-features = false, features = [ "derive" ] }
sp-api = { git = "https://github.com/purestake/substrate", branch = "moonbeam-polkadot-v0.9.29", default-features = false }
@@ -190,6 +194,7 @@ std = [
"pallet-balances/std",
"pallet-base-fee/std",
"pallet-collective/std",
+ "pallet-conviction-voting/std",
"pallet-crowdloan-rewards/std",
"pallet-democracy/std",
"pallet-ethereum-chain-id/std",
@@ -213,10 +218,12 @@ std = [
"pallet-migrations/std",
"pallet-moonbeam-orbiters/std",
"pallet-parachain-staking/std",
+ "pallet-preimage/std",
"pallet-proxy-genesis-companion/std",
"pallet-proxy/std",
"pallet-randomness-collective-flip/std",
"pallet-randomness/std",
+ "pallet-referenda/std",
"pallet-scheduler/std",
"pallet-society/std",
"pallet-sudo/std",
@@ -225,6 +232,7 @@ std = [
"pallet-transaction-payment/std",
"pallet-treasury/std",
"pallet-utility/std",
+ "pallet-whitelist/std",
"pallet-xcm-transactor/std",
"pallet-xcm/std",
"parachain-info/std",
@@ -277,12 +285,15 @@ runtime-benchmarks = [
"pallet-author-slot-filter/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-collective/runtime-benchmarks",
+ "pallet-conviction-voting/runtime-benchmarks",
"pallet-crowdloan-rewards/runtime-benchmarks",
"pallet-ethereum-xcm/runtime-benchmarks",
"pallet-ethereum/runtime-benchmarks",
"pallet-moonbeam-orbiters/runtime-benchmarks",
"pallet-parachain-staking/runtime-benchmarks",
+ "pallet-preimage/runtime-benchmarks",
"pallet-randomness/runtime-benchmarks",
+ "pallet-referenda/runtime-benchmarks",
"pallet-society/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-xcm-transactor/runtime-benchmarks",
@@ -301,11 +312,14 @@ try-runtime = [
"pallet-author-slot-filter/try-runtime",
"pallet-balances/try-runtime",
"pallet-collective/try-runtime",
+ "pallet-conviction-voting/try-runtime",
"pallet-maintenance-mode/try-runtime",
#"pallet-crowdloan-rewards/try-runtime",
"pallet-maintenance-mode/try-runtime",
"pallet-migrations/try-runtime",
"pallet-parachain-staking/try-runtime",
+ "pallet-preimage/try-runtime",
+ "pallet-referenda/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-society/try-runtime",
"pallet-timestamp/try-runtime",
diff --git a/runtime/moonbase/src/governance/councils.rs b/runtime/moonbase/src/governance/councils.rs
new file mode 100644
index 00000000000..b1ac215cd77
--- /dev/null
+++ b/runtime/moonbase/src/governance/councils.rs
@@ -0,0 +1,68 @@
+// Copyright 2019-2022 PureStake Inc.
+// This file is part of Moonbeam.
+
+// Moonbeam is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Moonbeam is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Moonbeam. If not, see .
+
+//! Councils for Gov1
+
+use super::*;
+
+pub type CouncilInstance = pallet_collective::Instance1;
+pub type TechCommitteeInstance = pallet_collective::Instance2;
+pub type TreasuryCouncilInstance = pallet_collective::Instance3;
+
+impl pallet_collective::Config for Runtime {
+ type Origin = Origin;
+ type Event = Event;
+ type Proposal = Call;
+ /// The maximum amount of time (in blocks) for council members to vote on motions.
+ /// Motions may end in fewer blocks if enough votes are cast to determine the result.
+ type MotionDuration = ConstU32<{ 3 * DAYS }>;
+ /// The maximum number of proposals that can be open in the council at once.
+ type MaxProposals = ConstU32<100>;
+ /// The maximum number of council members.
+ type MaxMembers = ConstU32<100>;
+ type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote;
+ type WeightInfo = pallet_collective::weights::SubstrateWeight;
+}
+
+impl pallet_collective::Config for Runtime {
+ type Origin = Origin;
+ type Event = Event;
+ type Proposal = Call;
+ /// The maximum amount of time (in blocks) for technical committee members to vote on motions.
+ /// Motions may end in fewer blocks if enough votes are cast to determine the result.
+ type MotionDuration = ConstU32<{ 3 * DAYS }>;
+ /// The maximum number of proposals that can be open in the technical committee at once.
+ type MaxProposals = ConstU32<100>;
+ /// The maximum number of technical committee members.
+ type MaxMembers = ConstU32<100>;
+ type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote;
+ type WeightInfo = pallet_collective::weights::SubstrateWeight;
+}
+
+impl pallet_collective::Config for Runtime {
+ type Origin = Origin;
+ type Event = Event;
+ type Proposal = Call;
+ /// The maximum amount of time (in blocks) for treasury council members to vote on motions.
+ /// Motions may end in fewer blocks if enough votes are cast to determine the result.
+ type MotionDuration = ConstU32<{ 3 * DAYS }>;
+ /// The maximum number of proposals that can be open in the treasury council at once.
+ type MaxProposals = ConstU32<20>;
+ /// The maximum number of treasury council members.
+ type MaxMembers = ConstU32<9>;
+ type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote;
+ type WeightInfo = pallet_collective::weights::SubstrateWeight;
+}
diff --git a/runtime/moonbase/src/governance/democracy.rs b/runtime/moonbase/src/governance/democracy.rs
new file mode 100644
index 00000000000..6c6fabea029
--- /dev/null
+++ b/runtime/moonbase/src/governance/democracy.rs
@@ -0,0 +1,75 @@
+// Copyright 2019-2022 PureStake Inc.
+// This file is part of Moonbeam.
+
+// Moonbeam is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Moonbeam is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Moonbeam. If not, see .
+
+//! Democracy config for Gov1
+
+use super::councils::*;
+use crate::*;
+
+// The purpose of this offset is to ensure that a democratic proposal will not apply in the same
+// block as a round change.
+const ENACTMENT_OFFSET: u32 = 300;
+
+impl pallet_democracy::Config for Runtime {
+ type Proposal = Call;
+ type Event = Event;
+ type Currency = Balances;
+ type EnactmentPeriod = ConstU32<{ 1 * DAYS + ENACTMENT_OFFSET }>;
+ type LaunchPeriod = ConstU32<{ 1 * DAYS }>;
+ type VotingPeriod = ConstU32<{ 5 * DAYS }>;
+ type VoteLockingPeriod = ConstU32<{ 1 * DAYS }>;
+ type FastTrackVotingPeriod = ConstU32<{ 4 * HOURS }>;
+ type MinimumDeposit = ConstU128<{ 4 * currency::UNIT * currency::SUPPLY_FACTOR }>;
+ /// To decide what their next motion is.
+ type ExternalOrigin =
+ pallet_collective::EnsureProportionAtLeast;
+ /// To have the next scheduled referendum be a straight majority-carries vote.
+ type ExternalMajorityOrigin =
+ pallet_collective::EnsureProportionAtLeast;
+ /// To have the next scheduled referendum be a straight default-carries (NTB) vote.
+ type ExternalDefaultOrigin =
+ pallet_collective::EnsureProportionAtLeast;
+ /// To allow a shorter voting/enactment period for external proposals.
+ type FastTrackOrigin =
+ pallet_collective::EnsureProportionAtLeast;
+ /// To instant fast track.
+ type InstantOrigin =
+ pallet_collective::EnsureProportionAtLeast;
+ // To cancel a proposal which has been passed.
+ type CancellationOrigin = EitherOfDiverse<
+ EnsureRoot,
+ pallet_collective::EnsureProportionAtLeast,
+ >;
+ // To cancel a proposal before it has been passed.
+ type CancelProposalOrigin = EitherOfDiverse<
+ EnsureRoot,
+ pallet_collective::EnsureProportionAtLeast,
+ >;
+ type BlacklistOrigin = EnsureRoot;
+ // Any single technical committee member may veto a coming council proposal, however they can
+ // only do it once and it lasts only for the cooloff period.
+ type VetoOrigin = pallet_collective::EnsureMember;
+ type CooloffPeriod = ConstU32<{ 7 * DAYS }>;
+ type PreimageByteDeposit = ConstU128<{ currency::STORAGE_BYTE_FEE }>;
+ type Slash = ();
+ type InstantAllowed = ConstBool;
+ type Scheduler = Scheduler;
+ type MaxVotes = ConstU32<100>;
+ type OperationalPreimageOrigin = pallet_collective::EnsureMember;
+ type PalletsOrigin = OriginCaller;
+ type WeightInfo = pallet_democracy::weights::SubstrateWeight;
+ type MaxProposals = ConstU32<100>;
+}
diff --git a/runtime/moonbase/src/governance/mod.rs b/runtime/moonbase/src/governance/mod.rs
new file mode 100644
index 00000000000..4832e518c14
--- /dev/null
+++ b/runtime/moonbase/src/governance/mod.rs
@@ -0,0 +1,30 @@
+// Copyright 2019-2022 PureStake Inc.
+// This file is part of Moonbeam.
+
+// Moonbeam is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Moonbeam is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Moonbeam. If not, see .
+
+//! Governance configurations
+
+pub mod councils;
+mod democracy;
+pub mod referenda;
+
+use super::*;
+
+mod origins;
+pub use origins::{
+ pallet_custom_origins, ReferendumCanceller, ReferendumKiller, Spender, WhitelistedCaller,
+};
+mod tracks;
+pub use tracks::TracksInfo;
diff --git a/runtime/moonbase/src/governance/origins.rs b/runtime/moonbase/src/governance/origins.rs
new file mode 100644
index 00000000000..821504db9d2
--- /dev/null
+++ b/runtime/moonbase/src/governance/origins.rs
@@ -0,0 +1,125 @@
+// Copyright 2019-2022 PureStake Inc.
+// This file is part of Moonbeam.
+
+// Moonbeam is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Moonbeam is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+//! Custom origins for governance interventions.
+
+pub use pallet_custom_origins::*;
+
+#[frame_support::pallet]
+pub mod pallet_custom_origins {
+ use crate::{
+ currency::{SUPPLY_FACTOR, UNIT},
+ Balance,
+ };
+ use frame_support::pallet_prelude::*;
+
+ #[pallet::config]
+ pub trait Config: frame_system::Config {}
+
+ #[pallet::pallet]
+ pub struct Pallet(_);
+
+ #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)]
+ #[pallet::origin]
+ pub enum Origin {
+ /// Origin for spending (any amount of) funds.
+ Treasurer,
+ /// Origin able to cancel referenda.
+ ReferendumCanceller,
+ /// Origin able to kill referenda.
+ ReferendumKiller,
+ /// Origin able to spend up to 10,000 UNIT from the treasury at once.
+ SmallSpender,
+ /// Origin able to spend up to 100,000 UNIT from the treasury at once.
+ MediumSpender,
+ /// Origin able to spend up to 1,000,000 UNIT from the treasury at once.
+ BigSpender,
+ /// Origin able to dispatch a whitelisted call.
+ WhitelistedCaller,
+ }
+
+ macro_rules! decl_unit_ensures {
+ ( $name:ident: $success_type:ty = $success:expr ) => {
+ pub struct $name;
+ impl> + From>
+ EnsureOrigin for $name
+ {
+ type Success = $success_type;
+ fn try_origin(o: O) -> Result {
+ o.into().and_then(|o| match o {
+ Origin::$name => Ok($success),
+ r => Err(O::from(r)),
+ })
+ }
+ #[cfg(feature = "runtime-benchmarks")]
+ fn try_successful_origin() -> Result {
+ Ok(O::from(Origin::$name))
+ }
+ }
+ };
+ ( $name:ident ) => { decl_unit_ensures! { $name : () = () } };
+ ( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => {
+ decl_unit_ensures! { $name: $success_type = $success }
+ decl_unit_ensures! { $( $rest )* }
+ };
+ ( $name:ident, $( $rest:tt )* ) => {
+ decl_unit_ensures! { $name }
+ decl_unit_ensures! { $( $rest )* }
+ };
+ () => {}
+ }
+ decl_unit_ensures!(ReferendumCanceller, ReferendumKiller, WhitelistedCaller,);
+
+ macro_rules! decl_ensure {
+ (
+ $vis:vis type $name:ident: EnsureOrigin {
+ $( $item:ident = $success:expr, )*
+ }
+ ) => {
+ $vis struct $name;
+ impl> + From>
+ EnsureOrigin for $name
+ {
+ type Success = $success_type;
+ fn try_origin(o: O) -> Result {
+ o.into().and_then(|o| match o {
+ $(
+ Origin::$item => Ok($success),
+ )*
+ r => Err(O::from(r)),
+ })
+ }
+ #[cfg(feature = "runtime-benchmarks")]
+ fn try_successful_origin() -> Result {
+ // By convention the more privileged origins go later, so for greatest chance
+ // of success, we want the last one.
+ let _result: Result = Err(());
+ $(
+ let _result: Result = Ok(O::from(Origin::$item));
+ )*
+ _result
+ }
+ }
+ }
+ }
+
+ // Origins able to spend up to $AMOUNT from the treasury at once
+ decl_ensure! {
+ pub type Spender: EnsureOrigin {
+ SmallSpender = 200 * UNIT * SUPPLY_FACTOR,
+ MediumSpender = 2000 * UNIT * SUPPLY_FACTOR,
+ BigSpender = 10000 * UNIT * SUPPLY_FACTOR,
+ Treasurer = Balance::max_value(),
+ }
+ }
+}
diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs
new file mode 100644
index 00000000000..a91f8edaf91
--- /dev/null
+++ b/runtime/moonbase/src/governance/referenda.rs
@@ -0,0 +1,94 @@
+// Copyright 2019-2022 PureStake Inc.
+// This file is part of Moonbeam.
+
+// Moonbeam is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Moonbeam is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Moonbeam. If not, see .
+
+//! # Gov2 config
+//! Includes runtime configs for these substrate pallets:
+//! 1. pallet-conviction-voting
+//! 2. pallet-whitelist
+//! 3. pallet-referenda
+
+use super::*;
+use crate::currency::*;
+use frame_support::traits::{EitherOf, MapSuccess};
+use frame_system::EnsureRootWithSuccess;
+use sp_runtime::traits::Replace;
+
+parameter_types! {
+ pub const VoteLockingPeriod: BlockNumber = 7 * DAYS;
+}
+
+impl pallet_conviction_voting::Config for Runtime {
+ type WeightInfo = pallet_conviction_voting::weights::SubstrateWeight;
+ type Event = Event;
+ type Currency = Balances;
+ type VoteLockingPeriod = VoteLockingPeriod;
+ type MaxVotes = ConstU32<512>;
+ type MaxTurnout = frame_support::traits::TotalIssuanceOf;
+ type Polls = Referenda;
+}
+
+parameter_types! {
+ pub const AlarmInterval: BlockNumber = 1;
+ pub const SubmissionDeposit: Balance = 100 * UNIT * SUPPLY_FACTOR;
+ pub const UndecidingTimeout: BlockNumber = 28 * DAYS;
+}
+
+parameter_types! {
+ pub const MaxBalance: Balance = Balance::max_value();
+}
+pub type TreasurySpender = EitherOf, Spender>;
+
+impl origins::pallet_custom_origins::Config for Runtime {}
+
+// purpose of this pallet is to queue calls to be dispatched as by root for later
+impl pallet_whitelist::Config for Runtime {
+ type WeightInfo = pallet_whitelist::weights::SubstrateWeight;
+ type Event = Event;
+ type Call = Call;
+ type WhitelistOrigin = EitherOf<
+ EnsureRootWithSuccess>,
+ MapSuccess<
+ pallet_collective::EnsureProportionAtLeast<
+ Self::AccountId,
+ TechCommitteeInstance,
+ 2,
+ 3,
+ >,
+ Replace>,
+ >,
+ >;
+ type DispatchWhitelistedOrigin = EitherOf, WhitelistedCaller>;
+ type PreimageProvider = Preimage;
+}
+
+impl pallet_referenda::Config for Runtime {
+ type WeightInfo = pallet_referenda::weights::SubstrateWeight;
+ type Call = Call;
+ type Event = Event;
+ type Scheduler = Scheduler;
+ type Currency = Balances;
+ type SubmitOrigin = frame_system::EnsureSigned;
+ type CancelOrigin = ReferendumCanceller;
+ type KillOrigin = ReferendumKiller;
+ type Slash = Treasury;
+ type Votes = pallet_conviction_voting::VotesOf;
+ type Tally = pallet_conviction_voting::TallyOf;
+ type SubmissionDeposit = SubmissionDeposit;
+ type MaxQueued = ConstU32<100>;
+ type UndecidingTimeout = UndecidingTimeout;
+ type AlarmInterval = AlarmInterval;
+ type Tracks = TracksInfo;
+}
diff --git a/runtime/moonbase/src/governance/tracks.rs b/runtime/moonbase/src/governance/tracks.rs
new file mode 100644
index 00000000000..a553dfbf43c
--- /dev/null
+++ b/runtime/moonbase/src/governance/tracks.rs
@@ -0,0 +1,211 @@
+// Copyright 2022 Parity Technologies (UK) Ltd.
+// This file is part of Polkadot.
+
+// Polkadot is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Polkadot is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Polkadot. If not, see .
+
+//! Track configurations for governance.
+
+use super::*;
+use crate::currency::{KILOUNIT, SUPPLY_FACTOR, UNIT};
+
+const fn percent(x: i32) -> sp_runtime::FixedI64 {
+ sp_runtime::FixedI64::from_rational(x as u128, 100)
+}
+use pallet_referenda::Curve;
+const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] = [
+ (
+ 0,
+ pallet_referenda::TrackInfo {
+ // Name of this track.
+ name: "root",
+ // A limit for the number of referenda on this track that can be being decided at once.
+ // For Root origin this should generally be just one.
+ max_deciding: 1,
+ // Amount that must be placed on deposit before a decision can be made.
+ decision_deposit: 100 * KILOUNIT * SUPPLY_FACTOR,
+ // Amount of time this must be submitted for before a decision can be made.
+ prepare_period: 3 * HOURS,
+ // Amount of time that a decision may take to be approved prior to cancellation.
+ decision_period: 14 * DAYS,
+ // Amount of time that the approval criteria must hold before it can be approved.
+ confirm_period: 3 * HOURS,
+ // Minimum amount of time that an approved proposal must be in the dispatch queue.
+ min_enactment_period: 3 * HOURS,
+ // Minimum aye votes as percentage of overall conviction-weighted votes needed for
+ // approval as a function of time into decision period.
+ min_approval: Curve::make_reciprocal(4, 14, percent(80), percent(50), percent(100)),
+ // Minimum pre-conviction aye-votes ("support") as percentage of overall population that
+ // is needed for approval as a function of time into decision period.
+ min_support: Curve::make_linear(14, 14, percent(0), percent(50)),
+ },
+ ),
+ (
+ 1,
+ pallet_referenda::TrackInfo {
+ name: "whitelisted_caller",
+ max_deciding: 10,
+ decision_deposit: 10 * KILOUNIT * SUPPLY_FACTOR,
+ prepare_period: 30 * MINUTES,
+ decision_period: 14 * DAYS,
+ confirm_period: 10 * MINUTES,
+ min_enactment_period: 30 * MINUTES,
+ min_approval: Curve::make_reciprocal(
+ 1,
+ 14 * 24,
+ percent(96),
+ percent(50),
+ percent(100),
+ ),
+ min_support: Curve::make_reciprocal(1, 14 * 24, percent(4), percent(2), percent(50)),
+ },
+ ),
+ (
+ 10,
+ pallet_referenda::TrackInfo {
+ name: "treasurer",
+ max_deciding: 1,
+ decision_deposit: 10 * KILOUNIT * SUPPLY_FACTOR,
+ prepare_period: 1 * DAYS,
+ decision_period: 14 * DAYS,
+ confirm_period: 2 * DAYS,
+ min_enactment_period: 2 * DAYS,
+ min_approval: Curve::make_linear(14, 14, percent(50), percent(100)),
+ min_support: Curve::make_reciprocal(10, 14, percent(10), percent(0), percent(50)),
+ },
+ ),
+ (
+ 11,
+ pallet_referenda::TrackInfo {
+ name: "referendum_canceller",
+ max_deciding: 100,
+ decision_deposit: 5 * KILOUNIT * SUPPLY_FACTOR,
+ prepare_period: 4,
+ decision_period: 14 * DAYS,
+ confirm_period: 1 * DAYS,
+ min_enactment_period: 10 * MINUTES,
+ min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)),
+ min_support: Curve::make_reciprocal(1, 14, percent(1), percent(0), percent(50)),
+ },
+ ),
+ (
+ 12,
+ pallet_referenda::TrackInfo {
+ name: "referendum_killer",
+ max_deciding: 100,
+ decision_deposit: 5 * KILOUNIT * SUPPLY_FACTOR,
+ prepare_period: 4,
+ decision_period: 14 * DAYS,
+ confirm_period: 1 * DAYS,
+ min_enactment_period: 10 * MINUTES,
+ min_approval: Curve::make_reciprocal(1, 14, percent(96), percent(50), percent(100)),
+ min_support: Curve::make_reciprocal(7, 14, percent(1), percent(0), percent(10)),
+ },
+ ),
+ (
+ 13,
+ pallet_referenda::TrackInfo {
+ name: "small_spender",
+ max_deciding: 5,
+ decision_deposit: 300 * UNIT * SUPPLY_FACTOR,
+ prepare_period: 4,
+ decision_period: 14 * DAYS,
+ confirm_period: 12 * HOURS,
+ min_enactment_period: 1 * DAYS,
+ min_approval: Curve::make_linear(8, 14, percent(50), percent(100)),
+ min_support: Curve::make_reciprocal(2, 14, percent(1), percent(0), percent(10)),
+ },
+ ),
+ (
+ 14,
+ pallet_referenda::TrackInfo {
+ name: "medium_spender",
+ max_deciding: 5,
+ decision_deposit: 3000 * UNIT * SUPPLY_FACTOR,
+ prepare_period: 4,
+ decision_period: 14 * DAYS,
+ confirm_period: 24 * HOURS,
+ min_enactment_period: 1 * DAYS,
+ min_approval: Curve::make_linear(10, 14, percent(50), percent(100)),
+ min_support: Curve::make_reciprocal(4, 14, percent(1), percent(0), percent(10)),
+ },
+ ),
+ (
+ 15,
+ pallet_referenda::TrackInfo {
+ name: "big_spender",
+ max_deciding: 5,
+ decision_deposit: 30 * KILOUNIT * SUPPLY_FACTOR,
+ prepare_period: 4,
+ decision_period: 14 * DAYS,
+ confirm_period: 48 * HOURS,
+ min_enactment_period: 1 * DAYS,
+ min_approval: Curve::make_linear(14, 14, percent(50), percent(100)),
+ min_support: Curve::make_reciprocal(8, 14, percent(1), percent(0), percent(10)),
+ },
+ ),
+];
+
+pub struct TracksInfo;
+impl pallet_referenda::TracksInfo for TracksInfo {
+ type Id = u16;
+ type Origin = ::PalletsOrigin;
+ fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] {
+ &TRACKS_DATA[..]
+ }
+ fn track_for(id: &Self::Origin) -> Result {
+ if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) {
+ match system_origin {
+ frame_system::RawOrigin::Root => Ok(0),
+ _ => Err(()),
+ }
+ } else if let Ok(custom_origin) = origins::Origin::try_from(id.clone()) {
+ match custom_origin {
+ origins::Origin::WhitelistedCaller => Ok(1),
+ // Unlimited spender
+ origins::Origin::Treasurer => Ok(10),
+ // Referendum admins
+ origins::Origin::ReferendumCanceller => Ok(11),
+ origins::Origin::ReferendumKiller => Ok(12),
+ // Limited spenders
+ origins::Origin::SmallSpender => Ok(13),
+ origins::Origin::MediumSpender => Ok(14),
+ origins::Origin::BigSpender => Ok(15),
+ }
+ } else {
+ Err(())
+ }
+ }
+}
+
+#[test]
+#[should_panic] // comment out to see curve info for all tracks
+fn print_all_approval_and_support_curves() {
+ for (_, track_info) in TRACKS_DATA {
+ println!("{} TRACK", track_info.name);
+ let decision_period_days = track_info.decision_period / DAYS;
+ println!(
+ "{} DECISION PERIOD: {} days",
+ track_info.name, decision_period_days
+ );
+ println!("{} MIN APPROVAL:", track_info.name);
+ track_info
+ .min_approval
+ .info(decision_period_days, track_info.name);
+ println!("{} MIN SUPPORT:", track_info.name);
+ track_info
+ .min_support
+ .info(decision_period_days, track_info.name);
+ }
+ assert!(false);
+}
diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs
index f4fa2d758da..796a6992df6 100644
--- a/runtime/moonbase/src/lib.rs
+++ b/runtime/moonbase/src/lib.rs
@@ -111,7 +111,9 @@ pub use sp_runtime::BuildStorage;
pub type Precompiles = MoonbasePrecompiles;
pub mod asset_config;
+pub mod governance;
pub mod xcm_config;
+use governance::{councils::*, pallet_custom_origins, referenda::*};
/// UNIT, the native token, uses 18 decimals of precision.
pub mod currency {
@@ -474,6 +476,7 @@ impl pallet_evm::Config for Runtime {
parameter_types! {
pub MaximumSchedulerWeight: Weight = NORMAL_DISPATCH_RATIO * RuntimeBlockWeights::get().max_block;
+ pub const NoPreimagePostponement: Option = Some(10);
}
impl pallet_scheduler::Config for Runtime {
@@ -486,111 +489,20 @@ impl pallet_scheduler::Config for Runtime {
type MaxScheduledPerBlock = ConstU32<50>;
type WeightInfo = pallet_scheduler::weights::SubstrateWeight;
type OriginPrivilegeCmp = EqualPrivilegeOnly;
- type PreimageProvider = ();
- type NoPreimagePostponement = ();
+ // Preimage provider with which we look up call hashes to get the call
+ type PreimageProvider = Preimage;
+ // Number of blocks to postpone execution for when the item is delayed
+ type NoPreimagePostponement = NoPreimagePostponement;
}
-type CouncilInstance = pallet_collective::Instance1;
-type TechCommitteeInstance = pallet_collective::Instance2;
-type TreasuryCouncilInstance = pallet_collective::Instance3;
-
-impl pallet_collective::Config for Runtime {
- type Origin = Origin;
- type Event = Event;
- type Proposal = Call;
- /// The maximum amount of time (in blocks) for council members to vote on motions.
- /// Motions may end in fewer blocks if enough votes are cast to determine the result.
- type MotionDuration = ConstU32<{ 3 * DAYS }>;
- /// The maximum number of proposals that can be open in the council at once.
- type MaxProposals = ConstU32<100>;
- /// The maximum number of council members.
- type MaxMembers = ConstU32<100>;
- type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote;
- type WeightInfo = pallet_collective::weights::SubstrateWeight;
-}
-
-impl pallet_collective::Config for Runtime {
- type Origin = Origin;
- type Event = Event;
- type Proposal = Call;
- /// The maximum amount of time (in blocks) for technical committee members to vote on motions.
- /// Motions may end in fewer blocks if enough votes are cast to determine the result.
- type MotionDuration = ConstU32<{ 3 * DAYS }>;
- /// The maximum number of proposals that can be open in the technical committee at once.
- type MaxProposals = ConstU32<100>;
- /// The maximum number of technical committee members.
- type MaxMembers = ConstU32<100>;
- type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote;
- type WeightInfo = pallet_collective::weights::SubstrateWeight;
-}
-
-impl pallet_collective::Config for Runtime {
- type Origin = Origin;
- type Event = Event;
- type Proposal = Call;
- /// The maximum amount of time (in blocks) for treasury council members to vote on motions.
- /// Motions may end in fewer blocks if enough votes are cast to determine the result.
- type MotionDuration = ConstU32<{ 3 * DAYS }>;
- /// The maximum number of proposals that can be open in the treasury council at once.
- type MaxProposals = ConstU32<20>;
- /// The maximum number of treasury council members.
- type MaxMembers = ConstU32<9>;
- type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote;
- type WeightInfo = pallet_collective::weights::SubstrateWeight;
-}
-// The purpose of this offset is to ensure that a democratic proposal will not apply in the same
-// block as a round change.
-const ENACTMENT_OFFSET: u32 = 300;
-
-impl pallet_democracy::Config for Runtime {
- type Proposal = Call;
+impl pallet_preimage::Config for Runtime {
+ type WeightInfo = pallet_preimage::weights::SubstrateWeight;
type Event = Event;
type Currency = Balances;
- type EnactmentPeriod = ConstU32<{ 1 * DAYS + ENACTMENT_OFFSET }>;
- type LaunchPeriod = ConstU32<{ 1 * DAYS }>;
- type VotingPeriod = ConstU32<{ 5 * DAYS }>;
- type VoteLockingPeriod = ConstU32<{ 1 * DAYS }>;
- type FastTrackVotingPeriod = ConstU32<{ 4 * HOURS }>;
- type MinimumDeposit = ConstU128<{ 4 * currency::UNIT * currency::SUPPLY_FACTOR }>;
- /// To decide what their next motion is.
- type ExternalOrigin =
- pallet_collective::EnsureProportionAtLeast;
- /// To have the next scheduled referendum be a straight majority-carries vote.
- type ExternalMajorityOrigin =
- pallet_collective::EnsureProportionAtLeast;
- /// To have the next scheduled referendum be a straight default-carries (NTB) vote.
- type ExternalDefaultOrigin =
- pallet_collective::EnsureProportionAtLeast;
- /// To allow a shorter voting/enactment period for external proposals.
- type FastTrackOrigin =
- pallet_collective::EnsureProportionAtLeast;
- /// To instant fast track.
- type InstantOrigin =
- pallet_collective::EnsureProportionAtLeast;
- // To cancel a proposal which has been passed.
- type CancellationOrigin = EitherOfDiverse<
- EnsureRoot,
- pallet_collective::EnsureProportionAtLeast,
- >;
- // To cancel a proposal before it has been passed.
- type CancelProposalOrigin = EitherOfDiverse<
- EnsureRoot,
- pallet_collective::EnsureProportionAtLeast,
- >;
- type BlacklistOrigin = EnsureRoot;
- // Any single technical committee member may veto a coming council proposal, however they can
- // only do it once and it lasts only for the cooloff period.
- type VetoOrigin = pallet_collective::EnsureMember;
- type CooloffPeriod = ConstU32<{ 7 * DAYS }>;
- type PreimageByteDeposit = ConstU128<{ currency::STORAGE_BYTE_FEE }>;
- type Slash = ();
- type InstantAllowed = ConstBool;
- type Scheduler = Scheduler;
- type MaxVotes = ConstU32<100>;
- type OperationalPreimageOrigin = pallet_collective::EnsureMember;
- type PalletsOrigin = OriginCaller;
- type WeightInfo = pallet_democracy::weights::SubstrateWeight;
- type MaxProposals = ConstU32<100>;
+ type ManagerOrigin = EnsureRoot;
+ type MaxSize = ConstU32<{ 4096 * 1024 }>;
+ type BaseDeposit = ConstU128<{ 5 * currency::UNIT * currency::SUPPLY_FACTOR }>;
+ type ByteDeposit = ConstU128<{ 1 * currency::UNIT * currency::SUPPLY_FACTOR }>;
}
parameter_types! {
@@ -627,7 +539,7 @@ impl pallet_treasury::Config for Runtime {
type WeightInfo = pallet_treasury::weights::SubstrateWeight;
type SpendFunds = ();
type ProposalBondMaximum = ();
- type SpendOrigin = frame_support::traits::NeverEnsureOrigin; // Same as Polkadot
+ type SpendOrigin = TreasurySpender;
}
type IdentityForceOrigin = EitherOfDiverse<
@@ -877,8 +789,9 @@ impl InstanceFilter for ProxyType {
c,
Call::System(..)
| Call::Timestamp(..) | Call::ParachainStaking(..)
- | Call::Democracy(..) | Call::CouncilCollective(..)
- | Call::Identity(..) | Call::TechCommitteeCollective(..)
+ | Call::CouncilCollective(..)
+ | Call::Democracy(..) | Call::Identity(..)
+ | Call::TechCommitteeCollective(..)
| Call::Utility(..) | Call::Proxy(..)
| Call::AuthorMapping(..)
| Call::CrowdloanRewards(pallet_crowdloan_rewards::Call::claim { .. })
@@ -1279,6 +1192,11 @@ construct_runtime! {
Randomness: pallet_randomness::{Pallet, Call, Storage, Event, Inherent} = 39,
TreasuryCouncilCollective:
pallet_collective::::{Pallet, Call, Storage, Event, Origin, Config} = 40,
+ ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event} = 41,
+ Referenda: pallet_referenda::{Pallet, Call, Storage, Event} = 42,
+ Origins: pallet_custom_origins::{Origin} = 43,
+ Preimage: pallet_preimage::{Pallet, Call, Storage, Event} = 44,
+ Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event} = 45,
}
}