From 52ad11f0953e7e928014a4314cf0dc550fd3e94a Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 23 Sep 2025 18:36:32 +0800 Subject: [PATCH 01/20] feature in good shape, most tests pass, except those that rely in mock signed shit --- .../election-provider-multi-block/src/lib.rs | 146 ++++++++++------ .../src/mock/mod.rs | 1 + .../src/mock/signed.rs | 1 + .../src/signed/mod.rs | 31 +--- .../src/signed/tests.rs | 109 ++++++------ .../src/types.rs | 7 +- .../src/unsigned/miner.rs | 1 - .../src/verifier/impls.rs | 158 ++++++++++-------- .../src/verifier/mod.rs | 4 + .../runtimes/parachain/src/staking.rs | 3 + 10 files changed, 248 insertions(+), 213 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index aaa292e2f3acf..6e51627fb33cc 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -195,6 +195,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use crate::verifier::AsynchronousVerifier; use codec::{Decode, Encode, MaxEncodedLen}; use frame_election_provider_support::{ onchain, BoundedSupportsOf, DataProviderBounds, ElectionDataProvider, ElectionProvider, @@ -203,6 +204,7 @@ use frame_election_provider_support::{ use frame_support::{ pallet_prelude::*, traits::{Defensive, EnsureOrigin}, + weights::WeightMeter, DebugNoBound, Twox64Concat, }; use frame_system::pallet_prelude::*; @@ -581,6 +583,9 @@ pub mod pallet { AccountId = Self::AccountId, > + verifier::AsynchronousVerifier; + /// Interface signed pallet's interface. + type Signed: crate::signed::Config; + /// The origin that can perform administration operations on this pallet. type AdminOrigin: EnsureOrigin; @@ -659,51 +664,29 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_now: BlockNumberFor) -> Weight { - let current_phase = CurrentPhase::::get(); - let weight1 = match current_phase { - Phase::Snapshot(x) if x == T::Pages::get() => { - // create the target snapshot - Self::create_targets_snapshot(); - T::WeightInfo::on_initialize_into_snapshot_msp() - }, - Phase::Snapshot(x) => { - // create voter snapshot - Self::create_voters_snapshot_paged(x); - T::WeightInfo::on_initialize_into_snapshot_rest() - }, - _ => T::WeightInfo::on_initialize_nothing(), - }; + let current_phase = Self::current_phase(); + let next_phase = current_phase.next(); + let (worst_case_weight, exec) = Self::meta_per_block(current_phase.clone()); - // Only transition if not in Export phase - if !matches!(current_phase, Phase::Export(_)) { - let next_phase = current_phase.next(); - - let weight2 = match next_phase { - Phase::Signed(_) => T::WeightInfo::on_initialize_into_signed(), - Phase::SignedValidation(_) => - T::WeightInfo::on_initialize_into_signed_validation(), - Phase::Unsigned(_) => T::WeightInfo::on_initialize_into_unsigned(), - _ => T::WeightInfo::on_initialize_nothing(), - }; - - Self::phase_transition(next_phase); - - // bit messy, but for now this works best. - #[cfg(test)] - { - let test_election_start: BlockNumberFor = - (crate::mock::ElectionStart::get() as u32).into(); - if _now == test_election_start { - crate::log!(info, "TESTING: Starting election at block {}", _now); - crate::mock::MultiBlock::start().unwrap(); - } - } + // TODO: check weight + let adjusted_weight = exec(); + Self::phase_transition(next_phase); - weight1 + weight2 - } else { - // If in Export phase, do nothing. - weight1 + // NOTE: why in here? bc it is more accessible, for example `roll_to_with_ocw`. + #[cfg(test)] + { + if _now > 200u32.into() { + panic!("looping to death"); + } + let test_election_start: BlockNumberFor = + (crate::mock::ElectionStart::get() as u32).into(); + if _now == test_election_start { + crate::log!(info, "TESTING: Starting election at block {}", _now); + crate::mock::MultiBlock::start().unwrap(); + } } + + adjusted_weight.unwrap_or(worst_case_weight) } fn integrity_test() { @@ -1066,8 +1049,9 @@ pub mod pallet { Phase::Off => Self::ensure_snapshot(false, T::Pages::get()), // we will star the snapshot in the next phase. - Phase::Snapshot(p) if p == T::Pages::get() => - Self::ensure_snapshot(false, T::Pages::get()), + // TODO: + // Phase::Snapshot(p) if p == T::Pages::get() => + // Self::ensure_snapshot(false, T::Pages::get()), // we are mid voter snapshot. Phase::Snapshot(p) if p < T::Pages::get() && p > 0 => Self::ensure_snapshot(true, T::Pages::get() - p - 1), @@ -1197,6 +1181,67 @@ impl Pallet { Zero::zero() } + // before doing anything, check what is our current phase, what is the next phase, and + // return a closure of what ought to happen. Later on, `execute_fn` can return an + // adjusted weight as well. + fn meta_per_block(current_phase: Phase) -> (Weight, Box Option>) { + type ExecuteFn = Box Option>; + let noop: (Weight, ExecuteFn) = (Weight::default(), Box::new(|| None)); + + match current_phase { + Phase::Snapshot(x) if x == T::Pages::get() => { + // first snapshot + let exec: ExecuteFn = Box::new(|| { + Self::create_targets_snapshot(); + None + }); + (T::WeightInfo::on_initialize_into_snapshot_msp(), exec) + }, + + Phase::Snapshot(x) => { + // rest of the snapshot, incl last one. + let exec: ExecuteFn = Box::new(move || { + Self::create_voters_snapshot_paged(x); + None + }); + (T::WeightInfo::on_initialize_into_snapshot_rest(), exec) + }, + Phase::Signed(x) => { + if x.is_zero() { + // Signed pallet should prep the best winner, and send the start signal, if some + // exists. + let maybe_leader = + crate::signed::Submissions::::leader(Self::round()); + log!( + debug, + "signed validation is starting, sending validation start signal? {:?}", + maybe_leader.is_some() + ); + + if maybe_leader.is_some() { + let exec: ExecuteFn = Box::new(|| { + // defensive: signed phase has just began, verifier should be in a + // clear state and ready to accept a solution. Moreover, if we have + // a leader, their score should be present, and pass the + // `ensure_score_quality` (TODO: we actually don't check the minimum + // score in signed.). + let _ = T::Verifier::start().defensive(); + None + }); + (T::WeightInfo::on_initialize_into_signed_validation(), exec) + } else { + noop + } + } else { + noop + } + }, + Phase::SignedValidation(_) => T::Verifier::on_init_execute_fn(), + Phase::Unsigned(_) | Phase::Off | Phase::Emergency | Phase::Done | Phase::Export(_) => + noop, + } + } + /// Return the `length` most significant pages. /// /// For example, if `Pages = 4`, and `length = 2`, our full snapshot range would be [0, @@ -1490,6 +1535,7 @@ where verifier::Pallet::::on_initialize(i); unsigned::Pallet::::on_initialize(i); + // TODO: remove as not sensible anymore. if with_signed { signed::Pallet::::on_initialize(i); } @@ -2325,21 +2371,21 @@ mod election_provider { // there is no queued solution prior to the last page of the solution getting verified assert_eq!(::Verifier::queued_score(), None); - assert_eq!(::Verifier::status(), verifier::Status::Nothing); - - // next block, signed will start the verifier, although nothing is verified yet. - roll_next(); assert_eq!( ::Verifier::status(), verifier::Status::Ongoing(2) ); - assert_eq!(verifier_events(), vec![]); - // proceed until it is fully verified. + // next block, signed will start the verifier, although nothing is verified yet. roll_next(); + assert_eq!( + ::Verifier::status(), + verifier::Status::Ongoing(1) + ); assert_eq!(verifier_events(), vec![verifier::Event::Verified(2, 2)]); roll_next(); + assert_eq!( verifier_events(), vec![verifier::Event::Verified(2, 2), verifier::Event::Verified(1, 2)] diff --git a/substrate/frame/election-provider-multi-block/src/mock/mod.rs b/substrate/frame/election-provider-multi-block/src/mock/mod.rs index 27846e813600b..94e44ecaadbd1 100644 --- a/substrate/frame/election-provider-multi-block/src/mock/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/mock/mod.rs @@ -229,6 +229,7 @@ impl crate::Config for Runtime { type AdminOrigin = EnsureRoot; type Pages = Pages; type AreWeDone = AreWeDone; + type Signed = Runtime; type OnRoundRotation = CleanRound; } diff --git a/substrate/frame/election-provider-multi-block/src/mock/signed.rs b/substrate/frame/election-provider-multi-block/src/mock/signed.rs index 75f4c2368e599..3cb6f73c8b88b 100644 --- a/substrate/frame/election-provider-multi-block/src/mock/signed.rs +++ b/substrate/frame/election-provider-multi-block/src/mock/signed.rs @@ -71,6 +71,7 @@ parameter_types! { pub static InvulnerableDeposit: Balance = 7; pub static SignedMaxSubmissions: u32 = 3; pub static SignedRewardBase: Balance = 3; + // TODO: fully remove; now all pallets get on-init-ed at the master pallet. pub static SignedPhaseSwitch: SignedSwitch = SignedSwitch::Real; pub static BailoutGraceRatio: Perbill = Perbill::from_percent(20); pub static EjectGraceRatio: Perbill = Perbill::from_percent(20); diff --git a/substrate/frame/election-provider-multi-block/src/signed/mod.rs b/substrate/frame/election-provider-multi-block/src/signed/mod.rs index 1aa0dadb2d452..8c255f866fa93 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/mod.rs @@ -950,31 +950,6 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { - fn on_initialize(_: BlockNumberFor) -> Weight { - // this code is only called when at the boundary of phase transition, which is already - // captured by the parent pallet. No need for weight. - let weight_taken_into_account: Weight = Default::default(); - - if crate::Pallet::::current_phase().is_signed_validation_opened_now() { - let maybe_leader = Submissions::::leader(Self::current_round()); - sublog!( - debug, - "signed", - "signed validation started, sending validation start signal? {:?}", - maybe_leader.is_some() - ); - - // start an attempt to verify our best thing. - if maybe_leader.is_some() { - // defensive: signed phase has just began, verifier should be in a clear state - // and ready to accept a solution. - let _ = ::start().defensive(); - } - } - - weight_taken_into_account - } - #[cfg(feature = "try-runtime")] fn try_state(n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { Self::do_try_state(n) @@ -1044,8 +1019,8 @@ impl Pallet { { // Only start verification if there are sufficient blocks remaining // Note: SignedValidation(N) means N+1 blocks remaining in the phase - let actual_blocks_remaining = remaining_blocks.saturating_add(One::one()); - if actual_blocks_remaining >= T::Pages::get().into() { + // TODO: check test cases for the edge cases of this. + if remaining_blocks >= T::Pages::get().into() { if Submissions::::has_leader(current_round) { // defensive: verifier just reported back a result, it must be in clear // state. @@ -1056,7 +1031,7 @@ impl Pallet { warn, "signed", "SignedValidation phase has {:?} blocks remaining, which are insufficient for {} pages", - actual_blocks_remaining, + remaining_blocks, T::Pages::get() ); } diff --git a/substrate/frame/election-provider-multi-block/src/signed/tests.rs b/substrate/frame/election-provider-multi-block/src/signed/tests.rs index 085cec58935c4..19c4547f3cf07 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/tests.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/tests.rs @@ -528,8 +528,7 @@ mod e2e { roll_to_signed_validation_open(); - // 92 is slashed in 3+1 blocks, 999 becomes rewarded in 3 blocks, and 99 is discarded. - roll_next(); + // 92 is slashed in 3 blocks, 999 becomes rewarded in 3 blocks, and 99 is discarded. roll_next(); roll_next(); roll_next(); @@ -675,7 +674,6 @@ mod e2e { assert_eq!(Submissions::::submitters_count(current_round), 1); roll_to_signed_validation_open(); - roll_next(); // one block so signed pallet will send start signal. roll_to_full_verification(); // Check that rejection events were properly generated @@ -816,42 +814,40 @@ mod e2e { roll_to_signed_validation_open(); assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(3)); - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Nothing)); - roll_next(); // one block so signed-pallet will send the start signal + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Ongoing(2)); + assert_eq!(verifier_events_since_last_call(), vec![]); + + roll_next(); assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(2)); - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Ongoing(2))); + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Ongoing(1)); + assert_eq!( + verifier_events_since_last_call(), + vec![crate::verifier::Event::Verified(2, 0)] + ); // Initial verifier state should have no queued solution assert_eq!(VerifierPallet::queued_score(), None); - // Bad solution is the current leader - let mut remaining_leader = Submissions::::leader(current_round).unwrap(); - assert_eq!(remaining_leader.0, 99); - // Bad solution starts verification roll_next(); assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(1)); - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Ongoing(_))); - - roll_next(); - assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(0)); - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Ongoing(_))); + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Ongoing(0)); + assert_eq!( + verifier_events_since_last_call(), + vec![crate::verifier::Event::Verified(1, 0)] + ); roll_next(); assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(0)); - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Nothing)); - - // Check events after bad solution verification completes + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Nothing); assert_eq!( verifier_events_since_last_call(), vec![ - crate::verifier::Event::Verified(2, 0), - crate::verifier::Event::Verified(1, 0), crate::verifier::Event::Verified(0, 0), crate::verifier::Event::VerificationFailed( 0, FeasibilityError::InvalidScore - ), + ) ] ); @@ -862,8 +858,6 @@ mod e2e { // Check that invalid solution is slashed but good solution remains assert_eq!(Submissions::::submitters_count(current_round), 1); assert!(Submissions::::has_leader(current_round)); - remaining_leader = Submissions::::leader(current_round).unwrap(); - assert_eq!(remaining_leader.0, 999); // Good solution remains // Check that expected events were emitted for the rejection assert_eq!( @@ -936,8 +930,7 @@ mod e2e { // henceforth we proceed block-by-block for better visibility of what is happening. - // 3 blocks to reject the first one: 1 to set status to ongoing, and 2 to verify - roll_next(); + // 2 blocks to reject the first one roll_next(); roll_next(); @@ -958,8 +951,12 @@ mod e2e { vec![crate::signed::Event::Slashed(0, 99, 8)] ); - // we have 1 block left in signed verification, but we cannot do anything here. + // we have 2 block left in signed verification, but we cannot do anything here. + // status is not set, as not enough time to do anything. + assert_eq!(crate::Pallet::::current_phase(), Phase::SignedValidation(1)); + roll_next(); assert_eq!(crate::Pallet::::current_phase(), Phase::SignedValidation(0)); + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Nothing); // we go back to signed next roll_next(); @@ -972,7 +969,6 @@ mod e2e { roll_next(); roll_next(); roll_next(); - roll_next(); assert_eq!( verifier_events_since_last_call(), @@ -1037,33 +1033,31 @@ mod e2e { let good_solution = mine_full_solution().unwrap(); load_signed_for_verification(999, good_solution.clone()); } + let _ = signed_events_since_last_call(); let current_round = SignedPallet::current_round(); assert_eq!(Submissions::::submitters_count(current_round), 2); roll_to_signed_validation_open(); - roll_next(); // one block so signed-pallet will send the start signal - assert!(matches!(MultiBlock::current_phase(), Phase::SignedValidation(_))); - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Ongoing(_))); + assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(3)); + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Ongoing(2)); // Bad solution is the current leader (higher score) - let leader = Submissions::::leader(current_round).unwrap(); - assert_eq!(leader.0, 99); + assert_eq!(Submissions::::leader(current_round).unwrap().0, 99); // Block 1: Start verification of bad solution (page 2) - roll_next(); // SignedValidation(2) -> SignedValidation(1) - assert!(matches!(MultiBlock::current_phase(), Phase::SignedValidation(1))); - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Ongoing(_))); + roll_next(); + assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(2)); + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Ongoing(1)); - // Should verify page 2 successfully assert_eq!( verifier_events_since_last_call(), vec![crate::verifier::Event::Verified(2, 2)] ); // Block 2: Continue verification (page 1) - bad solution should fail here - roll_next(); // SignedValidation(1) -> SignedValidation(0) - assert!(matches!(MultiBlock::current_phase(), Phase::SignedValidation(0))); + roll_next(); + assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(1)); // Bad solution should fail early with NposElection error on page 1 verification assert_eq!( @@ -1075,40 +1069,34 @@ mod e2e { ) )] ); - - // Block 3: No more verification needed - bad solution already failed - roll_next(); // SignedValidation(0) -> transitions to next phase - - // Check that bad solution is removed and good solution remains - assert_eq!(Submissions::::submitters_count(current_round), 1); - let remaining_leader = Submissions::::leader(current_round).unwrap(); - assert_eq!(remaining_leader.0, 999); // Good solution is now leader + assert_eq!( + signed_events_since_last_call(), + vec![crate::signed::Event::Slashed(0, 99, 8)] + ); // CRITICAL: Verifier should NOT restart because there are only 2 blocks remaining // (after using 1 block and failing early, but still need 3 blocks for a full // solution) Should transition back to Signed phase since verification cannot // restart - assert!(matches!(MultiBlock::current_phase(), Phase::Signed(_))); + roll_next(); + assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(0)); assert_eq!(VerifierPallet::status(), crate::verifier::Status::Nothing); - // Check events - bad solution should be slashed - let all_signed_events = signed_events(); - assert!(all_signed_events.iter().any(|e| matches!(e, Event::Slashed(0, 99, _)))); + roll_next(); + assert_eq!(MultiBlock::current_phase(), Phase::Signed(4)); + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Nothing); // At the end of signed phase, verifier is still idle assert_eq!(VerifierPallet::status(), crate::verifier::Status::Nothing); roll_to_signed_validation_open(); - roll_next(); // one block so signed-pallet will send the start signal - - // Now in the next validation phase, the good solution starts verification - assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Ongoing(_))); - assert_eq!(Submissions::::submitters_count(current_round), 1); + assert_eq!(MultiBlock::current_phase(), Phase::SignedValidation(3)); + assert_eq!(VerifierPallet::status(), crate::verifier::Status::Ongoing(2)); // Verify the good solution over 3 blocks - roll_next(); // Process page 2 - roll_next(); // Process page 1 - roll_next(); // Process page 0 + roll_next(); + roll_next(); + roll_next(); // Good solution should be fully verified and accepted assert_eq!(crate::Pallet::::current_phase(), Phase::SignedValidation(0)); @@ -1158,7 +1146,6 @@ mod e2e { // Move to verification phase roll_to_signed_validation_open(); - roll_next(); // one block so signed-pallet will send the start signal assert!(matches!(VerifierPallet::status(), crate::verifier::Status::Ongoing(_))); // Process first invalid solution (91) @@ -1520,7 +1507,6 @@ mod invulnerables { let _ = signed_events_since_last_call(); roll_to_signed_validation_open(); - roll_next(); roll_to_full_verification(); assert_eq!( @@ -1605,7 +1591,6 @@ mod invulnerables { assert_ok!(SignedPallet::register(RuntimeOrigin::signed(99), invalid_score)); roll_to_signed_validation_open(); - roll_next(); // one block so signed pallet will send start signal. roll_to_full_verification(); // Check that rejection events were properly generated @@ -1641,7 +1626,7 @@ mod defensive_tests { #[test] #[cfg(debug_assertions)] - #[should_panic(expected = "Defensive failure has been triggered!")] + #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: Other(\"item existing in metadata but missing in sorted list.\")")] fn missing_leader_storage_triggers_defensive() { // Call Verifier::start and mutate storage to delete the score of the leader. // This creates the scenario where score becomes unavailable during verification diff --git a/substrate/frame/election-provider-multi-block/src/types.rs b/substrate/frame/election-provider-multi-block/src/types.rs index 41dffb49c7c4d..17d7dba747893 100644 --- a/substrate/frame/election-provider-multi-block/src/types.rs +++ b/substrate/frame/election-provider-multi-block/src/types.rs @@ -361,10 +361,9 @@ impl Phase { // Done. Wait for export to start. Self::Done => Self::Done, - // Export - Self::Export(0) => Self::Off, - Self::Export(non_zero_left) => - Self::Export(non_zero_left.defensive_saturating_sub(One::one())), + // Export never moves forward via this function, and is always manually set in `elect` + // code path. + Self::Export(x) => Self::Export(x), } } diff --git a/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs b/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs index 6e2e11aa16942..ea4f14cfcc1ca 100644 --- a/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs +++ b/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs @@ -1023,7 +1023,6 @@ mod trimming { ); assert_eq!(solution.solution_pages.encoded_size(), 105); - load_mock_signed_and_start(solution); let supports = roll_to_full_verification(); diff --git a/substrate/frame/election-provider-multi-block/src/verifier/impls.rs b/substrate/frame/election-provider-multi-block/src/verifier/impls.rs index ee67db14fe12f..9be37746dd1e0 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/impls.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/impls.rs @@ -612,10 +612,6 @@ pub(crate) mod pallet { assert!(T::MaxBackersPerWinner::get() <= T::MaxBackersPerWinnerFinal::get()); } - fn on_initialize(_n: BlockNumberFor) -> Weight { - Self::do_on_initialize() - } - #[cfg(feature = "try-runtime")] fn try_state(_now: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { Self::do_try_state(_now) @@ -624,75 +620,97 @@ pub(crate) mod pallet { } impl Pallet { - fn do_on_initialize() -> Weight { + fn do_on_init_execute_fn() -> (Weight, Box Option>) { if let Status::Ongoing(current_page) = Self::status_storage() { - let page_solution = - ::get_page(current_page); - - let maybe_supports = Self::feasibility_check_page_inner(page_solution, current_page); - - sublog!( - debug, - "verifier", - "verified page {} of a solution, outcome = {:?}", - current_page, - maybe_supports.as_ref().map(|s| s.len()) - ); - - match maybe_supports { - Ok(supports) => { - Self::deposit_event(Event::::Verified(current_page, supports.len() as u32)); - QueuedSolution::::set_invalid_page(current_page, supports); - - if current_page > crate::Pallet::::lsp() { - // not last page, just tick forward. - StatusStorage::::put(Status::Ongoing(current_page.saturating_sub(1))); - VerifierWeightsOf::::on_initialize_valid_non_terminal() - } else { - // last page, finalize everything. Get the claimed score. - let claimed_score = T::SolutionDataProvider::get_score(); - - // in both cases of the following match, we are back to the nothing state. - StatusStorage::::put(Status::Nothing); - - match Self::finalize_async_verification(claimed_score) { - Ok(_) => { - T::SolutionDataProvider::report_result(VerificationResult::Queued); - VerifierWeightsOf::::on_initialize_valid_terminal() - }, - Err(_) => { + let worst_case_weight = VerifierWeightsOf::::on_initialize_valid_non_terminal() + .max(VerifierWeightsOf::::on_initialize_valid_terminal()) + .max(VerifierWeightsOf::::on_initialize_invalid_non_terminal(T::Pages::get())) + .max(VerifierWeightsOf::::on_initialize_invalid_terminal()); + let execute = Box::new(move || { + { + let page_solution = + ::get_page(current_page); + let maybe_supports = + Self::feasibility_check_page_inner(page_solution, current_page); + + sublog!( + debug, + "verifier", + "verified page {} of a solution, outcome = {:?}", + current_page, + maybe_supports.as_ref().map(|s| s.len()) + ); + let actual_weight = match maybe_supports { + Ok(supports) => { + Self::deposit_event(Event::::Verified( + current_page, + supports.len() as u32, + )); + QueuedSolution::::set_invalid_page(current_page, supports); + + if current_page > crate::Pallet::::lsp() { + // not last page, just tick forward. + StatusStorage::::put(Status::Ongoing( + current_page.saturating_sub(1), + )); + VerifierWeightsOf::::on_initialize_valid_non_terminal() + } else { + // last page, finalize everything. Get the claimed score. + let claimed_score = T::SolutionDataProvider::get_score(); + + // in both cases of the following match, we are back to the nothing + // state. + StatusStorage::::put(Status::Nothing); + + match Self::finalize_async_verification(claimed_score) { + Ok(_) => { + T::SolutionDataProvider::report_result( + VerificationResult::Queued, + ); + VerifierWeightsOf::::on_initialize_valid_terminal() + }, + Err(_) => { + T::SolutionDataProvider::report_result( + VerificationResult::Rejected, + ); + // In case of any of the errors, kill the solution. + QueuedSolution::::clear_invalid_and_backings(); + VerifierWeightsOf::::on_initialize_invalid_terminal() + }, + } + } + }, + Err(err) => { + // the page solution was invalid. + Self::deposit_event(Event::::VerificationFailed(current_page, err)); + + sublog!(warn, "verifier", "Clearing any ongoing unverified solution."); + // Clear any ongoing solution that has not been verified, regardless of + // the current state. + QueuedSolution::::clear_invalid_and_backings_unchecked(); + + // we also mutate the status back to doing nothing. + let was_ongoing = + matches!(StatusStorage::::get(), Status::Ongoing(_)); + StatusStorage::::put(Status::Nothing); + + if was_ongoing { T::SolutionDataProvider::report_result( VerificationResult::Rejected, ); - // In case of any of the errors, kill the solution. - QueuedSolution::::clear_invalid_and_backings(); - VerifierWeightsOf::::on_initialize_invalid_terminal() - }, - } - } - }, - Err(err) => { - // the page solution was invalid. - Self::deposit_event(Event::::VerificationFailed(current_page, err)); - - sublog!(warn, "verifier", "Clearing any ongoing unverified solutions."); - // Clear any ongoing solution that has not been verified, regardless of the - // current state. - QueuedSolution::::clear_invalid_and_backings_unchecked(); - - // we also mutate the status back to doing nothing. - let was_ongoing = matches!(StatusStorage::::get(), Status::Ongoing(_)); - StatusStorage::::put(Status::Nothing); - - if was_ongoing { - T::SolutionDataProvider::report_result(VerificationResult::Rejected); - } - let wasted_pages = T::Pages::get().saturating_sub(current_page); - VerifierWeightsOf::::on_initialize_invalid_non_terminal(wasted_pages) - }, - } + } + let wasted_pages = T::Pages::get().saturating_sub(current_page); + VerifierWeightsOf::::on_initialize_invalid_non_terminal(wasted_pages) + }, + }; + + Some(actual_weight) + } + }); + + (worst_case_weight, execute) } else { - T::DbWeight::get().reads(1) + (T::DbWeight::get().reads(1), Box::new(|| None)) } } @@ -990,6 +1008,10 @@ impl Verifier for Pallet { Self::deposit_event(Event::::Queued(score, QueuedSolution::::queued_score())); QueuedSolution::::force_set_single_page_valid(page, partial_supports, score); } + + fn on_init_execute_fn() -> (Weight, Box Option>) { + Self::do_on_init_execute_fn() + } } impl AsynchronousVerifier for Pallet { diff --git a/substrate/frame/election-provider-multi-block/src/verifier/mod.rs b/substrate/frame/election-provider-multi-block/src/verifier/mod.rs index a561de63e9008..f6693b2d724ff 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/mod.rs @@ -81,6 +81,7 @@ use impls::SupportsOfVerifier; pub use impls::{feasibility_check_page_inner_with_snapshot, pallet::*, Status}; use sp_core::Get; use sp_npos_elections::ElectionScore; +use sp_runtime::Weight; use sp_std::{fmt::Debug, prelude::*}; /// Errors that can happen in the feasibility check. @@ -213,6 +214,9 @@ pub trait Verifier { page: PageIndex, score: ElectionScore, ); + + /// What this pallet has to be doing on-init. + fn on_init_execute_fn() -> (Weight, Box Option>); } /// Simple enum to encapsulate the result of the verification of a candidate solution. diff --git a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs index 3e06f263432e0..840f682aeb9f9 100644 --- a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs +++ b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs @@ -65,6 +65,9 @@ pub(crate) fn enable_ksm_preset(fast: bool) { // // The default values here are related to `dev`. The above helper functions are used at launch (see // `build_state` runtime-api) to enable dot/ksm presets. +/// This macro contains all of the variable parameters that we intend to use for Polkadot and +/// Kusama. + parameter_types! { /// Number of election pages that we operate upon. /// From 2608c36f10fa15215002d1cfd0611d457bf82928 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 23 Sep 2025 19:19:20 +0800 Subject: [PATCH 02/20] new combinator logic, all tests pass --- .../election-provider-multi-block/src/lib.rs | 128 +++++++++++------- .../src/signed/tests.rs | 2 +- .../src/verifier/impls.rs | 2 +- .../src/verifier/mod.rs | 2 +- 4 files changed, 82 insertions(+), 52 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index 6e51627fb33cc..842995cab5457 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -59,20 +59,6 @@ //! reverse, we rely on [`crate::verifier::Verifier`] trait, which is indeed part of //! [`crate::Config`]. This is merely an implementation opinion. //! -//! ### Pallet Ordering: -//! -//! TODO: @kiaenigma: this needs clarification and a enforcement. Signed pallet should come first. -//! Fixing this should yield removing `verifier_done` from the phase transition. -//! -//! The ordering of these pallets in a runtime should be: -//! * parent -//! * verifier -//! * signed -//! * unsigned -//! -//! This is critical for the phase transition to work. -//! -//! > This should be manually checked, there is not automated way to test it. //! //! ## Pagination //! @@ -663,13 +649,41 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { + /// [`create::types::Phase`] fn on_initialize(_now: BlockNumberFor) -> Weight { let current_phase = Self::current_phase(); let next_phase = current_phase.next(); - let (worst_case_weight, exec) = Self::meta_per_block(current_phase.clone()); + + let (meta_weight, meta_exec) = Self::per_block_exec(current_phase.clone()); + let (verifier_weight, verifier_exc) = T::Verifier::per_block_exec(); + + // The following will combine `Self::per_block_exec` and `T::Verifier::per_block_exec` + // into a single set of `(Weight, Box<_>)`. Can be moved into a function if we have this + // pattern in more places. + let (combined_weight, combined_exec) = ( + // pre-exec weight is simply addition. + meta_weight.saturating_add(verifier_weight), + // our new exec is.. + Box::new(move || { + // execute both this.. + let corrected_meta_weight = meta_exec(); + // .. and that + let corrected_verifier_weight = verifier_exc(); + // for each, if they have returned an updated weight, use that, else the + // pre-exec weight, and re-sum them up. + let final_weight = corrected_meta_weight + .unwrap_or(meta_weight) + .saturating_add(corrected_verifier_weight.unwrap_or(verifier_weight)); + if final_weight != meta_weight.saturating_add(verifier_weight) { + Some(final_weight) + } else { + None + } + }), + ); // TODO: check weight - let adjusted_weight = exec(); + let final_combined_weight = combined_exec(); Self::phase_transition(next_phase); // NOTE: why in here? bc it is more accessible, for example `roll_to_with_ocw`. @@ -686,7 +700,7 @@ pub mod pallet { } } - adjusted_weight.unwrap_or(worst_case_weight) + final_combined_weight.unwrap_or(combined_weight) } fn integrity_test() { @@ -1181,10 +1195,33 @@ impl Pallet { Zero::zero() } - // before doing anything, check what is our current phase, what is the next phase, and - // return a closure of what ought to happen. Later on, `execute_fn` can return an - // adjusted weight as well. - fn meta_per_block(current_phase: Phase) -> (Weight, Box Option>) { + /// The meta-phase transition logic that applies to all pallets. Includes the following: + /// + /// * Creating snapshot once `ElectionProvider::start` has instructed us to do so. + /// * Transition into `Phase::Signed`. + /// * Upon last page of `Phase::Signed`, instruct the `Verifier` to start, if any solution + /// exists. + /// + /// What it does not: + /// + /// * Instruct the verifier to move forward. This happens through + /// [`verifier::Verifier::per_block_exec`]. On each block [`T::Verifier`] is given a chance to + /// do something. (Under the hood, if the `Status` is set, it will do something, regardless of + /// which phase we are in.) + /// * Move us forward if we are in either of `Phase::Done` or `Phase::Export`. These are + /// controlled by the caller of our `ElectionProvider` implementation, i.e. staking. + /// + /// ### Type + /// + /// The commonly used `(Weight, Box Option>)` should be interpreted as such: + /// + /// * The `Weight` is the pre-computed worst case weight of the operation that we are going to + /// do. + /// * The `Box Option>` is the function that represents that the work that + /// will at most consume the said amount of weight. + /// * Optionally, it can return an updated weight that is more "accurate", based on the + /// execution. + fn per_block_exec(current_phase: Phase) -> (Weight, Box Option>) { type ExecuteFn = Box Option>; let noop: (Weight, ExecuteFn) = (Weight::default(), Box::new(|| None)); @@ -1207,38 +1244,31 @@ impl Pallet { (T::WeightInfo::on_initialize_into_snapshot_rest(), exec) }, Phase::Signed(x) => { - if x.is_zero() { - // Signed pallet should prep the best winner, and send the start signal, if some - // exists. - let maybe_leader = - crate::signed::Submissions::::leader(Self::round()); - log!( - debug, - "signed validation is starting, sending validation start signal? {:?}", - maybe_leader.is_some() - ); - - if maybe_leader.is_some() { - let exec: ExecuteFn = Box::new(|| { - // defensive: signed phase has just began, verifier should be in a - // clear state and ready to accept a solution. Moreover, if we have - // a leader, their score should be present, and pass the - // `ensure_score_quality` (TODO: we actually don't check the minimum - // score in signed.). - let _ = T::Verifier::start().defensive(); - None - }); - (T::WeightInfo::on_initialize_into_signed_validation(), exec) - } else { - noop - } + // Signed pallet should prep the best winner, and send the start signal, if some + // exists. + if x.is_zero() && + crate::signed::Submissions::::leader(Self::round()).is_some() + { + let exec: ExecuteFn = Box::new(|| { + // defensive: signed phase has just began, verifier should be in a + // clear state and ready to accept a solution. Moreover, if we have + // a leader, their score should be present, and pass the + // `ensure_score_quality` (TODO: we actually don't check the minimum + // score in signed.). + let _ = T::Verifier::start().defensive(); + None + }); + (T::WeightInfo::on_initialize_into_signed_validation(), exec) } else { noop } }, - Phase::SignedValidation(_) => T::Verifier::on_init_execute_fn(), - Phase::Unsigned(_) | Phase::Off | Phase::Emergency | Phase::Done | Phase::Export(_) => - noop, + Phase::SignedValidation(_) | + Phase::Unsigned(_) | + Phase::Off | + Phase::Emergency | + Phase::Done | + Phase::Export(_) => noop, } } diff --git a/substrate/frame/election-provider-multi-block/src/signed/tests.rs b/substrate/frame/election-provider-multi-block/src/signed/tests.rs index 19c4547f3cf07..756b085ebac7c 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/tests.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/tests.rs @@ -1626,7 +1626,7 @@ mod defensive_tests { #[test] #[cfg(debug_assertions)] - #[should_panic(expected = "called `Result::unwrap()` on an `Err` value: Other(\"item existing in metadata but missing in sorted list.\")")] + #[should_panic(expected = "Defensive failure has been triggered!")] fn missing_leader_storage_triggers_defensive() { // Call Verifier::start and mutate storage to delete the score of the leader. // This creates the scenario where score becomes unavailable during verification diff --git a/substrate/frame/election-provider-multi-block/src/verifier/impls.rs b/substrate/frame/election-provider-multi-block/src/verifier/impls.rs index 9be37746dd1e0..a02d813075882 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/impls.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/impls.rs @@ -1009,7 +1009,7 @@ impl Verifier for Pallet { QueuedSolution::::force_set_single_page_valid(page, partial_supports, score); } - fn on_init_execute_fn() -> (Weight, Box Option>) { + fn per_block_exec() -> (Weight, Box Option>) { Self::do_on_init_execute_fn() } } diff --git a/substrate/frame/election-provider-multi-block/src/verifier/mod.rs b/substrate/frame/election-provider-multi-block/src/verifier/mod.rs index f6693b2d724ff..fadaf13934816 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/mod.rs @@ -216,7 +216,7 @@ pub trait Verifier { ); /// What this pallet has to be doing on-init. - fn on_init_execute_fn() -> (Weight, Box Option>); + fn per_block_exec() -> (Weight, Box Option>); } /// Simple enum to encapsulate the result of the verification of a candidate solution. From 88cb1604680436792ba08ce65a65f61488d7f3d9 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 1 Oct 2025 10:06:46 +0100 Subject: [PATCH 03/20] fix benchmarks too --- substrate/frame/election-provider-multi-block/src/lib.rs | 8 ++++---- .../src/verifier/benchmarking.rs | 8 -------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index 842995cab5457..fdb59a45e7fd6 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -649,7 +649,7 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { - /// [`create::types::Phase`] + /// see [`create::types::Phase`]. fn on_initialize(_now: BlockNumberFor) -> Weight { let current_phase = Self::current_phase(); let next_phase = current_phase.next(); @@ -658,8 +658,8 @@ pub mod pallet { let (verifier_weight, verifier_exc) = T::Verifier::per_block_exec(); // The following will combine `Self::per_block_exec` and `T::Verifier::per_block_exec` - // into a single set of `(Weight, Box<_>)`. Can be moved into a function if we have this - // pattern in more places. + // into a single tuple of `(Weight, Box<_>)`. Can be moved into a reusable combinator + // function if we have this pattern in more places. let (combined_weight, combined_exec) = ( // pre-exec weight is simply addition. meta_weight.saturating_add(verifier_weight), @@ -667,7 +667,7 @@ pub mod pallet { Box::new(move || { // execute both this.. let corrected_meta_weight = meta_exec(); - // .. and that + // .. and that. let corrected_verifier_weight = verifier_exc(); // for each, if they have returned an updated weight, use that, else the // pre-exec weight, and re-sum them up. diff --git a/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs b/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs index 50c3e73fbe5c6..15233b2baac9e 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs @@ -51,8 +51,6 @@ mod benchmarks { crate::Pallet::::roll_until_matches(|| { matches!(CurrentPhase::::get(), Phase::SignedValidation(_)) }); - // send start signal - crate::Pallet::::roll_next(true, false); // start signal must have been sent by now assert_eq!(StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp())); @@ -83,8 +81,6 @@ mod benchmarks { crate::Pallet::::roll_until_matches(|| { matches!(CurrentPhase::::get(), Phase::SignedValidation(_)) }); - // send start signal - crate::Pallet::::roll_next(true, false); // start signal must have been sent by now assert_eq!(StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp())); @@ -137,8 +133,6 @@ mod benchmarks { crate::Pallet::::roll_until_matches(|| { matches!(CurrentPhase::::get(), Phase::SignedValidation(_)) }); - // send start signal - crate::Pallet::::roll_next(true, false); assert_eq!(StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp())); // verify all pages, except for the last one. @@ -206,8 +200,6 @@ mod benchmarks { crate::Pallet::::roll_until_matches(|| { matches!(CurrentPhase::::get(), Phase::SignedValidation(_)) }); - // send start signal - crate::Pallet::::roll_next(true, false); // we should be ready to go assert_eq!(StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp())); From fac19566c1e212a76432dcc5cb9845491b5bbf76 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 1 Oct 2025 11:39:00 +0100 Subject: [PATCH 04/20] move to poll, rename all weights --- .../src/benchmarking.rs | 50 ++----------- .../election-provider-multi-block/src/lib.rs | 58 ++++++++++----- .../src/mock/mod.rs | 17 ++--- .../src/weights/mod.rs | 24 ++---- ..._election_provider_multi_block_dot_size.rs | 74 +------------------ ..._election_provider_multi_block_ksm_size.rs | 74 +------------------ .../runtimes/papi-tests/src/cmd.ts | 2 +- .../runtimes/parachain/src/staking.rs | 2 +- 8 files changed, 69 insertions(+), 232 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/benchmarking.rs b/substrate/frame/election-provider-multi-block/src/benchmarking.rs index f818cfc43ce11..3a55fca123c42 100644 --- a/substrate/frame/election-provider-multi-block/src/benchmarking.rs +++ b/substrate/frame/election-provider-multi-block/src/benchmarking.rs @@ -35,7 +35,7 @@ mod benchmarks { use super::*; #[benchmark(pov_mode = Measured)] - fn on_initialize_nothing() -> Result<(), BenchmarkError> { + fn per_block_nothing() -> Result<(), BenchmarkError> { assert_eq!(CurrentPhase::::get(), Phase::Off); #[block] @@ -48,7 +48,7 @@ mod benchmarks { } #[benchmark(pov_mode = Measured)] - fn on_initialize_into_snapshot_msp() -> Result<(), BenchmarkError> { + fn per_block_snapshot_msp() -> Result<(), BenchmarkError> { assert!(T::Pages::get() >= 2, "this benchmark only works in a runtime with 2 pages or more, set at least `type Pages = 2` for benchmark run"); #[cfg(test)] @@ -76,7 +76,7 @@ mod benchmarks { } #[benchmark(pov_mode = Measured)] - fn on_initialize_into_snapshot_rest() -> Result<(), BenchmarkError> { + fn per_block_snapshot_rest() -> Result<(), BenchmarkError> { assert!(T::Pages::get() >= 2, "this benchmark only works in a runtime with 2 pages or more, set at least `type Pages = 2` for benchmark run"); #[cfg(test)] @@ -115,29 +115,7 @@ mod benchmarks { } #[benchmark(pov_mode = Measured)] - fn on_initialize_into_signed() -> Result<(), BenchmarkError> { - #[cfg(test)] - crate::mock::ElectionStart::set(sp_runtime::traits::Bounded::max_value()); - crate::Pallet::::start().unwrap(); - - Pallet::::roll_until_before_matches(|| { - matches!(CurrentPhase::::get(), Phase::Signed(_)) - }); - - assert_eq!(CurrentPhase::::get(), Phase::Snapshot(0)); - - #[block] - { - Pallet::::roll_next(true, false); - } - - assert!(CurrentPhase::::get().is_signed()); - - Ok(()) - } - - #[benchmark(pov_mode = Measured)] - fn on_initialize_into_signed_validation() -> Result<(), BenchmarkError> { + fn per_block_start_signed_validation() -> Result<(), BenchmarkError> { #[cfg(test)] crate::mock::ElectionStart::set(sp_runtime::traits::Bounded::max_value()); crate::Pallet::::start().unwrap(); @@ -153,26 +131,8 @@ mod benchmarks { Pallet::::roll_next(true, false); } - Ok(()) - } - - #[benchmark(pov_mode = Measured)] - fn on_initialize_into_unsigned() -> Result<(), BenchmarkError> { - #[cfg(test)] - crate::mock::ElectionStart::set(sp_runtime::traits::Bounded::max_value()); - crate::Pallet::::start().unwrap(); - - Pallet::::roll_until_before_matches(|| { - matches!(CurrentPhase::::get(), Phase::Unsigned(_)) - }); - assert!(matches!(CurrentPhase::::get(), Phase::SignedValidation(_))); - - #[block] - { - Pallet::::roll_next(true, false); - } + assert!(CurrentPhase::::get().is_signed_validation()); - assert!(matches!(CurrentPhase::::get(), Phase::Unsigned(_))); Ok(()) } diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index fdb59a45e7fd6..650d5d4c45b62 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -649,8 +649,8 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { - /// see [`create::types::Phase`]. - fn on_initialize(_now: BlockNumberFor) -> Weight { + fn on_poll(_now: BlockNumberFor, weight_meter: &mut WeightMeter) { + // we need current phase to be read in any case -- we can live wiht it. let current_phase = Self::current_phase(); let next_phase = current_phase.next(); @@ -682,9 +682,26 @@ pub mod pallet { }), ); - // TODO: check weight - let final_combined_weight = combined_exec(); - Self::phase_transition(next_phase); + // TODO: we are not registering export weight anywhere. + log!( + debug, + "required weight for transition from {:?} to {:?} is {:?}", + current_phase, + next_phase, + combined_weight + ); + if weight_meter.can_consume(combined_weight) { + let final_combined_weight = combined_exec(); + Self::phase_transition(next_phase); + weight_meter.consume(final_combined_weight.unwrap_or(combined_weight)) + } else { + Self::deposit_event(Event::UnexpectedPhaseTransitionOutOfWeight { + from: current_phase, + to: next_phase, + required: combined_weight, + had: weight_meter.remaining(), + }); + } // NOTE: why in here? bc it is more accessible, for example `roll_to_with_ocw`. #[cfg(test)] @@ -699,8 +716,6 @@ pub mod pallet { crate::mock::MultiBlock::start().unwrap(); } } - - final_combined_weight.unwrap_or(combined_weight) } fn integrity_test() { @@ -783,6 +798,13 @@ pub mod pallet { UnexpectedTargetSnapshotFailed, /// Voter snapshot creation failed UnexpectedVoterSnapshotFailed, + /// Phase transition could not proceed due to being out of weight + UnexpectedPhaseTransitionOutOfWeight { + from: Phase, + to: Phase, + required: Weight, + had: Weight, + }, } /// Error of the pallet that can be returned in response to dispatches. @@ -1223,7 +1245,7 @@ impl Pallet { /// execution. fn per_block_exec(current_phase: Phase) -> (Weight, Box Option>) { type ExecuteFn = Box Option>; - let noop: (Weight, ExecuteFn) = (Weight::default(), Box::new(|| None)); + let noop: (Weight, ExecuteFn) = (T::WeightInfo::per_block_nothing(), Box::new(|| None)); match current_phase { Phase::Snapshot(x) if x == T::Pages::get() => { @@ -1232,7 +1254,7 @@ impl Pallet { Self::create_targets_snapshot(); None }); - (T::WeightInfo::on_initialize_into_snapshot_msp(), exec) + (T::WeightInfo::per_block_snapshot_msp(), exec) }, Phase::Snapshot(x) => { @@ -1241,7 +1263,7 @@ impl Pallet { Self::create_voters_snapshot_paged(x); None }); - (T::WeightInfo::on_initialize_into_snapshot_rest(), exec) + (T::WeightInfo::per_block_snapshot_rest(), exec) }, Phase::Signed(x) => { // Signed pallet should prep the best winner, and send the start signal, if some @@ -1258,7 +1280,7 @@ impl Pallet { let _ = T::Verifier::start().defensive(); None }); - (T::WeightInfo::on_initialize_into_signed_validation(), exec) + (T::WeightInfo::per_block_start_signed_validation(), exec) } else { noop } @@ -1561,14 +1583,14 @@ where while i <= n { frame_system::Pallet::::set_block_number(i); - Pallet::::on_initialize(i); - verifier::Pallet::::on_initialize(i); - unsigned::Pallet::::on_initialize(i); + Pallet::::on_poll(i, &mut WeightMeter::new()); + // verifier::Pallet::::on_poll(i); + // unsigned::Pallet::::on_poll(i); - // TODO: remove as not sensible anymore. - if with_signed { - signed::Pallet::::on_initialize(i); - } + // // TODO: remove as not sensible anymore. + // if with_signed { + // signed::Pallet::::on_poll(i); + // } // invariants must hold at the end of each block. if try_state { diff --git a/substrate/frame/election-provider-multi-block/src/mock/mod.rs b/substrate/frame/election-provider-multi-block/src/mock/mod.rs index 94e44ecaadbd1..e9330ad81919d 100644 --- a/substrate/frame/election-provider-multi-block/src/mock/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/mock/mod.rs @@ -741,19 +741,14 @@ pub fn roll_to_with_ocw(n: BlockNumber, maybe_pool: Option System::set_block_number(i); - MultiBlock::on_initialize(i); - VerifierPallet::on_initialize(i); - UnsignedPallet::on_initialize(i); - if matches!(SignedPhaseSwitch::get(), SignedSwitch::Real) { - SignedPallet::on_initialize(i); - } + MultiBlock::on_poll(i, &mut WeightMeter::new()); + // VerifierPallet::on_poll(i); + // UnsignedPallet::on_poll(i); + // if matches!(SignedPhaseSwitch::get(), SignedSwitch::Real) { + // SignedPallet::on_poll(i); + // } - MultiBlock::offchain_worker(i); - VerifierPallet::offchain_worker(i); UnsignedPallet::offchain_worker(i); - if matches!(SignedPhaseSwitch::get(), SignedSwitch::Real) { - SignedPallet::offchain_worker(i); - } // invariants must hold at the end of each block. all_pallets_sanity_checks() diff --git a/substrate/frame/election-provider-multi-block/src/weights/mod.rs b/substrate/frame/election-provider-multi-block/src/weights/mod.rs index 2fc9b824c9723..9d47381759fd7 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/mod.rs @@ -121,34 +121,26 @@ pub mod traits { /// Weight functions needed for `pallet_election_provider_multi_block`. pub trait WeightInfo { - fn on_initialize_nothing() -> Weight; - fn on_initialize_into_snapshot_msp() -> Weight; - fn on_initialize_into_snapshot_rest() -> Weight; - fn on_initialize_into_signed() -> Weight; - fn on_initialize_into_signed_validation() -> Weight; - fn on_initialize_into_unsigned() -> Weight; + fn per_block_nothing() -> Weight; + fn per_block_snapshot_msp() -> Weight; + fn per_block_snapshot_rest() -> Weight; + fn per_block_start_signed_validation() -> Weight; fn export_non_terminal() -> Weight; fn export_terminal() -> Weight; fn manage() -> Weight; } impl WeightInfo for () { - fn on_initialize_nothing() -> Weight { + fn per_block_nothing() -> Weight { Default::default() } - fn on_initialize_into_snapshot_msp() -> Weight { + fn per_block_snapshot_msp() -> Weight { Default::default() } - fn on_initialize_into_snapshot_rest() -> Weight { + fn per_block_snapshot_rest() -> Weight { Default::default() } - fn on_initialize_into_signed() -> Weight { - Default::default() - } - fn on_initialize_into_signed_validation() -> Weight { - Default::default() - } - fn on_initialize_into_unsigned() -> Weight { + fn per_block_start_signed_validation() -> Weight { Default::default() } fn export_non_terminal() -> Weight { diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs index 67967eff9d159..c5ae4c1d8e619 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs @@ -71,7 +71,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - fn on_initialize_nothing() -> Weight { + fn per_block_nothing() -> Weight { // Proof Size summary in bytes: // Measured: `250` // Estimated: `3715` @@ -104,7 +104,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::PagedTargetSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:0 w:1) /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(64026), added: 66501, mode: `Measured`) - fn on_initialize_into_snapshot_msp() -> Weight { + fn per_block_snapshot_msp() -> Weight { // Proof Size summary in bytes: // Measured: `95465` // Estimated: `5048930` @@ -149,7 +149,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) /// Storage: `MultiBlockElection::PagedVoterSnapshotHash` (r:0 w:1) /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) - fn on_initialize_into_snapshot_rest() -> Weight { + fn per_block_snapshot_rest() -> Weight { // Proof Size summary in bytes: // Measured: `1449068` // Estimated: `3194933` @@ -160,60 +160,13 @@ impl crate::weights::traits::pallet_election_provider_m } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Storage: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// Storage: `Staking::VoterSnapshotStatus` (r:1 w:1) - /// Proof: `Staking::VoterSnapshotStatus` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `Measured`) - /// Storage: `VoterList::CounterForListNodes` (r:1 w:0) - /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: `VoterList::ListNodes` (r:705 w:0) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `Measured`) - /// Storage: `Staking::Bonded` (r:703 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `Measured`) - /// Storage: `Staking::Ledger` (r:703 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(753), added: 3228, mode: `Measured`) - /// Storage: `Staking::Nominators` (r:703 w:0) - /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `Measured`) - /// Storage: `VoterList::ListBags` (r:1 w:0) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `Measured`) - /// Storage: `Staking::Validators` (r:45 w:0) - /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) - /// Storage: `MultiBlockElection::Round` (r:1 w:0) - /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x6358acd2035ec4bb863fa981e0c177b9` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x6358acd2035ec4bb863fa981e0c177b9` (r:1 w:0) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Storage: `Staking::MinimumActiveStake` (r:0 w:1) - /// Proof: `Staking::MinimumActiveStake` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`) - /// Storage: `VoterList::Lock` (r:0 w:1) - /// Proof: `VoterList::Lock` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `Measured`) - /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:0 w:1) - /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) - /// Storage: `MultiBlockElection::PagedVoterSnapshotHash` (r:0 w:1) - /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) - fn on_initialize_into_signed() -> Weight { - // Proof Size summary in bytes: - // Measured: `1516243` - // Estimated: `3262108` - // Minimum execution time: 50_546_380_000 picoseconds. - Weight::from_parts(51_815_377_000, 3262108) - .saturating_add(T::DbWeight::get().reads(2869_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) - } - /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) - /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - fn on_initialize_into_signed_validation() -> Weight { + fn per_block_start_signed_validation() -> Weight { // Proof Size summary in bytes: // Measured: `444` // Estimated: `3909` @@ -222,25 +175,6 @@ impl crate::weights::traits::pallet_election_provider_m .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) - /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xc209f5d8eb920681b56c64b8694ea78c` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xc209f5d8eb920681b56c64b8694ea78c` (r:1 w:0) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - fn on_initialize_into_unsigned() -> Weight { - // Proof Size summary in bytes: - // Measured: `444` - // Estimated: `3909` - // Minimum execution time: 3_740_878_000 picoseconds. - Weight::from_parts(3_808_557_000, 3909) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs index 367b9e8a7028c..501419118ccdc 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs @@ -71,7 +71,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - fn on_initialize_nothing() -> Weight { + fn per_block_nothing() -> Weight { // Proof Size summary in bytes: // Measured: `250` // Estimated: `3715` @@ -104,7 +104,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::PagedTargetSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:0 w:1) /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) - fn on_initialize_into_snapshot_msp() -> Weight { + fn per_block_snapshot_msp() -> Weight { // Proof Size summary in bytes: // Measured: `189963` // Estimated: `10093428` @@ -149,7 +149,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(431919), added: 434394, mode: `Measured`) /// Storage: `MultiBlockElection::PagedVoterSnapshotHash` (r:0 w:1) /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) - fn on_initialize_into_snapshot_rest() -> Weight { + fn per_block_snapshot_rest() -> Weight { // Proof Size summary in bytes: // Measured: `1370478` // Estimated: `3309393` @@ -160,60 +160,13 @@ impl crate::weights::traits::pallet_election_provider_m } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Storage: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// Storage: `Staking::VoterSnapshotStatus` (r:1 w:1) - /// Proof: `Staking::VoterSnapshotStatus` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `Measured`) - /// Storage: `VoterList::CounterForListNodes` (r:1 w:0) - /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: `VoterList::ListNodes` (r:783 w:0) - /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `Measured`) - /// Storage: `Staking::Bonded` (r:781 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `Measured`) - /// Storage: `Staking::Ledger` (r:781 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(753), added: 3228, mode: `Measured`) - /// Storage: `Staking::Nominators` (r:781 w:0) - /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `Measured`) - /// Storage: `VoterList::ListBags` (r:1 w:0) - /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `Measured`) - /// Storage: `Staking::Validators` (r:173 w:0) - /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) - /// Storage: `MultiBlockElection::Round` (r:1 w:0) - /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x6358acd2035ec4bb863fa981e0c177b9` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x6358acd2035ec4bb863fa981e0c177b9` (r:1 w:0) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Storage: `Staking::MinimumActiveStake` (r:0 w:1) - /// Proof: `Staking::MinimumActiveStake` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`) - /// Storage: `VoterList::Lock` (r:0 w:1) - /// Proof: `VoterList::Lock` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `Measured`) - /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:0 w:1) - /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(431919), added: 434394, mode: `Measured`) - /// Storage: `MultiBlockElection::PagedVoterSnapshotHash` (r:0 w:1) - /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) - fn on_initialize_into_signed() -> Weight { - // Proof Size summary in bytes: - // Measured: `1472353` - // Estimated: `3411268` - // Minimum execution time: 55_352_841_000 picoseconds. - Weight::from_parts(55_916_036_000, 3411268) - .saturating_add(T::DbWeight::get().reads(3309_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) - } - /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) - /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - fn on_initialize_into_signed_validation() -> Weight { + fn per_block_start_signed_validation() -> Weight { // Proof Size summary in bytes: // Measured: `444` // Estimated: `3909` @@ -222,25 +175,6 @@ impl crate::weights::traits::pallet_election_provider_m .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) - /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xc209f5d8eb920681b56c64b8694ea78c` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xc209f5d8eb920681b56c64b8694ea78c` (r:1 w:0) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - fn on_initialize_into_unsigned() -> Weight { - // Proof Size summary in bytes: - // Measured: `444` - // Estimated: `3909` - // Minimum execution time: 981_606_000 picoseconds. - Weight::from_parts(2_872_530_000, 3909) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) diff --git a/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts b/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts index 200675d7ac895..7df50029c6b7d 100644 --- a/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts +++ b/substrate/frame/staking-async/runtimes/papi-tests/src/cmd.ts @@ -84,7 +84,7 @@ export async function spawnMiner(): Promise<() => void> { [ "--uri", "ws://127.0.0.1:9946", - "experimental-monitor-multi-block", + "monitor", "--seed-or-path", "//Bob", ], diff --git a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs index 840f682aeb9f9..98be1c7d0060b 100644 --- a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs +++ b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs @@ -67,7 +67,6 @@ pub(crate) fn enable_ksm_preset(fast: bool) { // `build_state` runtime-api) to enable dot/ksm presets. /// This macro contains all of the variable parameters that we intend to use for Polkadot and /// Kusama. - parameter_types! { /// Number of election pages that we operate upon. /// @@ -296,6 +295,7 @@ impl multi_block::Config for Runtime { #[cfg(feature = "runtime-benchmarks")] type Fallback = frame_election_provider_support::onchain::OnChainExecution; type MinerConfig = Self; + type Signed = Self; type Verifier = MultiBlockElectionVerifier; type OnRoundRotation = multi_block::CleanRound; type WeightInfo = multi_block::weights::polkadot::MultiBlockWeightInfo; From 65a2964e59755c17e0b006b93d9ea358a934a7f3 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 1 Oct 2025 12:18:53 +0100 Subject: [PATCH 05/20] cleanup mock signed stuff --- .../src/benchmarking.rs | 8 +- .../election-provider-multi-block/src/lib.rs | 16 +--- .../src/mock/mod.rs | 15 +-- .../src/unsigned/miner.rs | 66 +++++++------- .../src/unsigned/mod.rs | 16 ++-- .../src/verifier/benchmarking.rs | 14 +-- .../src/verifier/tests.rs | 91 +++++++++---------- 7 files changed, 102 insertions(+), 124 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/benchmarking.rs b/substrate/frame/election-provider-multi-block/src/benchmarking.rs index 3a55fca123c42..3a759e6d5580b 100644 --- a/substrate/frame/election-provider-multi-block/src/benchmarking.rs +++ b/substrate/frame/election-provider-multi-block/src/benchmarking.rs @@ -40,7 +40,7 @@ mod benchmarks { #[block] { - Pallet::::roll_next(true, false); + Pallet::::roll_next(false); } assert_eq!(CurrentPhase::::get(), Phase::Off); @@ -59,7 +59,7 @@ mod benchmarks { #[block] { - Pallet::::roll_next(true, false); + Pallet::::roll_next(false); } // we have collected the target snapshot only @@ -99,7 +99,7 @@ mod benchmarks { // take one more snapshot page. #[block] { - Pallet::::roll_next(true, false); + Pallet::::roll_next(false); } // we have now collected the first page of voters. @@ -128,7 +128,7 @@ mod benchmarks { #[block] { - Pallet::::roll_next(true, false); + Pallet::::roll_next(false); } assert!(CurrentPhase::::get().is_signed_validation()); diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index 650d5d4c45b62..a94850cb3a11f 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -1495,7 +1495,7 @@ where /// Progress blocks until the criteria is met. pub(crate) fn roll_until_matches(criteria: impl FnOnce() -> bool + Copy) { loop { - Self::roll_next(true, false); + Self::roll_next(false); if criteria() { break; } @@ -1508,7 +1508,7 @@ where loop { let should_break = frame_support::storage::with_transaction( || -> TransactionOutcome> { - Pallet::::roll_next(true, false); + Pallet::::roll_next(false); if criteria() { TransactionOutcome::Rollback(Ok(true)) } else { @@ -1575,7 +1575,7 @@ where } /// Roll all pallets forward, for the given number of blocks. - pub(crate) fn roll_to(n: BlockNumberFor, with_signed: bool, try_state: bool) { + pub(crate) fn roll_to(n: BlockNumberFor, try_state: bool) { let now = frame_system::Pallet::::block_number(); assert!(n > now, "cannot roll to current or past block"); let one: BlockNumberFor = 1u32.into(); @@ -1584,13 +1584,6 @@ where frame_system::Pallet::::set_block_number(i); Pallet::::on_poll(i, &mut WeightMeter::new()); - // verifier::Pallet::::on_poll(i); - // unsigned::Pallet::::on_poll(i); - - // // TODO: remove as not sensible anymore. - // if with_signed { - // signed::Pallet::::on_poll(i); - // } // invariants must hold at the end of each block. if try_state { @@ -1605,10 +1598,9 @@ where } /// Roll to next block. - pub(crate) fn roll_next(with_signed: bool, try_state: bool) { + pub(crate) fn roll_next(try_state: bool) { Self::roll_to( frame_system::Pallet::::block_number() + 1u32.into(), - with_signed, try_state, ); } diff --git a/substrate/frame/election-provider-multi-block/src/mock/mod.rs b/substrate/frame/election-provider-multi-block/src/mock/mod.rs index e9330ad81919d..8abcde197f40f 100644 --- a/substrate/frame/election-provider-multi-block/src/mock/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/mock/mod.rs @@ -329,14 +329,7 @@ impl ExtBuilder { Self {} } - pub fn verifier() -> Self { - SignedPhase::set(0); - SignedValidationPhase::set(0); - signed::SignedPhaseSwitch::set(signed::SignedSwitch::Mock); - Self {} - } - - pub fn unsigned() -> Self { + pub fn mock_signed() -> Self { SignedPhase::set(0); SignedValidationPhase::set(0); signed::SignedPhaseSwitch::set(signed::SignedSwitch::Mock); @@ -654,7 +647,6 @@ pub fn verifier_events_since_last_call() -> Vec> pub fn roll_to(n: BlockNumber) { crate::Pallet::::roll_to( n, - matches!(SignedPhaseSwitch::get(), SignedSwitch::Real), true, ); } @@ -742,11 +734,6 @@ pub fn roll_to_with_ocw(n: BlockNumber, maybe_pool: Option System::set_block_number(i); MultiBlock::on_poll(i, &mut WeightMeter::new()); - // VerifierPallet::on_poll(i); - // UnsignedPallet::on_poll(i); - // if matches!(SignedPhaseSwitch::get(), SignedSwitch::Real) { - // SignedPallet::on_poll(i); - // } UnsignedPallet::offchain_worker(i); diff --git a/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs b/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs index ea4f14cfcc1ca..1a5d57d0fc4e2 100644 --- a/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs +++ b/substrate/frame/election-provider-multi-block/src/unsigned/miner.rs @@ -1007,7 +1007,7 @@ mod trimming { #[test] fn solution_without_any_trimming() { - ExtBuilder::unsigned().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { // adjust the voters a bit, such that they are all different backings let mut current_voters = Voters::get(); current_voters.iter_mut().for_each(|(who, stake, ..)| *stake = *who); @@ -1050,7 +1050,7 @@ mod trimming { #[test] fn trim_length() { - ExtBuilder::unsigned().miner_max_length(104).build_and_execute(|| { + ExtBuilder::mock_signed().miner_max_length(104).build_and_execute(|| { // adjust the voters a bit, such that they are all different backings let mut current_voters = Voters::get(); current_voters.iter_mut().for_each(|(who, stake, ..)| *stake = *who); @@ -1094,7 +1094,7 @@ mod trimming { #[test] fn trim_length_2() { - ExtBuilder::unsigned().miner_max_length(98).build_and_execute(|| { + ExtBuilder::mock_signed().miner_max_length(98).build_and_execute(|| { // adjust the voters a bit, such that they are all different backings let mut current_voters = Voters::get(); current_voters.iter_mut().for_each(|(who, stake, ..)| *stake = *who); @@ -1136,7 +1136,7 @@ mod trimming { #[test] fn trim_length_3() { - ExtBuilder::unsigned().miner_max_length(92).build_and_execute(|| { + ExtBuilder::mock_signed().miner_max_length(92).build_and_execute(|| { // adjust the voters a bit, such that they are all different backings let mut current_voters = Voters::get(); current_voters.iter_mut().for_each(|(who, stake, ..)| *stake = *who); @@ -1178,7 +1178,7 @@ mod trimming { #[test] fn trim_backers_per_page_works() { - ExtBuilder::unsigned().max_backers_per_winner(2).build_and_execute(|| { + ExtBuilder::mock_signed().max_backers_per_winner(2).build_and_execute(|| { // adjust the voters a bit, such that they are all different backings let mut current_voters = Voters::get(); current_voters.iter_mut().for_each(|(who, stake, ..)| *stake = *who); @@ -1222,7 +1222,7 @@ mod trimming { fn trim_backers_per_page_works_2() { // This one is more interesting, as it also shows that as we trim backers, we re-distribute // their weight elsewhere. - ExtBuilder::unsigned().max_backers_per_winner(1).build_and_execute(|| { + ExtBuilder::mock_signed().max_backers_per_winner(1).build_and_execute(|| { // adjust the voters a bit, such that they are all different backings let mut current_voters = Voters::get(); current_voters.iter_mut().for_each(|(who, stake, ..)| *stake = *who); @@ -1261,7 +1261,7 @@ mod trimming { #[test] fn trim_backers_final_works() { - ExtBuilder::unsigned() + ExtBuilder::mock_signed() .max_backers_per_winner(4) .max_backers_per_winner_final(4) .build_and_execute(|| { @@ -1304,7 +1304,7 @@ mod trimming { #[test] fn trim_backers_per_page_and_final_works() { - ExtBuilder::unsigned() + ExtBuilder::mock_signed() .max_backers_per_winner_final(4) .max_backers_per_winner(2) .build_and_execute(|| { @@ -1348,7 +1348,7 @@ mod trimming { fn aggressive_backer_trimming_maintains_winner_count() { // Test the scenario where aggressive backer trimming is applied but the solution // should still maintain the correct winner count to avoid WrongWinnerCount errors. - ExtBuilder::unsigned() + ExtBuilder::mock_signed() .desired_targets(3) .max_winners_per_page(2) .pages(2) @@ -1403,7 +1403,7 @@ mod base_miner { #[test] fn pagination_does_not_affect_score() { - let score_1 = ExtBuilder::unsigned() + let score_1 = ExtBuilder::mock_signed() .pages(1) .voter_per_page(12) .build_unchecked() @@ -1411,7 +1411,7 @@ mod base_miner { roll_to_snapshot_created(); mine_full_solution().unwrap().score }); - let score_2 = ExtBuilder::unsigned() + let score_2 = ExtBuilder::mock_signed() .pages(2) .voter_per_page(6) .build_unchecked() @@ -1419,7 +1419,7 @@ mod base_miner { roll_to_snapshot_created(); mine_full_solution().unwrap().score }); - let score_3 = ExtBuilder::unsigned() + let score_3 = ExtBuilder::mock_signed() .pages(3) .voter_per_page(4) .build_unchecked() @@ -1434,7 +1434,7 @@ mod base_miner { #[test] fn mine_solution_single_page_works() { - ExtBuilder::unsigned().pages(1).voter_per_page(8).build_and_execute(|| { + ExtBuilder::mock_signed().pages(1).voter_per_page(8).build_and_execute(|| { roll_to_snapshot_created(); ensure_voters(1, 8); @@ -1486,7 +1486,7 @@ mod base_miner { #[test] fn mine_solution_double_page_works() { - ExtBuilder::unsigned().pages(2).voter_per_page(4).build_and_execute(|| { + ExtBuilder::mock_signed().pages(2).voter_per_page(4).build_and_execute(|| { roll_to_snapshot_created(); // 2 pages of 8 voters @@ -1572,7 +1572,7 @@ mod base_miner { #[test] fn mine_solution_triple_page_works() { - ExtBuilder::unsigned().pages(3).voter_per_page(4).build_and_execute(|| { + ExtBuilder::mock_signed().pages(3).voter_per_page(4).build_and_execute(|| { roll_to_snapshot_created(); ensure_voters(3, 12); @@ -1663,7 +1663,7 @@ mod base_miner { #[test] fn mine_solution_choses_most_significant_pages() { - ExtBuilder::unsigned().pages(2).voter_per_page(4).build_and_execute(|| { + ExtBuilder::mock_signed().pages(2).voter_per_page(4).build_and_execute(|| { roll_to_snapshot_created(); ensure_voters(2, 8); @@ -1734,7 +1734,7 @@ mod base_miner { #[test] fn mine_solution_2_out_of_3_pages() { - ExtBuilder::unsigned().pages(3).voter_per_page(4).build_and_execute(|| { + ExtBuilder::mock_signed().pages(3).voter_per_page(4).build_and_execute(|| { roll_to_snapshot_created(); ensure_voters(3, 12); @@ -1833,7 +1833,7 @@ mod base_miner { #[test] fn can_reduce_solution() { - ExtBuilder::unsigned().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let full_edges = OffchainWorkerMiner::::mine_solution(Pages::get(), false) .unwrap() @@ -1862,7 +1862,7 @@ mod offchain_worker_miner { #[test] fn lock_prevents_frequent_execution() { - let (mut ext, _) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, _) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { let offchain_repeat = ::OffchainRepeat::get(); @@ -1900,7 +1900,7 @@ mod offchain_worker_miner { #[test] fn lock_released_after_successful_execution() { // first, ensure that a successful execution releases the lock - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { let guard = StorageValueRef::persistent(&OffchainWorkerMiner::::OFFCHAIN_LOCK); let last_block = @@ -1924,7 +1924,7 @@ mod offchain_worker_miner { #[test] fn lock_prevents_overlapping_execution() { // ensure that if the guard is in hold, a new execution is not allowed. - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { roll_to_unsigned_open(); @@ -1951,7 +1951,7 @@ mod offchain_worker_miner { #[test] fn initial_ocw_runs_and_saves_new_cache() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { roll_to_unsigned_open(); @@ -1974,7 +1974,7 @@ mod offchain_worker_miner { #[test] fn ocw_pool_submission_works() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { roll_to_unsigned_open(); @@ -1995,7 +1995,7 @@ mod offchain_worker_miner { #[test] fn resubmits_after_offchain_repeat() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { let offchain_repeat = ::OffchainRepeat::get(); roll_to_unsigned_open(); @@ -2020,7 +2020,7 @@ mod offchain_worker_miner { #[test] fn regenerates_and_resubmits_after_offchain_repeat_if_no_cache() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { let offchain_repeat = ::OffchainRepeat::get(); roll_to_unsigned_open(); @@ -2054,7 +2054,7 @@ mod offchain_worker_miner { #[test] fn altering_snapshot_invalidates_solution_cache() { // by infeasible, we mean here that if the snapshot fingerprint has changed. - let (mut ext, pool) = ExtBuilder::unsigned().unsigned_phase(999).build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().unsigned_phase(999).build_offchainify(); ext.execute_with_sanity_checks(|| { let offchain_repeat = ::OffchainRepeat::get(); roll_to_unsigned_open(); @@ -2097,7 +2097,7 @@ mod offchain_worker_miner { fn wont_resubmit_if_weak_score() { // common case, if the score is weak, don't bother with anything, ideally check from the // logs that we don't run feasibility in this call path. Score check must come before. - let (mut ext, pool) = ExtBuilder::unsigned().unsigned_phase(999).build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().unsigned_phase(999).build_offchainify(); ext.execute_with_sanity_checks(|| { let offchain_repeat = ::OffchainRepeat::get(); // unfortunately there's no pretty way to run the ocw code such that it generates a @@ -2134,7 +2134,7 @@ mod offchain_worker_miner { #[test] fn ocw_submission_e2e_works() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { assert!(VerifierPallet::queued_score().is_none()); roll_to_with_ocw(25 + 1, Some(pool.clone())); @@ -2152,7 +2152,7 @@ mod offchain_worker_miner { #[test] fn ocw_e2e_submits_and_queued_msp_only() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { // roll to mine roll_to_unsigned_open_with_ocw(None); @@ -2191,7 +2191,7 @@ mod offchain_worker_miner { #[test] fn multi_page_ocw_e2e_submits_and_queued_msp_only() { - let (mut ext, pool) = ExtBuilder::unsigned().miner_pages(2).build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().miner_pages(2).build_offchainify(); ext.execute_with_sanity_checks(|| { // roll to mine roll_to_unsigned_open_with_ocw(None); @@ -2231,7 +2231,7 @@ mod offchain_worker_miner { #[test] fn full_multi_page_ocw_e2e_submits_and_queued_msp_only() { - let (mut ext, pool) = ExtBuilder::unsigned().miner_pages(3).build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().miner_pages(3).build_offchainify(); ext.execute_with_sanity_checks(|| { // roll to mine roll_to_unsigned_open_with_ocw(None); @@ -2277,7 +2277,7 @@ mod offchain_worker_miner { #[test] fn will_not_mine_if_not_enough_winners() { // also see `trim_weight_too_much_makes_solution_invalid`. - let (mut ext, _) = ExtBuilder::unsigned().desired_targets(77).build_offchainify(); + let (mut ext, _) = ExtBuilder::mock_signed().desired_targets(77).build_offchainify(); ext.execute_with_sanity_checks(|| { roll_to_unsigned_open(); ensure_voters(3, 12); @@ -2298,7 +2298,7 @@ mod offchain_worker_miner { // - Initial run: mines and submits without caching // - Resubmission: re-mines fresh solution instead of restoring from cache let (mut ext, pool) = - ExtBuilder::unsigned().offchain_storage(false).build_offchainify(); + ExtBuilder::mock_signed().offchain_storage(false).build_offchainify(); ext.execute_with_sanity_checks(|| { let offchain_repeat = ::OffchainRepeat::get(); roll_to_unsigned_open(); diff --git a/substrate/frame/election-provider-multi-block/src/unsigned/mod.rs b/substrate/frame/election-provider-multi-block/src/unsigned/mod.rs index 0d646e04f5040..e0437ec90dbd4 100644 --- a/substrate/frame/election-provider-multi-block/src/unsigned/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/unsigned/mod.rs @@ -382,7 +382,7 @@ mod validate_unsigned { #[test] fn retracts_weak_score_accepts_threshold_better() { - ExtBuilder::unsigned() + ExtBuilder::mock_signed() .solution_improvement_threshold(sp_runtime::Perbill::from_percent(10)) .build_and_execute(|| { roll_to_snapshot_created(); @@ -443,7 +443,7 @@ mod validate_unsigned { #[test] fn retracts_wrong_round() { - ExtBuilder::unsigned().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_unsigned_open(); let mut attempt = @@ -461,7 +461,7 @@ mod validate_unsigned { #[test] fn retracts_too_many_pages_unsigned() { - ExtBuilder::unsigned().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { // NOTE: unsigned solutions should have just 1 page, regardless of the configured // page count. roll_to_unsigned_open(); @@ -491,7 +491,7 @@ mod validate_unsigned { #[test] fn retracts_wrong_winner_count() { - ExtBuilder::unsigned().desired_targets(2).build_and_execute(|| { + ExtBuilder::mock_signed().desired_targets(2).build_and_execute(|| { roll_to_unsigned_open(); let paged = raw_paged_from_supports( @@ -511,7 +511,7 @@ mod validate_unsigned { #[test] fn retracts_wrong_phase() { - ExtBuilder::unsigned().signed_phase(5, 6).build_and_execute(|| { + ExtBuilder::mock_signed().signed_phase(5, 6).build_and_execute(|| { let solution = raw_paged_solution_low_score(); let call = Call::submit_unsigned { paged_solution: Box::new(solution.clone()) }; @@ -561,7 +561,7 @@ mod validate_unsigned { #[test] fn priority_is_set() { - ExtBuilder::unsigned() + ExtBuilder::mock_signed() .miner_tx_priority(20) .desired_targets(0) .build_and_execute(|| { @@ -591,7 +591,7 @@ mod call { #[test] fn unsigned_submission_e2e() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { roll_to_unsigned_open(); @@ -619,7 +619,7 @@ mod call { expected = "Invalid unsigned submission must produce invalid block and deprive validator from their authoring reward." )] fn unfeasible_solution_panics() { - let (mut ext, pool) = ExtBuilder::unsigned().build_offchainify(); + let (mut ext, pool) = ExtBuilder::mock_signed().build_offchainify(); ext.execute_with_sanity_checks(|| { roll_to_unsigned_open(); diff --git a/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs b/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs index 15233b2baac9e..24a8a25eaff49 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs @@ -57,7 +57,7 @@ mod benchmarks { #[block] { - crate::Pallet::::roll_next(true, false); + crate::Pallet::::roll_next(false); } assert_eq!(StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp() - 1)); @@ -85,7 +85,7 @@ mod benchmarks { // start signal must have been sent by now assert_eq!(StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp())); for _ in 0..(T::Pages::get() - 1) { - crate::Pallet::::roll_next(true, false); + crate::Pallet::::roll_next(false); } // we must have verified all pages by now, minus the last one. @@ -97,7 +97,7 @@ mod benchmarks { // verify the last page. #[block] { - crate::Pallet::::roll_next(true, false); + crate::Pallet::::roll_next(false); } // we are done @@ -137,7 +137,7 @@ mod benchmarks { assert_eq!(StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp())); // verify all pages, except for the last one. for i in 0..T::Pages::get() - 1 { - crate::Pallet::::roll_next(true, false); + crate::Pallet::::roll_next(false); assert_eq!( StatusStorage::::get(), Status::Ongoing(crate::Pallet::::msp() - 1 - i) @@ -153,7 +153,7 @@ mod benchmarks { #[block] { - crate::Pallet::::roll_next(true, false); + crate::Pallet::::roll_next(false); } // we are now reset. @@ -206,7 +206,7 @@ mod benchmarks { // validate the the parameterized number of valid pages. for _ in 0..v { - crate::Pallet::::roll_next(true, false); + crate::Pallet::::roll_next(false); } // we are still ready to continue @@ -215,7 +215,7 @@ mod benchmarks { // verify one page, which will be invalid. #[block] { - crate::Pallet::::roll_next(true, false); + crate::Pallet::::roll_next(false); } // we are now reset, because this page was invalid. diff --git a/substrate/frame/election-provider-multi-block/src/verifier/tests.rs b/substrate/frame/election-provider-multi-block/src/verifier/tests.rs index ffa04df8f6eb8..fc4ddf7f17c99 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/tests.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/tests.rs @@ -35,7 +35,7 @@ mod feasibility_check { #[test] fn missing_snapshot() { - ExtBuilder::verifier().build_unchecked().execute_with(|| { + ExtBuilder::mock_signed().build_unchecked().execute_with(|| { // create snapshot just so that we can create a solution.. roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -49,7 +49,7 @@ mod feasibility_check { ); }); - ExtBuilder::verifier().pages(2).build_unchecked().execute_with(|| { + ExtBuilder::mock_signed().pages(2).build_unchecked().execute_with(|| { roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -62,7 +62,7 @@ mod feasibility_check { ); }); - ExtBuilder::verifier().pages(2).build_unchecked().execute_with(|| { + ExtBuilder::mock_signed().pages(2).build_unchecked().execute_with(|| { roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -75,7 +75,7 @@ mod feasibility_check { )); }); - ExtBuilder::verifier().pages(2).build_unchecked().execute_with(|| { + ExtBuilder::mock_signed().pages(2).build_unchecked().execute_with(|| { roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -88,7 +88,7 @@ mod feasibility_check { ); }); - ExtBuilder::verifier().pages(2).build_unchecked().execute_with(|| { + ExtBuilder::mock_signed().pages(2).build_unchecked().execute_with(|| { roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -104,7 +104,7 @@ mod feasibility_check { #[test] fn winner_indices_single_page_must_be_in_bounds() { - ExtBuilder::verifier().pages(1).desired_targets(2).build_and_execute(|| { + ExtBuilder::mock_signed().pages(1).desired_targets(2).build_and_execute(|| { roll_to_snapshot_created(); let mut paged = mine_full_solution().unwrap(); assert_eq!(crate::Snapshot::::targets().unwrap().len(), 4); @@ -126,7 +126,7 @@ mod feasibility_check { #[test] fn voter_indices_per_page_must_be_in_bounds() { - ExtBuilder::verifier() + ExtBuilder::mock_signed() .pages(1) .voter_per_page(Bounded::max_value()) .desired_targets(2) @@ -160,7 +160,7 @@ mod feasibility_check { #[test] fn voter_must_have_same_targets_as_snapshot() { - ExtBuilder::verifier() + ExtBuilder::mock_signed() .pages(1) .voter_per_page(Bounded::max_value()) .desired_targets(2) @@ -191,7 +191,7 @@ mod feasibility_check { #[test] fn prevents_duplicate_voter_index() { - ExtBuilder::verifier().pages(1).build_and_execute(|| { + ExtBuilder::mock_signed().pages(1).build_and_execute(|| { roll_to_snapshot_created(); // let's build a manual, bogus solution with duplicate voters, on top of page 0 of @@ -216,7 +216,7 @@ mod feasibility_check { #[test] fn prevents_duplicate_target_index() { - ExtBuilder::verifier().pages(1).build_and_execute(|| { + ExtBuilder::mock_signed().pages(1).build_and_execute(|| { roll_to_snapshot_created(); // A bad solution with duplicate targets for a single voter in votes2. @@ -237,7 +237,7 @@ mod feasibility_check { #[test] fn heuristic_max_backers_per_winner_per_page() { - ExtBuilder::verifier().max_backers_per_winner(2).build_and_execute(|| { + ExtBuilder::mock_signed().max_backers_per_winner(2).build_and_execute(|| { roll_to_snapshot_created(); // these votes are all valid, but some dude has 3 supports in a single page. @@ -256,7 +256,7 @@ mod feasibility_check { #[test] fn heuristic_desired_target_check_per_page() { - ExtBuilder::verifier().desired_targets(2).build_and_execute(|| { + ExtBuilder::mock_signed().desired_targets(2).build_and_execute(|| { roll_to(25); assert_full_snapshot(); @@ -288,7 +288,7 @@ mod async_verification { #[test] fn basic_single_verification_works() { - ExtBuilder::verifier().pages(1).build_and_execute(|| { + ExtBuilder::mock_signed().pages(1).build_and_execute(|| { // load a solution after the snapshot has been created. roll_to_snapshot_created(); @@ -313,7 +313,7 @@ mod async_verification { #[test] fn basic_multi_verification_works() { - ExtBuilder::verifier().pages(3).build_and_execute(|| { + ExtBuilder::mock_signed().pages(3).build_and_execute(|| { // load a solution after the snapshot has been created. roll_to_snapshot_created(); @@ -367,7 +367,7 @@ mod async_verification { #[test] fn basic_multi_verification_partial() { - ExtBuilder::verifier().pages(3).build_and_execute(|| { + ExtBuilder::mock_signed().pages(3).build_and_execute(|| { // load a solution after the snapshot has been created. roll_to_snapshot_created(); @@ -429,12 +429,11 @@ mod async_verification { #[test] fn solution_data_provider_empty_data_solution() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { // not super important, but anyways.. roll_to_snapshot_created(); // The solution data provider is empty. - assert_eq!(SignedPhaseSwitch::get(), SignedSwitch::Mock); assert_eq!(MockSignedNextSolution::get(), None); // nothing happens.. @@ -468,7 +467,7 @@ mod async_verification { #[test] fn solution_data_provider_empty_data_midway() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let solution = mine_full_solution().unwrap(); @@ -523,7 +522,7 @@ mod async_verification { #[test] fn solution_data_provider_missing_score_at_end() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let solution = mine_full_solution().unwrap(); @@ -559,7 +558,7 @@ mod async_verification { #[test] fn rejects_new_verification_via_start_if_ongoing() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let solution = mine_full_solution().unwrap(); @@ -583,7 +582,7 @@ mod async_verification { #[test] fn verification_failure_clears_everything() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let mut solution = mine_full_solution().unwrap(); @@ -620,7 +619,7 @@ mod async_verification { #[test] fn weak_valid_solution_is_insta_rejected() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -671,7 +670,7 @@ mod async_verification { #[test] fn better_valid_solution_replaces() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); // a weak one, which we will still accept. @@ -728,7 +727,7 @@ mod async_verification { #[test] fn invalid_solution_bad_score() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let mut paged = mine_full_solution().unwrap(); @@ -757,7 +756,7 @@ mod async_verification { #[test] fn invalid_solution_bad_minimum_score() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -785,7 +784,7 @@ mod async_verification { #[test] fn invalid_solution_bad_desired_targets() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); assert_eq!(crate::Snapshot::::desired_targets().unwrap(), 2); let paged = mine_full_solution().unwrap(); @@ -816,7 +815,7 @@ mod async_verification { #[test] fn invalid_solution_bad_bounds_per_page() { - ExtBuilder::verifier() + ExtBuilder::mock_signed() .desired_targets(1) .max_backers_per_winner(1) // in each page we allow 1 baker to be presented. .build_and_execute(|| { @@ -865,7 +864,7 @@ mod async_verification { #[test] fn invalid_solution_bad_bounds_final() { - ExtBuilder::verifier() + ExtBuilder::mock_signed() .desired_targets(1) .max_backers_per_winner(2) .max_backers_per_winner_final(2) @@ -923,7 +922,7 @@ mod async_verification { #[test] fn invalid_solution_does_not_alter_queue() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let mut paged = mine_full_solution().unwrap(); let correct_score = paged.score; @@ -979,7 +978,7 @@ mod multi_page_sync_verification { #[test] fn basic_sync_verification_works() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let paged = mine_solution(2).unwrap(); @@ -1007,7 +1006,7 @@ mod multi_page_sync_verification { #[test] fn basic_sync_verification_works_full() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let paged = mine_full_solution().unwrap(); @@ -1036,7 +1035,7 @@ mod multi_page_sync_verification { #[test] fn incorrect_score_checked_at_end() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { // A solution that where each individual page is valid, but the final score is bad. roll_to_snapshot_created(); let mut paged = mine_solution(2).unwrap(); @@ -1069,7 +1068,7 @@ mod multi_page_sync_verification { #[test] fn invalid_second_page() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { // A solution that where the second validated page is invalid. use frame_election_provider_support::traits::NposSolution; roll_to_snapshot_created(); @@ -1107,7 +1106,7 @@ mod multi_page_sync_verification { #[test] fn too_may_max_backers_per_winner_second_page() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { // A solution that where the at the second page with hit the final max backers per // winner final bound. roll_to_snapshot_created(); @@ -1183,7 +1182,7 @@ mod single_page_sync_verification { #[test] fn basic_sync_verification_works() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1210,7 +1209,7 @@ mod single_page_sync_verification { #[test] fn winner_count_more() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1242,7 +1241,7 @@ mod single_page_sync_verification { #[test] fn winner_count_less() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1275,7 +1274,7 @@ mod single_page_sync_verification { #[test] fn incorrect_score_is_rejected() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1304,7 +1303,7 @@ mod single_page_sync_verification { #[test] fn minimum_untrusted_score_is_rejected() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1334,7 +1333,7 @@ mod single_page_sync_verification { #[test] fn bad_bounds_rejected_max_backers_per_winner() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1363,7 +1362,7 @@ mod single_page_sync_verification { #[test] fn bad_bounds_rejected_max_winners_per_page() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1392,7 +1391,7 @@ mod single_page_sync_verification { #[test] fn bad_bounds_rejected_max_backers_per_winner_final() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let single_page = mine_solution(1).unwrap(); @@ -1421,7 +1420,7 @@ mod single_page_sync_verification { #[test] fn solution_improvement_threshold_respected() { - ExtBuilder::verifier() + ExtBuilder::mock_signed() .solution_improvement_threshold(Perbill::from_percent(10)) .build_and_execute(|| { roll_to_snapshot_created(); @@ -1456,7 +1455,7 @@ mod single_page_sync_verification { #[test] fn weak_score_is_insta_rejected() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); // queue something useful. @@ -1498,7 +1497,7 @@ mod single_page_sync_verification { #[test] fn good_solution_replaces() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); let weak_solution = solution_from_supports( @@ -1549,7 +1548,7 @@ mod single_page_sync_verification { #[test] fn weak_valid_is_discarded() { - ExtBuilder::verifier().build_and_execute(|| { + ExtBuilder::mock_signed().build_and_execute(|| { roll_to_snapshot_created(); // first, submit something good From 1e4bfc254554c538933990282b5e78830921df46 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 1 Oct 2025 14:40:18 +0100 Subject: [PATCH 06/20] staking uses poll now as well --- .../election-provider-multi-block/src/lib.rs | 28 +++--- .../src/mock/mod.rs | 9 +- .../election-provider-multi-phase/src/lib.rs | 6 +- .../election-provider-multi-phase/src/mock.rs | 4 +- .../election-provider-support/src/lib.rs | 16 ++-- .../election-provider-support/src/onchain.rs | 4 +- .../runtimes/parachain/bench_all.sh | 2 +- substrate/frame/staking-async/src/mock.rs | 21 +++-- .../frame/staking-async/src/pallet/mod.rs | 34 ++++++-- .../staking-async/src/session_rotation.rs | 86 +++++++++++-------- 10 files changed, 128 insertions(+), 82 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index a94850cb3a11f..2264f491f6d53 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -256,8 +256,8 @@ impl ElectionProvider for InitiateEmergencyPhase { Err("Emergency phase started.") } - fn status() -> Result { - Ok(true) + fn status() -> Result, ()> { + Ok(Some(Default::default())) } fn start() -> Result<(), Self::Error> { @@ -309,8 +309,8 @@ impl ElectionProvider for Continue { Zero::zero() } - fn status() -> Result { - Ok(true) + fn status() -> Result, ()> { + Ok(Some(Default::default())) } } @@ -683,6 +683,7 @@ pub mod pallet { ); // TODO: we are not registering export weight anywhere. + // TODO: basic tests for all weight registeration. log!( debug, "required weight for transition from {:?} to {:?} is {:?}", @@ -1599,10 +1600,7 @@ where /// Roll to next block. pub(crate) fn roll_next(try_state: bool) { - Self::roll_to( - frame_system::Pallet::::block_number() + 1u32.into(), - try_state, - ); + Self::roll_to(frame_system::Pallet::::block_number() + 1u32.into(), try_state); } } @@ -1680,7 +1678,7 @@ impl ElectionProvider for Pallet { Self::average_election_duration().into() } - fn status() -> Result { + fn status() -> Result, ()> { match >::get() { // we're not doing anything. Phase::Off => Err(()), @@ -1690,10 +1688,16 @@ impl ElectionProvider for Pallet { Phase::SignedValidation(_) | Phase::Unsigned(_) | Phase::Snapshot(_) | - Phase::Emergency => Ok(false), + Phase::Emergency => Ok(None), // we're ready - Phase::Done | Phase::Export(_) => Ok(true), + Phase::Done => Ok(Some(T::WeightInfo::export_non_terminal())), + Phase::Export(p) => + if p.is_zero() { + Ok(Some(T::WeightInfo::export_terminal())) + } else { + Ok(Some(T::WeightInfo::export_non_terminal())) + }, } } @@ -2836,7 +2840,7 @@ mod election_provider { fn elect_call_when_not_ongoing() { ExtBuilder::full().fallback_mode(FallbackModes::Onchain).build_and_execute(|| { roll_to_snapshot_created(); - assert_eq!(MultiBlock::status(), Ok(false)); + assert_eq!(MultiBlock::status(), Ok(None)); assert!(MultiBlock::elect(0).is_ok()); }); ExtBuilder::full().fallback_mode(FallbackModes::Onchain).build_and_execute(|| { diff --git a/substrate/frame/election-provider-multi-block/src/mock/mod.rs b/substrate/frame/election-provider-multi-block/src/mock/mod.rs index 8abcde197f40f..725587f2a0ae6 100644 --- a/substrate/frame/election-provider-multi-block/src/mock/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/mock/mod.rs @@ -271,8 +271,8 @@ impl ElectionProvider for MockFallback { Ok(()) } - fn status() -> Result { - Ok(true) + fn status() -> Result, ()> { + Ok(Some(Default::default())) } } @@ -645,10 +645,7 @@ pub fn verifier_events_since_last_call() -> Vec> /// proceed block number to `n`. pub fn roll_to(n: BlockNumber) { - crate::Pallet::::roll_to( - n, - true, - ); + crate::Pallet::::roll_to(n, true); } /// proceed block number to whenever the snapshot is fully created (`Phase::Snapshot(0)`). diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs index c47b49b59b4a8..d8ed7f82e5bb5 100644 --- a/substrate/frame/election-provider-multi-phase/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/src/lib.rs @@ -1841,13 +1841,13 @@ impl ElectionProvider for Pallet { Ok(()) } - fn status() -> Result { + fn status() -> Result, ()> { let has_queued = QueuedSolution::::exists(); let phase = CurrentPhase::::get(); match (phase, has_queued) { - (Phase::Unsigned(_), true) => Ok(true), + (Phase::Unsigned(_), true) => Ok(Some(Default::default())), (Phase::Off, _) => Err(()), - _ => Ok(false), + _ => Ok(None), } } diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index 78c631f67db40..27e84c55e0090 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -340,8 +340,8 @@ impl ElectionProvider for MockFallback { Ok(()) } - fn status() -> Result { - Ok(true) + fn status() -> Result, ()> { + Ok(Some(Default::default()) } } diff --git a/substrate/frame/election-provider-support/src/lib.rs b/substrate/frame/election-provider-support/src/lib.rs index 83ee955468905..c77898979763d 100644 --- a/substrate/frame/election-provider-support/src/lib.rs +++ b/substrate/frame/election-provider-support/src/lib.rs @@ -133,6 +133,7 @@ //! mod generic_election_provider { //! use super::*; //! use sp_runtime::traits::Zero; +//! use frame_support::pallet_prelude::Weight; //! //! pub struct GenericElectionProvider(std::marker::PhantomData); //! @@ -161,7 +162,7 @@ //! unimplemented!() //! } //! -//! fn status() -> Result { +//! fn status() -> Result, ()> { //! unimplemented!() //! } //! } @@ -523,10 +524,13 @@ pub trait ElectionProvider { /// Indicate whether this election provider is currently ongoing an asynchronous election. /// - /// `Err(())` should signal that we are not doing anything, and `elect` should def. not be - /// called. `Ok(false)` means we are doing something, but work is still ongoing. `elect` should - /// not be called. `Ok(true)` means we are done and ready for a call to `elect`. - fn status() -> Result; + /// * `Err(())` should signal that we are not doing anything, and `elect` should def. not be + /// called. + /// * `Ok(None)` means we are doing something, but we are not done. `elect` should + /// not be called. + /// * `Ok(Some(Weight))` means we are done and ready for a call to `elect`, which should consume + /// at most the given weight when called. + fn status() -> Result, ()>; /// Signal the election provider that we are about to call `elect` asap, and it should prepare /// itself. @@ -585,7 +589,7 @@ where Zero::zero() } - fn status() -> Result { + fn status() -> Result, ()> { Err(()) } } diff --git a/substrate/frame/election-provider-support/src/onchain.rs b/substrate/frame/election-provider-support/src/onchain.rs index eb4911c7e24e3..f6fc29fe6b191 100644 --- a/substrate/frame/election-provider-support/src/onchain.rs +++ b/substrate/frame/election-provider-support/src/onchain.rs @@ -206,8 +206,8 @@ impl ElectionProvider for OnChainExecution { sp_runtime::traits::Zero::zero() } - fn status() -> Result { - Ok(true) + fn status() -> Result, ()> { + Ok(Some(Default::default())) } } diff --git a/substrate/frame/staking-async/runtimes/parachain/bench_all.sh b/substrate/frame/staking-async/runtimes/parachain/bench_all.sh index f3b7efb7018ab..affd38195690e 100755 --- a/substrate/frame/staking-async/runtimes/parachain/bench_all.sh +++ b/substrate/frame/staking-async/runtimes/parachain/bench_all.sh @@ -5,7 +5,7 @@ STEPS=2 REPEAT=2 # if any of the command line arguments are equal to `--log=X`, set X to the below log levels -LOG="runtime::multiblock-election=info,runtime::staking-async=info,polkadot_sdk_frame::benchmark=info" +LOG="runtime::multiblock-election=info,runtime::staking-async=info,frame::benchmark=info" if [[ "${NO_COMPILE}" == "1" ]]; then echo "Skipping compilation because 'NO_COMPILE' was set" diff --git a/substrate/frame/staking-async/src/mock.rs b/substrate/frame/staking-async/src/mock.rs index 2b9809426bfe3..68313f2fb572e 100644 --- a/substrate/frame/staking-async/src/mock.rs +++ b/substrate/frame/staking-async/src/mock.rs @@ -37,7 +37,7 @@ use pallet_staking_async_rc_client as rc_client; use sp_core::{ConstBool, ConstU64}; use sp_io; use sp_npos_elections::BalancingConfig; -use sp_runtime::{traits::Zero, BuildStorage}; +use sp_runtime::{traits::Zero, BuildStorage, Weight}; use sp_staking::{ currency_to_vote::SaturatingCurrencyToVote, OnStakingUpdate, SessionIndex, StakingAccount, }; @@ -194,11 +194,11 @@ impl ElectionProvider for TestElectionProvider { fn duration() -> Self::BlockNumber { InnerElection::duration() + ElectionDelay::get() } - fn status() -> Result { + fn status() -> Result, ()> { let now = System::block_number(); match StartReceived::get() { - Some(at) if now - at >= ElectionDelay::get() => Ok(true), - Some(_) => Ok(false), + Some(at) if now - at >= ElectionDelay::get() => Ok(Some(Default::default())), + Some(_) => Ok(None), None => Err(()), } } @@ -243,6 +243,10 @@ impl Contains for MockedRestrictList { /// A representation of the session pallet that lives on the relay chain. pub mod session_mock { use super::*; + use frame_support::{ + traits::{OnInitialize, OnPoll}, + weights::WeightMeter, + }; use pallet_staking_async_rc_client::ValidatorSetReport; pub struct Session; @@ -269,7 +273,14 @@ pub mod session_mock { pub fn roll_next() { let now = System::block_number(); Timestamp::mutate(|ts| *ts += BLOCK_TIME); - System::run_to_block::(now + 1); + + System::set_block_number(now + 1); + >::on_initialize(now + 1); + >::on_poll( + now + 1, + &mut WeightMeter::new(), + ); + // System::run_to_block::(now + 1); Self::maybe_rotate_session_now(); } diff --git a/substrate/frame/staking-async/src/pallet/mod.rs b/substrate/frame/staking-async/src/pallet/mod.rs index 11174e7f26ade..be374392bad19 100644 --- a/substrate/frame/staking-async/src/pallet/mod.rs +++ b/substrate/frame/staking-async/src/pallet/mod.rs @@ -18,10 +18,11 @@ //! `pallet-staking-async`'s main `pallet` module. use crate::{ - asset, slashing, weights::WeightInfo, AccountIdLookupOf, ActiveEraInfo, BalanceOf, EraPayout, - EraRewardPoints, ExposurePage, Forcing, LedgerIntegrityState, MaxNominationsOf, - NegativeImbalanceOf, Nominations, NominationsQuota, PositiveImbalanceOf, RewardDestination, - StakingLedger, UnappliedSlash, UnlockChunk, ValidatorPrefs, + asset, session_rotation::EraElectionPlanner, slashing, weights::WeightInfo, AccountIdLookupOf, + ActiveEraInfo, BalanceOf, EraPayout, EraRewardPoints, ExposurePage, Forcing, + LedgerIntegrityState, MaxNominationsOf, NegativeImbalanceOf, Nominations, NominationsQuota, + PositiveImbalanceOf, RewardDestination, StakingLedger, UnappliedSlash, UnlockChunk, + ValidatorPrefs, }; use alloc::{format, vec::Vec}; use codec::Codec; @@ -68,7 +69,7 @@ pub mod pallet { use crate::{session_rotation, PagedExposureMetadata, SnapshotStatus}; use codec::HasCompact; use frame_election_provider_support::{ElectionDataProvider, PageIndex}; - use frame_support::DefaultNoBound; + use frame_support::{weights::WeightMeter, DefaultNoBound}; /// Represents the current step in the era pruning process #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -1226,6 +1227,8 @@ pub mod pallet { EraDurationBoundExceeded, /// Received a validator activation event that is not recognized. UnknownValidatorActivation, + /// Failed to proceed paged election due to weight limits + PagedElectionOutOfWeight { page: PageIndex, required: Weight, had: Weight }, } #[pallet::error] @@ -1427,6 +1430,24 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { + fn on_poll(_now: BlockNumberFor, weight_meter: &mut WeightMeter) { + let (weight, exec) = + EraElectionPlanner::::per_block_exec_maybe_fetch_election_results(); + if weight_meter.try_consume(weight).is_ok() { + let _adjusted_weight = exec(); + } else { + Self::deposit_event(Event::::Unexpected( + UnexpectedKind::PagedElectionOutOfWeight { + page: NextElectionPage::::get().unwrap_or( + EraElectionPlanner::::election_pages().defensive_saturating_sub(1), + ), + required: weight, + had: weight_meter.remaining(), + }, + )); + } + } + fn on_initialize(_now: BlockNumberFor) -> Weight { // process our queue. let mut consumed_weight = slashing::process_offence::(); @@ -1438,9 +1459,6 @@ pub mod pallet { consumed_weight.saturating_accrue(slash_weight); } - // maybe plan eras and stuff. Note that this is benchmark as a part of the - // election-provider's benchmarks. - session_rotation::EraElectionPlanner::::maybe_fetch_election_results(); consumed_weight } diff --git a/substrate/frame/staking-async/src/session_rotation.rs b/substrate/frame/staking-async/src/session_rotation.rs index ac6edd9d6cf6b..f840f4db367df 100644 --- a/substrate/frame/staking-async/src/session_rotation.rs +++ b/substrate/frame/staking-async/src/session_rotation.rs @@ -83,6 +83,7 @@ use frame_support::{ pallet_prelude::*, traits::{Defensive, DefensiveMax, DefensiveSaturating, OnUnbalanced, TryCollect}, }; +use pallet_staking_async_rc_client::RcClientInterface; use sp_runtime::{Perbill, Percent, Saturating}; use sp_staking::{ currency_to_vote::CurrencyToVote, Exposure, Page, PagedExposureMetadata, SessionIndex, @@ -859,47 +860,58 @@ impl EraElectionPlanner { .inspect_err(|e| log!(warn, "Election provider failed to start: {:?}", e)) } - /// Hook to be used in the pallet's on-initialize. - pub(crate) fn maybe_fetch_election_results() { - if let Ok(true) = T::ElectionProvider::status() { - crate::log!( - debug, - "Election provider is ready, our status is {:?}", - NextElectionPage::::get() - ); - - debug_assert!( - CurrentEra::::get().unwrap_or(0) == - ActiveEra::::get().map_or(0, |a| a.index) + 1, - "Next era must be already planned." - ); - - let current_page = NextElectionPage::::get() - .unwrap_or(Self::election_pages().defensive_saturating_sub(1)); - let maybe_next_page = current_page.checked_sub(1); - crate::log!(debug, "fetching page {:?}, next {:?}", current_page, maybe_next_page); + pub(crate) fn per_block_exec_maybe_fetch_election_results( + ) -> (Weight, Box Option>) { + if let Ok(Some(required_weight)) = T::ElectionProvider::status() { + ( + required_weight, + Box::new(|| { + crate::log!( + debug, + "Election provider is ready, our status is {:?}", + NextElectionPage::::get() + ); - Self::do_elect_paged(current_page); - NextElectionPage::::set(maybe_next_page); + debug_assert!( + CurrentEra::::get().unwrap_or(0) == + ActiveEra::::get().map_or(0, |a| a.index) + 1, + "Next era must be already planned." + ); - // if current page was `Some`, and next is `None`, we have finished an election and - // we can report it now. - if maybe_next_page.is_none() { - use pallet_staking_async_rc_client::RcClientInterface; - let id = CurrentEra::::get().defensive_unwrap_or(0); - let prune_up_to = Self::get_prune_up_to(); - let rc_validators = ElectableStashes::::take().into_iter().collect::>(); + let current_page = NextElectionPage::::get() + .unwrap_or(Self::election_pages().defensive_saturating_sub(1)); + let maybe_next_page = current_page.checked_sub(1); + crate::log!( + debug, + "fetching page {:?}, next {:?}", + current_page, + maybe_next_page + ); - crate::log!( - info, - "Sending new validator set of size {:?} to RC. ID: {:?}, prune_up_to: {:?}", - rc_validators.len(), - id, - prune_up_to - ); + Self::do_elect_paged(current_page); + NextElectionPage::::set(maybe_next_page); + + if maybe_next_page.is_none() { + let id = CurrentEra::::get().defensive_unwrap_or(0); + let prune_up_to = Self::get_prune_up_to(); + let rc_validators = + ElectableStashes::::take().into_iter().collect::>(); + + crate::log!( + info, + "Sending new validator set of size {:?} to RC. ID: {:?}, prune_up_to: {:?}", + rc_validators.len(), + id, + prune_up_to + ); + T::RcClientInterface::validator_set(rc_validators, id, prune_up_to); + } - T::RcClientInterface::validator_set(rc_validators, id, prune_up_to); - } + None + }), + ) + } else { + (Default::default(), Box::new(|| None)) } } From 624e627ec636ac85530f99f4b662d273c2a30708 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 3 Oct 2025 09:45:45 +0100 Subject: [PATCH 07/20] tidy up --- .../parachains/runtimes/assets/asset-hub-westend/src/staking.rs | 1 + substrate/frame/staking-async/src/session_rotation.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs index 1674e02f1c1cb..01f32f47ccd5a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs @@ -133,6 +133,7 @@ impl multi_block::Config for Runtime { // Revert back to signed phase if nothing is submitted and queued, so we prolong the election. type AreWeDone = multi_block::RevertToSignedIfNotQueuedOf; type OnRoundRotation = multi_block::CleanRound; + type Signed = Self; type WeightInfo = multi_block::weights::westend::MultiBlockWeightInfo; } diff --git a/substrate/frame/staking-async/src/session_rotation.rs b/substrate/frame/staking-async/src/session_rotation.rs index f840f4db367df..642acbd014725 100644 --- a/substrate/frame/staking-async/src/session_rotation.rs +++ b/substrate/frame/staking-async/src/session_rotation.rs @@ -88,6 +88,7 @@ use sp_runtime::{Perbill, Percent, Saturating}; use sp_staking::{ currency_to_vote::CurrencyToVote, Exposure, Page, PagedExposureMetadata, SessionIndex, }; +use alloc::boxed::Box; /// A handler for all era-based storage items. /// From c05bf0dfd3a7fd6fefe0d2b284233cf470e152af Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 3 Oct 2025 12:51:02 +0100 Subject: [PATCH 08/20] solid round of self-review --- .../assets/asset-hub-westend/src/staking.rs | 2 +- .../election-provider-multi-block/src/lib.rs | 52 ++++-- .../src/mock/mod.rs | 2 +- .../src/mock/signed.rs | 1 - .../src/signed/mod.rs | 7 +- .../src/signed/tests.rs | 1 + .../src/types.rs | 11 +- .../src/verifier/benchmarking.rs | 8 +- .../src/verifier/impls.rs | 169 +++++++++--------- .../src/verifier/mod.rs | 5 +- .../src/weights/mod.rs | 16 +- ..._provider_multi_block_verifier_dot_size.rs | 8 +- ..._provider_multi_block_verifier_ksm_size.rs | 8 +- .../staking-async/ahm-test/src/ah/mock.rs | 2 +- .../runtimes/parachain/src/staking.rs | 2 +- .../frame/staking-async/src/pallet/mod.rs | 8 +- .../staking-async/src/session_rotation.rs | 91 +++++----- 17 files changed, 203 insertions(+), 190 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs index 01f32f47ccd5a..ab8279e6576f0 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs @@ -133,7 +133,7 @@ impl multi_block::Config for Runtime { // Revert back to signed phase if nothing is submitted and queued, so we prolong the election. type AreWeDone = multi_block::RevertToSignedIfNotQueuedOf; type OnRoundRotation = multi_block::CleanRound; - type Signed = Self; + type Signed = MultiBlockElectionSigned; type WeightInfo = multi_block::weights::westend::MultiBlockWeightInfo; } diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index 57ff7363187da..f68f68336ab35 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -55,10 +55,13 @@ //! the shared information that all child pallets use. All child pallets depend on the top level //! pallet ONLY, but not the other way around. For those cases, traits are used. //! -//! As in, notice that [`crate::verifier::Config`] relies on [`crate::Config`], but for the -//! reverse, we rely on [`crate::verifier::Verifier`] trait, which is indeed part of -//! [`crate::Config`]. This is merely an implementation opinion. +//! For reverse linking, or child-linking, only explicit traits with clear interfaces are used. For +//! example, the following traits facilitate other communication: //! +//! * [`crate::types::SignedInterface`]: Parent talking to signed. +//! * [`crate::verifier::Verifier`]: Parent talking to verifier. +//! * [`crate::verifier::SolutionDataProvider`]: Verifier talking to signed. + //! //! ## Pagination //! @@ -80,7 +83,7 @@ //! //! ## Phases //! -//! The operations in this pallet are divided intor rounds, a `u32` number stored in [`Round`]. +//! The operations in this pallet are divided into rounds, a `u32` number stored in [`Round`]. //! This value helps this pallet organize itself, and leaves the door open for lazy deletion of any //! stale data. A round, under the happy path, starts by receiving the call to //! [`ElectionProvider::start`], and is terminated by receiving a call to @@ -113,6 +116,20 @@ //! > Given this, it is rather important for the user of this pallet to ensure it always terminates //! > election via `elect` before requesting a new one. //! +//! ### Phase Transition +//! +//! Within all 4 pallets only the parent pallet is allowed to move forward the phases. As of now, +//! the transition happens `on-poll`, ensuring that we don't consume too much weight. The parent +//! pallet is in charge of aggregating the work to be done by all pallets, checking if it can fit +//! within the current block's weight limits, and executing it if so. +//! +//! Occasional phase transition stalling is not a critical issue. Every instance of phase transition +//! failing is accompanied by a [`Event::UnexpectedPhaseTransitionOutOfWeight`] for visibility. +//! +//! Note this pallet transitions phases all the way into [`crate::types::Phase::Done`]. At this +//! point, we will move to `Export` phase an onwards by calls into `elect`. A call to `elect(0)` +//! rotates the round, as stated above. +//! //! ## Feasible Solution (correct solution) //! //! All submissions must undergo a feasibility check. Signed solutions are checked one by one at the @@ -572,7 +589,7 @@ pub mod pallet { > + verifier::AsynchronousVerifier; /// Interface signed pallet's interface. - type Signed: crate::signed::Config; + type Signed: SignedInterface; /// The origin that can perform administration operations on this pallet. type AdminOrigin: EnsureOrigin; @@ -652,11 +669,11 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_poll(_now: BlockNumberFor, weight_meter: &mut WeightMeter) { - // we need current phase to be read in any case -- we can live wiht it. + // we need current phase to be read in any case -- we can live with it. let current_phase = Self::current_phase(); let next_phase = current_phase.next(); - let (meta_weight, meta_exec) = Self::per_block_exec(current_phase.clone()); + let (self_weight, self_exec) = Self::per_block_exec(current_phase.clone()); let (verifier_weight, verifier_exc) = T::Verifier::per_block_exec(); // The following will combine `Self::per_block_exec` and `T::Verifier::per_block_exec` @@ -664,19 +681,19 @@ pub mod pallet { // function if we have this pattern in more places. let (combined_weight, combined_exec) = ( // pre-exec weight is simply addition. - meta_weight.saturating_add(verifier_weight), + self_weight.saturating_add(verifier_weight), // our new exec is.. Box::new(move || { // execute both this.. - let corrected_meta_weight = meta_exec(); + let corrected_self_weight = self_exec(); // .. and that. let corrected_verifier_weight = verifier_exc(); // for each, if they have returned an updated weight, use that, else the // pre-exec weight, and re-sum them up. - let final_weight = corrected_meta_weight - .unwrap_or(meta_weight) + let final_weight = corrected_self_weight + .unwrap_or(self_weight) .saturating_add(corrected_verifier_weight.unwrap_or(verifier_weight)); - if final_weight != meta_weight.saturating_add(verifier_weight) { + if final_weight != self_weight.saturating_add(verifier_weight) { Some(final_weight) } else { None @@ -695,6 +712,8 @@ pub mod pallet { ); if weight_meter.can_consume(combined_weight) { let final_combined_weight = combined_exec(); + // Note: we _always_ transition into the next phase, but note that `.next` in + // `Export` is a noop, so we don't transition. Self::phase_transition(next_phase); weight_meter.consume(final_combined_weight.unwrap_or(combined_weight)) } else { @@ -1088,9 +1107,8 @@ pub mod pallet { Phase::Off => Self::ensure_snapshot(false, T::Pages::get()), // we will star the snapshot in the next phase. - // TODO: - // Phase::Snapshot(p) if p == T::Pages::get() => - // Self::ensure_snapshot(false, T::Pages::get()), + Phase::Snapshot(p) if p == T::Pages::get() => + Self::ensure_snapshot(false, T::Pages::get()), // we are mid voter snapshot. Phase::Snapshot(p) if p < T::Pages::get() && p > 0 => Self::ensure_snapshot(true, T::Pages::get() - p - 1), @@ -1271,9 +1289,7 @@ impl Pallet { Phase::Signed(x) => { // Signed pallet should prep the best winner, and send the start signal, if some // exists. - if x.is_zero() && - crate::signed::Submissions::::leader(Self::round()).is_some() - { + if x.is_zero() && T::Signed::has_leader(Self::round()) { let exec: ExecuteFn = Box::new(|| { // defensive: signed phase has just began, verifier should be in a // clear state and ready to accept a solution. Moreover, if we have diff --git a/substrate/frame/election-provider-multi-block/src/mock/mod.rs b/substrate/frame/election-provider-multi-block/src/mock/mod.rs index 725587f2a0ae6..8cc73df45f929 100644 --- a/substrate/frame/election-provider-multi-block/src/mock/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/mock/mod.rs @@ -229,7 +229,7 @@ impl crate::Config for Runtime { type AdminOrigin = EnsureRoot; type Pages = Pages; type AreWeDone = AreWeDone; - type Signed = Runtime; + type Signed = SignedPallet; type OnRoundRotation = CleanRound; } diff --git a/substrate/frame/election-provider-multi-block/src/mock/signed.rs b/substrate/frame/election-provider-multi-block/src/mock/signed.rs index 3cb6f73c8b88b..75f4c2368e599 100644 --- a/substrate/frame/election-provider-multi-block/src/mock/signed.rs +++ b/substrate/frame/election-provider-multi-block/src/mock/signed.rs @@ -71,7 +71,6 @@ parameter_types! { pub static InvulnerableDeposit: Balance = 7; pub static SignedMaxSubmissions: u32 = 3; pub static SignedRewardBase: Balance = 3; - // TODO: fully remove; now all pallets get on-init-ed at the master pallet. pub static SignedPhaseSwitch: SignedSwitch = SignedSwitch::Real; pub static BailoutGraceRatio: Perbill = Perbill::from_percent(20); pub static EjectGraceRatio: Perbill = Perbill::from_percent(20); diff --git a/substrate/frame/election-provider-multi-block/src/signed/mod.rs b/substrate/frame/election-provider-multi-block/src/signed/mod.rs index 8c255f866fa93..a878d3d87d03e 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/mod.rs @@ -111,6 +111,12 @@ pub struct SubmissionMetadata { pages: BoundedVec, } +impl crate::types::SignedInterface for Pallet { + fn has_leader(round: u32) -> bool { + Submissions::::has_leader(round) + } +} + impl SolutionDataProvider for Pallet { type Solution = SolutionOf; @@ -1019,7 +1025,6 @@ impl Pallet { { // Only start verification if there are sufficient blocks remaining // Note: SignedValidation(N) means N+1 blocks remaining in the phase - // TODO: check test cases for the edge cases of this. if remaining_blocks >= T::Pages::get().into() { if Submissions::::has_leader(current_round) { // defensive: verifier just reported back a result, it must be in clear diff --git a/substrate/frame/election-provider-multi-block/src/signed/tests.rs b/substrate/frame/election-provider-multi-block/src/signed/tests.rs index 756b085ebac7c..6a2cf47130592 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/tests.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/tests.rs @@ -1215,6 +1215,7 @@ mod e2e { ] ); + // we are done _exactly on time_. assert_eq!(crate::Pallet::::current_phase(), Phase::SignedValidation(0)); assert_eq!(VerifierPallet::status(), crate::verifier::Status::Nothing); diff --git a/substrate/frame/election-provider-multi-block/src/types.rs b/substrate/frame/election-provider-multi-block/src/types.rs index 17d7dba747893..c0aea0ca2c3d7 100644 --- a/substrate/frame/election-provider-multi-block/src/types.rs +++ b/substrate/frame/election-provider-multi-block/src/types.rs @@ -271,8 +271,8 @@ pub enum Phase { /// The inner value should be read as "`remaining` number of pages are left to be fetched". /// Thus, if inner value is `0` if the snapshot is complete and we are ready to move on. /// - /// This value should be interpreted after `on_initialize` of this pallet has already been - /// called. + /// This value should be interpreted after `on_initialize`/`on_poll` of this pallet has already + /// been called. Snapshot(PageIndex), /// Snapshot is done, and we are waiting for `Export` to kick in. Done, @@ -418,6 +418,12 @@ impl Phase { } } +/// Slim interface for the parent pallet to be able to inspect the state of the signed pallet. +pub trait SignedInterface { + /// Returns `true` if there is a candidate solution to be verified. + fn has_leader(round: u32) -> bool; +} + #[cfg(test)] mod pagify { use super::{PadSolutionPages, Pagify}; @@ -446,3 +452,4 @@ mod pagify { assert_eq!(solution.pad_solution_pages(3), vec![0, 2, 3]); } } + diff --git a/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs b/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs index 24a8a25eaff49..6cc5deb8f3eea 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/benchmarking.rs @@ -39,7 +39,7 @@ mod benchmarks { } #[benchmark(pov_mode = Measured)] - fn on_initialize_valid_non_terminal() -> Result<(), BenchmarkError> { + fn verification_valid_non_terminal() -> Result<(), BenchmarkError> { #[cfg(test)] crate::mock::ElectionStart::set(sp_runtime::traits::Bounded::max_value()); crate::Pallet::::start().unwrap(); @@ -65,7 +65,7 @@ mod benchmarks { } #[benchmark(pov_mode = Measured)] - fn on_initialize_valid_terminal() -> Result<(), BenchmarkError> { + fn verification_valid_terminal() -> Result<(), BenchmarkError> { #[cfg(test)] crate::mock::ElectionStart::set(sp_runtime::traits::Bounded::max_value()); crate::Pallet::::start().unwrap(); @@ -112,7 +112,7 @@ mod benchmarks { } #[benchmark(pov_mode = Measured)] - fn on_initialize_invalid_terminal() -> Result<(), BenchmarkError> { + fn verification_invalid_terminal() -> Result<(), BenchmarkError> { // this is the verification of the current page + removing all of the previously valid // pages. The worst case is therefore when the last page is invalid, for example the final // score. @@ -171,7 +171,7 @@ mod benchmarks { } #[benchmark(pov_mode = Measured)] - fn on_initialize_invalid_non_terminal( + fn verification_invalid_non_terminal( // number of valid pages that have been verified, before we verify the non-terminal invalid // page. v: Linear<0, { T::Pages::get() - 1 }>, diff --git a/substrate/frame/election-provider-multi-block/src/verifier/impls.rs b/substrate/frame/election-provider-multi-block/src/verifier/impls.rs index a02d813075882..0f66640116480 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/impls.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/impls.rs @@ -33,7 +33,7 @@ use frame_election_provider_support::{ use frame_support::{ ensure, pallet_prelude::{ValueQuery, *}, - traits::{defensive_prelude::*, Get}, + traits::{defensive_prelude::*, DefensiveSaturating, Get}, }; use frame_system::pallet_prelude::*; use pallet::*; @@ -620,98 +620,89 @@ pub(crate) mod pallet { } impl Pallet { - fn do_on_init_execute_fn() -> (Weight, Box Option>) { - if let Status::Ongoing(current_page) = Self::status_storage() { - let worst_case_weight = VerifierWeightsOf::::on_initialize_valid_non_terminal() - .max(VerifierWeightsOf::::on_initialize_valid_terminal()) - .max(VerifierWeightsOf::::on_initialize_invalid_non_terminal(T::Pages::get())) - .max(VerifierWeightsOf::::on_initialize_invalid_terminal()); - let execute = Box::new(move || { - { - let page_solution = - ::get_page(current_page); - let maybe_supports = - Self::feasibility_check_page_inner(page_solution, current_page); - - sublog!( - debug, - "verifier", - "verified page {} of a solution, outcome = {:?}", - current_page, - maybe_supports.as_ref().map(|s| s.len()) - ); - let actual_weight = match maybe_supports { - Ok(supports) => { - Self::deposit_event(Event::::Verified( - current_page, - supports.len() as u32, - )); - QueuedSolution::::set_invalid_page(current_page, supports); - - if current_page > crate::Pallet::::lsp() { - // not last page, just tick forward. - StatusStorage::::put(Status::Ongoing( - current_page.saturating_sub(1), - )); - VerifierWeightsOf::::on_initialize_valid_non_terminal() - } else { - // last page, finalize everything. Get the claimed score. - let claimed_score = T::SolutionDataProvider::get_score(); - - // in both cases of the following match, we are back to the nothing - // state. - StatusStorage::::put(Status::Nothing); - - match Self::finalize_async_verification(claimed_score) { - Ok(_) => { - T::SolutionDataProvider::report_result( - VerificationResult::Queued, - ); - VerifierWeightsOf::::on_initialize_valid_terminal() - }, - Err(_) => { - T::SolutionDataProvider::report_result( - VerificationResult::Rejected, - ); - // In case of any of the errors, kill the solution. - QueuedSolution::::clear_invalid_and_backings(); - VerifierWeightsOf::::on_initialize_invalid_terminal() - }, - } - } - }, - Err(err) => { - // the page solution was invalid. - Self::deposit_event(Event::::VerificationFailed(current_page, err)); - - sublog!(warn, "verifier", "Clearing any ongoing unverified solution."); - // Clear any ongoing solution that has not been verified, regardless of - // the current state. - QueuedSolution::::clear_invalid_and_backings_unchecked(); - - // we also mutate the status back to doing nothing. - let was_ongoing = - matches!(StatusStorage::::get(), Status::Ongoing(_)); - StatusStorage::::put(Status::Nothing); - - if was_ongoing { + fn do_per_block_exec() -> (Weight, Box Option>) { + let Status::Ongoing(current_page) = Self::status_storage() else { + return (T::DbWeight::get().reads(1), Box::new(|| None)) + }; + + // before executing, we don't know which weight we will consume; return the max. + let worst_case_weight = VerifierWeightsOf::::verification_valid_non_terminal() + .max(VerifierWeightsOf::::verification_valid_terminal()) + .max(VerifierWeightsOf::::verification_invalid_non_terminal(T::Pages::get())) + .max(VerifierWeightsOf::::verification_invalid_terminal()); + + let execute = Box::new(move || { + let page_solution = + ::get_page(current_page); + let maybe_supports = Self::feasibility_check_page_inner(page_solution, current_page); + + sublog!( + debug, + "verifier", + "verified page {} of a solution, outcome = {:?}", + current_page, + maybe_supports.as_ref().map(|s| s.len()) + ); + let actual_weight = match maybe_supports { + Ok(supports) => { + Self::deposit_event(Event::::Verified(current_page, supports.len() as u32)); + QueuedSolution::::set_invalid_page(current_page, supports); + + if current_page > crate::Pallet::::lsp() { + // not last page, just move forward. + StatusStorage::::put(Status::Ongoing( + current_page.defensive_saturating_sub(1), + )); + VerifierWeightsOf::::verification_valid_non_terminal() + } else { + // last page, finalize everything. Get the claimed score. + let claimed_score = T::SolutionDataProvider::get_score(); + + // in both cases of the following match, we are back to the nothing + // state. + StatusStorage::::put(Status::Nothing); + + match Self::finalize_async_verification(claimed_score) { + Ok(_) => { + T::SolutionDataProvider::report_result(VerificationResult::Queued); + VerifierWeightsOf::::verification_valid_terminal() + }, + Err(_) => { T::SolutionDataProvider::report_result( VerificationResult::Rejected, ); - } - let wasted_pages = T::Pages::get().saturating_sub(current_page); - VerifierWeightsOf::::on_initialize_invalid_non_terminal(wasted_pages) - }, - }; + // In case of any of the errors, kill the solution. + QueuedSolution::::clear_invalid_and_backings(); + VerifierWeightsOf::::verification_invalid_terminal() + }, + } + } + }, + Err(err) => { + // the page solution was invalid. + Self::deposit_event(Event::::VerificationFailed(current_page, err)); + + sublog!(warn, "verifier", "Clearing any ongoing unverified solution."); + // Clear any ongoing solution that has not been verified, regardless of + // the current state. + QueuedSolution::::clear_invalid_and_backings_unchecked(); + + // we also mutate the status back to doing nothing. + let was_ongoing = matches!(StatusStorage::::get(), Status::Ongoing(_)); + StatusStorage::::put(Status::Nothing); + + if was_ongoing { + T::SolutionDataProvider::report_result(VerificationResult::Rejected); + } + let wasted_pages = T::Pages::get().saturating_sub(current_page); + VerifierWeightsOf::::verification_invalid_non_terminal(wasted_pages) + }, + }; - Some(actual_weight) - } - }); + Some(actual_weight) + }); - (worst_case_weight, execute) - } else { - (T::DbWeight::get().reads(1), Box::new(|| None)) - } + (worst_case_weight, execute) } fn do_verify_synchronous_multi( @@ -1010,7 +1001,7 @@ impl Verifier for Pallet { } fn per_block_exec() -> (Weight, Box Option>) { - Self::do_on_init_execute_fn() + Self::do_per_block_exec() } } diff --git a/substrate/frame/election-provider-multi-block/src/verifier/mod.rs b/substrate/frame/election-provider-multi-block/src/verifier/mod.rs index fadaf13934816..8d2eeaa92543a 100644 --- a/substrate/frame/election-provider-multi-block/src/verifier/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/verifier/mod.rs @@ -215,7 +215,10 @@ pub trait Verifier { score: ElectionScore, ); - /// What this pallet has to be doing on-init. + /// Return the execution schedule of this pallet's work to be done per-block (`on_poll`, + /// `on_init` independent). + /// + /// Returns a `(Weight, ExecFn)` tuple in-line with `per_block_exec` of the parent block. fn per_block_exec() -> (Weight, Box Option>); } diff --git a/substrate/frame/election-provider-multi-block/src/weights/mod.rs b/substrate/frame/election-provider-multi-block/src/weights/mod.rs index 9d47381759fd7..3647f4e11657c 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/mod.rs @@ -94,23 +94,23 @@ pub mod traits { /// Weight functions needed for `pallet_election_provider_multi_block_verifier`. pub trait WeightInfo { - fn on_initialize_valid_non_terminal() -> Weight; - fn on_initialize_valid_terminal() -> Weight; - fn on_initialize_invalid_terminal() -> Weight; - fn on_initialize_invalid_non_terminal(v: u32) -> Weight; + fn verification_valid_non_terminal() -> Weight; + fn verification_valid_terminal() -> Weight; + fn verification_invalid_terminal() -> Weight; + fn verification_invalid_non_terminal(v: u32) -> Weight; } impl WeightInfo for () { - fn on_initialize_valid_non_terminal() -> Weight { + fn verification_valid_non_terminal() -> Weight { Default::default() } - fn on_initialize_valid_terminal() -> Weight { + fn verification_valid_terminal() -> Weight { Default::default() } - fn on_initialize_invalid_terminal() -> Weight { + fn verification_invalid_terminal() -> Weight { Default::default() } - fn on_initialize_invalid_non_terminal(_v: u32) -> Weight { + fn verification_invalid_non_terminal(_v: u32) -> Weight { Default::default() } } diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs index 36d782c70c47f..4d79816cdd877 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs @@ -93,7 +93,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) - fn on_initialize_valid_non_terminal() -> Weight { + fn verification_valid_non_terminal() -> Weight { // Proof Size summary in bytes: // Measured: `337306` // Estimated: `340771` @@ -138,7 +138,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) - fn on_initialize_valid_terminal() -> Weight { + fn verification_valid_terminal() -> Weight { // Proof Size summary in bytes: // Measured: `1184612` // Estimated: `1267277` @@ -181,7 +181,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - fn on_initialize_invalid_terminal() -> Weight { + fn verification_invalid_terminal() -> Weight { // Proof Size summary in bytes: // Measured: `1185633` // Estimated: `1268298` @@ -225,7 +225,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// The range of component `v` is `[0, 31]`. - fn on_initialize_invalid_non_terminal(v: u32, ) -> Weight { + fn verification_invalid_non_terminal(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `341548 + v * (4932 ±0)` // Estimated: `443308 + v * (4988 ±806)` diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs index 5243dc3d27c2f..4f42bbe341643 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs @@ -93,7 +93,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(37538026), added: 37540501, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) - fn on_initialize_valid_non_terminal() -> Weight { + fn verification_valid_non_terminal() -> Weight { // Proof Size summary in bytes: // Measured: `350585` // Estimated: `354050` @@ -138,7 +138,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(37538026), added: 37540501, mode: `Measured`) - fn on_initialize_valid_terminal() -> Weight { + fn verification_valid_terminal() -> Weight { // Proof Size summary in bytes: // Measured: `1183276` // Estimated: `1226341` @@ -181,7 +181,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(37538026), added: 37540501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - fn on_initialize_invalid_terminal() -> Weight { + fn verification_invalid_terminal() -> Weight { // Proof Size summary in bytes: // Measured: `1183625` // Estimated: `1226690` @@ -225,7 +225,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// The range of component `v` is `[0, 15]`. - fn on_initialize_invalid_non_terminal(v: u32, ) -> Weight { + fn verification_invalid_non_terminal(v: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `384413 + v * (8974 ±0)` // Estimated: `502395 + v * (7186 ±2_803)` diff --git a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs index f4aa721744604..f839bf0cc5bfc 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs @@ -281,7 +281,7 @@ impl multi_block::Config for Runtime { type TargetSnapshotPerBlock = TargetSnapshotPerBlock; type VoterSnapshotPerBlock = VoterSnapshotPerBlock; type Verifier = MultiBlockVerifier; - type Signed = Self; + type Signed = MultiBlockSigned; type AreWeDone = multi_block::ProceedRegardlessOf; type OnRoundRotation = multi_block::CleanRound; type WeightInfo = (); diff --git a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs index f56b9a8ab4301..a5d0b9ed33b2b 100644 --- a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs +++ b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs @@ -294,7 +294,7 @@ impl multi_block::Config for Runtime { #[cfg(feature = "runtime-benchmarks")] type Fallback = frame_election_provider_support::onchain::OnChainExecution; type MinerConfig = Self; - type Signed = Self; + type Signed = MultiBlockElectionSigned; type Verifier = MultiBlockElectionVerifier; type OnRoundRotation = multi_block::CleanRound; type WeightInfo = multi_block::weights::polkadot::MultiBlockWeightInfo; diff --git a/substrate/frame/staking-async/src/pallet/mod.rs b/substrate/frame/staking-async/src/pallet/mod.rs index be374392bad19..d49838d74a696 100644 --- a/substrate/frame/staking-async/src/pallet/mod.rs +++ b/substrate/frame/staking-async/src/pallet/mod.rs @@ -1431,10 +1431,10 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_poll(_now: BlockNumberFor, weight_meter: &mut WeightMeter) { - let (weight, exec) = - EraElectionPlanner::::per_block_exec_maybe_fetch_election_results(); - if weight_meter.try_consume(weight).is_ok() { - let _adjusted_weight = exec(); + let (weight, exec) = EraElectionPlanner::::maybe_fetch_election_results(); + if weight_meter.can_consume(weight) { + let adjusted_weight = exec(); + weight_meter.consume(adjusted_weight.unwrap_or(weight)); } else { Self::deposit_event(Event::::Unexpected( UnexpectedKind::PagedElectionOutOfWeight { diff --git a/substrate/frame/staking-async/src/session_rotation.rs b/substrate/frame/staking-async/src/session_rotation.rs index 642acbd014725..e86da7d7b89a6 100644 --- a/substrate/frame/staking-async/src/session_rotation.rs +++ b/substrate/frame/staking-async/src/session_rotation.rs @@ -77,7 +77,7 @@ //! * end 5, start 6, plan 7 // Session report contains activation timestamp with Current Era. use crate::*; -use alloc::vec::Vec; +use alloc::{boxed::Box, vec::Vec}; use frame_election_provider_support::{BoundedSupportsOf, ElectionProvider, PageIndex}; use frame_support::{ pallet_prelude::*, @@ -88,7 +88,6 @@ use sp_runtime::{Perbill, Percent, Saturating}; use sp_staking::{ currency_to_vote::CurrencyToVote, Exposure, Page, PagedExposureMetadata, SessionIndex, }; -use alloc::boxed::Box; /// A handler for all era-based storage items. /// @@ -861,59 +860,51 @@ impl EraElectionPlanner { .inspect_err(|e| log!(warn, "Election provider failed to start: {:?}", e)) } - pub(crate) fn per_block_exec_maybe_fetch_election_results( + pub(crate) fn maybe_fetch_election_results( ) -> (Weight, Box Option>) { - if let Ok(Some(required_weight)) = T::ElectionProvider::status() { - ( - required_weight, - Box::new(|| { - crate::log!( - debug, - "Election provider is ready, our status is {:?}", - NextElectionPage::::get() - ); + let Ok((Some(required_weight))) = T::ElectionProvider::status() else { + // no election ongoing + return (Default::default(), Box::new(|| None)) + }; + let exec = Box::new(|| { + crate::log!( + debug, + "Election provider is ready, our status is {:?}", + NextElectionPage::::get() + ); - debug_assert!( - CurrentEra::::get().unwrap_or(0) == - ActiveEra::::get().map_or(0, |a| a.index) + 1, - "Next era must be already planned." - ); + debug_assert!( + CurrentEra::::get().unwrap_or(0) == + ActiveEra::::get().map_or(0, |a| a.index) + 1, + "Next era must be already planned." + ); - let current_page = NextElectionPage::::get() - .unwrap_or(Self::election_pages().defensive_saturating_sub(1)); - let maybe_next_page = current_page.checked_sub(1); - crate::log!( - debug, - "fetching page {:?}, next {:?}", - current_page, - maybe_next_page - ); + let current_page = NextElectionPage::::get() + .unwrap_or(Self::election_pages().defensive_saturating_sub(1)); + let maybe_next_page = current_page.checked_sub(1); + crate::log!(debug, "fetching page {:?}, next {:?}", current_page, maybe_next_page); - Self::do_elect_paged(current_page); - NextElectionPage::::set(maybe_next_page); - - if maybe_next_page.is_none() { - let id = CurrentEra::::get().defensive_unwrap_or(0); - let prune_up_to = Self::get_prune_up_to(); - let rc_validators = - ElectableStashes::::take().into_iter().collect::>(); - - crate::log!( - info, - "Sending new validator set of size {:?} to RC. ID: {:?}, prune_up_to: {:?}", - rc_validators.len(), - id, - prune_up_to - ); - T::RcClientInterface::validator_set(rc_validators, id, prune_up_to); - } + Self::do_elect_paged(current_page); + NextElectionPage::::set(maybe_next_page); - None - }), - ) - } else { - (Default::default(), Box::new(|| None)) - } + if maybe_next_page.is_none() { + let id = CurrentEra::::get().defensive_unwrap_or(0); + let prune_up_to = Self::get_prune_up_to(); + let rc_validators = ElectableStashes::::take().into_iter().collect::>(); + + crate::log!( + info, + "Sending new validator set of size {:?} to RC. ID: {:?}, prune_up_to: {:?}", + rc_validators.len(), + id, + prune_up_to + ); + T::RcClientInterface::validator_set(rc_validators, id, prune_up_to); + } + + None + }); + (required_weight, exec) } /// Get the right value of the first session that needs to be pruned on the RC's historical From 10afe31df4c0650d26b2a2ce80cdddd1e0674e42 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 3 Oct 2025 13:25:40 +0100 Subject: [PATCH 09/20] remove some todos --- .../frame/election-provider-multi-block/src/lib.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index f68f68336ab35..e8cacda30a7e7 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -531,8 +531,7 @@ pub mod pallet { /// Duration of the singed validation phase. /// /// The duration of this should not be less than `T::Pages`, and there is no point in it - /// being more than `SignedPhase::MaxSubmission::get() * T::Pages`. TODO: integrity test for - /// it. + /// being more than `SignedPhase::MaxSubmission::get() * T::Pages`. #[pallet::constant] type SignedValidationPhase: Get>; @@ -701,8 +700,6 @@ pub mod pallet { }), ); - // TODO: we are not registering export weight anywhere. - // TODO: basic tests for all weight registeration. log!( trace, "required weight for transition from {:?} to {:?} is {:?}", @@ -1291,11 +1288,8 @@ impl Pallet { // exists. if x.is_zero() && T::Signed::has_leader(Self::round()) { let exec: ExecuteFn = Box::new(|| { - // defensive: signed phase has just began, verifier should be in a - // clear state and ready to accept a solution. Moreover, if we have - // a leader, their score should be present, and pass the - // `ensure_score_quality` (TODO: we actually don't check the minimum - // score in signed.). + // defensive: signed phase has just began, verifier should be in a clear + // state and ready to accept a solution. let _ = T::Verifier::start().defensive(); None }); @@ -1723,7 +1717,7 @@ impl ElectionProvider for Pallet { // we're not doing anything. Phase::Off => Err(()), - // we're doing sth but not read. + // we're doing sth but not ready. Phase::Signed(_) | Phase::SignedValidation(_) | Phase::Unsigned(_) | From 0c4289deedc6d2bdf1421cd05cc259cffcb94330 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 3 Oct 2025 13:25:54 +0100 Subject: [PATCH 10/20] fmt --- substrate/frame/election-provider-multi-block/src/types.rs | 1 - substrate/frame/staking-async/ahm-test/src/ah/mock.rs | 3 ++- substrate/frame/staking-async/src/session_rotation.rs | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/types.rs b/substrate/frame/election-provider-multi-block/src/types.rs index c0aea0ca2c3d7..715980d2083aa 100644 --- a/substrate/frame/election-provider-multi-block/src/types.rs +++ b/substrate/frame/election-provider-multi-block/src/types.rs @@ -452,4 +452,3 @@ mod pagify { assert_eq!(solution.pad_solution_pages(3), vec![0, 2, 3]); } } - diff --git a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs index f839bf0cc5bfc..82e73769d2d8f 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs @@ -54,7 +54,8 @@ pub fn roll_next() { let next = now + 1; System::set_block_number(next); - // Re-init frame-system, as execute would do. This resets the block weight usage counter, as we are using a realistic weight meter here. + // Re-init frame-system, as execute would do. This resets the block weight usage counter, as we + // are using a realistic weight meter here. frame_system::BlockWeight::::kill(); Staking::on_initialize(next); diff --git a/substrate/frame/staking-async/src/session_rotation.rs b/substrate/frame/staking-async/src/session_rotation.rs index e86da7d7b89a6..9292ecbb92157 100644 --- a/substrate/frame/staking-async/src/session_rotation.rs +++ b/substrate/frame/staking-async/src/session_rotation.rs @@ -860,8 +860,7 @@ impl EraElectionPlanner { .inspect_err(|e| log!(warn, "Election provider failed to start: {:?}", e)) } - pub(crate) fn maybe_fetch_election_results( - ) -> (Weight, Box Option>) { + pub(crate) fn maybe_fetch_election_results() -> (Weight, Box Option>) { let Ok((Some(required_weight))) = T::ElectionProvider::status() else { // no election ongoing return (Default::default(), Box::new(|| None)) From 5b712bbb3ede8491b7f23d8db3d340c143bf77f1 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 3 Oct 2025 14:07:24 +0100 Subject: [PATCH 11/20] fix build --- substrate/frame/staking-async/src/session_rotation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/staking-async/src/session_rotation.rs b/substrate/frame/staking-async/src/session_rotation.rs index 9292ecbb92157..16fbdcc1605ad 100644 --- a/substrate/frame/staking-async/src/session_rotation.rs +++ b/substrate/frame/staking-async/src/session_rotation.rs @@ -861,7 +861,7 @@ impl EraElectionPlanner { } pub(crate) fn maybe_fetch_election_results() -> (Weight, Box Option>) { - let Ok((Some(required_weight))) = T::ElectionProvider::status() else { + let Ok(Some(required_weight)) = T::ElectionProvider::status() else { // no election ongoing return (Default::default(), Box::new(|| None)) }; From 7bda95ec57d609aed76c44534d547b0c281b97dc Mon Sep 17 00:00:00 2001 From: kianenigma Date: Mon, 6 Oct 2025 11:42:31 +0100 Subject: [PATCH 12/20] add unit test --- .../election-provider-multi-block/src/lib.rs | 7 +- .../staking-async/ahm-test/src/ah/mock.rs | 39 ++- .../staking-async/ahm-test/src/ah/mod.rs | 1 + .../staking-async/ahm-test/src/ah/test.rs | 258 +++++++++++++++++- .../staking-async/ahm-test/src/ah/weights.rs | 104 +++++++ 5 files changed, 395 insertions(+), 14 deletions(-) create mode 100644 substrate/frame/staking-async/ahm-test/src/ah/weights.rs diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index e8cacda30a7e7..3ad02fef5c790 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -672,7 +672,7 @@ pub mod pallet { let current_phase = Self::current_phase(); let next_phase = current_phase.next(); - let (self_weight, self_exec) = Self::per_block_exec(current_phase.clone()); + let (self_weight, self_exec) = Self::per_block_exec(current_phase); let (verifier_weight, verifier_exc) = T::Verifier::per_block_exec(); // The following will combine `Self::per_block_exec` and `T::Verifier::per_block_exec` @@ -702,10 +702,11 @@ pub mod pallet { log!( trace, - "required weight for transition from {:?} to {:?} is {:?}", + "required weight for transition from {:?} to {:?} is {:?}, has {:?}", current_phase, next_phase, - combined_weight + combined_weight, + weight_meter.remaining() ); if weight_meter.can_consume(combined_weight) { let final_combined_weight = combined_exec(); diff --git a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs index 82e73769d2d8f..dd0c249985404 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs @@ -21,7 +21,7 @@ use frame_election_provider_support::{ bounds::{ElectionBounds, ElectionBoundsBuilder}, SequentialPhragmen, }; -use frame_support::sp_runtime::testing::TestXt; +use frame_support::{sp_runtime::testing::TestXt, weights::WeightMeter}; use pallet_election_provider_multi_block as multi_block; use pallet_staking_async::Forcing; use pallet_staking_async_rc_client::{SessionReport, ValidatorSetReport}; @@ -49,6 +49,10 @@ construct_runtime! { // alias Runtime with T. pub type T = Runtime; +parameter_types! { + pub static NextPollWeight: Option = None; +} + pub fn roll_next() { let now = System::block_number(); let next = now + 1; @@ -65,13 +69,11 @@ pub fn roll_next() { MultiBlockSigned::on_initialize(next); MultiBlockUnsigned::on_initialize(next); - let mut meter = System::remaining_block_weight(); + let mut meter = NextPollWeight::take() + .map(WeightMeter::with_limit) + .unwrap_or_else(System::remaining_block_weight); Staking::on_poll(next, &mut meter); - RcClient::on_poll(next, &mut meter); MultiBlock::on_poll(next, &mut meter); - MultiBlockVerifier::on_poll(next, &mut meter); - MultiBlockSigned::on_poll(next, &mut meter); - MultiBlockUnsigned::on_poll(next, &mut meter); } pub fn roll_many(blocks: BlockNumber) { @@ -285,7 +287,7 @@ impl multi_block::Config for Runtime { type Signed = MultiBlockSigned; type AreWeDone = multi_block::ProceedRegardlessOf; type OnRoundRotation = multi_block::CleanRound; - type WeightInfo = (); + type WeightInfo = super::weights::MultiBlockElectionWeightInfo; } impl multi_block::verifier::Config for Runtime { @@ -295,16 +297,16 @@ impl multi_block::verifier::Config for Runtime { type SolutionDataProvider = MultiBlockSigned; type SolutionImprovementThreshold = (); - type WeightInfo = (); + type WeightInfo = super::weights::MultiBlockElectionWeightInfo; } impl multi_block::unsigned::Config for Runtime { type MinerPages = ConstU32<1>; - type WeightInfo = (); type OffchainStorage = ConstBool; type MinerTxPriority = ConstU64<{ u64::MAX }>; type OffchainRepeat = (); type OffchainSolver = SequentialPhragmen; + type WeightInfo = super::weights::MultiBlockElectionWeightInfo; } parameter_types! { @@ -324,7 +326,7 @@ impl multi_block::signed::Config for Runtime { type EstimateCallFee = ConstU32<1>; type MaxSubmissions = MaxSubmissions; type RewardBase = RewardBase; - type WeightInfo = (); + type WeightInfo = super::weights::MultiBlockElectionWeightInfo; } parameter_types! { @@ -548,6 +550,7 @@ impl ExtBuilder { parameter_types! { static StakingEventsIndex: usize = 0; static ElectionEventsIndex: usize = 0; + static VerifierEventsIndex: usize = 0; static RcClientEventsIndex: usize = 0; } @@ -584,3 +587,19 @@ pub(crate) fn election_events_since_last_call() -> Vec> { ElectionEventsIndex::set(all.len()); all.into_iter().skip(seen).collect() } + +pub(crate) fn verifier_events_since_last_call() -> Vec> { + let all: Vec<_> = System::events() + .into_iter() + .filter_map(|r| { + if let RuntimeEvent::MultiBlockVerifier(inner) = r.event { + Some(inner) + } else { + None + } + }) + .collect(); + let seen = VerifierEventsIndex::get(); + VerifierEventsIndex::set(all.len()); + all.into_iter().skip(seen).collect() +} diff --git a/substrate/frame/staking-async/ahm-test/src/ah/mod.rs b/substrate/frame/staking-async/ahm-test/src/ah/mod.rs index 7a5aa43baf0df..bc5273f03a713 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/mod.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/mod.rs @@ -17,6 +17,7 @@ pub mod mock; pub mod test; +pub mod weights; // re-export for easier use in dual runtime tests. pub use mock::*; diff --git a/substrate/frame/staking-async/ahm-test/src/ah/test.rs b/substrate/frame/staking-async/ahm-test/src/ah/test.rs index a1327603c50f9..bce9167f9bfd2 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/test.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/test.rs @@ -17,8 +17,12 @@ use crate::ah::mock::*; use frame::prelude::Perbill; +use frame_election_provider_support::Weight; use frame_support::assert_ok; -use pallet_election_provider_multi_block::{Event as ElectionEvent, Phase}; +use pallet_election_provider_multi_block::{ + unsigned::miner::OffchainWorkerMiner, verifier::Event as VerifierEvent, CurrentPhase, + ElectionScore, Event as ElectionEvent, Phase, +}; use pallet_staking_async::{ self as staking_async, session_rotation::Rotator, ActiveEra, ActiveEraInfo, CurrentEra, Event as StakingEvent, @@ -1023,3 +1027,255 @@ fn on_offence_previous_era_instant_apply() { assert_eq!(staking_events_since_last_call(), vec![]); }); } + +mod poll_operations { + use super::*; + + #[test] + fn full_election_cycle_with_occasional_out_of_weight_completes() { + ExtBuilder::default().local_queue().build().execute_with(|| { + // given initial state of AH + assert_eq!(System::block_number(), 1); + assert_eq!(CurrentEra::::get(), Some(0)); + assert_eq!(Rotator::::active_era_start_session_index(), 0); + assert_eq!(ActiveEra::::get(), Some(ActiveEraInfo { index: 0, start: Some(0) })); + assert!(pallet_staking_async_rc_client::OutgoingValidatorSet::::get().is_none()); + + // receive first 3 session reports that don't trigger election + for i in 0..3 { + assert_ok!(rc_client::Pallet::::relay_session_report( + RuntimeOrigin::root(), + rc_client::SessionReport { + end_index: i, + validator_points: vec![(1, 10)], + activation_timestamp: None, + leftover: false, + } + )); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::SessionRotated { + starting_session: i + 1, + active_era: 0, + planned_era: 0 + }] + ); + } + + // receive session 4 which causes election to start + assert_ok!(rc_client::Pallet::::relay_session_report( + RuntimeOrigin::root(), + rc_client::SessionReport { + end_index: 3, + validator_points: vec![(1, 10)], + activation_timestamp: None, + leftover: false, + } + )); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::SessionRotated { + starting_session: 4, + active_era: 0, + // planned era 1 indicates election start signal is sent. + planned_era: 1 + }] + ); + + assert_eq!( + election_events_since_last_call(), + // Snapshot phase has started which will run for 3 blocks + vec![ElectionEvent::PhaseTransitioned { from: Phase::Off, to: Phase::Snapshot(3) }] + ); + assert_eq!(CurrentPhase::::get(), Phase::Snapshot(3)); + + // create 1 snapshot page normally + roll_next(); + assert_eq!(election_events_since_last_call(), vec![]); + assert_eq!(CurrentPhase::::get(), Phase::Snapshot(2)); + + // next block won't have enough weight + NextPollWeight::set(Some(crate::ah::weights::SMALL)); + roll_next(); + assert_eq!( + election_events_since_last_call(), + vec![ElectionEvent::UnexpectedPhaseTransitionOutOfWeight { + from: Phase::Snapshot(2), + to: Phase::Snapshot(1), + required: Weight::from_parts(100, 0), + had: Weight::from_parts(10, 0) + }] + ); + assert_eq!(CurrentPhase::::get(), Phase::Snapshot(2)); + + // next 2 blocks happen fine + roll_next(); + assert_eq!(election_events_since_last_call(), vec![]); + assert_eq!(CurrentPhase::::get(), Phase::Snapshot(1)); + + roll_next(); + assert_eq!(election_events_since_last_call(), vec![]); + assert_eq!(CurrentPhase::::get(), Phase::Snapshot(0)); + + // transition to signed + roll_next(); + assert_eq!( + election_events_since_last_call(), + vec![ElectionEvent::PhaseTransitioned { + from: Phase::Snapshot(0), + to: Phase::Signed(3) + }] + ); + assert_eq!(CurrentPhase::::get(), Phase::Signed(3)); + + // roll 1 + roll_next(); + assert_eq!(election_events_since_last_call(), vec![]); + assert_eq!(CurrentPhase::::get(), Phase::Signed(2)); + + // unlikely: we have zero weight, we won't progress + NextPollWeight::set(Some(Weight::default())); + roll_next(); + assert_eq!( + election_events_since_last_call(), + vec![ElectionEvent::UnexpectedPhaseTransitionOutOfWeight { + from: Phase::Signed(2), + to: Phase::Signed(1), + required: Weight::from_parts(10, 0), + had: Weight::from_parts(0, 0) + }] + ); + assert_eq!(CurrentPhase::::get(), Phase::Signed(2)); + + // submit a signed solution + let solution = OffchainWorkerMiner::::mine_solution(3, true).unwrap(); + assert_ok!(MultiBlockSigned::register(RuntimeOrigin::signed(1), solution.score)); + for (index, page) in solution.solution_pages.into_iter().enumerate() { + assert_ok!(MultiBlockSigned::submit_page( + RuntimeOrigin::signed(1), + index as u32, + Some(Box::new(page)) + )); + } + + // go to signed validation + roll_until_matches(|| CurrentPhase::::get() == Phase::SignedValidation(6), false); + assert_eq!( + election_events_since_last_call(), + vec![ElectionEvent::PhaseTransitioned { + from: Phase::Signed(0), + to: Phase::SignedValidation(6) + }] + ); + + // first block rolls okay + roll_next(); + assert_eq!(verifier_events_since_last_call(), vec![VerifierEvent::Verified(2, 4)]); + assert_eq!(election_events_since_last_call(), vec![]); + assert_eq!(CurrentPhase::::get(), Phase::SignedValidation(5)); + + // next block has not enough weight left for verification (verification of non-terminal + // pages requires MEDIUM) + NextPollWeight::set(Some(crate::ah::weights::SMALL)); + roll_next(); + assert_eq!(verifier_events_since_last_call(), vec![]); + assert_eq!( + election_events_since_last_call(), + vec![ElectionEvent::UnexpectedPhaseTransitionOutOfWeight { + from: Phase::SignedValidation(5), + to: Phase::SignedValidation(4), + required: Weight::from_parts(1010, 0), + had: Weight::from_parts(10, 0) + }] + ); + assert_eq!(CurrentPhase::::get(), Phase::SignedValidation(5)); + + // rest go by fine, roll until done + roll_until_matches(|| CurrentPhase::::get() == Phase::Done, false); + assert_eq!( + verifier_events_since_last_call(), + vec![ + VerifierEvent::Verified(1, 0), + VerifierEvent::Verified(0, 3), + VerifierEvent::Queued( + ElectionScore { + minimal_stake: 100, + sum_stake: 800, + sum_stake_squared: 180000 + }, + None + ) + ] + ); + assert_eq!( + election_events_since_last_call(), + vec![ + ElectionEvent::PhaseTransitioned { + from: Phase::SignedValidation(0), + to: Phase::Unsigned(3) + }, + ElectionEvent::PhaseTransitioned { from: Phase::Unsigned(0), to: Phase::Done }, + ] + ); + + // first export page goes by fine + assert_eq!(pallet_staking_async::NextElectionPage::::get(), None); + roll_next(); + assert_eq!( + election_events_since_last_call(), + vec![ElectionEvent::PhaseTransitioned { from: Phase::Done, to: Phase::Export(1) }] + ); + assert_eq!(CurrentPhase::::get(), Phase::Export(1)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::PagedElectionProceeded { page: 2, result: Ok(4) }] + ); + assert_eq!(pallet_staking_async::NextElectionPage::::get(), Some(1)); + + // second page goes by fine + roll_next(); + assert_eq!(election_events_since_last_call(), vec![]); + assert_eq!(CurrentPhase::::get(), Phase::Export(0)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::PagedElectionProceeded { page: 1, result: Ok(0) }] + ); + assert_eq!(pallet_staking_async::NextElectionPage::::get(), Some(0)); + + // last (LARGE page) runs out of weight + NextPollWeight::set(Some(crate::ah::weights::MEDIUM)); + roll_next(); + assert_eq!(election_events_since_last_call(), vec![]); + assert_eq!(CurrentPhase::::get(), Phase::Export(0)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unexpected( + pallet_staking_async::UnexpectedKind::PagedElectionOutOfWeight { + page: 0, + required: Weight::from_parts(1000, 0), + had: Weight::from_parts(100, 0) + } + )] + ); + assert_eq!(pallet_staking_async::NextElectionPage::::get(), Some(0)); + + // next time it goes by fine + roll_next(); + assert_eq!( + election_events_since_last_call(), + vec![ElectionEvent::PhaseTransitioned { from: Phase::Export(0), to: Phase::Off }] + ); + assert_eq!(CurrentPhase::::get(), Phase::Off); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::PagedElectionProceeded { page: 0, result: Ok(0) }] + ); + assert_eq!(pallet_staking_async::NextElectionPage::::get(), None); + + // outgoing message is queued + assert!(pallet_staking_async_rc_client::OutgoingValidatorSet::::get().is_some()); + }) + } +} diff --git a/substrate/frame/staking-async/ahm-test/src/ah/weights.rs b/substrate/frame/staking-async/ahm-test/src/ah/weights.rs new file mode 100644 index 0000000000000..7c2dcb334a8a4 --- /dev/null +++ b/substrate/frame/staking-async/ahm-test/src/ah/weights.rs @@ -0,0 +1,104 @@ +// This file is part of Substrate. + +// Copyright (C) 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. + +//! Note: we put as many things as possible as `unreachable!()` to limit the scope. + +use frame_election_provider_support::Weight; +use pallet_election_provider_multi_block::weights::traits::{ + pallet_election_provider_multi_block_signed, pallet_election_provider_multi_block_unsigned, + pallet_election_provider_multi_block_verifier, +}; + +pub const SMALL: Weight = Weight::from_parts(10, 0); +pub const MEDIUM: Weight = Weight::from_parts(100, 0); +pub const LARGE: Weight = Weight::from_parts(1_000, 0); + +pub struct MultiBlockElectionWeightInfo; +impl pallet_election_provider_multi_block::WeightInfo for MultiBlockElectionWeightInfo { + fn manage() -> Weight { + unreachable!() + } + fn export_non_terminal() -> Weight { + MEDIUM + } + fn export_terminal() -> Weight { + LARGE + } + fn per_block_nothing() -> Weight { + SMALL + } + fn per_block_snapshot_msp() -> Weight { + LARGE + } + fn per_block_snapshot_rest() -> Weight { + MEDIUM + } + fn per_block_start_signed_validation() -> Weight { + SMALL + } +} + +impl pallet_election_provider_multi_block_verifier::WeightInfo for MultiBlockElectionWeightInfo { + fn verification_invalid_non_terminal(_: u32) -> Weight { + MEDIUM + } + fn verification_invalid_terminal() -> Weight { + LARGE + } + fn verification_valid_non_terminal() -> Weight { + MEDIUM + } + fn verification_valid_terminal() -> Weight { + LARGE + } +} + +impl pallet_election_provider_multi_block_signed::WeightInfo for MultiBlockElectionWeightInfo { + fn bail() -> Weight { + unreachable!() + } + fn clear_old_round_data(_: u32) -> Weight { + unreachable!() + } + fn register_eject() -> Weight { + unreachable!() + } + fn register_not_full() -> Weight { + // we submit pages in tests + Default::default() + } + fn submit_page() -> Weight { + unreachable!() + } + fn unset_page() -> Weight { + unreachable!() + } +} + +impl pallet_election_provider_multi_block_unsigned::WeightInfo for MultiBlockElectionWeightInfo { + fn mine_solution(_p: u32) -> Weight { + unreachable!() + } + fn submit_unsigned() -> Weight { + // NOTE: this one is checked in the integrity tests of the runtime, we don't care about it + // here. + Default::default() + } + fn validate_unsigned() -> Weight { + unreachable!() + } +} From e6d025a433a6903fc30d3b60e3eaded67c28e45e Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 8 Oct 2025 10:13:11 +0100 Subject: [PATCH 13/20] add more tests, ready for benchmarks --- .../src/genesis_config_presets.rs | 2 +- .../assets/asset-hub-westend/src/lib.rs | 5 +- .../src/benchmarking.rs | 5 +- .../election-provider-multi-block/src/lib.rs | 159 +++++++++++++++++- .../src/signed/tests.rs | 4 +- .../src/types.rs | 4 +- .../election-provider-support/src/lib.rs | 4 +- 7 files changed, 165 insertions(+), 18 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs index 9bd617513bc09..8af83341ffcef 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/genesis_config_presets.rs @@ -105,7 +105,7 @@ mod preset_names { /// Provides the JSON representation of predefined genesis config for given `id`. pub fn get_preset(id: &PresetId) -> Option> { use preset_names::*; - let dev_stakers = Some((0, 25_000)); + let dev_stakers = Some((1000, 25_000)); let patch = match id.as_ref() { PRESET_GENESIS => asset_hub_westend_genesis( // initial collators. diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index b42fc1c244806..64019b503ed84 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1678,9 +1678,8 @@ mod benches { [pallet_bags_list, VoterList] [pallet_balances, Balances] [pallet_conviction_voting, ConvictionVoting] - // Temporarily disabled due to https://github.com/paritytech/polkadot-sdk/issues/7714 - // [pallet_election_provider_multi_block, MultiBlockElection] - // [pallet_election_provider_multi_block_verifier, MultiBlockElectionVerifier] + [pallet_election_provider_multi_block, MultiBlockElection] + [pallet_election_provider_multi_block_verifier, MultiBlockElectionVerifier] [pallet_election_provider_multi_block_unsigned, MultiBlockElectionUnsigned] [pallet_election_provider_multi_block_signed, MultiBlockElectionSigned] [pallet_fast_unstake, FastUnstake] diff --git a/substrate/frame/election-provider-multi-block/src/benchmarking.rs b/substrate/frame/election-provider-multi-block/src/benchmarking.rs index 3a759e6d5580b..f341f6533f9c5 100644 --- a/substrate/frame/election-provider-multi-block/src/benchmarking.rs +++ b/substrate/frame/election-provider-multi-block/src/benchmarking.rs @@ -24,9 +24,10 @@ use frame_election_provider_support::{ElectionDataProvider, ElectionProvider}; use frame_support::pallet_prelude::*; const SNAPSHOT_NOT_BIG_ENOUGH: &'static str = "Snapshot page is not full, you should run this \ -benchmark with enough genesis stakers in staking (DataProvider) to fill a page of voters/targets \ +benchmark with enough genesis stakers in staking to fill a page of voters/targets \ as per VoterSnapshotPerBlock and TargetSnapshotPerBlock. Generate at least \ -2 * VoterSnapshotPerBlock) nominators and TargetSnapshotPerBlock validators"; +2 * VoterSnapshotPerBlock) nominators and TargetSnapshotPerBlock validators. Use `dev_stakers` in \ +genesis config."; // TODO: remove unwraps from all benchmarks of this pallet -- it makes debugging via wasm harder diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index 3ad02fef5c790..05f1ab1e9af4b 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -118,7 +118,7 @@ //! //! ### Phase Transition //! -//! Within all 4 pallets only the parent pallet is allowed to move forward the phases. As of now, +//! Within all 4 pallets only the parent pallet is allowed to move the phases forward. As of now, //! the transition happens `on-poll`, ensuring that we don't consume too much weight. The parent //! pallet is in charge of aggregating the work to be done by all pallets, checking if it can fit //! within the current block's weight limits, and executing it if so. @@ -668,7 +668,8 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_poll(_now: BlockNumberFor, weight_meter: &mut WeightMeter) { - // we need current phase to be read in any case -- we can live with it. + // read the current phase in any case -- one storage read is the minimum we do in all + // cases. let current_phase = Self::current_phase(); let next_phase = current_phase.next(); @@ -723,7 +724,7 @@ pub mod pallet { }); } - // NOTE: why in here? bc it is more accessible, for example `roll_to_with_ocw`. + // NOTE: why in here? because it is more accessible, for example `roll_to_with_ocw`. #[cfg(test)] { if _now > 200u32.into() { @@ -1243,7 +1244,7 @@ impl Pallet { /// * Upon last page of `Phase::Signed`, instruct the `Verifier` to start, if any solution /// exists. /// - /// What it does not: + /// What it does not do: /// /// * Instruct the verifier to move forward. This happens through /// [`verifier::Verifier::per_block_exec`]. On each block [`T::Verifier`] is given a chance to @@ -1491,11 +1492,157 @@ impl Pallet { snapshot + signed + signed_validation + unsigned } +} - #[cfg(any(test, feature = "runtime-benchmarks", feature = "try-runtime"))] +#[cfg(any(test, feature = "runtime-benchmarks", feature = "try-runtime"))] +impl Pallet { pub(crate) fn do_try_state(_: BlockNumberFor) -> Result<(), &'static str> { Snapshot::::sanity_check() } + + fn analyze_weight( + op_name: &str, + op_weight: Weight, + limit_weight: Weight, + maybe_max_ratio: Option, + maybe_max_warn_ratio: Option, + ) { + use frame_support::weights::constants::{ + WEIGHT_PROOF_SIZE_PER_KB, WEIGHT_REF_TIME_PER_MILLIS, + }; + + let ref_time_ms = op_weight.ref_time() / WEIGHT_REF_TIME_PER_MILLIS; + let ref_time_ratio = + sp_runtime::Percent::from_rational(op_weight.ref_time(), limit_weight.ref_time()); + let proof_size_kb = op_weight.proof_size() / WEIGHT_PROOF_SIZE_PER_KB; + let proof_size_ratio = + sp_runtime::Percent::from_rational(op_weight.proof_size(), limit_weight.proof_size()); + let limit_ms = limit_weight.ref_time() / WEIGHT_REF_TIME_PER_MILLIS; + let limit_kb = limit_weight.proof_size() / WEIGHT_PROOF_SIZE_PER_KB; + log::info!( + target: crate::LOG_PREFIX, + "weight of {op_name:?} is: ref-time: {ref_time_ms}ms, {ref_time_ratio:?} of total, proof-size: {proof_size_kb}KiB, {proof_size_ratio:?} of total (total: {limit_ms}ms, {limit_kb}KiB)", + ); + + if let Some(max_ratio) = maybe_max_ratio { + assert!(ref_time_ratio <= max_ratio && proof_size_ratio <= max_ratio,) + } + if let Some(warn_ratio) = maybe_max_warn_ratio { + if ref_time_ratio > warn_ratio || proof_size_ratio > warn_ratio { + log::warn!( + target: crate::LOG_PREFIX, + "weight of {op_name:?} is above {warn_ratio:?} of the block limit", + ); + } + } + } + + pub fn check_all_weights( + limit_weight: Weight, + maybe_max_ratio: Option, + maybe_max_warn_ratio: Option, + ) where + T: crate::verifier::Config + crate::signed::Config + crate::unsigned::Config, + { + use crate::weights::traits::{ + pallet_election_provider_multi_block_signed::WeightInfo as _, + pallet_election_provider_multi_block_unsigned::WeightInfo as _, + pallet_election_provider_multi_block_verifier::WeightInfo as _, + }; + + // -------------- snapshot + Self::analyze_weight( + "snapshot_msp", + ::WeightInfo::per_block_snapshot_msp(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + Self::analyze_weight( + "snapshot_rest", + ::WeightInfo::per_block_snapshot_rest(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + // -------------- signed + Self::analyze_weight( + "signed_clear_all_pages", + ::WeightInfo::clear_old_round_data(T::Pages::get()), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + Self::analyze_weight( + "signed_submit_single_pages", + ::WeightInfo::submit_page(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + // -------------- unsigned + Self::analyze_weight( + "verify unsigned solution", + ::WeightInfo::submit_unsigned(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + // -------------- verification + Self::analyze_weight( + "verifier valid terminal", + ::WeightInfo::verification_valid_terminal(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + Self::analyze_weight( + "verifier invalid terminal", + ::WeightInfo::verification_invalid_terminal(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + Self::analyze_weight( + "verifier valid non terminal", + ::WeightInfo::verification_valid_non_terminal(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + Self::analyze_weight( + "verifier invalid non terminal", + ::WeightInfo::verification_invalid_non_terminal( + T::Pages::get(), + ), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + // -------------- export + Self::analyze_weight( + "export non-terminal", + ::WeightInfo::export_non_terminal(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + + Self::analyze_weight( + "export terminal", + ::WeightInfo::export_terminal(), + limit_weight, + maybe_max_ratio, + maybe_max_warn_ratio, + ); + } } #[allow(unused)] @@ -1718,7 +1865,7 @@ impl ElectionProvider for Pallet { // we're not doing anything. Phase::Off => Err(()), - // we're doing sth but not ready. + // we're doing something but not ready. Phase::Signed(_) | Phase::SignedValidation(_) | Phase::Unsigned(_) | diff --git a/substrate/frame/election-provider-multi-block/src/signed/tests.rs b/substrate/frame/election-provider-multi-block/src/signed/tests.rs index 6a2cf47130592..db25b1fbec710 100644 --- a/substrate/frame/election-provider-multi-block/src/signed/tests.rs +++ b/substrate/frame/election-provider-multi-block/src/signed/tests.rs @@ -951,8 +951,8 @@ mod e2e { vec![crate::signed::Event::Slashed(0, 99, 8)] ); - // we have 2 block left in signed verification, but we cannot do anything here. - // status is not set, as not enough time to do anything. + // we have 2 blocks left in signed verification, but we cannot do anything here. + // status is not set, as there's not enough time to do anything. assert_eq!(crate::Pallet::::current_phase(), Phase::SignedValidation(1)); roll_next(); assert_eq!(crate::Pallet::::current_phase(), Phase::SignedValidation(0)); diff --git a/substrate/frame/election-provider-multi-block/src/types.rs b/substrate/frame/election-provider-multi-block/src/types.rs index 715980d2083aa..60ed8c99b7fc6 100644 --- a/substrate/frame/election-provider-multi-block/src/types.rs +++ b/substrate/frame/election-provider-multi-block/src/types.rs @@ -361,8 +361,8 @@ impl Phase { // Done. Wait for export to start. Self::Done => Self::Done, - // Export never moves forward via this function, and is always manually set in `elect` - // code path. + // Export never moves forward via this function, and is always manually set in the + // `elect` code path. Self::Export(x) => Self::Export(x), } } diff --git a/substrate/frame/election-provider-support/src/lib.rs b/substrate/frame/election-provider-support/src/lib.rs index c77898979763d..7925eead4a964 100644 --- a/substrate/frame/election-provider-support/src/lib.rs +++ b/substrate/frame/election-provider-support/src/lib.rs @@ -524,8 +524,8 @@ pub trait ElectionProvider { /// Indicate whether this election provider is currently ongoing an asynchronous election. /// - /// * `Err(())` should signal that we are not doing anything, and `elect` should def. not be - /// called. + /// * `Err(())` should signal that we are not doing anything, and `elect` should definitely not + /// be called. /// * `Ok(None)` means we are doing something, but we are not done. `elect` should /// not be called. /// * `Ok(Some(Weight))` means we are done and ready for a call to `elect`, which should consume From cdba7191a1a23985191f9dcee21fc2416df027cc Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 8 Oct 2025 11:01:13 +0100 Subject: [PATCH 14/20] docs and add weight test --- .../assets/asset-hub-westend/src/lib.rs | 14 ++++++++++ .../election-provider-multi-block/src/lib.rs | 26 ++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 64019b503ed84..b4e55ab4aacbd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -2661,3 +2661,17 @@ fn ensure_key_ss58() { AccountId::from_ss58check("5F4EbSkZz18X36xhbsjvDNs6NuZ82HyYtq5UiJ1h9SBHJXZD").unwrap(); assert_eq!(acc, RootMigController::sorted_members()[0]); } + +#[test] +fn ensure_epmb_weights_sane() { + use sp_io::TestExternalities; + use sp_runtime::Percent; + sp_tracing::try_init_simple(); + TestExternalities::default().execute_with(|| { + pallet_election_provider_multi_block::Pallet::::check_all_weights( + ::BlockWeights::get().max_block, + Some(Percent::from_percent(75)), + Some(Percent::from_percent(50)), + ) + }); +} diff --git a/substrate/frame/election-provider-multi-block/src/lib.rs b/substrate/frame/election-provider-multi-block/src/lib.rs index 05f1ab1e9af4b..4b8c3de7cce2e 100644 --- a/substrate/frame/election-provider-multi-block/src/lib.rs +++ b/substrate/frame/election-provider-multi-block/src/lib.rs @@ -1492,14 +1492,15 @@ impl Pallet { snapshot + signed + signed_validation + unsigned } -} -#[cfg(any(test, feature = "runtime-benchmarks", feature = "try-runtime"))] -impl Pallet { + #[cfg(any(test, feature = "runtime-benchmarks", feature = "try-runtime"))] pub(crate) fn do_try_state(_: BlockNumberFor) -> Result<(), &'static str> { Snapshot::::sanity_check() } +} +#[cfg(feature = "std")] +impl Pallet { fn analyze_weight( op_name: &str, op_weight: Weight, @@ -1537,6 +1538,25 @@ impl Pallet { } } + /// Helper function to check the weights of all signifcant operations of this this pallet + /// against a runtime. + /// + /// Will check the weights for: + /// + /// * snapshot + /// * signed submission and cleanip + /// * unsigned solution submission + /// * signed validation + /// * export. + /// + /// Arguments: + /// + /// * `limit_weight` should be the maximum block weight (often obtained from `frame_system`). + /// * `maybe_max_ratio` is the maximum ratio of `limit_weight` that we may consume, else we + /// panic. + /// * `maybe_max_warn_rati` has the same effect, but it emits a warning instead of panic. + /// + /// A reasonable value for `maybe_max_weight` would be 75%, and 50% for `maybe_max_warn_ratio`. pub fn check_all_weights( limit_weight: Weight, maybe_max_ratio: Option, From 62a0050040f466f3aa1098375415ff82a8ee0e1d Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:36:18 +0100 Subject: [PATCH 15/20] Apply suggestion from @kianenigma --- substrate/frame/staking-async/ahm-test/src/ah/weights.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/substrate/frame/staking-async/ahm-test/src/ah/weights.rs b/substrate/frame/staking-async/ahm-test/src/ah/weights.rs index 7c2dcb334a8a4..fdebb21033144 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/weights.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/weights.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Weights to be used with `full_election_cycle_with_occasional_out_of_weight_completes` test. +//! //! Note: we put as many things as possible as `unreachable!()` to limit the scope. use frame_election_provider_support::Weight; From 172ef4a183686e892da55e1dda75ddc688cd34b7 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 8 Oct 2025 11:48:37 +0100 Subject: [PATCH 16/20] add more tests --- .../runtimes/parachain/src/staking.rs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs index a5d0b9ed33b2b..e9e6621814082 100644 --- a/substrate/frame/staking-async/runtimes/parachain/src/staking.rs +++ b/substrate/frame/staking-async/runtimes/parachain/src/staking.rs @@ -688,6 +688,36 @@ mod tests { ); } + #[test] + fn ensure_epmb_weights_sane_polkadot() { + use sp_io::TestExternalities; + use sp_runtime::Percent; + sp_tracing::try_init_simple(); + TestExternalities::default().execute_with(|| { + super::enable_dot_preset(false); + pallet_election_provider_multi_block::Pallet::::check_all_weights( + ::BlockWeights::get().max_block, + Some(Percent::from_percent(75)), + Some(Percent::from_percent(50)), + ) + }); + } + + #[test] + fn ensure_epmb_weights_sane_kusama() { + use sp_io::TestExternalities; + use sp_runtime::Percent; + sp_tracing::try_init_simple(); + TestExternalities::default().execute_with(|| { + super::enable_ksm_preset(false); + pallet_election_provider_multi_block::Pallet::::check_all_weights( + ::BlockWeights::get().max_block, + Some(Percent::from_percent(75)), + Some(Percent::from_percent(50)), + ) + }); + } + #[test] fn signed_weight_ratios() { sp_tracing::try_init_simple(); From 7837c72710b51c52e45f3b72b4588ba7cdecbe74 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:49:59 +0000 Subject: [PATCH 17/20] Update from github-actions[bot] running command 'bench --pallet pallet_election_provider_multi_block pallet_election_provider_multi_block_signed pallet_election_provider_multi_block_verifier pallet_election_provider_multi_block_unsigned --runtime asset-hub-westend' --- .../pallet_election_provider_multi_block.rs | 225 ++++++++++++++++++ ...et_election_provider_multi_block_signed.rs | 197 +++++++++++++++ ..._election_provider_multi_block_unsigned.rs | 104 ++++++++ ..._election_provider_multi_block_verifier.rs | 205 ++++++++++++++++ 4 files changed, 731 insertions(+) create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs create mode 100644 cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block.rs new file mode 100644 index 0000000000000..efdf5d7c88e8b --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block.rs @@ -0,0 +1,225 @@ +// Copyright (C) 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. + +//! Autogenerated weights for `pallet_election_provider_multi_block` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-10-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `30261411344a`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --extrinsic=* +// --runtime=target/production/wbuild/asset-hub-westend-runtime/asset_hub_westend_runtime.wasm +// --pallet=pallet_election_provider_multi_block +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --no-storage-info +// --no-min-squares +// --no-median-slopes + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_election_provider_multi_block`. +pub struct WeightInfo(PhantomData); +impl pallet_election_provider_multi_block::WeightInfo for WeightInfo { + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + fn per_block_nothing() -> Weight { + // Proof Size summary in bytes: + // Measured: `118` + // Estimated: `1603` + // Minimum execution time: 7_306_000 picoseconds. + Weight::from_parts(7_601_000, 0) + .saturating_add(Weight::from_parts(0, 1603)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `Staking::ValidatorCount` (r:1 w:0) + /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `Staking::CounterForValidators` (r:1 w:0) + /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `Staking::Validators` (r:1001 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:0 w:1) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshotHash` (r:0 w:1) + /// Proof: `MultiBlockElection::PagedTargetSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:0 w:1) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(32026), added: 34501, mode: `Measured`) + fn per_block_snapshot_msp() -> Weight { + // Proof Size summary in bytes: + // Measured: `48346` + // Estimated: `2526811` + // Minimum execution time: 5_889_231_000 picoseconds. + Weight::from_parts(5_978_684_000, 0) + .saturating_add(Weight::from_parts(0, 2526811)) + .saturating_add(T::DbWeight::get().reads(1006)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `Staking::VoterSnapshotStatus` (r:1 w:1) + /// Proof: `Staking::VoterSnapshotStatus` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `Measured`) + /// Storage: `VoterList::CounterForListNodes` (r:1 w:0) + /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `VoterList::ListBags` (r:1 w:0) + /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `Measured`) + /// Storage: `VoterList::ListNodes` (r:705 w:0) + /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `Measured`) + /// Storage: `Staking::Bonded` (r:703 w:0) + /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `Measured`) + /// Storage: `Staking::Ledger` (r:703 w:0) + /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(753), added: 3228, mode: `Measured`) + /// Storage: `Staking::Nominators` (r:703 w:0) + /// Proof: `Staking::Nominators` (`max_values`: None, `max_size`: Some(558), added: 3033, mode: `Measured`) + /// Storage: `Staking::Validators` (r:103 w:0) + /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `Staking::MinimumActiveStake` (r:0 w:1) + /// Proof: `Staking::MinimumActiveStake` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`) + /// Storage: `VoterList::Lock` (r:0 w:1) + /// Proof: `VoterList::Lock` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:0 w:1) + /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshotHash` (r:0 w:1) + /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) + fn per_block_snapshot_rest() -> Weight { + // Proof Size summary in bytes: + // Measured: `1495638` + // Estimated: `3241503` + // Minimum execution time: 31_397_565_000 picoseconds. + Weight::from_parts(33_054_412_000, 0) + .saturating_add(Weight::from_parts(0, 3241503)) + .saturating_add(T::DbWeight::get().reads(2923)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + fn per_block_start_signed_validation() -> Weight { + // Proof Size summary in bytes: + // Measured: `592` + // Estimated: `4057` + // Minimum execution time: 48_861_000 picoseconds. + Weight::from_parts(57_380_000, 0) + .saturating_add(Weight::from_parts(0, 4057)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `Staking::ElectableStashes` (r:1 w:1) + /// Proof: `Staking::ElectableStashes` (`max_values`: Some(1), `max_size`: Some(32002), added: 32497, mode: `Measured`) + /// Storage: `Staking::ErasTotalStake` (r:1 w:1) + /// Proof: `Staking::ErasTotalStake` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `Measured`) + fn export_non_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `1479` + // Estimated: `4944` + // Minimum execution time: 74_862_000 picoseconds. + Weight::from_parts(93_436_000, 0) + .saturating_add(Weight::from_parts(0, 4944)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:1) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:32 w:32) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:32 w:32) + /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshotHash` (r:32 w:32) + /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:1) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(32026), added: 34501, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshotHash` (r:1 w:1) + /// Proof: `MultiBlockElection::PagedTargetSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) + /// Storage: `Staking::CurrentEra` (r:1 w:0) + /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `Staking::ElectableStashes` (r:1 w:1) + /// Proof: `Staking::ElectableStashes` (`max_values`: Some(1), `max_size`: Some(32002), added: 32497, mode: `Measured`) + /// Storage: `Staking::ErasTotalStake` (r:1 w:1) + /// Proof: `Staking::ErasTotalStake` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:0 w:1) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionScore` (r:0 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionScore` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:0 w:1) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + fn export_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `4847` + // Estimated: `85037` + // Minimum execution time: 273_049_000 picoseconds. + Weight::from_parts(329_970_000, 0) + .saturating_add(Weight::from_parts(0, 85037)) + .saturating_add(T::DbWeight::get().reads(104)) + .saturating_add(T::DbWeight::get().writes(106)) + } + fn manage() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 198_000 picoseconds. + Weight::from_parts(234_000, 0) + .saturating_add(Weight::from_parts(0, 0)) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs new file mode 100644 index 0000000000000..9933de080103e --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs @@ -0,0 +1,197 @@ +// Copyright (C) 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. + +//! Autogenerated weights for `pallet_election_provider_multi_block_signed` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-10-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `30261411344a`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --extrinsic=* +// --runtime=target/production/wbuild/asset-hub-westend-runtime/asset_hub_westend_runtime.wasm +// --pallet=pallet_election_provider_multi_block_signed +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --no-storage-info +// --no-min-squares +// --no-median-slopes + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_election_provider_multi_block_signed`. +pub struct WeightInfo(PhantomData); +impl pallet_election_provider_multi_block_signed::WeightInfo for WeightInfo { + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:0 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + fn register_not_full() -> Weight { + // Proof Size summary in bytes: + // Measured: `3252` + // Estimated: `6717` + // Minimum execution time: 82_268_000 picoseconds. + Weight::from_parts(84_404_000, 0) + .saturating_add(Weight::from_parts(0, 6717)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `Balances::Holds` (r:2 w:2) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:2) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + fn register_eject() -> Weight { + // Proof Size summary in bytes: + // Measured: `7851` + // Estimated: `88041` + // Minimum execution time: 224_911_000 picoseconds. + Weight::from_parts(234_697_000, 0) + .saturating_add(Weight::from_parts(0, 88041)) + .saturating_add(T::DbWeight::get().reads(39)) + .saturating_add(T::DbWeight::get().writes(37)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + fn submit_page() -> Weight { + // Proof Size summary in bytes: + // Measured: `3785` + // Estimated: `7250` + // Minimum execution time: 173_658_000 picoseconds. + Weight::from_parts(227_077_000, 0) + .saturating_add(Weight::from_parts(0, 7250)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + fn unset_page() -> Weight { + // Proof Size summary in bytes: + // Measured: `3887` + // Estimated: `7352` + // Minimum execution time: 171_867_000 picoseconds. + Weight::from_parts(212_382_000, 0) + .saturating_add(Weight::from_parts(0, 7352)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + fn bail() -> Weight { + // Proof Size summary in bytes: + // Measured: `4717` + // Estimated: `84907` + // Minimum execution time: 139_262_000 picoseconds. + Weight::from_parts(145_668_000, 0) + .saturating_add(Weight::from_parts(0, 84907)) + .saturating_add(T::DbWeight::get().reads(37)) + .saturating_add(T::DbWeight::get().writes(35)) + } + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) + /// The range of component `p` is `[1, 32]`. + fn clear_old_round_data(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `3709 + p * (32 ±0)` + // Estimated: `7174 + p * (2507 ±0)` + // Minimum execution time: 84_803_000 picoseconds. + Weight::from_parts(86_900_104, 0) + .saturating_add(Weight::from_parts(0, 7174)) + // Standard Error: 9_113 + .saturating_add(Weight::from_parts(1_149_584, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) + .saturating_add(Weight::from_parts(0, 2507).saturating_mul(p.into())) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs new file mode 100644 index 0000000000000..13bee900725bc --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs @@ -0,0 +1,104 @@ +// Copyright (C) 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. + +//! Autogenerated weights for `pallet_election_provider_multi_block_unsigned` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-10-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `30261411344a`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --extrinsic=* +// --runtime=target/production/wbuild/asset-hub-westend-runtime/asset_hub_westend_runtime.wasm +// --pallet=pallet_election_provider_multi_block_unsigned +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --no-storage-info +// --no-min-squares +// --no-median-slopes + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_election_provider_multi_block_unsigned`. +pub struct WeightInfo(PhantomData); +impl pallet_election_provider_multi_block_unsigned::WeightInfo for WeightInfo { + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0x33ed3d010c1fea25c2adbfba9297161f` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x33ed3d010c1fea25c2adbfba9297161f` (r:1 w:0) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionScore` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionScore` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::MinimumScore` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::MinimumScore` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xc209f5d8eb920681b56c64b8694ea78c` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xc209f5d8eb920681b56c64b8694ea78c` (r:1 w:0) + fn validate_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `351` + // Estimated: `3816` + // Minimum execution time: 38_144_000 picoseconds. + Weight::from_parts(46_852_000, 0) + .saturating_add(Weight::from_parts(0, 3816)) + .saturating_add(T::DbWeight::get().reads(7)) + } + /// Storage: UNKNOWN KEY `0x33ed3d010c1fea25c2adbfba9297161f` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x33ed3d010c1fea25c2adbfba9297161f` (r:1 w:0) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionScore` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionScore` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::MinimumScore` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::MinimumScore` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(32026), added: 34501, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:2 w:0) + /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionY` (r:0 w:2) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionY` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) + fn submit_unsigned() -> Weight { + // Proof Size summary in bytes: + // Measured: `760999` + // Estimated: `766939` + // Minimum execution time: 1_224_980_000 picoseconds. + Weight::from_parts(1_295_589_000, 0) + .saturating_add(Weight::from_parts(0, 766939)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs new file mode 100644 index 0000000000000..61e7b40b3a584 --- /dev/null +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs @@ -0,0 +1,205 @@ +// Copyright (C) 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. + +//! Autogenerated weights for `pallet_election_provider_multi_block_verifier` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-10-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `30261411344a`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --extrinsic=* +// --runtime=target/production/wbuild/asset-hub-westend-runtime/asset_hub_westend_runtime.wasm +// --pallet=pallet_election_provider_multi_block_verifier +// --header=/__w/polkadot-sdk/polkadot-sdk/cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights +// --wasm-execution=compiled +// --steps=50 +// --repeat=20 +// --heap-pages=4096 +// --no-storage-info +// --no-min-squares +// --no-median-slopes + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_election_provider_multi_block_verifier`. +pub struct WeightInfo(PhantomData); +impl pallet_election_provider_multi_block_verifier::WeightInfo for WeightInfo { + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(32026), added: 34501, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:0 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) + fn verification_valid_non_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `373126` + // Estimated: `376591` + // Minimum execution time: 641_281_000 picoseconds. + Weight::from_parts(720_764_000, 0) + .saturating_add(Weight::from_parts(0, 376591)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(32026), added: 34501, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:33 w:32) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionScore` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionScore` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) + fn verification_valid_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `409681` + // Estimated: `492346` + // Minimum execution time: 1_163_590_000 picoseconds. + Weight::from_parts(1_241_096_000, 0) + .saturating_add(Weight::from_parts(0, 492346)) + .saturating_add(T::DbWeight::get().reads(76)) + .saturating_add(T::DbWeight::get().writes(72)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(32026), added: 34501, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:33 w:32) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:31 w:32) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) + fn verification_invalid_terminal() -> Weight { + // Proof Size summary in bytes: + // Measured: `409681` + // Estimated: `492346` + // Minimum execution time: 1_129_775_000 picoseconds. + Weight::from_parts(1_227_323_000, 0) + .saturating_add(Weight::from_parts(0, 492346)) + .saturating_add(T::DbWeight::get().reads(107)) + .saturating_add(T::DbWeight::get().writes(102)) + } + /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) + /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) + /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(46478), added: 48953, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(32026), added: 34501, mode: `Measured`) + /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) + /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) + /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) + /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:31 w:31) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) + /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:31 w:31) + /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SubmissionMetadataStorage` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) + /// Storage: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(265), added: 2740, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) + /// The range of component `v` is `[0, 31]`. + fn verification_invalid_non_terminal(v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `417092 + v * (37 ±0)` + // Estimated: `488244 + v * (2550 ±72)` + // Minimum execution time: 853_783_000 picoseconds. + Weight::from_parts(946_789_493, 0) + .saturating_add(Weight::from_parts(0, 488244)) + // Standard Error: 118_548 + .saturating_add(Weight::from_parts(4_126_302, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(43)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(v.into()))) + .saturating_add(T::DbWeight::get().writes(38)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(v.into()))) + .saturating_add(Weight::from_parts(0, 2550).saturating_mul(v.into())) + } +} From 493a46e698f90d1d9b4dfacab7e7c855d05060a3 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 8 Oct 2025 11:57:26 +0100 Subject: [PATCH 18/20] integrate new westend weights --- .../runtimes/assets/asset-hub-westend/src/staking.rs | 8 ++++---- .../runtimes/assets/asset-hub-westend/src/weights/mod.rs | 4 ++++ .../pallet_election_provider_multi_block_signed.rs | 2 +- .../pallet_election_provider_multi_block_unsigned.rs | 2 +- .../pallet_election_provider_multi_block_verifier.rs | 2 +- .../election-provider-multi-block/src/weights/mod.rs | 3 --- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs index 5ea020ad9e789..30df85e6d3d24 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/staking.rs @@ -134,7 +134,7 @@ impl multi_block::Config for Runtime { type AreWeDone = multi_block::RevertToSignedIfNotQueuedOf; type OnRoundRotation = multi_block::CleanRound; type Signed = MultiBlockElectionSigned; - type WeightInfo = multi_block::weights::westend::MultiBlockWeightInfo; + type WeightInfo = weights::pallet_election_provider_multi_block::WeightInfo; } impl multi_block::verifier::Config for Runtime { @@ -143,7 +143,7 @@ impl multi_block::verifier::Config for Runtime { type MaxBackersPerWinnerFinal = MaxBackersPerWinnerFinal; type SolutionDataProvider = MultiBlockElectionSigned; type SolutionImprovementThreshold = SolutionImprovementThreshold; - type WeightInfo = multi_block::weights::westend::MultiBlockVerifierWeightInfo; + type WeightInfo = weights::pallet_election_provider_multi_block_verifier::WeightInfo; } parameter_types! { @@ -165,7 +165,7 @@ impl multi_block::signed::Config for Runtime { type RewardBase = RewardBase; type MaxSubmissions = MaxSubmissions; type EstimateCallFee = TransactionPayment; - type WeightInfo = multi_block::weights::westend::MultiBlockSignedWeightInfo; + type WeightInfo = weights::pallet_election_provider_multi_block_signed::WeightInfo; } parameter_types! { @@ -182,7 +182,7 @@ impl multi_block::unsigned::Config for Runtime { type OffchainSolver = SequentialPhragmen>; type MinerTxPriority = MinerTxPriority; type OffchainRepeat = OffchainRepeat; - type WeightInfo = multi_block::weights::westend::MultiBlockUnsignedWeightInfo; + type WeightInfo = weights::pallet_election_provider_multi_block_unsigned::WeightInfo; } parameter_types! { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs index 0559b559ec144..e5711d0607a6e 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/mod.rs @@ -34,6 +34,10 @@ pub mod pallet_bags_list; pub mod pallet_balances; pub mod pallet_collator_selection; pub mod pallet_conviction_voting; +pub mod pallet_election_provider_multi_block; +pub mod pallet_election_provider_multi_block_signed; +pub mod pallet_election_provider_multi_block_unsigned; +pub mod pallet_election_provider_multi_block_verifier; pub mod pallet_fast_unstake; pub mod pallet_indices; pub mod pallet_message_queue; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs index 9933de080103e..46c0aa87133da 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_signed.rs @@ -49,7 +49,7 @@ use core::marker::PhantomData; /// Weight functions for `pallet_election_provider_multi_block_signed`. pub struct WeightInfo(PhantomData); -impl pallet_election_provider_multi_block_signed::WeightInfo for WeightInfo { +impl pallet_election_provider_multi_block::signed::WeightInfo for WeightInfo { /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs index 13bee900725bc..050633d64ab9c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_unsigned.rs @@ -49,7 +49,7 @@ use core::marker::PhantomData; /// Weight functions for `pallet_election_provider_multi_block_unsigned`. pub struct WeightInfo(PhantomData); -impl pallet_election_provider_multi_block_unsigned::WeightInfo for WeightInfo { +impl pallet_election_provider_multi_block::unsigned::WeightInfo for WeightInfo { /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0x33ed3d010c1fea25c2adbfba9297161f` (r:1 w:0) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs index 61e7b40b3a584..e2e6fbb59bd1a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_election_provider_multi_block_verifier.rs @@ -49,7 +49,7 @@ use core::marker::PhantomData; /// Weight functions for `pallet_election_provider_multi_block_verifier`. pub struct WeightInfo(PhantomData); -impl pallet_election_provider_multi_block_verifier::WeightInfo for WeightInfo { +impl pallet_election_provider_multi_block::verifier::WeightInfo for WeightInfo { /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) diff --git a/substrate/frame/election-provider-multi-block/src/weights/mod.rs b/substrate/frame/election-provider-multi-block/src/weights/mod.rs index 3647f4e11657c..b820e8c2201a8 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/mod.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/mod.rs @@ -173,6 +173,3 @@ pub mod polkadot { pallet_election_provider_multi_block_verifier_dot_size::WeightInfo as MultiBlockVerifierWeightInfo, }; } -pub mod westend { - pub use super::polkadot::*; -} From aa517d8afe39fdb16bbc9b5f268e8120d1b6fe19 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Wed, 8 Oct 2025 13:49:30 +0100 Subject: [PATCH 19/20] add comment --- substrate/frame/staking-async/ahm-test/src/ah/weights.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/frame/staking-async/ahm-test/src/ah/weights.rs b/substrate/frame/staking-async/ahm-test/src/ah/weights.rs index fdebb21033144..e0c2d4d015b8e 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/weights.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/weights.rs @@ -16,7 +16,7 @@ // limitations under the License. //! Weights to be used with `full_election_cycle_with_occasional_out_of_weight_completes` test. -//! +//! //! Note: we put as many things as possible as `unreachable!()` to limit the scope. use frame_election_provider_support::Weight; From c816fae3580b33ada5d2dc6ade117c1ef56b5caa Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 9 Oct 2025 11:57:32 +0100 Subject: [PATCH 20/20] fresh tests --- ..._election_provider_multi_block_dot_size.rs | 90 +++++++------ ..._election_provider_multi_block_ksm_size.rs | 120 +++++++++--------- ...on_provider_multi_block_signed_dot_size.rs | 58 +++++---- ...on_provider_multi_block_signed_ksm_size.rs | 60 +++++---- ..._provider_multi_block_unsigned_dot_size.rs | 42 +----- ..._provider_multi_block_unsigned_ksm_size.rs | 48 ++----- ..._provider_multi_block_verifier_dot_size.rs | 80 ++++++------ ..._provider_multi_block_verifier_ksm_size.rs | 86 ++++++------- 8 files changed, 267 insertions(+), 317 deletions(-) diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs index c5ae4c1d8e619..c8fe9be1ce0c7 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_dot_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-17, STEPS: `5`, REPEAT: `5`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,9 +39,9 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 5 +// 10 // --genesis-builder-preset // fake-dot // --template @@ -67,23 +67,21 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) fn per_block_nothing() -> Weight { // Proof Size summary in bytes: - // Measured: `250` - // Estimated: `3715` - // Minimum execution time: 24_100_000 picoseconds. - Weight::from_parts(25_330_000, 3715) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `118` + // Estimated: `1603` + // Minimum execution time: 11_890_000 picoseconds. + Weight::from_parts(12_290_000, 1603) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `Staking::ValidatorCount` (r:1 w:0) /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) @@ -94,10 +92,6 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `Staking::Validators` (r:2001 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElection::DesiredTargets` (r:0 w:1) /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshotHash` (r:0 w:1) @@ -106,17 +100,19 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(64026), added: 66501, mode: `Measured`) fn per_block_snapshot_msp() -> Weight { // Proof Size summary in bytes: - // Measured: `95465` - // Estimated: `5048930` - // Minimum execution time: 18_878_131_000 picoseconds. - Weight::from_parts(18_983_212_000, 5048930) - .saturating_add(T::DbWeight::get().reads(2009_u64)) + // Measured: `95360` + // Estimated: `5048825` + // Minimum execution time: 17_142_277_000 picoseconds. + Weight::from_parts(17_250_897_000, 5048825) + .saturating_add(T::DbWeight::get().reads(2008_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) /// Storage: `Staking::VoterSnapshotStatus` (r:1 w:1) @@ -137,10 +133,6 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `Staking::MinimumActiveStake` (r:0 w:1) /// Proof: `Staking::MinimumActiveStake` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`) /// Storage: `VoterList::Lock` (r:0 w:1) @@ -151,11 +143,11 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) fn per_block_snapshot_rest() -> Weight { // Proof Size summary in bytes: - // Measured: `1449068` - // Estimated: `3194933` - // Minimum execution time: 45_723_834_000 picoseconds. - Weight::from_parts(45_910_816_000, 3194933) - .saturating_add(T::DbWeight::get().reads(3084_u64)) + // Measured: `1448963` + // Estimated: `3194828` + // Minimum execution time: 45_863_295_000 picoseconds. + Weight::from_parts(46_462_736_000, 3194828) + .saturating_add(T::DbWeight::get().reads(3083_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) @@ -164,15 +156,19 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) fn per_block_start_signed_validation() -> Weight { // Proof Size summary in bytes: - // Measured: `444` - // Estimated: `3909` - // Minimum execution time: 3_711_197_000 picoseconds. - Weight::from_parts(3_810_718_000, 3909) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `586` + // Estimated: `4051` + // Minimum execution time: 74_560_000 picoseconds. + Weight::from_parts(89_270_000, 4051) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) @@ -200,13 +196,13 @@ impl crate::weights::traits::pallet_election_provider_m /// Storage: `Staking::ErasValidatorPrefs` (r:0 w:491) /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `Measured`) /// Storage: `Staking::ErasStakersPaged` (r:0 w:490) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(3152), added: 5627, mode: `Measured`) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(24656), added: 27131, mode: `Measured`) fn export_non_terminal() -> Weight { // Proof Size summary in bytes: // Measured: `167757` // Estimated: `1383972` - // Minimum execution time: 13_949_429_000 picoseconds. - Weight::from_parts(13_983_218_000, 1383972) + // Minimum execution time: 14_054_590_000 picoseconds. + Weight::from_parts(14_923_170_000, 1383972) .saturating_add(T::DbWeight::get().reads(991_u64)) .saturating_add(T::DbWeight::get().writes(1475_u64)) } @@ -236,8 +232,8 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `Staking::ElectableStashes` (`max_values`: Some(1), `max_size`: Some(32002), added: 32497, mode: `Measured`) /// Storage: `Staking::ErasStakersOverview` (r:310 w:310) /// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `Measured`) - /// Storage: `Staking::ErasStakersPaged` (r:310 w:345) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(3152), added: 5627, mode: `Measured`) + /// Storage: `Staking::ErasStakersPaged` (r:310 w:310) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(24656), added: 27131, mode: `Measured`) /// Storage: `Staking::ErasTotalStake` (r:1 w:1) /// Proof: `Staking::ErasTotalStake` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `Measured`) /// Storage: `Staking::Validators` (r:310 w:0) @@ -252,18 +248,18 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) fn export_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `770035` - // Estimated: `1538275` - // Minimum execution time: 18_379_354_000 picoseconds. - Weight::from_parts(19_010_697_000, 1538275) + // Measured: `1734835` + // Estimated: `2503075` + // Minimum execution time: 17_499_059_000 picoseconds. + Weight::from_parts(19_255_420_000, 2503075) .saturating_add(T::DbWeight::get().reads(1036_u64)) - .saturating_add(T::DbWeight::get().writes(1071_u64)) + .saturating_add(T::DbWeight::get().writes(1036_u64)) } fn manage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 280_000 picoseconds. - Weight::from_parts(290_000, 0) + // Minimum execution time: 270_000 picoseconds. + Weight::from_parts(310_000, 0) } } diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs index 501419118ccdc..6fb8105bf8b51 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_ksm_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-17, STEPS: `5`, REPEAT: `5`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,9 +39,9 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 5 +// 10 // --genesis-builder-preset // fake-ksm // --template @@ -67,23 +67,21 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) fn per_block_nothing() -> Weight { // Proof Size summary in bytes: - // Measured: `250` - // Estimated: `3715` - // Minimum execution time: 24_070_000 picoseconds. - Weight::from_parts(25_070_000, 3715) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `118` + // Estimated: `1603` + // Minimum execution time: 11_830_000 picoseconds. + Weight::from_parts(12_020_000, 1603) + .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `Staking::ValidatorCount` (r:1 w:0) /// Proof: `Staking::ValidatorCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) @@ -92,31 +90,29 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Storage: `Staking::CounterForValidators` (r:1 w:0) /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: `Staking::Validators` (r:4001 w:0) + /// Storage: `Staking::Validators` (r:2501 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElection::DesiredTargets` (r:0 w:1) /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshotHash` (r:0 w:1) /// Proof: `MultiBlockElection::PagedTargetSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:0 w:1) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(80026), added: 82501, mode: `Measured`) fn per_block_snapshot_msp() -> Weight { // Proof Size summary in bytes: - // Measured: `189963` - // Estimated: `10093428` - // Minimum execution time: 41_110_812_000 picoseconds. - Weight::from_parts(41_368_864_000, 10093428) - .saturating_add(T::DbWeight::get().reads(4009_u64)) + // Measured: `119137` + // Estimated: `6310102` + // Minimum execution time: 21_947_065_000 picoseconds. + Weight::from_parts(22_112_625_000, 6310102) + .saturating_add(T::DbWeight::get().reads(2508_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) + /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) /// Storage: `Staking::VoterSnapshotStatus` (r:1 w:1) @@ -137,10 +133,6 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) - /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `Staking::MinimumActiveStake` (r:0 w:1) /// Proof: `Staking::MinimumActiveStake` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `Measured`) /// Storage: `VoterList::Lock` (r:0 w:1) @@ -151,11 +143,11 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) fn per_block_snapshot_rest() -> Weight { // Proof Size summary in bytes: - // Measured: `1370478` - // Estimated: `3309393` - // Minimum execution time: 55_933_967_000 picoseconds. - Weight::from_parts(56_210_319_000, 3309393) - .saturating_add(T::DbWeight::get().reads(3590_u64)) + // Measured: `1370373` + // Estimated: `3309288` + // Minimum execution time: 50_135_617_000 picoseconds. + Weight::from_parts(50_591_808_000, 3309288) + .saturating_add(T::DbWeight::get().reads(3589_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) @@ -164,15 +156,19 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElection::Round` (r:1 w:0) + /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) fn per_block_start_signed_validation() -> Weight { // Proof Size summary in bytes: - // Measured: `444` - // Estimated: `3909` - // Minimum execution time: 202_762_000 picoseconds. - Weight::from_parts(2_761_480_000, 3909) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `586` + // Estimated: `4051` + // Minimum execution time: 84_170_000 picoseconds. + Weight::from_parts(88_100_000, 4051) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) @@ -191,24 +187,24 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `Staking::ElectableStashes` (r:1 w:1) /// Proof: `Staking::ElectableStashes` (`max_values`: Some(1), `max_size`: Some(32002), added: 32497, mode: `Measured`) - /// Storage: `Staking::ErasStakersOverview` (r:792 w:792) + /// Storage: `Staking::ErasStakersOverview` (r:773 w:773) /// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `Measured`) /// Storage: `Staking::ErasTotalStake` (r:1 w:1) /// Proof: `Staking::ErasTotalStake` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `Measured`) - /// Storage: `Staking::Validators` (r:792 w:0) + /// Storage: `Staking::Validators` (r:773 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) - /// Storage: `Staking::ErasValidatorPrefs` (r:0 w:792) + /// Storage: `Staking::ErasValidatorPrefs` (r:0 w:773) /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `Measured`) - /// Storage: `Staking::ErasStakersPaged` (r:0 w:740) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(3152), added: 5627, mode: `Measured`) + /// Storage: `Staking::ErasStakersPaged` (r:0 w:723) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(24656), added: 27131, mode: `Measured`) fn export_non_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `233920` - // Estimated: `2195110` - // Minimum execution time: 24_478_931_000 picoseconds. - Weight::from_parts(24_520_800_000, 2195110) - .saturating_add(T::DbWeight::get().reads(1593_u64)) - .saturating_add(T::DbWeight::get().writes(2327_u64)) + // Measured: `195526` + // Estimated: `2109691` + // Minimum execution time: 22_310_257_000 picoseconds. + Weight::from_parts(22_452_856_000, 2109691) + .saturating_add(T::DbWeight::get().reads(1555_u64)) + .saturating_add(T::DbWeight::get().writes(2272_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) @@ -227,43 +223,43 @@ impl crate::weights::traits::pallet_election_provider_m /// Storage: `MultiBlockElection::PagedVoterSnapshotHash` (r:16 w:16) /// Proof: `MultiBlockElection::PagedVoterSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:1) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(80026), added: 82501, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshotHash` (r:1 w:1) /// Proof: `MultiBlockElection::PagedTargetSnapshotHash` (`max_values`: None, `max_size`: Some(56), added: 2531, mode: `Measured`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `Staking::ElectableStashes` (r:1 w:1) /// Proof: `Staking::ElectableStashes` (`max_values`: Some(1), `max_size`: Some(32002), added: 32497, mode: `Measured`) - /// Storage: `Staking::ErasStakersOverview` (r:580 w:580) + /// Storage: `Staking::ErasStakersOverview` (r:571 w:571) /// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `Measured`) - /// Storage: `Staking::ErasStakersPaged` (r:580 w:580) - /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(3152), added: 5627, mode: `Measured`) + /// Storage: `Staking::ErasStakersPaged` (r:571 w:571) + /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: Some(24656), added: 27131, mode: `Measured`) /// Storage: `Staking::ErasTotalStake` (r:1 w:1) /// Proof: `Staking::ErasTotalStake` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `Measured`) - /// Storage: `Staking::Validators` (r:580 w:0) + /// Storage: `Staking::Validators` (r:571 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionScore` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionScore` (`max_values`: None, `max_size`: Some(60), added: 2535, mode: `Measured`) - /// Storage: `Staking::ErasValidatorPrefs` (r:0 w:580) + /// Storage: `Staking::ErasValidatorPrefs` (r:0 w:571) /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `Measured`) /// Storage: `MultiBlockElection::DesiredTargets` (r:0 w:1) /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) fn export_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1168790` - // Estimated: `2605280` - // Minimum execution time: 31_737_516_000 picoseconds. - Weight::from_parts(31_793_526_000, 2605280) - .saturating_add(T::DbWeight::get().reads(1798_u64)) - .saturating_add(T::DbWeight::get().writes(1798_u64)) + // Measured: `1079027` + // Estimated: `2493242` + // Minimum execution time: 29_991_252_000 picoseconds. + Weight::from_parts(30_181_686_000, 2493242) + .saturating_add(T::DbWeight::get().reads(1771_u64)) + .saturating_add(T::DbWeight::get().writes(1771_u64)) } fn manage() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 250_000 picoseconds. - Weight::from_parts(300_000, 0) + // Minimum execution time: 280_000 picoseconds. + Weight::from_parts(310_000, 0) } } diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_dot_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_dot_size.rs index 1ec37eea09351..3b9ba5345e680 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_dot_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_dot_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-17, STEPS: `5`, REPEAT: `5`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,9 +39,9 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 5 +// 10 // --genesis-builder-preset // fake-dot // --template @@ -65,6 +65,8 @@ pub struct WeightInfo(PhantomData); impl crate::weights::traits::pallet_election_provider_multi_block_signed::WeightInfo for WeightInfo { /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) @@ -79,13 +81,15 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `3312` // Estimated: `6777` - // Minimum execution time: 143_730_000 picoseconds. - Weight::from_parts(146_621_000, 6777) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 130_211_000 picoseconds. + Weight::from_parts(131_911_000, 6777) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) @@ -102,9 +106,9 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `7846` // Estimated: `88036` - // Minimum execution time: 345_252_000 picoseconds. - Weight::from_parts(348_112_000, 88036) - .saturating_add(T::DbWeight::get().reads(39_u64)) + // Minimum execution time: 314_814_000 picoseconds. + Weight::from_parts(323_504_000, 88036) + .saturating_add(T::DbWeight::get().reads(40_u64)) .saturating_add(T::DbWeight::get().writes(37_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) @@ -115,6 +119,8 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -125,9 +131,9 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `3845` // Estimated: `7310` - // Minimum execution time: 5_672_789_000 picoseconds. - Weight::from_parts(6_445_424_000, 7310) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Minimum execution time: 313_002_000 picoseconds. + Weight::from_parts(329_092_000, 7310) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) @@ -138,6 +144,8 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -148,9 +156,9 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `6737` // Estimated: `10202` - // Minimum execution time: 8_071_243_000 picoseconds. - Weight::from_parts(8_089_732_000, 10202) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Minimum execution time: 262_482_000 picoseconds. + Weight::from_parts(288_781_000, 10202) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) @@ -171,8 +179,8 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `4777` // Estimated: `84967` - // Minimum execution time: 234_231_000 picoseconds. - Weight::from_parts(240_031_000, 84967) + // Minimum execution time: 204_581_000 picoseconds. + Weight::from_parts(206_781_000, 84967) .saturating_add(T::DbWeight::get().reads(38_u64)) .saturating_add(T::DbWeight::get().writes(35_u64)) } @@ -188,16 +196,18 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// The range of component `p` is `[1, 32]`. fn clear_old_round_data(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3767 + p * (32 ±0)` - // Estimated: `7232 + p * (2507 ±0)` - // Minimum execution time: 143_121_000 picoseconds. - Weight::from_parts(141_105_005, 7232) - // Standard Error: 44_586 - .saturating_add(Weight::from_parts(1_987_686, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Measured: `3769 + p * (32 ±0)` + // Estimated: `7234 + p * (2507 ±0)` + // Minimum execution time: 128_480_000 picoseconds. + Weight::from_parts(127_828_412, 7234) + // Standard Error: 25_106 + .saturating_add(Weight::from_parts(1_389_687, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_ksm_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_ksm_size.rs index 7719f44f5a439..7d0274e09c49e 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_ksm_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_signed_ksm_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-17, STEPS: `5`, REPEAT: `5`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,9 +39,9 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 5 +// 10 // --genesis-builder-preset // fake-ksm // --template @@ -65,6 +65,8 @@ pub struct WeightInfo(PhantomData); impl crate::weights::traits::pallet_election_provider_multi_block_signed::WeightInfo for WeightInfo { /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) @@ -79,13 +81,15 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `3180` // Estimated: `6645` - // Minimum execution time: 141_781_000 picoseconds. - Weight::from_parts(144_891_000, 6645) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 130_501_000 picoseconds. + Weight::from_parts(132_060_000, 6645) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) @@ -102,9 +106,9 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `7144` // Estimated: `47734` - // Minimum execution time: 303_662_000 picoseconds. - Weight::from_parts(306_382_000, 47734) - .saturating_add(T::DbWeight::get().reads(23_u64)) + // Minimum execution time: 289_301_000 picoseconds. + Weight::from_parts(297_421_000, 47734) + .saturating_add(T::DbWeight::get().reads(24_u64)) .saturating_add(T::DbWeight::get().writes(21_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) @@ -115,6 +119,8 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(165), added: 2640, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -125,9 +131,9 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `3697` // Estimated: `7162` - // Minimum execution time: 2_316_144_000 picoseconds. - Weight::from_parts(2_483_425_000, 7162) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Minimum execution time: 286_851_000 picoseconds. + Weight::from_parts(298_461_000, 7162) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) @@ -138,6 +144,8 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(165), added: 2640, mode: `Measured`) /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) @@ -146,11 +154,11 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(50064), added: 52539, mode: `Measured`) fn unset_page() -> Weight { // Proof Size summary in bytes: - // Measured: `8620` - // Estimated: `12085` - // Minimum execution time: 2_016_652_000 picoseconds. - Weight::from_parts(2_284_763_000, 12085) - .saturating_add(T::DbWeight::get().reads(7_u64)) + // Measured: `8460` + // Estimated: `11925` + // Minimum execution time: 261_751_000 picoseconds. + Weight::from_parts(266_200_000, 11925) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:0) @@ -171,8 +179,8 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `4110` // Estimated: `44700` - // Minimum execution time: 200_051_000 picoseconds. - Weight::from_parts(201_981_000, 44700) + // Minimum execution time: 180_681_000 picoseconds. + Weight::from_parts(181_711_000, 44700) .saturating_add(T::DbWeight::get().reads(22_u64)) .saturating_add(T::DbWeight::get().writes(19_u64)) } @@ -188,16 +196,18 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:0) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// The range of component `p` is `[1, 16]`. fn clear_old_round_data(p: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3622 + p * (31 ±0)` + // Measured: `3624 + p * (31 ±0)` // Estimated: `7089 + p * (2507 ±0)` - // Minimum execution time: 141_960_000 picoseconds. - Weight::from_parts(142_125_963, 7089) - // Standard Error: 117_080 - .saturating_add(Weight::from_parts(1_784_427, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(5_u64)) + // Minimum execution time: 128_660_000 picoseconds. + Weight::from_parts(128_812_002, 7089) + // Standard Error: 48_513 + .saturating_add(Weight::from_parts(1_276_202, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(p.into()))) diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_dot_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_dot_size.rs index 0eebcb65f1688..3257a91fc3ebc 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_dot_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_dot_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-17, STEPS: `5`, REPEAT: `3`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,16 +39,15 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 3 +// 10 // --genesis-builder-preset // fake-dot // --template // ../../../../../substrate/frame/election-provider-multi-block/src/template.hbs // --heap-pages // 65000 -// --extra // --output // ./pallet_election_provider_multi_block_unsigned_fake-dot.rs @@ -84,8 +83,8 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `378` // Estimated: `3843` - // Minimum execution time: 3_343_638_000 picoseconds. - Weight::from_parts(3_863_700_000, 3843) + // Minimum execution time: 872_562_000 picoseconds. + Weight::from_parts(884_363_000, 3843) .saturating_add(T::DbWeight::get().reads(8_u64)) } /// Storage: UNKNOWN KEY `0x33ed3d010c1fea25c2adbfba9297161f` (r:1 w:0) @@ -116,36 +115,9 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `1451085` // Estimated: `1461975` - // Minimum execution time: 27_632_103_000 picoseconds. - Weight::from_parts(27_843_954_000, 1461975) + // Minimum execution time: 21_018_046_000 picoseconds. + Weight::from_parts(21_116_907_000, 1461975) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `MultiBlockElection::Round` (r:1 w:0) - /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) - /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(64026), added: 66501, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) - /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:32 w:0) - /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(388785), added: 391260, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// The range of component `p` is `[1, 32]`. - fn mine_solution(p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `0 + p * (360895 ±0)` - // Estimated: `332140 + p * (348312 ±2_731)` - // Minimum execution time: 926_273_131_000 picoseconds. - Weight::from_parts(926_273_131_000, 332140) - // Standard Error: 303_324_142_965 - .saturating_add(Weight::from_parts(6_610_814_674_792, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) - .saturating_add(Weight::from_parts(0, 348312).saturating_mul(p.into())) - } } diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_ksm_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_ksm_size.rs index 1c614472fe91a..2df4273187bb1 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_ksm_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_unsigned_ksm_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-18, STEPS: `5`, REPEAT: `3`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,16 +39,15 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 3 +// 10 // --genesis-builder-preset // fake-ksm // --template // ../../../../../substrate/frame/election-provider-multi-block/src/template.hbs // --heap-pages // 65000 -// --extra // --output // ./pallet_election_provider_multi_block_unsigned_fake-ksm.rs @@ -84,8 +83,8 @@ impl crate::weights::traits::pallet_election_provider_m // Proof Size summary in bytes: // Measured: `378` // Estimated: `3843` - // Minimum execution time: 2_236_486_000 picoseconds. - Weight::from_parts(2_276_596_000, 3843) + // Minimum execution time: 1_127_114_000 picoseconds. + Weight::from_parts(1_133_504_000, 3843) .saturating_add(T::DbWeight::get().reads(8_u64)) } /// Storage: UNKNOWN KEY `0x33ed3d010c1fea25c2adbfba9297161f` (r:1 w:0) @@ -99,7 +98,7 @@ impl crate::weights::traits::pallet_election_provider_m /// Storage: `MultiBlockElectionVerifier::MinimumScore` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::MinimumScore` (`max_values`: Some(1), `max_size`: Some(48), added: 543, mode: `Measured`) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(80026), added: 82501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:4 w:0) @@ -114,38 +113,11 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionVerifier::QueuedSolutionY` (`max_values`: None, `max_size`: Some(37538026), added: 37540501, mode: `Measured`) fn submit_unsigned() -> Weight { // Proof Size summary in bytes: - // Measured: `1440523` - // Estimated: `1451413` - // Minimum execution time: 30_959_432_000 picoseconds. - Weight::from_parts(31_005_092_000, 1451413) + // Measured: `1392523` + // Estimated: `1403413` + // Minimum execution time: 28_725_870_000 picoseconds. + Weight::from_parts(28_893_151_000, 1403413) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } - /// Storage: `MultiBlockElection::Round` (r:1 w:0) - /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) - /// Storage: `MultiBlockElection::DesiredTargets` (r:1 w:0) - /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) - /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:16 w:0) - /// Proof: `MultiBlockElection::PagedVoterSnapshot` (`max_values`: None, `max_size`: Some(431919), added: 434394, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x6f320d44e42312c78638e6c92dff65af` (r:1 w:0) - /// The range of component `p` is `[1, 16]`. - fn mine_solution(p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `39458 + p * (349682 ±0)` - // Estimated: `26136 + p * (352057 ±1_160)` - // Minimum execution time: 3_353_004_496_000 picoseconds. - Weight::from_parts(3_353_004_496_000, 26136) - // Standard Error: 376_745_635_821 - .saturating_add(Weight::from_parts(6_831_608_018_289, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(p.into()))) - .saturating_add(Weight::from_parts(0, 352057).saturating_mul(p.into())) - } } diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs index 4d79816cdd877..129ec315256c6 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_dot_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-17, STEPS: `5`, REPEAT: `5`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,9 +39,9 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 5 +// 10 // --genesis-builder-preset // fake-dot // --template @@ -67,14 +67,14 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(45072), added: 47547, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(64026), added: 66501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) @@ -87,33 +87,31 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) fn verification_valid_non_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `337306` - // Estimated: `340771` - // Minimum execution time: 4_050_122_000 picoseconds. - Weight::from_parts(4_070_462_000, 340771) - .saturating_add(T::DbWeight::get().reads(13_u64)) + // Measured: `337201` + // Estimated: `340666` + // Minimum execution time: 4_365_357_000 picoseconds. + Weight::from_parts(4_431_208_000, 340666) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(45072), added: 47547, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(64026), added: 66501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) @@ -134,31 +132,29 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) fn verification_valid_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1184612` - // Estimated: `1267277` - // Minimum execution time: 17_111_945_000 picoseconds. - Weight::from_parts(17_278_715_000, 1267277) - .saturating_add(T::DbWeight::get().reads(80_u64)) + // Measured: `1184507` + // Estimated: `1267172` + // Minimum execution time: 17_247_679_000 picoseconds. + Weight::from_parts(17_320_580_000, 1267172) + .saturating_add(T::DbWeight::get().reads(79_u64)) .saturating_add(T::DbWeight::get().writes(72_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(45072), added: 47547, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(64026), added: 66501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) @@ -177,31 +173,31 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:31 w:32) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(33794026), added: 33796501, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) fn verification_invalid_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1185633` - // Estimated: `1268298` - // Minimum execution time: 17_293_481_000 picoseconds. - Weight::from_parts(17_381_352_000, 1268298) + // Measured: `1185528` + // Estimated: `1268193` + // Minimum execution time: 17_116_788_000 picoseconds. + Weight::from_parts(17_320_458_000, 1268193) .saturating_add(T::DbWeight::get().reads(110_u64)) - .saturating_add(T::DbWeight::get().writes(101_u64)) + .saturating_add(T::DbWeight::get().writes(102_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:32 w:32) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(45072), added: 47547, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(64026), added: 66501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) @@ -222,21 +218,21 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(181), added: 2656, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// The range of component `v` is `[0, 31]`. fn verification_invalid_non_terminal(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `341548 + v * (4932 ±0)` - // Estimated: `443308 + v * (4988 ±806)` - // Minimum execution time: 1_165_016_000 picoseconds. - Weight::from_parts(1_057_101_975, 443308) - // Standard Error: 4_684_378 - .saturating_add(Weight::from_parts(27_427_295, 0).saturating_mul(v.into())) + // Measured: `353164 + v * (3034 ±0)` + // Estimated: `474195 + v * (2961 ±477)` + // Minimum execution time: 1_267_164_000 picoseconds. + Weight::from_parts(1_223_951_167, 474195) + // Standard Error: 1_944_459 + .saturating_add(Weight::from_parts(21_624_995, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(46_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(v.into()))) - .saturating_add(T::DbWeight::get().writes(37_u64)) + .saturating_add(T::DbWeight::get().writes(38_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(v.into()))) - .saturating_add(Weight::from_parts(0, 4988).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(0, 2961).saturating_mul(v.into())) } } diff --git a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs index 4f42bbe341643..c4e27336f53eb 100644 --- a/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs +++ b/substrate/frame/election-provider-multi-block/src/weights/pallet_election_provider_multi_block_verifier_ksm_size.rs @@ -22,7 +22,7 @@ // ! we don't want to generate the `trait WeightInfo`. //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2025-06-17, STEPS: `5`, REPEAT: `5`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2025-10-08, STEPS: `10`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `ggwpez-ref-hw`, CPU: `AMD EPYC 7232P 8-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` @@ -39,9 +39,9 @@ // --runtime // ../../../../../target/release/wbuild/pallet-staking-async-parachain-runtime/pallet_staking_async_parachain_runtime.compact.wasm // --steps -// 5 +// 10 // --repeat -// 5 +// 10 // --genesis-builder-preset // fake-ksm // --template @@ -67,16 +67,16 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:1 w:0) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(50064), added: 52539, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(80026), added: 82501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) @@ -87,35 +87,33 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElection::DesiredTargets` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedValidVariant` (r:1 w:0) /// Proof: `MultiBlockElectionVerifier::QueuedValidVariant` (`max_values`: None, `max_size`: Some(13), added: 2488, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(37538026), added: 37540501, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionBackings` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionBackings` (`max_values`: None, `max_size`: Some(52026), added: 54501, mode: `Measured`) fn verification_valid_non_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `350585` - // Estimated: `354050` - // Minimum execution time: 8_603_879_000 picoseconds. - Weight::from_parts(8_934_521_000, 354050) - .saturating_add(T::DbWeight::get().reads(13_u64)) + // Measured: `302068` + // Estimated: `305533` + // Minimum execution time: 5_113_427_000 picoseconds. + Weight::from_parts(5_191_017_000, 305533) + .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:16 w:16) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(50064), added: 52539, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(80026), added: 82501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) @@ -134,33 +132,31 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(165), added: 2640, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:0 w:1) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(37538026), added: 37540501, mode: `Measured`) fn verification_valid_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1183276` - // Estimated: `1226341` - // Minimum execution time: 18_426_816_000 picoseconds. - Weight::from_parts(18_490_837_000, 1226341) - .saturating_add(T::DbWeight::get().reads(48_u64)) + // Measured: `1123155` + // Estimated: `1166220` + // Minimum execution time: 17_655_638_000 picoseconds. + Weight::from_parts(17_783_458_000, 1166220) + .saturating_add(T::DbWeight::get().reads(47_u64)) .saturating_add(T::DbWeight::get().writes(40_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:16 w:16) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(50064), added: 52539, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(80026), added: 82501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) @@ -177,33 +173,33 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(165), added: 2640, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::QueuedSolutionX` (r:15 w:16) /// Proof: `MultiBlockElectionVerifier::QueuedSolutionX` (`max_values`: None, `max_size`: Some(37538026), added: 37540501, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) fn verification_invalid_terminal() -> Weight { // Proof Size summary in bytes: - // Measured: `1183625` - // Estimated: `1226690` - // Minimum execution time: 18_057_114_000 picoseconds. - Weight::from_parts(18_334_996_000, 1226690) + // Measured: `1123504` + // Estimated: `1166569` + // Minimum execution time: 17_623_388_000 picoseconds. + Weight::from_parts(18_013_619_000, 1166569) .saturating_add(T::DbWeight::get().reads(62_u64)) - .saturating_add(T::DbWeight::get().writes(53_u64)) + .saturating_add(T::DbWeight::get().writes(54_u64)) } /// Storage: `MultiBlockElection::CurrentPhase` (r:1 w:1) /// Proof: `MultiBlockElection::CurrentPhase` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) /// Storage: `MultiBlockElectionVerifier::StatusStorage` (r:1 w:1) /// Proof: `MultiBlockElectionVerifier::StatusStorage` (`max_values`: Some(1), `max_size`: Some(5), added: 500, mode: `Measured`) + /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) + /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::Round` (r:1 w:0) /// Proof: `MultiBlockElection::Round` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SortedScores` (r:1 w:1) /// Proof: `MultiBlockElectionSigned::SortedScores` (`max_values`: None, `max_size`: Some(653), added: 3128, mode: `Measured`) /// Storage: `MultiBlockElectionSigned::SubmissionStorage` (r:16 w:16) /// Proof: `MultiBlockElectionSigned::SubmissionStorage` (`max_values`: None, `max_size`: Some(50064), added: 52539, mode: `Measured`) - /// Storage: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) - /// Proof: UNKNOWN KEY `0xa143099d7a337c5fd879b91b2b157c2d` (r:1 w:0) /// Storage: `MultiBlockElection::PagedTargetSnapshot` (r:1 w:0) - /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(128026), added: 130501, mode: `Measured`) + /// Proof: `MultiBlockElection::PagedTargetSnapshot` (`max_values`: None, `max_size`: Some(80026), added: 82501, mode: `Measured`) /// Storage: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Proof: UNKNOWN KEY `0x5640fd84ada5e16d1b6739279282536c` (r:1 w:0) /// Storage: `MultiBlockElection::PagedVoterSnapshot` (r:1 w:0) @@ -222,19 +218,21 @@ impl crate::weights::traits::pallet_election_provider_m /// Proof: `MultiBlockElectionSigned::SubmissionMetadataStorage` (`max_values`: None, `max_size`: Some(165), added: 2640, mode: `Measured`) /// Storage: `Balances::Holds` (r:1 w:1) /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(211), added: 2686, mode: `Measured`) - /// Storage: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) - /// Proof: UNKNOWN KEY `0x48384a816e4f71a936cb76dc9e303f2a` (r:1 w:0) + /// Storage: `MultiBlockElectionSigned::Invulnerables` (r:1 w:1) + /// Proof: `MultiBlockElectionSigned::Invulnerables` (`max_values`: Some(1), `max_size`: Some(513), added: 1008, mode: `Measured`) /// The range of component `v` is `[0, 15]`. fn verification_invalid_non_terminal(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `384413 + v * (8974 ±0)` - // Estimated: `502395 + v * (7186 ±2_803)` - // Minimum execution time: 1_502_809_000 picoseconds. - Weight::from_parts(4_607_201_267, 502395) + // Measured: `446823` + // Estimated: `493569 + v * (813 ±1_678)` + // Minimum execution time: 1_320_902_000 picoseconds. + Weight::from_parts(1_471_494_315, 493569) + // Standard Error: 1_870_663 + .saturating_add(Weight::from_parts(13_057_611, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(30_u64)) .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(v.into()))) - .saturating_add(T::DbWeight::get().writes(21_u64)) + .saturating_add(T::DbWeight::get().writes(22_u64)) .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(v.into()))) - .saturating_add(Weight::from_parts(0, 7186).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(0, 813).saturating_mul(v.into())) } }