From 072f0026d1f6964c49a7097d48fcd0f16871835e Mon Sep 17 00:00:00 2001 From: abdbee Date: Sun, 8 Dec 2024 03:19:47 +0100 Subject: [PATCH] extend Tally to include no-rank votes, update test --- substrate/frame/ranked-collective/src/lib.rs | 51 +++++++++++++++---- .../frame/ranked-collective/src/tests.rs | 22 ++++---- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/substrate/frame/ranked-collective/src/lib.rs b/substrate/frame/ranked-collective/src/lib.rs index 586865b8b487f..25eab015269ec 100644 --- a/substrate/frame/ranked-collective/src/lib.rs +++ b/substrate/frame/ranked-collective/src/lib.rs @@ -96,14 +96,17 @@ pub type Votes = u32; #[codec(mel_bound())] pub struct Tally { bare_ayes: MemberIndex, + out_of_rank_ayes: MemberIndex, + out_of_rank_nays: MemberIndex, ayes: Votes, nays: Votes, dummy: PhantomData<(T, I, M)>, + } impl, I: 'static, M: GetMaxVoters> Tally { - pub fn from_parts(bare_ayes: MemberIndex, ayes: Votes, nays: Votes) -> Self { - Tally { bare_ayes, ayes, nays, dummy: PhantomData } + pub fn from_parts(bare_ayes: MemberIndex, out_of_rank_ayes: MemberIndex, out_of_rank_nays: MemberIndex, ayes: Votes, nays: Votes) -> Self { + Tally { bare_ayes, out_of_rank_ayes, out_of_rank_nays, ayes, nays, dummy: PhantomData } } } @@ -123,7 +126,7 @@ impl, I: 'static, M: GetMaxVoters>> VoteTally> for Tally { fn new(_: ClassOf) -> Self { - Self { bare_ayes: 0, ayes: 0, nays: 0, dummy: PhantomData } + Self { bare_ayes: 0, out_of_rank_ayes: 0, out_of_rank_nays: 0, ayes: 0, nays: 0, dummy: PhantomData } } fn ayes(&self, _: ClassOf) -> Votes { self.bare_ayes @@ -629,22 +632,48 @@ pub mod pallet { PollStatus::Ongoing(ref mut tally, class) => { match Voting::::get(&poll, &who) { Some(Aye(votes)) => { - tally.bare_ayes.saturating_dec(); - tally.ayes.saturating_reduce(votes); + if votes > 0 { + tally.bare_ayes.saturating_dec(); + tally.ayes.saturating_reduce(votes); + } else { + tally.out_of_rank_ayes.saturating_dec(); + } + + }, + Some(Nay(votes)) => { + if votes > 0 { + tally.nays.saturating_reduce(votes) + } else { + tally.out_of_rank_nays.saturating_dec(); + } }, - Some(Nay(votes)) => tally.nays.saturating_reduce(votes), None => pays = Pays::No, } let min_rank = T::MinRankOfClass::convert(class); let votes = Self::rank_to_votes(record.rank, min_rank).unwrap_or(0); let vote = VoteRecord::from((aye, votes)); - match aye { - true => { - tally.bare_ayes.saturating_inc(); - tally.ayes.saturating_accrue(votes); + match votes { + 0 => { + match aye { + true => { + tally.out_of_rank_ayes.saturating_inc(); + }, + false => { + tally.out_of_rank_nays.saturating_inc(); + }, + } + }, + _ => { + match aye { + true => { + tally.bare_ayes.saturating_inc(); + tally.ayes.saturating_accrue(votes); + }, + false => tally.nays.saturating_accrue(votes), + } }, - false => tally.nays.saturating_accrue(votes), } + Voting::::insert(&poll, &who, &vote); Ok((tally.clone(), vote)) }, diff --git a/substrate/frame/ranked-collective/src/tests.rs b/substrate/frame/ranked-collective/src/tests.rs index 47e3057fdb406..e2f180b05e7ab 100644 --- a/substrate/frame/ranked-collective/src/tests.rs +++ b/substrate/frame/ranked-collective/src/tests.rs @@ -59,7 +59,7 @@ parameter_types! { pub static Polls: BTreeMap = vec![ (1, Completed(1, true)), (2, Completed(2, false)), - (3, Ongoing(Tally::from_parts(0, 0, 0), 1)), + (3, Ongoing(Tally::from_parts(0, 0, 0, 0, 0), 1)), ].into_iter().collect(); } @@ -253,7 +253,7 @@ fn completed_poll_should_panic() { #[test] fn basic_stuff() { ExtBuilder::default().build_and_execute(|| { - assert_eq!(tally(3), Tally::from_parts(0, 0, 0)); + assert_eq!(tally(3), Tally::from_parts(0, 0, 0, 0, 0)); }); } @@ -412,22 +412,24 @@ fn voting_works() { assert_ok!(Club::promote_member(RuntimeOrigin::root(), 3)); assert_ok!(Club::vote(RuntimeOrigin::signed(0), 3, true)); - assert_eq!(tally(3), Tally::from_parts(1, 0, 0)); + assert_eq!(tally(3), Tally::from_parts(0, 1, 0, 0, 0)); + assert_ok!(Club::vote(RuntimeOrigin::signed(0), 3, false)); + assert_eq!(tally(3), Tally::from_parts(0, 0, 1, 0, 0)); assert_ok!(Club::vote(RuntimeOrigin::signed(1), 3, true)); - assert_eq!(tally(3), Tally::from_parts(2, 1, 0)); + assert_eq!(tally(3), Tally::from_parts(1, 0, 1, 1, 0)); assert_ok!(Club::vote(RuntimeOrigin::signed(1), 3, false)); - assert_eq!(tally(3), Tally::from_parts(1, 0, 1)); + assert_eq!(tally(3), Tally::from_parts(0, 0, 1, 0, 1)); assert_ok!(Club::vote(RuntimeOrigin::signed(2), 3, true)); - assert_eq!(tally(3), Tally::from_parts(2, 3, 1)); + assert_eq!(tally(3), Tally::from_parts(1, 0, 1, 3, 1)); assert_ok!(Club::vote(RuntimeOrigin::signed(2), 3, false)); - assert_eq!(tally(3), Tally::from_parts(1, 0, 4)); + assert_eq!(tally(3), Tally::from_parts(0, 0, 1, 0, 4)); assert_ok!(Club::vote(RuntimeOrigin::signed(3), 3, true)); - assert_eq!(tally(3), Tally::from_parts(2, 6, 4)); + assert_eq!(tally(3), Tally::from_parts(1, 0, 1, 6, 4)); assert_ok!(Club::vote(RuntimeOrigin::signed(3), 3, false)); - assert_eq!(tally(3), Tally::from_parts(1, 0, 10)); + assert_eq!(tally(3), Tally::from_parts(0, 0, 1, 0, 10)); }); } @@ -588,7 +590,7 @@ fn tally_support_correct() { assert_ok!(Club::promote_member(RuntimeOrigin::root(), 3)); // init tally with 1 aye vote. - let tally: TallyOf = Tally::from_parts(1, 1, 0); + let tally: TallyOf = Tally::from_parts(1, 0, 0, 1, 0); // with minRank(Class) = Class // for class 3, 100% support.