Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Next Next commit
make instantiable
  • Loading branch information
Doordashcon committed Mar 1, 2022
commit 5c48b57af767109920d0a87359cc5d021a9b1c2d
36 changes: 18 additions & 18 deletions frame/bags-list/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,29 +36,29 @@ frame_benchmarking::benchmarks! {

// clear any pre-existing storage.
// NOTE: safe to call outside block production
List::<T>::unsafe_clear();
List::<T, I>::unsafe_clear();

// define our origin and destination thresholds.
let origin_bag_thresh = T::BagThresholds::get()[0];
let dest_bag_thresh = T::BagThresholds::get()[1];

// seed items in the origin bag.
let origin_head: T::AccountId = account("origin_head", 0, 0);
assert_ok!(List::<T>::insert(origin_head.clone(), origin_bag_thresh));
assert_ok!(List::<T, I>::insert(origin_head.clone(), origin_bag_thresh));

let origin_middle: T::AccountId = account("origin_middle", 0, 0); // the node we rebag (_R_)
assert_ok!(List::<T>::insert(origin_middle.clone(), origin_bag_thresh));
assert_ok!(List::<T, I>::insert(origin_middle.clone(), origin_bag_thresh));

let origin_tail: T::AccountId = account("origin_tail", 0, 0);
assert_ok!(List::<T>::insert(origin_tail.clone(), origin_bag_thresh));
assert_ok!(List::<T, I>::insert(origin_tail.clone(), origin_bag_thresh));

// seed items in the destination bag.
let dest_head: T::AccountId = account("dest_head", 0, 0);
assert_ok!(List::<T>::insert(dest_head.clone(), dest_bag_thresh));
assert_ok!(List::<T, I>::insert(dest_head.clone(), dest_bag_thresh));

// the bags are in the expected state after initial setup.
assert_eq!(
List::<T>::get_bags(),
List::<T, I>::get_bags(),
vec![
(origin_bag_thresh, vec![origin_head.clone(), origin_middle.clone(), origin_tail.clone()]),
(dest_bag_thresh, vec![dest_head.clone()])
Expand All @@ -72,7 +72,7 @@ frame_benchmarking::benchmarks! {
verify {
// check the bags have updated as expected.
assert_eq!(
List::<T>::get_bags(),
List::<T, I>::get_bags(),
vec![
(
origin_bag_thresh,
Expand Down Expand Up @@ -104,18 +104,18 @@ frame_benchmarking::benchmarks! {

// seed items in the origin bag.
let origin_head: T::AccountId = account("origin_head", 0, 0);
assert_ok!(List::<T>::insert(origin_head.clone(), origin_bag_thresh));
assert_ok!(List::<T, I>::insert(origin_head.clone(), origin_bag_thresh));

let origin_tail: T::AccountId = account("origin_tail", 0, 0); // the node we rebag (_R_)
assert_ok!(List::<T>::insert(origin_tail.clone(), origin_bag_thresh));
assert_ok!(List::<T, I>::insert(origin_tail.clone(), origin_bag_thresh));

// seed items in the destination bag.
let dest_head: T::AccountId = account("dest_head", 0, 0);
assert_ok!(List::<T>::insert(dest_head.clone(), dest_bag_thresh));
assert_ok!(List::<T, I>::insert(dest_head.clone(), dest_bag_thresh));

// the bags are in the expected state after initial setup.
assert_eq!(
List::<T>::get_bags(),
List::<T, I>::get_bags(),
vec![
(origin_bag_thresh, vec![origin_head.clone(), origin_tail.clone()]),
(dest_bag_thresh, vec![dest_head.clone()])
Expand All @@ -129,7 +129,7 @@ frame_benchmarking::benchmarks! {
verify {
// check the bags have updated as expected.
assert_eq!(
List::<T>::get_bags(),
List::<T, I>::get_bags(),
vec![
(origin_bag_thresh, vec![origin_head.clone()]),
(dest_bag_thresh, vec![dest_head.clone(), origin_tail.clone()])
Expand All @@ -147,30 +147,30 @@ frame_benchmarking::benchmarks! {

// insert the nodes in order
let lighter: T::AccountId = account("lighter", 0, 0);
assert_ok!(List::<T>::insert(lighter.clone(), bag_thresh));
assert_ok!(List::<T, I>::insert(lighter.clone(), bag_thresh));

let heavier_prev: T::AccountId = account("heavier_prev", 0, 0);
assert_ok!(List::<T>::insert(heavier_prev.clone(), bag_thresh));
assert_ok!(List::<T, I>::insert(heavier_prev.clone(), bag_thresh));

let heavier: T::AccountId = account("heavier", 0, 0);
assert_ok!(List::<T>::insert(heavier.clone(), bag_thresh));
assert_ok!(List::<T, I>::insert(heavier.clone(), bag_thresh));

let heavier_next: T::AccountId = account("heavier_next", 0, 0);
assert_ok!(List::<T>::insert(heavier_next.clone(), bag_thresh));
assert_ok!(List::<T, I>::insert(heavier_next.clone(), bag_thresh));

T::VoteWeightProvider::set_vote_weight_of(&lighter, bag_thresh - 1);
T::VoteWeightProvider::set_vote_weight_of(&heavier, bag_thresh);

assert_eq!(
List::<T>::iter().map(|n| n.id().clone()).collect::<Vec<_>>(),
List::<T, I>::iter().map(|n| n.id().clone()).collect::<Vec<_>>(),
vec![lighter.clone(), heavier_prev.clone(), heavier.clone(), heavier_next.clone()]
);

whitelist_account!(heavier);
}: _(SystemOrigin::Signed(heavier.clone()), lighter.clone())
verify {
assert_eq!(
List::<T>::iter().map(|n| n.id().clone()).collect::<Vec<_>>(),
List::<T, I>::iter().map(|n| n.id().clone()).collect::<Vec<_>>(),
vec![heavier, lighter, heavier_prev, heavier_next]
)
}
Expand Down
54 changes: 27 additions & 27 deletions frame/bags-list/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ pub mod pallet {

#[pallet::pallet]
#[pallet::generate_store(pub(crate) trait Store)]
pub struct Pallet<T>(_);
pub struct Pallet<T, I = ()>(_);

#[pallet::config]
pub trait Config: frame_system::Config {
pub trait Config<I: 'static = ()>: frame_system::Config {
/// The overarching event type.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;

/// Weight information for extrinsics in this pallet.
type WeightInfo: weights::WeightInfo;
Expand Down Expand Up @@ -156,25 +156,25 @@ pub mod pallet {
///
/// Nodes store links forward and back within their respective bags.
#[pallet::storage]
pub(crate) type ListNodes<T: Config> =
CountedStorageMap<_, Twox64Concat, T::AccountId, list::Node<T>>;
pub(crate) type ListNodes<T: Config<I>, I: 'static = ()> =
CountedStorageMap<_, Twox64Concat, T::AccountId, list::Node<T, I>>;

/// A bag stored in storage.
///
/// Stores a `Bag` struct, which stores head and tail pointers to itself.
#[pallet::storage]
pub(crate) type ListBags<T: Config> = StorageMap<_, Twox64Concat, VoteWeight, list::Bag<T>>;
pub(crate) type ListBags<T: Config<I>, I: 'static = ()> = StorageMap<_, Twox64Concat, VoteWeight, list::Bag<T, I>>;

#[pallet::event]
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config> {
pub enum Event<T: Config<I>, I: 'static = ()> {
/// Moved an account from one bag to another.
Rebagged { who: T::AccountId, from: VoteWeight, to: VoteWeight },
}

#[pallet::error]
#[cfg_attr(test, derive(PartialEq))]
pub enum Error<T> {
pub enum Error<T, I = ()> {
/// Attempted to place node in front of a node in another bag.
NotInSameBag,
/// Id not found in list.
Expand All @@ -184,7 +184,7 @@ pub mod pallet {
}

#[pallet::call]
impl<T: Config> Pallet<T> {
impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Declare that some `dislocated` account has, through rewards or penalties, sufficiently
/// changed its weight that it should properly fall into a different bag than its current
/// one.
Expand All @@ -197,7 +197,7 @@ pub mod pallet {
pub fn rebag(origin: OriginFor<T>, dislocated: T::AccountId) -> DispatchResult {
ensure_signed(origin)?;
let current_weight = T::VoteWeightProvider::vote_weight(&dislocated);
let _ = Pallet::<T>::do_rebag(&dislocated, current_weight);
let _ = Pallet::<T, I>::do_rebag(&dislocated, current_weight);
Ok(())
}

Expand All @@ -212,12 +212,12 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::put_in_front_of())]
pub fn put_in_front_of(origin: OriginFor<T>, lighter: T::AccountId) -> DispatchResult {
let heavier = ensure_signed(origin)?;
List::<T>::put_in_front_of(&lighter, &heavier).map_err(Into::into)
List::<T, I>::put_in_front_of(&lighter, &heavier).map_err(Into::into)
}
}

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
fn integrity_test() {
// ensure they are strictly increasing, this also implies that duplicates are detected.
assert!(
Expand All @@ -228,7 +228,7 @@ pub mod pallet {
}
}

impl<T: Config> Pallet<T> {
impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Move an account from one bag to another, depositing an event on success.
///
/// If the account changed bags, returns `Some((from, to))`.
Expand All @@ -238,46 +238,46 @@ impl<T: Config> Pallet<T> {
) -> Option<(VoteWeight, VoteWeight)> {
// if no voter at that node, don't do anything.
// the caller just wasted the fee to call this.
let maybe_movement = list::Node::<T>::get(&account)
let maybe_movement = list::Node::<T, I>::get(&account)
.and_then(|node| List::update_position_for(node, new_weight));
if let Some((from, to)) = maybe_movement {
Self::deposit_event(Event::<T>::Rebagged { who: account.clone(), from, to });
Self::deposit_event(Event::<T, I>::Rebagged { who: account.clone(), from, to });
};
maybe_movement
}

/// Equivalent to `ListBags::get`, but public. Useful for tests in outside of this crate.
#[cfg(feature = "std")]
pub fn list_bags_get(weight: VoteWeight) -> Option<list::Bag<T>> {
pub fn list_bags_get(weight: VoteWeight) -> Option<list::Bag<T, I>> {
ListBags::get(weight)
}
}

impl<T: Config> SortedListProvider<T::AccountId> for Pallet<T> {
impl<T: Config<I>, I: 'static> SortedListProvider<T::AccountId> for Pallet<T, I> {
type Error = Error;

fn iter() -> Box<dyn Iterator<Item = T::AccountId>> {
Box::new(List::<T>::iter().map(|n| n.id().clone()))
Box::new(List::<T, I>::iter().map(|n| n.id().clone()))
}

fn count() -> u32 {
ListNodes::<T>::count()
ListNodes::<T, I>::count()
}

fn contains(id: &T::AccountId) -> bool {
List::<T>::contains(id)
List::<T, I>::contains(id)
}

fn on_insert(id: T::AccountId, weight: VoteWeight) -> Result<(), Error> {
List::<T>::insert(id, weight)
List::<T, I>::insert(id, weight)
}

fn on_update(id: &T::AccountId, new_weight: VoteWeight) {
Pallet::<T>::do_rebag(id, new_weight);
Pallet::<T, I>::do_rebag(id, new_weight);
}

fn on_remove(id: &T::AccountId) {
List::<T>::remove(id)
List::<T, I>::remove(id)
}

fn unsafe_regenerate(
Expand All @@ -287,12 +287,12 @@ impl<T: Config> SortedListProvider<T::AccountId> for Pallet<T> {
// NOTE: This call is unsafe for the same reason as SortedListProvider::unsafe_regenerate.
// I.e. because it can lead to many storage accesses.
// So it is ok to call it as caller must ensure the conditions.
List::<T>::unsafe_regenerate(all, weight_of)
List::<T, I>::unsafe_regenerate(all, weight_of)
}

#[cfg(feature = "std")]
fn sanity_check() -> Result<(), &'static str> {
List::<T>::sanity_check()
List::<T, I>::sanity_check()
}

#[cfg(not(feature = "std"))]
Expand All @@ -304,14 +304,14 @@ impl<T: Config> SortedListProvider<T::AccountId> for Pallet<T> {
// NOTE: This call is unsafe for the same reason as SortedListProvider::unsafe_clear.
// I.e. because it can lead to many storage accesses.
// So it is ok to call it as caller must ensure the conditions.
List::<T>::unsafe_clear()
List::<T, I>::unsafe_clear()
}

#[cfg(feature = "runtime-benchmarks")]
fn weight_update_worst_case(who: &T::AccountId, is_increase: bool) -> VoteWeight {
use frame_support::traits::Get as _;
let thresholds = T::BagThresholds::get();
let node = list::Node::<T>::get(who).unwrap();
let node = list::Node::<T, I>::get(who).unwrap();
let current_bag_idx = thresholds
.iter()
.chain(sp_std::iter::once(&VoteWeight::MAX))
Expand Down
Loading