-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Decouple Staking and Election - Part 3: Signed Phase #7910
Changes from all commits
d998b12
5aea9cc
8607d3d
6523f5b
632e107
c52e65d
b4fc5e1
cc26881
15cdb28
67a9fae
75eca3f
8daec3a
49613ed
eae69b0
35f1faf
6c82d9f
e6ffc4d
483018c
54460eb
33b8e69
be89dc5
62f8ce4
dff422a
5f1637e
c58b2f9
76c3387
872a3c8
f5f4605
859f594
0fc7a58
1137698
8c26900
a882ff5
d5fe671
75ddba9
abae602
f4aea1d
ebface4
151e880
189a870
8d95722
edfb376
a3574d5
5ecd6b5
ee66c84
17faa86
94314bf
9e6b559
10cfdee
6f9cf10
134ab4f
61b7680
b06f3a8
ca97603
7ce5afb
bdf45ba
87b7ff1
308b522
0d892f4
ea2b1ab
22248e1
c651962
29d9242
fd38356
c503fa7
252f310
725cadf
88f856a
ce0974f
c1a4f1e
75e6637
2f26f16
eb07d0b
18f4aaa
a6b3770
fb187fc
2ed81bc
8f0c16e
0b0abb8
73071aa
955f5bc
65b6926
7b673d1
300c5f6
f84093b
2355a78
e4e9eda
65d7af6
2c61152
368e97b
2491916
e12e542
a195ed8
b0a57da
3325691
e0b3a52
ad9d095
3a46890
0ddfeda
bf4572c
dfd0bf1
786898d
9e6e75f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,6 +73,7 @@ use pallet_session::{historical as pallet_session_historical}; | |
| use sp_inherents::{InherentData, CheckInherentsResult}; | ||
| use static_assertions::const_assert; | ||
| use pallet_contracts::weights::WeightInfo; | ||
| use pallet_election_provider_multi_phase::FallbackStrategy; | ||
|
|
||
| #[cfg(any(feature = "std", test))] | ||
| pub use sp_runtime::BuildStorage; | ||
|
|
@@ -516,9 +517,14 @@ parameter_types! { | |
| pub const SignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4; | ||
| pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4; | ||
|
|
||
| // fallback: no need to do on-chain phragmen initially. | ||
| pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy = | ||
| pallet_election_provider_multi_phase::FallbackStrategy::Nothing; | ||
| // signed config | ||
| pub const SignedMaxSubmissions: u32 = 10; | ||
| pub const SignedRewardBase: Balance = 1 * DOLLARS; | ||
| pub const SignedDepositBase: Balance = 1 * DOLLARS; | ||
| pub const SignedDepositByte: Balance = 1 * CENTS; | ||
|
|
||
| // fallback: no on-chain fallback. | ||
| pub const Fallback: FallbackStrategy = FallbackStrategy::Nothing; | ||
|
|
||
| pub SolutionImprovementThreshold: Perbill = Perbill::from_rational(1u32, 10_000); | ||
|
|
||
|
|
@@ -559,6 +565,14 @@ impl pallet_election_provider_multi_phase::Config for Runtime { | |
| type MinerMaxWeight = MinerMaxWeight; | ||
| type MinerMaxLength = MinerMaxLength; | ||
| type MinerTxPriority = MultiPhaseUnsignedPriority; | ||
| type SignedMaxSubmissions = SignedMaxSubmissions; | ||
| type SignedRewardBase = SignedRewardBase; | ||
| type SignedDepositBase = SignedDepositBase; | ||
| type SignedDepositByte = SignedDepositByte; | ||
| type SignedDepositWeight = (); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note |
||
| type SignedMaxWeight = MinerMaxWeight; | ||
| type SlashHandler = (); // burn slashes | ||
kianenigma marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| type RewardHandler = (); // nothing to do upon rewards | ||
coriolinus marked this conversation as resolved.
Show resolved
Hide resolved
emostov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| type DataProvider = Staking; | ||
| type OnChainAccuracy = Perbill; | ||
| type CompactSolution = NposCompactSolution16; | ||
|
|
@@ -1556,6 +1570,7 @@ impl_runtime_apis! { | |
| add_benchmark!(params, batches, pallet_uniques, Uniques); | ||
| add_benchmark!(params, batches, pallet_utility, Utility); | ||
| add_benchmark!(params, batches, pallet_vesting, Vesting); | ||
| add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase); | ||
|
|
||
| if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } | ||
| Ok(batches) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,7 @@ | |
|
|
||
| use super::*; | ||
| use crate::{Pallet as MultiPhase, unsigned::IndexAssignmentOf}; | ||
| use frame_benchmarking::impl_benchmark_test_suite; | ||
| use frame_benchmarking::{account, impl_benchmark_test_suite}; | ||
| use frame_support::{assert_ok, traits::OnInitialize}; | ||
| use frame_system::RawOrigin; | ||
| use rand::{prelude::SliceRandom, rngs::SmallRng, SeedableRng}; | ||
|
|
@@ -57,7 +57,7 @@ fn solution_with_size<T: Config>( | |
| let targets: Vec<T::AccountId> = | ||
| (0..size.targets).map(|i| frame_benchmarking::account("Targets", i, SEED)).collect(); | ||
|
|
||
| let mut rng = SmallRng::seed_from_u64(SEED as u64); | ||
| let mut rng = SmallRng::seed_from_u64(SEED.into()); | ||
|
|
||
| // decide who are the winners. | ||
| let winners = targets | ||
|
|
@@ -176,6 +176,39 @@ frame_benchmarking::benchmarks! { | |
| assert!(<MultiPhase<T>>::current_phase().is_unsigned()); | ||
| } | ||
|
|
||
| finalize_signed_phase_accept_solution { | ||
| let receiver = account("receiver", 0, SEED); | ||
| let initial_balance = T::Currency::minimum_balance() * 10u32.into(); | ||
| T::Currency::make_free_balance_be(&receiver, initial_balance); | ||
| let ready: ReadySolution<T::AccountId> = Default::default(); | ||
| let deposit: BalanceOf<T> = 10u32.into(); | ||
| let reward: BalanceOf<T> = 20u32.into(); | ||
|
|
||
| assert_ok!(T::Currency::reserve(&receiver, deposit)); | ||
| assert_eq!(T::Currency::free_balance(&receiver), initial_balance - 10u32.into()); | ||
| }: { | ||
| <MultiPhase<T>>::finalize_signed_phase_accept_solution(ready, &receiver, deposit, reward) | ||
| } verify { | ||
| assert_eq!(T::Currency::free_balance(&receiver), initial_balance + 20u32.into()); | ||
| assert_eq!(T::Currency::reserved_balance(&receiver), 0u32.into()); | ||
| } | ||
|
|
||
| finalize_signed_phase_reject_solution { | ||
| let receiver = account("receiver", 0, SEED); | ||
| let initial_balance = T::Currency::minimum_balance().max(One::one()) * 10u32.into(); | ||
| let deposit: BalanceOf<T> = 10u32.into(); | ||
| T::Currency::make_free_balance_be(&receiver, initial_balance); | ||
| assert_ok!(T::Currency::reserve(&receiver, deposit)); | ||
|
|
||
| assert_eq!(T::Currency::free_balance(&receiver), initial_balance - 10u32.into()); | ||
| assert_eq!(T::Currency::reserved_balance(&receiver), 10u32.into()); | ||
| }: { | ||
| <MultiPhase<T>>::finalize_signed_phase_reject_solution(&receiver, deposit) | ||
| } verify { | ||
| assert_eq!(T::Currency::free_balance(&receiver), initial_balance - 10u32.into()); | ||
| assert_eq!(T::Currency::reserved_balance(&receiver), 0u32.into()); | ||
| } | ||
|
|
||
| on_initialize_open_unsigned_without_snapshot { | ||
| // need to assume signed phase was open before | ||
| <MultiPhase<T>>::on_initialize_open_signed().unwrap(); | ||
|
|
@@ -227,16 +260,51 @@ frame_benchmarking::benchmarks! { | |
| assert!(<MultiPhase<T>>::snapshot().is_some()); | ||
| } | ||
|
|
||
| submit { | ||
| let c in 1 .. (T::SignedMaxSubmissions::get() - 1); | ||
|
|
||
| // the solution will be worse than all of them meaning the score need to be checked against | ||
| // ~ log2(c) | ||
| let solution = RawSolution { | ||
| score: [(10_000_000u128 - 1).into(), 0, 0], | ||
| ..Default::default() | ||
| }; | ||
|
|
||
| MultiPhase::<T>::on_initialize_open_signed().expect("should be ok to start signed phase"); | ||
| <Round<T>>::put(1); | ||
|
|
||
| let mut signed_submissions = SignedSubmissions::<T>::get(); | ||
| for i in 0..c { | ||
| let solution = RawSolution { | ||
| score: [(10_000_000 + i).into(), 0, 0], | ||
| ..Default::default() | ||
| }; | ||
| let signed_submission = SignedSubmission { solution, ..Default::default() }; | ||
| signed_submissions.insert(signed_submission); | ||
| } | ||
| signed_submissions.put(); | ||
|
|
||
| let caller = frame_benchmarking::whitelisted_caller(); | ||
| T::Currency::make_free_balance_be(&caller, T::Currency::minimum_balance() * 10u32.into()); | ||
|
|
||
| }: _(RawOrigin::Signed(caller), solution, c) | ||
| verify { | ||
| assert!(<MultiPhase<T>>::signed_submissions().len() as u32 == c + 1); | ||
| } | ||
|
|
||
| submit_unsigned { | ||
| // number of votes in snapshot. | ||
| let v in (T::BenchmarkingConfig::VOTERS[0]) .. T::BenchmarkingConfig::VOTERS[1]; | ||
| // number of targets in snapshot. | ||
| let t in (T::BenchmarkingConfig::TARGETS[0]) .. T::BenchmarkingConfig::TARGETS[1]; | ||
| // number of assignments, i.e. compact.len(). This means the active nominators, thus must be | ||
| // a subset of `v` component. | ||
| let a in (T::BenchmarkingConfig::ACTIVE_VOTERS[0]) .. T::BenchmarkingConfig::ACTIVE_VOTERS[1]; | ||
| let a in | ||
| (T::BenchmarkingConfig::ACTIVE_VOTERS[0]) .. T::BenchmarkingConfig::ACTIVE_VOTERS[1]; | ||
| // number of desired targets. Must be a subset of `t` component. | ||
| let d in (T::BenchmarkingConfig::DESIRED_TARGETS[0]) .. T::BenchmarkingConfig::DESIRED_TARGETS[1]; | ||
| let d in | ||
| (T::BenchmarkingConfig::DESIRED_TARGETS[0]) .. | ||
| T::BenchmarkingConfig::DESIRED_TARGETS[1]; | ||
|
|
||
| let witness = SolutionOrSnapshotSize { voters: v, targets: t }; | ||
| let raw_solution = solution_with_size::<T>(witness, a, d); | ||
|
|
@@ -249,7 +317,8 @@ frame_benchmarking::benchmarks! { | |
| let encoded_call = <Call<T>>::submit_unsigned(raw_solution.clone(), witness).encode(); | ||
| }: { | ||
| assert_ok!(<MultiPhase<T>>::submit_unsigned(RawOrigin::None.into(), raw_solution, witness)); | ||
| let _decoded_snap = <RoundSnapshot<T::AccountId> as Decode>::decode(&mut &*encoded_snapshot).unwrap(); | ||
| let _decoded_snap = <RoundSnapshot<T::AccountId> as Decode>::decode(&mut &*encoded_snapshot) | ||
| .unwrap(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of decoding here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe they are trying to take into account decode time to the benchmarking. Especially if it is a very large and potentially expensive storage item. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indeed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I think I see: is it that If this is the case though, shouldn't decoding be taken into account because we have a scenario that will read in the snapshot? |
||
| let _decoded_call = <Call<T> as Decode>::decode(&mut &*encoded_call).unwrap(); | ||
| } verify { | ||
| assert!(<MultiPhase<T>>::queued_solution().is_some()); | ||
|
|
@@ -263,13 +332,17 @@ frame_benchmarking::benchmarks! { | |
| let t in (T::BenchmarkingConfig::TARGETS[0]) .. T::BenchmarkingConfig::TARGETS[1]; | ||
| // number of assignments, i.e. compact.len(). This means the active nominators, thus must be | ||
| // a subset of `v` component. | ||
| let a in (T::BenchmarkingConfig::ACTIVE_VOTERS[0]) .. T::BenchmarkingConfig::ACTIVE_VOTERS[1]; | ||
| let a in | ||
| (T::BenchmarkingConfig::ACTIVE_VOTERS[0]) .. T::BenchmarkingConfig::ACTIVE_VOTERS[1]; | ||
| // number of desired targets. Must be a subset of `t` component. | ||
| let d in (T::BenchmarkingConfig::DESIRED_TARGETS[0]) .. T::BenchmarkingConfig::DESIRED_TARGETS[1]; | ||
| let d in | ||
| (T::BenchmarkingConfig::DESIRED_TARGETS[0]) .. | ||
| T::BenchmarkingConfig::DESIRED_TARGETS[1]; | ||
| // Subtract this percentage from the actual encoded size | ||
| let f in 0 .. 95; | ||
|
|
||
| // Compute a random solution, then work backwards to get the lists of voters, targets, and assignments | ||
| // Compute a random solution, then work backwards to get the lists of voters, targets, and | ||
| // assignments | ||
| let witness = SolutionOrSnapshotSize { voters: v, targets: t }; | ||
| let RawSolution { compact, .. } = solution_with_size::<T>(witness, a, d); | ||
| let RoundSnapshot { voters, targets } = MultiPhase::<T>::snapshot().unwrap(); | ||
|
|
@@ -313,7 +386,11 @@ frame_benchmarking::benchmarks! { | |
| } verify { | ||
| let compact = CompactOf::<T>::try_from(index_assignments.as_slice()).unwrap(); | ||
| let encoding = compact.encode(); | ||
| log!(trace, "encoded size prediction = {}", encoded_size_of(index_assignments.as_slice()).unwrap()); | ||
| log!( | ||
| trace, | ||
| "encoded size prediction = {}", | ||
| encoded_size_of(index_assignments.as_slice()).unwrap(), | ||
| ); | ||
| log!(trace, "actual encoded size = {}", encoding.len()); | ||
| assert!(encoding.len() <= desired_size); | ||
| } | ||
|
|
@@ -326,9 +403,12 @@ frame_benchmarking::benchmarks! { | |
| let t in (T::BenchmarkingConfig::TARGETS[0]) .. T::BenchmarkingConfig::TARGETS[1]; | ||
| // number of assignments, i.e. compact.len(). This means the active nominators, thus must be | ||
| // a subset of `v` component. | ||
| let a in (T::BenchmarkingConfig::ACTIVE_VOTERS[0]) .. T::BenchmarkingConfig::ACTIVE_VOTERS[1]; | ||
| let a in | ||
| (T::BenchmarkingConfig::ACTIVE_VOTERS[0]) .. T::BenchmarkingConfig::ACTIVE_VOTERS[1]; | ||
| // number of desired targets. Must be a subset of `t` component. | ||
| let d in (T::BenchmarkingConfig::DESIRED_TARGETS[0]) .. T::BenchmarkingConfig::DESIRED_TARGETS[1]; | ||
| let d in | ||
| (T::BenchmarkingConfig::DESIRED_TARGETS[0]) .. | ||
| T::BenchmarkingConfig::DESIRED_TARGETS[1]; | ||
|
|
||
| let size = SolutionOrSnapshotSize { voters: v, targets: t }; | ||
| let raw_solution = solution_with_size::<T>(size, a, d); | ||
|
|
@@ -340,7 +420,8 @@ frame_benchmarking::benchmarks! { | |
| let encoded_snapshot = <MultiPhase<T>>::snapshot().unwrap().encode(); | ||
| }: { | ||
| assert_ok!(<MultiPhase<T>>::feasibility_check(raw_solution, ElectionCompute::Unsigned)); | ||
| let _decoded_snap = <RoundSnapshot<T::AccountId> as Decode>::decode(&mut &*encoded_snapshot).unwrap(); | ||
| let _decoded_snap = <RoundSnapshot<T::AccountId> as Decode>::decode(&mut &*encoded_snapshot) | ||
| .unwrap(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.