Skip to content

Staking Pallet Architecture Diagram

General Structure

┌─────────────────────────────────────────────────────────────────┐
│                        Staking Pallet                           │
├─────────────────────────────────────────────────────────────────┤
│  mod.rs (Structure)                    impls.rs (Logic)         │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐                ┌─────────────────────────┐ │
│  │   Config        │                │   Core Functions        │ │
│  │   - Currency    │                │   - ledger()            │ │
│  │   - Time        │                │   - calculate_interest  │ │
│  │   - Economics   │                │   - do_payout_stakers   │ │
│  │   - Elections   │                │   - new_session()       │ │
│  └─────────────────┘                └─────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐                ┌─────────────────────────┐ │
│  │   Storage       │                │   Session Management    │ │
│  │   - Bonded      │                │   - new_session()       │ │
│  │   - Ledger      │                │   - start_session()     │ │
│  │   - Validators  │                │   - end_session()       │ │
│  │   - Nominators  │                └─────────────────────────┘ │
│  │   - Eras        │                                            │
│  └─────────────────┘                                            │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐                ┌─────────────────────────┐ │
│  │   Events        │                │   Election Provider     │ │
│  │   - Rewarded    │                │   - get_npos_voters()   │ │
│  │   - Slashed     │                │   - get_npos_targets()  │ │
│  │   - Bonded      │                │   - electing_voters()   │ │
│  │   - VividStaking│                │   - electable_targets() │ │
│  └─────────────────┘                └─────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│  ┌───────────────────────────┐      ┌─────────────────────────┐ │
│  │   Errors                  │      │   Runtime API           │ │
│  │   - NotStash              │      │  - api_nominations_quota│ │
│  │   - NotController         │      │  - api_estimate_payout  │ │
│  │   - InsufficientBond      │      │  - StakingInterface     │ │
│  │   - VividStakingInProgress│      └─────────────────────────┘ │
│  └───────────────────────────┘                                  │
└─────────────────────────────────────────────────────────────────┘

Detailed Storage Structure

Storage Layer
├── Account Management
│   ├── Bonded<T>                      // stash -> controller mapping
│   ├── Ledger<T>                     // controller -> StakingLedger
│   └── Payee<T>                     // stash -> RewardDestination
├── Validators & Nominators
│   ├── Validators<T>                  // validator -> ValidatorPrefs
│   ├── Nominators<T>                 // nominator -> Nominations
│   ├── ValidatorCount<T>            // desired validator count
│   └── MinimumValidatorCount<T>    // minimum validators
├── Era Management
│   ├── CurrentEra<T>                // current era index
│   ├── ActiveEra<T>                // active era info
│   ├── ErasStartSessionIndex<T>    // era -> session mapping
│   ├── ErasStakers<T>              // era -> validator -> Exposure
│   ├── ErasStakersClipped<T>       // clipped exposures
│   ├── ErasValidatorPrefs<T>       // era -> validator -> prefs
│   ├── ErasDuration<T>             // era -> duration
│   ├── ErasRewardPoints<T>         // era -> reward points
│   └── ErasTotalStake<T>           // era -> total stake
├── Slashing
│   ├── UnappliedSlashes<T>         // era -> Vec<UnappliedSlash>
│   ├── SlashingSpans<T>            // stash -> SlashingSpans
│   ├── SpanSlash<T>                // (stash, span) -> SpanRecord
│   ├── ValidatorSlashInEra<T>      // era -> validator -> (fraction, amount)
│   └── NominatorSlashInEra<T>      // era -> nominator -> amount
└── Configuration
    ├── MinNominatorBond<T>         // minimum nominator bond
    ├── MinValidatorBond<T>         // minimum validator bond
    ├── ForceEra<T>                 // force era mode
    ├── StakingActive<T>            // staking enabled flag
    └── IssuanceLimit<T>            // maximum token issuance

Data Flow for Reward Payouts

Payout Flow
┌─────────────┐    ┌──────────────┐    ┌─────────────┐
│   User      │    │   Runtime    │    │   Staking   │
│   Call      │─▶  │   Dispatch   │───▶│   Pallet   │
└─────────────┘    └──────────────┘    └─────────────┘
┌─────────────────────────────────────────────────────────┐
│                do_payout_stakers()                      │
├─────────────────────────────────────────────────────────┤
│  1. Validate era and check permissions                  │
│  2. Get exposure from ErasStakersClipped                │
│  3. Calculate interest for each nominator               │
│     - Check vivid staking status                        │
│     - Apply standard + vivid interest rates             │
│  4. Calculate validator commission                      │
│  5. Create payouts via make_payout()                    │
│     - Controller/Stash/Staked/Account/None              │
│  6. Emit Rewarded events                                │
│  7. Update ledger.claimed_rewards                       │
└─────────────────────────────────────────────────────────┘

Vivid Staking Flow

Vivid Staking Process
┌─────────────┐    ┌──────────────┐    ┌─────────────┐
│   User      │    │   vivid()    │    │   Storage   │
│   Call      │──▶ │   Function   │───▶│   Update   │
└─────────────┘    └──────────────┘    └─────────────┘
┌─────────────────────────────────────────────────────────┐
│                Vivid Staking Logic                      │
├─────────────────────────────────────────────────────────┤
│  1. Validate months_count parameter                     │
│  2. Check no existing vivid staking                     │
│  3. Calculate starting and ending eras                  │
│  4. Create VividStakingState                            │
│  5. Update ledger.vivid_staking                         │
│  6. Emit VividStakingScheduled event                    │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│              Interest Calculation                       │
├─────────────────────────────────────────────────────────┤
│  calculate_interest(era, vivid_staking)                 │
│  ├── Check if era is within vivid period                │
│  ├── Calculate months locked                            │
│  └── Return: StandardInterest + VividInterest * months  │
└─────────────────────────────────────────────────────────┘

Election Provider Flow

Election Process
┌─────────────┐    ┌──────────────┐    ┌─────────────┐
│   Session   │    │   Election   │    │   Validator │
│   Manager   │───▶│   Provider  │───▶│   Selection │
└─────────────┘    └──────────────┘    └─────────────┘
┌─────────────────────────────────────────────────────────┐
│                get_npos_voters()                        │
├─────────────────────────────────────────────────────────┤
│  1. Iterate through VoterList                           │
│  2. Filter by weight (exclude zero weights)             │
│  3. Separate validators and nominators                  │
│  4. Apply bounds constraints                            │
│  5. Track minimum active stake                          │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                get_npos_targets()                       │
├─────────────────────────────────────────────────────────┤
│  1. Iterate through TargetList                          │
│  2. Filter active validators only                       │
│  3. Apply bounds constraints                            │
│  4. Return validator list                               │
└─────────────────────────────────────────────────────────┘

Session Management Flow

Session Lifecycle
┌─────────────┐    ┌──────────────┐    ┌─────────────┐
│   Session   │    │   Era        │    │   Validator │
│   Start     │──▶ │   Planning   │───▶│   Rotation │
└─────────────┘    └──────────────┘    └─────────────┘
┌─────────────────────────────────────────────────────────┐
│                new_session()                            │
├─────────────────────────────────────────────────────────┤
│  1. Check current era                                   │
│  2. Analyze force era modes                             │
│  3. Check session limit per era                         │
│  4. Trigger new era if needed                           │
│  5. Return new validator set                            │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                start_era()                              │
├─────────────────────────────────────────────────────────┤
│  1. Increment active era index                          │
│  2. Update BondedEras                                   │
│  3. Clean old era data                                  │
│  4. Apply deferred slashes                              │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                end_era()                                │
├─────────────────────────────────────────────────────────┤
│  1. Calculate era duration                              │
│  2. Estimate payouts                                    │
│  3. Check issuance limit                                │
│  4. Disable staking if limit exceeded                   │
└─────────────────────────────────────────────────────────┘

Economic Model

Economic Model
┌─────────────────────────────────────────────────────────┐
│                Interest Calculation                     │
├─────────────────────────────────────────────────────────┤
│  Standard Staking:                                      │
│  └── StandartStakingInterest (base rate)                │
│                                                         │
│  Vivid Staking:                                         │
│  ├── StandartStakingInterest (base rate)                │
│  └── VividStakingInterestPerMonth * months_locked       │
│                                                         │
│  Total Interest = Base + (Vivid * Months)               │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                Payout Calculation                       │
├─────────────────────────────────────────────────────────┤
│  Era Duration = Current Time - Era Start                │
│  Portion = Era Duration / Year Duration                 │
│  Interest = calculate_interest(era, vivid_staking)      │
│  Payout = Portion * Interest * Stake                    │
│                                                         │
│  Validator Commission:                                  │
│  ├── Validator gets: own_stake * interest               │
│  ├── Validator gets: commission * nominator_rewards     │
│  └── Nominators get: (1 - commission) * their_rewards   │
└─────────────────────────────────────────────────────────┘

Security and Validation

Security Measures
┌─────────────────────────────────────────────────────────┐
│                Input Validation                         │
├─────────────────────────────────────────────────────────┤
│  ├── Era bounds checking                                │
│  ├── Balance sufficiency                                │
│  ├── Slashing span validation                           │
│  ├── Vivid staking constraints                          │
│  └── Commission limits                                  │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                State Consistency                        │
├─────────────────────────────────────────────────────────┤
│  ├── Ledger total = active + sum(unlocking)             │
│  ├── VoterList count = Validators + Nominators          │
│  ├── Exposure total = own + sum(others)                 │
│  └── Era progression validation                         │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                Economic Limits                          │
├─────────────────────────────────────────────────────────┤
│  ├── IssuanceLimit: Maximum token creation              │
│  ├── StakingActive: Enable/disable staking              │
│  ├── MinNominatorBond: Minimum stake for nominators     │
│  └── MinValidatorBond: Minimum stake for validators     │
└─────────────────────────────────────────────────────────┘

This architecture provides: - Modularity: Clear separation of structure and logic - Security: Multiple checks and validations - Performance: Optimized algorithms and storage - Flexibility: Support for different types of staking - Scalability: Efficient management of large datasets