Alliance pallet: split force_set_members call (#12179)

* Alliance pallet: split force_set_members call

* use counts for event

* ".git/.scripts/bench-bot.sh" pallet dev pallet_alliance

Co-authored-by: command-bot <>
This commit is contained in:
Muharem Ismailov
2022-09-05 17:08:50 +02:00
committed by GitHub
parent b6f67b08ed
commit f919894c84
8 changed files with 358 additions and 512 deletions
+66 -76
View File
@@ -84,7 +84,8 @@
//!
//! #### Root Calls
//!
//! - `force_set_members` - Set the members via chain governance.
//! - `init_members` - Initialize the Alliance, onboard founders, fellows, and allies.
//! - `disband` - Disband the Alliance, remove all active members and unreserve deposits.
#![cfg_attr(not(feature = "std"), no_std)]
@@ -204,14 +205,6 @@ pub trait ProposalProvider<AccountId, Hash, Proposal> {
/// Return a proposal of the given hash.
fn proposal_of(proposal_hash: Hash) -> Option<Proposal>;
/// Return hashes of all active proposals.
fn proposals() -> Vec<Hash>;
// Return count of all active proposals.
//
// Used to check witness data for an extrinsic.
fn proposals_count() -> u32;
}
/// The various roles that a member can hold.
@@ -428,8 +421,8 @@ pub mod pallet {
UnscrupulousItemAdded { items: Vec<UnscrupulousItemOf<T, I>> },
/// Accounts or websites have been removed from the list of unscrupulous items.
UnscrupulousItemRemoved { items: Vec<UnscrupulousItemOf<T, I>> },
/// Alliance disbanded.
AllianceDisbanded { members: Vec<T::AccountId>, proposals: Vec<T::Hash> },
/// Alliance disbanded. Includes number deleted members and unreserved deposits.
AllianceDisbanded { voting_members: u32, ally_members: u32, unreserved: u32 },
}
#[pallet::genesis_config]
@@ -647,81 +640,25 @@ pub mod pallet {
Ok(info.into())
}
/// Initialize the founders, fellows, and allies.
/// Founders must be provided to initialize the Alliance.
///
/// Provide witness data to disband current Alliance before initializing new.
/// Alliance must be empty or disband first to initialize new.
///
/// Alliance is only disbanded if new member set is not provided.
/// Initialize the Alliance, onboard founders, fellows, and allies.
///
/// Founders must be not empty.
/// The Alliance must be empty.
/// Must be called by the Root origin.
#[pallet::weight(T::WeightInfo::force_set_members(
T::MaxFounders::get(),
T::MaxFellows::get(),
T::MaxAllies::get(),
witness.proposals,
witness.voting_members,
witness.ally_members,
#[pallet::weight(T::WeightInfo::init_members(
founders.len() as u32,
fellows.len() as u32,
allies.len() as u32,
))]
pub fn force_set_members(
pub fn init_members(
origin: OriginFor<T>,
founders: Vec<T::AccountId>,
fellows: Vec<T::AccountId>,
allies: Vec<T::AccountId>,
witness: ForceSetWitness,
) -> DispatchResult {
ensure_root(origin)?;
if !witness.is_zero() {
// Disband Alliance by removing all members and returning deposits.
// Veto and remove all active proposals to avoid any unexpected behavior from
// actionable items managed outside of the pallet. Items managed within the pallet,
// like `UnscrupulousWebsites`, are left for the new Alliance to clean up or keep.
ensure!(
T::ProposalProvider::proposals_count() <= witness.proposals,
Error::<T, I>::BadWitness
);
ensure!(
Self::voting_members_count() <= witness.voting_members,
Error::<T, I>::BadWitness
);
ensure!(
Self::ally_members_count() <= witness.ally_members,
Error::<T, I>::BadWitness
);
let mut proposals = T::ProposalProvider::proposals();
for hash in proposals.iter() {
T::ProposalProvider::veto_proposal(*hash);
}
let mut members = Self::voting_members();
T::MembershipChanged::change_members_sorted(&[], &members, &[]);
members.append(&mut Self::members_of(MemberRole::Ally));
for member in members.iter() {
if let Some(deposit) = DepositOf::<T, I>::take(&member) {
let err_amount = T::Currency::unreserve(&member, deposit);
debug_assert!(err_amount.is_zero());
}
}
Members::<T, I>::remove(&MemberRole::Founder);
Members::<T, I>::remove(&MemberRole::Fellow);
Members::<T, I>::remove(&MemberRole::Ally);
members.sort();
proposals.sort();
Self::deposit_event(Event::AllianceDisbanded { members, proposals });
}
if founders.is_empty() {
ensure!(fellows.is_empty() && allies.is_empty(), Error::<T, I>::FoundersMissing);
// new members set not provided.
return Ok(())
}
ensure!(!founders.is_empty(), Error::<T, I>::FoundersMissing);
ensure!(!Self::is_initialized(), Error::<T, I>::AllianceAlreadyInitialized);
let mut founders: BoundedVec<T::AccountId, T::MaxMembersCount> =
@@ -765,6 +702,59 @@ pub mod pallet {
Ok(())
}
/// Disband the Alliance, remove all active members and unreserve deposits.
///
/// Witness data must be set.
#[pallet::weight(T::WeightInfo::disband(
witness.voting_members,
witness.ally_members,
witness.voting_members + witness.ally_members,
))]
pub fn disband(
origin: OriginFor<T>,
witness: DisbandWitness,
) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
ensure!(!witness.is_zero(), Error::<T, I>::BadWitness);
ensure!(
Self::voting_members_count() <= witness.voting_members,
Error::<T, I>::BadWitness
);
ensure!(Self::ally_members_count() <= witness.ally_members, Error::<T, I>::BadWitness);
ensure!(Self::is_initialized(), Error::<T, I>::AllianceNotYetInitialized);
let voting_members = Self::voting_members();
T::MembershipChanged::change_members_sorted(&[], &voting_members, &[]);
let ally_members = Self::members_of(MemberRole::Ally);
let mut unreserve_count: u32 = 0;
for member in voting_members.iter().chain(ally_members.iter()) {
if let Some(deposit) = DepositOf::<T, I>::take(&member) {
let err_amount = T::Currency::unreserve(&member, deposit);
debug_assert!(err_amount.is_zero());
unreserve_count += 1;
}
}
Members::<T, I>::remove(&MemberRole::Founder);
Members::<T, I>::remove(&MemberRole::Fellow);
Members::<T, I>::remove(&MemberRole::Ally);
Self::deposit_event(Event::AllianceDisbanded {
voting_members: voting_members.len() as u32,
ally_members: ally_members.len() as u32,
unreserved: unreserve_count,
});
Ok(Some(T::WeightInfo::disband(
voting_members.len() as u32,
ally_members.len() as u32,
unreserve_count,
))
.into())
}
/// Set a new IPFS CID to the alliance rule.
#[pallet::weight(T::WeightInfo::set_rule())]
pub fn set_rule(origin: OriginFor<T>, rule: Cid) -> DispatchResult {