mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 17:21:08 +00:00
Fix offchain election to respect the weight (#7215)
* Mockup * Fix offchain election to respect the weight * Fix builds a bit * Update frame/staking/src/offchain_election.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Update frame/staking/src/offchain_election.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Make it build, binary search * Fix a number of grumbles * one more fix. * remove unwrap. * better alg. * Better alg again. * Final fixes * Fix * Rollback to normal * Final touches. * Better tests. * Update frame/staking/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Proper maxExtWeight * Final fix * Final fix for the find_voter Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
@@ -152,6 +152,7 @@ fn struct_def(
|
||||
let len_impl = len_impl(count);
|
||||
let edge_count_impl = edge_count_impl(count);
|
||||
let unique_targets_impl = unique_targets_impl(count);
|
||||
let remove_voter_impl = remove_voter_impl(count);
|
||||
|
||||
let derives_and_maybe_compact_encoding = if compact_encoding {
|
||||
// custom compact encoding.
|
||||
@@ -220,10 +221,58 @@ fn struct_def(
|
||||
pub fn average_edge_count(&self) -> usize {
|
||||
self.edge_count().checked_div(self.len()).unwrap_or(0)
|
||||
}
|
||||
|
||||
/// Remove a certain voter.
|
||||
///
|
||||
/// This will only search until the first instance of `to_remove`, and return true. If
|
||||
/// no instance is found (no-op), then it returns false.
|
||||
///
|
||||
/// In other words, if this return true, exactly one element must have been removed from
|
||||
/// `self.len()`.
|
||||
pub fn remove_voter(&mut self, to_remove: #voter_type) -> bool {
|
||||
#remove_voter_impl
|
||||
return false
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
fn remove_voter_impl(count: usize) -> TokenStream2 {
|
||||
let field_name = field_name_for(1);
|
||||
let single = quote! {
|
||||
if let Some(idx) = self.#field_name.iter().position(|(x, _)| *x == to_remove) {
|
||||
self.#field_name.remove(idx);
|
||||
return true
|
||||
}
|
||||
};
|
||||
|
||||
let field_name = field_name_for(2);
|
||||
let double = quote! {
|
||||
if let Some(idx) = self.#field_name.iter().position(|(x, _, _)| *x == to_remove) {
|
||||
self.#field_name.remove(idx);
|
||||
return true
|
||||
}
|
||||
};
|
||||
|
||||
let rest = (3..=count)
|
||||
.map(|c| {
|
||||
let field_name = field_name_for(c);
|
||||
quote! {
|
||||
if let Some(idx) = self.#field_name.iter().position(|(x, _, _)| *x == to_remove) {
|
||||
self.#field_name.remove(idx);
|
||||
return true
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect::<TokenStream2>();
|
||||
|
||||
quote! {
|
||||
#single
|
||||
#double
|
||||
#rest
|
||||
}
|
||||
}
|
||||
|
||||
fn len_impl(count: usize) -> TokenStream2 {
|
||||
(1..=count).map(|c| {
|
||||
let field_name = field_name_for(c);
|
||||
|
||||
@@ -1155,6 +1155,69 @@ mod solution_type {
|
||||
assert_eq!(compact.unique_targets(), vec![10, 11, 20, 40, 50, 51]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remove_voter_works() {
|
||||
let mut compact = TestSolutionCompact {
|
||||
votes1: vec![(0, 2), (1, 6)],
|
||||
votes2: vec![
|
||||
(2, (0, TestAccuracy::from_percent(80)), 1),
|
||||
(3, (7, TestAccuracy::from_percent(85)), 8),
|
||||
],
|
||||
votes3: vec![
|
||||
(
|
||||
4,
|
||||
[(3, TestAccuracy::from_percent(50)), (4, TestAccuracy::from_percent(25))],
|
||||
5,
|
||||
),
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
assert!(!compact.remove_voter(11));
|
||||
assert!(compact.remove_voter(2));
|
||||
assert_eq!(
|
||||
compact,
|
||||
TestSolutionCompact {
|
||||
votes1: vec![(0, 2), (1, 6)],
|
||||
votes2: vec![
|
||||
(3, (7, TestAccuracy::from_percent(85)), 8),
|
||||
],
|
||||
votes3: vec![
|
||||
(
|
||||
4,
|
||||
[(3, TestAccuracy::from_percent(50)), (4, TestAccuracy::from_percent(25))],
|
||||
5,
|
||||
),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
assert!(compact.remove_voter(4));
|
||||
assert_eq!(
|
||||
compact,
|
||||
TestSolutionCompact {
|
||||
votes1: vec![(0, 2), (1, 6)],
|
||||
votes2: vec![
|
||||
(3, (7, TestAccuracy::from_percent(85)), 8),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
assert!(compact.remove_voter(1));
|
||||
assert_eq!(
|
||||
compact,
|
||||
TestSolutionCompact {
|
||||
votes1: vec![(0, 2)],
|
||||
votes2: vec![
|
||||
(3, (7, TestAccuracy::from_percent(85)), 8),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic_from_and_into_compact_works_assignments() {
|
||||
let voters = vec![
|
||||
|
||||
Reference in New Issue
Block a user