This repository has been 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.6k
Implements approval voting to use as a NposSolver
#13367
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
401a2f0
Implements the approval voting methods in sp_npos_elections
gpestana 5e5d0ff
Replaces phragmen elections in pallet-elections tests for approval vo…
gpestana 5782216
nits for checks
gpestana a7643af
rfmt
gpestana e22b87c
Uses ApprovalVoting in node runtime
gpestana 46697cc
Update primitives/npos-elections/src/approval_voting.rs
gpestana 0b4a52d
reverts num max voters tests
gpestana e337c26
Rework generated API docs (#13178)
athei 8511c9b
pallet-scheduler: Ensure we request a preimage (#13340)
bkchr 1651553
[Fix] Try-state feature-gated for BagsList (#13296)
ruseinov eb4cff9
bump version of zombienet and update snaps links (#13359)
pepoviola e52858c
Fix longest chain finalization target lookup (#13289)
davxy 87190e9
SetMembers configurable origin (#13159)
girazoki 3b282df
grandpa: don't error if best block and finality target are inconsiste…
andresilva 4d83204
Improve Weight Template and API (#13355)
shawntabrizi 53e059a
[ci] Change label checker (#13360)
alvicsam c92e2b6
client/beefy: request justifs from peers further in consensus (#13343)
acatangiu 483bbfb
[ci] Change GHA to add J2 labels instead Z0 (#13375)
alvicsam a056cd4
sc-client-db: Fix `PruningMode::ArchiveCanonical` (#13361)
bkchr aceb761
subkey: only decode hex if requested, CLI `0x` prefixed hex for all `…
ggwpez 819a42a
[Feature] Introduce storage_alias for CountedStorageMap (#13366)
ruseinov b658723
simplifies approval edge weight calculation
gpestana 198082a
Merge remote-tracking branch 'origin/gpestana8250_npossolver' into gp…
87503ee
Adds test
gpestana 3e001b2
Merge branch 'master' into gpestana/approval_voting
gpestana 186cf8d
Removes vote normalization for approval voting
gpestana f4a0f34
Merge remote-tracking branch 'origin/gpestana8250_npossolver' into gp…
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 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 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 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 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 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 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 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 |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// This file is part of Substrate. | ||
|
||
// Copyright (C) 2023 Parity Technologies (UK) Ltd. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
//! Implementation of the approval voting election method. | ||
//! | ||
//! This method allows voters to select many candidates and backing each of them with the same | ||
//! vote weight. The candidates with the most backing are the election winners. | ||
use crate::{setup_inputs, ElectionResult, IdentifierT, PerThing128, VoteWeight}; | ||
use sp_arithmetic::traits::Zero; | ||
use sp_std::{cmp::Reverse, vec::Vec}; | ||
|
||
/// Execute an approvals voting election scheme. The return type is a list of winners and a weight | ||
/// distribution vector of all voters who contribute to the winners. | ||
/// | ||
/// - The vote assignment distribution for each vote is always 100%, since a voter backs a candidate | ||
/// with its full stake, regardless of how many candidates are backed by the same stake. However, | ||
/// the caller may normalize votes on site if required. | ||
/// - Returning winners are sorted based on desirability. Voters are unsorted. | ||
/// - The returning winners are zipped with their final backing stake. Yet, to get the exact final | ||
/// weight distribution from the winner's point of view, one needs to build a support map. See | ||
/// [`crate::SupportMap`] for more info. Note that this backing stake is computed in | ||
/// ExtendedBalance and may be slightly different that what will be computed from the support map, | ||
/// due to accuracy loss. | ||
/// | ||
/// This can only fail of the normalization fails. This can happen if for any of the resulting | ||
/// assignments, `assignment.distribution.map(|p| p.deconstruct()).sum()` fails to fit inside | ||
/// `UpperOf<P>`. A user of this crate may statically assert that this can never happen and safely | ||
/// `expect` this to return `Ok`. | ||
pub fn approval_voting<AccountId: IdentifierT, P: PerThing128>( | ||
to_elect: usize, | ||
candidates: Vec<AccountId>, | ||
voters: Vec<(AccountId, VoteWeight, impl IntoIterator<Item = AccountId>)>, | ||
) -> Result<ElectionResult<AccountId, P>, crate::Error> { | ||
let to_elect = to_elect.min(candidates.len()); | ||
|
||
let (mut candidates, mut voters) = setup_inputs(candidates, voters); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ahh interesting, I didn't recall that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We get a few things from
I think it won't be easy to optimise this further for the approval voting case. |
||
|
||
candidates.sort_by_key(|c| Reverse(c.borrow().approval_stake)); | ||
|
||
let winners = candidates | ||
.into_iter() | ||
.take(to_elect) | ||
.map(|w| { | ||
w.borrow_mut().elected = true; | ||
w | ||
}) | ||
.map(|w_ptr| (w_ptr.borrow().who.clone(), w_ptr.borrow().approval_stake)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Curious if we need to borrow here to clone |
||
.collect(); | ||
|
||
for voter in &mut voters { | ||
for edge in &mut voter.edges { | ||
if edge.candidate.borrow().elected { | ||
edge.weight = voter.budget | ||
} else { | ||
edge.weight = Zero::zero() | ||
} | ||
} | ||
} | ||
|
||
let assignments = voters.into_iter().filter_map(|v| v.into_assignment()).collect::<Vec<_>>(); | ||
|
||
Ok(ElectionResult { winners, assignments }) | ||
} |
This file contains 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 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 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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if