Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
500bc9d
Implement the new validator-in-bags-list scenario + migration
kianenigma Feb 8, 2022
ddcc81b
Apply suggestions from code review
kianenigma Feb 15, 2022
41540f2
some review comments
kianenigma Feb 15, 2022
8ba2563
Merge branch 'kiz-validators-in-bags' of github.com:paritytech/substr…
kianenigma Feb 15, 2022
c293a0c
Merge branch 'master' of github.com:paritytech/substrate into kiz-val…
kianenigma Feb 16, 2022
398cf70
guard the migration
kianenigma Feb 16, 2022
66fc7d2
some review comments
kianenigma Feb 16, 2022
75989de
Fix tests 🤦‍♂️
kianenigma Feb 16, 2022
db2a7b8
Fix build
kianenigma Feb 16, 2022
53561cb
Merge branch 'kiz-validators-in-bags' of github.com:paritytech/substr…
kianenigma Feb 28, 2022
18fb2f4
lay the groundwork to store validators in a bags-list instance
kianenigma Feb 28, 2022
ae8165f
add migration struct
kianenigma Feb 28, 2022
3e0a25d
make node-runtime build fine
kianenigma Feb 28, 2022
8f74872
Merge branch 'master' of github.com:paritytech/substrate into kiz-val…
kianenigma Feb 28, 2022
ac6473b
Merge branch 'master' of github.com:paritytech/substrate into kiz-rev…
kianenigma Feb 28, 2022
5c48b57
make instantiable
Mar 1, 2022
90d09f2
update
Mar 4, 2022
7d6cb8d
cargo fmt
Mar 4, 2022
0304977
Merge branch 'paritytech:master' into ddc-BPL-T1
Doordashcon Mar 4, 2022
dc7bd89
Most things work now
kianenigma Mar 8, 2022
7a55fad
Master.into()
kianenigma Mar 8, 2022
44d1281
Upstream.into()
kianenigma Mar 8, 2022
b3f93c5
most things wokr now
kianenigma Mar 9, 2022
1ac8c34
Master.into()
kianenigma Mar 9, 2022
8cdd144
Everything merged, tests need a lot of fixing
kianenigma Mar 10, 2022
700141e
All tests work now
kianenigma Mar 10, 2022
93d79a4
dead-end with restricted nominations
kianenigma Mar 11, 2022
2f295b7
dead-end with restricted nominations
kianenigma Mar 11, 2022
29071fc
most tests work again
kianenigma Mar 11, 2022
34b1d8a
use balance as the type for TargetList
kianenigma Mar 11, 2022
8a431dd
a little bit of self-review
kianenigma Mar 11, 2022
0ce73d5
Merge branch 'master' of github.com:paritytech/substrate into kiz-val…
kianenigma Mar 11, 2022
f892d04
fix weight_of_fn
kianenigma Mar 11, 2022
5640da7
reformat line width
kianenigma Mar 11, 2022
3aefa00
make const
kianenigma Mar 11, 2022
0923d5b
use weight of fn cached
kianenigma Mar 11, 2022
2ea0769
SortedListProvider -> VoterList
kianenigma Mar 11, 2022
4c9ef4b
Fix all build and docs
kianenigma Mar 11, 2022
b311d03
check post migration
kianenigma Mar 11, 2022
a4bbda1
better doc
kianenigma Mar 11, 2022
4c275a6
Upstream.into()
kianenigma Mar 11, 2022
19bd4cd
mostly stable and working stuff
kianenigma Mar 11, 2022
bfe5d2a
Master.into()
kianenigma Mar 25, 2022
43cec35
some fixes to make node-runtime work
kianenigma Mar 25, 2022
0d395bb
Master.into()
kianenigma Apr 13, 2022
0c8a891
Update frame/bags-list/src/list/mod.rs
kianenigma Apr 19, 2022
dbae8a5
small fixes + add an important TODO about a potential leftover bug
kianenigma May 1, 2022
96948e0
Merge branch 'kiz-revamp-sorted-list-providers-2-approval-stake' of g…
kianenigma May 1, 2022
7837d07
Master.into()
kianenigma May 1, 2022
cc7ee91
Fix a few things in the bags-list pallet
kianenigma May 1, 2022
a10ff10
cleanup a few things
kianenigma May 3, 2022
488362c
Merge branch 'master' into kiz-revamp-sorted-list-providers-2-approva…
shawntabrizi May 3, 2022
10a7ced
Update frame/staking/src/pallet/impls.rs
shawntabrizi May 3, 2022
20bc48e
Update frame/bags-list/src/list/tests.rs
shawntabrizi May 3, 2022
4e7821d
Fix everything build related
kianenigma May 3, 2022
b3ac3c4
Merge branch 'kiz-revamp-sorted-list-providers-2-approval-stake' of g…
kianenigma May 3, 2022
3381b4c
Update frame/staking/src/pallet/mod.rs
kianenigma May 3, 2022
b3aeb44
some feedback
kianenigma May 3, 2022
3258cc4
Merge branch 'kiz-revamp-sorted-list-providers-2-approval-stake' of g…
kianenigma May 3, 2022
d60d2ab
some review feedback
kianenigma May 3, 2022
8e54545
fix compile
shawntabrizi May 3, 2022
f93563f
Merge branch 'master' into kiz-revamp-sorted-list-providers-2-approva…
shawntabrizi May 4, 2022
518ffb3
fix warning
shawntabrizi May 4, 2022
8457800
Merge branch 'master' into kiz-revamp-sorted-list-providers-2-approva…
shawntabrizi Jul 26, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
cleanup a few things
  • Loading branch information
kianenigma committed May 3, 2022
commit a10ff102d90e9cc907e5f953c40fa76c0017d832
20 changes: 16 additions & 4 deletions frame/bags-list/src/list/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,10 @@ mod list {
List::<Runtime>::insert_at_unchecked(node_1, node_42);

// then
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![42, 1]), (1_000, vec![2, 3, 4])]);
assert_eq!(
List::<Runtime>::get_bags(),
vec![(10, vec![42, 1]), (1_000, vec![2, 3, 4])]
);
})
}

Expand All @@ -478,7 +481,10 @@ mod list {
List::<Runtime>::insert_at_unchecked(node_2, node_42);

// then
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![42, 2, 3, 4])]);
assert_eq!(
List::<Runtime>::get_bags(),
vec![(10, vec![1]), (1_000, vec![42, 2, 3, 4])]
);
})
}

Expand All @@ -505,7 +511,10 @@ mod list {
List::<Runtime>::insert_at_unchecked(node_3, node_42);

// then
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 42, 3, 4])]);
assert_eq!(
List::<Runtime>::get_bags(),
vec![(10, vec![1]), (1_000, vec![2, 42, 3, 4])]
);
})
}

Expand All @@ -532,7 +541,10 @@ mod list {
List::<Runtime>::insert_at_unchecked(node_4, node_42);

// then
assert_eq!(List::<Runtime>::get_bags(), vec![(10, vec![1]), (1_000, vec![2, 3, 42, 4])]);
assert_eq!(
List::<Runtime>::get_bags(),
vec![(10, vec![1]), (1_000, vec![2, 3, 42, 4])]
);
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion frame/election-provider-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ use sp_std::{fmt::Debug, prelude::*};

/// Re-export the solution generation macro.
pub use frame_election_provider_solution_type::generate_solution_type;
use frame_support::{traits::Get, BoundedVec, RuntimeDebug, weights::Weight};
use frame_support::{traits::Get, weights::Weight, BoundedVec, RuntimeDebug};
/// Re-export some type as they are used in the interface.
pub use sp_arithmetic::PerThing;
pub use sp_npos_elections::{
Expand Down
111 changes: 56 additions & 55 deletions frame/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use sp_runtime::{
traits::{IdentityLookup, Zero},
};
use sp_staking::offence::{DisableStrategy, OffenceDetails, OnOffenceHandler};
use std::{cell::RefCell, cmp::Ordering};
use std::{cell::RefCell};

pub const INIT_TIMESTAMP: u64 = 30_000;
pub const BLOCK_TIME: u64 = 1000;
Expand Down Expand Up @@ -288,59 +288,60 @@ impl<T: Config> sp_staking::OnStakerSlash<AccountId, Balance> for OnStakerSlashM
}
}

pub struct TargetBagListCompat;
impl SortedListProvider<AccountId> for TargetBagListCompat {
type Error = <TargetBagsList as SortedListProvider<AccountId>>::Error;
type Score = <TargetBagsList as SortedListProvider<AccountId>>::Score;

fn iter() -> Box<dyn Iterator<Item = AccountId>> {
let mut all = TargetBagsList::iter()
.map(|x| (x, TargetBagsList::get_score(&x).unwrap_or_default()))
.collect::<Vec<_>>();
all.sort_by(|a, b| match a.1.partial_cmp(&b.1).unwrap() {
Ordering::Equal => b.0.partial_cmp(&a.0).unwrap(),
x @ _ => x,
});
Box::new(all.into_iter().map(|(x, _)| x))
}
fn iter_from(start: &AccountId) -> Result<Box<dyn Iterator<Item = AccountId>>, Self::Error> {
TargetBagsList::iter_from(start)
}
fn count() -> u32 {
TargetBagsList::count()
}
fn contains(id: &AccountId) -> bool {
TargetBagsList::contains(id)
}
fn on_insert(id: AccountId, weight: Self::Score) -> Result<(), Self::Error> {
TargetBagsList::on_insert(id, weight)
}
fn on_update(id: &AccountId, weight: Self::Score) -> Result<(), Self::Error> {
TargetBagsList::on_update(id, weight)
}
fn get_score(id: &AccountId) -> Result<Self::Score, Self::Error> {
TargetBagsList::get_score(id)
}
fn on_remove(id: &AccountId) -> Result<(), Self::Error> {
TargetBagsList::on_remove(id)
}
fn unsafe_regenerate(
all: impl IntoIterator<Item = AccountId>,
weight_of: Box<dyn Fn(&AccountId) -> Self::Score>,
) -> u32 {
TargetBagsList::unsafe_regenerate(all, weight_of)
}
fn unsafe_clear() {
TargetBagsList::unsafe_clear();
}
fn sanity_check() -> Result<(), &'static str> {
TargetBagsList::sanity_check()
}
#[cfg(feature = "runtime-benchmarks")]
fn score_update_worst_case(_who: &AccountId, _is_increase: bool) -> Self::Score {
Balance::MAX
}
}
// pub struct TargetBagsListCompat;
// impl SortedListProvider<AccountId> for TargetBagsListCompat {
// type Error = <TargetBagsList as SortedListProvider<AccountId>>::Error;
// type Score = <TargetBagsList as SortedListProvider<AccountId>>::Score;

// fn iter() -> Box<dyn Iterator<Item = AccountId>> {
// let mut all = TargetBagsList::iter()
// .map(|x| (x, TargetBagsList::get_score(&x).unwrap_or_default()))
// .collect::<Vec<_>>();
// dbg!(&all);
// all.sort_by(|a, b| match a.1.partial_cmp(&b.1).unwrap() {
// Ordering::Equal => b.0.partial_cmp(&a.0).unwrap(),
// x @ _ => x,
// });
// Box::new(all.into_iter().map(|(x, _)| x))
// }
// fn iter_from(start: &AccountId) -> Result<Box<dyn Iterator<Item = AccountId>>, Self::Error> {
// TargetBagsList::iter_from(start)
// }
// fn count() -> u32 {
// TargetBagsList::count()
// }
// fn contains(id: &AccountId) -> bool {
// TargetBagsList::contains(id)
// }
// fn on_insert(id: AccountId, weight: Self::Score) -> Result<(), Self::Error> {
// TargetBagsList::on_insert(id, weight)
// }
// fn on_update(id: &AccountId, weight: Self::Score) -> Result<(), Self::Error> {
// TargetBagsList::on_update(id, weight)
// }
// fn get_score(id: &AccountId) -> Result<Self::Score, Self::Error> {
// TargetBagsList::get_score(id)
// }
// fn on_remove(id: &AccountId) -> Result<(), Self::Error> {
// TargetBagsList::on_remove(id)
// }
// fn unsafe_regenerate(
// all: impl IntoIterator<Item = AccountId>,
// weight_of: Box<dyn Fn(&AccountId) -> Self::Score>,
// ) -> u32 {
// TargetBagsList::unsafe_regenerate(all, weight_of)
// }
// fn unsafe_clear() {
// TargetBagsList::unsafe_clear();
// }
// fn sanity_check() -> Result<(), &'static str> {
// TargetBagsList::sanity_check()
// }
// #[cfg(feature = "runtime-benchmarks")]
// fn score_update_worst_case(_who: &AccountId, _is_increase: bool) -> Self::Score {
// Balance::MAX
// }
// }

impl crate::pallet::pallet::Config for Test {
type MaxNominations = MaxNominations;
Expand All @@ -365,7 +366,7 @@ impl crate::pallet::pallet::Config for Test {
type GenesisElectionProvider = Self::ElectionProvider;
// NOTE: consider a macro and use `UseNominatorsAndValidatorsMap<Self>` as well.
type VoterList = VoterBagsList;
type TargetList = TargetBagListCompat;
type TargetList = TargetBagsList;
type MaxUnlockingChunks = ConstU32<32>;
type OnStakerSlash = OnStakerSlashMock<Test>;
type BenchmarkingConfig = TestBenchmarkingConfig;
Expand Down
97 changes: 53 additions & 44 deletions frame/staking/src/pallet/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ impl<T: Config> Pallet<T> {
let _ = T::VoterList::on_update(&ledger.stash, to_vote(ledger.active))
.defensive_proof("any nominator should have an entry in the voter list.");

#[cfg(debug_assertions)]
Self::sanity_check_list_providers();
debug_assert!(Self::sanity_check_list_providers().is_ok());
}

// if this ledger belonged to a validator..
Expand All @@ -263,8 +262,7 @@ impl<T: Config> Pallet<T> {
let _ = T::VoterList::on_update(&ledger.stash, to_vote(ledger.active))
.defensive_proof("any validator should have an entry in the voter list.");

#[cfg(debug_assertions)]
Self::sanity_check_list_providers();
debug_assert!(Self::sanity_check_list_providers().is_ok());
}
}

Expand All @@ -276,8 +274,7 @@ impl<T: Config> Pallet<T> {
Self::deposit_event(Event::<T>::Chilled(stash.clone()));
}

#[cfg(debug_assertions)]
Self::sanity_check_approval_stakes();
debug_assert!(Self::sanity_check_list_providers().is_ok())
}

/// Actually make a payment to a staker. This uses the currency's reward function
Expand Down Expand Up @@ -628,8 +625,7 @@ impl<T: Config> Pallet<T> {
Self::do_remove_validator(stash);
Self::do_remove_nominator(stash);

#[cfg(debug_assertions)]
Self::sanity_check_approval_stakes();
debug_assert!(Self::sanity_check_list_providers().is_ok());

<Bonded<T>>::remove(stash);
<Ledger<T>>::remove(&controller);
Expand Down Expand Up @@ -813,15 +809,31 @@ impl<T: Config> Pallet<T> {
///
/// This function is self-weighing as [`DispatchClass::Mandatory`].
pub fn get_npos_targets(maybe_max_len: Option<usize>) -> Vec<T::AccountId> {
// TODO: what comes out here might not be a validator.
let targets = T::TargetList::iter()
.take(maybe_max_len.unwrap_or_else(Bounded::max_value))
.collect::<Vec<_>>();
let max_allowed_len = maybe_max_len.unwrap_or_else(|| T::TargetList::count() as usize);
let mut all_targets = Vec::<T::AccountId>::with_capacity(max_allowed_len);
let mut targets_seen = 0;

Self::register_weight(T::WeightInfo::get_npos_targets(targets.len() as u32));
log!(info, "generated {} npos targets", targets.len());
let mut targets_iter = T::TargetList::iter();
while all_targets.len() < max_allowed_len &&
targets_seen < (NPOS_MAX_ITERATIONS_COEFFICIENT * max_allowed_len as u32)
{
let target = match targets_iter.next() {
Some(target) => {
targets_seen.saturating_inc();
target
},
None => break,
};

if Validators::<T>::contains_key(&target) {
all_targets.push(target);
}
}

Self::register_weight(T::WeightInfo::get_npos_targets(all_targets.len() as u32));
log!(info, "generated {} npos targets", all_targets.len());

targets
all_targets
}

/// This function will add a nominator to the `Nominators` storage map,
Expand Down Expand Up @@ -865,9 +877,7 @@ impl<T: Config> Pallet<T> {
});

Nominators::<T>::insert(stash, nominations);

#[cfg(debug_assertions)]
Self::sanity_check_list_providers();
debug_assert!(Self::sanity_check_list_providers().is_ok())
}

/// This function will remove a nominator from the `Nominators` storage map,
Expand Down Expand Up @@ -895,9 +905,7 @@ impl<T: Config> Pallet<T> {
false
};

#[cfg(debug_assertions)]
Self::sanity_check_list_providers();

debug_assert!(Self::sanity_check_list_providers().is_ok());
outcome
}

Expand All @@ -921,9 +929,7 @@ impl<T: Config> Pallet<T> {
}

Validators::<T>::insert(who, prefs);

#[cfg(debug_assertions)]
Self::sanity_check_list_providers();
debug_assert!(Self::sanity_check_list_providers().is_ok());
}

/// This function will remove a validator from the `Validators` storage map.
Expand All @@ -946,8 +952,7 @@ impl<T: Config> Pallet<T> {
false
};

#[cfg(debug_assertions)]
Self::sanity_check_list_providers();
debug_assert!(Self::sanity_check_list_providers().is_ok());

outcome
}
Expand All @@ -964,33 +969,37 @@ impl<T: Config> Pallet<T> {

/// Perform all checks related to both [`Config::TargetList`] and [`Config::VoterList`].
#[cfg(any(debug_assertions, feature = "std"))]
pub(crate) fn sanity_check_list_providers() {
debug_assert_eq!(
Nominators::<T>::count() + Validators::<T>::count(),
T::VoterList::count()
pub(crate) fn sanity_check_list_providers() -> Result<(), &'static str> {
ensure!(
Nominators::<T>::count() + Validators::<T>::count() == T::VoterList::count(),
"invalid voter list count",
);

debug_assert_eq!(T::VoterList::sanity_check(), Ok(()));
debug_assert_eq!(T::TargetList::sanity_check(), Ok(()));
// note that we cannot say much about the count of the target list.

let _ = T::VoterList::sanity_check()?;
let _ = T::TargetList::sanity_check()?;

Ok(())
}

#[cfg(any(debug_assertions, feature = "std"))]
pub(crate) fn sanity_check_approval_stakes() {
pub(crate) fn sanity_check_approval_stakes() -> Result<(), &'static str> {
// additionally, if asked for the full check, we ensure that the TargetList is indeed
// composed of the approval stakes.
use crate::migrations::v10::InjectValidatorsApprovalStakeIntoTargetList as TargetListMigration;
let approval_stakes = TargetListMigration::<T>::build_approval_stakes();
approval_stakes.iter().for_each(|(v, a)| {
debug_assert_eq!(
T::TargetList::get_score(v).unwrap_or_default(),
*a,
"staker {:?}, score in TargetList {:?}, computed: {:?}",
v,
T::TargetList::get_score(v).unwrap_or_default(),
a
)
});
approval_stakes
.iter()
.map(|(v, a)| {
let known = T::TargetList::get_score(v).unwrap_or_default();
if known != *a {
log!(error, "wrong approval computed for {:?}: {:?} != {:?}", v, known, *a);
Err("bad approval")
} else {
Ok(())
}
})
.collect::<Result<_, _>>()
}
}

Expand Down
Loading