Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Custom vote weights
Browse files Browse the repository at this point in the history
  • Loading branch information
gavofyork committed May 24, 2022
1 parent 374daab commit aaca320
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 24 deletions.
1 change: 1 addition & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,7 @@ impl pallet_ranked_collective::Config for Runtime {
type Event = Event;
type AdminOrigin = EnsureRoot<AccountId>;
type Polls = RankedPolls;
type VoteWeight = pallet_ranked_collective::Geometric;
}

impl pallet_remark::Config for Runtime {
Expand Down
49 changes: 47 additions & 2 deletions frame/ranked-collective/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
use scale_info::TypeInfo;
use sp_arithmetic::traits::Saturating;
use sp_runtime::{
traits::Convert,
ArithmeticError::Overflow,
Perbill, RuntimeDebug,
};
Expand Down Expand Up @@ -174,6 +175,45 @@ impl From<(bool, Votes)> for VoteRecord {
}
}

/// Vote-weight scheme where all voters get one vote regardless of rank.
pub struct Unit;
impl Convert<Rank, Votes> for Unit {
fn convert(_: Rank) -> Votes {
1
}
}

/// Vote-weight scheme where all voters get one vote plus an additional vote for every excess rank
/// they have. I.e.:
///
/// - Each member with no excess rank gets 1 vote;
/// - ...with an excess rank of 1 gets 2 votes;
/// - ...with an excess rank of 2 gets 2 votes;
/// - ...with an excess rank of 3 gets 3 votes;
/// - ...with an excess rank of 4 gets 4 votes.
pub struct Linear;
impl Convert<Rank, Votes> for Linear {
fn convert(r: Rank) -> Votes {
(r + 1) as Votes
}
}

/// Vote-weight scheme where all voters get one vote plus additional votes for every excess rank
/// they have incrementing by one vote for each excess rank. I.e.:
///
/// - Each member with no excess rank gets 1 vote;
/// - ...with an excess rank of 1 gets 2 votes;
/// - ...with an excess rank of 2 gets 3 votes;
/// - ...with an excess rank of 3 gets 6 votes;
/// - ...with an excess rank of 4 gets 10 votes.
pub struct Geometric;
impl Convert<Rank, Votes> for Geometric {
fn convert(r: Rank) -> Votes {
let v = (r + 1) as Votes;
v * (v + 1) / 2
}
}

#[frame_support::pallet]
pub mod pallet {
use super::*;
Expand All @@ -198,6 +238,12 @@ pub mod pallet {

/// The polling system used for our voting.
type Polls: Polling<TallyOf<Self, I>, Votes = Votes, Class = Rank, Moment = Self::BlockNumber>;

/// Convert a rank_delta into a number of votes the rank gets.
///
/// Rank_delta is defined as the number of ranks above the minimum required to take part
/// in the poll.
type VoteWeight: Convert<Rank, Votes>;
}

/// The number of members in the collective who have at least the rank according to the index
Expand Down Expand Up @@ -467,8 +513,7 @@ pub mod pallet {

fn rank_to_votes(rank: Rank, min: Rank) -> Result<Votes, DispatchError> {
let excess = rank.checked_sub(min).ok_or(Error::<T, I>::RankTooLow)?;
let v = (excess + 1) as Votes;
Ok(v * (v + 1) / 2)
Ok(T::VoteWeight::convert(excess))
}

fn remove_from_rank(who: &T::AccountId, rank: Rank) -> DispatchResult {
Expand Down
1 change: 1 addition & 0 deletions frame/ranked-collective/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ impl Config for Test {
type Event = Event;
type AdminOrigin = frame_system::EnsureRoot<Self::AccountId>;
type Polls = TestPolls;
type VoteWeight = Geometric;
}

pub fn new_test_ext() -> sp_io::TestExternalities {
Expand Down
44 changes: 22 additions & 22 deletions frame/ranked-collective/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: RankedCollective IdToIndex (r:1 w:1)
// Storage: RankedCollective IndexToId (r:1 w:1)
fn remove_member(r: u32, ) -> Weight {
(16_814_000 as Weight)
// Standard Error: 29_000
.saturating_add((8_128_000 as Weight).saturating_mul(r as Weight))
(16_855_000 as Weight)
// Standard Error: 27_000
.saturating_add((8_107_000 as Weight).saturating_mul(r as Weight))
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(r as Weight)))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
Expand All @@ -83,9 +83,9 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: RankedCollective IndexToId (r:0 w:1)
// Storage: RankedCollective IdToIndex (r:0 w:1)
fn promote_member(r: u32, ) -> Weight {
(12_036_000 as Weight)
// Standard Error: 7_000
.saturating_add((7_000 as Weight).saturating_mul(r as Weight))
(11_936_000 as Weight)
// Standard Error: 3_000
.saturating_add((9_000 as Weight).saturating_mul(r as Weight))
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
Expand All @@ -94,9 +94,9 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: RankedCollective IdToIndex (r:1 w:1)
// Storage: RankedCollective IndexToId (r:1 w:1)
fn demote_member(r: u32, ) -> Weight {
(17_605_000 as Weight)
// Standard Error: 17_000
.saturating_add((165_000 as Weight).saturating_mul(r as Weight))
(17_582_000 as Weight)
// Standard Error: 14_000
.saturating_add((142_000 as Weight).saturating_mul(r as Weight))
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
Expand All @@ -112,9 +112,9 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: RankedPolls ReferendumInfoFor (r:1 w:0)
// Storage: RankedCollective Voting (r:0 w:1)
fn cleanup_poll(n: u32, ) -> Weight {
(6_273_000 as Weight)
(6_188_000 as Weight)
// Standard Error: 1_000
.saturating_add((847_000 as Weight).saturating_mul(n as Weight))
.saturating_add((867_000 as Weight).saturating_mul(n as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(n as Weight)))
}
Expand All @@ -136,9 +136,9 @@ impl WeightInfo for () {
// Storage: RankedCollective IdToIndex (r:1 w:1)
// Storage: RankedCollective IndexToId (r:1 w:1)
fn remove_member(r: u32, ) -> Weight {
(16_814_000 as Weight)
// Standard Error: 29_000
.saturating_add((8_128_000 as Weight).saturating_mul(r as Weight))
(16_855_000 as Weight)
// Standard Error: 27_000
.saturating_add((8_107_000 as Weight).saturating_mul(r as Weight))
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(r as Weight)))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
Expand All @@ -149,9 +149,9 @@ impl WeightInfo for () {
// Storage: RankedCollective IndexToId (r:0 w:1)
// Storage: RankedCollective IdToIndex (r:0 w:1)
fn promote_member(r: u32, ) -> Weight {
(12_036_000 as Weight)
// Standard Error: 7_000
.saturating_add((7_000 as Weight).saturating_mul(r as Weight))
(11_936_000 as Weight)
// Standard Error: 3_000
.saturating_add((9_000 as Weight).saturating_mul(r as Weight))
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
Expand All @@ -160,9 +160,9 @@ impl WeightInfo for () {
// Storage: RankedCollective IdToIndex (r:1 w:1)
// Storage: RankedCollective IndexToId (r:1 w:1)
fn demote_member(r: u32, ) -> Weight {
(17_605_000 as Weight)
// Standard Error: 17_000
.saturating_add((165_000 as Weight).saturating_mul(r as Weight))
(17_582_000 as Weight)
// Standard Error: 14_000
.saturating_add((142_000 as Weight).saturating_mul(r as Weight))
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
Expand All @@ -178,9 +178,9 @@ impl WeightInfo for () {
// Storage: RankedPolls ReferendumInfoFor (r:1 w:0)
// Storage: RankedCollective Voting (r:0 w:1)
fn cleanup_poll(n: u32, ) -> Weight {
(6_273_000 as Weight)
(6_188_000 as Weight)
// Standard Error: 1_000
.saturating_add((847_000 as Weight).saturating_mul(n as Weight))
.saturating_add((867_000 as Weight).saturating_mul(n as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(n as Weight)))
}
Expand Down

0 comments on commit aaca320

Please sign in to comment.