Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BlockNumberProvider to salary pallet config #7000

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6481857
Update salary logic to use BlockNumberProvider
PolkadotDom Dec 21, 2024
0e650b6
Salary v0 to v1 migration
PolkadotDom Dec 23, 2024
4359f23
Set block provider to system for now
PolkadotDom Dec 23, 2024
7752f6c
Set to block number provider to relay chain
PolkadotDom Dec 23, 2024
52790c5
Fix storage version issue
PolkadotDom Dec 23, 2024
cb119b0
Add migrations
PolkadotDom Dec 23, 2024
bdd0727
Remove unused import
PolkadotDom Dec 23, 2024
77741b3
fmt
PolkadotDom Dec 23, 2024
a31302c
Add alloc crate back in
PolkadotDom Dec 24, 2024
a071803
Fix noop issue
PolkadotDom Dec 24, 2024
47e7079
Update spec version
PolkadotDom Dec 24, 2024
331469e
Add space
PolkadotDom Dec 25, 2024
5cea0ca
Remove testing functions
PolkadotDom Dec 25, 2024
30cc991
Remove unused imports
PolkadotDom Dec 25, 2024
25053cc
Update prdoc and cargo tomls
PolkadotDom Dec 25, 2024
e53d8b9
Cargo reversions, one doc
PolkadotDom Jan 6, 2025
0de9976
Add to docs for migration block converter
PolkadotDom Jan 6, 2025
b208d52
Update migration.rs
PolkadotDom Jan 7, 2025
606812b
Some more doc and naming updates, migration checks WIP
PolkadotDom Jan 7, 2025
1cbf8bd
fmt
PolkadotDom Jan 7, 2025
0a47eb6
fix migration checks
PolkadotDom Jan 7, 2025
cbc90eb
fmt
PolkadotDom Jan 7, 2025
724795d
Allow for future moments, some wording and syntax
PolkadotDom Jan 7, 2025
7a77e7e
Add runtime user to prdoc
PolkadotDom Jan 8, 2025
519a71d
Fix missing config type issue
PolkadotDom Jan 9, 2025
8d4cf70
Update pr_7000.prdoc
PolkadotDom Jan 9, 2025
d8e7a4e
Documentation fixes
PolkadotDom Jan 9, 2025
a1a2ad8
Merge remote-tracking branch 'upstream/master' into dom/salary-block-…
PolkadotDom Jan 9, 2025
9f4c28a
Fixes after update to umbrella crate
PolkadotDom Jan 10, 2025
5e7a539
small fix
PolkadotDom Jan 10, 2025
73536d9
Update migration.rs
PolkadotDom Jan 10, 2025
d682adf
fmt
PolkadotDom Jan 11, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -270,4 +270,6 @@ impl pallet_salary::Config<AmbassadorSalaryInstance> for Runtime {
type PayoutPeriod = ConstU32<{ 15 * DAYS }>;
// Total monthly salary budget.
type Budget = ConstU128<{ 10_000 * DOLLARS }>;

type BlockNumberProvider = cumulus_pallet_parachain_system::RelaychainDataProvider<Runtime>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ impl pallet_salary::Config<FellowshipSalaryInstance> for Runtime {
type PayoutPeriod = ConstU32<{ 15 * DAYS }>;
// Total monthly salary budget.
type Budget = ConstU128<{ 100_000 * USDT_UNITS }>;

type BlockNumberProvider = cumulus_pallet_parachain_system::RelaychainDataProvider<Runtime>;
}

parameter_types! {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ extern crate alloc;
pub use ambassador::pallet_ambassador_origins;

use alloc::{vec, vec::Vec};
use ambassador::AmbassadorCoreInstance;
use ambassador::{AmbassadorCoreInstance, AmbassadorSalaryInstance};
use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
use fellowship::{pallet_fellowship_origins, Fellows, FellowshipCoreInstance};
use fellowship::{
pallet_fellowship_origins, Fellows, FellowshipCoreInstance, FellowshipSalaryInstance,
};
use impls::{AllianceProposalProvider, EqualOrGreatestRootCmp};
use sp_api::impl_runtime_apis;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
Expand Down Expand Up @@ -770,8 +772,58 @@ type Migrations = (
pallet_core_fellowship::migration::MigrateV0ToV1<Runtime, FellowshipCoreInstance>,
// unreleased
pallet_core_fellowship::migration::MigrateV0ToV1<Runtime, AmbassadorCoreInstance>,
// unreleased
pallet_salary::migration::MigrateV0ToV1<
Runtime,
SalaryBlockNumberConverter,
FellowshipSalaryInstance,
>,
pallet_salary::migration::MigrateV0ToV1<
Runtime,
SalaryBlockNumberConverter,
AmbassadorSalaryInstance,
>,
);

// Helpers for the salary pallet v0->v1 storage migration.
use sp_runtime::traits::BlockNumberProvider;
type SalaryLocalBlockNumber = <System as BlockNumberProvider>::BlockNumber;
type SalaryNewBlockNumber = <cumulus_pallet_parachain_system::RelaychainDataProvider<Runtime>
as BlockNumberProvider>::BlockNumber;
pub struct SalaryBlockNumberConverter;
impl pallet_salary::migration::v1::ConvertBlockNumber<SalaryLocalBlockNumber, SalaryNewBlockNumber>
for SalaryBlockNumberConverter
{
/// Simply convert the types. Cycle index storage item uses block number but is agnostic to the
/// time that denotes for instance.
fn convert(local: SalaryLocalBlockNumber) -> SalaryNewBlockNumber {
local
}

/// The equivalent moment in time from the perspective of the relay chain, starting from a
/// local moment in time (system block number).
fn equivalent_moment_in_time(local_moment: SalaryLocalBlockNumber) -> SalaryNewBlockNumber {
let local_block_number = System::block_number();
let local_duration = u32::abs_diff(local_block_number, local_moment);
let relay_duration = Self::equivalent_block_duration(local_duration); // 6s to 6s
let relay_block_number = ParachainSystem::last_relay_block_number();
if local_block_number >= local_moment {
// Moment was in past.
relay_block_number.saturating_sub(relay_duration)
} else {
// Moment is in future.
relay_block_number.saturating_add(relay_duration)
}
}

/// The equivalent duration from the perspective of the relay chain, starting from
/// a local duration (number of block). Identity function for Westend, since both
/// relay and collectives chain run 6s block times.
fn equivalent_block_duration(local_duration: SalaryLocalBlockNumber) -> SalaryNewBlockNumber {
local_duration
}
}

/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
Runtime,
Expand Down
1 change: 1 addition & 0 deletions polkadot/xcm/xcm-builder/src/tests/pay/salary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl pallet_salary::Config for Test {
type RegistrationPeriod = RegistrationPeriod;
type PayoutPeriod = PayoutPeriod;
type Budget = Budget;
type BlockNumberProvider = System;
}

/// Scenario:
Expand Down
22 changes: 22 additions & 0 deletions prdoc/pr_7000.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
title: 'Adds BlockNumberProvider to pallet-core-fellowship'
doc:
- audience: Runtime Dev
description: |-
This PR adds a parameter 'BlockNumberProvider' to the pallet-salary
config such that a block provider can be set for use in the pallet. This would
usually be the frame system pallet or the appropriate relay chain. Previously
it defaulted to the frame system pallet.
- audience: Runtime User
description: |-
This PR updates the Westend runtime to use the relaychain's block number for
salary pallet logic. The type remains the same, but the values have
shifted.
crates:
- name: pallet-salary
bump: major
- name: collectives-westend-runtime
bump: minor
- name: kitchensink-runtime
bump: patch
- name: staging-xcm-builder
bump: patch
1 change: 1 addition & 0 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,7 @@ impl pallet_salary::Config for Runtime {
type RegistrationPeriod = ConstU32<200>;
type PayoutPeriod = ConstU32<200>;
type Budget = Budget;
type BlockNumberProvider = System;
}

impl pallet_core_fellowship::Config for Runtime {
Expand Down
28 changes: 18 additions & 10 deletions substrate/frame/salary/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
#![cfg(feature = "runtime-benchmarks")]

use super::*;
use crate::Pallet as Salary;

use crate::{pallet::BlockNumberFor as SalaryBlockNumberFor, Pallet as Salary};
use frame::benchmarking::prelude::*;

const SEED: u32 = 0;

fn ensure_member_with_salary<T: Config<I>, I: 'static>(who: &T::AccountId) {
Expand All @@ -44,6 +44,14 @@ fn ensure_member_with_salary<T: Config<I>, I: 'static>(who: &T::AccountId) {
mod benchmarks {
use super::*;

fn get_block_number<T: Config<I>, I: 'static>() -> SalaryBlockNumberFor<T, I> {
T::BlockNumberProvider::current_block_number()
}

fn set_block_number<T: Config<I>, I: 'static>(n: SalaryBlockNumberFor<T, I>) {
T::BlockNumberProvider::set_block_number(n);
}

#[benchmark]
fn init() {
let caller: T::AccountId = whitelisted_caller();
Expand All @@ -58,7 +66,7 @@ mod benchmarks {
fn bump() {
let caller: T::AccountId = whitelisted_caller();
Salary::<T, I>::init(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + Salary::<T, I>::cycle_period());
set_block_number::<T, I>(get_block_number::<T, I>() + Salary::<T, I>::cycle_period());

#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
Expand All @@ -84,7 +92,7 @@ mod benchmarks {
ensure_member_with_salary::<T, I>(&caller);
Salary::<T, I>::init(RawOrigin::Signed(caller.clone()).into()).unwrap();
Salary::<T, I>::induct(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + Salary::<T, I>::cycle_period());
set_block_number::<T, I>(get_block_number::<T, I>() + Salary::<T, I>::cycle_period());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();

#[extrinsic_call]
Expand All @@ -99,9 +107,9 @@ mod benchmarks {
ensure_member_with_salary::<T, I>(&caller);
Salary::<T, I>::init(RawOrigin::Signed(caller.clone()).into()).unwrap();
Salary::<T, I>::induct(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + Salary::<T, I>::cycle_period());
set_block_number::<T, I>(get_block_number::<T, I>() + Salary::<T, I>::cycle_period());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + T::RegistrationPeriod::get());
set_block_number::<T, I>(get_block_number::<T, I>() + T::RegistrationPeriod::get());

let salary = T::Salary::get_salary(T::Members::rank_of(&caller).unwrap(), &caller);
T::Paymaster::ensure_successful(&caller, (), salary);
Expand All @@ -125,9 +133,9 @@ mod benchmarks {
ensure_member_with_salary::<T, I>(&caller);
Salary::<T, I>::init(RawOrigin::Signed(caller.clone()).into()).unwrap();
Salary::<T, I>::induct(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + Salary::<T, I>::cycle_period());
set_block_number::<T, I>(get_block_number::<T, I>() + Salary::<T, I>::cycle_period());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + T::RegistrationPeriod::get());
set_block_number::<T, I>(get_block_number::<T, I>() + T::RegistrationPeriod::get());

let salary = T::Salary::get_salary(T::Members::rank_of(&caller).unwrap(), &caller);
let recipient: T::AccountId = account("recipient", 0, SEED);
Expand All @@ -152,9 +160,9 @@ mod benchmarks {
ensure_member_with_salary::<T, I>(&caller);
Salary::<T, I>::init(RawOrigin::Signed(caller.clone()).into()).unwrap();
Salary::<T, I>::induct(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + Salary::<T, I>::cycle_period());
set_block_number::<T, I>(get_block_number::<T, I>() + Salary::<T, I>::cycle_period());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + T::RegistrationPeriod::get());
set_block_number::<T, I>(get_block_number::<T, I>() + T::RegistrationPeriod::get());

let salary = T::Salary::get_salary(T::Members::rank_of(&caller).unwrap(), &caller);
let recipient: T::AccountId = account("recipient", 0, SEED);
Expand Down
51 changes: 34 additions & 17 deletions substrate/frame/salary/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#![cfg_attr(not(feature = "std"), no_std)]

extern crate alloc;

use core::marker::PhantomData;
use frame::{
prelude::*,
Expand All @@ -30,6 +32,7 @@ mod tests;

#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
pub mod migration;
pub mod weights;

pub use pallet::*;
Expand All @@ -42,15 +45,15 @@ pub type Cycle = u32;
#[derive(Encode, Decode, Eq, PartialEq, Clone, TypeInfo, MaxEncodedLen, RuntimeDebug)]
pub struct StatusType<CycleIndex, BlockNumber, Balance> {
/// The index of the "current cycle" (i.e. the last cycle being processed).
cycle_index: CycleIndex,
pub cycle_index: CycleIndex,
/// The first block of the "current cycle" (i.e. the last cycle being processed).
cycle_start: BlockNumber,
pub cycle_start: BlockNumber,
/// The total budget available for all payments in the current cycle.
budget: Balance,
pub budget: Balance,
/// The total amount of the payments registered in the current cycle.
total_registrations: Balance,
pub total_registrations: Balance,
/// The total amount of unregistered payments which have been made in the current cycle.
total_unregistered_paid: Balance,
pub total_unregistered_paid: Balance,
}

/// The state of a specific payment claim.
Expand Down Expand Up @@ -78,7 +81,12 @@ pub struct ClaimantStatus<CycleIndex, Balance, Id> {
#[frame::pallet]
pub mod pallet {
use super::*;

/// The in-code storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);

#[pallet::config]
Expand Down Expand Up @@ -112,27 +120,36 @@ pub mod pallet {
/// The number of blocks between sequential payout cycles is the sum of this and
/// `PayoutPeriod`.
#[pallet::constant]
type RegistrationPeriod: Get<BlockNumberFor<Self>>;
type RegistrationPeriod: Get<BlockNumberFor<Self, I>>;

/// The number of blocks within a cycle which accounts have to claim the payout.
///
/// The number of blocks between sequential payout cycles is the sum of this and
/// `RegistrationPeriod`.
#[pallet::constant]
type PayoutPeriod: Get<BlockNumberFor<Self>>;
type PayoutPeriod: Get<BlockNumberFor<Self, I>>;

/// The total budget per cycle.
///
/// This may change over the course of a cycle without any problem.
#[pallet::constant]
type Budget: Get<BalanceOf<Self, I>>;

/// Provides the current block number.
///
/// This is usually `cumulus_pallet_parachain_system::RelaychainDataProvider` if a
/// parachain, or `frame_system::Pallet` if a solo- or relaychain.
type BlockNumberProvider: BlockNumberProvider;
}

pub type CycleIndexOf<T> = BlockNumberFor<T>;
pub type BlockNumberFor<T, I> =
<<T as Config<I>>::BlockNumberProvider as BlockNumberProvider>::BlockNumber;
pub type CycleIndexOf<T, I> = BlockNumberFor<T, I>;
pub type BalanceOf<T, I> = <<T as Config<I>>::Paymaster as Pay>::Balance;
pub type IdOf<T, I> = <<T as Config<I>>::Paymaster as Pay>::Id;
pub type StatusOf<T, I> = StatusType<CycleIndexOf<T>, BlockNumberFor<T>, BalanceOf<T, I>>;
pub type ClaimantStatusOf<T, I> = ClaimantStatus<CycleIndexOf<T>, BalanceOf<T, I>, IdOf<T, I>>;
pub type StatusOf<T, I> = StatusType<CycleIndexOf<T, I>, BlockNumberFor<T, I>, BalanceOf<T, I>>;
pub type ClaimantStatusOf<T, I> =
ClaimantStatus<CycleIndexOf<T, I>, BalanceOf<T, I>, IdOf<T, I>>;

/// The overall status of the system.
#[pallet::storage]
Expand All @@ -159,7 +176,7 @@ pub mod pallet {
id: <T::Paymaster as Pay>::Id,
},
/// The next cycle begins.
CycleStarted { index: CycleIndexOf<T> },
CycleStarted { index: CycleIndexOf<T, I> },
/// A member swapped their account.
Swapped { who: T::AccountId, new_who: T::AccountId },
}
Expand Down Expand Up @@ -205,7 +222,7 @@ pub mod pallet {
#[pallet::call_index(0)]
pub fn init(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let _ = ensure_signed(origin)?;
let now = frame_system::Pallet::<T>::block_number();
let now = T::BlockNumberProvider::current_block_number();
ensure!(!Status::<T, I>::exists(), Error::<T, I>::AlreadyStarted);
let status = StatusType {
cycle_index: Zero::zero(),
Expand All @@ -227,7 +244,7 @@ pub mod pallet {
#[pallet::call_index(1)]
pub fn bump(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let _ = ensure_signed(origin)?;
let now = frame_system::Pallet::<T>::block_number();
let now = T::BlockNumberProvider::current_block_number();
let cycle_period = Self::cycle_period();
let mut status = Status::<T, I>::get().ok_or(Error::<T, I>::NotStarted)?;
status.cycle_start.saturating_accrue(cycle_period);
Expand Down Expand Up @@ -273,7 +290,7 @@ pub mod pallet {
let rank = T::Members::rank_of(&who).ok_or(Error::<T, I>::NotMember)?;
let mut status = Status::<T, I>::get().ok_or(Error::<T, I>::NotStarted)?;
let mut claimant = Claimant::<T, I>::get(&who).ok_or(Error::<T, I>::NotInducted)?;
let now = frame_system::Pallet::<T>::block_number();
let now = T::BlockNumberProvider::current_block_number();
ensure!(
now < status.cycle_start + T::RegistrationPeriod::get(),
Error::<T, I>::TooLate
Expand Down Expand Up @@ -373,17 +390,17 @@ pub mod pallet {
pub fn status() -> Option<StatusOf<T, I>> {
Status::<T, I>::get()
}
pub fn last_active(who: &T::AccountId) -> Result<CycleIndexOf<T>, DispatchError> {
pub fn last_active(who: &T::AccountId) -> Result<CycleIndexOf<T, I>, DispatchError> {
Ok(Claimant::<T, I>::get(&who).ok_or(Error::<T, I>::NotInducted)?.last_active)
}
pub fn cycle_period() -> BlockNumberFor<T> {
pub fn cycle_period() -> BlockNumberFor<T, I> {
T::RegistrationPeriod::get() + T::PayoutPeriod::get()
}
fn do_payout(who: T::AccountId, beneficiary: T::AccountId) -> DispatchResult {
let mut status = Status::<T, I>::get().ok_or(Error::<T, I>::NotStarted)?;
let mut claimant = Claimant::<T, I>::get(&who).ok_or(Error::<T, I>::NotInducted)?;

let now = frame_system::Pallet::<T>::block_number();
let now = T::BlockNumberProvider::current_block_number();
ensure!(
now >= status.cycle_start + T::RegistrationPeriod::get(),
Error::<T, I>::TooEarly,
Expand Down
Loading
Loading