mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-21 05:11:02 +00:00
exchange member with a new account and same rank in the ranked collec… (#2587)
closes https://github.com/polkadot-fellows/help-center/issues/1 --------- Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: command-bot <> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
@@ -161,6 +161,7 @@ impl<T: Config<I>, I: 'static, M: GetMaxVoters<Class = ClassOf<T, I>>>
|
||||
crate::Pallet::<T, I>::do_add_member_to_rank(
|
||||
who,
|
||||
T::MinRankOfClass::convert(class.clone()),
|
||||
true,
|
||||
)
|
||||
.expect("could not add members for benchmarks");
|
||||
}
|
||||
@@ -299,7 +300,7 @@ impl<T: Config<I>, I: 'static> EnsureOriginWithArg<T::RuntimeOrigin, Rank> for E
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin(min_rank: &Rank) -> Result<T::RuntimeOrigin, ()> {
|
||||
let who = frame_benchmarking::account::<T::AccountId>("successful_origin", 0, 0);
|
||||
crate::Pallet::<T, I>::do_add_member_to_rank(who.clone(), *min_rank)
|
||||
crate::Pallet::<T, I>::do_add_member_to_rank(who.clone(), *min_rank, true)
|
||||
.expect("Could not add members for benchmarks");
|
||||
Ok(frame_system::RawOrigin::Signed(who).into())
|
||||
}
|
||||
@@ -352,7 +353,7 @@ impl<T: Config<I>, I: 'static, const MIN_RANK: u16> EnsureOrigin<T::RuntimeOrigi
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
fn try_successful_origin() -> Result<T::RuntimeOrigin, ()> {
|
||||
let who = frame_benchmarking::account::<T::AccountId>("successful_origin", 0, 0);
|
||||
crate::Pallet::<T, I>::do_add_member_to_rank(who.clone(), MIN_RANK)
|
||||
crate::Pallet::<T, I>::do_add_member_to_rank(who.clone(), MIN_RANK, true)
|
||||
.expect("Could not add members for benchmarks");
|
||||
Ok(frame_system::RawOrigin::Signed(who).into())
|
||||
}
|
||||
@@ -390,6 +391,9 @@ pub mod pallet {
|
||||
/// maximum rank *from which* the demotion/removal may be.
|
||||
type DemoteOrigin: EnsureOrigin<Self::RuntimeOrigin, Success = Rank>;
|
||||
|
||||
/// The origin that can swap the account of a member.
|
||||
type ExchangeOrigin: EnsureOrigin<Self::RuntimeOrigin>;
|
||||
|
||||
/// The polling system used for our voting.
|
||||
type Polls: Polling<TallyOf<Self, I>, Votes = Votes, Moment = BlockNumberFor<Self>>;
|
||||
|
||||
@@ -454,6 +458,8 @@ pub mod pallet {
|
||||
/// The member `who` has voted for the `poll` with the given `vote` leading to an updated
|
||||
/// `tally`.
|
||||
Voted { who: T::AccountId, poll: PollIndexOf<T, I>, vote: VoteRecord, tally: TallyOf<T, I> },
|
||||
/// The member `who` had their `AccountId` changed to `new_who`.
|
||||
MemberExchanged { who: T::AccountId, new_who: T::AccountId },
|
||||
}
|
||||
|
||||
#[pallet::error]
|
||||
@@ -476,6 +482,8 @@ pub mod pallet {
|
||||
InvalidWitness,
|
||||
/// The origin is not sufficiently privileged to do the operation.
|
||||
NoPermission,
|
||||
/// The new member to exchange is the same as the old member
|
||||
SameMember,
|
||||
}
|
||||
|
||||
#[pallet::call]
|
||||
@@ -492,7 +500,7 @@ pub mod pallet {
|
||||
pub fn add_member(origin: OriginFor<T>, who: AccountIdLookupOf<T>) -> DispatchResult {
|
||||
let _ = T::PromoteOrigin::ensure_origin(origin)?;
|
||||
let who = T::Lookup::lookup(who)?;
|
||||
Self::do_add_member(who)
|
||||
Self::do_add_member(who, true)
|
||||
}
|
||||
|
||||
/// Increment the rank of an existing member by one.
|
||||
@@ -506,7 +514,7 @@ pub mod pallet {
|
||||
pub fn promote_member(origin: OriginFor<T>, who: AccountIdLookupOf<T>) -> DispatchResult {
|
||||
let max_rank = T::PromoteOrigin::ensure_origin(origin)?;
|
||||
let who = T::Lookup::lookup(who)?;
|
||||
Self::do_promote_member(who, Some(max_rank))
|
||||
Self::do_promote_member(who, Some(max_rank), true)
|
||||
}
|
||||
|
||||
/// Decrement the rank of an existing member by one. If the member is already at rank zero,
|
||||
@@ -544,10 +552,7 @@ pub mod pallet {
|
||||
ensure!(min_rank >= rank, Error::<T, I>::InvalidWitness);
|
||||
ensure!(max_rank >= rank, Error::<T, I>::NoPermission);
|
||||
|
||||
for r in 0..=rank {
|
||||
Self::remove_from_rank(&who, r)?;
|
||||
}
|
||||
Members::<T, I>::remove(&who);
|
||||
Self::do_remove_member_from_rank(&who, rank)?;
|
||||
Self::deposit_event(Event::MemberRemoved { who, rank });
|
||||
Ok(PostDispatchInfo {
|
||||
actual_weight: Some(T::WeightInfo::remove_member(rank as u32)),
|
||||
@@ -650,6 +655,33 @@ pub mod pallet {
|
||||
pays_fee: Pays::No,
|
||||
})
|
||||
}
|
||||
|
||||
/// Exchanges a member with a new account and the same existing rank.
|
||||
///
|
||||
/// - `origin`: Must be the `ExchangeOrigin`.
|
||||
/// - `who`: Account of existing member of rank greater than zero to be exchanged.
|
||||
/// - `new_who`: New Account of existing member of rank greater than zero to exchanged to.
|
||||
#[pallet::call_index(6)]
|
||||
#[pallet::weight(T::WeightInfo::exchange_member())]
|
||||
pub fn exchange_member(
|
||||
origin: OriginFor<T>,
|
||||
who: AccountIdLookupOf<T>,
|
||||
new_who: AccountIdLookupOf<T>,
|
||||
) -> DispatchResult {
|
||||
T::ExchangeOrigin::ensure_origin(origin)?;
|
||||
let who = T::Lookup::lookup(who)?;
|
||||
let new_who = T::Lookup::lookup(new_who)?;
|
||||
|
||||
ensure!(who != new_who, Error::<T, I>::SameMember);
|
||||
|
||||
let MemberRecord { rank, .. } = Self::ensure_member(&who)?;
|
||||
|
||||
Self::do_remove_member_from_rank(&who, rank)?;
|
||||
Self::do_add_member_to_rank(new_who.clone(), rank, false)?;
|
||||
|
||||
Self::deposit_event(Event::MemberExchanged { who, new_who });
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
@@ -683,7 +715,7 @@ pub mod pallet {
|
||||
/// Adds a member into the ranked collective at level 0.
|
||||
///
|
||||
/// No origin checks are executed.
|
||||
pub fn do_add_member(who: T::AccountId) -> DispatchResult {
|
||||
pub fn do_add_member(who: T::AccountId, emit_event: bool) -> DispatchResult {
|
||||
ensure!(!Members::<T, I>::contains_key(&who), Error::<T, I>::AlreadyMember);
|
||||
let index = MemberCount::<T, I>::get(0);
|
||||
let count = index.checked_add(1).ok_or(Overflow)?;
|
||||
@@ -692,7 +724,9 @@ pub mod pallet {
|
||||
IdToIndex::<T, I>::insert(0, &who, index);
|
||||
IndexToId::<T, I>::insert(0, index, &who);
|
||||
MemberCount::<T, I>::insert(0, count);
|
||||
Self::deposit_event(Event::MemberAdded { who });
|
||||
if emit_event {
|
||||
Self::deposit_event(Event::MemberAdded { who });
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -703,6 +737,7 @@ pub mod pallet {
|
||||
pub fn do_promote_member(
|
||||
who: T::AccountId,
|
||||
maybe_max_rank: Option<Rank>,
|
||||
emit_event: bool,
|
||||
) -> DispatchResult {
|
||||
let record = Self::ensure_member(&who)?;
|
||||
let rank = record.rank.checked_add(1).ok_or(Overflow)?;
|
||||
@@ -714,7 +749,9 @@ pub mod pallet {
|
||||
IdToIndex::<T, I>::insert(rank, &who, index);
|
||||
IndexToId::<T, I>::insert(rank, index, &who);
|
||||
Members::<T, I>::insert(&who, MemberRecord { rank });
|
||||
Self::deposit_event(Event::RankChanged { who, rank });
|
||||
if emit_event {
|
||||
Self::deposit_event(Event::RankChanged { who, rank });
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -747,10 +784,14 @@ pub mod pallet {
|
||||
|
||||
/// Add a member to the rank collective, and continue to promote them until a certain rank
|
||||
/// is reached.
|
||||
pub fn do_add_member_to_rank(who: T::AccountId, rank: Rank) -> DispatchResult {
|
||||
Self::do_add_member(who.clone())?;
|
||||
pub fn do_add_member_to_rank(
|
||||
who: T::AccountId,
|
||||
rank: Rank,
|
||||
emit_event: bool,
|
||||
) -> DispatchResult {
|
||||
Self::do_add_member(who.clone(), emit_event)?;
|
||||
for _ in 0..rank {
|
||||
Self::do_promote_member(who.clone(), None)?;
|
||||
Self::do_promote_member(who.clone(), None, emit_event)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -763,6 +804,15 @@ pub mod pallet {
|
||||
use frame_support::traits::CallerTrait;
|
||||
o.as_signed().and_then(Self::rank_of)
|
||||
}
|
||||
|
||||
/// Removes a member from the rank collective
|
||||
pub fn do_remove_member_from_rank(who: &T::AccountId, rank: Rank) -> DispatchResult {
|
||||
for r in 0..=rank {
|
||||
Self::remove_from_rank(&who, r)?;
|
||||
}
|
||||
Members::<T, I>::remove(&who);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config<I>, I: 'static> RankedMembers for Pallet<T, I> {
|
||||
@@ -778,11 +828,11 @@ pub mod pallet {
|
||||
}
|
||||
|
||||
fn induct(who: &Self::AccountId) -> DispatchResult {
|
||||
Self::do_add_member(who.clone())
|
||||
Self::do_add_member(who.clone(), true)
|
||||
}
|
||||
|
||||
fn promote(who: &Self::AccountId) -> DispatchResult {
|
||||
Self::do_promote_member(who.clone(), None)
|
||||
Self::do_promote_member(who.clone(), None, true)
|
||||
}
|
||||
|
||||
fn demote(who: &Self::AccountId) -> DispatchResult {
|
||||
|
||||
Reference in New Issue
Block a user