mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 02:21:04 +00:00
Add rules and unfounding to society. (#4671)
* Add rules and unfounding to society. * Docs and event * Extra bit of docs. * Cunningly reduce complexity * Remove candidates when unfounding. * Remove suspended candidates when unfounding, too.
This commit is contained in:
@@ -497,7 +497,7 @@ decl_module! {
|
||||
}
|
||||
|
||||
/// Vote in a referendum on behalf of a stash. If `vote.is_aye()`, the vote is to enact
|
||||
/// the proposal; otherwise it is a vote to keep the status quo.
|
||||
/// the proposal; otherwise it is a vote to keep the status quo.
|
||||
///
|
||||
/// # <weight>
|
||||
/// - O(1).
|
||||
|
||||
@@ -228,6 +228,7 @@
|
||||
//! * `defender_vote` - A member can vote to approve or reject a defender's continued membership
|
||||
//! to the society.
|
||||
//! * `payout` - A member can claim their first matured payment.
|
||||
//! * `unfound` - Allow the founder to unfound the society when they are the only member.
|
||||
//!
|
||||
//! #### For Super Users
|
||||
//!
|
||||
@@ -254,7 +255,7 @@ use sp_std::prelude::*;
|
||||
use codec::{Encode, Decode};
|
||||
use sp_runtime::{Percent, ModuleId, RuntimeDebug,
|
||||
traits::{
|
||||
StaticLookup, AccountIdConversion, Saturating, Zero, IntegerSquareRoot,
|
||||
StaticLookup, AccountIdConversion, Saturating, Zero, IntegerSquareRoot, Hash,
|
||||
TrailingZeroInput, CheckedSub, EnsureOrigin
|
||||
}
|
||||
};
|
||||
@@ -404,6 +405,10 @@ decl_storage! {
|
||||
pub Founder get(founder) build(|config: &GenesisConfig<T, I>| config.members.first().cloned()):
|
||||
Option<T::AccountId>;
|
||||
|
||||
/// A hash of the rules of this society concerning membership. Can only be set once and
|
||||
/// only by the founder.
|
||||
pub Rules get(rules): Option<T::Hash>;
|
||||
|
||||
/// The current set of candidates; bidders that are attempting to become members.
|
||||
pub Candidates get(candidates): Vec<Bid<T::AccountId, BalanceOf<T, I>>>;
|
||||
|
||||
@@ -805,6 +810,7 @@ decl_module! {
|
||||
/// Parameters:
|
||||
/// - `founder` - The first member and head of the newly founded society.
|
||||
/// - `max_members` - The initial max number of members for the society.
|
||||
/// - `rules` - The rules of this society concerning membership.
|
||||
///
|
||||
/// # <weight>
|
||||
/// - Two storage mutates to set `Head` and `Founder`. O(1)
|
||||
@@ -814,7 +820,7 @@ decl_module! {
|
||||
/// Total Complexity: O(1)
|
||||
/// # </weight>
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(10_000)]
|
||||
fn found(origin, founder: T::AccountId, max_members: u32) {
|
||||
fn found(origin, founder: T::AccountId, max_members: u32, rules: Vec<u8>) {
|
||||
T::FounderSetOrigin::ensure_origin(origin)?;
|
||||
ensure!(!<Head<T, I>>::exists(), Error::<T, I>::AlreadyFounded);
|
||||
ensure!(max_members > 1, Error::<T, I>::MaxMembers);
|
||||
@@ -823,8 +829,38 @@ decl_module! {
|
||||
Self::add_member(&founder)?;
|
||||
<Head<T, I>>::put(&founder);
|
||||
<Founder<T, I>>::put(&founder);
|
||||
Rules::<T, I>::put(T::Hashing::hash(&rules));
|
||||
Self::deposit_event(RawEvent::Founded(founder));
|
||||
}
|
||||
|
||||
/// Anull the founding of the society.
|
||||
///
|
||||
/// The dispatch origin for this call must be Signed, and the signing account must be both
|
||||
/// the `Founder` and the `Head`. This implies that it may only be done when there is one
|
||||
/// member.
|
||||
///
|
||||
/// # <weight>
|
||||
/// - Two storage reads O(1).
|
||||
/// - Four storage removals O(1).
|
||||
/// - One event.
|
||||
///
|
||||
/// Total Complexity: O(1)
|
||||
/// # </weight>
|
||||
#[weight = SimpleDispatchInfo::FixedNormal(20_000)]
|
||||
fn unfound(origin) {
|
||||
let founder = ensure_signed(origin)?;
|
||||
ensure!(Founder::<T, I>::get() == Some(founder.clone()), Error::<T, I>::NotFounder);
|
||||
ensure!(Head::<T, I>::get() == Some(founder.clone()), Error::<T, I>::NotHead);
|
||||
|
||||
Members::<T, I>::kill();
|
||||
Head::<T, I>::kill();
|
||||
Founder::<T, I>::kill();
|
||||
Rules::<T, I>::kill();
|
||||
Candidates::<T, I>::kill();
|
||||
SuspendedCandidates::<T, I>::remove_all();
|
||||
Self::deposit_event(RawEvent::Unfounded(founder));
|
||||
}
|
||||
|
||||
/// Allow suspension judgement origin to make judgement on a suspended member.
|
||||
///
|
||||
/// If a suspended member is forgiven, we simply add them back as a member, not affecting
|
||||
@@ -1047,6 +1083,10 @@ decl_error! {
|
||||
NotCandidate,
|
||||
/// Too many members in the society.
|
||||
MaxMembers,
|
||||
/// The caller is not the founder.
|
||||
NotFounder,
|
||||
/// The caller is not the head.
|
||||
NotHead,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1087,6 +1127,8 @@ decl_event! {
|
||||
DefenderVote(AccountId, bool),
|
||||
/// A new max member count has been set
|
||||
NewMaxMembers(u32),
|
||||
/// Society is unfounded.
|
||||
Unfounded(AccountId),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1224,16 +1266,16 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
|
||||
ensure!(Self::head() != Some(m.clone()), Error::<T, I>::Head);
|
||||
ensure!(Self::founder() != Some(m.clone()), Error::<T, I>::Founder);
|
||||
|
||||
<Members<T, I>>::mutate(|members|
|
||||
match members.binary_search(&m) {
|
||||
Err(_) => Err(Error::<T, I>::NotMember)?,
|
||||
Ok(i) => {
|
||||
members.remove(i);
|
||||
T::MembershipChanged::change_members_sorted(&[], &[m.clone()], members);
|
||||
Ok(())
|
||||
}
|
||||
let mut members = <Members<T, I>>::get();
|
||||
match members.binary_search(&m) {
|
||||
Err(_) => Err(Error::<T, I>::NotMember)?,
|
||||
Ok(i) => {
|
||||
members.remove(i);
|
||||
T::MembershipChanged::change_members_sorted(&[], &[m.clone()], &members[..]);
|
||||
<Members<T, I>>::put(members);
|
||||
Ok(())
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// End the current period and begin a new one.
|
||||
|
||||
@@ -21,6 +21,7 @@ use mock::*;
|
||||
|
||||
use frame_support::{assert_ok, assert_noop};
|
||||
use sp_runtime::traits::BadOrigin;
|
||||
use sp_core::blake2_256;
|
||||
|
||||
#[test]
|
||||
fn founding_works() {
|
||||
@@ -31,9 +32,9 @@ fn founding_works() {
|
||||
assert_eq!(Society::pot(), 0);
|
||||
// Account 1 is set as the founder origin
|
||||
// Account 5 cannot start a society
|
||||
assert_noop!(Society::found(Origin::signed(5), 20, 100), BadOrigin);
|
||||
assert_noop!(Society::found(Origin::signed(5), 20, 100, vec![]), BadOrigin);
|
||||
// Account 1 can start a society, where 10 is the founding member
|
||||
assert_ok!(Society::found(Origin::signed(1), 10, 100));
|
||||
assert_ok!(Society::found(Origin::signed(1), 10, 100, b"be cool".to_vec()));
|
||||
// Society members only include 10
|
||||
assert_eq!(Society::members(), vec![10]);
|
||||
// 10 is the head of the society
|
||||
@@ -42,11 +43,39 @@ fn founding_works() {
|
||||
assert_eq!(Society::founder(), Some(10));
|
||||
// 100 members max
|
||||
assert_eq!(Society::max_members(), 100);
|
||||
// rules are correct
|
||||
assert_eq!(Society::rules(), Some(blake2_256(b"be cool").into()));
|
||||
// Pot grows after first rotation period
|
||||
run_to_block(4);
|
||||
assert_eq!(Society::pot(), 1000);
|
||||
// Cannot start another society
|
||||
assert_noop!(Society::found(Origin::signed(1), 20, 100), Error::<Test, _>::AlreadyFounded);
|
||||
assert_noop!(
|
||||
Society::found(Origin::signed(1), 20, 100, vec![]),
|
||||
Error::<Test, _>::AlreadyFounded
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unfounding_works() {
|
||||
EnvBuilder::new().with_max_members(0).with_members(vec![]).execute(|| {
|
||||
// Account 1 sets the founder...
|
||||
assert_ok!(Society::found(Origin::signed(1), 10, 100, vec![]));
|
||||
// Account 2 cannot unfound it as it's not the founder.
|
||||
assert_noop!(Society::unfound(Origin::signed(2)), Error::<Test, _>::NotFounder);
|
||||
// Account 10 can, though.
|
||||
assert_ok!(Society::unfound(Origin::signed(10)));
|
||||
|
||||
// 1 sets the founder to 20 this time
|
||||
assert_ok!(Society::found(Origin::signed(1), 20, 100, vec![]));
|
||||
// Bring in a new member...
|
||||
assert_ok!(Society::bid(Origin::signed(10), 0));
|
||||
run_to_block(4);
|
||||
assert_ok!(Society::vote(Origin::signed(20), 10, true));
|
||||
run_to_block(8);
|
||||
|
||||
// Unfounding won't work now, even though it's from 20.
|
||||
assert_noop!(Society::unfound(Origin::signed(20)), Error::<Test, _>::NotHead);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user