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 index 6fb96a19412..b1ac215cd77 100644 --- a/runtime/moonbase/src/governance/councils.rs +++ b/runtime/moonbase/src/governance/councils.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . -//! Councils from old governance config +//! Councils for Gov1 use super::*; diff --git a/runtime/moonbase/src/governance/democracy.rs b/runtime/moonbase/src/governance/democracy.rs index 9756bc0efc0..6c6fabea029 100644 --- a/runtime/moonbase/src/governance/democracy.rs +++ b/runtime/moonbase/src/governance/democracy.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . -//! Old democracy config +//! Democracy config for Gov1 use super::councils::*; use crate::*; diff --git a/runtime/moonbase/src/governance/mod.rs b/runtime/moonbase/src/governance/mod.rs index 09081544714..5f601d10ad1 100644 --- a/runtime/moonbase/src/governance/mod.rs +++ b/runtime/moonbase/src/governance/mod.rs @@ -14,9 +14,18 @@ // You should have received a copy of the GNU General Public License // along with Moonbeam. If not, see . -//! New governance configurations for the Moonbase runtime. - -use super::*; +//! Governance configurations pub mod councils; mod democracy; +pub mod referenda; + +use super::*; + +mod origins; +pub use origins::{ + pallet_custom_origins, GeneralAdmin, 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..671daa26547 --- /dev/null +++ b/runtime/moonbase/src/governance/origins.rs @@ -0,0 +1,137 @@ +// 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::{KILOUNIT, 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 for managing the registrar. + GeneralAdmin, + /// Origin able to cancel referenda. + ReferendumCanceller, + /// Origin able to kill referenda. + ReferendumKiller, + /// Origin able to spend up to 250 UNIT from the treasury at once. + SmallTipper, + /// Origin able to spend up to 1,000 UNIT from the treasury at once. + BigTipper, + /// 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!( + GeneralAdmin, + 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 { + SmallTipper = 250 * UNIT, + BigTipper = 1 * KILOUNIT, + SmallSpender = 10 * KILOUNIT, + MediumSpender = 100 * KILOUNIT, + BigSpender = 1_000 * KILOUNIT, + } + } +} diff --git a/runtime/moonbase/src/governance/referenda.rs b/runtime/moonbase/src/governance/referenda.rs new file mode 100644 index 00000000000..94e1f56a098 --- /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; + 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..a6782624a27 --- /dev/null +++ b/runtime/moonbase/src/governance/tracks.rs @@ -0,0 +1,274 @@ +// 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, UNIT}; + +const fn percent(x: i32) -> sp_runtime::FixedI64 { + sp_runtime::FixedI64::from_rational(x as u128, 100) +} +use pallet_referenda::Curve; +const APP_ROOT: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_ROOT: Curve = Curve::make_linear(28, 28, percent(0), percent(50)); +const APP_TREASURER: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_TREASURER: Curve = Curve::make_linear(28, 28, percent(0), percent(50)); +const APP_GENERAL_ADMIN: Curve = + Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_GENERAL_ADMIN: Curve = + Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50)); +const APP_REFERENDUM_CANCELLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_REFERENDUM_CANCELLER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_REFERENDUM_KILLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_REFERENDUM_KILLER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_SMALL_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100)); +const SUP_SMALL_TIPPER: Curve = Curve::make_reciprocal(1, 28, percent(4), percent(0), percent(50)); +const APP_BIG_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100)); +const SUP_BIG_TIPPER: Curve = Curve::make_reciprocal(8, 28, percent(1), percent(0), percent(50)); +const APP_SMALL_SPENDER: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_SMALL_SPENDER: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_MEDIUM_SPENDER: Curve = Curve::make_linear(23, 28, percent(50), percent(100)); +const SUP_MEDIUM_SPENDER: Curve = + Curve::make_reciprocal(16, 28, percent(1), percent(0), percent(50)); +const APP_BIG_SPENDER: Curve = Curve::make_linear(28, 28, percent(50), percent(100)); +const SUP_BIG_SPENDER: Curve = Curve::make_reciprocal(20, 28, percent(1), percent(0), percent(50)); +const APP_WHITELISTED_CALLER: Curve = + Curve::make_reciprocal(16, 28 * 24, percent(96), percent(50), percent(100)); +const SUP_WHITELISTED_CALLER: Curve = + Curve::make_reciprocal(1, 28, percent(20), percent(10), percent(50)); + +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 11] = [ + ( + 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: 1_000 * KILOUNIT, + // 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: 28 * 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: APP_ROOT, + // 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: SUP_ROOT, + }, + ), + // Fastrack + ( + 1, + pallet_referenda::TrackInfo { + name: "whitelisted_caller", + max_deciding: 10, + decision_deposit: 10_000 * KILOUNIT, + prepare_period: 3 * HOURS, + decision_period: 28 * DAYS, + confirm_period: 10 * MINUTES, + min_enactment_period: 30 * MINUTES, + min_approval: APP_WHITELISTED_CALLER, + min_support: SUP_WHITELISTED_CALLER, + }, + ), + ( + 10, + pallet_referenda::TrackInfo { + name: "treasurer", + max_deciding: 10, + decision_deposit: 5 * KILOUNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 2 * DAYS, + min_approval: APP_TREASURER, + min_support: SUP_TREASURER, + }, + ), + ( + 11, + pallet_referenda::TrackInfo { + name: "general_admin", + max_deciding: 10, + decision_deposit: 5 * KILOUNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 2 * DAYS, + min_approval: APP_GENERAL_ADMIN, + min_support: SUP_GENERAL_ADMIN, + }, + ), + ( + 12, + pallet_referenda::TrackInfo { + name: "referendum_canceller", + max_deciding: 1_000, + decision_deposit: 50 * KILOUNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_CANCELLER, + min_support: SUP_REFERENDUM_CANCELLER, + }, + ), + ( + 13, + pallet_referenda::TrackInfo { + name: "referendum_killer", + max_deciding: 1_000, + decision_deposit: 50 * KILOUNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_KILLER, + min_support: SUP_REFERENDUM_KILLER, + }, + ), + ( + 14, + pallet_referenda::TrackInfo { + name: "small_tipper", + max_deciding: 200, + decision_deposit: 5 * 100 * UNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 3 * HOURS, + min_enactment_period: 28 * DAYS, + min_approval: APP_SMALL_TIPPER, + min_support: SUP_SMALL_TIPPER, + }, + ), + ( + 15, + pallet_referenda::TrackInfo { + name: "big_tipper", + max_deciding: 100, + decision_deposit: 50 * 100 * UNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 6 * HOURS, + min_enactment_period: 28 * DAYS, + min_approval: APP_BIG_TIPPER, + min_support: SUP_BIG_TIPPER, + }, + ), + ( + 16, + pallet_referenda::TrackInfo { + name: "small_spender", + max_deciding: 50, + decision_deposit: 500 * 100 * UNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 12 * HOURS, + min_enactment_period: 28 * DAYS, + min_approval: APP_SMALL_SPENDER, + min_support: SUP_SMALL_SPENDER, + }, + ), + ( + 17, + pallet_referenda::TrackInfo { + name: "medium_spender", + max_deciding: 20, + decision_deposit: 1_500 * 100 * UNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: 28 * DAYS, + min_approval: APP_MEDIUM_SPENDER, + min_support: SUP_MEDIUM_SPENDER, + }, + ), + ( + 18, + pallet_referenda::TrackInfo { + name: "big_spender", + max_deciding: 10, + decision_deposit: 5 * KILOUNIT, + prepare_period: 4, + decision_period: 28 * DAYS, + confirm_period: 48 * HOURS, + min_enactment_period: 28 * DAYS, + min_approval: APP_BIG_SPENDER, + min_support: SUP_BIG_SPENDER, + }, + ), +]; + +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), + // General admin + origins::Origin::Treasurer => Ok(10), + origins::Origin::GeneralAdmin => Ok(11), + // Referendum admins + origins::Origin::ReferendumCanceller => Ok(12), + origins::Origin::ReferendumKiller => Ok(13), + // Limited treasury spenders + origins::Origin::SmallTipper => Ok(14), + origins::Origin::BigTipper => Ok(15), + origins::Origin::SmallSpender => Ok(16), + origins::Origin::MediumSpender => Ok(17), + origins::Origin::BigSpender => Ok(18), + } + } else { + Err(()) + } + } +} + +#[test] +#[should_panic] // comment out to see curve info for all tracks +fn print_all_approval_and_support_curves() { + // decision_period 28 days + confirm_period 2 days + for (_, track_info) in TRACKS_DATA { + println!("TRACK NAME: {}", track_info.name); + println!("Min approval info:"); + track_info.min_approval.info(30, track_info.name); + println!("Min support info:"); + track_info.min_support.info(30, track_info.name); + } + assert!(false); +} diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index b8e20b34c01..796a6992df6 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -113,7 +113,7 @@ pub type Precompiles = MoonbasePrecompiles; pub mod asset_config; pub mod governance; pub mod xcm_config; -use governance::councils::*; +use governance::{councils::*, pallet_custom_origins, referenda::*}; /// UNIT, the native token, uses 18 decimals of precision. pub mod currency { @@ -476,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 { @@ -488,8 +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; +} + +impl pallet_preimage::Config for Runtime { + type WeightInfo = pallet_preimage::weights::SubstrateWeight; + type Event = Event; + type Currency = Balances; + 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! { @@ -526,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< @@ -1179,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, } }