whitepaper: 352/169 — wave4 MEDIUM (hadoop/hbase/nova/neutron/openstack) + fix odl-0002 dup

This commit is contained in:
russell@unturf.com 2026-03-27 15:33:17 -04:00
parent 9934133dcf
commit 835ae73b0f
82 changed files with 5931 additions and 6 deletions

View file

@ -0,0 +1,34 @@
--- 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)
+ })
}

View file

@ -0,0 +1,34 @@
--- a/substrate/frame/aura/src/lib.rs
+++ b/substrate/frame/aura/src/lib.rs
@@ -441,6 +441,8 @@ impl<T: Config> IsMember<T::AuthorityId> for Pallet<T> {
fn is_member(authority_id: &T::AuthorityId) -> bool {
- Authorities::<T>::get().iter().any(|id| id == authority_id)
+ // Authorities is stored sorted (invariant maintained by set_authorities).
+ // Binary search replaces O(A) linear scan with O(log A).
+ Authorities::<T>::get().binary_search(authority_id).is_ok()
}
}
Note: Requires Authorities BoundedVec to be kept sorted. The set_authorities
call site must sort before storing. Aura already processes authorities in
session index order which is stable — sorting once on write is correct.
--- a/substrate/frame/babe/src/lib.rs
+++ b/substrate/frame/babe/src/lib.rs
@@ -508,5 +508,6 @@ impl<T: Config> IsMember<AuthorityId> for Pallet<T> {
fn is_member(authority_id: &AuthorityId) -> bool {
- Authorities::<T>::get().iter().any(|id| &id.0 == authority_id)
+ Authorities::<T>::get()
+ .binary_search_by(|id| id.0.cmp(authority_id))
+ .is_ok()
}
}
--- a/substrate/frame/beefy/src/lib.rs
+++ b/substrate/frame/beefy/src/lib.rs
@@ -737,5 +737,6 @@ impl<T: Config> IsMember<T::BeefyId> for Pallet<T> {
fn is_member(authority_id: &T::BeefyId) -> bool {
- Authorities::<T>::get().iter().any(|id| id == authority_id)
+ Authorities::<T>::get().binary_search(authority_id).is_ok()
}
}