Expand description
§Staking Async Pallet
This pallet is a fork of the original pallet-staking
, with a number of key differences:
- It no longer has access to a secure timestamp, previously used to calculate the duration of an era.
- It no longer has access to a pallet-session.
- It no longer has access to a pallet-authorship.
- It is capable of working with a multi-page
ElectionProvider``, aka.
pallet-election-provider-multi-block`.
While pallet-staking
was somewhat general-purpose, this pallet is absolutely NOT right from
the get-go: It is designed to be used ONLY in Polkadot/Kusama AssetHub system parachains.
The workings of this pallet can be divided into a number of subsystems, as follows.
§User Interactions
TODO
§Session and Era Rotation
TODO
§Exposure Collection
TODO
§Slashing Pipeline and Withdrawal Restrictions
This pallet implements a robust slashing mechanism that ensures the integrity of the staking system while preventing stakers from withdrawing funds that might still be subject to slashing.
§Overview of the Slashing Pipeline
The slashing process consists of multiple phases:
- Offence Reporting: Offences are reported from the relay chain through
on_new_offences
- Queuing: Valid offences are added to the
OffenceQueue
for processing - Processing: Offences are processed incrementally over multiple blocks
- Application: Slashes are either applied immediately or deferred based on configuration
§Phase 1: Offence Reporting
Offences are reported from the relay chain (e.g., from BABE, GRANDPA, BEEFY, or parachain
modules) through the on_new_offences
function:
struct Offence {
offender: AccountId, // The validator being slashed
reporters: Vec<AccountId>, // Who reported the offence (may be empty)
slash_fraction: Perbill, // Percentage of stake to slash
}
Reporting Deadlines:
- With deferred slashing: Offences must be reported within
SlashDeferDuration - 1
eras - With immediate slashing: Offences can be reported up to
BondingDuration
eras old
Example: If SlashDeferDuration = 27
and current era is 100:
- Oldest reportable offence: Era 74 (100 - 26)
- Offences from era 73 or earlier are rejected
§Phase 2: Queuing
When an offence passes validation, it’s added to the queue:
- Storage: Added to
OffenceQueue
:(EraIndex, AccountId) -> OffenceRecord
- Era Tracking: Era added to
OffenceQueueEras
(sorted vector of eras with offences) - Duplicate Handling: If an offence already exists for the same validator in the same era, only the higher slash fraction is kept
§Phase 3: Processing
Offences are processed incrementally in on_initialize
each block:
1. Load oldest offence from queue
2. Move to `ProcessingOffence` storage
3. For each exposure page (from last to first):
- Calculate slash for validator's own stake
- Calculate slash for each nominator (pro-rata based on exposure)
- Track total slash and reward amounts
4. Once all pages processed, create `UnappliedSlash`
Key Features:
- Page-by-page processing: Large validator sets don’t overwhelm a single block
- Pro-rata slashing: Nominators slashed proportionally to their stake
- Reward calculation: A portion goes to reporters (if any)
§Phase 4: Application
Based on SlashDeferDuration
, slashes are either:
Immediate (SlashDeferDuration = 0):
- Applied right away in the same block
- Funds deducted from staking ledger immediately
Deferred (SlashDeferDuration > 0):
- Stored in
UnappliedSlashes
for future application - Applied at era:
offence_era + SlashDeferDuration
- Can be cancelled by governance before application
§Storage Items Involved
OffenceQueue
: Pending offences to processOffenceQueueEras
: Sorted list of eras with offencesProcessingOffence
: Currently processing offenceValidatorSlashInEra
: Tracks highest slash per validator per eraUnappliedSlashes
: Deferred slashes waiting for application
§Withdrawal Restrictions
To maintain slashing guarantees, withdrawals are restricted:
Withdrawal Era Calculation:
earliest_era_to_withdraw = min(
active_era,
last_fully_processed_offence_era + BondingDuration
)
Example:
- Active era: 100
- Oldest unprocessed offence: Era 70
- BondingDuration: 28
- Withdrawal allowed only for chunks with era ≤ 97 (70 - 1 + 28)
Withdrawal Timeline Example with an Offence:
Era: 90 91 92 93 94 95 96 97 98 99 100 ... 117 118
| | | | | | | | | | | | |
Unbond: U
Offence: X
Reported: R
Processed: P (within next few blocks)
Slash Applied: S
Withdraw: ❌ ✓
With BondingDuration = 28 and SlashDeferDuration = 27:
- User unbonds in era 90
- Offence occurs in era 90
- Reported in era 92 (typically within 2 days, but reportable until Era 116)
- Processed in era 92 (within next few blocks after reporting)
- Slash deferred for 27 eras, applied at era 117 (90 + 27)
- Cannot withdraw unbonded chunks until era 118 (90 + 28)
The 28-era bonding duration ensures that any offences committed before or during
unbonding have time to be reported, processed, and applied before funds can be
withdrawn. This provides a window for governance to cancel slashes that may have
resulted from software bugs.
Key Restrictions:
- Cannot withdraw if previous era has unapplied slashes
- Cannot withdraw funds from eras with unprocessed offences
Re-exports§
pub use weights::WeightInfo;
pub use ledger::StakingLedger;
pub use ledger::UnlockChunk;
Modules§
- asset
- Contains all the interactions with
Config::Currency
to manipulate the underlying staking asset. - benchmarking
- Staking pallet benchmarking.
- config_
preludes - Default implementations of
DefaultConfig
, which can be used to implementConfig
. - dispatchables
- Auto-generated docs-only module listing all defined dispatchables for this pallet.
- election_
size_ tracker - A static size tracker for the election snapshot data.
- ledger
- A Ledger implementation for stakers.
- session_
rotation - Manages all era rotation logic based on session increments.
- slashing
- A slashing implementation for NPoS systems.
- storage_
types - Auto-generated docs-only module listing all (public and private) defined storage types for this pallet.
- testing_
utils - Testing utils for staking. Provides some common functions to setup staking state, such as bonding validators, nominators, and generating different types of solutions.
- weights
- Autogenerated weights for
pallet_staking_async
Macros§
Structs§
- Active
EraInfo - Information regarding the active era (era in used in session).
- AllStakers
- A utility struct that provides a way to check if a given account is a staker.
- Bonded
Eras Bound - Custom bound for
BondedEras
which is equal toConfig::BondingDuration
+ 1. - Bounded
Exposure Page - A bounded wrapper for [
sp_staking::ExposurePage
]. - Claimed
Rewards Bound - EraReward
Points - Reward points of an era. Used to split era total payout between validators.
- Exposure
- A snapshot of the stake backing a single validator in the system.
- Fixed
Nominations Quota - A nomination quota that allows up to MAX nominations for all validators.
- Genesis
Config - Can be used to configure the genesis state of this pallet.
- Individual
Exposure - The amount of exposure for an era that an individual nominator has (susceptible to slashing).
- Nominations
- A record of the nominations made by a specific account.
- Paged
Exposure - Facade struct to encapsulate
PagedExposureMetadata
and a single page ofExposurePage
. - Pallet
- The
Pallet
struct, the main type that implements traits and standalone functions within the pallet. - Planning
EraOffset Of - A smart type to determine the
Config::PlanningEraOffset
, given: - Unapplied
Slash - A pending slash record. The value of the slash has been computed but not applied yet, rather deferred for several eras.
- UseNominators
AndValidators Map - A simple voter list implementation that does not require any additional pallets. Note, this does not provided nominators in sorted ordered. If you desire nominators in a sorted order take a look at [`pallet-bags-list].
- UseValidators
Map - A simple sorted list implementation that does not require any additional pallets. Note, this
does not provide validators in sorted order. If you desire nominators in a sorted order take
a look at [
pallet-bags-list
]. - Validator
Prefs - Preference of what happens regarding validation.
Enums§
- Call
- Contains a variant per dispatchable extrinsic that this pallet has.
- Config
Op - Possible operations on the configuration values of this pallet.
- Error
- The
Error
enum of this pallet. - Event
- The
Event
enum of this pallet - Forcing
- Mode of era-forcing.
- Hold
Reason - A reason for placing a hold on funds.
- Reward
Destination - A destination account for payment.
- Snapshot
Status - Status of a paged snapshot progress.
- Staker
Status - Representation of the status of a staker.
- Unexpected
Kind - Represents unexpected or invariant-breaking conditions encountered during execution.
Traits§
- Config
- Configuration trait of this pallet.
- Default
Config - Based on
Config
. Auto-generated by#[pallet::config(with_default)]
. Can be used in tandem with#[register_default_config]
and#[derive_impl]
to derive test config traits based on existing pallet config traits in a safe and developer-friendly way. - EraPayout
- Handler for determining how much of a balance should be paid out on the current era.
- Nominations
Quota - Something that defines the maximum number of nominations per nominator based on a curve.
Type Aliases§
- Active
Era - The active era information, it holds index and start.
- Balance
Of - The balance type of this pallet.
- Bonded
- Map from all locked “stash” accounts to the controller account.
- Bonded
Eras - A mapping from still-bonded eras to the first session index of that era.
- Bounded
Exposures Of - Alias for a bounded set of exposures behind a validator, parameterized by this pallet’s election provider.
- Canceled
Slash Payout - The amount of currency given to reporters of a slash event which was canceled by extraordinary circumstances (e.g. governance).
- Cancelled
Slashes - Cancelled slashes by era and validator with maximum slash fraction to be cancelled.
- Chill
Threshold - The threshold for when users can start calling
chill_other
for other validators / nominators. The threshold is compared to the actual number of validators / nominators (CountFor*
) in the system compared to the configured max (Max*Count
). - Claimed
Rewards - History of claimed paged rewards by era and validator.
- Current
Era - The current planned era index.
- Electable
Stashes - A bounded list of the “electable” stashes that resulted from a successful election.
- Eras
Reward Points - Rewards for the last
Config::HistoryDepth
eras. If reward hasn’t been set or has been removed then 0 reward is returned. - Eras
Stakers Overview - Summary of validator exposure at a given era.
- Eras
Stakers Paged - Paginated exposure of a validator at given era.
- Eras
Total Stake - The total amount staked for the last
Config::HistoryDepth
eras. If total hasn’t been set or has been removed then 0 stake is returned. - Eras
Validator Prefs - Exposure of validator at era with the preferences of validators.
- Eras
Validator Reward - The total validator era payout for the last
Config::HistoryDepth
eras. - Force
Era - Mode of era forcing.
- Invulnerables
- Any validators that may never be slashed or forcibly kicked. It’s a Vec since they’re easy to initialize and the performance hit is minimal (we expect no more than four invulnerables) and restricted to testnets.
- Ledger
- Map from all (unlocked) “controller” accounts to the info regarding the staking.
- MaxNominations
Of - Maximum number of nominations per nominator.
- MaxNominators
Count - The maximum nominator count before we stop allowing new validators to join.
- MaxStaked
Rewards - Maximum staked rewards, i.e. the percentage of the era inflation that is used for stake rewards. See Era payout.
- MaxValidators
Count - The maximum validator count before we stop allowing new validators to join.
- MaxWinners
Of - Alias for the maximum number of winners (aka. active validators), as defined in by this pallet’s config.
- MaxWinners
PerPage Of - Alias for the maximum number of winners per page, as expected by the election provider.
- MinCommission
- The minimum amount of commission that validators can set.
- MinNominator
Bond - The minimum active bond to become and maintain the role of a nominator.
- MinValidator
Bond - The minimum active bond to become and maintain the role of a validator.
- Minimum
Active Stake - The minimum active nominator stake of the last successful election.
- Module
Deprecated - Type alias to
Pallet
, to be used byconstruct_runtime
. - Negative
Imbalance Of - Next
Election Page - Keeps track of an ongoing multi-page election solution request.
- Nominators
- The map from nominator stash key to their nomination preferences, namely the validators that they wish to support.
- Offence
Queue - Stores reported offences in a queue until they are processed in subsequent blocks.
- Offence
Queue Eras - Tracks the eras that contain offences in
OffenceQueue
, sorted from earliest to latest. - Payee
- Where the reward payment should be made. Keyed by stash.
- Processing
Offence - Tracks the currently processed offence record from the
OffenceQueue
. - Reward
Point - Counter for the number of “reward” points earned by a given validator.
- Slash
Reward Fraction - The percentage of the slash that is distributed to reporters.
- Unapplied
Slashes - All unapplied slashes that are queued for later.
- Validator
Count - The ideal number of active validators.
- Validator
Slash InEra - All slashing events on validators, mapped by era to the highest slash proportion and slash value of the era.
- Validators
- The map from (wannabe) validator stash key to the preferences of that validator.
- Virtual
Stakers - Stakers whose funds are managed by other pallets.
- Voter
Snapshot Status - Voter snapshot progress status.