Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Runtime: Polkadot Fellowship promotion/demotion periods, members activity and salaries #2607

Merged
merged 32 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
13bb75e
core fellowship
muharem May 19, 2023
de643ea
core fellowship weights
muharem May 19, 2023
16b0815
salary
muharem May 20, 2023
102fdcf
Merge remote-tracking branch 'origin/master' into muharem-core-fellow…
muharem May 20, 2023
c4a7425
weights
muharem May 20, 2023
ffbb342
fellowship pot
muharem May 20, 2023
ad45934
registration period 15 days
muharem May 22, 2023
bc05ae6
use treasury account for salary pay, promotion origin
muharem May 25, 2023
e3d744a
decision period for tracks 30 days
muharem May 25, 2023
2c556af
docs
muharem May 25, 2023
fa1d47f
comment
muharem May 25, 2023
9787bc1
Merge remote-tracking branch 'origin/master' into muharem-core-fellow…
gavofyork May 29, 2023
5092d3c
Couple of fixes and some refactoring
gavofyork Jun 1, 2023
c7f3292
Alter curves to be a bit more conservative
gavofyork Jun 1, 2023
7c245b3
Use `PayOverXcm` for fellowship salary payments
gavofyork Jun 1, 2023
320b12c
Merge remote-tracking branch 'origin/master' into muharem-core-fellow…
gavofyork Jun 1, 2023
842bc9d
Docs and remove unneeded code
gavofyork Jun 1, 2023
f3ede4c
Fixes
gavofyork Jun 1, 2023
be0a235
Move Fellowship stuff in line with whitepaper
gavofyork Jun 2, 2023
3b58f19
fix: induction by a single Fellow (not proficient)
muharem Jun 2, 2023
2a882f9
doc fix
muharem Jun 2, 2023
9cc708b
renames, pallet index, allow unpaid for salary pallet
muharem Jun 4, 2023
b37bbe4
Merge remote-tracking branch 'origin/master' into muharem-core-fellow…
gavofyork Jun 5, 2023
44ffd21
Fix budget units
gavofyork Jun 5, 2023
f53b4a4
Fixes
gavofyork Jun 5, 2023
d83fd85
Merge remote-tracking branch 'origin/master' into muharem-core-fellow…
gavofyork Jun 5, 2023
459977b
Test sovereign account for Fellowship salaries
gavofyork Jun 5, 2023
1c9b566
Nice address test
gavofyork Jun 5, 2023
7b9cf0f
Fixes
gavofyork Jun 5, 2023
caaa989
test for PayOverXcm setup
muharem Jun 5, 2023
af2d1f2
Merge remote-tracking branch 'origin/master' into muharem-core-fellow…
muharem Jun 5, 2023
cf929c3
Update parachains/runtimes/collectives/collectives-polkadot/src/fello…
gavofyork Jun 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
718 changes: 410 additions & 308 deletions Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/parityt
pallet-utility = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-referenda = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-ranked-collective = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-core-fellowship = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-salary = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-arithmetic = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" }
sp-block-builder = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
Expand Down Expand Up @@ -103,6 +105,8 @@ runtime-benchmarks = [
"pallet-preimage/runtime-benchmarks",
"pallet-referenda/runtime-benchmarks",
"pallet-ranked-collective/runtime-benchmarks",
"pallet-core-fellowship/runtime-benchmarks",
"pallet-salary/runtime-benchmarks",
]
try-runtime = [
"cumulus-pallet-aura-ext/try-runtime",
Expand Down Expand Up @@ -131,6 +135,8 @@ try-runtime = [
"pallet-preimage/try-runtime",
"pallet-referenda/try-runtime",
"pallet-ranked-collective/try-runtime",
"pallet-core-fellowship/try-runtime",
"pallet-salary/try-runtime",
]
std = [
"codec/std",
Expand Down Expand Up @@ -187,4 +193,6 @@ std = [
"pallet-referenda/std",
"pallet-ranked-collective/std",
"substrate-wasm-builder",
"pallet-core-fellowship/std",
"pallet-salary/std",
]
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
pub mod account {
use frame_support::PalletId;

/// Relay Chain treasury pallet id, used to convert into AccountId
pub const RELAY_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/trsry");
/// Polkadot treasury pallet id, used to convert into AccountId
pub const POLKADOT_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/trsry");
/// Alliance pallet ID.
/// It is used as a temporarily place to deposit a slashed imbalance
/// before the teleport to the Treasury.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,33 @@
pub(crate) mod migration;
mod origins;
mod tracks;
use cumulus_primitives_core::Junction::GeneralIndex;
use frame_system::EnsureNever;
pub use origins::{
pallet_origins as pallet_fellowship_origins, Fellows, FellowshipCandidates, FellowshipExperts,
FellowshipMasters,
pallet_origins as pallet_fellowship_origins, Architects, Candidates, Fellows, Masters, Members,
};
use xcm_builder::{LocatableAssetId, PayOverXcm};

use self::origins::EnsureFellowship;
use crate::{
constants, impls::ToParentTreasury, weights, AccountId, Balance, Balances, BlockNumber,
FellowshipReferenda, GovernanceLocation, Preimage, RelayTreasuryAccount, Runtime, RuntimeCall,
RuntimeEvent, Scheduler, DAYS,
constants, impls::ToParentTreasury, weights, AccountId, Balance, Balances, FellowshipReferenda,
GovernanceLocation, PolkadotTreasuryAccount, Preimage, Runtime, RuntimeCall, RuntimeEvent,
Scheduler, DAYS,
};
use frame_support::{
parameter_types,
traits::{EitherOf, MapSuccess, TryMapSuccess},
traits::{EitherOf, EitherOfDiverse, MapSuccess, TryMapSuccess},
};
use pallet_xcm::{EnsureXcm, IsVoiceOfBody};
use polkadot_runtime_constants::xcm::body::FELLOWSHIP_ADMIN_INDEX;
use polkadot_runtime_constants::{currency::UNITS, time::HOURS, xcm::body::FELLOWSHIP_ADMIN_INDEX};
use sp_arithmetic::traits::CheckedSub;
use sp_core::ConstU32;
use sp_core::{ConstU128, ConstU32};
use sp_runtime::{
morph_types,
traits::{AccountIdConversion, ConstU16, Replace, TypedGet},
traits::{AccountIdConversion, ConstU16, ConvertToValue, Replace, TryMorph, TypedGet},
};
use xcm::latest::BodyId;

use self::origins::EnsureFellowship;

/// The Fellowship members' ranks.
pub mod ranks {
use pallet_ranked_collective::Rank;
Expand All @@ -62,9 +63,6 @@ pub mod ranks {
}

parameter_types! {
pub const AlarmInterval: BlockNumber = 1;
pub const SubmissionDeposit: Balance = 0;
pub const UndecidingTimeout: BlockNumber = 7 * DAYS;
// Referenda pallet account, used to temporarily deposit slashed imbalance before teleporting.
pub ReferendaPalletAccount: AccountId = constants::account::REFERENDA_PALLET_ID.into_account_truncating();
pub const FellowshipAdminBodyId: BodyId = BodyId::Index(FELLOWSHIP_ADMIN_INDEX);
Expand All @@ -80,63 +78,173 @@ impl pallet_referenda::Config<FellowshipReferendaInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type Scheduler = Scheduler;
type Currency = Balances;
// Fellows can submit proposals.
type SubmitOrigin =
pallet_ranked_collective::EnsureMember<Runtime, FellowshipCollectiveInstance, 1>;
type CancelOrigin = FellowshipExperts;
type KillOrigin = FellowshipMasters;
type Slash = ToParentTreasury<RelayTreasuryAccount, ReferendaPalletAccount, Runtime>;
pallet_ranked_collective::EnsureMember<Runtime, FellowshipCollectiveInstance, 3>;
type CancelOrigin = Architects;
type KillOrigin = Masters;
type Slash = ToParentTreasury<PolkadotTreasuryAccount, ReferendaPalletAccount, Runtime>;
type Votes = pallet_ranked_collective::Votes;
type Tally = pallet_ranked_collective::TallyOf<Runtime, FellowshipCollectiveInstance>;
type SubmissionDeposit = SubmissionDeposit;
type SubmissionDeposit = ConstU128<0>;
type MaxQueued = ConstU32<100>;
type UndecidingTimeout = UndecidingTimeout;
type AlarmInterval = AlarmInterval;
type UndecidingTimeout = ConstU32<{ 7 * DAYS }>;
type AlarmInterval = ConstU32<1>;
type Tracks = tracks::TracksInfo;
type Preimages = Preimage;
}

pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1;

// TODO: Use versions in `sp_runtime`.
morph_types! {
/// A `TryMorph` implementation to reduce a scalar by a particular amount, checking for
/// underflow.
pub type CheckedReduceBy<N: TypedGet>: TryMorph = |r: N::Type| -> Result<N::Type, ()> {
r.checked_sub(&N::get()).ok_or(())
} where N::Type: CheckedSub;

/// A `TryMorph` implementation to enforce an upper limit for a result of the outer morphed type.
pub type MorphWithUpperLimit<L: TypedGet, M>: TryMorph = |r: L::Type| -> Result<L::Type, ()> {
M::try_morph(r).map(|m| m.min(L::get()))
} where L::Type: Ord, M: TryMorph<L::Type, Outcome = L::Type>;
}

impl pallet_ranked_collective::Config<FellowshipCollectiveInstance> for Runtime {
type WeightInfo = weights::pallet_ranked_collective::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;
// Promotion is by any of:
// - Root can promote arbitrarily.
// - the FellowshipAdmin origin (i.e. token holder referendum);
// - a vote by the rank *above* the new rank.
type PromoteOrigin = EitherOf<
frame_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
EitherOf<
MapSuccess<
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
Replace<ConstU16<9>>,
>,
TryMapSuccess<EnsureFellowship, CheckedReduceBy<ConstU16<1>>>,
>,
>;
// Promotions and the induction of new members are serviced by `FellowshipCore` pallet instance.
type PromoteOrigin = EnsureNever<pallet_ranked_collective::Rank>;
// Demotion is by any of:
// - Root can demote arbitrarily.
// - the FellowshipAdmin origin (i.e. token holder referendum);
// - a vote by the rank two above the current rank.
type DemoteOrigin = EitherOf<
frame_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
EitherOf<
MapSuccess<
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
Replace<ConstU16<9>>,
>,
TryMapSuccess<EnsureFellowship, CheckedReduceBy<ConstU16<2>>>,
frame_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<{ ranks::DAN_9 }>>,
MapSuccess<
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
Replace<ConstU16<{ ranks::DAN_9 }>>,
>,
>;
type Polls = FellowshipReferenda;
type MinRankOfClass = sp_runtime::traits::Identity;
type VoteWeight = pallet_ranked_collective::Geometric;
}

pub type FellowshipCoreInstance = pallet_core_fellowship::Instance1;
ggwpez marked this conversation as resolved.
Show resolved Hide resolved

impl pallet_core_fellowship::Config<FellowshipCoreInstance> for Runtime {
type WeightInfo = weights::pallet_core_fellowship::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;
type Members = pallet_ranked_collective::Pallet<Runtime, FellowshipCollectiveInstance>;
type Balance = Balance;
// Parameters are set by any of:
// - Root;
// - the FellowshipAdmin origin (i.e. token holder referendum);
// - a vote among all Fellows.
type ParamsOrigin = EitherOfDiverse<
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
Fellows,
>;
// Induction (creating a candidate) is by any of:
// - Root;
// - the FellowshipAdmin origin (i.e. token holder referendum);
// - a single Fellow;
// - a vote among all Members.
type InductOrigin = EitherOfDiverse<
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
EitherOfDiverse<
pallet_ranked_collective::EnsureMember<Runtime, FellowshipCollectiveInstance, 2>,
muharem marked this conversation as resolved.
Show resolved Hide resolved
Members,
>,
>;
// Approval (rank-retention) of a Member's current rank is by any of:
// - Root;
// - the FellowshipAdmin origin (i.e. token holder referendum);
// - a vote by the rank one above the current rank.
type ApproveOrigin = EitherOf<
MapSuccess<
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
Replace<ConstU16<{ ranks::DAN_9 }>>,
>,
TryMapSuccess<EnsureFellowship, CheckedReduceBy<ConstU16<1>>>,
>;
// Promotion is by any of:
// - Root can promote arbitrarily.
// - the FellowshipAdmin origin (i.e. token holder referendum);
// - a vote by the rank two above the new rank for all promotions up to the Master rank.
type PromoteOrigin = EitherOf<
MapSuccess<
EnsureXcm<IsVoiceOfBody<GovernanceLocation, FellowshipAdminBodyId>>,
Replace<ConstU16<{ ranks::DAN_9 }>>,
>,
TryMapSuccess<
EnsureFellowship,
MorphWithUpperLimit<ConstU16<{ ranks::DAN_6 }>, CheckedReduceBy<ConstU16<2>>>,
>,
>;
type EvidenceSize = ConstU32<65536>;
}

pub type FellowshipSalaryInstance = pallet_salary::Instance1;

use xcm::prelude::*;

parameter_types! {
pub Statemint: MultiLocation = (Parent, Parachain(1000)).into();
pub StatemintUsdtId: AssetId = GeneralIndex(1984).into();
muharem marked this conversation as resolved.
Show resolved Hide resolved
pub UsdtAsset: LocatableAssetId = LocatableAssetId {
location: Statemint::get(),
asset_id: StatemintUsdtId::get(),
};
// The interior location on Statemint for the paying account. This is the Fellowship Salary
// pallet instance (which sits at index 64). This sovereign account will need funding.
pub Interior: InteriorMultiLocation = PalletInstance(64).into();
}

gavofyork marked this conversation as resolved.
Show resolved Hide resolved
// TODO: Move into location_conversion.rs
/// Conversion implementation which converts from a `[u8; 32]`-based `AccountId` into a
/// `MultiLocation` consisting solely of a `AccountId32` junction with a fixed value for its
/// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`.
pub struct AliasesIntoAccountId32<Network, AccountId>(
sp_std::marker::PhantomData<(Network, AccountId)>,
);
impl<
'a,
Network: sp_runtime::traits::Get<Option<NetworkId>>,
AccountId: Clone + Into<[u8; 32]> + Clone,
> sp_runtime::traits::Convert<&'a AccountId, MultiLocation>
for AliasesIntoAccountId32<Network, AccountId>
{
fn convert(who: &AccountId) -> MultiLocation {
AccountId32 { network: Network::get(), id: who.clone().into() }.into()
}
}

impl pallet_salary::Config<FellowshipSalaryInstance> for Runtime {
type WeightInfo = weights::pallet_salary::WeightInfo<Runtime>;
type RuntimeEvent = RuntimeEvent;
type Paymaster = PayOverXcm<
Interior,
crate::xcm_config::XcmRouter,
crate::PolkadotXcm,
ConstU32<{ 6 * HOURS }>,
AccountId,
(),
ConvertToValue<UsdtAsset>,
AliasesIntoAccountId32<(), AccountId>,
>;
type Members = pallet_ranked_collective::Pallet<Runtime, FellowshipCollectiveInstance>;

#[cfg(not(feature = "runtime-benchmarks"))]
type Salary = pallet_core_fellowship::Pallet<Runtime, FellowshipCoreInstance>;
#[cfg(feature = "runtime-benchmarks")]
type Salary = frame_support::traits::tokens::ConvertRank<
crate::impls::benchmarks::RankToSalary<Balances>,
>;
// 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<{ 100000 * UNITS }>;
gavofyork marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,22 @@ pub mod pallet_origins {
#[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)]
#[pallet::origin]
pub enum Origin {
/// Origin commanded by any members of the Polkadot Fellowship (no Dan grade needed).
FellowshipCandidates,
/// Origin commanded by Polkadot Fellows (3rd Dan fellows or greater).
Fellows,
/// Origin commanded by Polkadot Experts (5th Dan fellows or greater).
FellowshipExperts,
/// Origin commanded by Polkadot Masters (7th Dan fellows of greater).
FellowshipMasters,
/// Origin commanded by anyone invlved with the Polkadot Fellowship (no Dan grade needed).
Candidates,
/// Origin commanded by rank 1 of the Polkadot Fellowship and with a success of 1.
Fellowship1Dan,
Members,
/// Origin commanded by rank 2 of the Polkadot Fellowship and with a success of 2.
Fellowship2Dan,
/// Origin commanded by rank 3 of the Polkadot Fellowship and with a success of 3.
Fellowship3Dan,
/// Origin commanded by rank 4 of the Polkadot Fellowship and with a success of 4.
Fellowship4Dan,
/// Origin commanded by Polkadot Fellows (3rd Dan fellows or greater).
Fellows,
/// Origin commanded by Polkadot Architects (4th Dan fellows or greater).
Architects,
/// Origin commanded by rank 5 of the Polkadot Fellowship and with a success of 5.
Fellowship5Dan,
/// Origin commanded by rank 6 of the Polkadot Fellowship and with a success of 6.
Fellowship6Dan,
/// Origin commanded by rank 7 of the Polkadot Fellowship and with a success of 7.
Fellowship7Dan,
/// Origin commanded by Polkadot Masters (7th Dan fellows of greater).
Masters,
/// Origin commanded by rank 8 of the Polkadot Fellowship and with a success of 8.
Fellowship8Dan,
/// Origin commanded by rank 9 of the Polkadot Fellowship and with a success of 9.
Expand Down Expand Up @@ -93,10 +87,11 @@ pub mod pallet_origins {
() => {}
}
decl_unit_ensures!(
FellowshipCandidates: Rank = ranks::CANDIDATES,
Candidates: Rank = ranks::CANDIDATES,
Members: Rank = ranks::DAN_1,
Fellows: Rank = ranks::DAN_3,
FellowshipExperts: Rank = ranks::DAN_5,
FellowshipMasters: Rank = ranks::DAN_7,
Architects: Rank = ranks::DAN_4,
Masters: Rank = ranks::DAN_7,
);

macro_rules! decl_ensure {
Expand Down Expand Up @@ -134,13 +129,13 @@ pub mod pallet_origins {

decl_ensure! {
pub type EnsureFellowship: EnsureOrigin<Success = Rank> {
Fellowship1Dan = ranks::DAN_1,
Members = ranks::DAN_1,
Fellowship2Dan = ranks::DAN_2,
Fellowship3Dan = ranks::DAN_3,
Fellowship4Dan = ranks::DAN_4,
Fellows = ranks::DAN_3,
Architects = ranks::DAN_4,
Fellowship5Dan = ranks::DAN_5,
Fellowship6Dan = ranks::DAN_6,
Fellowship7Dan = ranks::DAN_7,
Masters = ranks::DAN_7,
Fellowship8Dan = ranks::DAN_8,
Fellowship9Dan = ranks::DAN_9,
}
Expand Down
Loading