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
@@ -0,0 +1,211 @@
// 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.
//! Benchmarking for pezpallet-fast-unstake.
#![cfg(feature = "runtime-benchmarks")]
use crate::{types::*, *};
use alloc::vec::Vec;
use pezframe_benchmarking::v2::*;
use pezframe_support::{
assert_ok,
traits::{Currency, EnsureOrigin, Get, Hooks},
};
use pezframe_system::RawOrigin;
use pezsp_runtime::traits::Zero;
use pezsp_staking::{EraIndex, StakingInterface};
const USER_SEED: u32 = 0;
type CurrencyOf<T> = <T as Config>::Currency;
fn create_unexposed_batch<T: Config>(batch_size: u32) -> Vec<T::AccountId> {
(0..batch_size)
.map(|i| {
let account =
pezframe_benchmarking::account::<T::AccountId>("unexposed_nominator", i, USER_SEED);
fund_and_bond_account::<T>(&account);
account
})
.collect()
}
fn fund_and_bond_account<T: Config>(account: &T::AccountId) {
let stake = CurrencyOf::<T>::minimum_balance() * 100u32.into();
CurrencyOf::<T>::make_free_balance_be(&account, stake * 100u32.into());
// bond without nominating - fast-unstake works with non-nominating bonded accounts.
// Note that if we want to nominate a validator, we must first create a valid one; otherwise,
// `nominate()` will fail with a BadTarget error. However, fast-unstaking is intended for
// accounts that are bonded but not actively nominating, making this an unnecessary complication
// for our needs.
assert_ok!(T::Staking::bond(account, stake, account));
}
pub(crate) fn fast_unstake_events<T: Config>() -> Vec<crate::Event<T>> {
pezframe_system::Pallet::<T>::events()
.into_iter()
.map(|r| r.event)
.filter_map(|e| <T as Config>::RuntimeEvent::from(e).try_into().ok())
.collect::<Vec<_>>()
}
fn setup_staking<T: Config>(v: u32, until: EraIndex) {
let ed = CurrencyOf::<T>::minimum_balance();
log!(debug, "registering {} validators and {} eras.", v, until);
// our validators don't actually need to registered in staking -- just generate `v` random
// accounts.
let validators = (0..v)
.map(|x| pezframe_benchmarking::account::<T::AccountId>("validator", x, USER_SEED))
.collect::<Vec<_>>();
for era in 0..=until {
let others = (0..T::Staking::max_exposure_page_size())
.map(|s| {
let who = pezframe_benchmarking::account::<T::AccountId>("nominator", era, s.into());
let value = ed;
(who, value)
})
.collect::<Vec<_>>();
validators.iter().for_each(|v| {
T::Staking::add_era_stakers(&era, &v, others.clone());
});
}
}
fn on_idle_full_block<T: Config>() {
let remaining_weight = <T as pezframe_system::Config>::BlockWeights::get().max_block;
Pallet::<T>::on_idle(Zero::zero(), remaining_weight);
}
#[benchmarks]
mod benchmarks {
use super::*;
// on_idle, we don't check anyone, but fully unbond them.
#[benchmark]
fn on_idle_unstake(b: Linear<1, { T::BatchSize::get() }>) {
ErasToCheckPerBlock::<T>::put(1);
for who in create_unexposed_batch::<T>(b).into_iter() {
assert_ok!(Pallet::<T>::register_fast_unstake(RawOrigin::Signed(who.clone()).into(),));
}
// Run on_idle once. This will check era 0.
assert_eq!(Head::<T>::get(), None);
on_idle_full_block::<T>();
assert!(matches!(
Head::<T>::get(),
Some(UnstakeRequest {
checked,
stashes,
..
}) if checked.len() == 1 && stashes.len() as u32 == b
));
#[block]
{
on_idle_full_block::<T>();
}
assert_eq!(fast_unstake_events::<T>().last(), Some(&Event::BatchFinished { size: b }));
}
#[benchmark]
fn on_idle_check(v: Linear<1, 256>, b: Linear<1, { T::BatchSize::get() }>) {
// on_idle: When we check some number of eras and the queue is already set.
let u = T::MaxErasToCheckPerBlock::get().min(T::Staking::bonding_duration());
ErasToCheckPerBlock::<T>::put(u);
T::Staking::set_current_era(u);
// setup staking with v validators and u eras of data (0..=u+1)
setup_staking::<T>(v, u);
let stashes = create_unexposed_batch::<T>(b)
.into_iter()
.map(|s| {
assert_ok!(
Pallet::<T>::register_fast_unstake(RawOrigin::Signed(s.clone()).into(),)
);
(s, T::Deposit::get())
})
.collect::<Vec<_>>();
// no one is queued thus far.
assert_eq!(Head::<T>::get(), None);
Head::<T>::put(UnstakeRequest {
stashes: stashes.clone().try_into().unwrap(),
checked: Default::default(),
});
#[block]
{
on_idle_full_block::<T>();
}
let checked = (1..=u).rev().collect::<Vec<EraIndex>>();
let request = Head::<T>::get().unwrap();
assert_eq!(checked, request.checked.into_inner());
assert!(matches!(fast_unstake_events::<T>().last(), Some(Event::BatchChecked { .. })));
assert!(stashes.iter().all(|(s, _)| request.stashes.iter().any(|(ss, _)| ss == s)));
}
#[benchmark]
fn register_fast_unstake() {
ErasToCheckPerBlock::<T>::put(1);
let who = create_unexposed_batch::<T>(1).get(0).cloned().unwrap();
whitelist_account!(who);
assert_eq!(Queue::<T>::count(), 0);
#[extrinsic_call]
_(RawOrigin::Signed(who.clone()));
assert_eq!(Queue::<T>::count(), 1);
}
#[benchmark]
fn deregister() {
ErasToCheckPerBlock::<T>::put(1);
let who = create_unexposed_batch::<T>(1).get(0).cloned().unwrap();
assert_ok!(Pallet::<T>::register_fast_unstake(RawOrigin::Signed(who.clone()).into(),));
assert_eq!(Queue::<T>::count(), 1);
whitelist_account!(who);
#[extrinsic_call]
_(RawOrigin::Signed(who.clone()));
assert_eq!(Queue::<T>::count(), 0);
}
#[benchmark]
fn control() -> Result<(), BenchmarkError> {
let origin = <T as Config>::ControlOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
#[extrinsic_call]
_(origin as T::RuntimeOrigin, T::MaxErasToCheckPerBlock::get());
Ok(())
}
impl_benchmark_test_suite!(Pallet, mock::ExtBuilder::default().build(), mock::Runtime);
}
+630
View File
@@ -0,0 +1,630 @@
// 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.
//! > Made with *Bizinikiwi*, for *Pezkuwi*.
//!
//! [![github]](https://github.com/pezkuwichain/pezkuwi-sdk/tree/master/bizinikiwi/pezframe/fast-unstake) -
//! [![pezkuwi]](https://pezkuwichain.io)
//!
//! [pezkuwi]: https://img.shields.io/badge/polkadot-E6007A?style=for-the-badge&logo=polkadot&logoColor=white
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//!
//! # Fast Unstake Pallet
//!
//! A pallet to allow participants of the staking system (represented by [`Config::Staking`], being
//! [`StakingInterface`]) to unstake quicker, if and only if they meet the condition of not being
//! exposed to any slashes.
//!
//! ## Overview
//!
//! If a nominator is not exposed anywhere in the staking system, checked via
//! [`StakingInterface::is_exposed_in_era`] (i.e. "has not actively backed any validators in the
//! last [`StakingInterface::bonding_duration`] days"), then they can register themselves in this
//! pallet and unstake faster than having to wait an entire bonding duration.
//!
//! *Being exposed with validator* from the point of view of the staking system means earning
//! rewards with the validator, and also being at the risk of slashing with the validator. This is
//! equivalent to the "Active Nominator" role explained in
//! [here](https://pezkuwichain.io/blog/staking-update-february-2022/).
//!
//! Stakers who are certain about NOT being exposed can register themselves with
//! [`Pallet::register_fast_unstake`]. This will chill, fully unbond the staker and place them
//! in the queue to be checked.
//!
//! A successful registration implies being fully unbonded and chilled in the staking system. These
//! effects persist even if the fast-unstake registration is retracted (see [`Pallet::deregister`]
//! and further).
//!
//! Once registered as a fast-unstaker, the staker will be queued and checked by the system. This
//! can take a variable number of blocks based on demand, but will almost certainly be "faster" (as
//! the name suggest) than waiting the standard bonding duration.
//!
//! A fast-unstaker is either in [`Queue`] or actively being checked, at which point it lives in
//! [`Head`]. Once in [`Head`], the request cannot be retracted anymore. But, once in [`Queue`], it
//! can, via [`Pallet::deregister`].
//!
//! A deposit equal to [`Config::Deposit`] is collected for this process, and is returned in case a
//! successful unstake occurs (`Event::Unstaked` signals that).
//!
//! Once processed, if successful, no additional fee for the checking process is taken, and the
//! staker is instantly unbonded.
//!
//! If unsuccessful, meaning that the staker was exposed, the aforementioned deposit will be slashed
//! for the amount of wasted work they have inflicted on the chain.
//!
//! All in all, this pallet is meant to provide an easy off-ramp for some stakers.
//!
//! ### Example
//!
//! 1. Fast-unstake with multiple participants in the queue.
#![doc = docify::embed!("src/tests.rs", successful_multi_queue)]
//!
//! 2. Fast unstake failing because a nominator is exposed.
#![doc = docify::embed!("src/tests.rs", exposed_nominator_cannot_unstake)]
//!
//! ## Pallet API
//!
//! See the [`pallet`] module for more information about the interfaces this pallet exposes,
//! including its configuration trait, dispatchables, storage items, events and errors.
//!
//! ## Low Level / Implementation Details
//!
//! This pallet works off the basis of `on_idle`, meaning that it provides no guarantee about when
//! it will succeed, if at all. Moreover, the queue implementation is unordered. In case of
//! congestion, no FIFO ordering is provided.
//!
//! A few important considerations can be concluded based on the `on_idle`-based implementation:
//!
//! * It is crucial for the weights of this pallet to be correct. The code inside
//! [`Pallet::on_idle`] MUST be able to measure itself and report the remaining weight correctly
//! after execution.
//!
//! * If the weight measurement is incorrect, it can lead to perpetual overweight (consequently
//! slow) blocks.
//!
//! * The amount of weight that `on_idle` consumes is a direct function of [`ErasToCheckPerBlock`].
//!
//! * Thus, a correct value of [`ErasToCheckPerBlock`] (which can be set via [`Pallet::control`])
//! should be chosen, such that a reasonable amount of weight is used `on_idle`. If
//! [`ErasToCheckPerBlock`] is too large, `on_idle` will always conclude that it has not enough
//! weight to proceed, and will early-return. Nonetheless, this should also be *safe* as long as
//! the benchmarking/weights are *accurate*.
//!
//! * See the inline code-comments on `do_on_idle` (private) for more details.
//!
//! * For further safety, in case of any unforeseen errors, the pallet will emit
//! [`Event::InternalError`] and set [`ErasToCheckPerBlock`] back to 0, which essentially means
//! the pallet will halt/disable itself.
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
pub use pallet::*;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
// NOTE: enable benchmarking in tests as well.
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
pub mod migrations;
pub mod types;
pub mod weights;
// some extra imports for docs to link properly.
#[cfg(doc)]
pub use pezframe_support::traits::Hooks;
#[cfg(doc)]
pub use pezsp_staking::StakingInterface;
/// The logging target of this pallet.
pub const LOG_TARGET: &'static str = "runtime::fast-unstake";
#[macro_export]
macro_rules! log {
($level:tt, $patter:expr $(, $values:expr)* $(,)?) => {
log::$level!(
target: crate::LOG_TARGET,
concat!("[{:?}] 💨 ", $patter), pezframe_system::Pallet::<T>::block_number() $(, $values)*
)
};
}
#[pezframe_support::pallet]
pub mod pallet {
use super::*;
use crate::types::*;
use alloc::vec::Vec;
use pezframe_support::{
pezpallet_prelude::*,
traits::{Defensive, ReservableCurrency, StorageVersion},
};
use pezframe_system::pezpallet_prelude::*;
use pezsp_runtime::{traits::Zero, DispatchResult};
use pezsp_staking::{EraIndex, StakingInterface};
pub use weights::WeightInfo;
#[cfg(feature = "try-runtime")]
use pezsp_runtime::TryRuntimeError;
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(_);
#[pallet::config]
pub trait Config: pezframe_system::Config {
/// The overarching event type.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>>
+ IsType<<Self as pezframe_system::Config>::RuntimeEvent>
+ TryInto<Event<Self>>;
/// The currency used for deposits.
type Currency: ReservableCurrency<Self::AccountId>;
/// Deposit to take for unstaking, to make sure we're able to slash the it in order to cover
/// the costs of resources on unsuccessful unstake.
#[pallet::constant]
type Deposit: Get<BalanceOf<Self>>;
/// The origin that can control this pallet, in other words invoke [`Pallet::control`].
type ControlOrigin: pezframe_support::traits::EnsureOrigin<Self::RuntimeOrigin>;
/// Batch size.
///
/// This many stashes are processed in each unstake request.
type BatchSize: Get<u32>;
/// The access to staking functionality.
type Staking: StakingInterface<Balance = BalanceOf<Self>, AccountId = Self::AccountId>;
/// Maximum value for `ErasToCheckPerBlock`, checked in [`Pallet::control`].
///
/// This should be slightly bigger than the actual value in order to have accurate
/// benchmarks.
type MaxErasToCheckPerBlock: Get<u32>;
/// The weight information of this pallet.
type WeightInfo: WeightInfo;
}
/// The current "head of the queue" being unstaked.
///
/// The head in itself can be a batch of up to [`Config::BatchSize`] stakers.
#[pallet::storage]
pub type Head<T: Config> = StorageValue<_, UnstakeRequest<T>, OptionQuery>;
/// The map of all accounts wishing to be unstaked.
///
/// Keeps track of `AccountId` wishing to unstake and it's corresponding deposit.
// Hasher: Twox safe since `AccountId` is a secure hash.
#[pallet::storage]
pub type Queue<T: Config> = CountedStorageMap<_, Twox64Concat, T::AccountId, BalanceOf<T>>;
/// Number of eras to check per block.
///
/// If set to 0, this pallet does absolutely nothing. Cannot be set to more than
/// [`Config::MaxErasToCheckPerBlock`].
///
/// Based on the amount of weight available at [`Pallet::on_idle`], up to this many eras are
/// checked. The checking is represented by updating [`UnstakeRequest::checked`], which is
/// stored in [`Head`].
#[pallet::storage]
pub type ErasToCheckPerBlock<T: Config> = StorageValue<_, u32, ValueQuery>;
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// A staker was unstaked.
Unstaked { stash: T::AccountId, result: DispatchResult },
/// A staker was slashed for requesting fast-unstake whilst being exposed.
Slashed { stash: T::AccountId, amount: BalanceOf<T> },
/// A batch was partially checked for the given eras, but the process did not finish.
BatchChecked { eras: Vec<EraIndex> },
/// A batch of a given size was terminated.
///
/// This is always follows by a number of `Unstaked` or `Slashed` events, marking the end
/// of the batch. A new batch will be created upon next block.
BatchFinished { size: u32 },
/// An internal error happened. Operations will be paused now.
InternalError,
}
#[pallet::error]
#[cfg_attr(test, derive(PartialEq))]
pub enum Error<T> {
/// The provided Controller account was not found.
///
/// This means that the given account is not bonded.
NotController,
/// The bonded account has already been queued.
AlreadyQueued,
/// The bonded account has active unlocking chunks.
NotFullyBonded,
/// The provided un-staker is not in the `Queue`.
NotQueued,
/// The provided un-staker is already in Head, and cannot deregister.
AlreadyHead,
/// The call is not allowed at this point because the pallet is not active.
CallNotAllowed,
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_idle(_: BlockNumberFor<T>, remaining_weight: Weight) -> Weight {
if remaining_weight.any_lt(T::DbWeight::get().reads(2)) {
return Weight::from_parts(0, 0);
}
Self::do_on_idle(remaining_weight)
}
fn integrity_test() {
// Ensure that the value of `ErasToCheckPerBlock` is less or equal to
// `T::MaxErasToCheckPerBlock`.
assert!(
ErasToCheckPerBlock::<T>::get() <= T::MaxErasToCheckPerBlock::get(),
"the value of `ErasToCheckPerBlock` is greater than `T::MaxErasToCheckPerBlock`",
);
}
#[cfg(feature = "try-runtime")]
fn try_state(_n: BlockNumberFor<T>) -> Result<(), TryRuntimeError> {
// ensure that the value of `ErasToCheckPerBlock` is less than
// `T::MaxErasToCheckPerBlock`.
ensure!(
ErasToCheckPerBlock::<T>::get() <= T::MaxErasToCheckPerBlock::get(),
"the value of `ErasToCheckPerBlock` is greater than `T::MaxErasToCheckPerBlock`",
);
Ok(())
}
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Register oneself for fast-unstake.
///
/// ## Dispatch Origin
///
/// The dispatch origin of this call must be *signed* by whoever is permitted to call
/// unbond funds by the staking system. See [`Config::Staking`].
///
/// ## Details
///
/// The stash associated with the origin must have no ongoing unlocking chunks. If
/// successful, this will fully unbond and chill the stash. Then, it will enqueue the stash
/// to be checked in further blocks.
///
/// If by the time this is called, the stash is actually eligible for fast-unstake, then
/// they are guaranteed to remain eligible, because the call will chill them as well.
///
/// If the check works, the entire staking data is removed, i.e. the stash is fully
/// unstaked.
///
/// If the check fails, the stash remains chilled and waiting for being unbonded as in with
/// the normal staking system, but they lose part of their unbonding chunks due to consuming
/// the chain's resources.
///
/// ## Events
///
/// Some events from the staking and currency system might be emitted.
#[pallet::call_index(0)]
#[pallet::weight(<T as Config>::WeightInfo::register_fast_unstake())]
pub fn register_fast_unstake(origin: OriginFor<T>) -> DispatchResult {
let ctrl = ensure_signed(origin)?;
ensure!(ErasToCheckPerBlock::<T>::get() != 0, Error::<T>::CallNotAllowed);
let stash_account =
T::Staking::stash_by_ctrl(&ctrl).map_err(|_| Error::<T>::NotController)?;
ensure!(!Queue::<T>::contains_key(&stash_account), Error::<T>::AlreadyQueued);
ensure!(!Self::is_head(&stash_account), Error::<T>::AlreadyHead);
ensure!(!T::Staking::is_unbonding(&stash_account)?, Error::<T>::NotFullyBonded);
// chill and fully unstake.
T::Staking::chill(&stash_account)?;
T::Staking::fully_unbond(&stash_account)?;
T::Currency::reserve(&stash_account, T::Deposit::get())?;
// enqueue them.
Queue::<T>::insert(stash_account, T::Deposit::get());
Ok(())
}
/// Deregister oneself from the fast-unstake.
///
/// ## Dispatch Origin
///
/// The dispatch origin of this call must be *signed* by whoever is permitted to call
/// unbond funds by the staking system. See [`Config::Staking`].
///
/// ## Details
///
/// This is useful if one is registered, they are still waiting, and they change their mind.
///
/// Note that the associated stash is still fully unbonded and chilled as a consequence of
/// calling [`Pallet::register_fast_unstake`]. Therefore, this should probably be followed
/// by a call to `rebond` in the staking system.
///
/// ## Events
///
/// Some events from the staking and currency system might be emitted.
#[pallet::call_index(1)]
#[pallet::weight(<T as Config>::WeightInfo::deregister())]
pub fn deregister(origin: OriginFor<T>) -> DispatchResult {
let ctrl = ensure_signed(origin)?;
ensure!(ErasToCheckPerBlock::<T>::get() != 0, Error::<T>::CallNotAllowed);
let stash_account =
T::Staking::stash_by_ctrl(&ctrl).map_err(|_| Error::<T>::NotController)?;
ensure!(Queue::<T>::contains_key(&stash_account), Error::<T>::NotQueued);
ensure!(!Self::is_head(&stash_account), Error::<T>::AlreadyHead);
let deposit = Queue::<T>::take(stash_account.clone());
if let Some(deposit) = deposit.defensive() {
let remaining = T::Currency::unreserve(&stash_account, deposit);
if !remaining.is_zero() {
Self::halt("not enough balance to unreserve");
}
}
Ok(())
}
/// Control the operation of this pallet.
///
/// ## Dispatch Origin
///
/// The dispatch origin of this call must be [`Config::ControlOrigin`].
///
/// ## Details
///
/// Can set the number of eras to check per block, and potentially other admin work.
///
/// ## Events
///
/// No events are emitted from this dispatch.
#[pallet::call_index(2)]
#[pallet::weight(<T as Config>::WeightInfo::control())]
pub fn control(origin: OriginFor<T>, eras_to_check: EraIndex) -> DispatchResult {
T::ControlOrigin::ensure_origin(origin)?;
ensure!(eras_to_check <= T::MaxErasToCheckPerBlock::get(), Error::<T>::CallNotAllowed);
ErasToCheckPerBlock::<T>::put(eras_to_check);
Ok(())
}
}
impl<T: Config> Pallet<T> {
/// Returns `true` if `staker` is anywhere to be found in the `head`.
pub(crate) fn is_head(staker: &T::AccountId) -> bool {
Head::<T>::get().map_or(false, |UnstakeRequest { stashes, .. }| {
stashes.iter().any(|(stash, _)| stash == staker)
})
}
/// Halt the operations of this pallet.
pub(crate) fn halt(reason: &'static str) {
pezframe_support::defensive!(reason);
ErasToCheckPerBlock::<T>::put(0);
Self::deposit_event(Event::<T>::InternalError)
}
/// process up to `remaining_weight`.
///
/// Returns the actual weight consumed.
///
/// Written for readability in mind, not efficiency. For example:
///
/// 1. We assume this is only ever called once per `on_idle`. This is because we know that
/// in all use cases, even a single nominator cannot be unbonded in a single call. Multiple
/// calls to this function are thus not needed.
///
/// 2. We will only mark a staker as unstaked if at the beginning of a check cycle, they are
/// found out to have no eras to check. At the end of a check cycle, even if they are fully
/// checked, we don't finish the process.
pub(crate) fn do_on_idle(remaining_weight: Weight) -> Weight {
// any weight that is unaccounted for
let mut unaccounted_weight = Weight::from_parts(0, 0);
let eras_to_check_per_block = ErasToCheckPerBlock::<T>::get();
if eras_to_check_per_block.is_zero() {
return T::DbWeight::get().reads(1).saturating_add(unaccounted_weight);
}
// NOTE: here we're assuming that the number of validators has only ever increased,
// meaning that the number of exposures to check is either this per era, or less.
let validator_count = T::Staking::desired_validator_count();
let (next_batch_size, reads_from_queue) = Head::<T>::get()
.map_or((Queue::<T>::count().min(T::BatchSize::get()), true), |head| {
(head.stashes.len() as u32, false)
});
// determine the number of eras to check. This is based on both `ErasToCheckPerBlock`
// and `remaining_weight` passed on to us from the runtime executive.
let max_weight = |v, b| {
// NOTE: this potentially under-counts by up to `BatchSize` reads from the queue.
<T as Config>::WeightInfo::on_idle_check(v, b)
.max(<T as Config>::WeightInfo::on_idle_unstake(b))
.saturating_add(if reads_from_queue {
T::DbWeight::get().reads(next_batch_size.into())
} else {
Zero::zero()
})
};
if max_weight(validator_count, next_batch_size).any_gt(remaining_weight) {
log!(debug, "early exit because eras_to_check_per_block is zero");
return T::DbWeight::get().reads(3).saturating_add(unaccounted_weight);
}
if T::Staking::election_ongoing() {
// NOTE: we assume `ongoing` does not consume any weight.
// there is an ongoing election -- we better not do anything. Imagine someone is not
// exposed anywhere in the last era, and the snapshot for the election is already
// taken. In this time period, we don't want to accidentally unstake them.
return T::DbWeight::get().reads(4).saturating_add(unaccounted_weight);
}
let UnstakeRequest { stashes, mut checked } = match Head::<T>::take().or_else(|| {
// NOTE: there is no order guarantees in `Queue`.
let stashes: BoundedVec<_, T::BatchSize> = Queue::<T>::drain()
.take(T::BatchSize::get() as usize)
.collect::<Vec<_>>()
.try_into()
.expect("take ensures bound is met; qed");
unaccounted_weight.saturating_accrue(
T::DbWeight::get().reads_writes(stashes.len() as u64, stashes.len() as u64),
);
if stashes.is_empty() {
None
} else {
Some(UnstakeRequest { stashes, checked: Default::default() })
}
}) {
None => {
// There's no `Head` and nothing in the `Queue`, nothing to do here.
return T::DbWeight::get().reads(4);
},
Some(head) => head,
};
log!(
debug,
"checking {:?} stashes, eras_to_check_per_block = {:?}, checked {:?}, remaining_weight = {:?}",
stashes.len(),
eras_to_check_per_block,
checked,
remaining_weight,
);
// the range that we're allowed to check in this round.
let current_era = T::Staking::current_era();
let bonding_duration = T::Staking::bonding_duration();
// prune all the old eras that we don't care about. This will help us keep the bound
// of `checked`.
checked.retain(|e| *e >= current_era.saturating_sub(bonding_duration));
let unchecked_eras_to_check = {
// get the last available `bonding_duration` eras up to current era in reverse
// order.
let total_check_range = (current_era.saturating_sub(bonding_duration)..=
current_era)
.rev()
.collect::<Vec<_>>();
debug_assert!(
total_check_range.len() <= (bonding_duration + 1) as usize,
"{:?}",
total_check_range
);
// remove eras that have already been checked, take a maximum of
// eras_to_check_per_block.
total_check_range
.into_iter()
.filter(|e| !checked.contains(e))
.take(eras_to_check_per_block as usize)
.collect::<Vec<_>>()
};
log!(
debug,
"{} eras to check: {:?}",
unchecked_eras_to_check.len(),
unchecked_eras_to_check
);
let unstake_stash = |stash: T::AccountId, deposit| {
let result = T::Staking::force_unstake(stash.clone());
let remaining = T::Currency::unreserve(&stash, deposit);
if !remaining.is_zero() {
Self::halt("not enough balance to unreserve");
} else {
log!(debug, "unstaked {:?}, outcome: {:?}", stash, result);
Self::deposit_event(Event::<T>::Unstaked { stash, result });
}
};
let check_stash = |stash, deposit| {
let is_exposed = unchecked_eras_to_check
.iter()
.any(|e| T::Staking::is_exposed_in_era(&stash, e));
if is_exposed {
let _ = T::Currency::slash_reserved(&stash, deposit);
log!(info, "slashed {:?} by {:?}", stash, deposit);
Self::deposit_event(Event::<T>::Slashed { stash, amount: deposit });
false
} else {
true
}
};
if unchecked_eras_to_check.is_empty() {
// `stashes` are not exposed in any era now -- we can let go of them now.
let size = stashes.len() as u32;
stashes.into_iter().for_each(|(stash, deposit)| unstake_stash(stash, deposit));
Self::deposit_event(Event::<T>::BatchFinished { size });
<T as Config>::WeightInfo::on_idle_unstake(size).saturating_add(unaccounted_weight)
} else {
let pre_length = stashes.len();
let stashes: BoundedVec<(T::AccountId, BalanceOf<T>), T::BatchSize> = stashes
.into_iter()
.filter(|(stash, deposit)| check_stash(stash.clone(), *deposit))
.collect::<Vec<_>>()
.try_into()
.expect("filter can only lessen the length; still in bound; qed");
let post_length = stashes.len();
log!(
debug,
"checked {:?}, pre stashes: {:?}, post: {:?}",
unchecked_eras_to_check,
pre_length,
post_length,
);
match checked.try_extend(unchecked_eras_to_check.clone().into_iter()) {
Ok(_) =>
if stashes.is_empty() {
Self::deposit_event(Event::<T>::BatchFinished { size: 0 });
} else {
Head::<T>::put(UnstakeRequest { stashes, checked });
Self::deposit_event(Event::<T>::BatchChecked {
eras: unchecked_eras_to_check,
});
},
Err(_) => {
// don't put the head back in -- there is an internal error in the pallet.
Self::halt("checked is pruned via retain above")
},
}
<T as Config>::WeightInfo::on_idle_check(validator_count, pre_length as u32)
.saturating_add(unaccounted_weight)
}
}
}
}
@@ -0,0 +1,90 @@
// 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.
pub mod v1 {
use crate::{types::BalanceOf, *};
use alloc::vec::Vec;
use pezframe_support::{
storage::unhashed,
traits::{Defensive, Get, GetStorageVersion, OnRuntimeUpgrade},
weights::Weight,
};
use pezsp_staking::EraIndex;
#[cfg(feature = "try-runtime")]
use pezframe_support::ensure;
#[cfg(feature = "try-runtime")]
use pezsp_runtime::TryRuntimeError;
pub struct MigrateToV1<T>(core::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> {
fn on_runtime_upgrade() -> Weight {
let current = Pallet::<T>::in_code_storage_version();
let onchain = Pallet::<T>::on_chain_storage_version();
log!(
info,
"Running migration with in-code storage version {:?} / onchain {:?}",
current,
onchain
);
if current == 1 && onchain == 0 {
// update the version nonetheless.
current.put::<Pallet<T>>();
// if a head exists, then we put them back into the queue.
if Head::<T>::exists() {
if let Some((stash, _, deposit)) =
unhashed::take::<(T::AccountId, Vec<EraIndex>, BalanceOf<T>)>(
&Head::<T>::hashed_key(),
)
.defensive()
{
Queue::<T>::insert(stash, deposit);
} else {
// not much we can do here -- head is already deleted.
}
T::DbWeight::get().reads_writes(2, 3)
} else {
T::DbWeight::get().reads(2)
}
} else {
log!(info, "Migration did not execute. This probably should be removed");
T::DbWeight::get().reads(1)
}
}
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
ensure!(
Pallet::<T>::on_chain_storage_version() == 0,
"The onchain storage version must be zero for the migration to execute."
);
Ok(Default::default())
}
#[cfg(feature = "try-runtime")]
fn post_upgrade(_: Vec<u8>) -> Result<(), TryRuntimeError> {
ensure!(
Pallet::<T>::on_chain_storage_version() == 1,
"The onchain version must be updated after the migration."
);
Ok(())
}
}
}
@@ -0,0 +1,331 @@
// 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.
use crate::{self as fast_unstake};
use pezframe_election_provider_support::PageIndex;
use pezframe_support::{
assert_ok, derive_impl,
pezpallet_prelude::*,
parameter_types,
traits::{ConstU64, Currency},
weights::constants::WEIGHT_REF_TIME_PER_SECOND,
};
use pezsp_runtime::{traits::IdentityLookup, BuildStorage};
use pezpallet_staking::{Exposure, IndividualExposure, StakerStatus};
pub type AccountId = u128;
pub type BlockNumber = u64;
pub type Balance = u128;
pub type T = Runtime;
parameter_types! {
pub BlockWeights: pezframe_system::limits::BlockWeights =
pezframe_system::limits::BlockWeights::simple_max(
Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX),
);
}
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Runtime {
type Block = Block;
type AccountData = pezpallet_balances::AccountData<Balance>;
// we use U128 account id in order to get a better iteration order out of a map.
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
}
impl pezpallet_timestamp::Config for Runtime {
type Moment = u64;
type OnTimestampSet = ();
type MinimumPeriod = ConstU64<5>;
type WeightInfo = ();
}
parameter_types! {
pub static ExistentialDeposit: Balance = 1;
}
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
impl pezpallet_balances::Config for Runtime {
type Balance = Balance;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
}
pezpallet_staking_reward_curve::build! {
const I_NPOS: pezsp_runtime::curve::PiecewiseLinear<'static> = curve!(
min_inflation: 0_025_000,
max_inflation: 0_100_000,
ideal_stake: 0_500_000,
falloff: 0_050_000,
max_piece_count: 40,
test_precision: 0_005_000,
);
}
parameter_types! {
pub const RewardCurve: &'static pezsp_runtime::curve::PiecewiseLinear<'static> = &I_NPOS;
pub static BondingDuration: u32 = 3;
pub static CurrentEra: u32 = 0;
pub static Ongoing: bool = false;
}
pub struct MockElection;
impl pezframe_election_provider_support::ElectionProvider for MockElection {
type BlockNumber = BlockNumber;
type AccountId = AccountId;
type DataProvider = Staking;
type MaxBackersPerWinner = ConstU32<100>;
type MaxWinnersPerPage = ConstU32<100>;
type Pages = ConstU32<1>;
type MaxBackersPerWinnerFinal = Self::MaxBackersPerWinner;
type Error = ();
fn elect(
_remaining_pages: PageIndex,
) -> Result<pezframe_election_provider_support::BoundedSupportsOf<Self>, Self::Error> {
Err(())
}
fn start() -> Result<(), Self::Error> {
Ok(())
}
fn duration() -> Self::BlockNumber {
0
}
fn status() -> Result<bool, ()> {
if Ongoing::get() {
Ok(false)
} else {
Err(())
}
}
}
#[derive_impl(pezpallet_staking::config_preludes::TestDefaultConfig)]
impl pezpallet_staking::Config for Runtime {
type OldCurrency = Balances;
type Currency = Balances;
type UnixTime = pezpallet_timestamp::Pallet<Self>;
type AdminOrigin = pezframe_system::EnsureRoot<Self::AccountId>;
type BondingDuration = BondingDuration;
type EraPayout = pezpallet_staking::ConvertCurve<RewardCurve>;
type ElectionProvider = MockElection;
type GenesisElectionProvider = Self::ElectionProvider;
type VoterList = pezpallet_staking::UseNominatorsAndValidatorsMap<Self>;
type TargetList = pezpallet_staking::UseValidatorsMap<Self>;
}
parameter_types! {
pub static Deposit: u128 = 7;
pub static BatchSize: u32 = 1;
}
impl fast_unstake::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Deposit = Deposit;
type Currency = Balances;
type Staking = Staking;
type ControlOrigin = pezframe_system::EnsureRoot<Self::AccountId>;
type BatchSize = BatchSize;
type WeightInfo = ();
type MaxErasToCheckPerBlock = ConstU32<16>;
}
type Block = pezframe_system::mocking::MockBlock<Runtime>;
pezframe_support::construct_runtime!(
pub enum Runtime {
System: pezframe_system,
Timestamp: pezpallet_timestamp,
Balances: pezpallet_balances,
Staking: pezpallet_staking,
FastUnstake: fast_unstake,
}
);
parameter_types! {
static FastUnstakeEvents: u32 = 0;
}
pub(crate) fn fast_unstake_events_since_last_call() -> Vec<super::Event<Runtime>> {
let events = System::events()
.into_iter()
.map(|r| r.event)
.filter_map(|e| if let RuntimeEvent::FastUnstake(inner) = e { Some(inner) } else { None })
.collect::<Vec<_>>();
let already_seen = FastUnstakeEvents::get();
FastUnstakeEvents::set(events.len() as u32);
events.into_iter().skip(already_seen as usize).collect()
}
pub struct ExtBuilder {
unexposed: Vec<(AccountId, AccountId, Balance)>,
}
impl Default for ExtBuilder {
fn default() -> Self {
Self {
unexposed: vec![
(1, 1, 7 + 100),
(3, 3, 7 + 100),
(5, 5, 7 + 100),
(7, 7, 7 + 100),
(9, 9, 7 + 100),
],
}
}
}
pub(crate) const VALIDATORS_PER_ERA: AccountId = 32;
pub(crate) const VALIDATOR_PREFIX: AccountId = 100;
pub(crate) const NOMINATORS_PER_VALIDATOR_PER_ERA: AccountId = 4;
pub(crate) const NOMINATOR_PREFIX: AccountId = 1000;
impl ExtBuilder {
pub(crate) fn register_stakers_for_era(era: u32) {
// validators are prefixed with 100 and nominators with 1000 to prevent conflict. Make sure
// all the other accounts used in tests are below 100. Also ensure here that we don't
// overlap.
assert!(VALIDATOR_PREFIX + VALIDATORS_PER_ERA < NOMINATOR_PREFIX);
(VALIDATOR_PREFIX..VALIDATOR_PREFIX + VALIDATORS_PER_ERA)
.map(|v| {
// for the sake of sanity, let's register this taker as an actual validator.
let others = (NOMINATOR_PREFIX..
(NOMINATOR_PREFIX + NOMINATORS_PER_VALIDATOR_PER_ERA))
.map(|n| IndividualExposure { who: n, value: 0 as Balance })
.collect::<Vec<_>>();
(v, Exposure { total: 0, own: 0, others })
})
.for_each(|(validator, exposure)| {
pezpallet_staking::EraInfo::<T>::set_exposure(era, &validator, exposure);
});
}
pub(crate) fn batch(self, size: u32) -> Self {
BatchSize::set(size);
self
}
pub(crate) fn build(self) -> pezsp_io::TestExternalities {
pezsp_tracing::try_init_simple();
let mut storage =
pezframe_system::GenesisConfig::<Runtime>::default().build_storage().unwrap();
let validators_range = VALIDATOR_PREFIX..VALIDATOR_PREFIX + VALIDATORS_PER_ERA;
let nominators_range =
NOMINATOR_PREFIX..NOMINATOR_PREFIX + NOMINATORS_PER_VALIDATOR_PER_ERA;
let _ = pezpallet_balances::GenesisConfig::<Runtime> {
balances: self
.unexposed
.clone()
.into_iter()
.map(|(stash, _, balance)| (stash, balance * 2))
// give stakers enough balance for stake, ed and fast unstake deposit.
.chain(validators_range.clone().map(|x| (x, 7 + 1 + 100)))
.chain(nominators_range.clone().map(|x| (x, 7 + 1 + 100)))
.collect::<Vec<_>>(),
..Default::default()
}
.assimilate_storage(&mut storage);
let _ = pezpallet_staking::GenesisConfig::<Runtime> {
stakers: self
.unexposed
.into_iter()
.map(|(x, y, z)| (x, y, z, pezpallet_staking::StakerStatus::Nominator(vec![42])))
.chain(validators_range.map(|x| (x, x, 100, StakerStatus::Validator)))
.chain(nominators_range.map(|x| (x, x, 100, StakerStatus::Nominator(vec![x]))))
.collect::<Vec<_>>(),
..Default::default()
}
.assimilate_storage(&mut storage);
let mut ext = pezsp_io::TestExternalities::from(storage);
ext.execute_with(|| {
// for events to be deposited.
pezframe_system::Pallet::<Runtime>::set_block_number(1);
for era in 0..=(BondingDuration::get()) {
Self::register_stakers_for_era(era);
}
// because we read this value as a measure of how many validators we have.
pezpallet_staking::ValidatorCount::<Runtime>::put(VALIDATORS_PER_ERA as u32);
});
ext
}
pub fn build_and_execute(self, test: impl FnOnce() -> ()) {
self.build().execute_with(|| {
test();
})
}
}
pub(crate) fn run_to_block(n: u64, on_idle: bool) {
System::run_to_block_with::<AllPalletsWithSystem>(
n,
pezframe_system::RunToBlockHooks::default()
.before_finalize(|_| {
// Satisfy the timestamp pallet.
Timestamp::set_timestamp(0);
})
.after_initialize(|bn| {
if on_idle {
FastUnstake::on_idle(bn, BlockWeights::get().max_block);
}
}),
);
}
pub(crate) fn next_block(on_idle: bool) {
let current = System::block_number();
run_to_block(current + 1, on_idle);
}
pub fn assert_unstaked(stash: &AccountId) {
assert!(!pezpallet_staking::Bonded::<T>::contains_key(stash));
assert!(!pezpallet_staking::Payee::<T>::contains_key(stash));
assert!(!pezpallet_staking::Validators::<T>::contains_key(stash));
assert!(!pezpallet_staking::Nominators::<T>::contains_key(stash));
}
pub fn create_exposed_nominator(exposed: AccountId, era: u32) {
// create an exposed nominator in passed era
let mut exposure = pezpallet_staking::EraInfo::<T>::get_full_exposure(era, &VALIDATORS_PER_ERA);
exposure.others.push(IndividualExposure { who: exposed, value: 0 as Balance });
pezpallet_staking::EraInfo::<T>::set_exposure(era, &VALIDATORS_PER_ERA, exposure);
Balances::make_free_balance_be(&exposed, 100);
assert_ok!(Staking::bond(
RuntimeOrigin::signed(exposed),
10,
pezpallet_staking::RewardDestination::Staked
));
assert_ok!(Staking::nominate(RuntimeOrigin::signed(exposed), vec![exposed]));
// register the exposed one.
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(exposed)));
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,64 @@
// 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.
//! Types used in the Fast Unstake pallet.
use crate::Config;
use codec::{Decode, Encode, MaxEncodedLen};
use pezframe_support::{
traits::Currency, BoundedVec, CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
};
use scale_info::TypeInfo;
use pezsp_staking::{EraIndex, StakingInterface};
/// Maximum number of eras that we might check for a single staker.
///
/// In effect, it is the bonding duration, coming from [`Config::Staking`], plus one.
#[derive(scale_info::TypeInfo, codec::Encode, codec::Decode, codec::MaxEncodedLen)]
#[codec(mel_bound(T: Config))]
#[scale_info(skip_type_params(T))]
pub struct MaxChecking<T: Config>(core::marker::PhantomData<T>);
impl<T: Config> pezframe_support::traits::Get<u32> for MaxChecking<T> {
fn get() -> u32 {
T::Staking::bonding_duration() + 1
}
}
#[docify::export]
pub type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as pezframe_system::Config>::AccountId>>::Balance;
/// An unstake request.
///
/// This is stored in [`crate::Head`] storage item and points to the current unstake request that is
/// being processed.
#[derive(
Encode,
Decode,
EqNoBound,
PartialEqNoBound,
CloneNoBound,
TypeInfo,
RuntimeDebugNoBound,
MaxEncodedLen,
)]
#[scale_info(skip_type_params(T))]
pub struct UnstakeRequest<T: Config> {
/// This list of stashes are being processed in this request, and their corresponding deposit.
pub stashes: BoundedVec<(T::AccountId, BalanceOf<T>), T::BatchSize>,
/// The list of eras for which they have been checked.
pub checked: BoundedVec<EraIndex, MaxChecking<T>>,
}
@@ -0,0 +1,383 @@
// 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_fast_unstake`
//!
//! 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_fast_unstake
// --header=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/HEADER-APACHE2
// --output=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/pezframe/fast-unstake/src/weights.rs
// --wasm-execution=compiled
// --steps=50
// --repeat=20
// --heap-pages=4096
// --template=bizinikiwi/.maintain/frame-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 pezframe_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use core::marker::PhantomData;
/// Weight functions needed for `pezpallet_fast_unstake`.
pub trait WeightInfo {
fn on_idle_unstake(b: u32, ) -> Weight;
fn on_idle_check(v: u32, b: u32, ) -> Weight;
fn register_fast_unstake() -> Weight;
fn deregister() -> Weight;
fn control() -> Weight;
}
/// Weights for `pezpallet_fast_unstake` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ValidatorCount` (r:1 w:0)
/// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:1)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:0)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `MultiBlock::CurrentPhase` (r:1 w:0)
/// Proof: `MultiBlock::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::SlashingSpans` (r:64 w:0)
/// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Staking::Bonded` (r:64 w:64)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:64 w:64)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::VirtualStakers` (r:64 w:64)
/// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:64 w:64)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:64 w:64)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Staking::Validators` (r:64 w:0)
/// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`)
/// Storage: `Staking::Nominators` (r:64 w:0)
/// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`)
/// Storage: `Staking::Payee` (r:0 w:64)
/// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
/// The range of component `b` is `[1, 64]`.
fn on_idle_unstake(b: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `57 + b * (443 ±0)`
// Estimated: `7253 + b * (3566 ±0)`
// Minimum execution time: 86_174_000 picoseconds.
Weight::from_parts(9_455_381, 7253)
// Standard Error: 41_683
.saturating_add(Weight::from_parts(72_236_736, 0).saturating_mul(b.into()))
.saturating_add(T::DbWeight::get().reads(6_u64))
.saturating_add(T::DbWeight::get().reads((8_u64).saturating_mul(b.into())))
.saturating_add(T::DbWeight::get().writes(1_u64))
.saturating_add(T::DbWeight::get().writes((6_u64).saturating_mul(b.into())))
.saturating_add(Weight::from_parts(0, 3566).saturating_mul(b.into()))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ValidatorCount` (r:1 w:0)
/// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:1)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:0)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `MultiBlock::CurrentPhase` (r:1 w:0)
/// Proof: `MultiBlock::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakersPaged` (r:257 w:0)
/// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `v` is `[1, 256]`.
/// The range of component `b` is `[1, 64]`.
fn on_idle_check(v: u32, b: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `850 + b * (48 ±0) + v * (1318 ±0)`
// Estimated: `7253 + b * (49 ±0) + v * (3794 ±0)`
// Minimum execution time: 517_331_000 picoseconds.
Weight::from_parts(530_541_000, 7253)
// Standard Error: 2_918_095
.saturating_add(Weight::from_parts(95_402_277, 0).saturating_mul(v.into()))
// Standard Error: 11_675_633
.saturating_add(Weight::from_parts(365_913_743, 0).saturating_mul(b.into()))
.saturating_add(T::DbWeight::get().reads(7_u64))
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into())))
.saturating_add(T::DbWeight::get().writes(1_u64))
.saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into()))
.saturating_add(Weight::from_parts(0, 3794).saturating_mul(v.into()))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::Bonded` (r:1 w:0)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Queue` (r:1 w:1)
/// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:0)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `Staking::Validators` (r:1 w:0)
/// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`)
/// Storage: `Staking::Nominators` (r:1 w:1)
/// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`)
/// Storage: `Staking::CounterForNominators` (r:1 w:1)
/// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListNodes` (r:1 w:1)
/// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListBags` (r:1 w:1)
/// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`)
/// Storage: `VoterList::CounterForListNodes` (r:1 w:1)
/// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::VirtualStakers` (r:1 w:0)
/// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:0)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:1)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn register_fast_unstake() -> Weight {
// Proof Size summary in bytes:
// Measured: `702`
// Estimated: `7253`
// Minimum execution time: 115_559_000 picoseconds.
Weight::from_parts(118_297_000, 7253)
.saturating_add(T::DbWeight::get().reads(15_u64))
.saturating_add(T::DbWeight::get().writes(8_u64))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:0)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::Bonded` (r:1 w:0)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Queue` (r:1 w:1)
/// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:0)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:1)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn deregister() -> Weight {
// Proof Size summary in bytes:
// Measured: `428`
// Estimated: `7253`
// Minimum execution time: 38_629_000 picoseconds.
Weight::from_parts(39_404_000, 7253)
.saturating_add(T::DbWeight::get().reads(6_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:0 w:1)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn control() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 1_730_000 picoseconds.
Weight::from_parts(1_802_000, 0)
.saturating_add(T::DbWeight::get().writes(1_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ValidatorCount` (r:1 w:0)
/// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:1)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:0)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `MultiBlock::CurrentPhase` (r:1 w:0)
/// Proof: `MultiBlock::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::SlashingSpans` (r:64 w:0)
/// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Staking::Bonded` (r:64 w:64)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:64 w:64)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::VirtualStakers` (r:64 w:64)
/// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:64 w:64)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:64 w:64)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Staking::Validators` (r:64 w:0)
/// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`)
/// Storage: `Staking::Nominators` (r:64 w:0)
/// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`)
/// Storage: `Staking::Payee` (r:0 w:64)
/// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
/// The range of component `b` is `[1, 64]`.
fn on_idle_unstake(b: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `57 + b * (443 ±0)`
// Estimated: `7253 + b * (3566 ±0)`
// Minimum execution time: 86_174_000 picoseconds.
Weight::from_parts(9_455_381, 7253)
// Standard Error: 41_683
.saturating_add(Weight::from_parts(72_236_736, 0).saturating_mul(b.into()))
.saturating_add(RocksDbWeight::get().reads(6_u64))
.saturating_add(RocksDbWeight::get().reads((8_u64).saturating_mul(b.into())))
.saturating_add(RocksDbWeight::get().writes(1_u64))
.saturating_add(RocksDbWeight::get().writes((6_u64).saturating_mul(b.into())))
.saturating_add(Weight::from_parts(0, 3566).saturating_mul(b.into()))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ValidatorCount` (r:1 w:0)
/// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:1)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:0)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `MultiBlock::CurrentPhase` (r:1 w:0)
/// Proof: `MultiBlock::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakersPaged` (r:257 w:0)
/// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `v` is `[1, 256]`.
/// The range of component `b` is `[1, 64]`.
fn on_idle_check(v: u32, b: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `850 + b * (48 ±0) + v * (1318 ±0)`
// Estimated: `7253 + b * (49 ±0) + v * (3794 ±0)`
// Minimum execution time: 517_331_000 picoseconds.
Weight::from_parts(530_541_000, 7253)
// Standard Error: 2_918_095
.saturating_add(Weight::from_parts(95_402_277, 0).saturating_mul(v.into()))
// Standard Error: 11_675_633
.saturating_add(Weight::from_parts(365_913_743, 0).saturating_mul(b.into()))
.saturating_add(RocksDbWeight::get().reads(7_u64))
.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into())))
.saturating_add(RocksDbWeight::get().writes(1_u64))
.saturating_add(Weight::from_parts(0, 49).saturating_mul(b.into()))
.saturating_add(Weight::from_parts(0, 3794).saturating_mul(v.into()))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:1)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::Bonded` (r:1 w:0)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Queue` (r:1 w:1)
/// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:0)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `Staking::Validators` (r:1 w:0)
/// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`)
/// Storage: `Staking::Nominators` (r:1 w:1)
/// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `MaxEncodedLen`)
/// Storage: `Staking::CounterForNominators` (r:1 w:1)
/// Proof: `Staking::CounterForNominators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListNodes` (r:1 w:1)
/// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`)
/// Storage: `VoterList::ListBags` (r:1 w:1)
/// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`)
/// Storage: `VoterList::CounterForListNodes` (r:1 w:1)
/// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::VirtualStakers` (r:1 w:0)
/// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:0)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:1)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn register_fast_unstake() -> Weight {
// Proof Size summary in bytes:
// Measured: `702`
// Estimated: `7253`
// Minimum execution time: 115_559_000 picoseconds.
Weight::from_parts(118_297_000, 7253)
.saturating_add(RocksDbWeight::get().reads(15_u64))
.saturating_add(RocksDbWeight::get().writes(8_u64))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:1 w:0)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::Ledger` (r:1 w:0)
/// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`)
/// Storage: `Staking::Bonded` (r:1 w:0)
/// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Queue` (r:1 w:1)
/// Proof: `FastUnstake::Queue` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::Head` (r:1 w:0)
/// Proof: `FastUnstake::Head` (`max_values`: Some(1), `max_size`: Some(5768), added: 6263, mode: `MaxEncodedLen`)
/// Storage: `FastUnstake::CounterForQueue` (r:1 w:1)
/// Proof: `FastUnstake::CounterForQueue` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn deregister() -> Weight {
// Proof Size summary in bytes:
// Measured: `428`
// Estimated: `7253`
// Minimum execution time: 38_629_000 picoseconds.
Weight::from_parts(39_404_000, 7253)
.saturating_add(RocksDbWeight::get().reads(6_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `FastUnstake::ErasToCheckPerBlock` (r:0 w:1)
/// Proof: `FastUnstake::ErasToCheckPerBlock` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
fn control() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 1_730_000 picoseconds.
Weight::from_parts(1_802_000, 0)
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
}