Files
pezkuwi-subxt/substrate/primitives/npos-elections/fuzzer/src/phragmms_balancing.rs
T
Bastian Köcher e3e651f72c Happy new year (#7814)
* Happy new year

Updates the copyright years and fixes wrong license headers.

* Fix the template

* Split HEADER into HEADER-APACHE & HEADER-GPL
2021-01-04 09:03:13 +00:00

116 lines
3.2 KiB
Rust

// This file is part of Substrate.
// Copyright (C) 2020-2021 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.
//! Fuzzing for phragmms.
mod common;
use common::*;
use honggfuzz::fuzz;
use sp_npos_elections::{
assignment_ratio_to_staked_normalized, build_support_map, to_without_backing, VoteWeight,
evaluate_support, is_score_better, phragmms,
};
use sp_runtime::Perbill;
use rand::{self, SeedableRng};
fn main() {
loop {
fuzz!(|data: (usize, usize, usize, usize, u64)| {
let (
mut target_count,
mut voter_count,
mut iterations,
mut to_elect,
seed,
) = data;
let rng = rand::rngs::SmallRng::seed_from_u64(seed);
target_count = to_range(target_count, 100, 200);
voter_count = to_range(voter_count, 100, 200);
iterations = to_range(iterations, 5, 30);
to_elect = to_range(to_elect, 25, target_count);
println!(
"++ [voter_count: {} / target_count:{} / to_elect:{} / iterations:{}]",
voter_count, target_count, to_elect, iterations,
);
let (
unbalanced,
candidates,
voters,
stake_of_tree,
) = generate_random_npos_result(
voter_count as u64,
target_count as u64,
to_elect,
rng,
ElectionType::Phragmms(None),
);
let stake_of = |who: &AccountId| -> VoteWeight {
*stake_of_tree.get(who).unwrap()
};
let unbalanced_score = {
let staked = assignment_ratio_to_staked_normalized(unbalanced.assignments.clone(), &stake_of).unwrap();
let winners = to_without_backing(unbalanced.winners.clone());
let support = build_support_map(winners.as_ref(), staked.as_ref()).unwrap();
let score = evaluate_support(&support);
if score[0] == 0 {
// such cases cannot be improved by balancing.
return;
}
score
};
let balanced = phragmms::<AccountId, sp_runtime::Perbill>(
to_elect,
candidates,
voters,
Some((iterations, 0)),
).unwrap();
let balanced_score = {
let staked = assignment_ratio_to_staked_normalized(balanced.assignments.clone(), &stake_of).unwrap();
let winners = to_without_backing(balanced.winners);
let support = build_support_map(winners.as_ref(), staked.as_ref()).unwrap();
evaluate_support(&support)
};
let enhance = is_score_better(balanced_score, unbalanced_score, Perbill::zero());
println!(
"iter = {} // {:?} -> {:?} [{}]",
iterations,
unbalanced_score,
balanced_score,
enhance,
);
// The only guarantee of balancing is such that the first and third element of the score
// cannot decrease.
assert!(
balanced_score[0] >= unbalanced_score[0] &&
balanced_score[1] == unbalanced_score[1] &&
balanced_score[2] <= unbalanced_score[2]
);
});
}
}