Move Staking Weights to T::WeightInfo (#7007)

* Fix the benchmarks

* Migrate staking to weightInfo

* Fix global benchmarks

* re-calculate the submit solution weight.

* Fix some refund.

* Get rid of all the extra parameters.

* Fix staking tests.

* new values from the bench machine.

* Fix some grumbles

* better macro

* Some better doc

* Move to interpreted wasm

* Make it work temporarily

* Final fix of default ones.

* Fix payout benchmarks

* Fix payout stuff

* One last fix

* use benchmarking machine for numbers

* update weight docs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Kian Paimani
2020-09-16 14:25:31 +02:00
committed by GitHub
parent 7a075a990f
commit 83bde4c1e6
8 changed files with 660 additions and 378 deletions
@@ -149,22 +149,9 @@ fn struct_def(
)
}).collect::<TokenStream2>();
let len_impl = (1..=count).map(|c| {
let field_name = field_name_for(c);
quote!(
all_len = all_len.saturating_add(self.#field_name.len());
)
}).collect::<TokenStream2>();
let edge_count_impl = (1..=count).map(|c| {
let field_name = field_name_for(c);
quote!(
all_edges = all_edges.saturating_add(
self.#field_name.len().saturating_mul(#c as usize)
);
)
}).collect::<TokenStream2>();
let len_impl = len_impl(count);
let edge_count_impl = edge_count_impl(count);
let unique_targets_impl = unique_targets_impl(count);
let derives_and_maybe_compact_encoding = if compact_encoding {
// custom compact encoding.
@@ -209,6 +196,26 @@ fn struct_def(
all_edges
}
/// Get the number of unique targets in the whole struct.
///
/// Once presented with a list of winners, this set and the set of winners must be
/// equal.
///
/// The resulting indices are sorted.
pub fn unique_targets(&self) -> Vec<#target_type> {
let mut all_targets: Vec<#target_type> = Vec::with_capacity(self.average_edge_count());
let mut maybe_insert_target = |t: #target_type| {
match all_targets.binary_search(&t) {
Ok(_) => (),
Err(pos) => all_targets.insert(pos, t)
}
};
#unique_targets_impl
all_targets
}
/// Get the average edge count.
pub fn average_edge_count(&self) -> usize {
self.edge_count().checked_div(self.len()).unwrap_or(0)
@@ -217,6 +224,65 @@ fn struct_def(
))
}
fn len_impl(count: usize) -> TokenStream2 {
(1..=count).map(|c| {
let field_name = field_name_for(c);
quote!(
all_len = all_len.saturating_add(self.#field_name.len());
)
}).collect::<TokenStream2>()
}
fn edge_count_impl(count: usize) -> TokenStream2 {
(1..=count).map(|c| {
let field_name = field_name_for(c);
quote!(
all_edges = all_edges.saturating_add(
self.#field_name.len().saturating_mul(#c as usize)
);
)
}).collect::<TokenStream2>()
}
fn unique_targets_impl(count: usize) -> TokenStream2 {
let unique_targets_impl_single = {
let field_name = field_name_for(1);
quote! {
self.#field_name.iter().for_each(|(_, t)| {
maybe_insert_target(*t);
});
}
};
let unique_targets_impl_double = {
let field_name = field_name_for(2);
quote! {
self.#field_name.iter().for_each(|(_, (t1, _), t2)| {
maybe_insert_target(*t1);
maybe_insert_target(*t2);
});
}
};
let unique_targets_impl_rest = (3..=count).map(|c| {
let field_name = field_name_for(c);
quote! {
self.#field_name.iter().for_each(|(_, inners, t_last)| {
inners.iter().for_each(|(t, _)| {
maybe_insert_target(*t);
});
maybe_insert_target(*t_last);
});
}
}).collect::<TokenStream2>();
quote! {
#unique_targets_impl_single
#unique_targets_impl_double
#unique_targets_impl_rest
}
}
fn imports() -> Result<TokenStream2> {
if std::env::var("CARGO_PKG_NAME").unwrap() == "sp-npos-elections" {
Ok(quote! {
@@ -1002,6 +1002,7 @@ mod solution_type {
);
assert_eq!(compact.len(), 4);
assert_eq!(compact.edge_count(), 2 + 4);
assert_eq!(compact.unique_targets(), vec![10, 11, 20, 40, 50, 51]);
}
#[test]
@@ -1097,6 +1098,11 @@ mod solution_type {
}
);
assert_eq!(
compacted.unique_targets(),
vec![0, 1, 2, 3, 4, 5, 6, 7, 8],
);
let voter_at = |a: u32| -> Option<AccountId> {
voters.get(<u32 as TryInto<usize>>::try_into(a).unwrap()).cloned()
};
@@ -1110,6 +1116,69 @@ mod solution_type {
);
}
#[test]
fn unique_targets_len_edge_count_works() {
const ACC: TestAccuracy = TestAccuracy::from_percent(10);
// we don't really care about voters here so all duplicates. This is not invalid per se.
let compact = TestSolutionCompact {
votes1: vec![(99, 1), (99, 2)],
votes2: vec![
(99, (3, ACC.clone()), 7),
(99, (4, ACC.clone()), 8),
],
votes3: vec![
(99, [(11, ACC.clone()), (12, ACC.clone())], 13),
],
// ensure the last one is also counted.
votes16: vec![
(
99,
[
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
(66, ACC.clone()),
],
67,
)
],
..Default::default()
};
assert_eq!(compact.unique_targets(), vec![1, 2, 3, 4, 7, 8, 11, 12, 13, 66, 67]);
assert_eq!(compact.edge_count(), 2 + (2 * 2) + 3 + 16);
assert_eq!(compact.len(), 6);
// this one has some duplicates.
let compact = TestSolutionCompact {
votes1: vec![(99, 1), (99, 1)],
votes2: vec![
(99, (3, ACC.clone()), 7),
(99, (4, ACC.clone()), 8),
],
votes3: vec![
(99, [(11, ACC.clone()), (11, ACC.clone())], 13),
],
..Default::default()
};
assert_eq!(compact.unique_targets(), vec![1, 3, 4, 7, 8, 11, 13]);
assert_eq!(compact.edge_count(), 2 + (2 * 2) + 3);
assert_eq!(compact.len(), 5);
}
#[test]
fn compact_into_assignment_must_report_overflow() {
// in votes2
@@ -1165,7 +1234,7 @@ mod solution_type {
assert_eq!(compacted.unwrap_err(), PhragmenError::CompactTargetOverflow);
}
#[test]
#[test]
fn zero_target_count_is_ignored() {
let voters = vec![1 as AccountId, 2];
let targets = vec![10 as AccountId, 11];