Skip to content

Commit

Permalink
Salary pallet (paritytech#13378)
Browse files Browse the repository at this point in the history
* More drafting

* Paymaster pallet

* Fix build

* More tests

* Rename

* Rename

* Renaming

* Revert old changes

* Multi-phase payouts to avoid bank-runs

* Tests

* Tests

* Allow payment to be targeted elsewhere

* Proper ssync payment failure handling

* Test for repayment

* Docs

* Impl RankedMembers for RankedCollective

* Implement Pay for Pot (i.e. basic account).

* Benchmarks

* Weights

* Introduce Salary benchmark into node

* Fix warning

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_salary

* Update primitives/arithmetic/src/traits.rs

Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com>

* Update frame/salary/src/lib.rs

Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com>

* Update lib.rs

* Update frame/salary/src/lib.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Docs

* Update frame/salary/src/lib.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Update frame/salary/src/lib.rs

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Fix

* Fixes

* Fixes

* Move some salary traits stuff to a shared location

* Fix

* Update frame/salary/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Update frame/salary/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Mul floor

* Fix warnings

* Fix test

* Docs

---------

Co-authored-by: command-bot <>
Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com>
Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
  • Loading branch information
4 people authored and ukint-vs committed Apr 10, 2023
1 parent 373a72c commit 271c344
Show file tree
Hide file tree
Showing 17 changed files with 1,833 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ rls*.log
*.bin
*.iml
scripts/ci/node-template-release/Cargo.lock
substrate.code-workspace
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ members = [
"frame/recovery",
"frame/referenda",
"frame/remark",
"frame/salary",
"frame/scheduler",
"frame/scored-pool",
"frame/session",
Expand Down
4 changes: 4 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pallet-recovery = { version = "4.0.0-dev", default-features = false, path = "../
pallet-referenda = { version = "4.0.0-dev", default-features = false, path = "../../../frame/referenda" }
pallet-remark = { version = "4.0.0-dev", default-features = false, path = "../../../frame/remark" }
pallet-root-testing = { version = "1.0.0-dev", default-features = false, path = "../../../frame/root-testing" }
pallet-salary = { version = "4.0.0-dev", default-features = false, path = "../../../frame/salary" }
pallet-session = { version = "4.0.0-dev", features = [ "historical" ], path = "../../../frame/session", default-features = false }
pallet-session-benchmarking = { version = "4.0.0-dev", path = "../../../frame/session/benchmarking", default-features = false, optional = true }
pallet-staking = { version = "4.0.0-dev", default-features = false, path = "../../../frame/staking" }
Expand Down Expand Up @@ -185,6 +186,7 @@ std = [
"pallet-staking/std",
"pallet-staking-runtime-api/std",
"pallet-state-trie-migration/std",
"pallet-salary/std",
"sp-session/std",
"pallet-sudo/std",
"frame-support/std",
Expand Down Expand Up @@ -260,6 +262,7 @@ runtime-benchmarks = [
"pallet-referenda/runtime-benchmarks",
"pallet-recovery/runtime-benchmarks",
"pallet-remark/runtime-benchmarks",
"pallet-salary/runtime-benchmarks",
"pallet-session-benchmarking/runtime-benchmarks",
"pallet-society/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
Expand Down Expand Up @@ -318,6 +321,7 @@ try-runtime = [
"pallet-referenda/try-runtime",
"pallet-remark/try-runtime",
"pallet-root-testing/try-runtime",
"pallet-salary/try-runtime",
"pallet-session/try-runtime",
"pallet-staking/try-runtime",
"pallet-state-trie-migration/try-runtime",
Expand Down
34 changes: 30 additions & 4 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ use frame_support::{
pallet_prelude::Get,
parameter_types,
traits::{
fungible::ItemOf, tokens::nonfungibles_v2::Inspect, AsEnsureOriginWithArg, ConstBool,
ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse, EqualPrivilegeOnly, Everything,
Imbalance, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced,
U128CurrencyToVote, WithdrawReasons,
fungible::ItemOf,
tokens::{nonfungibles_v2::Inspect, GetSalary},
AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse,
EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem,
LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, WithdrawReasons,
},
weights::{
constants::{
Expand Down Expand Up @@ -1571,6 +1572,29 @@ impl pallet_uniques::Config for Runtime {
type Locker = ();
}

parameter_types! {
pub const Budget: Balance = 10_000 * DOLLARS;
pub TreasuryAccount: AccountId = Treasury::account_id();
}

pub struct SalaryForRank;
impl GetSalary<u16, AccountId, Balance> for SalaryForRank {
fn get_salary(a: u16, _: &AccountId) -> Balance {
Balance::from(a) * 1000 * DOLLARS
}
}

impl pallet_salary::Config for Runtime {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Paymaster = pallet_salary::PayFromAccount<Balances, TreasuryAccount>;
type Members = RankedCollective;
type Salary = SalaryForRank;
type RegistrationPeriod = ConstU32<200>;
type PayoutPeriod = ConstU32<200>;
type Budget = Budget;
}

parameter_types! {
pub Features: PalletFeatures = PalletFeatures::all_enabled();
pub const MaxAttributesPerCall: u32 = 10;
Expand Down Expand Up @@ -1766,6 +1790,7 @@ construct_runtime!(
Nis: pallet_nis,
Uniques: pallet_uniques,
Nfts: pallet_nfts,
Salary: pallet_salary,
TransactionStorage: pallet_transaction_storage,
VoterList: pallet_bags_list::<Instance1>,
StateTrieMigration: pallet_state_trie_migration,
Expand Down Expand Up @@ -1885,6 +1910,7 @@ mod benches {
[pallet_referenda, Referenda]
[pallet_recovery, Recovery]
[pallet_remark, Remark]
[pallet_salary, Salary]
[pallet_scheduler, Scheduler]
[pallet_glutton, Glutton]
[pallet_session, SessionBench::<Runtime>]
Expand Down
75 changes: 55 additions & 20 deletions frame/ranked-collective/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use frame_support::{
codec::{Decode, Encode, MaxEncodedLen},
dispatch::{DispatchError, DispatchResultWithPostInfo, PostDispatchInfo},
ensure,
traits::{EnsureOrigin, PollStatus, Polling, VoteTally},
traits::{EnsureOrigin, PollStatus, Polling, RankedMembers, VoteTally},
CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
};

Expand Down Expand Up @@ -472,24 +472,7 @@ pub mod pallet {
pub fn demote_member(origin: OriginFor<T>, who: AccountIdLookupOf<T>) -> DispatchResult {
let max_rank = T::DemoteOrigin::ensure_origin(origin)?;
let who = T::Lookup::lookup(who)?;
let mut record = Self::ensure_member(&who)?;
let rank = record.rank;
ensure!(max_rank >= rank, Error::<T, I>::NoPermission);

Self::remove_from_rank(&who, rank)?;
let maybe_rank = rank.checked_sub(1);
match maybe_rank {
None => {
Members::<T, I>::remove(&who);
Self::deposit_event(Event::MemberRemoved { who, rank: 0 });
},
Some(rank) => {
record.rank = rank;
Members::<T, I>::insert(&who, &record);
Self::deposit_event(Event::RankChanged { who, rank });
},
}
Ok(())
Self::do_demote_member(who, Some(max_rank))
}

/// Remove the member entirely.
Expand Down Expand Up @@ -659,7 +642,7 @@ pub mod pallet {
Ok(())
}

/// Promotes a member in the ranked collective into the next role.
/// Promotes a member in the ranked collective into the next higher rank.
///
/// A `maybe_max_rank` may be provided to check that the member does not get promoted beyond
/// a certain rank. Is `None` is provided, then the rank will be incremented without checks.
Expand All @@ -681,6 +664,33 @@ pub mod pallet {
Ok(())
}

/// Demotes a member in the ranked collective into the next lower rank.
///
/// A `maybe_max_rank` may be provided to check that the member does not get demoted from
/// a certain rank. Is `None` is provided, then the rank will be decremented without checks.
fn do_demote_member(who: T::AccountId, maybe_max_rank: Option<Rank>) -> DispatchResult {
let mut record = Self::ensure_member(&who)?;
let rank = record.rank;
if let Some(max_rank) = maybe_max_rank {
ensure!(max_rank >= rank, Error::<T, I>::NoPermission);
}

Self::remove_from_rank(&who, rank)?;
let maybe_rank = rank.checked_sub(1);
match maybe_rank {
None => {
Members::<T, I>::remove(&who);
Self::deposit_event(Event::MemberRemoved { who, rank: 0 });
},
Some(rank) => {
record.rank = rank;
Members::<T, I>::insert(&who, &record);
Self::deposit_event(Event::RankChanged { who, rank });
},
}
Ok(())
}

/// Add a member to the rank collective, and continue to promote them until a certain rank
/// is reached.
pub fn do_add_member_to_rank(who: T::AccountId, rank: Rank) -> DispatchResult {
Expand All @@ -691,4 +701,29 @@ pub mod pallet {
Ok(())
}
}

impl<T: Config<I>, I: 'static> RankedMembers for Pallet<T, I> {
type AccountId = T::AccountId;
type Rank = Rank;

fn min_rank() -> Self::Rank {
0
}

fn rank_of(who: &Self::AccountId) -> Option<Self::Rank> {
Some(Self::ensure_member(&who).ok()?.rank)
}

fn induct(who: &Self::AccountId) -> DispatchResult {
Self::do_add_member(who.clone())
}

fn promote(who: &Self::AccountId) -> DispatchResult {
Self::do_promote_member(who.clone(), None)
}

fn demote(who: &Self::AccountId) -> DispatchResult {
Self::do_demote_member(who.clone(), None)
}
}
}
49 changes: 49 additions & 0 deletions frame/salary/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[package]
name = "pallet-salary"
version = "4.0.0-dev"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "Apache-2.0"
homepage = "https://substrate.io"
repository = "https://github.com/paritytech/substrate/"
description = "Paymaster"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
log = { version = "0.4.16", default-features = false }
scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../benchmarking" }
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
sp-arithmetic = { version = "6.0.0", default-features = false, path = "../../primitives/arithmetic" }
sp-core = { version = "7.0.0", default-features = false, path = "../../primitives/core" }
sp-io = { version = "7.0.0", default-features = false, path = "../../primitives/io" }
sp-runtime = { version = "7.0.0", default-features = false, path = "../../primitives/runtime" }
sp-std = { version = "5.0.0", default-features = false, path = "../../primitives/std" }

[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"log/std",
"scale-info/std",
"sp-arithmetic/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = ["frame-support/try-runtime"]
3 changes: 3 additions & 0 deletions frame/salary/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Salary

Make periodic payment to members of a ranked collective according to rank.
Loading

0 comments on commit 271c344

Please sign in to comment.