diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 8987439db8e94c33a0be046f7561bfe9af44776e..bc889e002bf4fa2e9ebe6a4a4c635b8f207dbae3 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -24,7 +24,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; use frame_election_provider_support::{ - onchain, ElectionDataProvider, ExtendedBalance, SequentialPhragmen, VoteWeight, + onchain, BalancingConfig, ElectionDataProvider, SequentialPhragmen, VoteWeight, }; use frame_support::{ construct_runtime, @@ -630,10 +630,10 @@ pub const MINER_MAX_ITERATIONS: u32 = 10; /// A source of random balance for NposSolver, which is meant to be run by the OCW election miner. pub struct OffchainRandomBalancing; -impl Get<Option<(usize, ExtendedBalance)>> for OffchainRandomBalancing { - fn get() -> Option<(usize, ExtendedBalance)> { +impl Get<Option<BalancingConfig>> for OffchainRandomBalancing { + fn get() -> Option<BalancingConfig> { use sp_runtime::traits::TrailingZeroInput; - let iters = match MINER_MAX_ITERATIONS { + let iterations = match MINER_MAX_ITERATIONS { 0 => 0, max => { let seed = sp_io::offchain::random_seed(); @@ -644,7 +644,8 @@ impl Get<Option<(usize, ExtendedBalance)>> for OffchainRandomBalancing { }, }; - Some((iters, 0)) + let config = BalancingConfig { iterations, tolerance: 0 }; + Some(config) } } diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs index 7d8559050f3006395a0dd3f5f7821b0dcb83f2c1..2f1f6463df7194f004227841c2c09b3d956fae88 100644 --- a/substrate/frame/election-provider-multi-phase/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/src/lib.rs @@ -1808,7 +1808,7 @@ mod tests { }; use frame_election_provider_support::ElectionProvider; use frame_support::{assert_noop, assert_ok}; - use sp_npos_elections::Support; + use sp_npos_elections::{BalancingConfig, Support}; #[test] fn phase_rotation_works() { @@ -2163,7 +2163,7 @@ mod tests { assert_eq!(MultiPhase::current_phase(), Phase::Signed); // set the solution balancing to get the desired score. - crate::mock::Balancing::set(Some((2, 0))); + crate::mock::Balancing::set(Some(BalancingConfig { iterations: 2, tolerance: 0 })); let (solution, _) = MultiPhase::mine_solution().unwrap(); // Default solution's score. diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index bbc2d6d43beee088e0d8512a9a1c171dc77f8280..7eff70b47eba54f60f18ea43c29686d2496900ca 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -39,8 +39,8 @@ use sp_core::{ H256, }; use sp_npos_elections::{ - assignment_ratio_to_staked_normalized, seq_phragmen, to_supports, ElectionResult, - EvaluateSupport, ExtendedBalance, + assignment_ratio_to_staked_normalized, seq_phragmen, to_supports, BalancingConfig, + ElectionResult, EvaluateSupport, }; use sp_runtime::{ testing::Header, @@ -324,7 +324,7 @@ impl InstantElectionProvider for MockFallback { } parameter_types! { - pub static Balancing: Option<(usize, ExtendedBalance)> = Some((0, 0)); + pub static Balancing: Option<BalancingConfig> = Some( BalancingConfig { iterations: 0, tolerance: 0 } ); } pub struct TestBenchmarkingConfig; diff --git a/substrate/frame/election-provider-support/src/lib.rs b/substrate/frame/election-provider-support/src/lib.rs index 27bf7a37f96220a1e79102b9507e5d4d28912b9e..eee865d0b737bfce4536c3b4073e35d10c62d764 100644 --- a/substrate/frame/election-provider-support/src/lib.rs +++ b/substrate/frame/election-provider-support/src/lib.rs @@ -177,8 +177,8 @@ pub use frame_support::{traits::Get, weights::Weight, BoundedVec, RuntimeDebug}; /// Re-export some type as they are used in the interface. pub use sp_arithmetic::PerThing; pub use sp_npos_elections::{ - Assignment, ElectionResult, Error, ExtendedBalance, IdentifierT, PerThing128, Support, - Supports, VoteWeight, + Assignment, BalancingConfig, ElectionResult, Error, ExtendedBalance, IdentifierT, PerThing128, + Support, Supports, VoteWeight, }; pub use traits::NposSolution; @@ -568,11 +568,8 @@ pub struct SequentialPhragmen<AccountId, Accuracy, Balancing = ()>( sp_std::marker::PhantomData<(AccountId, Accuracy, Balancing)>, ); -impl< - AccountId: IdentifierT, - Accuracy: PerThing128, - Balancing: Get<Option<(usize, ExtendedBalance)>>, - > NposSolver for SequentialPhragmen<AccountId, Accuracy, Balancing> +impl<AccountId: IdentifierT, Accuracy: PerThing128, Balancing: Get<Option<BalancingConfig>>> + NposSolver for SequentialPhragmen<AccountId, Accuracy, Balancing> { type AccountId = AccountId; type Accuracy = Accuracy; @@ -596,11 +593,8 @@ pub struct PhragMMS<AccountId, Accuracy, Balancing = ()>( sp_std::marker::PhantomData<(AccountId, Accuracy, Balancing)>, ); -impl< - AccountId: IdentifierT, - Accuracy: PerThing128, - Balancing: Get<Option<(usize, ExtendedBalance)>>, - > NposSolver for PhragMMS<AccountId, Accuracy, Balancing> +impl<AccountId: IdentifierT, Accuracy: PerThing128, Balancing: Get<Option<BalancingConfig>>> + NposSolver for PhragMMS<AccountId, Accuracy, Balancing> { type AccountId = AccountId; type Accuracy = Accuracy; diff --git a/substrate/frame/election-provider-support/src/weights.rs b/substrate/frame/election-provider-support/src/weights.rs index f288ae63bb5dab9de0bc9c0f64046d7ae55a21be..c603b196519b5ef9c458a65b7ff543ab7b331c25 100644 --- a/substrate/frame/election-provider-support/src/weights.rs +++ b/substrate/frame/election-provider-support/src/weights.rs @@ -15,15 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for pallet_election_provider_support_onchain_benchmarking +//! Autogenerated weights for pallet_election_provider_support_benchmarking //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-04-04, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2022-04-23, STEPS: `1`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: // target/release/substrate // benchmark +// pallet // --chain=dev // --steps=1 // --repeat=1 diff --git a/substrate/primitives/npos-elections/README.md b/substrate/primitives/npos-elections/README.md index b518e63615fa661ae1b1f3c8b4f917c063abca5e..6881fc6418f3a93e476b097fd049e3fc354be0c7 100644 --- a/substrate/primitives/npos-elections/README.md +++ b/substrate/primitives/npos-elections/README.md @@ -8,7 +8,7 @@ sub-system. Notable implementation include: it can achieve a constant factor approximation of the maximin problem, similar to that of the MMS algorithm. - [`balance_solution`]: Implements the star balancing algorithm. This iterative process can push - a solution toward being more `balances`, which in turn can increase its score. + a solution toward being more `balanced`, which in turn can increase its score. ### Terminology @@ -46,7 +46,7 @@ let election_result = ElectionResult { winners, assignments }; The `Assignment` field of the election result is voter-major, i.e. it is from the perspective of the voter. The struct that represents the opposite is called a `Support`. This struct is usually -accessed in a map-like manner, i.e. keyed vy voters, therefor it is stored as a mapping called +accessed in a map-like manner, i.e. keyed by voters, therefore it is stored as a mapping called `SupportMap`. Moreover, the support is built from absolute backing values, not ratios like the example above. diff --git a/substrate/primitives/npos-elections/fuzzer/Cargo.toml b/substrate/primitives/npos-elections/fuzzer/Cargo.toml index 42a80296a4530c411e94179b9c8b5734ddf56fd3..a200d5c41ee35a50f6003b041c9892116be9afd1 100644 --- a/substrate/primitives/npos-elections/fuzzer/Cargo.toml +++ b/substrate/primitives/npos-elections/fuzzer/Cargo.toml @@ -36,4 +36,4 @@ path = "src/phragmms_balancing.rs" [[bin]] name = "phragmen_pjr" -path = "src/phragmen_pjr.rs" +path = "src/phragmen_pjr.rs" \ No newline at end of file diff --git a/substrate/primitives/npos-elections/fuzzer/src/common.rs b/substrate/primitives/npos-elections/fuzzer/src/common.rs index 6b89983c16abe720730bba030bd5b8b6f8d80e89..e5853f28c49290b540e7bbea9ab79cf1a157ffaa 100644 --- a/substrate/primitives/npos-elections/fuzzer/src/common.rs +++ b/substrate/primitives/npos-elections/fuzzer/src/common.rs @@ -21,7 +21,7 @@ #![allow(dead_code)] use rand::{self, seq::SliceRandom, Rng, RngCore}; -use sp_npos_elections::{phragmms, seq_phragmen, ElectionResult, VoteWeight}; +use sp_npos_elections::{phragmms, seq_phragmen, BalancingConfig, ElectionResult, VoteWeight}; use sp_runtime::Perbill; use std::collections::{BTreeMap, HashSet}; @@ -38,8 +38,8 @@ pub fn to_range(x: usize, a: usize, b: usize) -> usize { } pub enum ElectionType { - Phragmen(Option<(usize, u128)>), - Phragmms(Option<(usize, u128)>), + Phragmen(Option<BalancingConfig>), + Phragmms(Option<BalancingConfig>), } pub type AccountId = u64; diff --git a/substrate/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs b/substrate/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs index cacf64e81c8f792e25a2134f9c874d708c0623b4..e053f9aa0cddd7ec5498fda9ed9c925e5135834a 100644 --- a/substrate/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs +++ b/substrate/primitives/npos-elections/fuzzer/src/phragmen_balancing.rs @@ -23,8 +23,8 @@ use common::*; use honggfuzz::fuzz; use rand::{self, SeedableRng}; use sp_npos_elections::{ - assignment_ratio_to_staked_normalized, seq_phragmen, to_supports, ElectionResult, - EvaluateSupport, VoteWeight, + assignment_ratio_to_staked_normalized, seq_phragmen, to_supports, BalancingConfig, + ElectionResult, EvaluateSupport, VoteWeight, }; use sp_runtime::Perbill; @@ -66,8 +66,9 @@ fn main() { }; if iterations > 0 { + let config = BalancingConfig { iterations, tolerance: 0 }; let balanced: ElectionResult<AccountId, sp_runtime::Perbill> = - seq_phragmen(to_elect, candidates, voters, Some((iterations, 0))).unwrap(); + seq_phragmen(to_elect, candidates, voters, Some(config)).unwrap(); let balanced_score = { let staked = diff --git a/substrate/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs b/substrate/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs index 988889428c9cf463cb0a87a967dedd0d90c72f68..3f114674e29d9530a0f7f6973e425fa3c87241cf 100644 --- a/substrate/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs +++ b/substrate/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs @@ -23,8 +23,8 @@ use common::*; use honggfuzz::fuzz; use rand::{self, SeedableRng}; use sp_npos_elections::{ - assignment_ratio_to_staked_normalized, phragmms, to_supports, ElectionResult, EvaluateSupport, - VoteWeight, + assignment_ratio_to_staked_normalized, phragmms, to_supports, BalancingConfig, ElectionResult, + EvaluateSupport, VoteWeight, }; use sp_runtime::Perbill; @@ -65,8 +65,9 @@ fn main() { score }; + let config = BalancingConfig { iterations, tolerance: 0 }; let balanced: ElectionResult<AccountId, Perbill> = - phragmms(to_elect, candidates, voters, Some((iterations, 0))).unwrap(); + phragmms(to_elect, candidates, voters, Some(config)).unwrap(); let balanced_score = { let staked = diff --git a/substrate/primitives/npos-elections/src/balancing.rs b/substrate/primitives/npos-elections/src/balancing.rs index 54b8ee4bf243edd5c7755c159c4fe27954a22de8..4a713658ad38f6784c85d6f1288fc5955de54767 100644 --- a/substrate/primitives/npos-elections/src/balancing.rs +++ b/substrate/primitives/npos-elections/src/balancing.rs @@ -26,14 +26,15 @@ //! //! See [`balance`] for more information. -use crate::{Edge, ExtendedBalance, IdentifierT, Voter}; +use crate::{BalancingConfig, Edge, ExtendedBalance, IdentifierT, Voter}; use sp_arithmetic::traits::Zero; use sp_std::prelude::*; /// Balance the weight distribution of a given `voters` at most `iterations` times, or up until the /// point where the biggest difference created per iteration of all stakes is `tolerance`. If this /// is called with `tolerance = 0`, then exactly `iterations` rounds will be executed, except if no -/// change has been made (`difference = 0`). +/// change has been made (`difference = 0`). `tolerance` and `iterations` are part of the +/// [`BalancingConfig`] struct. /// /// In almost all cases, a balanced solution will have a better score than an unbalanced solution, /// yet this is not 100% guaranteed because the first element of a [`crate::ElectionScore`] does not @@ -52,12 +53,13 @@ use sp_std::prelude::*; /// - [A new approach to the maximum flow problem](https://dl.acm.org/doi/10.1145/48014.61051). /// - [Validator election in nominated proof-of-stake](https://arxiv.org/abs/2004.12990) (Appendix /// A.) +/// - [Computing a balanced solution](https://research.web3.foundation/en/latest/polkadot/NPoS/3.%20Balancing.html), +/// which contains the details of the algorithm implementation. pub fn balance<AccountId: IdentifierT>( voters: &mut Vec<Voter<AccountId>>, - iterations: usize, - tolerance: ExtendedBalance, + config: &BalancingConfig, ) -> usize { - if iterations == 0 { + if config.iterations == 0 { return 0 } @@ -65,14 +67,14 @@ pub fn balance<AccountId: IdentifierT>( loop { let mut max_diff = 0; for voter in voters.iter_mut() { - let diff = balance_voter(voter, tolerance); + let diff = balance_voter(voter, config.tolerance); if diff > max_diff { max_diff = diff; } } iter += 1; - if max_diff <= tolerance || iter >= iterations { + if max_diff <= config.tolerance || iter >= config.iterations { break iter } } @@ -158,7 +160,7 @@ pub(crate) fn balance_voter<AccountId: IdentifierT>( .get(last_index) .expect( "length of elected_edges is greater than or equal 2; last_index index is at the \ - minimum elected_edges.len() - 1; index is within range; qed", + minimum elected_edges.len() - 1; index is within range; qed", ) .candidate .borrow() diff --git a/substrate/primitives/npos-elections/src/lib.rs b/substrate/primitives/npos-elections/src/lib.rs index 63b9740b746398c7876ebd2b5eadad06a0072bda..dd2a9bf198f8d10cb6895fc3f716961084e5c4f3 100644 --- a/substrate/primitives/npos-elections/src/lib.rs +++ b/substrate/primitives/npos-elections/src/lib.rs @@ -62,7 +62,7 @@ //! //! The `Assignment` field of the election result is voter-major, i.e. it is from the perspective of //! the voter. The struct that represents the opposite is called a `Support`. This struct is usually -//! accessed in a map-like manner, i.e. keyed by voters, therefor it is stored as a mapping called +//! accessed in a map-like manner, i.e. keyed by voters, therefore it is stored as a mapping called //! `SupportMap`. //! //! Moreover, the support is built from absolute backing values, not ratios like the example above. @@ -217,6 +217,13 @@ impl sp_std::cmp::PartialOrd for ElectionScore { } } +/// Utility struct to group parameters for the balancing algorithm. +#[derive(Clone, Copy)] +pub struct BalancingConfig { + pub iterations: usize, + pub tolerance: ExtendedBalance, +} + /// A pointer to a candidate struct with interior mutability. pub type CandidatePtr<A> = Rc<RefCell<Candidate<A>>>; @@ -320,7 +327,7 @@ impl<AccountId: IdentifierT> Voter<AccountId> { /// /// Note that this might create _un-normalized_ assignments, due to accuracy loss of `P`. Call /// site might compensate by calling `normalize()` on the returned `Assignment` as a - /// post-precessing. + /// post-processing. pub fn into_assignment<P: PerThing>(self) -> Option<Assignment<AccountId, P>> { let who = self.who; let budget = self.budget; diff --git a/substrate/primitives/npos-elections/src/phragmen.rs b/substrate/primitives/npos-elections/src/phragmen.rs index 9b0bfa42215c3684b78384434524ba47906f77eb..9b50dc36e48fb97bcc0b4f03a7f92628661fdc76 100644 --- a/substrate/primitives/npos-elections/src/phragmen.rs +++ b/substrate/primitives/npos-elections/src/phragmen.rs @@ -21,8 +21,8 @@ //! to the Maximin problem. use crate::{ - balancing, setup_inputs, CandidatePtr, ElectionResult, ExtendedBalance, IdentifierT, - PerThing128, VoteWeight, Voter, + balancing, setup_inputs, BalancingConfig, CandidatePtr, ElectionResult, ExtendedBalance, + IdentifierT, PerThing128, VoteWeight, Voter, }; use sp_arithmetic::{ helpers_128bit::multiply_by_rational, @@ -71,16 +71,16 @@ pub fn seq_phragmen<AccountId: IdentifierT, P: PerThing128>( to_elect: usize, candidates: Vec<AccountId>, voters: Vec<(AccountId, VoteWeight, impl IntoIterator<Item = AccountId>)>, - balancing: Option<(usize, ExtendedBalance)>, + balancing: Option<BalancingConfig>, ) -> Result<ElectionResult<AccountId, P>, crate::Error> { let (candidates, voters) = setup_inputs(candidates, voters); let (candidates, mut voters) = seq_phragmen_core::<AccountId>(to_elect, candidates, voters)?; - if let Some((iterations, tolerance)) = balancing { + if let Some(ref config) = balancing { // NOTE: might create zero-edges, but we will strip them again when we convert voter into // assignment. - let _iters = balancing::balance::<AccountId>(&mut voters, iterations, tolerance); + let _iters = balancing::balance::<AccountId>(&mut voters, config); } let mut winners = candidates diff --git a/substrate/primitives/npos-elections/src/phragmms.rs b/substrate/primitives/npos-elections/src/phragmms.rs index 5d63517c8e22916046e39c2d043cedaa8255840c..3fbbad75e2f8fcea3489c924117ab1fea2f8247c 100644 --- a/substrate/primitives/npos-elections/src/phragmms.rs +++ b/substrate/primitives/npos-elections/src/phragmms.rs @@ -22,15 +22,15 @@ //! MMS algorithm. use crate::{ - balance, setup_inputs, CandidatePtr, ElectionResult, ExtendedBalance, IdentifierT, PerThing128, - VoteWeight, Voter, + balance, setup_inputs, BalancingConfig, CandidatePtr, ElectionResult, ExtendedBalance, + IdentifierT, PerThing128, VoteWeight, Voter, }; use sp_arithmetic::{traits::Bounded, PerThing, Rational128}; use sp_std::{prelude::*, rc::Rc}; /// Execute the phragmms method. /// -/// This can be used interchangeably with [`seq-phragmen`] and offers a similar API, namely: +/// This can be used interchangeably with `seq-phragmen` and offers a similar API, namely: /// /// - The resulting edge weight distribution is normalized (thus, safe to use for submission). /// - The accuracy can be configured via the generic type `P`. @@ -45,7 +45,7 @@ pub fn phragmms<AccountId: IdentifierT, P: PerThing128>( to_elect: usize, candidates: Vec<AccountId>, voters: Vec<(AccountId, VoteWeight, impl IntoIterator<Item = AccountId>)>, - balancing: Option<(usize, ExtendedBalance)>, + balancing: Option<BalancingConfig>, ) -> Result<ElectionResult<AccountId, P>, crate::Error> { let (candidates, mut voters) = setup_inputs(candidates, voters); @@ -58,8 +58,8 @@ pub fn phragmms<AccountId: IdentifierT, P: PerThing128>( round_winner.borrow_mut().elected = true; winners.push(round_winner); - if let Some((iterations, tolerance)) = balancing { - balance(&mut voters, iterations, tolerance); + if let Some(ref config) = balancing { + balance(&mut voters, config); } } else { break @@ -275,7 +275,8 @@ mod tests { drop(winner); // balancing makes no difference here but anyhow. - balance(&mut voters, 10, 0); + let config = BalancingConfig { iterations: 10, tolerance: 0 }; + balance(&mut voters, &config); // round 2 let winner = @@ -315,7 +316,7 @@ mod tests { drop(winner); // balancing will improve stuff here. - balance(&mut voters, 10, 0); + balance(&mut voters, &config); assert_eq!( voters @@ -348,8 +349,9 @@ mod tests { let candidates = vec![1, 2, 3]; let voters = vec![(10, 10, vec![1, 2]), (20, 20, vec![1, 3]), (30, 30, vec![2, 3])]; + let config = BalancingConfig { iterations: 2, tolerance: 0 }; let ElectionResult::<_, Perbill> { winners, assignments } = - phragmms(2, candidates, voters, Some((2, 0))).unwrap(); + phragmms(2, candidates, voters, Some(config)).unwrap(); assert_eq!(winners, vec![(3, 30), (2, 30)]); assert_eq!( assignments, @@ -380,8 +382,9 @@ mod tests { (130, 1000, vec![61, 71]), ]; + let config = BalancingConfig { iterations: 2, tolerance: 0 }; let ElectionResult::<_, Perbill> { winners, assignments: _ } = - phragmms(4, candidates, voters, Some((2, 0))).unwrap(); + phragmms(4, candidates, voters, Some(config)).unwrap(); assert_eq!(winners, vec![(11, 3000), (31, 2000), (51, 1500), (61, 1500),]); } @@ -393,8 +396,9 @@ mod tests { // give a bit more to 1 and 3. voters.push((2, u64::MAX, vec![1, 3])); + let config = BalancingConfig { iterations: 2, tolerance: 0 }; let ElectionResult::<_, Perbill> { winners, assignments: _ } = - phragmms(2, candidates, voters, Some((2, 0))).unwrap(); + phragmms(2, candidates, voters, Some(config)).unwrap(); assert_eq!(winners.into_iter().map(|(w, _)| w).collect::<Vec<_>>(), vec![1u32, 3]); } } diff --git a/substrate/primitives/npos-elections/src/tests.rs b/substrate/primitives/npos-elections/src/tests.rs index 1cf5ea8a24920e3527dd36544e79d7ae412bf6f3..5b88889201b3150ac31232d065fd403b81b31cc0 100644 --- a/substrate/primitives/npos-elections/src/tests.rs +++ b/substrate/primitives/npos-elections/src/tests.rs @@ -19,7 +19,7 @@ use crate::{ balancing, helpers::*, mock::*, seq_phragmen, seq_phragmen_core, setup_inputs, to_support_map, - Assignment, ElectionResult, ExtendedBalance, StakedAssignment, Support, Voter, + Assignment, BalancingConfig, ElectionResult, ExtendedBalance, StakedAssignment, Support, Voter, }; use sp_arithmetic::{PerU16, Perbill, Percent, Permill}; use substrate_test_utils::assert_eq_uvec; @@ -142,7 +142,8 @@ fn balancing_core_works() { let (candidates, voters) = setup_inputs(candidates, voters); let (candidates, mut voters) = seq_phragmen_core(4, candidates, voters).unwrap(); - let iters = balancing::balance::<AccountId>(&mut voters, 4, 0); + let config = BalancingConfig { iterations: 4, tolerance: 0 }; + let iters = balancing::balance::<AccountId>(&mut voters, &config); assert!(iters > 0); @@ -282,6 +283,7 @@ fn phragmen_poc_works_with_balancing() { let voters = vec![(10, vec![1, 2]), (20, vec![1, 3]), (30, vec![2, 3])]; let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30)]); + let config = BalancingConfig { iterations: 4, tolerance: 0 }; let ElectionResult::<_, Perbill> { winners, assignments } = seq_phragmen( 2, candidates, @@ -289,7 +291,7 @@ fn phragmen_poc_works_with_balancing() { .iter() .map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())) .collect::<Vec<_>>(), - Some((4, 0)), + Some(config), ) .unwrap();