This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Configurable voting-degree in council elections pallet #13305
Merged
Merged
Changes from 9 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
9bdae1f
configurable council elections pallet
kianenigma 17ef867
configurable council elections pallet
kianenigma c7136d5
add warning
kianenigma 38926b4
reduce sizes
kianenigma 19857b2
Merge branch 'master' of https://github.com/paritytech/substrate into…
c6c4f58
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_elections_p…
401d00d
Merge branch 'master' of github.com:paritytech/substrate into kiz-fix…
kianenigma 3b9f751
Merge branch 'kiz-fix-election-pallet' of github.com:paritytech/subst…
kianenigma 8fcf10b
fix stuff
kianenigma 0160b9f
Merge branch 'master' of github.com:paritytech/substrate into kiz-fix…
kianenigma 897f111
make assert
kianenigma cc74b3b
fix docs
kianenigma 3d4ed6c
fix docs again
kianenigma 93f0d50
fix docs again
kianenigma f94174e
Update frame/elections-phragmen/src/lib.rs
kianenigma e1b53da
Update frame/elections-phragmen/src/lib.rs
kianenigma dce84c0
Update frame/elections-phragmen/src/lib.rs
kianenigma 9d9b493
Merge branch 'master' of github.com:paritytech/substrate into kiz-fix…
kianenigma 4464433
fix docs
kianenigma b1c0eec
Merge branch 'kiz-fix-election-pallet' of github.com:paritytech/subst…
kianenigma File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,14 +43,14 @@ | |
| //! ### Voting | ||
| //! | ||
| //! Voters can vote for a limited number of the candidates by providing a list of account ids, | ||
| //! bounded by [`MAXIMUM_VOTE`]. Invalid votes (voting for non-candidates) and duplicate votes are | ||
| //! ignored during election. Yet, a voter _might_ vote for a future candidate. Voters reserve a bond | ||
| //! as they vote. Each vote defines a `value`. This amount is locked from the account of the voter | ||
| //! and indicates the weight of the vote. Voters can update their votes at any time by calling | ||
| //! `vote()` again. This can update the vote targets (which might update the deposit) or update the | ||
| //! vote's stake ([`Voter::stake`]). After a round, votes are kept and might still be valid for | ||
| //! further rounds. A voter is responsible for calling `remove_voter` once they are done to have | ||
| //! their bond back and remove the lock. | ||
| //! bounded by [`T::MaxVotesPerVoter`]. Invalid votes (voting for non-candidates) and duplicate | ||
| //! votes are ignored during election. Yet, a voter _might_ vote for a future candidate. Voters | ||
| //! reserve a bond as they vote. Each vote defines a `value`. This amount is locked from the account | ||
| //! of the voter and indicates the weight of the vote. Voters can update their votes at any time by | ||
| //! calling `vote()` again. This can update the vote targets (which might update the deposit) or | ||
| //! update the vote's stake ([`Voter::stake`]). After a round, votes are kept and might still be | ||
| //! valid for further rounds. A voter is responsible for calling `remove_voter` once they are done | ||
| //! to have their bond back and remove the lock. | ||
| //! | ||
| //! See [`Call::vote`], [`Call::remove_voter`]. | ||
| //! | ||
|
|
@@ -124,9 +124,6 @@ pub mod migrations; | |
|
|
||
| const LOG_TARGET: &str = "runtime::elections-phragmen"; | ||
|
|
||
| /// The maximum votes allowed per voter. | ||
| pub const MAXIMUM_VOTE: usize = 16; | ||
|
|
||
| type BalanceOf<T> = | ||
| <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance; | ||
| type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency< | ||
|
|
@@ -254,19 +251,29 @@ pub mod pallet { | |
|
|
||
| /// The maximum number of candidates in a phragmen election. | ||
| /// | ||
| /// Warning: The election happens onchain, and this value will determine | ||
| /// the size of the election. When this limit is reached no more | ||
| /// candidates are accepted in the election. | ||
| /// Warning: This impacts the size of the election which is run onchain. Chose wisely, and | ||
| /// consider how it will impact`T::WeightInfo::election_phragmen`. | ||
| /// | ||
| /// When this limit is reached no more candidates are accepted in the election. | ||
| #[pallet::constant] | ||
| type MaxCandidates: Get<u32>; | ||
|
|
||
| /// The maximum number of voters to allow in a phragmen election. | ||
| /// | ||
| /// Warning: This impacts the size of the election which is run onchain. | ||
| /// Warning: This impacts the size of the election which is run onchain. Chose wisely, and | ||
| /// consider how it will impact`T::WeightInfo::election_phragmen`. | ||
kianenigma marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// | ||
| /// When the limit is reached the new voters are ignored. | ||
| #[pallet::constant] | ||
| type MaxVoters: Get<u32>; | ||
|
|
||
| /// Maximum numbers of votes per voter. | ||
| /// | ||
| /// Warning: This impacts the size of the election which is run onchain. Chose wisely, and | ||
| /// consider how it will impact`T::WeightInfo::election_phragmen`. | ||
kianenigma marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| #[pallet::constant] | ||
| type MaxVotesPerVoter: Get<u32>; | ||
|
|
||
| /// Weight information for extrinsics in this pallet. | ||
| type WeightInfo: WeightInfo; | ||
| } | ||
|
|
@@ -284,6 +291,43 @@ pub mod pallet { | |
| Weight::zero() | ||
| } | ||
| } | ||
|
|
||
| fn integrity_test() { | ||
| let block_weight = T::BlockWeights::get().max_block; | ||
| // mind the order. | ||
| let election_weight = T::WeightInfo::election_phragmen( | ||
| T::MaxCandidates::get(), | ||
| T::MaxVoters::get(), | ||
| T::MaxVotesPerVoter::get() * T::MaxVoters::get(), | ||
| ); | ||
|
|
||
| let to_seconds = |w: &Weight| { | ||
| w.ref_time() as f32 / | ||
| frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND as f32 | ||
| }; | ||
|
|
||
| frame_support::log::debug!( | ||
| target: LOG_TARGET, | ||
| "election weight {}s ({:?}) // chain's block weight {}s ({:?})", | ||
| to_seconds(&election_weight), | ||
| election_weight, | ||
| to_seconds(&block_weight), | ||
| block_weight, | ||
| ); | ||
| if election_weight.any_gt(block_weight) { | ||
| frame_support::log::error!( | ||
|
||
| target: LOG_TARGET, | ||
| "election weight {}s ({:?}) will exceed a {}s chain's block weight ({:?}) (MaxCandidates {}, MaxVoters {}, MaxVotesPerVoter {} -- tweak these parameters)", | ||
| election_weight, | ||
| to_seconds(&election_weight), | ||
| to_seconds(&block_weight), | ||
| block_weight, | ||
| T::MaxCandidates::get(), | ||
| T::MaxVoters::get(), | ||
| T::MaxVotesPerVoter::get(), | ||
| ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[pallet::call] | ||
|
|
@@ -307,10 +351,6 @@ pub mod pallet { | |
| /// | ||
| /// It is the responsibility of the caller to **NOT** place all of their balance into the | ||
| /// lock and keep some for further operations. | ||
| /// | ||
| /// # <weight> | ||
| /// We assume the maximum weight among all 3 cases: vote_equal, vote_more and vote_less. | ||
| /// # </weight> | ||
| #[pallet::call_index(0)] | ||
| #[pallet::weight( | ||
| T::WeightInfo::vote_more(votes.len() as u32) | ||
|
|
@@ -324,8 +364,10 @@ pub mod pallet { | |
| ) -> DispatchResultWithPostInfo { | ||
| let who = ensure_signed(origin)?; | ||
|
|
||
| // votes should not be empty and more than `MAXIMUM_VOTE` in any case. | ||
| ensure!(votes.len() <= MAXIMUM_VOTE, Error::<T>::MaximumVotesExceeded); | ||
| ensure!( | ||
| votes.len() <= T::MaxVotesPerVoter::get() as usize, | ||
| Error::<T>::MaximumVotesExceeded | ||
| ); | ||
| ensure!(!votes.is_empty(), Error::<T>::NoVotes); | ||
|
|
||
| let candidates_count = <Candidates<T>>::decode_len().unwrap_or(0); | ||
|
|
@@ -1006,15 +1048,15 @@ impl<T: Config> Pallet<T> { | |
| // count](https://en.wikipedia.org/wiki/Borda_count). We weigh everyone's vote for | ||
| // that new member by a multiplier based on the order of the votes. i.e. the | ||
| // first person a voter votes for gets a 16x multiplier, the next person gets a | ||
| // 15x multiplier, an so on... (assuming `MAXIMUM_VOTE` = 16) | ||
| // 15x multiplier, an so on... (assuming `T::MaxVotesPerVoter` = 16) | ||
| let mut prime_votes = new_members_sorted_by_id | ||
| .iter() | ||
| .map(|c| (&c.0, BalanceOf::<T>::zero())) | ||
| .collect::<Vec<_>>(); | ||
| for (_, stake, votes) in voters_and_stakes.into_iter() { | ||
| for (vote_multiplier, who) in | ||
| votes.iter().enumerate().map(|(vote_position, who)| { | ||
| ((MAXIMUM_VOTE - vote_position) as u32, who) | ||
| ((T::MaxVotesPerVoter::get() as usize - vote_position) as u32, who) | ||
| }) { | ||
| if let Ok(i) = prime_votes.binary_search_by_key(&who, |k| k.0) { | ||
| prime_votes[i].1 = prime_votes[i] | ||
|
|
@@ -1297,6 +1339,7 @@ mod tests { | |
| type KickedMember = (); | ||
| type WeightInfo = (); | ||
| type MaxVoters = PhragmenMaxVoters; | ||
| type MaxVotesPerVoter = ConstU32<16>; | ||
| type MaxCandidates = PhragmenMaxCandidates; | ||
| } | ||
|
|
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.