#![cfg(feature = "runtime-benchmarks")]
use super::*;
use core::num::NonZeroU16;
use frame_benchmarking::v2::*;
use frame_benchmarking::{account, whitelisted_caller};
use frame_support::pallet_prelude::IsType;
use frame_support::traits::Get;
use frame_support::traits::StoredMap;
use frame_system::RawOrigin;
use pallet_balances::Pallet as Balances;
use sp_runtime::traits::Bounded;
use sp_runtime::traits::Convert;
use crate::Pallet;
const ED_MULTIPLIER: u32 = 10;
#[benchmarks(
where
T: pallet_balances::Config, T::Balance: From<u64>,
<T::Currency as Currency<T::AccountId>>::Balance: IsType<T::Balance>
)]
mod benchmarks {
use super::*;
fn assert_has_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
frame_system::Pallet::<T>::assert_has_event(generic_event.into());
}
#[benchmark]
fn claim_uds(i: Linear<1, { T::MaxPastReeval::get() }>) -> Result<(), BenchmarkError> {
let caller: T::AccountId = T::AccountIdOf::convert(1).unwrap();
CurrentUdIndex::<T>::put(2054u16);
T::MembersStorage::insert(
&caller,
FirstEligibleUd(Some(
NonZeroU16::new(CurrentUdIndex::<T>::get() - i as u16).unwrap(),
)),
)?;
let (_, uds_total) = compute_claim_uds::compute_claim_uds(
CurrentUdIndex::<T>::get(),
CurrentUdIndex::<T>::get() - i as u16,
PastReevals::<T>::get().into_iter(),
);
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
assert_has_event::<T>(
Event::<T>::UdsClaimed {
count: i as u16,
total: uds_total,
who: caller,
}
.into(),
);
Ok(())
}
#[benchmark]
fn transfer_ud() {
let existential_deposit = T::ExistentialDeposit::get();
let caller = whitelisted_caller();
let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into());
let _ = T::Currency::make_free_balance_be(&caller, balance.into());
let recipient: T::AccountId = account("recipient", 0, 1);
let recipient_lookup: <T::Lookup as StaticLookup>::Source =
T::Lookup::unlookup(recipient.clone());
let transfer_amount =
existential_deposit.saturating_mul((ED_MULTIPLIER - 1).into()) + 1u32.into();
let transfer_amount_ud =
transfer_amount.saturating_mul(1_000.into()) / Pallet::<T>::current_ud().into();
#[extrinsic_call]
_(
RawOrigin::Signed(caller.clone()),
recipient_lookup,
transfer_amount_ud.into(),
);
assert_eq!(Balances::<T>::free_balance(&caller), Zero::zero());
assert_eq!(Balances::<T>::free_balance(&recipient), transfer_amount);
}
#[benchmark]
fn transfer_ud_keep_alive() {
let caller = whitelisted_caller();
let recipient: T::AccountId = account("recipient", 0, 1);
let recipient_lookup: <T::Lookup as StaticLookup>::Source =
T::Lookup::unlookup(recipient.clone());
let _ = T::Currency::make_free_balance_be(
&caller,
<T::Currency as Currency<T::AccountId>>::Balance::max_value(),
);
let existential_deposit = T::ExistentialDeposit::get();
let transfer_amount = existential_deposit.saturating_mul(ED_MULTIPLIER.into());
let transfer_amount_ud =
transfer_amount.saturating_mul(1_000.into()) / Pallet::<T>::current_ud().into();
#[extrinsic_call]
_(
RawOrigin::Signed(caller.clone()),
recipient_lookup,
transfer_amount_ud.into(),
);
assert!(!Balances::<T>::free_balance(&caller).is_zero());
assert_eq!(Balances::<T>::free_balance(&recipient), transfer_amount);
}
#[benchmark]
fn on_removed_member(i: Linear<1, { T::MaxPastReeval::get() }>) -> Result<(), BenchmarkError> {
let caller: T::AccountId = T::AccountIdOf::convert(1).unwrap();
CurrentUdIndex::<T>::put(2054u16);
T::MembersStorage::insert(
&caller,
FirstEligibleUd(Some(
NonZeroU16::new(CurrentUdIndex::<T>::get() - i as u16).unwrap(),
)),
)?;
let (_, uds_total) = compute_claim_uds::compute_claim_uds(
CurrentUdIndex::<T>::get(),
CurrentUdIndex::<T>::get() - i as u16,
PastReevals::<T>::get().into_iter(),
);
#[block]
{
Pallet::<T>::on_removed_member(CurrentUdIndex::<T>::get() - i as u16, &caller);
}
if i != 0 {
assert_has_event::<T>(
Event::<T>::UdsAutoPaid {
count: i as u16,
total: uds_total,
who: caller,
}
.into(),
);
}
Ok(())
}
impl_benchmark_test_suite!(
Pallet,
crate::mock::new_test_ext(crate::mock::UniversalDividendConfig {
first_reeval: Some(48_000),
first_ud: Some(6_000),
initial_monetary_mass: 0,
initial_members: vec![1],
ud: 10,
}),
crate::mock::Test
);
}