diff --git a/tinkernet/Cargo.lock b/tinkernet/Cargo.lock index fe609f81..e81f5bde 100644 --- a/tinkernet/Cargo.lock +++ b/tinkernet/Cargo.lock @@ -13418,6 +13418,8 @@ dependencies = [ "pallet-balances", "pallet-checked-inflation", "pallet-collator-selection", + "pallet-collective", + "pallet-conviction-voting", "pallet-identity", "pallet-inv4", "pallet-maintenance-mode", @@ -13425,6 +13427,7 @@ dependencies = [ "pallet-multisig", "pallet-ocif-staking", "pallet-preimage", + "pallet-referenda", "pallet-rings", "pallet-scheduler", "pallet-session", @@ -13435,6 +13438,7 @@ dependencies = [ "pallet-treasury", "pallet-uniques", "pallet-utility", + "pallet-whitelist", "pallet-xcm", "parachains-common", "parity-scale-codec", @@ -13446,6 +13450,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 74808f36..f3e5e9a6 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..e4b07c36 --- /dev/null +++ b/tinkernet/runtime/src/governance/councils.rs @@ -0,0 +1,30 @@ +//! Councils for Governance + +use super::*; + +pub type TinkerCouncil = pallet_collective::Instance1; + +parameter_types! { + 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 { + 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 = MaxMotionDuration; + /// The maximum number of proposals that can be open in council at once. + type MaxProposals = MaxProposals; + /// The maximum number of council members. + type MaxMembers = MaxMembers; + type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote; + type WeightInfo = pallet_collective::weights::SubstrateWeight; + type SetMembersOrigin = EitherOf; + 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..2b636364 --- /dev/null +++ b/tinkernet/runtime/src/governance/mod.rs @@ -0,0 +1,86 @@ +use self::councils::TinkerCouncil; + +use super::*; +// use crate::xcm_config::CollectivesLocation; +use frame_support::{parameter_types, traits::EitherOf}; + +use frame_system::EnsureRootWithSuccess; + +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 = 7 * DAYS; +} + +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 = UNIT; + pub const UndecidingTimeout: BlockNumber = 14 * DAYS; +} + +parameter_types! { + pub const MaxBalance: Balance = Balance::max_value(); +} + +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 {} + +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>, CouncilMoreThanApprove>; + 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>; + 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..dfcf7c41 --- /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: 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: 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: 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: 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 ac4b0015..a4c9c41b 100644 --- a/tinkernet/runtime/src/lib.rs +++ b/tinkernet/runtime/src/lib.rs @@ -102,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; @@ -371,7 +377,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 = (); } @@ -599,13 +605,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; @@ -637,6 +640,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; @@ -649,10 +653,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; @@ -661,8 +665,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; @@ -775,10 +779,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 = (); @@ -880,6 +884,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; }