feat: Rebrand Polkadot/Substrate references to PezkuwiChain

This commit systematically rebrands various references from Parity Technologies'
Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk.

Key changes include:
- Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks.
- Modified internal documentation and code comments to reflect PezkuwiChain naming and structure.
- Replaced direct references to  with  or specific paths within the  for XCM, Pezkuwi, and other modules.
- Cleaned up deprecated  issue and PR references in various  and  files, particularly in  and  modules.
- Adjusted image and logo URLs in documentation to point to PezkuwiChain assets.
- Removed or rephrased comments related to external Polkadot/Substrate PRs and issues.

This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
2025-12-14 00:04:10 +03:00
parent 286de54384
commit 1c0e57d984
9084 changed files with 997839 additions and 997557 deletions
+38
View File
@@ -0,0 +1,38 @@
[package]
name = "pezpallet-salary"
version = "13.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage.workspace = true
repository.workspace = true
description = "Paymaster"
readme = "README.md"
[lints]
workspace = true
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { features = ["derive"], workspace = true }
frame = { workspace = true, features = ["runtime"] }
log = { workspace = true }
pezpallet-ranked-collective = { optional = true, workspace = true }
scale-info = { features = ["derive"], workspace = true }
[features]
default = ["std"]
std = [
"codec/std",
"frame/std",
"log/std",
"pezpallet-ranked-collective/std",
"scale-info/std",
]
runtime-benchmarks = [
"frame/runtime-benchmarks",
"pezpallet-ranked-collective/runtime-benchmarks",
]
try-runtime = ["frame/try-runtime", "pezpallet-ranked-collective?/try-runtime"]
+3
View File
@@ -0,0 +1,3 @@
# Salary
Make periodic payment to members of a ranked collective according to rank.
@@ -0,0 +1,180 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Salary pallet benchmarking.
#![cfg(feature = "runtime-benchmarks")]
use super::*;
use crate::Pallet as Salary;
use frame::benchmarking::prelude::*;
const SEED: u32 = 0;
fn ensure_member_with_salary<T: Config<I>, I: 'static>(who: &T::AccountId) {
// induct if not a member.
if T::Members::rank_of(who).is_none() {
T::Members::induct(who).unwrap();
}
// promote until they have a salary.
for _ in 0..255 {
let r = T::Members::rank_of(who).expect("prior guard ensures `who` is a member; qed");
if !T::Salary::get_salary(r, &who).is_zero() {
break;
}
T::Members::promote(who).unwrap();
}
}
#[instance_benchmarks]
mod benchmarks {
use super::*;
#[benchmark]
fn init() {
let caller: T::AccountId = whitelisted_caller();
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
assert!(Salary::<T, I>::status().is_some());
}
#[benchmark]
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());
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
assert_eq!(Salary::<T, I>::status().unwrap().cycle_index, 1u32.into());
}
#[benchmark]
fn induct() {
let caller = whitelisted_caller();
ensure_member_with_salary::<T, I>(&caller);
Salary::<T, I>::init(RawOrigin::Signed(caller.clone()).into()).unwrap();
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
assert!(Salary::<T, I>::last_active(&caller).is_ok());
}
#[benchmark]
fn register() {
let caller = whitelisted_caller();
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());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
assert_eq!(Salary::<T, I>::last_active(&caller).unwrap(), 1u32.into());
}
#[benchmark]
fn payout() {
let caller = whitelisted_caller();
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());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + T::RegistrationPeriod::get());
let salary = T::Salary::get_salary(T::Members::rank_of(&caller).unwrap(), &caller);
T::Paymaster::ensure_successful(&caller, (), salary);
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
match Claimant::<T, I>::get(&caller) {
Some(ClaimantStatus { last_active, status: Attempted { id, .. } }) => {
assert_eq!(last_active, 1u32.into());
assert_ne!(T::Paymaster::check_payment(id), PaymentStatus::Failure);
},
_ => panic!("No claim made"),
}
assert!(Salary::<T, I>::payout(RawOrigin::Signed(caller.clone()).into()).is_err());
}
#[benchmark]
fn payout_other() {
let caller = whitelisted_caller();
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());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + T::RegistrationPeriod::get());
let salary = T::Salary::get_salary(T::Members::rank_of(&caller).unwrap(), &caller);
let recipient: T::AccountId = account("recipient", 0, SEED);
T::Paymaster::ensure_successful(&recipient, (), salary);
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), recipient.clone());
match Claimant::<T, I>::get(&caller) {
Some(ClaimantStatus { last_active, status: Attempted { id, .. } }) => {
assert_eq!(last_active, 1u32.into());
assert_ne!(T::Paymaster::check_payment(id), PaymentStatus::Failure);
},
_ => panic!("No claim made"),
}
assert!(Salary::<T, I>::payout(RawOrigin::Signed(caller.clone()).into()).is_err());
}
#[benchmark]
fn check_payment() {
let caller = whitelisted_caller();
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());
Salary::<T, I>::bump(RawOrigin::Signed(caller.clone()).into()).unwrap();
System::<T>::set_block_number(System::<T>::block_number() + T::RegistrationPeriod::get());
let salary = T::Salary::get_salary(T::Members::rank_of(&caller).unwrap(), &caller);
let recipient: T::AccountId = account("recipient", 0, SEED);
T::Paymaster::ensure_successful(&recipient, (), salary);
Salary::<T, I>::payout(RawOrigin::Signed(caller.clone()).into()).unwrap();
let id = match Claimant::<T, I>::get(&caller).unwrap().status {
Attempted { id, .. } => id,
_ => panic!("No claim made"),
};
T::Paymaster::ensure_concluded(id);
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
assert!(!matches!(Claimant::<T, I>::get(&caller).unwrap().status, Attempted { .. }));
}
impl_benchmark_test_suite! {
Salary,
crate::tests::unit::new_test_ext(),
crate::tests::unit::Test,
}
}
+478
View File
@@ -0,0 +1,478 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Make periodic payment to members of a ranked collective according to rank.
#![cfg_attr(not(feature = "std"), no_std)]
use core::marker::PhantomData;
use frame::{
prelude::*,
traits::tokens::{GetSalary, Pay, PaymentStatus},
};
#[cfg(test)]
mod tests;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
pub mod weights;
pub use pallet::*;
pub use weights::WeightInfo;
/// Payroll cycle.
pub type Cycle = u32;
/// The status of the pallet instance.
#[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,
/// The first block of the "current cycle" (i.e. the last cycle being processed).
cycle_start: BlockNumber,
/// The total budget available for all payments in the current cycle.
budget: Balance,
/// The total amount of the payments registered in the current cycle.
total_registrations: Balance,
/// The total amount of unregistered payments which have been made in the current cycle.
total_unregistered_paid: Balance,
}
/// The state of a specific payment claim.
#[derive(Encode, Decode, Eq, PartialEq, Clone, TypeInfo, MaxEncodedLen, RuntimeDebug)]
pub enum ClaimState<Balance, Id> {
/// No claim recorded.
Nothing,
/// Amount reserved when last active.
Registered(Balance),
/// Amount attempted to be paid when last active as well as the identity of the payment.
Attempted { registered: Option<Balance>, id: Id, amount: Balance },
}
use ClaimState::*;
/// The status of a single payee/claimant.
#[derive(Encode, Decode, Eq, PartialEq, Clone, TypeInfo, MaxEncodedLen, RuntimeDebug)]
pub struct ClaimantStatus<CycleIndex, Balance, Id> {
/// The most recent cycle in which the claimant was active.
last_active: CycleIndex,
/// The state of the payment/claim with in the above cycle.
status: ClaimState<Balance, Id>,
}
#[frame::pallet]
pub mod pallet {
use super::*;
#[pallet::pallet]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::config]
pub trait Config<I: 'static = ()>: pezframe_system::Config {
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
/// The runtime event type.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
/// Means by which we can make payments to accounts. This also defines the currency and the
/// balance which we use to denote that currency.
type Paymaster: Pay<Beneficiary = <Self as pezframe_system::Config>::AccountId, AssetKind = ()>;
/// The current membership of payees.
type Members: RankedMembers<AccountId = <Self as pezframe_system::Config>::AccountId>;
/// The maximum payout to be made for a single period to an active member of the given rank.
///
/// The benchmarks require that this be non-zero for some rank at most 255.
type Salary: GetSalary<
<Self::Members as RankedMembers>::Rank,
Self::AccountId,
<Self::Paymaster as Pay>::Balance,
>;
/// The number of blocks within a cycle which accounts have to register their intent to
/// claim.
///
/// The number of blocks between sequential payout cycles is the sum of this and
/// `PayoutPeriod`.
#[pallet::constant]
type RegistrationPeriod: Get<BlockNumberFor<Self>>;
/// 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>>;
/// 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>>;
}
pub type CycleIndexOf<T> = BlockNumberFor<T>;
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>>;
/// The overall status of the system.
#[pallet::storage]
pub type Status<T: Config<I>, I: 'static = ()> = StorageValue<_, StatusOf<T, I>, OptionQuery>;
/// The status of a claimant.
#[pallet::storage]
pub type Claimant<T: Config<I>, I: 'static = ()> =
StorageMap<_, Twox64Concat, T::AccountId, ClaimantStatusOf<T, I>, OptionQuery>;
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> {
/// A member is inducted into the payroll.
Inducted { who: T::AccountId },
/// A member registered for a payout.
Registered { who: T::AccountId, amount: BalanceOf<T, I> },
/// A payment happened.
Paid {
who: T::AccountId,
beneficiary: T::AccountId,
amount: BalanceOf<T, I>,
id: <T::Paymaster as Pay>::Id,
},
/// The next cycle begins.
CycleStarted { index: CycleIndexOf<T> },
/// A member swapped their account.
Swapped { who: T::AccountId, new_who: T::AccountId },
}
#[pallet::error]
pub enum Error<T, I = ()> {
/// The salary system has already been started.
AlreadyStarted,
/// The account is not a ranked member.
NotMember,
/// The account is already inducted.
AlreadyInducted,
// The account is not yet inducted into the system.
NotInducted,
/// The member does not have a current valid claim.
NoClaim,
/// The member's claim is zero.
ClaimZero,
/// Current cycle's registration period is over.
TooLate,
/// Current cycle's payment period is not yet begun.
TooEarly,
/// Cycle is not yet over.
NotYet,
/// The payout cycles have not yet started.
NotStarted,
/// There is no budget left for the payout.
Bankrupt,
/// There was some issue with the mechanism of payment.
PayError,
/// The payment has neither failed nor succeeded yet.
Inconclusive,
/// The cycle is after that in which the payment was made.
NotCurrent,
}
#[pallet::call]
impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Start the first payout cycle.
///
/// - `origin`: A `Signed` origin of an account.
#[pallet::weight(T::WeightInfo::init())]
#[pallet::call_index(0)]
pub fn init(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
ensure_signed(origin)?;
let now = pezframe_system::Pallet::<T>::block_number();
ensure!(!Status::<T, I>::exists(), Error::<T, I>::AlreadyStarted);
let status = StatusType {
cycle_index: Zero::zero(),
cycle_start: now,
budget: T::Budget::get(),
total_registrations: Zero::zero(),
total_unregistered_paid: Zero::zero(),
};
Status::<T, I>::put(&status);
Self::deposit_event(Event::<T, I>::CycleStarted { index: status.cycle_index });
Ok(Pays::No.into())
}
/// Move to next payout cycle, assuming that the present block is now within that cycle.
///
/// - `origin`: A `Signed` origin of an account.
#[pallet::weight(T::WeightInfo::bump())]
#[pallet::call_index(1)]
pub fn bump(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
ensure_signed(origin)?;
let now = pezframe_system::Pallet::<T>::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);
ensure!(now >= status.cycle_start, Error::<T, I>::NotYet);
status.cycle_index.saturating_inc();
status.budget = T::Budget::get();
status.total_registrations = Zero::zero();
status.total_unregistered_paid = Zero::zero();
Status::<T, I>::put(&status);
Self::deposit_event(Event::<T, I>::CycleStarted { index: status.cycle_index });
Ok(Pays::No.into())
}
/// Induct oneself into the payout system.
#[pallet::weight(T::WeightInfo::induct())]
#[pallet::call_index(2)]
pub fn induct(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
let cycle_index = Status::<T, I>::get().ok_or(Error::<T, I>::NotStarted)?.cycle_index;
T::Members::rank_of(&who).ok_or(Error::<T, I>::NotMember)?;
ensure!(!Claimant::<T, I>::contains_key(&who), Error::<T, I>::AlreadyInducted);
Claimant::<T, I>::insert(
&who,
ClaimantStatus { last_active: cycle_index, status: Nothing },
);
Self::deposit_event(Event::<T, I>::Inducted { who });
Ok(Pays::No.into())
}
/// Register for a payout.
///
/// Will only work if we are in the first `RegistrationPeriod` blocks since the cycle
/// started.
///
/// - `origin`: A `Signed` origin of an account which is a member of `Members`.
#[pallet::weight(T::WeightInfo::register())]
#[pallet::call_index(3)]
pub fn register(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
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 = pezframe_system::Pallet::<T>::block_number();
ensure!(
now < status.cycle_start + T::RegistrationPeriod::get(),
Error::<T, I>::TooLate
);
ensure!(claimant.last_active < status.cycle_index, Error::<T, I>::NoClaim);
let payout = T::Salary::get_salary(rank, &who);
ensure!(!payout.is_zero(), Error::<T, I>::ClaimZero);
claimant.last_active = status.cycle_index;
claimant.status = Registered(payout);
status.total_registrations.saturating_accrue(payout);
Claimant::<T, I>::insert(&who, &claimant);
Status::<T, I>::put(&status);
Self::deposit_event(Event::<T, I>::Registered { who, amount: payout });
Ok(Pays::No.into())
}
/// Request a payout.
///
/// Will only work if we are after the first `RegistrationPeriod` blocks since the cycle
/// started but by no more than `PayoutPeriod` blocks.
///
/// - `origin`: A `Signed` origin of an account which is a member of `Members`.
#[pallet::weight(T::WeightInfo::payout())]
#[pallet::call_index(4)]
pub fn payout(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
Self::do_payout(who.clone(), who)?;
Ok(Pays::No.into())
}
/// Request a payout to a secondary account.
///
/// Will only work if we are after the first `RegistrationPeriod` blocks since the cycle
/// started but by no more than `PayoutPeriod` blocks.
///
/// - `origin`: A `Signed` origin of an account which is a member of `Members`.
/// - `beneficiary`: The account to receive payment.
#[pallet::weight(T::WeightInfo::payout_other())]
#[pallet::call_index(5)]
pub fn payout_other(
origin: OriginFor<T>,
beneficiary: T::AccountId,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
Self::do_payout(who, beneficiary)?;
Ok(Pays::No.into())
}
/// Update a payment's status; if it failed, alter the state so the payment can be retried.
///
/// This must be called within the same cycle as the failed payment. It will fail with
/// `Event::NotCurrent` otherwise.
///
/// - `origin`: A `Signed` origin of an account which is a member of `Members` who has
/// received a payment this cycle.
#[pallet::weight(T::WeightInfo::check_payment())]
#[pallet::call_index(6)]
pub fn check_payment(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
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)?;
ensure!(claimant.last_active == status.cycle_index, Error::<T, I>::NotCurrent);
let (id, registered, amount) = match claimant.status {
Attempted { id, registered, amount } => (id, registered, amount),
_ => return Err(Error::<T, I>::NoClaim.into()),
};
match T::Paymaster::check_payment(id) {
PaymentStatus::Failure => {
// Payment failed: we reset back to the status prior to payment.
if let Some(amount) = registered {
// Account registered; this makes it simple to roll back and allow retry.
claimant.status = ClaimState::Registered(amount);
} else {
// Account didn't register; we set it to `Nothing` but must decrement
// the `last_active` also to ensure a retry works.
claimant.last_active.saturating_reduce(1u32.into());
claimant.status = ClaimState::Nothing;
// Since it is not registered, we must walk back our counter for what has
// been paid.
status.total_unregistered_paid.saturating_reduce(amount);
}
},
PaymentStatus::Success => claimant.status = ClaimState::Nothing,
_ => return Err(Error::<T, I>::Inconclusive.into()),
}
Claimant::<T, I>::insert(&who, &claimant);
Status::<T, I>::put(&status);
Ok(Pays::No.into())
}
}
impl<T: Config<I>, I: 'static> Pallet<T, I> {
pub fn status() -> Option<StatusOf<T, I>> {
Status::<T, I>::get()
}
pub fn last_active(who: &T::AccountId) -> Result<CycleIndexOf<T>, DispatchError> {
Ok(Claimant::<T, I>::get(&who).ok_or(Error::<T, I>::NotInducted)?.last_active)
}
pub fn cycle_period() -> BlockNumberFor<T> {
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 = pezframe_system::Pallet::<T>::block_number();
ensure!(
now >= status.cycle_start + T::RegistrationPeriod::get(),
Error::<T, I>::TooEarly,
);
let (payout, registered) = match claimant.status {
Registered(unpaid) if claimant.last_active == status.cycle_index => {
// Registered for this cycle. Pay accordingly.
let payout = if status.total_registrations <= status.budget {
// Can pay in full.
unpaid
} else {
// Must be reduced pro-rata
Perbill::from_rational(status.budget, status.total_registrations)
.mul_floor(unpaid)
};
(payout, Some(unpaid))
},
Nothing | Attempted { .. } | Registered(_)
if claimant.last_active < status.cycle_index =>
{
// Not registered for this cycle (or stale registration from previous cycle).
// Pay from whatever is left.
let rank = T::Members::rank_of(&who).ok_or(Error::<T, I>::NotMember)?;
let ideal_payout = T::Salary::get_salary(rank, &who);
let pot = status
.budget
.saturating_sub(status.total_registrations)
.saturating_sub(status.total_unregistered_paid);
let payout = ideal_payout.min(pot);
ensure!(!payout.is_zero(), Error::<T, I>::ClaimZero);
status.total_unregistered_paid.saturating_accrue(payout);
(payout, None)
},
_ => return Err(Error::<T, I>::NoClaim.into()),
};
claimant.last_active = status.cycle_index;
let id =
T::Paymaster::pay(&beneficiary, (), payout).map_err(|_| Error::<T, I>::PayError)?;
claimant.status = Attempted { registered, id, amount: payout };
Claimant::<T, I>::insert(&who, &claimant);
Status::<T, I>::put(&status);
Self::deposit_event(Event::<T, I>::Paid { who, beneficiary, amount: payout, id });
Ok(())
}
}
}
impl<T: Config<I>, I: 'static>
RankedMembersSwapHandler<T::AccountId, <T::Members as RankedMembers>::Rank> for Pallet<T, I>
{
fn swapped(
who: &T::AccountId,
new_who: &T::AccountId,
_rank: <T::Members as RankedMembers>::Rank,
) {
if who == new_who {
defensive!("Should not try to swap with self");
return;
}
if Claimant::<T, I>::contains_key(new_who) {
defensive!("Should not try to overwrite existing claimant");
return;
}
let Some(claimant) = Claimant::<T, I>::take(who) else {
defensive!("Claimant should exist when swapping");
return;
};
Claimant::<T, I>::insert(new_who, claimant);
Self::deposit_event(Event::<T, I>::Swapped { who: who.clone(), new_who: new_who.clone() });
}
}
#[cfg(feature = "runtime-benchmarks")]
impl<T: Config<I>, I: 'static>
pezpallet_ranked_collective::BenchmarkSetup<<T as pezframe_system::Config>::AccountId> for Pallet<T, I>
{
fn ensure_member(who: &<T as pezframe_system::Config>::AccountId) {
Self::init(pezframe_system::RawOrigin::Signed(who.clone()).into()).unwrap();
Self::induct(pezframe_system::RawOrigin::Signed(who.clone()).into()).unwrap();
}
}
@@ -0,0 +1,230 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! The crate's tests.
use crate as pezpallet_salary;
use crate::*;
use frame::{deps::pezsp_io, testing_prelude::*};
use pezpallet_ranked_collective::{EnsureRanked, Geometric};
type Rank = u16;
type Block = pezframe_system::mocking::MockBlock<Test>;
construct_runtime!(
pub struct Test {
System: pezframe_system,
Salary: pezpallet_salary,
Club: pezpallet_ranked_collective,
}
);
parameter_types! {
pub BlockWeights: pezframe_system::limits::BlockWeights =
pezframe_system::limits::BlockWeights::simple_max(Weight::from_parts(1_000_000, 0));
}
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Test {
type Block = Block;
}
pub struct MinRankOfClass<Delta>(PhantomData<Delta>);
impl<Delta: Get<Rank>> Convert<u16, Rank> for MinRankOfClass<Delta> {
fn convert(a: u16) -> Rank {
a.saturating_sub(Delta::get())
}
}
pub struct TestPay;
impl Pay for TestPay {
type Beneficiary = u64;
type Balance = u64;
type Id = u64;
type AssetKind = ();
type Error = ();
fn pay(
_: &Self::Beneficiary,
_: Self::AssetKind,
_: Self::Balance,
) -> Result<Self::Id, Self::Error> {
unreachable!()
}
fn check_payment(_: Self::Id) -> PaymentStatus {
unreachable!()
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) {}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_concluded(_: Self::Id) {
unreachable!()
}
}
parameter_types! {
pub static Budget: u64 = 10;
}
impl Config for Test {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Paymaster = TestPay;
type Members = Club;
type Salary = FixedSalary;
type RegistrationPeriod = ConstU64<2>;
type PayoutPeriod = ConstU64<2>;
type Budget = Budget;
}
pub struct FixedSalary;
impl GetSalary<u16, u64, u64> for FixedSalary {
fn get_salary(_rank: u16, _who: &u64) -> u64 {
123
}
}
parameter_types! {
pub static MinRankOfClassDelta: Rank = 0;
}
impl pezpallet_ranked_collective::Config for Test {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type PromoteOrigin = EitherOf<
// Root can promote arbitrarily.
pezframe_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
// Members can promote up to the rank of 2 below them.
MapSuccess<EnsureRanked<Test, (), 2>, ReduceBy<ConstU16<2>>>,
>;
type AddOrigin = MapSuccess<Self::PromoteOrigin, ReplaceWithDefault<()>>;
type DemoteOrigin = EitherOf<
// Root can demote arbitrarily.
pezframe_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
// Members can demote up to the rank of 3 below them.
MapSuccess<EnsureRanked<Test, (), 3>, ReduceBy<ConstU16<3>>>,
>;
type RemoveOrigin = Self::DemoteOrigin;
type ExchangeOrigin = EitherOf<
// Root can exchange arbitrarily.
pezframe_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
// Members can exchange up to the rank of 2 below them.
MapSuccess<EnsureRanked<Test, (), 2>, ReduceBy<ConstU16<2>>>,
>;
type Polls = NoOpPoll<BlockNumberFor<Test>>;
type MinRankOfClass = MinRankOfClass<MinRankOfClassDelta>;
type MemberSwappedHandler = Salary;
type VoteWeight = Geometric;
type MaxMemberCount = ();
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkSetup = Salary;
}
pub fn new_test_ext() -> TestState {
let t = pezframe_system::GenesisConfig::<Test>::default().build_storage().unwrap();
let mut ext = TestState::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
}
fn assert_last_event(generic_event: <Test as Config>::RuntimeEvent) {
let events = pezframe_system::Pallet::<Test>::events();
let system_event: <Test as pezframe_system::Config>::RuntimeEvent = generic_event.into();
let pezframe_system::EventRecord { event, .. } = events.last().expect("Event expected");
assert_eq!(event, &system_event.into());
}
fn promote_n_times(acc: u64, r: u16) {
for _ in 0..r {
assert_ok!(Club::promote_member(RuntimeOrigin::root(), acc));
}
}
#[test]
fn swap_simple_works() {
new_test_ext().execute_with(|| {
for i in 0u16..9 {
let acc = i as u64;
assert_ok!(Club::add_member(RuntimeOrigin::root(), acc));
promote_n_times(acc, i);
let _ = Salary::init(RuntimeOrigin::signed(acc));
assert_ok!(Salary::induct(RuntimeOrigin::signed(acc)));
// Swapping normally works:
assert_ok!(Club::exchange_member(RuntimeOrigin::root(), acc, acc + 10));
assert_last_event(Event::Swapped { who: acc, new_who: acc + 10 }.into());
}
});
}
#[test]
fn swap_exhaustive_works() {
new_test_ext().execute_with(|| {
let root_add = hypothetically!({
assert_ok!(Club::add_member(RuntimeOrigin::root(), 1));
assert_ok!(Club::promote_member(RuntimeOrigin::root(), 1));
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
// The events mess up the storage root:
System::reset_events();
pezsp_io::storage::root(StateVersion::V1)
});
let root_swap = hypothetically!({
assert_ok!(Club::add_member(RuntimeOrigin::root(), 0));
assert_ok!(Club::promote_member(RuntimeOrigin::root(), 0));
assert_ok!(Salary::init(RuntimeOrigin::signed(0)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(0)));
assert_ok!(Club::exchange_member(RuntimeOrigin::root(), 0, 1));
// The events mess up the storage root:
System::reset_events();
pezsp_io::storage::root(StateVersion::V1)
});
assert_eq!(root_add, root_swap);
// Ensure that we don't compare trivial stuff like `()` from a type error above.
assert_eq!(root_add.len(), 32);
});
}
#[test]
fn swap_bad_noops() {
new_test_ext().execute_with(|| {
assert_ok!(Club::add_member(RuntimeOrigin::root(), 0));
promote_n_times(0, 0);
assert_ok!(Salary::init(RuntimeOrigin::signed(0)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(0)));
assert_ok!(Club::add_member(RuntimeOrigin::root(), 1));
promote_n_times(1, 1);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
// Swapping for another member is a noop:
assert_noop!(
Club::exchange_member(RuntimeOrigin::root(), 0, 1),
pezpallet_ranked_collective::Error::<Test>::AlreadyMember
);
// Swapping for the same member is a noop:
assert_noop!(
Club::exchange_member(RuntimeOrigin::root(), 0, 0),
pezpallet_ranked_collective::Error::<Test>::SameMember
);
});
}
@@ -0,0 +1,23 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![cfg(test)]
//! Unit and integration tests for the salary pallet.
pub(crate) mod integration;
pub(crate) mod unit;
@@ -0,0 +1,637 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! The crate's tests.
use crate as pezpallet_salary;
use crate::*;
use core::cell::RefCell;
use frame::{deps::pezsp_runtime::traits::Identity, testing_prelude::*, traits::tokens::ConvertRank};
use std::collections::BTreeMap;
type Block = MockBlock<Test>;
construct_runtime!(
pub enum Test
{
System: pezframe_system,
Salary: pezpallet_salary,
}
);
parameter_types! {
pub BlockWeights: pezframe_system::limits::BlockWeights =
pezframe_system::limits::BlockWeights::simple_max(Weight::from_parts(1_000_000, 0));
}
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Test {
type Block = Block;
}
thread_local! {
pub static PAID: RefCell<BTreeMap<u64, u64>> = RefCell::new(BTreeMap::new());
pub static STATUS: RefCell<BTreeMap<u64, PaymentStatus>> = RefCell::new(BTreeMap::new());
pub static LAST_ID: RefCell<u64> = RefCell::new(0u64);
}
fn paid(who: u64) -> u64 {
PAID.with(|p| p.borrow().get(&who).cloned().unwrap_or(0))
}
fn unpay(who: u64, amount: u64) {
PAID.with(|p| p.borrow_mut().entry(who).or_default().saturating_reduce(amount))
}
fn set_status(id: u64, s: PaymentStatus) {
STATUS.with(|m| m.borrow_mut().insert(id, s));
}
pub struct TestPay;
impl Pay for TestPay {
type Beneficiary = u64;
type Balance = u64;
type Id = u64;
type AssetKind = ();
type Error = ();
fn pay(
who: &Self::Beneficiary,
_: Self::AssetKind,
amount: Self::Balance,
) -> Result<Self::Id, Self::Error> {
PAID.with(|paid| *paid.borrow_mut().entry(*who).or_default() += amount);
Ok(LAST_ID.with(|lid| {
let x = *lid.borrow();
lid.replace(x + 1);
x
}))
}
fn check_payment(id: Self::Id) -> PaymentStatus {
STATUS.with(|s| s.borrow().get(&id).cloned().unwrap_or(PaymentStatus::Unknown))
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) {}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_concluded(id: Self::Id) {
set_status(id, PaymentStatus::Failure)
}
}
thread_local! {
pub static CLUB: RefCell<BTreeMap<u64, u64>> = RefCell::new(BTreeMap::new());
}
pub struct TestClub;
impl RankedMembers for TestClub {
type AccountId = u64;
type Rank = u64;
fn min_rank() -> Self::Rank {
0
}
fn rank_of(who: &Self::AccountId) -> Option<Self::Rank> {
CLUB.with(|club| club.borrow().get(who).cloned())
}
fn induct(who: &Self::AccountId) -> DispatchResult {
CLUB.with(|club| club.borrow_mut().insert(*who, 0));
Ok(())
}
fn promote(who: &Self::AccountId) -> DispatchResult {
CLUB.with(|club| {
club.borrow_mut().entry(*who).and_modify(|r| *r += 1);
});
Ok(())
}
fn demote(who: &Self::AccountId) -> DispatchResult {
CLUB.with(|club| match club.borrow().get(who) {
None => Err(DispatchError::Unavailable),
Some(&0) => {
club.borrow_mut().remove(&who);
Ok(())
},
Some(_) => {
club.borrow_mut().entry(*who).and_modify(|x| *x -= 1);
Ok(())
},
})
}
}
fn set_rank(who: u64, rank: u64) {
CLUB.with(|club| club.borrow_mut().insert(who, rank));
}
parameter_types! {
pub static Budget: u64 = 10;
}
impl Config for Test {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Paymaster = TestPay;
type Members = TestClub;
type Salary = ConvertRank<Identity>;
type RegistrationPeriod = ConstU64<2>;
type PayoutPeriod = ConstU64<2>;
type Budget = Budget;
}
pub fn new_test_ext() -> TestState {
let t = pezframe_system::GenesisConfig::<Test>::default().build_storage().unwrap();
let mut ext = TestState::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
}
fn next_block() {
System::set_block_number(System::block_number() + 1);
}
#[allow(dead_code)]
fn run_to(n: u64) {
while System::block_number() < n {
next_block();
}
}
#[test]
fn basic_stuff() {
new_test_ext().execute_with(|| {
assert!(Salary::last_active(&0).is_err());
assert_eq!(Salary::status(), None);
});
}
#[test]
fn can_start() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_eq!(
Salary::status(),
Some(StatusType {
cycle_index: 0,
cycle_start: 1,
budget: 10,
total_registrations: 0,
total_unregistered_paid: 0,
})
);
});
}
#[test]
fn bump_works() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
run_to(4);
assert_noop!(Salary::bump(RuntimeOrigin::signed(1)), Error::<Test>::NotYet);
run_to(5);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_eq!(
Salary::status(),
Some(StatusType {
cycle_index: 1,
cycle_start: 5,
budget: 10,
total_registrations: 0,
total_unregistered_paid: 0
})
);
run_to(8);
assert_noop!(Salary::bump(RuntimeOrigin::signed(1)), Error::<Test>::NotYet);
BUDGET.with(|b| b.replace(5));
run_to(9);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_eq!(
Salary::status(),
Some(StatusType {
cycle_index: 2,
cycle_start: 9,
budget: 5,
total_registrations: 0,
total_unregistered_paid: 0
})
);
});
}
#[test]
fn induct_works() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_noop!(Salary::induct(RuntimeOrigin::signed(1)), Error::<Test>::NotMember);
set_rank(1, 1);
assert!(Salary::last_active(&1).is_err());
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
assert_eq!(Salary::last_active(&1).unwrap(), 0);
assert_noop!(Salary::induct(RuntimeOrigin::signed(1)), Error::<Test>::AlreadyInducted);
});
}
#[test]
fn unregistered_payment_works() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_noop!(Salary::induct(RuntimeOrigin::signed(1)), Error::<Test>::NotStarted);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NotInducted);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
// No claim on the cycle active during induction.
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::TooEarly);
run_to(3);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
run_to(6);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::TooEarly);
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
run_to(8);
assert_noop!(Salary::bump(RuntimeOrigin::signed(1)), Error::<Test>::NotYet);
run_to(9);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
run_to(11);
assert_ok!(Salary::payout_other(RuntimeOrigin::signed(1), 10));
assert_eq!(paid(1), 1);
assert_eq!(paid(10), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
});
}
#[test]
fn retry_payment_works() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
run_to(6);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
// Payment failed.
unpay(1, 1);
set_status(0, PaymentStatus::Failure);
assert_eq!(paid(1), 0);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
// Can't just retry.
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
// Check status.
assert_ok!(Salary::check_payment(RuntimeOrigin::signed(1)));
// Allowed to try again.
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
run_to(8);
assert_noop!(Salary::bump(RuntimeOrigin::signed(1)), Error::<Test>::NotYet);
run_to(9);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
run_to(11);
assert_ok!(Salary::payout_other(RuntimeOrigin::signed(1), 10));
assert_eq!(paid(1), 1);
assert_eq!(paid(10), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
});
}
#[test]
fn retry_registered_payment_works() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
run_to(6);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(1)));
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
// Payment failed.
unpay(1, 1);
set_status(0, PaymentStatus::Failure);
assert_eq!(paid(1), 0);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 0);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
// Check status.
assert_ok!(Salary::check_payment(RuntimeOrigin::signed(1)));
// Allowed to try again.
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 0);
});
}
#[test]
fn retry_payment_later_is_not_allowed() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
run_to(6);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
// Payment failed.
unpay(1, 1);
set_status(0, PaymentStatus::Failure);
assert_eq!(paid(1), 0);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
// Can't just retry.
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
// Next cycle.
run_to(9);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
// Payment did fail but now too late to retry.
assert_noop!(Salary::check_payment(RuntimeOrigin::signed(1)), Error::<Test>::NotCurrent);
// We do get this cycle's payout, but we must wait for the payout period to start.
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::TooEarly);
run_to(11);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
});
}
#[test]
fn retry_payment_later_without_bump_is_allowed() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
run_to(6);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
// Payment failed.
unpay(1, 1);
set_status(0, PaymentStatus::Failure);
// Next cycle.
run_to(9);
// Payment did fail but we can still retry as long as we don't `bump`.
assert_ok!(Salary::check_payment(RuntimeOrigin::signed(1)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
});
}
#[test]
fn retry_payment_to_other_works() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
run_to(6);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
run_to(7);
assert_ok!(Salary::payout_other(RuntimeOrigin::signed(1), 10));
// Payment failed.
unpay(10, 1);
set_status(0, PaymentStatus::Failure);
// Can't just retry.
assert_noop!(Salary::payout_other(RuntimeOrigin::signed(1), 10), Error::<Test>::NoClaim);
// Check status.
assert_ok!(Salary::check_payment(RuntimeOrigin::signed(1)));
// Allowed to try again.
assert_ok!(Salary::payout_other(RuntimeOrigin::signed(1), 10));
assert_eq!(paid(10), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
assert_noop!(Salary::payout_other(RuntimeOrigin::signed(1), 10), Error::<Test>::NoClaim);
run_to(8);
assert_noop!(Salary::bump(RuntimeOrigin::signed(1)), Error::<Test>::NotYet);
run_to(9);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
run_to(11);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 1);
assert_eq!(paid(10), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
});
}
#[test]
fn registered_payment_works() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_noop!(Salary::induct(RuntimeOrigin::signed(1)), Error::<Test>::NotStarted);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NotInducted);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
// No claim on the cycle active during induction.
assert_noop!(Salary::register(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
run_to(3);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
run_to(5);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(1)));
assert_eq!(Salary::status().unwrap().total_registrations, 1);
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 0);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::NoClaim);
run_to(9);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_eq!(Salary::status().unwrap().total_registrations, 0);
assert_ok!(Salary::register(RuntimeOrigin::signed(1)));
assert_eq!(Salary::status().unwrap().total_registrations, 1);
run_to(11);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 2);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 0);
});
}
#[test]
fn zero_payment_fails() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
set_rank(1, 0);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
run_to(7);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::ClaimZero);
});
}
#[test]
fn unregistered_bankruptcy_fails_gracefully() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
set_rank(1, 2);
set_rank(2, 6);
set_rank(3, 12);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(2)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(3)));
run_to(7);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(2)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(3)));
assert_eq!(paid(1), 2);
assert_eq!(paid(2), 6);
assert_eq!(paid(3), 2);
});
}
#[test]
fn registered_bankruptcy_fails_gracefully() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
set_rank(1, 2);
set_rank(2, 6);
set_rank(3, 12);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(2)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(3)));
run_to(5);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(2)));
assert_ok!(Salary::register(RuntimeOrigin::signed(3)));
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(2)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(3)));
assert_eq!(paid(1), 1);
assert_eq!(paid(2), 3);
assert_eq!(paid(3), 6);
});
}
#[test]
fn mixed_bankruptcy_fails_gracefully() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
set_rank(1, 2);
set_rank(2, 6);
set_rank(3, 12);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(2)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(3)));
run_to(5);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(2)));
run_to(7);
assert_ok!(Salary::payout(RuntimeOrigin::signed(3)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(2)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
assert_eq!(paid(1), 2);
assert_eq!(paid(2), 6);
assert_eq!(paid(3), 2);
});
}
#[test]
fn other_mixed_bankruptcy_fails_gracefully() {
new_test_ext().execute_with(|| {
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
set_rank(1, 2);
set_rank(2, 6);
set_rank(3, 12);
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(2)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(3)));
run_to(5);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(2)));
assert_ok!(Salary::register(RuntimeOrigin::signed(3)));
run_to(7);
assert_noop!(Salary::payout(RuntimeOrigin::signed(1)), Error::<Test>::ClaimZero);
assert_ok!(Salary::payout(RuntimeOrigin::signed(2)));
assert_ok!(Salary::payout(RuntimeOrigin::signed(3)));
assert_eq!(paid(1), 0);
assert_eq!(paid(2), 3);
assert_eq!(paid(3), 6);
});
}
#[test]
fn stale_registration_from_previous_cycle_works() {
new_test_ext().execute_with(|| {
set_rank(1, 1);
assert_ok!(Salary::init(RuntimeOrigin::signed(1)));
assert_ok!(Salary::induct(RuntimeOrigin::signed(1)));
run_to(5);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_ok!(Salary::register(RuntimeOrigin::signed(1)));
assert_eq!(Salary::status().unwrap().total_registrations, 1);
// Miss the payout window for cycle 1 (don't call payout)
// Start cycle 2 without claiming from cycle 1
run_to(9);
assert_ok!(Salary::bump(RuntimeOrigin::signed(1)));
assert_eq!(Salary::status().unwrap().cycle_index, 2);
assert_eq!(Salary::status().unwrap().total_registrations, 0);
run_to(11);
assert_ok!(Salary::payout(RuntimeOrigin::signed(1)));
// Should get paid from the unregistered pool
assert_eq!(paid(1), 1);
assert_eq!(Salary::status().unwrap().total_unregistered_paid, 1);
});
}
+284
View File
@@ -0,0 +1,284 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Autogenerated weights for `pezpallet_salary`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `4563561839a5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024`
// Executed Command:
// frame-omni-bencher
// v1
// benchmark
// pallet
// --extrinsic=*
// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm
// --pallet=pezpallet_salary
// --header=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/HEADER-APACHE2
// --output=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/pezframe/salary/src/weights.rs
// --wasm-execution=compiled
// --steps=50
// --repeat=20
// --heap-pages=4096
// --template=bizinikiwi/.maintain/frame-umbrella-weight-template.hbs
// --no-storage-info
// --no-min-squares
// --no-median-slopes
// --genesis-builder-policy=none
// --exclude-pallets=pezpallet_xcm,pezpallet_xcm_benchmarks::fungible,pezpallet_xcm_benchmarks::generic,pezpallet_nomination_pools,pezpallet_remark,pezpallet_transaction_storage,pezpallet_election_provider_multi_block,pezpallet_election_provider_multi_block::signed,pezpallet_election_provider_multi_block::unsigned,pezpallet_election_provider_multi_block::verifier
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
#![allow(dead_code)]
use frame::weights_prelude::*;
/// Weight functions needed for `pezpallet_salary`.
pub trait WeightInfo {
fn init() -> Weight;
fn bump() -> Weight;
fn induct() -> Weight;
fn register() -> Weight;
fn payout() -> Weight;
fn payout_other() -> Weight;
fn check_payment() -> Weight;
}
/// Weights for `pezpallet_salary` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
fn init() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `1541`
// Minimum execution time: 5_326_000 picoseconds.
Weight::from_parts(5_563_000, 1541)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
fn bump() -> Weight {
// Proof Size summary in bytes:
// Measured: `26`
// Estimated: `1541`
// Minimum execution time: 6_708_000 picoseconds.
Weight::from_parts(6_971_000, 1541)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `Salary::Status` (r:1 w:0)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
fn induct() -> Weight {
// Proof Size summary in bytes:
// Measured: `177`
// Estimated: `3543`
// Minimum execution time: 14_418_000 picoseconds.
Weight::from_parts(14_844_000, 3543)
.saturating_add(T::DbWeight::get().reads(3_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
fn register() -> Weight {
// Proof Size summary in bytes:
// Measured: `229`
// Estimated: `3543`
// Minimum execution time: 18_333_000 picoseconds.
Weight::from_parts(18_876_000, 3543)
.saturating_add(T::DbWeight::get().reads(3_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
fn payout() -> Weight {
// Proof Size summary in bytes:
// Measured: `229`
// Estimated: `3543`
// Minimum execution time: 60_650_000 picoseconds.
Weight::from_parts(61_965_000, 3543)
.saturating_add(T::DbWeight::get().reads(3_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn payout_other() -> Weight {
// Proof Size summary in bytes:
// Measured: `229`
// Estimated: `3593`
// Minimum execution time: 60_860_000 picoseconds.
Weight::from_parts(61_739_000, 3593)
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().writes(3_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
fn check_payment() -> Weight {
// Proof Size summary in bytes:
// Measured: `95`
// Estimated: `3543`
// Minimum execution time: 9_559_000 picoseconds.
Weight::from_parts(9_936_000, 3543)
.saturating_add(T::DbWeight::get().reads(2_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
fn init() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `1541`
// Minimum execution time: 5_326_000 picoseconds.
Weight::from_parts(5_563_000, 1541)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
fn bump() -> Weight {
// Proof Size summary in bytes:
// Measured: `26`
// Estimated: `1541`
// Minimum execution time: 6_708_000 picoseconds.
Weight::from_parts(6_971_000, 1541)
.saturating_add(RocksDbWeight::get().reads(1_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `Salary::Status` (r:1 w:0)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
fn induct() -> Weight {
// Proof Size summary in bytes:
// Measured: `177`
// Estimated: `3543`
// Minimum execution time: 14_418_000 picoseconds.
Weight::from_parts(14_844_000, 3543)
.saturating_add(RocksDbWeight::get().reads(3_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
fn register() -> Weight {
// Proof Size summary in bytes:
// Measured: `229`
// Estimated: `3543`
// Minimum execution time: 18_333_000 picoseconds.
Weight::from_parts(18_876_000, 3543)
.saturating_add(RocksDbWeight::get().reads(3_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
fn payout() -> Weight {
// Proof Size summary in bytes:
// Measured: `229`
// Estimated: `3543`
// Minimum execution time: 60_650_000 picoseconds.
Weight::from_parts(61_965_000, 3543)
.saturating_add(RocksDbWeight::get().reads(3_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
/// Storage: `RankedCollective::Members` (r:1 w:0)
/// Proof: `RankedCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn payout_other() -> Weight {
// Proof Size summary in bytes:
// Measured: `229`
// Estimated: `3593`
// Minimum execution time: 60_860_000 picoseconds.
Weight::from_parts(61_739_000, 3593)
.saturating_add(RocksDbWeight::get().reads(4_u64))
.saturating_add(RocksDbWeight::get().writes(3_u64))
}
/// Storage: `Salary::Status` (r:1 w:1)
/// Proof: `Salary::Status` (`max_values`: Some(1), `max_size`: Some(56), added: 551, mode: `MaxEncodedLen`)
/// Storage: `Salary::Claimant` (r:1 w:1)
/// Proof: `Salary::Claimant` (`max_values`: None, `max_size`: Some(78), added: 2553, mode: `MaxEncodedLen`)
fn check_payment() -> Weight {
// Proof Size summary in bytes:
// Measured: `95`
// Estimated: `3543`
// Minimum execution time: 9_559_000 picoseconds.
Weight::from_parts(9_936_000, 3543)
.saturating_add(RocksDbWeight::get().reads(2_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
}