java-topology/defects/substrate/patch/substrate-0001-is-exposed-validator-fastpath.patch

35 lines
1.5 KiB
Diff

# UNDF: UNDF-2026-000000303
--- a/substrate/frame/staking/src/pallet/impls.rs
+++ b/substrate/frame/staking/src/pallet/impls.rs
@@ -2081,12 +2081,21 @@ impl<T: Config> sp_staking::StakingInterface for Pallet<T> {
fn is_exposed_in_era(who: &Self::AccountId, era: &EraIndex) -> bool {
- // look in the non paged exposures
- // FIXME: Can be cleaned up once non paged exposures are cleared (https://github.com/paritytech/polkadot-sdk/issues/433)
- ErasStakers::<T>::iter_prefix(era).any(|(validator, exposures)| {
- validator == *who || exposures.others.iter().any(|i| i.who == *who)
- })
- ||
- // look in the paged exposures
- ErasStakersPaged::<T>::iter_prefix((era,)).any(|((validator, _), exposure_page)| {
- validator == *who || exposure_page.others.iter().any(|i| i.who == *who)
- })
+ // Fast path: check if `who` was an active validator in this era.
+ // ErasValidatorPrefs is keyed (era, validator) — O(1) storage read.
+ if ErasValidatorPrefs::<T>::contains_key(era, who) {
+ return true;
+ }
+
+ // Nominator path: still requires scanning exposure pages.
+ // FIXME: A nominator→validator reverse index would make this O(1).
+ // See https://github.com/paritytech/polkadot-sdk/issues/433
+ //
+ // look in the non-paged exposures (legacy)
+ ErasStakers::<T>::iter_prefix(era).any(|(_, exposures)| {
+ exposures.others.iter().any(|i| i.who == *who)
+ })
+ ||
+ // look in the paged exposures
+ ErasStakersPaged::<T>::iter_prefix((era,)).any(|(_, exposure_page)| {
+ exposure_page.others.iter().any(|i| i.who == *who)
+ })
}