From 70ed8864799d89d402c0177584f72794f930b6b4 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Mon, 7 Oct 2024 13:58:02 +0100 Subject: [PATCH 1/5] Add PoToC Signed-off-by: Oliver Tale-Yazdi --- .../collectives-polkadot/src/lib.rs | 15 +- .../collectives-polkadot/src/potoc/mod.rs | 293 ++++++++++++++++++ .../collectives-polkadot/src/potoc/origins.rs | 66 ++++ .../collectives-polkadot/src/potoc/tracks.rs | 91 ++++++ system-parachains/constants/src/polkadot.rs | 5 +- 5 files changed, 462 insertions(+), 8 deletions(-) create mode 100644 system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs create mode 100644 system-parachains/collectives/collectives-polkadot/src/potoc/origins.rs create mode 100644 system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs diff --git a/system-parachains/collectives/collectives-polkadot/src/lib.rs b/system-parachains/collectives/collectives-polkadot/src/lib.rs index eccb696614..40c6474a77 100644 --- a/system-parachains/collectives/collectives-polkadot/src/lib.rs +++ b/system-parachains/collectives/collectives-polkadot/src/lib.rs @@ -44,11 +44,13 @@ mod weights; pub mod xcm_config; // Fellowship configurations. pub mod fellowship; +pub mod potoc; pub use ambassador::pallet_ambassador_origins; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use fellowship::{pallet_fellowship_origins, Fellows}; +use potoc::pallet_potoc_origins; use impls::{AllianceProposalProvider, EqualOrGreatestRootCmp, ToParentTreasury}; use polkadot_runtime_common::impls::{ ContainsParts as ContainsLocationParts, VersionedLocatableAsset, @@ -723,16 +725,11 @@ construct_runtime!( AllianceMotion: pallet_collective:: = 51, // The Fellowship. - // pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1; FellowshipCollective: pallet_ranked_collective:: = 60, - // pub type FellowshipReferendaInstance = pallet_referenda::Instance1; FellowshipReferenda: pallet_referenda:: = 61, FellowshipOrigins: pallet_fellowship_origins = 62, - // pub type FellowshipCoreInstance = pallet_core_fellowship::Instance1; FellowshipCore: pallet_core_fellowship:: = 63, - // pub type FellowshipSalaryInstance = pallet_salary::Instance1; FellowshipSalary: pallet_salary:: = 64, - // pub type FellowshipTreasuryInstance = pallet_treasury::Instance1; FellowshipTreasury: pallet_treasury:: = 65, // Ambassador Program. @@ -742,6 +739,14 @@ construct_runtime!( AmbassadorCore: pallet_core_fellowship:: = 73, AmbassadorSalary: pallet_salary:: = 74, AmbassadorTreasury: pallet_treasury:: = 75, + + // Tooling Collective + PotocCollective: pallet_ranked_collective:: = 80, + PotocReferenda: pallet_referenda:: = 81, + PotocOrigins: pallet_potoc_origins = 82, + PotocCore: pallet_core_fellowship:: = 83, + PotocSalary: pallet_salary:: = 84, + PotocTreasury: pallet_treasury:: = 85 } ); diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs new file mode 100644 index 0000000000..a7c6bf9110 --- /dev/null +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs @@ -0,0 +1,293 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see . + +//! The Polkadot Tooling Collective. + +mod origins; +mod tracks; + +use frame_support::traits::NeverEnsureOrigin; +use crate::{ + impls::ToParentTreasury, + weights, + xcm_config::{AssetHubUsdt, FellowshipAdminBodyId, LocationToAccountId, TreasurerBodyId}, + AccountId, AssetRateWithNative, Balance, Balances, GovernanceLocation, PolkadotTreasuryAccount, + PotocReferenda, Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, DAYS, + POTOC_TREASURY_PALLET_ID, *, +}; +use frame_support::traits::TryMapSuccess; +use frame_support::{ + parameter_types, + traits::{ + EitherOf, EitherOfDiverse, MapSuccess, OriginTrait, PalletInfoAccess, TryWithMorphedArg, + }, + PalletId, +}; +use frame_system::{EnsureRoot, EnsureRootWithSuccess}; +pub use origins::{ + pallet_origins as pallet_potoc_origins, Members, +}; +use pallet_ranked_collective::EnsureOfRank; +use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; +use polkadot_runtime_common::impls::{ + LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, +}; +use polkadot_runtime_constants::{currency::GRAND, time::HOURS, xcm::body::FELLOWSHIP_ADMIN_INDEX}; +use sp_arithmetic::Permill; +use sp_core::{ConstU128, ConstU32}; +use sp_runtime::traits::{ + ConstU16, ConvertToValue, IdentityLookup, Replace, ReplaceWithDefault, TakeFirst, +}; +use xcm_builder::{AliasesIntoAccountId32, PayOverXcm}; + +#[cfg(feature = "runtime-benchmarks")] +use crate::impls::benchmarks::{OpenHrmpChannel, PayWithEnsure}; + +/// PoToC's members ranks. +pub mod ranks { + use pallet_ranked_collective::Rank; + + /// A Candidate. + pub const CANDIDATE: Rank = 0; + /// A Member. + pub const MEMBER: Rank = 1; +} + +/// Root, FellowshipAdmin or Members. +pub type OpenGovOrMembers = EitherOfDiverse< + EnsureRoot, + EitherOfDiverse>, Members>, +>; + +/// Promote origin, either: +/// - Root +/// - PoToC's Admin origin (i.e. token holder referendum) +/// - Members vote +pub type PromoteOrigin = EitherOf< + EnsureRootWithSuccess>, + EitherOf< + MapSuccess< + EnsureXcm>, + Replace>, + >, + TryMapSuccess>>, + >, +>; + +impl pallet_potoc_origins::Config for Runtime {} + +pub type PotocReferendaInstance = pallet_referenda::Instance3; + +impl pallet_referenda::Config for Runtime { + type WeightInfo = weights::pallet_referenda_fellowship_referenda::WeightInfo; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type Scheduler = Scheduler; + type Currency = Balances; + // Members can submit proposals, candidates cannot. + type SubmitOrigin = + pallet_ranked_collective::EnsureMember; + type CancelOrigin = OpenGovOrMembers; + type KillOrigin = OpenGovOrMembers; + type Slash = ToParentTreasury; + type Votes = pallet_ranked_collective::Votes; + type Tally = pallet_ranked_collective::TallyOf; + type SubmissionDeposit = ConstU128<0>; + type MaxQueued = ConstU32<100>; + type UndecidingTimeout = ConstU32<{ 7 * DAYS }>; + type AlarmInterval = ConstU32<1>; + type Tracks = tracks::TracksInfo; + type Preimages = Preimage; +} + +pub type PotocCollectiveInstance = pallet_ranked_collective::Instance3; + +impl pallet_ranked_collective::Config for Runtime { + type WeightInfo = weights::pallet_ranked_collective_fellowship_collective::WeightInfo; + type RuntimeEvent = RuntimeEvent; + + // Promotions and the induction of new members are serviced by `PotocCore` pallet instance. + #[cfg(not(feature = "runtime-benchmarks"))] + type PromoteOrigin = frame_system::EnsureNever; + // The maximum value of `u16` set as a success value for the root to ensure the benchmarks will + // pass. + #[cfg(feature = "runtime-benchmarks")] + type PromoteOrigin = EnsureRootWithSuccess>; + + // Demotion is by any of: + // - Root can demote arbitrarily. + // - PoToC's Admin origin (i.e. token holder referendum); + // + // The maximum value of `u16` set as a success value for the root to ensure the benchmarks will + // pass. + type DemoteOrigin = EitherOf< + EnsureRootWithSuccess>, + MapSuccess< + EnsureXcm>, + Replace>, + >, + >; + // Exchange is by any of: + // - Root can exchange arbitrarily. + // - the Members origin + type ExchangeOrigin = + EitherOf, Members>; + type AddOrigin = MapSuccess>; + type RemoveOrigin = Self::DemoteOrigin; + type Polls = PotocReferenda; + // Map ranks 1:1 to the tracks that they can vote on. + type MinRankOfClass = sp_runtime::traits::Identity; + type MemberSwappedHandler = (crate::PotocCore, crate::PotocSalary); + type VoteWeight = pallet_ranked_collective::Geometric; + type MaxMemberCount = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkSetup = (crate::PotocCore, crate::PotocSalary); +} + +pub type PotocCoreInstance = pallet_core_fellowship::Instance3; + +impl pallet_core_fellowship::Config for Runtime { + type WeightInfo = weights::pallet_core_fellowship_fellowship_core::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type Members = pallet_ranked_collective::Pallet; + type Balance = Balance; + type ParamsOrigin = OpenGovOrMembers; + type InductOrigin = OpenGovOrMembers; + type PromoteOrigin = PromoteOrigin; + type ApproveOrigin = Self::PromoteOrigin; + // Fast promotions are not needed with a single rank and would require higher turnout. + type FastPromoteOrigin = NeverEnsureOrigin; + type EvidenceSize = ConstU32<65536>; + type MaxRank = ConstU32<9>; +} + +pub type PotocSalaryInstance = pallet_salary::Instance3; + +use xcm::prelude::*; + +parameter_types! { + // The interior location on AssetHub for the paying account. This is PoToC's Salary + // pallet instance. This sovereign account will need funding. + pub Interior: InteriorLocation = PalletInstance(::index() as u8).into(); +} + +const USDT_UNITS: u128 = 1_000_000; + +/// [`PayOverXcm`] setup to pay PoToC's salary on the AssetHub in USDT. +pub type PotocSalaryPaymaster = PayOverXcm< + Interior, + crate::xcm_config::XcmRouter, + crate::PolkadotXcm, + ConstU32<{ 6 * HOURS }>, + AccountId, + (), + ConvertToValue, + AliasesIntoAccountId32<(), AccountId>, +>; + +impl pallet_salary::Config for Runtime { + type WeightInfo = weights::pallet_salary_fellowship_salary::WeightInfo; + type RuntimeEvent = RuntimeEvent; + + #[cfg(not(feature = "runtime-benchmarks"))] + type Paymaster = PotocSalaryPaymaster; + #[cfg(feature = "runtime-benchmarks")] + type Paymaster = PayWithEnsure>>; + type Members = pallet_ranked_collective::Pallet; + + #[cfg(not(feature = "runtime-benchmarks"))] + type Salary = pallet_core_fellowship::Pallet; + #[cfg(feature = "runtime-benchmarks")] + type Salary = frame_support::traits::tokens::ConvertRank< + crate::impls::benchmarks::RankToSalary, + >; + // 15 days to register for a salary payment. + type RegistrationPeriod = ConstU32<{ 15 * DAYS }>; + // 15 days to claim the salary payment. + type PayoutPeriod = ConstU32<{ 15 * DAYS }>; + // Total monthly salary budget. + type Budget = ConstU128<{ 250_000 * USDT_UNITS }>; +} + +parameter_types! { + pub const PotocTreasuryPalletId: PalletId = POTOC_TREASURY_PALLET_ID; + pub const ProposalBond: Permill = Permill::from_percent(100); + pub const Burn: Permill = Permill::from_percent(0); + pub const MaxBalance: Balance = Balance::MAX; + // The asset's interior location for the paying account. This is PoToC's Treasury + // pallet instance. + pub PotocTreasuryInteriorLocation: InteriorLocation = + PalletInstance(::index() as u8).into(); +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub const ProposalBondForBenchmark: Permill = Permill::from_percent(5); +} + +/// [`PayOverXcm`] setup to pay PoToC's Treasury. +pub type PotocTreasuryPaymaster = PayOverXcm< + PotocTreasuryInteriorLocation, + crate::xcm_config::XcmRouter, + crate::PolkadotXcm, + ConstU32<{ 6 * HOURS }>, + VersionedLocation, + VersionedLocatableAsset, + LocatableAssetConverter, + VersionedLocationConverter, +>; + +pub type PotocTreasuryInstance = pallet_treasury::Instance3; + +impl pallet_treasury::Config for Runtime { + type WeightInfo = weights::pallet_treasury_fellowship_treasury::WeightInfo; + type RuntimeEvent = RuntimeEvent; + type PalletId = PotocTreasuryPalletId; + type Currency = Balances; + type RejectOrigin = EitherOfDiverse< + EnsureRoot, + EitherOfDiverse>, Fellows>, + >; + type SpendPeriod = ConstU32<{ 7 * DAYS }>; + type Burn = Burn; + type BurnDestination = (); + type SpendFunds = (); + type MaxApprovals = ConstU32<100>; + type SpendOrigin = EitherOf< + EitherOf< + EnsureRootWithSuccess, + MapSuccess< + EnsureXcm>, + Replace>, + >, + >, + MapSuccess>>, + >; + type AssetKind = VersionedLocatableAsset; + type Beneficiary = VersionedLocation; + type BeneficiaryLookup = IdentityLookup; + #[cfg(not(feature = "runtime-benchmarks"))] + type Paymaster = PotocTreasuryPaymaster; + #[cfg(feature = "runtime-benchmarks")] + type Paymaster = PayWithEnsure>>; + type BalanceConverter = AssetRateWithNative; + type PayoutPeriod = ConstU32<{ 30 * DAYS }>; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = polkadot_runtime_common::impls::benchmarks::TreasuryArguments< + sp_core::ConstU8<1>, + ConstU32<1000>, + >; +} diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/origins.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/origins.rs new file mode 100644 index 0000000000..30b6b1d096 --- /dev/null +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/origins.rs @@ -0,0 +1,66 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see . + +//! PoToC custom origins. + +use super::ranks; +pub use pallet_origins::*; + +#[frame_support::pallet] +pub mod pallet_origins { + use super::ranks; + use frame_support::pallet_prelude::*; + use pallet_ranked_collective::Rank; + + #[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 { + /// Plurality voice of the [ranks::MEMBER] members given via referendum. + Members, + } + + impl Origin { + /// Returns the rank that the origin `self` speaks for, or `None` if it doesn't speak for + /// any. + pub fn as_voice(&self) -> Option { + Some(match &self { + Origin::Members => ranks::MEMBER, + }) + } + } + + /// Ensures [`Origin::Members`] origin. + pub struct Members; + impl> + From> EnsureOrigin for Members { + type Success = (); + fn try_origin(o: O) -> Result { + o.into().map(|o| match o { + Origin::Members => (), + }) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin() -> Result { + Ok(O::from(Origin::Members)) + } + } +} diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs new file mode 100644 index 0000000000..afdcd1a95c --- /dev/null +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs @@ -0,0 +1,91 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see . + +//! Track configurations for PoToC. + +use super::origins::Origin; +use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, DOLLARS, HOURS, MINUTES}; +use pallet_ranked_collective::Rank; +use sp_runtime::{traits::Convert, Perbill}; + +/// Referendum `TrackId` type. +pub type TrackId = u16; + +/// Referendum track IDs. +pub mod constants { + use super::TrackId; + + /// The members track. + pub const MEMBERS: TrackId = 1; +} + +/// The type implementing the [`pallet_referenda::TracksInfo`] trait for referenda pallet. +pub struct TracksInfo; + +/// Information on the voting tracks. +impl pallet_referenda::TracksInfo for TracksInfo { + type Id = TrackId; + + type RuntimeOrigin = ::PalletsOrigin; + + /// Return the array of available tracks and their information. + fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] { + static DATA: [(TrackId, pallet_referenda::TrackInfo); 1] = [( + constants::MEMBERS, + pallet_referenda::TrackInfo { + name: "members", + max_deciding: 20, + decision_deposit: 5 * DOLLARS, + prepare_period: 24 * HOURS, + decision_period: 7 * DAYS, + confirm_period: 24 * HOURS, + min_enactment_period: HOURS, + min_approval: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(50), + ceil: Perbill::from_percent(100), + }, + min_support: pallet_referenda::Curve::LinearDecreasing { + length: Perbill::from_percent(100), + floor: Perbill::from_percent(0), + ceil: Perbill::from_percent(50), + }, + }, + )]; + &DATA[..] + } + + /// Determine the voting track for the given `origin`. + fn track_for(id: &Self::RuntimeOrigin) -> Result { + #[cfg(feature = "runtime-benchmarks")] + { + // For benchmarks, we enable a root origin. + // It is important that this is not available in production! + let root: Self::RuntimeOrigin = frame_system::RawOrigin::Root.into(); + if &root == id { + return Ok(constants::MEMBERS) + } + } + + match Origin::try_from(id.clone()) { + Ok(Origin::Members) => Ok(constants::MEMBERS), + _ => Err(()), + } + } +} + +// implements [`frame_support::traits::Get`] for [`TracksInfo`] +pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber); diff --git a/system-parachains/constants/src/polkadot.rs b/system-parachains/constants/src/polkadot.rs index d42ca84d82..fc2f057bdc 100644 --- a/system-parachains/constants/src/polkadot.rs +++ b/system-parachains/constants/src/polkadot.rs @@ -25,9 +25,6 @@ pub mod account { /// Referenda pallet ID. /// Used as a temporary place to deposit a slashed imbalance before teleporting to the Treasury. pub const REFERENDA_PALLET_ID: PalletId = PalletId(*b"py/refer"); - /// Ambassador Referenda pallet ID. - /// Used as a temporary place to deposit a slashed imbalance before teleporting to the Treasury. - pub const AMBASSADOR_REFERENDA_PALLET_ID: PalletId = PalletId(*b"py/amref"); /// Identity pallet ID. /// Used as a temporary place to deposit a slashed imbalance before teleporting to the Treasury. pub const IDENTITY_PALLET_ID: PalletId = PalletId(*b"py/ident"); @@ -35,6 +32,8 @@ pub mod account { pub const FELLOWSHIP_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/feltr"); /// Ambassador treasury pallet ID pub const AMBASSADOR_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/ambtr"); + /// Potoc treasury pallet ID + pub const POTOC_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/ptctr"); } /// Consensus-related. From 1ed29d442ca9554e6c85f8edd4bdbd3f8db4ce10 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 10 Oct 2024 13:52:20 +0100 Subject: [PATCH 2/5] Cleanup Signed-off-by: Oliver Tale-Yazdi --- .../src/ambassador/mod.rs | 10 ++--- .../collectives-polkadot/src/lib.rs | 2 +- .../collectives-polkadot/src/potoc/mod.rs | 45 +++++++------------ .../collectives-polkadot/src/potoc/tracks.rs | 19 ++++---- 4 files changed, 33 insertions(+), 43 deletions(-) diff --git a/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs b/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs index 034206c542..a39196acb3 100644 --- a/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs +++ b/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs @@ -18,14 +18,14 @@ //! The module defines the following on-chain functionality of the Ambassador Program: //! //! - Managed set of program members, where every member has a [rank](ranks) -//! (via [AmbassadorCollective](pallet_ranked_collective)). +//! (via [AmbassadorCollective](pallet_ranked_collective)). //! - Referendum functionality for the program members to propose, vote on, and execute -//! proposals on behalf of the members of a certain [rank](Origin) -//! (via [AmbassadorReferenda](pallet_referenda)). +//! proposals on behalf of the members of a certain [rank](Origin) +//! (via [AmbassadorReferenda](pallet_referenda)). //! - Promotion and demotion periods, register of members' activity, and rank based salaries -//! (via [AmbassadorCore](pallet_core_fellowship)). +//! (via [AmbassadorCore](pallet_core_fellowship)). //! - Members' salaries (via [AmbassadorSalary](pallet_salary), requiring a member to be -//! imported or inducted into [AmbassadorCore](pallet_core_fellowship)). +//! imported or inducted into [AmbassadorCore](pallet_core_fellowship)). //! - Ambassador Program Sub-Treasury (via [AmbassadorTreasury](pallet_treasury)). pub mod migrations; diff --git a/system-parachains/collectives/collectives-polkadot/src/lib.rs b/system-parachains/collectives/collectives-polkadot/src/lib.rs index 40c6474a77..30a33087d5 100644 --- a/system-parachains/collectives/collectives-polkadot/src/lib.rs +++ b/system-parachains/collectives/collectives-polkadot/src/lib.rs @@ -1136,7 +1136,7 @@ impl_runtime_apis! { Asset { fun: Fungible(ExistentialDeposit::get()), id: AssetId(Parent.into()) - }.into(), + }, Parent.into(), )) } diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs index a7c6bf9110..40dece9b52 100644 --- a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs @@ -23,16 +23,17 @@ use frame_support::traits::NeverEnsureOrigin; use crate::{ impls::ToParentTreasury, weights, - xcm_config::{AssetHubUsdt, FellowshipAdminBodyId, LocationToAccountId, TreasurerBodyId}, + xcm_config::{AssetHubUsdt, LocationToAccountId, TreasurerBodyId}, AccountId, AssetRateWithNative, Balance, Balances, GovernanceLocation, PolkadotTreasuryAccount, - PotocReferenda, Preimage, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, Scheduler, DAYS, + PotocReferenda, Preimage, Runtime, RuntimeCall, RuntimeEvent, Scheduler, DAYS, POTOC_TREASURY_PALLET_ID, *, }; -use frame_support::traits::TryMapSuccess; +// There is only one admin for all collectives: +use crate::xcm_config::FellowshipAdminBodyId as PotocAdminBodyId; use frame_support::{ parameter_types, traits::{ - EitherOf, EitherOfDiverse, MapSuccess, OriginTrait, PalletInfoAccess, TryWithMorphedArg, + EitherOf, EitherOfDiverse, MapSuccess, PalletInfoAccess, }, PalletId, }; @@ -40,23 +41,22 @@ use frame_system::{EnsureRoot, EnsureRootWithSuccess}; pub use origins::{ pallet_origins as pallet_potoc_origins, Members, }; -use pallet_ranked_collective::EnsureOfRank; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use polkadot_runtime_common::impls::{ LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, }; -use polkadot_runtime_constants::{currency::GRAND, time::HOURS, xcm::body::FELLOWSHIP_ADMIN_INDEX}; +use polkadot_runtime_constants::{currency::GRAND, time::HOURS}; use sp_arithmetic::Permill; use sp_core::{ConstU128, ConstU32}; use sp_runtime::traits::{ - ConstU16, ConvertToValue, IdentityLookup, Replace, ReplaceWithDefault, TakeFirst, + ConstU16, ConvertToValue, IdentityLookup, Replace, ReplaceWithDefault, }; use xcm_builder::{AliasesIntoAccountId32, PayOverXcm}; #[cfg(feature = "runtime-benchmarks")] use crate::impls::benchmarks::{OpenHrmpChannel, PayWithEnsure}; -/// PoToC's members ranks. +/// PoToC's ranks. pub mod ranks { use pallet_ranked_collective::Rank; @@ -66,31 +66,24 @@ pub mod ranks { pub const MEMBER: Rank = 1; } -/// Root, FellowshipAdmin or Members. +/// Origin of either Member vote, OpenGov or Root. pub type OpenGovOrMembers = EitherOfDiverse< - EnsureRoot, - EitherOfDiverse>, Members>, + Members, + EitherOfDiverse< + EnsureXcm>, + EnsureRoot, + >, >; /// Promote origin, either: /// - Root /// - PoToC's Admin origin (i.e. token holder referendum) /// - Members vote -pub type PromoteOrigin = EitherOf< - EnsureRootWithSuccess>, - EitherOf< - MapSuccess< - EnsureXcm>, - Replace>, - >, - TryMapSuccess>>, - >, ->; +pub type PromoteOrigin = MapSuccess>>; impl pallet_potoc_origins::Config for Runtime {} pub type PotocReferendaInstance = pallet_referenda::Instance3; - impl pallet_referenda::Config for Runtime { type WeightInfo = weights::pallet_referenda_fellowship_referenda::WeightInfo; type RuntimeCall = RuntimeCall; @@ -114,14 +107,13 @@ impl pallet_referenda::Config for Runtime { } pub type PotocCollectiveInstance = pallet_ranked_collective::Instance3; - impl pallet_ranked_collective::Config for Runtime { type WeightInfo = weights::pallet_ranked_collective_fellowship_collective::WeightInfo; type RuntimeEvent = RuntimeEvent; // Promotions and the induction of new members are serviced by `PotocCore` pallet instance. #[cfg(not(feature = "runtime-benchmarks"))] - type PromoteOrigin = frame_system::EnsureNever; + type PromoteOrigin = frame_system::EnsureNever; // The maximum value of `u16` set as a success value for the root to ensure the benchmarks will // pass. #[cfg(feature = "runtime-benchmarks")] @@ -130,13 +122,10 @@ impl pallet_ranked_collective::Config for Runtime { // Demotion is by any of: // - Root can demote arbitrarily. // - PoToC's Admin origin (i.e. token holder referendum); - // - // The maximum value of `u16` set as a success value for the root to ensure the benchmarks will - // pass. type DemoteOrigin = EitherOf< EnsureRootWithSuccess>, MapSuccess< - EnsureXcm>, + EnsureXcm>, Replace>, >, >; diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs index afdcd1a95c..ace3dd10bc 100644 --- a/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs @@ -17,9 +17,10 @@ //! Track configurations for PoToC. use super::origins::Origin; -use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, DOLLARS, HOURS, MINUTES}; -use pallet_ranked_collective::Rank; -use sp_runtime::{traits::Convert, Perbill}; +use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, DOLLARS, HOURS}; +use sp_runtime::Perbill; +use pallet_referenda::TrackInfo; +use pallet_referenda::Curve::LinearDecreasing; /// Referendum `TrackId` type. pub type TrackId = u16; @@ -42,23 +43,23 @@ impl pallet_referenda::TracksInfo for TracksInfo { type RuntimeOrigin = ::PalletsOrigin; /// Return the array of available tracks and their information. - fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo)] { - static DATA: [(TrackId, pallet_referenda::TrackInfo); 1] = [( + fn tracks() -> &'static [(Self::Id, TrackInfo)] { + static DATA: [(TrackId, TrackInfo); 1] = [( constants::MEMBERS, - pallet_referenda::TrackInfo { + TrackInfo { name: "members", - max_deciding: 20, + max_deciding: 10, decision_deposit: 5 * DOLLARS, prepare_period: 24 * HOURS, decision_period: 7 * DAYS, confirm_period: 24 * HOURS, min_enactment_period: HOURS, - min_approval: pallet_referenda::Curve::LinearDecreasing { + min_approval: LinearDecreasing { length: Perbill::from_percent(100), floor: Perbill::from_percent(50), ceil: Perbill::from_percent(100), }, - min_support: pallet_referenda::Curve::LinearDecreasing { + min_support: LinearDecreasing { length: Perbill::from_percent(100), floor: Perbill::from_percent(0), ceil: Perbill::from_percent(50), From 017b53f28264c369622e2ef1231a00a3d93cc526 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 10 Oct 2024 18:56:48 +0100 Subject: [PATCH 3/5] Fixes Signed-off-by: Oliver Tale-Yazdi --- .../collectives-polkadot/Cargo.toml | 1 + .../collectives-polkadot/src/potoc/mod.rs | 2 +- .../collectives-polkadot/src/potoc/tracks.rs | 23 +++++++++++++++---- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/system-parachains/collectives/collectives-polkadot/Cargo.toml b/system-parachains/collectives/collectives-polkadot/Cargo.toml index 6c7eec3d7d..dd2cd7425a 100644 --- a/system-parachains/collectives/collectives-polkadot/Cargo.toml +++ b/system-parachains/collectives/collectives-polkadot/Cargo.toml @@ -94,6 +94,7 @@ substrate-wasm-builder = { optional = true, workspace = true } [features] default = ["std"] +fast-runtime = [] runtime-benchmarks = [ "cumulus-pallet-parachain-system/runtime-benchmarks", "cumulus-pallet-session-benchmarking/runtime-benchmarks", diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs index 40dece9b52..b66c52b233 100644 --- a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs @@ -113,7 +113,7 @@ impl pallet_ranked_collective::Config for Runtime { // Promotions and the induction of new members are serviced by `PotocCore` pallet instance. #[cfg(not(feature = "runtime-benchmarks"))] - type PromoteOrigin = frame_system::EnsureNever; + type PromoteOrigin = frame_system::EnsureNever; // The maximum value of `u16` set as a success value for the root to ensure the benchmarks will // pass. #[cfg(feature = "runtime-benchmarks")] diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs index ace3dd10bc..8570dff7b5 100644 --- a/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs @@ -17,10 +17,11 @@ //! Track configurations for PoToC. use super::origins::Origin; -use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, DOLLARS, HOURS}; +use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, DOLLARS, HOURS, MINUTES}; use sp_runtime::Perbill; use pallet_referenda::TrackInfo; use pallet_referenda::Curve::LinearDecreasing; +use polkadot_runtime_common::prod_or_fast; /// Referendum `TrackId` type. pub type TrackId = u16; @@ -50,10 +51,22 @@ impl pallet_referenda::TracksInfo for TracksInfo { name: "members", max_deciding: 10, decision_deposit: 5 * DOLLARS, - prepare_period: 24 * HOURS, - decision_period: 7 * DAYS, - confirm_period: 24 * HOURS, - min_enactment_period: HOURS, + prepare_period: prod_or_fast!( + 24 * HOURS, + 1 * MINUTES + ), + decision_period: prod_or_fast!( + 7 * DAYS, + 5 * MINUTES + ), + confirm_period: prod_or_fast!( + 24 * HOURS, + 1 * MINUTES + ), + min_enactment_period: prod_or_fast!( + HOURS, + 1 * MINUTES + ), min_approval: LinearDecreasing { length: Perbill::from_percent(100), floor: Perbill::from_percent(50), From 27f353f98f09ef75297e604dffa01da2cc552882 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 10 Oct 2024 18:57:15 +0100 Subject: [PATCH 4/5] fmt Signed-off-by: Oliver Tale-Yazdi --- .../src/ambassador/mod.rs | 18 ++++++------- .../collectives-polkadot/src/lib.rs | 2 +- .../collectives-polkadot/src/potoc/mod.rs | 17 ++++--------- .../collectives-polkadot/src/potoc/tracks.rs | 25 +++++-------------- 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs b/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs index a39196acb3..6096c2ef27 100644 --- a/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs +++ b/system-parachains/collectives/collectives-polkadot/src/ambassador/mod.rs @@ -17,15 +17,15 @@ //! //! The module defines the following on-chain functionality of the Ambassador Program: //! -//! - Managed set of program members, where every member has a [rank](ranks) -//! (via [AmbassadorCollective](pallet_ranked_collective)). -//! - Referendum functionality for the program members to propose, vote on, and execute -//! proposals on behalf of the members of a certain [rank](Origin) -//! (via [AmbassadorReferenda](pallet_referenda)). -//! - Promotion and demotion periods, register of members' activity, and rank based salaries -//! (via [AmbassadorCore](pallet_core_fellowship)). -//! - Members' salaries (via [AmbassadorSalary](pallet_salary), requiring a member to be -//! imported or inducted into [AmbassadorCore](pallet_core_fellowship)). +//! - Managed set of program members, where every member has a [rank](ranks) (via +//! [AmbassadorCollective](pallet_ranked_collective)). +//! - Referendum functionality for the program members to propose, vote on, and execute proposals on +//! behalf of the members of a certain [rank](Origin) (via +//! [AmbassadorReferenda](pallet_referenda)). +//! - Promotion and demotion periods, register of members' activity, and rank based salaries (via +//! [AmbassadorCore](pallet_core_fellowship)). +//! - Members' salaries (via [AmbassadorSalary](pallet_salary), requiring a member to be imported or +//! inducted into [AmbassadorCore](pallet_core_fellowship)). //! - Ambassador Program Sub-Treasury (via [AmbassadorTreasury](pallet_treasury)). pub mod migrations; diff --git a/system-parachains/collectives/collectives-polkadot/src/lib.rs b/system-parachains/collectives/collectives-polkadot/src/lib.rs index 30a33087d5..c918447aac 100644 --- a/system-parachains/collectives/collectives-polkadot/src/lib.rs +++ b/system-parachains/collectives/collectives-polkadot/src/lib.rs @@ -50,11 +50,11 @@ pub use ambassador::pallet_ambassador_origins; use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use fellowship::{pallet_fellowship_origins, Fellows}; -use potoc::pallet_potoc_origins; use impls::{AllianceProposalProvider, EqualOrGreatestRootCmp, ToParentTreasury}; use polkadot_runtime_common::impls::{ ContainsParts as ContainsLocationParts, VersionedLocatableAsset, }; +use potoc::pallet_potoc_origins; use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; use sp_runtime::{ diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs index b66c52b233..b4200e6902 100644 --- a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs @@ -19,7 +19,6 @@ mod origins; mod tracks; -use frame_support::traits::NeverEnsureOrigin; use crate::{ impls::ToParentTreasury, weights, @@ -28,19 +27,16 @@ use crate::{ PotocReferenda, Preimage, Runtime, RuntimeCall, RuntimeEvent, Scheduler, DAYS, POTOC_TREASURY_PALLET_ID, *, }; +use frame_support::traits::NeverEnsureOrigin; // There is only one admin for all collectives: use crate::xcm_config::FellowshipAdminBodyId as PotocAdminBodyId; use frame_support::{ parameter_types, - traits::{ - EitherOf, EitherOfDiverse, MapSuccess, PalletInfoAccess, - }, + traits::{EitherOf, EitherOfDiverse, MapSuccess, PalletInfoAccess}, PalletId, }; use frame_system::{EnsureRoot, EnsureRootWithSuccess}; -pub use origins::{ - pallet_origins as pallet_potoc_origins, Members, -}; +pub use origins::{pallet_origins as pallet_potoc_origins, Members}; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use polkadot_runtime_common::impls::{ LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, @@ -48,9 +44,7 @@ use polkadot_runtime_common::impls::{ use polkadot_runtime_constants::{currency::GRAND, time::HOURS}; use sp_arithmetic::Permill; use sp_core::{ConstU128, ConstU32}; -use sp_runtime::traits::{ - ConstU16, ConvertToValue, IdentityLookup, Replace, ReplaceWithDefault, -}; +use sp_runtime::traits::{ConstU16, ConvertToValue, IdentityLookup, Replace, ReplaceWithDefault}; use xcm_builder::{AliasesIntoAccountId32, PayOverXcm}; #[cfg(feature = "runtime-benchmarks")] @@ -132,8 +126,7 @@ impl pallet_ranked_collective::Config for Runtime { // Exchange is by any of: // - Root can exchange arbitrarily. // - the Members origin - type ExchangeOrigin = - EitherOf, Members>; + type ExchangeOrigin = EitherOf, Members>; type AddOrigin = MapSuccess>; type RemoveOrigin = Self::DemoteOrigin; type Polls = PotocReferenda; diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs index 8570dff7b5..dfbfd29ebd 100644 --- a/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/tracks.rs @@ -18,10 +18,9 @@ use super::origins::Origin; use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, DOLLARS, HOURS, MINUTES}; -use sp_runtime::Perbill; -use pallet_referenda::TrackInfo; -use pallet_referenda::Curve::LinearDecreasing; +use pallet_referenda::{Curve::LinearDecreasing, TrackInfo}; use polkadot_runtime_common::prod_or_fast; +use sp_runtime::Perbill; /// Referendum `TrackId` type. pub type TrackId = u16; @@ -51,22 +50,10 @@ impl pallet_referenda::TracksInfo for TracksInfo { name: "members", max_deciding: 10, decision_deposit: 5 * DOLLARS, - prepare_period: prod_or_fast!( - 24 * HOURS, - 1 * MINUTES - ), - decision_period: prod_or_fast!( - 7 * DAYS, - 5 * MINUTES - ), - confirm_period: prod_or_fast!( - 24 * HOURS, - 1 * MINUTES - ), - min_enactment_period: prod_or_fast!( - HOURS, - 1 * MINUTES - ), + prepare_period: prod_or_fast!(24 * HOURS, 1 * MINUTES), + decision_period: prod_or_fast!(7 * DAYS, 5 * MINUTES), + confirm_period: prod_or_fast!(24 * HOURS, 1 * MINUTES), + min_enactment_period: prod_or_fast!(HOURS, 1 * MINUTES), min_approval: LinearDecreasing { length: Perbill::from_percent(100), floor: Perbill::from_percent(50), From ccbab14f9c8c8ed907974b9853228222b9ae90ff Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 10 Oct 2024 19:20:47 +0100 Subject: [PATCH 5/5] add seed migration Signed-off-by: Oliver Tale-Yazdi --- .../collectives-polkadot/src/lib.rs | 1 + .../collectives-polkadot/src/potoc/mod.rs | 54 +++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/system-parachains/collectives/collectives-polkadot/src/lib.rs b/system-parachains/collectives/collectives-polkadot/src/lib.rs index c918447aac..5ba93e5b00 100644 --- a/system-parachains/collectives/collectives-polkadot/src/lib.rs +++ b/system-parachains/collectives/collectives-polkadot/src/lib.rs @@ -782,6 +782,7 @@ type Migrations = ( pallet_core_fellowship::migration::MigrateV0ToV1, pallet_core_fellowship::migration::MigrateV0ToV1, ambassador::migrations::TruncateHeadAmbassadors, + potoc::InsertSeedMembers, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, ); diff --git a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs index b4200e6902..d722ac9252 100644 --- a/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs +++ b/system-parachains/collectives/collectives-polkadot/src/potoc/mod.rs @@ -27,23 +27,26 @@ use crate::{ PotocReferenda, Preimage, Runtime, RuntimeCall, RuntimeEvent, Scheduler, DAYS, POTOC_TREASURY_PALLET_ID, *, }; -use frame_support::traits::NeverEnsureOrigin; // There is only one admin for all collectives: use crate::xcm_config::FellowshipAdminBodyId as PotocAdminBodyId; use frame_support::{ parameter_types, - traits::{EitherOf, EitherOfDiverse, MapSuccess, PalletInfoAccess}, + traits::{ + DefensiveResult, EitherOf, EitherOfDiverse, MapSuccess, NeverEnsureOrigin, + OnRuntimeUpgrade, PalletInfoAccess, RankedMembers, + }, PalletId, }; use frame_system::{EnsureRoot, EnsureRootWithSuccess}; pub use origins::{pallet_origins as pallet_potoc_origins, Members}; +use pallet_ranked_collective::WeightInfo; use pallet_xcm::{EnsureXcm, IsVoiceOfBody}; use polkadot_runtime_common::impls::{ LocatableAssetConverter, VersionedLocatableAsset, VersionedLocationConverter, }; use polkadot_runtime_constants::{currency::GRAND, time::HOURS}; use sp_arithmetic::Permill; -use sp_core::{ConstU128, ConstU32}; +use sp_core::{crypto::Ss58Codec, ConstU128, ConstU32}; use sp_runtime::traits::{ConstU16, ConvertToValue, IdentityLookup, Replace, ReplaceWithDefault}; use xcm_builder::{AliasesIntoAccountId32, PayOverXcm}; @@ -273,3 +276,48 @@ impl pallet_treasury::Config for Runtime { ConstU32<1000>, >; } + +pub struct InsertSeedMembers; +impl OnRuntimeUpgrade for InsertSeedMembers { + fn on_runtime_upgrade() -> Weight { + let mut weight = Weight::default(); + + let seed_member = vec![ + "151S1YrZd4zfUYCeWhNERkGdmom8kdqAtRqtHwh9HYMTfFYJ", + "14DsLzVyTUTDMm2eP3czwPbH53KgqnQRp3CJJZS9GR7yxGDP", + "16JskuojL6mSp6HNcjiHYa9jqksWbLD8L9YGWU1ppiPWQ9sa", + "15oLanodWWweiZJSoDTEBtrX7oGfq6e8ct5y5E6fVRDPhUgj", + "14iKbZws1fjJ6TH27yoRq6KeeVNof83VmxUBN2W2udQVBe5o", + "12TNvHiRkwzYqT5UZ86cfUvBeZBjLLYUzHLa4Hix99oTrgqT", + "12W3ea6jWKhzSWSCMjUKqtDwasRACeYFGkyvVb9Y9b5dGm2v", + "15roJ4ZrgrZam5BQWJgiGHpgp7ShFQBRNLq6qUfiNqXDZjMK", + "15DCWHQknBjc5YPFoVj8Pn2KoqrqYywJJ95BYNYJ4Fj3NLqz", + "15DCZocYEM2ThYCAj22QE4QENRvUNVrDtoLBVbCm5x4EQncr", + "16a357f5Sxab3V2ne4emGQvqJaCLeYpTMx3TCjnQhmJQ71DX", + "13ogXJ1tpHZoaav2iQQRDH5eHcvpAEfwB1UFY6dijDBmDcic", + "16JGzEsi8gcySKjpmxHVrkLTHdFHodRepEz8n244gNZpr9J", + ]; + + for address in seed_member.iter() { + let Ok(member) = AccountId::from_ss58check(address) else { + frame_support::defensive!("Invalid seed member: {member}"); + continue; + }; + + as RankedMembers>::induct( + &member, + ).defensive_ok(); + as RankedMembers>::promote( + &member, + ).defensive_ok(); + + log::info!("PoToC Seed member inserted: {address}"); + + // TODO use potoc weight + weight.saturating_accrue(weights::pallet_ranked_collective_fellowship_collective::WeightInfo::::add_member()); + weight.saturating_accrue(weights::pallet_ranked_collective_fellowship_collective::WeightInfo::::promote_member(1)); + } + + weight + } +}