From 67a85ee1ad84d3874a8485b79afc51fb6bb8443a Mon Sep 17 00:00:00 2001 From: Francisco Valentim Castilho Date: Sun, 28 Apr 2024 21:58:49 -0300 Subject: [PATCH 1/5] Feat: Base governance implementation --- tinkernet/Cargo.lock | 5 + tinkernet/Cargo.toml | 5 + tinkernet/runtime/Cargo.toml | 18 ++ tinkernet/runtime/src/constants.rs | 1 + tinkernet/runtime/src/governance/councils.rs | 27 ++ tinkernet/runtime/src/governance/mod.rs | 95 +++++++ tinkernet/runtime/src/governance/origins.rs | 112 ++++++++ tinkernet/runtime/src/governance/tracks.rs | 275 +++++++++++++++++++ tinkernet/runtime/src/lib.rs | 39 ++- tinkernet/runtime/src/nft.rs | 6 +- tinkernet/runtime/src/rings/mod.rs | 5 +- 11 files changed, 568 insertions(+), 20 deletions(-) create mode 100644 tinkernet/runtime/src/governance/councils.rs create mode 100644 tinkernet/runtime/src/governance/mod.rs create mode 100644 tinkernet/runtime/src/governance/origins.rs create mode 100644 tinkernet/runtime/src/governance/tracks.rs diff --git a/tinkernet/Cargo.lock b/tinkernet/Cargo.lock index a6787682..fa3f6371 100644 --- a/tinkernet/Cargo.lock +++ b/tinkernet/Cargo.lock @@ -13417,6 +13417,8 @@ dependencies = [ "pallet-balances", "pallet-checked-inflation", "pallet-collator-selection", + "pallet-collective", + "pallet-conviction-voting", "pallet-identity", "pallet-inv4", "pallet-maintenance-mode", @@ -13424,6 +13426,7 @@ dependencies = [ "pallet-multisig", "pallet-ocif-staking", "pallet-preimage", + "pallet-referenda", "pallet-rings", "pallet-scheduler", "pallet-session", @@ -13434,6 +13437,7 @@ dependencies = [ "pallet-treasury", "pallet-uniques", "pallet-utility", + "pallet-whitelist", "pallet-xcm", "parachains-common", "parity-scale-codec", @@ -13445,6 +13449,7 @@ dependencies = [ "serde", "smallvec", "sp-api", + "sp-arithmetic", "sp-block-builder", "sp-consensus-aura", "sp-core", diff --git a/tinkernet/Cargo.toml b/tinkernet/Cargo.toml index cdc19023..6d09ee9e 100644 --- a/tinkernet/Cargo.toml +++ b/tinkernet/Cargo.toml @@ -99,9 +99,14 @@ pallet-treasury = { git = "https://github.com/paritytech/polkadot-sdk.git", bran pallet-transaction-payment = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } pallet-utility = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } +pallet-referenda = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } +pallet-conviction-voting = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } +pallet-whitelist = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } # Substrate Primitive Dependencies sp-api = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", branch = "release-polkadot-v1.6.0", default-features = false } diff --git a/tinkernet/runtime/Cargo.toml b/tinkernet/runtime/Cargo.toml index 3b81fb1e..20e05900 100644 --- a/tinkernet/runtime/Cargo.toml +++ b/tinkernet/runtime/Cargo.toml @@ -77,9 +77,14 @@ pallet-treasury = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-utility = { workspace = true } +pallet-referenda = { workspace = true } +pallet-conviction-voting = { workspace = true } +pallet-whitelist = { workspace = true } +pallet-collective = { workspace = true } # Substrate Primitive Dependencies sp-api = { workspace = true } +sp-arithmetic = { workspace = true } sp-block-builder = { workspace = true } sp-consensus-aura = { workspace = true } sp-core = { workspace = true } @@ -172,9 +177,14 @@ std = [ "pallet-utility/std", "pallet-xcm/std", "pallet-collator-selection/std", + "pallet-referenda/std", + "pallet-conviction-voting/std", + "pallet-whitelist/std", + "pallet-collective/std", "parachain-info/std", "polkadot-parachain/std", "sp-api/std", + "sp-arithmetic/std", "sp-block-builder/std", "sp-consensus-aura/std", "sp-core/std", @@ -224,6 +234,10 @@ runtime-benchmarks = [ "pallet-rings/runtime-benchmarks", "pallet-ocif-staking/runtime-benchmarks", "pallet-checked-inflation/runtime-benchmarks", + "pallet-referenda/runtime-benchmarks", + "pallet-conviction-voting/runtime-benchmarks", + "pallet-whitelist/runtime-benchmarks", + "pallet-collective/runtime-benchmarks", ] try-runtime = [ @@ -267,4 +281,8 @@ try-runtime = [ "pallet-checked-inflation/try-runtime", "pallet-rings/try-runtime", "pallet-asset-tx-payment/try-runtime", + "pallet-referenda/try-runtime", + "pallet-conviction-voting/try-runtime", + "pallet-whitelist/try-runtime", + "pallet-collective/try-runtime", ] diff --git a/tinkernet/runtime/src/constants.rs b/tinkernet/runtime/src/constants.rs index a33ef314..781d9c16 100644 --- a/tinkernet/runtime/src/constants.rs +++ b/tinkernet/runtime/src/constants.rs @@ -6,6 +6,7 @@ pub mod currency { use crate::Balance; pub const UNIT: Balance = 1_000_000_000_000; + pub const GRAND: Balance = UNIT * 1_000; pub const MILLIUNIT: Balance = 1_000_000_000; pub const MICROUNIT: Balance = 1_000_000; diff --git a/tinkernet/runtime/src/governance/councils.rs b/tinkernet/runtime/src/governance/councils.rs new file mode 100644 index 00000000..fcf01178 --- /dev/null +++ b/tinkernet/runtime/src/governance/councils.rs @@ -0,0 +1,27 @@ +//! Councils for Governance + +use super::*; + +pub type TinkerCouncil = pallet_collective::Instance1; + +parameter_types! { + // TODO: Check value of this parameter + pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; +} + +impl pallet_collective::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeEvent = RuntimeEvent; + type Proposal = RuntimeCall; + /// The maximum amount of time (in blocks) 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 council at once. + type MaxProposals = ConstU32<20>; + /// The maximum number of council members. + type MaxMembers = ConstU32<9>; + type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; + type SetMembersOrigin = EitherOf, CouncilAdmin>; + type MaxProposalWeight = MaxProposalWeight; +} diff --git a/tinkernet/runtime/src/governance/mod.rs b/tinkernet/runtime/src/governance/mod.rs new file mode 100644 index 00000000..9abe7328 --- /dev/null +++ b/tinkernet/runtime/src/governance/mod.rs @@ -0,0 +1,95 @@ +use self::councils::TinkerCouncil; + +use super::*; +// use crate::xcm_config::CollectivesLocation; +use frame_support::{ + parameter_types, + traits::{EitherOf, EitherOfDiverse}, +}; + +use frame_system::EnsureRootWithSuccess; +use polkadot_runtime_common::prod_or_fast; + +mod origins; +pub use origins::{ + pallet_custom_origins, CouncilAdmin, GeneralManagement, ReferendumCanceller, ReferendumKiller, + Spender, WhitelistedCaller, +}; +mod tracks; +pub use tracks::TracksInfo; + +mod councils; + +parameter_types! { + pub const VoteLockingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1); +} + +impl pallet_conviction_voting::Config for Runtime { + type WeightInfo = pallet_conviction_voting::weights::SubstrateWeight; + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type VoteLockingPeriod = VoteLockingPeriod; + type MaxVotes = ConstU32<512>; + type MaxTurnout = + frame_support::traits::tokens::currency::ActiveIssuanceOf; + type Polls = Referenda; +} + +parameter_types! { + pub const AlarmInterval: BlockNumber = 1; + pub const SubmissionDeposit: Balance = 1 * UNIT; + pub const UndecidingTimeout: BlockNumber = 14 * DAYS; +} + +parameter_types! { + pub const MaxBalance: Balance = Balance::max_value(); +} + +pub type TreasurySpender = EitherOf, Spender>; +pub type RootOrGeneralManagement = EitherOf, GeneralManagement>; + +pub type AllCouncil = pallet_collective::EnsureProportionAtLeast; + +pub type CouncilApproveOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionAtLeast, +>; + +pub type CouncilRejectOrigin = EitherOfDiverse< + EnsureRoot, + pallet_collective::EnsureProportionMoreThan, +>; + +impl pallet_custom_origins::Config for Runtime {} + +impl pallet_whitelist::Config for Runtime { + type WeightInfo = pallet_whitelist::weights::SubstrateWeight; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type WhitelistOrigin = CouncilApproveOrigin; + type DispatchWhitelistedOrigin = EitherOf, WhitelistedCaller>; + type Preimages = Preimage; +} + +impl pallet_referenda::Config for Runtime { + type WeightInfo = pallet_referenda::weights::SubstrateWeight; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + type SubmitOrigin = frame_system::EnsureSigned; + type CancelOrigin = EitherOf, ReferendumCanceller>, AllCouncil>; + type KillOrigin = EitherOf, ReferendumKiller>, AllCouncil>; + type Slash = Treasury; + type Votes = pallet_conviction_voting::VotesOf; + type Tally = pallet_conviction_voting::TallyOf; + type SubmissionDeposit = SubmissionDeposit; + type MaxQueued = ConstU32<100>; + #[cfg(not(feature = "on-chain-release-build"))] + type UndecidingTimeout = UndecidingTimeout; + #[cfg(feature = "on-chain-release-build")] + type UndecidingTimeout = UndecidingTimeout; + type AlarmInterval = AlarmInterval; + type Tracks = TracksInfo; + type Preimages = Preimage; +} diff --git a/tinkernet/runtime/src/governance/origins.rs b/tinkernet/runtime/src/governance/origins.rs new file mode 100644 index 00000000..54ba53c5 --- /dev/null +++ b/tinkernet/runtime/src/governance/origins.rs @@ -0,0 +1,112 @@ +//! Custom origins for governance interventions. + +pub use pallet_custom_origins::*; + +#[frame_support::pallet] +pub mod pallet_custom_origins { + use crate::{Balance, GRAND}; + 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 managing the composition of the council. + CouncilAdmin, + /// Origin able to cancel a referenda. + ReferendumCanceller, + /// Origin able to kill referenda. + ReferendumKiller, + /// Origin able to dispatch a whitelisted call. + WhitelistedCaller, + /// Origin for general management that does not require a runtime upgrade. + GeneralManagement, + /// Origin able to spend around $??? from the treasury at once. + SmallSpender, + /// Origin able to spend up to $??? from the treasury at once. + BigSpender, + } + + 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!( + CouncilAdmin, + ReferendumCanceller, + ReferendumKiller, + WhitelistedCaller, + GeneralManagement, + ); + + 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 + } + } + } + } + + decl_ensure! { + pub type Spender: EnsureOrigin { + SmallSpender = 10 * GRAND, + BigSpender = 1_000 * GRAND, + } + } +} diff --git a/tinkernet/runtime/src/governance/tracks.rs b/tinkernet/runtime/src/governance/tracks.rs new file mode 100644 index 00000000..757384ea --- /dev/null +++ b/tinkernet/runtime/src/governance/tracks.rs @@ -0,0 +1,275 @@ +//! Track configurations for governance. + +use super::*; + +const fn percent(x: i32) -> sp_arithmetic::FixedI64 { + sp_arithmetic::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_COUNCIL_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100)); +const SUP_COUNCIL_ADMIN: Curve = + Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50)); +const APP_GENERAL_MANAGEMENT: Curve = + Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100)); +const SUP_GENERAL_MANAGEMENT: 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_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_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(5), percent(50)); +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] = [ + ( + 0, + pallet_referenda::TrackInfo { + name: "root", + max_deciding: 1, + decision_deposit: 100 * GRAND, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 4 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 2 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 28 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 7 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 24 * HOURS, + min_approval: APP_ROOT, + min_support: SUP_ROOT, + }, + ), + ( + 1, + pallet_referenda::TrackInfo { + name: "whitelisted_caller", + max_deciding: 100, + decision_deposit: 10 * GRAND, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 2 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 30 * MINUTES, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 28 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 10 * MINUTES, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 10 * MINUTES, + min_approval: APP_WHITELISTED_CALLER, + min_support: SUP_WHITELISTED_CALLER, + }, + ), + ( + 2, + pallet_referenda::TrackInfo { + name: "general_management", + max_deciding: 10, + decision_deposit: 20 * GRAND, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 4 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 2 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 28 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 24 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 10 * MINUTES, + min_approval: APP_GENERAL_MANAGEMENT, + min_support: SUP_GENERAL_MANAGEMENT, + }, + ), + ( + 13, + pallet_referenda::TrackInfo { + name: "council_admin", + max_deciding: 10, + decision_deposit: 5 * GRAND, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 4 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 2 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 28 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 3 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 10 * MINUTES, + min_approval: APP_COUNCIL_ADMIN, + min_support: SUP_COUNCIL_ADMIN, + }, + ), + ( + 20, + pallet_referenda::TrackInfo { + name: "referendum_canceller", + max_deciding: 1_000, + decision_deposit: 10 * GRAND, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 4 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 2 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 7 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 3 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_CANCELLER, + min_support: SUP_REFERENDUM_CANCELLER, + }, + ), + ( + 21, + pallet_referenda::TrackInfo { + name: "referendum_killer", + max_deciding: 1_000, + decision_deposit: 50 * GRAND, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 4 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 2 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 28 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 3 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 10 * MINUTES, + min_approval: APP_REFERENDUM_KILLER, + min_support: SUP_REFERENDUM_KILLER, + }, + ), + ( + 32, + pallet_referenda::TrackInfo { + name: "small_spender", + max_deciding: 50, + decision_deposit: 100 * UNIT, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 4 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 28 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 2 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 24 * HOURS, + min_approval: APP_SMALL_SPENDER, + min_support: SUP_SMALL_SPENDER, + }, + ), + ( + 34, + pallet_referenda::TrackInfo { + name: "big_spender", + max_deciding: 50, + decision_deposit: 400 * UNIT, + #[cfg(not(feature = "on-chain-release-build"))] + prepare_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + prepare_period: 4 * HOURS, + #[cfg(not(feature = "on-chain-release-build"))] + decision_period: 10 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + decision_period: 28 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + confirm_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + confirm_period: 7 * DAYS, + #[cfg(not(feature = "on-chain-release-build"))] + min_enactment_period: 5 * MINUTES, + #[cfg(feature = "on-chain-release-build")] + min_enactment_period: 24 * HOURS, + min_approval: APP_BIG_SPENDER, + min_support: SUP_BIG_SPENDER, + }, + ), +]; + +pub struct TracksInfo; +impl pallet_referenda::TracksInfo for TracksInfo { + type Id = u16; + type RuntimeOrigin = ::PalletsOrigin; + fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] { + &TRACKS_DATA[..] + } + fn track_for(id: &Self::RuntimeOrigin) -> 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), + origins::Origin::GeneralManagement => Ok(2), + // General admin + origins::Origin::CouncilAdmin => Ok(13), + // Referendum admins + origins::Origin::ReferendumCanceller => Ok(20), + origins::Origin::ReferendumKiller => Ok(21), + // Limited treasury spenders + origins::Origin::SmallSpender => Ok(32), + origins::Origin::BigSpender => Ok(34), + } + } else { + Err(()) + } + } +} +pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber); diff --git a/tinkernet/runtime/src/lib.rs b/tinkernet/runtime/src/lib.rs index af3f8735..9c34c5bd 100644 --- a/tinkernet/runtime/src/lib.rs +++ b/tinkernet/runtime/src/lib.rs @@ -23,7 +23,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use codec::{Decode, Encode, MaxEncodedLen}; +use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::DmpMessageHandler; use frame_support::{ @@ -57,7 +57,6 @@ use pallet_identity::legacy::IdentityInfo; use pallet_inv4::{origin::INV4Origin, INV4Lookup}; use pallet_transaction_payment::{FeeDetails, InclusionFee, Multiplier}; use polkadot_runtime_common::SlowAdjustingFeeUpdate; -use scale_info::TypeInfo; use smallvec::smallvec; use sp_api::impl_runtime_apis; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -103,6 +102,12 @@ use common_types::*; mod assets; mod fee_handling; use fee_handling::TnkrToKsm; +mod governance; +pub use governance::{ + pallet_custom_origins, CouncilAdmin, CouncilApproveOrigin, CouncilRejectOrigin, + GeneralManagement, ReferendumCanceller, ReferendumKiller, RootOrGeneralManagement, + TreasurySpender, WhitelistedCaller, +}; mod inflation; mod inv4; // mod migrations; @@ -365,7 +370,7 @@ impl pallet_maintenance_mode::Config for Runtime { type RuntimeEvent = RuntimeEvent; type NormalCallFilter = BaseFilter; type MaintenanceCallFilter = MaintenanceFilter; - type MaintenanceOrigin = EnsureRoot; + type MaintenanceOrigin = RootOrGeneralManagement; type XcmExecutionManager = (); } @@ -593,13 +598,10 @@ parameter_types! { pub const ExecutiveBody: BodyId = BodyId::Executive; } -// We allow root only to execute privileged collator selection operations. -pub type CollatorSelectionUpdateOrigin = EnsureRoot; - impl pallet_collator_selection::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; - type UpdateOrigin = CollatorSelectionUpdateOrigin; + type UpdateOrigin = RootOrGeneralManagement; type PotId = PotId; type MaxCandidates = MaxCandidates; type MinEligibleCollators = MinCandidates; @@ -631,6 +633,7 @@ parameter_types! { pub const ProposalBondMinimum: Balance = 100 * UNIT; pub const SpendPeriod: BlockNumber = DAYS; pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS; + pub const ProposalBondMaximum: Balance = 50_000 * UNIT; pub const Burn: Permill = Permill::from_percent(1); pub const TreasuryPalletId: PalletId = PalletId(*b"ia/trsry"); pub const MaxApprovals: u32 = 100; @@ -643,10 +646,10 @@ parameter_types! { impl pallet_treasury::Config for Runtime { type PalletId = TreasuryPalletId; type Currency = Balances; - type ApproveOrigin = EnsureRoot; - type RejectOrigin = EnsureRoot; + type ApproveOrigin = CouncilApproveOrigin; + type RejectOrigin = CouncilRejectOrigin; type RuntimeEvent = RuntimeEvent; - type OnSlash = (); + type OnSlash = Treasury; type ProposalBond = ProposalBond; type ProposalBondMinimum = ProposalBondMinimum; type SpendPeriod = SpendPeriod; @@ -655,8 +658,8 @@ impl pallet_treasury::Config for Runtime { type SpendFunds = (); type WeightInfo = pallet_treasury::weights::SubstrateWeight; type MaxApprovals = MaxApprovals; - type ProposalBondMaximum = (); - type SpendOrigin = frame_support::traits::NeverEnsureOrigin; + type ProposalBondMaximum = ProposalBondMaximum; + type SpendOrigin = TreasurySpender; type AssetKind = (); type Beneficiary = AccountId; type BeneficiaryLookup = IdentityLookup; @@ -769,10 +772,10 @@ parameter_types! { impl pallet_identity::Config for Runtime { type Currency = Balances; type RuntimeEvent = RuntimeEvent; - type ForceOrigin = EnsureRoot; + type ForceOrigin = RootOrGeneralManagement; type MaxRegistrars = MaxRegistrars; type MaxSubAccounts = MaxSubAccounts; - type RegistrarOrigin = EnsureRoot; + type RegistrarOrigin = RootOrGeneralManagement; type Slashed = Treasury; type SubAccountDeposit = SubAccountDeposit; type WeightInfo = (); @@ -874,6 +877,14 @@ construct_runtime_modified!( AssetRegistry: orml_asset_registry = 94, Currencies: orml_currencies = 95, Tokens: orml_tokens = 96, + + // Governance + Council: pallet_collective:: = 100, + Referenda: pallet_referenda = 101, + ConvictionVoting: pallet_conviction_voting = 102, + Origins: governance::pallet_custom_origins = 103, + Whitelist: pallet_whitelist = 104, + } ); diff --git a/tinkernet/runtime/src/nft.rs b/tinkernet/runtime/src/nft.rs index bed6aa10..ddf4296a 100644 --- a/tinkernet/runtime/src/nft.rs +++ b/tinkernet/runtime/src/nft.rs @@ -1,11 +1,11 @@ use crate::{ common_types::CommonId, constants::currency::{MILLIUNIT, UNIT}, - AccountId, Balance, Balances, Runtime, RuntimeEvent, + AccountId, Balance, Balances, RootOrGeneralManagement, Runtime, RuntimeEvent, }; use frame_support::{parameter_types, traits::AsEnsureOriginWithArg}; -use frame_system::{EnsureRoot, EnsureSigned}; +use frame_system::EnsureSigned; parameter_types! { pub const CollectionDeposit: Balance = UNIT; @@ -23,7 +23,7 @@ impl pallet_uniques::Config for Runtime { type CollectionId = CommonId; type ItemId = CommonId; type Currency = Balances; - type ForceOrigin = EnsureRoot; + type ForceOrigin = RootOrGeneralManagement; type CreateOrigin = AsEnsureOriginWithArg>; type Locker = (); type CollectionDeposit = CollectionDeposit; diff --git a/tinkernet/runtime/src/rings/mod.rs b/tinkernet/runtime/src/rings/mod.rs index 531f390e..c569649d 100644 --- a/tinkernet/runtime/src/rings/mod.rs +++ b/tinkernet/runtime/src/rings/mod.rs @@ -1,7 +1,6 @@ -use crate::{AccountId, Balance, Runtime, RuntimeEvent}; +use crate::{Balance, RootOrGeneralManagement, Runtime, RuntimeEvent}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::parameter_types; -use frame_system::EnsureRoot; use pallet_rings::{ChainAssetsList, ChainList}; use scale_info::TypeInfo; use xcm::prelude::*; @@ -29,7 +28,7 @@ impl pallet_rings::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Chains = Chains; type MaxXCMCallLength = MaxXCMCallLength; - type MaintenanceOrigin = EnsureRoot; + type MaintenanceOrigin = RootOrGeneralManagement; type WeightInfo = pallet_rings::weights::SubstrateWeight; } From 14ec307da7dc168a31860e4e0a5a6a1b4c98cf85 Mon Sep 17 00:00:00 2001 From: Francisco Valentim Castilho Date: Sun, 28 Apr 2024 22:12:17 -0300 Subject: [PATCH 2/5] Refactor: out of place --- tinkernet/runtime/src/governance/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/tinkernet/runtime/src/governance/mod.rs b/tinkernet/runtime/src/governance/mod.rs index 9abe7328..8a0a10d3 100644 --- a/tinkernet/runtime/src/governance/mod.rs +++ b/tinkernet/runtime/src/governance/mod.rs @@ -85,9 +85,6 @@ impl pallet_referenda::Config for Runtime { type Tally = pallet_conviction_voting::TallyOf; type SubmissionDeposit = SubmissionDeposit; type MaxQueued = ConstU32<100>; - #[cfg(not(feature = "on-chain-release-build"))] - type UndecidingTimeout = UndecidingTimeout; - #[cfg(feature = "on-chain-release-build")] type UndecidingTimeout = UndecidingTimeout; type AlarmInterval = AlarmInterval; type Tracks = TracksInfo; From b3bf1fac42f363bfdd27df03faac104a0a9d9a41 Mon Sep 17 00:00:00 2001 From: Francisco Valentim Castilho Date: Tue, 30 Apr 2024 12:52:01 -0300 Subject: [PATCH 3/5] Fix: Added self managing council origin --- tinkernet/runtime/src/governance/councils.rs | 3 ++- tinkernet/runtime/src/governance/mod.rs | 13 +++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tinkernet/runtime/src/governance/councils.rs b/tinkernet/runtime/src/governance/councils.rs index fcf01178..65cfffb2 100644 --- a/tinkernet/runtime/src/governance/councils.rs +++ b/tinkernet/runtime/src/governance/councils.rs @@ -22,6 +22,7 @@ impl pallet_collective::Config for Runtime { type MaxMembers = ConstU32<9>; type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; - type SetMembersOrigin = EitherOf, CouncilAdmin>; + type SetMembersOrigin = + EitherOf, CouncilAdmin>, CouncilTwoThirds>; type MaxProposalWeight = MaxProposalWeight; } diff --git a/tinkernet/runtime/src/governance/mod.rs b/tinkernet/runtime/src/governance/mod.rs index 8a0a10d3..9b1bb380 100644 --- a/tinkernet/runtime/src/governance/mod.rs +++ b/tinkernet/runtime/src/governance/mod.rs @@ -49,16 +49,13 @@ pub type TreasurySpender = EitherOf pub type RootOrGeneralManagement = EitherOf, GeneralManagement>; pub type AllCouncil = pallet_collective::EnsureProportionAtLeast; +pub type CouncilTwoThirds = + pallet_collective::EnsureProportionAtLeast; +pub type ConcilHalf = pallet_collective::EnsureProportionAtLeast; -pub type CouncilApproveOrigin = EitherOfDiverse< - EnsureRoot, - pallet_collective::EnsureProportionAtLeast, ->; +pub type CouncilApproveOrigin = EitherOfDiverse, CouncilTwoThirds>; -pub type CouncilRejectOrigin = EitherOfDiverse< - EnsureRoot, - pallet_collective::EnsureProportionMoreThan, ->; +pub type CouncilRejectOrigin = EitherOfDiverse, ConcilHalf>; impl pallet_custom_origins::Config for Runtime {} From f2b00d19e69d35ad37a792103b3d69ca3665875a Mon Sep 17 00:00:00 2001 From: Francisco Valentim Castilho Date: Tue, 30 Apr 2024 20:56:09 -0300 Subject: [PATCH 4/5] Fix: proper council parameters --- tinkernet/runtime/src/governance/councils.rs | 5 ++--- tinkernet/runtime/src/governance/mod.rs | 13 +++++-------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/tinkernet/runtime/src/governance/councils.rs b/tinkernet/runtime/src/governance/councils.rs index 65cfffb2..06c82249 100644 --- a/tinkernet/runtime/src/governance/councils.rs +++ b/tinkernet/runtime/src/governance/councils.rs @@ -19,10 +19,9 @@ impl pallet_collective::Config for Runtime { /// The maximum number of proposals that can be open in council at once. type MaxProposals = ConstU32<20>; /// The maximum number of council members. - type MaxMembers = ConstU32<9>; + type MaxMembers = ConstU32<7>; type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; - type SetMembersOrigin = - EitherOf, CouncilAdmin>, CouncilTwoThirds>; + type SetMembersOrigin = EitherOf; type MaxProposalWeight = MaxProposalWeight; } diff --git a/tinkernet/runtime/src/governance/mod.rs b/tinkernet/runtime/src/governance/mod.rs index 9b1bb380..0c1314b2 100644 --- a/tinkernet/runtime/src/governance/mod.rs +++ b/tinkernet/runtime/src/governance/mod.rs @@ -2,10 +2,7 @@ use self::councils::TinkerCouncil; use super::*; // use crate::xcm_config::CollectivesLocation; -use frame_support::{ - parameter_types, - traits::{EitherOf, EitherOfDiverse}, -}; +use frame_support::{parameter_types, traits::EitherOf}; use frame_system::EnsureRootWithSuccess; use polkadot_runtime_common::prod_or_fast; @@ -49,13 +46,13 @@ pub type TreasurySpender = EitherOf pub type RootOrGeneralManagement = EitherOf, GeneralManagement>; pub type AllCouncil = pallet_collective::EnsureProportionAtLeast; -pub type CouncilTwoThirds = - pallet_collective::EnsureProportionAtLeast; pub type ConcilHalf = pallet_collective::EnsureProportionAtLeast; +pub type CouncilThreeFifths = + pallet_collective::EnsureProportionAtLeast; -pub type CouncilApproveOrigin = EitherOfDiverse, CouncilTwoThirds>; +pub type CouncilApproveOrigin = EitherOf, CouncilThreeFifths>; -pub type CouncilRejectOrigin = EitherOfDiverse, ConcilHalf>; +pub type CouncilRejectOrigin = EitherOf, ConcilHalf>; impl pallet_custom_origins::Config for Runtime {} From d9cbf46c988109820ed182576dacb0841b570de4 Mon Sep 17 00:00:00 2001 From: Francisco Valentim Castilho Date: Mon, 20 May 2024 01:30:22 -0300 Subject: [PATCH 5/5] Fix: Changes on council and tracks params --- tinkernet/runtime/src/governance/councils.rs | 11 +++++++---- tinkernet/runtime/src/governance/mod.rs | 16 ++++++++-------- tinkernet/runtime/src/governance/tracks.rs | 4 ++-- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tinkernet/runtime/src/governance/councils.rs b/tinkernet/runtime/src/governance/councils.rs index 06c82249..e4b07c36 100644 --- a/tinkernet/runtime/src/governance/councils.rs +++ b/tinkernet/runtime/src/governance/councils.rs @@ -5,8 +5,11 @@ use super::*; pub type TinkerCouncil = pallet_collective::Instance1; parameter_types! { - // TODO: Check value of this parameter pub MaxProposalWeight: Weight = Perbill::from_percent(50) * RuntimeBlockWeights::get().max_block; + pub MaxMotionDuration: u32 = 3 * DAYS ; + pub MaxProposals: u32 = 20; + pub MaxMembers: u32 = 5; + } impl pallet_collective::Config for Runtime { @@ -15,11 +18,11 @@ impl pallet_collective::Config for Runtime { type Proposal = RuntimeCall; /// The maximum amount of time (in blocks) 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 }>; + type MotionDuration = MaxMotionDuration; /// The maximum number of proposals that can be open in council at once. - type MaxProposals = ConstU32<20>; + type MaxProposals = MaxProposals; /// The maximum number of council members. - type MaxMembers = ConstU32<7>; + type MaxMembers = MaxMembers; type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; type WeightInfo = pallet_collective::weights::SubstrateWeight; type SetMembersOrigin = EitherOf; diff --git a/tinkernet/runtime/src/governance/mod.rs b/tinkernet/runtime/src/governance/mod.rs index 0c1314b2..2b636364 100644 --- a/tinkernet/runtime/src/governance/mod.rs +++ b/tinkernet/runtime/src/governance/mod.rs @@ -5,7 +5,6 @@ use super::*; use frame_support::{parameter_types, traits::EitherOf}; use frame_system::EnsureRootWithSuccess; -use polkadot_runtime_common::prod_or_fast; mod origins; pub use origins::{ @@ -18,7 +17,7 @@ pub use tracks::TracksInfo; mod councils; parameter_types! { - pub const VoteLockingPeriod: BlockNumber = prod_or_fast!(7 * DAYS, 1); + pub const VoteLockingPeriod: BlockNumber = 7 * DAYS; } impl pallet_conviction_voting::Config for Runtime { @@ -34,7 +33,7 @@ impl pallet_conviction_voting::Config for Runtime { parameter_types! { pub const AlarmInterval: BlockNumber = 1; - pub const SubmissionDeposit: Balance = 1 * UNIT; + pub const SubmissionDeposit: Balance = UNIT; pub const UndecidingTimeout: BlockNumber = 14 * DAYS; } @@ -42,16 +41,16 @@ parameter_types! { pub const MaxBalance: Balance = Balance::max_value(); } -pub type TreasurySpender = EitherOf, Spender>; -pub type RootOrGeneralManagement = EitherOf, GeneralManagement>; - pub type AllCouncil = pallet_collective::EnsureProportionAtLeast; +pub type CouncilMoreThanApprove = + pallet_collective::EnsureProportionMoreThan; pub type ConcilHalf = pallet_collective::EnsureProportionAtLeast; pub type CouncilThreeFifths = pallet_collective::EnsureProportionAtLeast; +pub type TreasurySpender = EitherOf, Spender>; +pub type RootOrGeneralManagement = EitherOf, GeneralManagement>; pub type CouncilApproveOrigin = EitherOf, CouncilThreeFifths>; - pub type CouncilRejectOrigin = EitherOf, ConcilHalf>; impl pallet_custom_origins::Config for Runtime {} @@ -72,7 +71,8 @@ impl pallet_referenda::Config for Runtime { type Scheduler = Scheduler; type Currency = Balances; type SubmitOrigin = frame_system::EnsureSigned; - type CancelOrigin = EitherOf, ReferendumCanceller>, AllCouncil>; + type CancelOrigin = + EitherOf, ReferendumCanceller>, CouncilMoreThanApprove>; type KillOrigin = EitherOf, ReferendumKiller>, AllCouncil>; type Slash = Treasury; type Votes = pallet_conviction_voting::VotesOf; diff --git a/tinkernet/runtime/src/governance/tracks.rs b/tinkernet/runtime/src/governance/tracks.rs index 757384ea..dfcf7c41 100644 --- a/tinkernet/runtime/src/governance/tracks.rs +++ b/tinkernet/runtime/src/governance/tracks.rs @@ -88,7 +88,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "general_management", max_deciding: 10, - decision_deposit: 20 * GRAND, + decision_deposit: 10 * GRAND, #[cfg(not(feature = "on-chain-release-build"))] prepare_period: 4 * MINUTES, #[cfg(feature = "on-chain-release-build")] @@ -114,7 +114,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 8] pallet_referenda::TrackInfo { name: "council_admin", max_deciding: 10, - decision_deposit: 5 * GRAND, + decision_deposit: 10 * GRAND, #[cfg(not(feature = "on-chain-release-build"))] prepare_period: 4 * MINUTES, #[cfg(feature = "on-chain-release-build")]