-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Fuzzing for phragmen #4632
Description
There should be a fuzzer that does the following:
- (Important -- needed ASAP) Generate a random election edge vector, as such
let mut assignments = vec![
StakedAssignment {
who: 1, // voter
distribution: vec![(10, 10)] // (target, weight)
},
StakedAssignment {
who: 2,
distribution: vec![
(10, 15),
(20, 5),
],
},
...
]pass a cloned version of it through the reduce() function, then assert that it is equal to the original value. This can be easily done by using build_support_map and comparing the results. This means that the reduction algorithm, as expected, will just remove some edges but has no effect on the final outcome. I have written a function in my other PR to help with this:
substrate/primitives/phragmen/src/mock.rs
Lines 410 to 438 in ca68e24
| #[allow(dead_code)] // to be used with fuzzing | |
| pub fn assert_assignments_equal( | |
| winners: &Vec<AccountId>, | |
| ass1: &Vec<StakedAssignment<AccountId>>, | |
| ass2: &Vec<StakedAssignment<AccountId>>, | |
| ) { | |
| let support_1 = build_support_map::<Balance, AccountId>(winners, ass1); | |
| let support_2 = build_support_map::<Balance, AccountId>(winners, ass2); | |
| for (who, support) in support_1.iter() { | |
| assert_eq!(support.total, support_2.get(who).unwrap().total); | |
| assert_eq!(support.voters, support_2.get(who).unwrap().voters); | |
| } | |
| } | |
| #[allow(dead_code)] // to be used with fuzzing | |
| pub fn reduce_and_compare( | |
| assignment: &Vec<StakedAssignment<AccountId>>, | |
| winners: &Vec<AccountId>, | |
| ) { | |
| let mut altered_assignment = assignment.clone(); | |
| crate::reduce(&mut altered_assignment); | |
| assert_assignments_equal( | |
| winners, | |
| &assignment, | |
| &altered_assignment, | |
| ); | |
| } |
Basically just run this over a sensibly large random input.
There should also be an assertion that the encoded length of the result is always less than or equal to that of the original one. We cannot make this strict to just less than since the random generation might actually lead to some graphs that cannot be reduced. A very good bonus is to tell us the size of reduced on average by how many percent.
- Likewise, the main
electfunction can also be compared to the float implementation. This has less priority at the moment. There is also a helper for this:run_and_compareinprimitives/phragmen/mock.rswhich is doing exactly that. The It just need to be fed some sensible data.