Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add storage bounds for pallet staking #6445

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from

Conversation

re-gius
Copy link
Contributor

@re-gius re-gius commented Nov 11, 2024

This is part of #6289 and necessary for the Asset Hub migration.

Building on the observations and suggestions from #255 .

Changes

  • Add MaxInvulnerables to bound Invulnerables Vec.
    • Set to constant 20 in the pallet (must be >= 17 for backward compatibility of runtime westend).
  • Use MaxWinners from pallet-election-provider-support to bound DisabledValidators Vec and EraRewardPoints.individual BTreeMap.
    • This corresponds to the number of max active validators.
  • Remove ErasStakers and ErasStakersClipped (see Tracker issue for cleaning up old non-paged exposure logic in staking pallet #433 )
  • Use MaxExposurePageSize to bound ErasStakersPaged -> ExposurePage.others Vec
  • Add MaxBondedEras to bound BondedEras Vec
    • Set to BondingDuration::get() + 1 everywhere to include both time interval endpoints
  • Add MaxRewardPagesPerValidator to bound ClaimedRewards Vec of pages
    • Set to constant 20 in the pallet. The vector of pages is now a WeakBoundedVec

TO DO
Slashing storage items will be bounded in another PR.

  • UnappliedSlashes
  • SlashingSpans

@Ank4n Ank4n self-requested a review November 27, 2024 21:57
/// Ideally, it should be `BondingDuration::get() + 1` to include all eras in the interval
/// [current_era - BondingDuration::get(), current_era].
#[pallet::constant]
type MaxBondedEras: Get<u32>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have an integrity test ensuring MaxBondedEras >= BondingDuration + 1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added in tests

assert_eq!(MaxBondedEras::get(), (BondingDuration::get() as u32) + 1);

pub type ErasStakersPaged<T: Config> = StorageNMap<
_,
(
NMapKey<Twox64Concat, EraIndex>,
NMapKey<Twox64Concat, T::AccountId>,
NMapKey<Twox64Concat, Page>,
),
ExposurePage<T::AccountId, BalanceOf<T>>,
ExposurePage<T::AccountId, BalanceOf<T>, T::MaxExposurePageSize>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gpestana should we reduce MaxExposurePageSize before we do this? What would be the ideal number? 64/128?

To give context, once we make this bounded, reducing it would need (large) migration. Alternatively, we can make it WeaklyBoundedVec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using WeakBoundedVec in c066632

_,
Twox64Concat,
EraIndex,
EraRewardPoints<T::AccountId, <T::ElectionProvider as ElectionProviderBase>::MaxWinners>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this is not correct. The storage ValidatorCount is the right value.

We can potentially turn it into a config item but that has the implication that increasing validator count would always require runtime upgrade and cannot happen via governance. To fix that, you will have to also turn it into a dynamic parameter (see here).

_,
BoundedVec<
(u32, OffenceSeverity),
<T::ElectionProvider as ElectionProviderBase>::MaxWinners,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

Also, consider using WeaklyBoundedVec since we expect validator numbers to change over time. An increase in the value is not an issue but for some reason if we decrease it, it can lead to decode issues with BoundedVec.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, DisabledValidators would be a much smaller number than the actual validator set, and it depends on the DisablingStrategy, which is currenctly 1/3rd of the set. This can also be a new config value.

self.invulnerables.len() as u32 <= T::MaxInvulnerables::get(),
"Too many invulnerable validators at genesis."
);
<Invulnerables<T>>::put(BoundedVec::truncate_from(self.invulnerables.clone()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stakers param in GenesisConfig itself can be BoundedVec, right?

@paritytech-workflow-stopper
Copy link

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/12088846530
Failed job name: quick-benchmarks-omni

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T2-pallets This PR/Issue is related to a particular pallet.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants