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 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
399cf4b
Revamp npos-elections and implement phragmms
kianenigma Jul 19, 2020
6a7354c
Update primitives/npos-elections/src/phragmms.rs
kianenigma Jul 20, 2020
2254e21
Master.into()
kianenigma Jul 27, 2020
bd4c4ca
Merge branch 'kiz-impl-phragmms' of github.com:paritytech/substrate i…
kianenigma Jul 27, 2020
2dcfade
Fix build
kianenigma Jul 27, 2020
b29ff31
Some review grumbles
kianenigma Jul 27, 2020
51e98ff
Master.into()
kianenigma Aug 4, 2020
37b57d8
Add some stuff for remote testing
kianenigma Aug 4, 2020
01e5473
fix some of the grumbles.
kianenigma Aug 4, 2020
3ed7024
Add remote testing stuff.
kianenigma Aug 4, 2020
47640bb
Cleanup
kianenigma Aug 6, 2020
1c765c2
Master.into()
kianenigma Aug 11, 2020
dca91e6
fix docs
kianenigma Aug 11, 2020
2fa2a96
Update primitives/arithmetic/src/rational.rs
kianenigma Aug 12, 2020
3892d26
Master.into()
kianenigma Aug 12, 2020
20e3de0
Small config change
kianenigma Aug 12, 2020
c28858d
Better handling of approval_stake == 0
kianenigma Aug 13, 2020
073325d
Final touhces.
kianenigma Aug 13, 2020
decc17f
Clean fuzzer a bit
kianenigma Aug 13, 2020
c675a20
Clean fuzzer a bit
kianenigma Aug 13, 2020
8f5087b
Merge branch 'master' of github.com:paritytech/substrate into kiz-imp…
kianenigma Aug 13, 2020
b27700d
Master.into()
kianenigma Aug 14, 2020
427ee99
Master.into()
kianenigma Aug 21, 2020
9ec941b
Update primitives/npos-elections/src/balancing.rs
kianenigma Aug 24, 2020
b4a91dd
Master.into()
kianenigma Aug 24, 2020
67d2be6
Fix fuzzer.
kianenigma Sep 11, 2020
432db79
Master.into()
kianenigma Sep 11, 2020
8f75cd9
Better api for normalize
kianenigma Sep 14, 2020
4e10ab9
Master.into()
kianenigma Sep 14, 2020
7a3aa8b
Add noramlize_up
kianenigma Sep 15, 2020
379e4c9
A large number of small fixes.
kianenigma Sep 16, 2020
15f452e
Master.into()
kianenigma Sep 22, 2020
4b26106
make it merge ready
kianenigma Sep 22, 2020
629f39a
Fix warns
kianenigma Sep 23, 2020
06edce5
bump
kianenigma Sep 23, 2020
8fd1959
Fix fuzzers a bit.
kianenigma Sep 23, 2020
c14b64a
Fix warns as well.
kianenigma Sep 23, 2020
9f97731
Fix more tests.
kianenigma Sep 23, 2020
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
Prev Previous commit
Next Next commit
A large number of small fixes.
  • Loading branch information
kianenigma committed Sep 16, 2020
commit 379e4c94ebc7e3c2e1f6056f2697e08de9e21f6c
10 changes: 4 additions & 6 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2725,12 +2725,10 @@ impl<T: Trait> Module<T> {
// build the support map thereof in order to evaluate.
// OPTIMIZATION: loop to create the staked assignments but it would bloat the code. Okay for
// now as it does not add to the complexity order.
let (supports, num_error) = build_support_map::<T::AccountId>(
let supports = build_support_map::<T::AccountId>(
&winners,
&staked_assignments,
);
// This technically checks that all targets in all nominators were among the winners.
ensure!(num_error == 0, Error::<T>::OffchainElectionBogusEdge);
).map_err(|_| Error::<T>::OffchainElectionBogusEdge)?;

// Check if the score is the same as the claimed one.
let submitted_score = evaluate_support(&supports);
Expand Down Expand Up @@ -2987,10 +2985,10 @@ impl<T: Trait> Module<T> {
Self::slashable_balance_of_vote_weight,
);

let (supports, _) = build_support_map::<T::AccountId>(
let supports = build_support_map::<T::AccountId>(
&elected_stashes,
&staked_assignments,
);
).ok()?;

// collect exposures
let exposures = Self::collect_exposure(supports);
Expand Down
6 changes: 3 additions & 3 deletions frame/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ pub(crate) fn horrible_npos_solution(
let score = {
let (_, _, better_score) = prepare_submission_with(true, 0, |_| {});

let support = build_support_map::<AccountId>(&winners, &staked_assignment).0;
let support = build_support_map::<AccountId>(&winners, &staked_assignment).unwrap();
let score = evaluate_support(&support);

assert!(sp_npos_elections::is_score_better::<Perbill>(
Expand Down Expand Up @@ -957,10 +957,10 @@ pub(crate) fn prepare_submission_with(
Staking::slashable_balance_of_vote_weight,
);

let (support_map, _) = build_support_map::<AccountId>(
let support_map = build_support_map::<AccountId>(
winners.as_slice(),
staked.as_slice(),
);
).unwrap();
evaluate_support::<AccountId>(&support_map)
};

Expand Down
3 changes: 2 additions & 1 deletion frame/staking/src/offchain_election.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ pub fn prepare_submission<T: Trait>(
<Module<T>>::slashable_balance_of_vote_weight,
);

let (support_map, _) = build_support_map::<T::AccountId>(&winners, &staked);
let support_map = build_support_map::<T::AccountId>(&winners, &staked)
.map_err(|_| OffchainElectionError::ElectionFailed)?;
evaluate_support::<T::AccountId>(&support_map)
};

Expand Down
6 changes: 4 additions & 2 deletions frame/staking/src/testing_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,10 @@ pub fn get_weak_solution<T: Trait>(
stake_of
);

let (support_map, _) =
build_support_map::<T::AccountId>(winners.as_slice(), staked.as_slice());
let support_map = build_support_map::<T::AccountId>(
winners.as_slice(),
staked.as_slice(),
).unwrap();
evaluate_support::<T::AccountId>(&support_map)
};

Expand Down
50 changes: 26 additions & 24 deletions primitives/arithmetic/fuzzer/src/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,33 @@ fn main() {
let sum_limit = Ty::max_value() as u128;
let len_limit: usize = Ty::max_value().try_into().unwrap();

fuzz!(|data: (Vec<Ty>, Ty)| {
let (data, norm) = data;
if data.len() == 0 { return; }
let pre_sum: u128 = data.iter().map(|x| *x as u128).sum();
loop {
fuzz!(|data: (Vec<Ty>, Ty)| {
let (data, norm) = data;
if data.len() == 0 { return; }
let pre_sum: u128 = data.iter().map(|x| *x as u128).sum();

let normalized = data.normalize(norm);
// error cases.
if pre_sum > sum_limit || data.len() > len_limit {
assert!(normalized.is_err())
} else {
if let Ok(normalized) = normalized {
// if sum goes beyond u128, panic.
let sum: u128 = normalized.iter().map(|x| *x as u128).sum();

// if this function returns Ok(), then it will ALWAYS be accurate.
assert_eq!(
sum,
norm as u128,
"sums don't match {:?}, {}",
normalized,
norm,
);
let normalized = data.normalize(norm);
// error cases.
if pre_sum > sum_limit || data.len() > len_limit {
assert!(normalized.is_err())
} else {
panic!("Should have returned Ok for input = {:?}, target = {:?}", data, norm);
if let Ok(normalized) = normalized {
// if sum goes beyond u128, panic.
let sum: u128 = normalized.iter().map(|x| *x as u128).sum();

// if this function returns Ok(), then it will ALWAYS be accurate.
assert_eq!(
sum,
norm as u128,
"sums don't match {:?}, {}",
normalized,
norm,
);
} else {
panic!("Should have returned Ok for input = {:?}, target = {:?}", data, norm);
}
}
}
})
})
}
}
52 changes: 27 additions & 25 deletions primitives/arithmetic/fuzzer/src/normalize_up.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,31 @@ type Ty = u64;
fn main() {
let len_limit: usize = Ty::max_value().try_into().unwrap();

fuzz!(|data: (Vec<Ty>, Ty)| {
let (data, norm) = data;
if data.len() == 0 { return; }
let pre_sum: u128 = data.iter().map(|x| *x as u128).sum();

let normalized = data.normalize_up(norm);

// error cases.
let sum_limit = norm;
if pre_sum > sum_limit.into() || data.len() > len_limit {
// noop
assert_eq!(normalized, data);
} else {
// if sum goes beyond u128, panic.
let sum: u128 = normalized.iter().map(|x| *x as u128).sum();

assert_eq!(
sum,
norm as u128,
"sums don't match {:?}, {}",
normalized,
norm,
);
}
})
loop {
fuzz!(|data: (Vec<Ty>, Ty)| {
let (data, norm) = data;
if data.len() == 0 { return; }
let pre_sum: u128 = data.iter().map(|x| *x as u128).sum();

let normalized = data.normalize_up(norm);

// error cases.
let sum_limit = norm;
if pre_sum > sum_limit.into() || data.len() > len_limit {
// noop
assert_eq!(normalized, data);
} else {
// if sum goes beyond u128, panic.
let sum: u128 = normalized.iter().map(|x| *x as u128).sum();

assert_eq!(
sum,
norm as u128,
"sums don't match {:?}, {}",
normalized,
norm,
);
}
})
}
}
5 changes: 4 additions & 1 deletion primitives/npos-elections/benches/phragmen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,10 @@ fn do_phragmen(
if eq_iters > 0 {
let staked = assignment_ratio_to_staked(assignments, &stake_of);
let winners = to_without_backing(winners);
let mut support = build_support_map(winners.as_ref(), staked.as_ref()).0;
let mut support = build_support_map(
winners.as_ref(),
staked.as_ref(),
).unwrap();

balance_solution(
staked.into_iter().map(|a| (a.clone(), stake_of(&a.who))).collect(),
Expand Down
8 changes: 6 additions & 2 deletions primitives/npos-elections/fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ name = "reduce"
path = "src/reduce.rs"

[[bin]]
name = "balancing"
path = "src/balancing.rs"
name = "phragmen_balancing"
path = "src/phragmen_balancing.rs"

[[bin]]
name = "phragmms_balancing"
path = "src/phragmms_balancing.rs"

[[bin]]
name = "compact"
Expand Down
83 changes: 83 additions & 0 deletions primitives/npos-elections/fuzzer/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@

//! Common fuzzing utils.

// Each function will be used based on which fuzzer binary is being used.
#![allow(dead_code)]

use sp_npos_elections::{ElectionResult, VoteWeight, phragmms, seq_phragmen};
use sp_std::collections::btree_map::BTreeMap;
use sp_runtime::Perbill;
use rand::{self, Rng, RngCore};

/// converts x into the range [a, b] in a pseudo-fair way.
pub fn to_range(x: usize, a: usize, b: usize) -> usize {
// does not work correctly if b < 2 * a
Expand All @@ -28,3 +36,78 @@ pub fn to_range(x: usize, a: usize, b: usize) -> usize {
collapsed + a
}
}

pub enum ElectionType {
Phragmen(Option<(usize, u128)>),
Phragmms(Option<(usize, u128)>)
}

pub type AccountId = u64;

pub fn generate_random_npos_result(
voter_count: u64,
target_count: u64,
to_elect: usize,
mut rng: impl RngCore,
election_type: ElectionType,
) -> (
ElectionResult<AccountId, Perbill>,
Vec<AccountId>,
Vec<(AccountId, VoteWeight, Vec<AccountId>)>,
BTreeMap<AccountId, VoteWeight>,
) {
let prefix = 100_000;
// Note, it is important that stakes are always bigger than ed.
let base_stake: u64 = 1_000_000_000_000;
let ed: u64 = base_stake;

let mut candidates = Vec::with_capacity(target_count as usize);
let mut stake_of: BTreeMap<AccountId, VoteWeight> = BTreeMap::new();

(1..=target_count).for_each(|acc| {
candidates.push(acc);
let stake_var = rng.gen_range(ed, 100 * ed);
stake_of.insert(acc, base_stake + stake_var);
});

let mut voters = Vec::with_capacity(voter_count as usize);
(prefix ..= (prefix + voter_count)).for_each(|acc| {
let edge_per_this_voter = rng.gen_range(1, candidates.len());
// all possible targets
let mut all_targets = candidates.clone();
// we remove and pop into `targets` `edge_per_this_voter` times.
let targets = (0..edge_per_this_voter).map(|_| {
let upper = all_targets.len() - 1;
let idx = rng.gen_range(0, upper);
all_targets.remove(idx)
})
.collect::<Vec<AccountId>>();

let stake_var = rng.gen_range(ed, 100 * ed) ;
let stake = base_stake + stake_var;
stake_of.insert(acc, stake);
voters.push((acc, stake, targets));
});

(
match election_type {
ElectionType::Phragmen(conf) =>
seq_phragmen::<AccountId, sp_runtime::Perbill>(
to_elect,
candidates.clone(),
voters.clone(),
conf,
).unwrap(),
ElectionType::Phragmms(conf) =>
phragmms::<AccountId, sp_runtime::Perbill>(
to_elect,
candidates.clone(),
voters.clone(),
conf,
).unwrap(),
},
candidates,
voters,
stake_of,
)
}
Loading