Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
605c893
Move `sp-npos-elections-solution-type`
Mar 6, 2022
020cd99
Fixing tests
Mar 6, 2022
676923d
Fixing tests
Mar 7, 2022
7c31687
Fixing cargo.toml for std configuration
Mar 7, 2022
79538d2
Implementing `MaxEncodedLen`
Mar 7, 2022
4dac1d2
Full implementation of `max_encoded_len`
Mar 8, 2022
38dc2fa
Fixing implementation bug
Mar 8, 2022
d034a12
Merge branch 'paritytech:master' into election-solution-bounded-move
georgesdib Mar 11, 2022
bb71738
fmt
Mar 11, 2022
dbf082b
Merge branch 'paritytech:master' into election-solution-bounded-move
georgesdib Mar 11, 2022
4ba1eea
Committing suggested changes
Mar 12, 2022
4fb9569
Merge branch 'election-solution-bounded-move' of https://github.com/g…
Mar 12, 2022
a076c9b
Removing unneeded imports
Mar 12, 2022
505f5aa
Implementing `MaxEncodedLen`
Mar 7, 2022
dff988d
Full implementation of `max_encoded_len`
Mar 8, 2022
4c37fbb
Fixing implementation bug
Mar 8, 2022
2a6f778
rebase
Mar 12, 2022
45d778c
Move `NposSolution` to frame
Mar 13, 2022
e9db59e
Merge branch 'master' into support-to-frame
Mar 14, 2022
626878d
Implementing `MaxEncodedLen`
Mar 7, 2022
d57cd90
Full implementation of `max_encoded_len`
Mar 8, 2022
6759535
Fixing implementation bug
Mar 8, 2022
563d00d
Merge branch 'election-solution-bounded' of https://github.com/george…
Mar 14, 2022
64b083a
Fixing test
Mar 14, 2022
529b5cd
Merge master
Mar 16, 2022
5b01e89
Removing unneeded dependencies
Mar 16, 2022
51dd862
Merge master
Mar 19, 2022
6848ce1
`VoterSnapshotPerBlock` -> `MaxElectingVoters`
Mar 19, 2022
0883324
rename `SizeBound` to `MaxVoters`
Mar 20, 2022
d3b06c6
Removing TODO and change bound
Mar 20, 2022
0cd8944
renaming `size_bound` to `max_voters`
Mar 20, 2022
38c0cf5
Enabling tests for `solution-type`
Mar 20, 2022
084e586
Adding tests for `MaxEncodedLen` of solution_type
Mar 20, 2022
0578224
Better rustdocs. Better indenting and comments.
Mar 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,11 +597,13 @@ frame_election_provider_support::generate_solution_type!(
VoterIndex = u32,
TargetIndex = u16,
Accuracy = sp_runtime::PerU16,
MaxVoters = MaxElectingVoters,
>(16)
);

parameter_types! {
pub MaxNominations: u32 = <NposSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
pub MaxElectingVoters: u32 = 10_000;
}

/// The numbers configured here could always be more than the the maximum limits of staking pallet
Expand Down Expand Up @@ -677,7 +679,7 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
>;
type ForceOrigin = EnsureRootOrHalfCouncil;
type MaxElectableTargets = ConstU16<{ u16::MAX }>;
type MaxElectingVoters = ConstU32<10_000>;
type MaxElectingVoters = MaxElectingVoters;
type BenchmarkingConfig = ElectionProviderBenchmarkConfig;
type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight<Self>;
}
Expand Down
7 changes: 6 additions & 1 deletion frame/election-provider-multi-phase/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ pub(crate) type TargetIndex = u16;

frame_election_provider_support::generate_solution_type!(
#[compact]
pub struct TestNposSolution::<VoterIndex = VoterIndex, TargetIndex = TargetIndex, Accuracy = PerU16>(16)
pub struct TestNposSolution::<
VoterIndex = VoterIndex,
TargetIndex = TargetIndex,
Accuracy = PerU16,
MaxVoters = ConstU32::<20>
>(16)
);

/// All events of this pallet.
Expand Down
1 change: 1 addition & 0 deletions frame/election-provider-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ frame-system = { version = "4.0.0-dev", default-features = false, path = "../sys
frame-election-provider-solution-type = { version = "4.0.0-dev", path = "solution-type" }

[dev-dependencies]
rand = "0.7.3"
sp-npos-elections = { version = "4.0.0-dev", path = "../../primitives/npos-elections" }
sp-core = { version = "6.0.0", path = "../../primitives/core" }
sp-io = { version = "6.0.0", path = "../../primitives/io" }
Expand Down
1 change: 1 addition & 0 deletions frame/election-provider-support/solution-type/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ scale-info = "2.0.1"
sp-arithmetic = { version = "5.0.0", path = "../../../primitives/arithmetic" }
# used by generate_solution_type:
frame-election-provider-support = { version = "4.0.0-dev", path = ".." }
frame-support = { version = "4.0.0-dev", path = "../../support" }
trybuild = "1.0.53"
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ sp-arithmetic = { version = "5.0.0", path = "../../../../primitives/arithmetic"
sp-runtime = { version = "6.0.0", path = "../../../../primitives/runtime" }
# used by generate_solution_type:
sp-npos-elections = { version = "4.0.0-dev", default-features = false, path = "../../../../primitives/npos-elections" }
frame-support = { version = "4.0.0-dev", path = "../../../support" }

[[bin]]
name = "compact"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ fn main() {
VoterIndex = u32,
TargetIndex = u32,
Accuracy = Percent,
MaxVoters = frame_support::traits::ConstU32::<100_000>,
>(16));
loop {
fuzz!(|fuzzer_data: &[u8]| {
Expand Down
35 changes: 30 additions & 5 deletions frame/election-provider-support/solution-type/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ pub(crate) fn syn_err(message: &'static str) -> syn::Error {
/// compact encoding.
/// - The accuracy of the ratios. This must be one of the `PerThing` types defined in
/// `sp-arithmetic`.
/// - The maximum number of voters. This must be of type `Get<u32>`. Check <https://github.com/paritytech/substrate/issues/10866>
/// for more details. This is used to bound the struct, by leveraging the fact that `votes1.len()
/// < votes2.len() < ... < votesn.len()` (the details of the struct is explained further below).
/// We know that `sum_i votes_i.len() <= MaxVoters`, and we know that the maximum size of the
/// struct would be achieved if all voters fall in the last bucket. One can also check the tests
/// and more specifically `max_encoded_len_exact` for a concrete example.
///
/// Moreover, the maximum number of edges per voter (distribution per assignment) also need to be
/// specified. Attempting to convert from/to an assignment with more distributions will fail.
Expand All @@ -59,10 +65,12 @@ pub(crate) fn syn_err(message: &'static str) -> syn::Error {
/// ```
/// # use frame_election_provider_solution_type::generate_solution_type;
/// # use sp_arithmetic::per_things::Perbill;
/// # use frame_support::traits::ConstU32;
/// generate_solution_type!(pub struct TestSolution::<
/// VoterIndex = u16,
/// TargetIndex = u8,
/// Accuracy = Perbill,
/// MaxVoters = ConstU32::<10>,
/// >(4));
/// ```
///
Expand Down Expand Up @@ -103,9 +111,15 @@ pub(crate) fn syn_err(message: &'static str) -> syn::Error {
/// # use frame_election_provider_solution_type::generate_solution_type;
/// # use frame_election_provider_support::NposSolution;
/// # use sp_arithmetic::per_things::Perbill;
/// # use frame_support::traits::ConstU32;
/// generate_solution_type!(
/// #[compact]
/// pub struct TestSolutionCompact::<VoterIndex = u16, TargetIndex = u8, Accuracy = Perbill>(8)
/// pub struct TestSolutionCompact::<
/// VoterIndex = u16,
/// TargetIndex = u8,
/// Accuracy = Perbill,
/// MaxVoters = ConstU32::<10>,
/// >(8)
/// );
/// ```
#[proc_macro]
Expand All @@ -129,6 +143,7 @@ struct SolutionDef {
voter_type: syn::Type,
target_type: syn::Type,
weight_type: syn::Type,
max_voters: syn::Type,
count: usize,
compact_encoding: bool,
}
Expand Down Expand Up @@ -167,11 +182,11 @@ impl Parse for SolutionDef {
let _ = <syn::Token![::]>::parse(input)?;
let generics: syn::AngleBracketedGenericArguments = input.parse()?;

if generics.args.len() != 3 {
return Err(syn_err("Must provide 3 generic args."))
if generics.args.len() != 4 {
return Err(syn_err("Must provide 4 generic args."))
}

let expected_types = ["VoterIndex", "TargetIndex", "Accuracy"];
let expected_types = ["VoterIndex", "TargetIndex", "Accuracy", "MaxVoters"];

let mut types: Vec<syn::Type> = generics
.args
Expand All @@ -197,6 +212,7 @@ impl Parse for SolutionDef {
})
.collect::<Result<_>>()?;

let max_voters = types.pop().expect("Vector of length 4 can be popped; qed");
let weight_type = types.pop().expect("Vector of length 3 can be popped; qed");
let target_type = types.pop().expect("Vector of length 2 can be popped; qed");
let voter_type = types.pop().expect("Vector of length 1 can be popped; qed");
Expand All @@ -205,7 +221,16 @@ impl Parse for SolutionDef {
let count_expr: syn::ExprParen = input.parse()?;
let count = parse_parenthesized_number::<usize>(count_expr)?;

Ok(Self { vis, ident, voter_type, target_type, weight_type, count, compact_encoding })
Ok(Self {
vis,
ident,
voter_type,
target_type,
weight_type,
max_voters,
count,
compact_encoding,
})
}
}

Expand Down
22 changes: 22 additions & 0 deletions frame/election-provider-support/solution-type/src/single_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub(crate) fn generate(def: crate::SolutionDef) -> Result<TokenStream2> {
voter_type,
target_type,
weight_type,
max_voters,
compact_encoding,
} = def;

Expand Down Expand Up @@ -178,6 +179,27 @@ pub(crate) fn generate(def: crate::SolutionDef) -> Result<TokenStream2> {
<#ident as _feps::NposSolution>::TargetIndex,
<#ident as _feps::NposSolution>::Accuracy,
>;
impl _feps::codec::MaxEncodedLen for #ident {
fn max_encoded_len() -> usize {
use frame_support::traits::Get;
use _feps::codec::Encode;
let s: u32 = #max_voters::get();
let max_element_size =
// the first voter..
#voter_type::max_encoded_len()
// #count - 1 tuples..
.saturating_add(
(#count - 1).saturating_mul(
#target_type::max_encoded_len().saturating_add(#weight_type::max_encoded_len())))
// and the last target.
.saturating_add(#target_type::max_encoded_len());
// The assumption is that it contains #count-1 empty elements
// and then last element with full size
#count
.saturating_mul(_feps::codec::Compact(0u32).encoded_size())
.saturating_add((s as usize).saturating_mul(max_element_size))
}
}
impl<'a> _feps::sp_std::convert::TryFrom<&'a [__IndexAssignment]> for #ident {
type Error = _feps::Error;
fn try_from(index_assignments: &'a [__IndexAssignment]) -> Result<Self, Self::Error> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ generate_solution_type!(pub struct TestSolution::<
VoterIndex = u16,
TargetIndex = u8,
Perbill,
MaxVoters = ConstU32::<10>,
>(8));

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use frame_election_provider_solution_type::generate_solution_type;

generate_solution_type!(pub struct TestSolution::<
VoterIndex = u16,
TargetIndex = u8,
Accuracy = Perbill,
ConstU32::<10>,
>(8));

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
error: Expected binding: `MaxVoters = ...`
--> tests/ui/fail/missing_size_bound.rs:7:2
|
7 | ConstU32::<10>,
| ^^^^^^^^^^^^^^
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ generate_solution_type!(pub struct TestSolution::<
VoterIndex = u16,
u8,
Accuracy = Perbill,
MaxVoters = ConstU32::<10>,
>(8));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ generate_solution_type!(pub struct TestSolution::<
u16,
TargetIndex = u8,
Accuracy = Perbill,
MaxVoters = ConstU32::<10>,
>(8));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ generate_solution_type!(pub struct TestSolution::<
u16,
u8,
Perbill,
MaxVoters = ConstU32::<10>,
>(8));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ generate_solution_type!(pub struct TestSolution::<
TargetIndex = u16,
VoterIndex = u8,
Accuracy = Perbill,
MaxVoters = ConstU32::<10>,
>(8));

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ generate_solution_type!(
VoterIndex = u8,
TargetIndex = u16,
Accuracy = Perbill,
MaxVoters = ConstU32::<10>,
>(8)
);

Expand Down
5 changes: 5 additions & 0 deletions frame/election-provider-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ pub use scale_info;
pub use sp_arithmetic;
#[doc(hidden)]
pub use sp_std;

#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
// Simple Extension trait to easily convert `None` from index closures to `Err`.
//
// This is only generated and re-exported for the solution code to use.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@

#![cfg(test)]

use std::{collections::HashMap, convert::TryInto, hash::Hash, HashSet};
use std::{
collections::{HashMap, HashSet},
convert::TryInto,
hash::Hash,
};

use rand::{seq::SliceRandom, Rng};

pub type AccountId = u64;

/// The candidate mask allows easy disambiguation between voters and candidates: accounts
/// for which this bit is set are candidates, and without it, are voters.
pub const CANDIDATE_MASK: AccountId = 1 << ((std::mem::size_of::<AccountId>() * 8) - 1);
Expand All @@ -34,13 +40,14 @@ pub fn p(p: u8) -> TestAccuracy {
}

pub type MockAssignment = crate::Assignment<AccountId, TestAccuracy>;
pub type Voter = (AccountId, VoteWeight, Vec<AccountId>);
pub type Voter = (AccountId, crate::VoteWeight, Vec<AccountId>);

crate::generate_solution_type! {
pub struct TestSolution::<
VoterIndex = u32,
TargetIndex = u16,
Accuracy = TestAccuracy,
MaxVoters = frame_support::traits::ConstU32::<20>,
>(16)
}

Expand Down
Loading