[FRAME] Make core-fellowship ans salary work for swapped members (#3156)

Fixup for https://github.com/paritytech/polkadot-sdk/pull/2587 to make
the `core-fellowship` crate work with swapped members.

Adds a `MemberSwappedHandler` to the `ranked-collective` pallet that are
implemented by `core-fellowship+salary`.
There is are exhaustive tests
[here](https://github.com/paritytech/polkadot-sdk/blob/72aa7ac17a0e5b16faab5d2992aa2db2e01b05d0/substrate/frame/core-fellowship/src/tests/integration.rs#L338)
and
[here](https://github.com/paritytech/polkadot-sdk/blob/ab3cdb05a5ebc1ff841f8dda67edef0ea40bbba5/substrate/frame/salary/src/tests/integration.rs#L224)
to check that adding member `1` is equivalent to adding member `0` and
then swapping.

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
Oliver Tale-Yazdi
2024-01-31 17:29:48 +01:00
committed by GitHub
parent 6ea472ad5a
commit 07e55006ad
25 changed files with 795 additions and 69 deletions
@@ -65,10 +65,12 @@ use sp_runtime::RuntimeDebug;
use sp_std::{marker::PhantomData, prelude::*};
use frame_support::{
defensive,
dispatch::DispatchResultWithPostInfo,
ensure, impl_ensure_origin_with_arg_ignoring_arg,
traits::{
tokens::Balance as BalanceTrait, EnsureOrigin, EnsureOriginWithArg, Get, RankedMembers,
RankedMembersSwapHandler,
},
BoundedVec,
};
@@ -249,6 +251,8 @@ pub mod pallet {
},
/// Pre-ranked account has been inducted at their current rank.
Imported { who: T::AccountId, rank: RankOf<T, I> },
/// A member had its AccountId swapped.
Swapped { who: T::AccountId, new_who: T::AccountId },
}
#[pallet::error]
@@ -603,3 +607,38 @@ impl_ensure_origin_with_arg_ignoring_arg! {
EnsureOriginWithArg<T::RuntimeOrigin, A> for EnsureInducted<T, I, MIN_RANK>
{}
}
impl<T: Config<I>, I: 'static> RankedMembersSwapHandler<T::AccountId, u16> for Pallet<T, I> {
fn swapped(old: &T::AccountId, new: &T::AccountId, _rank: u16) {
if old == new {
defensive!("Should not try to swap with self");
return
}
if !Member::<T, I>::contains_key(old) {
defensive!("Should not try to swap non-member");
return
}
if Member::<T, I>::contains_key(new) {
defensive!("Should not try to overwrite existing member");
return
}
if let Some(member) = Member::<T, I>::take(old) {
Member::<T, I>::insert(new, member);
}
if let Some(we) = MemberEvidence::<T, I>::take(old) {
MemberEvidence::<T, I>::insert(new, we);
}
Self::deposit_event(Event::<T, I>::Swapped { who: old.clone(), new_who: new.clone() });
}
}
#[cfg(feature = "runtime-benchmarks")]
impl<T: Config<I>, I: 'static>
pallet_ranked_collective::BenchmarkSetup<<T as frame_system::Config>::AccountId> for Pallet<T, I>
{
fn ensure_member(who: &<T as frame_system::Config>::AccountId) {
Self::import(frame_system::RawOrigin::Signed(who.clone()).into()).unwrap();
}
}