3139ffa25e
- snowbridge-pezpallet-* → pezsnowbridge-pezpallet-* (201 refs) - pallet/ directories → pezpallet/ (4 locations) - Fixed pezpallet.rs self-include recursion bug - Fixed sc-chain-spec hardcoded crate name in derive macro - Reverted .pezpallet_by_name() to .pallet_by_name() (subxt API) - Added BizinikiwiConfig type alias for zombienet tests - Deleted obsolete session state files Verified: pezsnowbridge-pezpallet-*, pezpallet-staking, pezpallet-staking-async, pezframe-benchmarking-cli all pass cargo check
283 lines
9.6 KiB
Rust
283 lines
9.6 KiB
Rust
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// This file is part of Pezkuwi.
|
|
|
|
// Pezkuwi is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// Pezkuwi is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Pezkuwi. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
//! Benchmarking for auctions pezpallet
|
|
|
|
#![cfg(feature = "runtime-benchmarks")]
|
|
use super::{Pezpallet as Auctions, *};
|
|
use pezframe_support::{
|
|
assert_ok,
|
|
traits::{EnsureOrigin, OnInitialize},
|
|
};
|
|
use pezframe_system::RawOrigin;
|
|
use pezkuwi_runtime_teyrchains::paras;
|
|
use pezsp_runtime::{traits::Bounded, SaturatedConversion};
|
|
|
|
use pezframe_benchmarking::v2::*;
|
|
|
|
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
|
|
let events = pezframe_system::Pezpallet::<T>::events();
|
|
let system_event: <T as pezframe_system::Config>::RuntimeEvent = generic_event.into();
|
|
// compare to the last event record
|
|
let pezframe_system::EventRecord { event, .. } = &events[events.len() - 1];
|
|
assert_eq!(event, &system_event);
|
|
}
|
|
|
|
fn fill_winners<T: Config + paras::Config>(lease_period_index: LeasePeriodOf<T>) {
|
|
let auction_index = AuctionCounter::<T>::get();
|
|
let minimum_balance = CurrencyOf::<T>::minimum_balance();
|
|
|
|
for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 {
|
|
let owner = account("owner", n, 0);
|
|
let worst_validation_code = T::Registrar::worst_validation_code();
|
|
let worst_head_data = T::Registrar::worst_head_data();
|
|
CurrencyOf::<T>::make_free_balance_be(&owner, BalanceOf::<T>::max_value());
|
|
|
|
assert!(T::Registrar::register(
|
|
owner,
|
|
ParaId::from(n),
|
|
worst_head_data,
|
|
worst_validation_code
|
|
)
|
|
.is_ok());
|
|
}
|
|
assert_ok!(paras::Pezpallet::<T>::add_trusted_validation_code(
|
|
pezframe_system::Origin::<T>::Root.into(),
|
|
T::Registrar::worst_validation_code(),
|
|
));
|
|
|
|
T::Registrar::execute_pending_transitions();
|
|
|
|
for n in 1..=SlotRange::SLOT_RANGE_COUNT as u32 {
|
|
let bidder = account("bidder", n, 0);
|
|
CurrencyOf::<T>::make_free_balance_be(&bidder, BalanceOf::<T>::max_value());
|
|
|
|
let slot_range = SlotRange::n((n - 1) as u8).unwrap();
|
|
let (start, end) = slot_range.as_pair();
|
|
|
|
assert!(Auctions::<T>::bid(
|
|
RawOrigin::Signed(bidder).into(),
|
|
ParaId::from(n),
|
|
auction_index,
|
|
lease_period_index + start.into(), // First Slot
|
|
lease_period_index + end.into(), // Last slot
|
|
minimum_balance.saturating_mul(n.into()), // Amount
|
|
)
|
|
.is_ok());
|
|
}
|
|
}
|
|
|
|
#[benchmarks(
|
|
where T: pezpallet_babe::Config + paras::Config,
|
|
)]
|
|
mod benchmarks {
|
|
use super::*;
|
|
|
|
#[benchmark]
|
|
fn new_auction() -> Result<(), BenchmarkError> {
|
|
let duration = BlockNumberFor::<T>::max_value();
|
|
let lease_period_index = LeasePeriodOf::<T>::max_value();
|
|
let origin =
|
|
T::InitiateOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
|
|
|
#[extrinsic_call]
|
|
_(origin as T::RuntimeOrigin, duration, lease_period_index);
|
|
|
|
assert_last_event::<T>(
|
|
Event::<T>::AuctionStarted {
|
|
auction_index: AuctionCounter::<T>::get(),
|
|
lease_period: LeasePeriodOf::<T>::max_value(),
|
|
ending: BlockNumberFor::<T>::max_value(),
|
|
}
|
|
.into(),
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Worst case scenario a new bid comes in which kicks out an existing bid for the same slot.
|
|
#[benchmark]
|
|
fn bid() -> Result<(), BenchmarkError> {
|
|
// If there is an offset, we need to be on that block to be able to do lease things.
|
|
let (_, offset) = T::Leaser::lease_period_length();
|
|
pezframe_system::Pezpallet::<T>::set_block_number(offset + One::one());
|
|
|
|
// Create a new auction
|
|
let duration = BlockNumberFor::<T>::max_value();
|
|
let lease_period_index = LeasePeriodOf::<T>::zero();
|
|
let origin = T::InitiateOrigin::try_successful_origin()
|
|
.expect("InitiateOrigin has no successful origin required for the benchmark");
|
|
Auctions::<T>::new_auction(origin, duration, lease_period_index)?;
|
|
|
|
let para = ParaId::from(0);
|
|
let new_para = ParaId::from(1_u32);
|
|
|
|
// Register the paras
|
|
let owner = account("owner", 0, 0);
|
|
CurrencyOf::<T>::make_free_balance_be(&owner, BalanceOf::<T>::max_value());
|
|
let worst_head_data = T::Registrar::worst_head_data();
|
|
let worst_validation_code = T::Registrar::worst_validation_code();
|
|
T::Registrar::register(
|
|
owner.clone(),
|
|
para,
|
|
worst_head_data.clone(),
|
|
worst_validation_code.clone(),
|
|
)?;
|
|
T::Registrar::register(owner, new_para, worst_head_data, worst_validation_code.clone())?;
|
|
assert_ok!(paras::Pezpallet::<T>::add_trusted_validation_code(
|
|
pezframe_system::Origin::<T>::Root.into(),
|
|
worst_validation_code,
|
|
));
|
|
|
|
T::Registrar::execute_pending_transitions();
|
|
|
|
// Make an existing bid
|
|
let auction_index = AuctionCounter::<T>::get();
|
|
let first_slot = AuctionInfo::<T>::get().unwrap().0;
|
|
let last_slot = first_slot + 3u32.into();
|
|
let first_amount = CurrencyOf::<T>::minimum_balance();
|
|
let first_bidder: T::AccountId = account("first_bidder", 0, 0);
|
|
CurrencyOf::<T>::make_free_balance_be(&first_bidder, BalanceOf::<T>::max_value());
|
|
Auctions::<T>::bid(
|
|
RawOrigin::Signed(first_bidder.clone()).into(),
|
|
para,
|
|
auction_index,
|
|
first_slot,
|
|
last_slot,
|
|
first_amount,
|
|
)?;
|
|
|
|
let caller: T::AccountId = whitelisted_caller();
|
|
CurrencyOf::<T>::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
|
|
let bigger_amount = CurrencyOf::<T>::minimum_balance().saturating_mul(10u32.into());
|
|
assert_eq!(CurrencyOf::<T>::reserved_balance(&first_bidder), first_amount);
|
|
|
|
#[extrinsic_call]
|
|
_(
|
|
RawOrigin::Signed(caller.clone()),
|
|
new_para,
|
|
auction_index,
|
|
first_slot,
|
|
last_slot,
|
|
bigger_amount,
|
|
);
|
|
|
|
// Confirms that we unreserved funds from a previous bidder, which is worst case
|
|
// scenario.
|
|
assert_eq!(CurrencyOf::<T>::reserved_balance(&caller), bigger_amount);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Worst case: 10 bidders taking all wining spots, and we need to calculate the winner for
|
|
// auction end. Entire winner map should be full and removed at the end of the benchmark.
|
|
#[benchmark]
|
|
fn on_initialize() -> Result<(), BenchmarkError> {
|
|
// If there is an offset, we need to be on that block to be able to do lease things.
|
|
let (lease_length, offset) = T::Leaser::lease_period_length();
|
|
pezframe_system::Pezpallet::<T>::set_block_number(offset + One::one());
|
|
|
|
// Create a new auction
|
|
let duration: BlockNumberFor<T> = lease_length / 2u32.into();
|
|
let lease_period_index = LeasePeriodOf::<T>::zero();
|
|
let now = pezframe_system::Pezpallet::<T>::block_number();
|
|
let origin = T::InitiateOrigin::try_successful_origin()
|
|
.expect("InitiateOrigin has no successful origin required for the benchmark");
|
|
Auctions::<T>::new_auction(origin, duration, lease_period_index)?;
|
|
|
|
fill_winners::<T>(lease_period_index);
|
|
|
|
for winner in Winning::<T>::get(BlockNumberFor::<T>::from(0u32)).unwrap().iter() {
|
|
assert!(winner.is_some());
|
|
}
|
|
|
|
let winning_data = Winning::<T>::get(BlockNumberFor::<T>::from(0u32)).unwrap();
|
|
// Make winning map full
|
|
for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() {
|
|
Winning::<T>::insert(BlockNumberFor::<T>::from(i), winning_data.clone());
|
|
}
|
|
|
|
// Move ahead to the block we want to initialize
|
|
pezframe_system::Pezpallet::<T>::set_block_number(duration + now + T::EndingPeriod::get());
|
|
|
|
// Trigger epoch change for new random number value:
|
|
{
|
|
pezpallet_babe::EpochStart::<T>::set((Zero::zero(), u32::MAX.into()));
|
|
pezpallet_babe::Pezpallet::<T>::on_initialize(duration + now + T::EndingPeriod::get());
|
|
let authorities = pezpallet_babe::Pezpallet::<T>::authorities();
|
|
// Check for non empty authority set since it otherwise emits a No-OP warning.
|
|
if !authorities.is_empty() {
|
|
pezpallet_babe::Pezpallet::<T>::enact_epoch_change(
|
|
authorities.clone(),
|
|
authorities,
|
|
None,
|
|
);
|
|
}
|
|
}
|
|
|
|
#[block]
|
|
{
|
|
Auctions::<T>::on_initialize(duration + now + T::EndingPeriod::get());
|
|
}
|
|
|
|
let auction_index = AuctionCounter::<T>::get();
|
|
assert_last_event::<T>(Event::<T>::AuctionClosed { auction_index }.into());
|
|
assert!(Winning::<T>::iter().count().is_zero());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Worst case: 10 bidders taking all wining spots, and winning data is full.
|
|
#[benchmark]
|
|
fn cancel_auction() -> Result<(), BenchmarkError> {
|
|
// If there is an offset, we need to be on that block to be able to do lease things.
|
|
let (lease_length, offset) = T::Leaser::lease_period_length();
|
|
pezframe_system::Pezpallet::<T>::set_block_number(offset + One::one());
|
|
|
|
// Create a new auction
|
|
let duration: BlockNumberFor<T> = lease_length / 2u32.into();
|
|
let lease_period_index = LeasePeriodOf::<T>::zero();
|
|
let origin = T::InitiateOrigin::try_successful_origin()
|
|
.expect("InitiateOrigin has no successful origin required for the benchmark");
|
|
Auctions::<T>::new_auction(origin, duration, lease_period_index)?;
|
|
|
|
fill_winners::<T>(lease_period_index);
|
|
|
|
let winning_data = Winning::<T>::get(BlockNumberFor::<T>::from(0u32)).unwrap();
|
|
for winner in winning_data.iter() {
|
|
assert!(winner.is_some());
|
|
}
|
|
|
|
// Make winning map full
|
|
for i in 0u32..(T::EndingPeriod::get() / T::SampleLength::get()).saturated_into() {
|
|
Winning::<T>::insert(BlockNumberFor::<T>::from(i), winning_data.clone());
|
|
}
|
|
assert!(AuctionInfo::<T>::get().is_some());
|
|
|
|
#[extrinsic_call]
|
|
_(RawOrigin::Root);
|
|
|
|
assert!(AuctionInfo::<T>::get().is_none());
|
|
Ok(())
|
|
}
|
|
|
|
impl_benchmark_test_suite!(
|
|
Auctions,
|
|
crate::integration_tests::new_test_ext(),
|
|
crate::integration_tests::Test,
|
|
);
|
|
}
|