From dc75e3bdbdf8d83b1fd812698597a6a3829536af Mon Sep 17 00:00:00 2001 From: Manuel Mauro Date: Tue, 14 Jan 2025 13:18:32 +0100 Subject: [PATCH] Fix notify inactive collators failures at the end of a round (#3128) * fix: :bug: call ParachainStaking::on_finalize on mock blocks rolling * fix: :bug: pass correct block number to ParachainStaking::on_finalize * test: :white_check_mark: fix happy path test for notify inactive collator * revert: :fire: remove debug code * feat: :sparkles: add round length-aware block rolling functions * test: :white_check_mark: increase MaxOfflineRounds to 2 to match RewardPaymentDelay * test: :white_check_mark: call ParachainStaking::on_finalize before Balances and System on_finalize * test: :white_check_mark: add test reproducing a bug in notify_inactive_collator * refactor: :fire: remove unused use statement * test: :white_check_mark: minimize changes to mocking framework for ParachainStaking * docs: :memo: improve comment * fix: :bug: add historical staking information * refactor: :recycle: make roll_to_round functions round length-aware * test: :sparkles: improve mock fidelity * refactor: :art: use POINTS_PER_ROUND const in set_author invocations * docs: :memo: restore comments in tests * perf: :zap: use a WasInactive storage to keep track of inactive collators * test: :white_check_mark: fix benchmark test * fix: :bug: update benchmarks * fix: :bug: correctly update weight calculation on mark_collators_as_inactive invocation * refactor: :zap: use a more realistic upper bound to the number of collators in benchmarks * chore: :wrench: compute new weights * test: :white_check_mark: update test with new weights for operations on initialize * perf: :zap: improve estimation of mark_collators_as_inactive weights * test: :white_check_mark: update test test_on_initialize_weights --- pallets/parachain-staking/src/benchmarks.rs | 41 +- pallets/parachain-staking/src/lib.rs | 70 ++- pallets/parachain-staking/src/mock.rs | 31 +- pallets/parachain-staking/src/tests.rs | 451 +++++++++++------- pallets/parachain-staking/src/weights.rs | 45 ++ .../src/weights/pallet_parachain_staking.rs | 22 + .../src/weights/pallet_parachain_staking.rs | 22 + .../src/weights/pallet_parachain_staking.rs | 22 + 8 files changed, 507 insertions(+), 197 deletions(-) diff --git a/pallets/parachain-staking/src/benchmarks.rs b/pallets/parachain-staking/src/benchmarks.rs index d9067aef03..b6e5a2033a 100644 --- a/pallets/parachain-staking/src/benchmarks.rs +++ b/pallets/parachain-staking/src/benchmarks.rs @@ -2275,7 +2275,7 @@ benchmarks! { } notify_inactive_collator { - use crate::{AtStake, CollatorSnapshot, AwardedPts}; + use crate::{WasInactive}; // Blocks per-round must be greater than TotalSelected Pallet::::set_blocks_per_round(RawOrigin::Root.into(), 101u32)?; @@ -2325,11 +2325,8 @@ benchmarks! { // Manually change these values for inactive_collator, // so that it can be marked as inactive. - >::insert(1, &inactive_collator, CollatorSnapshot::default()); - >::insert(1, &inactive_collator, 0); - - >::insert(2, &inactive_collator, CollatorSnapshot::default()); - >::insert(2, &inactive_collator, 0); + >::insert(1, &inactive_collator, ()); + >::insert(2, &inactive_collator, ()); // Enable killswitch >::set(true); @@ -2338,6 +2335,38 @@ benchmarks! { verify { assert!(!Pallet::::candidate_info(&inactive_collator).expect("must exist").is_active()); } + + mark_collators_as_inactive { + let x in 0..50; // num collators + + // must come after 'let foo in 0..` statements for macro + use crate::{AtStake, CollatorSnapshot, AwardedPts}; + + let round = 2; + let prev = round - 1; + + + + for i in 0..x { + let collator = create_funded_collator::( + "collator", + USER_SEED + i, + min_candidate_stk::() * 1_000_000u32.into(), + true, + 999999, + )?; + + // All collators were inactinve in previous round + >::insert(prev, &collator, CollatorSnapshot::default()); + >::insert(prev, &collator, 0); + } + + }: { + let cur = 2; + let inactive_info = Pallet::::mark_collators_as_inactive(cur); + } + verify { + } } #[cfg(test)] diff --git a/pallets/parachain-staking/src/lib.rs b/pallets/parachain-staking/src/lib.rs index 7f1a13e177..8730c1cbbc 100644 --- a/pallets/parachain-staking/src/lib.rs +++ b/pallets/parachain-staking/src/lib.rs @@ -489,6 +489,8 @@ pub mod pallet { selected_collators_number: collator_count, total_balance: total_staked, }); + // record inactive collators + weight = weight.saturating_add(Self::mark_collators_as_inactive(round.current)); // account for Round write weight = weight.saturating_add(T::DbWeight::get().reads_writes(0, 1)); } else { @@ -496,13 +498,14 @@ pub mod pallet { } // add on_finalize weight - // read: Author, Points, AwardedPts - // write: Points, AwardedPts - weight = weight.saturating_add(T::DbWeight::get().reads_writes(3, 2)); + // read: Author, Points, AwardedPts, WasInactive + // write: Points, AwardedPts, WasInactive + weight = weight.saturating_add(T::DbWeight::get().reads_writes(4, 3)); weight } fn on_finalize(_n: BlockNumberFor) { Self::award_points_to_block_author(); + Self::cleanup_inactive_collator_info(); } } @@ -643,6 +646,13 @@ pub mod pallet { OptionQuery, >; + #[pallet::storage] + #[pallet::getter(fn was_inactive)] + /// Records collators' inactivity. + /// Data persists for MaxOfflineRounds + 1 rounds before being pruned. + pub type WasInactive = + StorageDoubleMap<_, Twox64Concat, RoundIndex, Twox64Concat, T::AccountId, (), OptionQuery>; + #[pallet::storage] #[pallet::getter(fn delayed_payouts)] /// Delayed payouts @@ -1417,17 +1427,9 @@ pub mod pallet { // the collator should be notified as inactive let mut inactive_counter: RoundIndex = 0u32; - // Iter rounds to check - // - // - The collator has AtStake associated and their AwardedPts are zero - // - // If the previous condition is met in all rounds of rounds_to_check, - // the collator is notified as inactive + // Iter rounds and check whether the collator has been inactive for r in rounds_to_check { - let stake = >::get(r, &collator); - let pts = >::get(r, &collator); - - if stake.is_some() && pts.is_zero() { + if >::get(r, &collator).is_some() { inactive_counter = inactive_counter.saturating_add(1); } } @@ -1704,8 +1706,8 @@ pub mod pallet { let return_stake = |bond: Bond>| { // remove delegation from delegator state let mut delegator = DelegatorState::::get(&bond.owner).expect( - "Collator state and delegator state are consistent. - Collator state has a record of this delegation. Therefore, + "Collator state and delegator state are consistent. + Collator state has a record of this delegation. Therefore, Delegator state also has a record. qed.", ); @@ -2333,11 +2335,9 @@ pub mod pallet { }); }; } - } - /// Add reward points to block authors: - /// * 20 points to the block producer for producing a block in the chain - impl Pallet { + /// Add reward points to block authors: + /// * 20 points to the block producer for producing a block in the chain fn award_points_to_block_author() { let author = T::BlockAuthor::get(); let now = >::get().current; @@ -2345,6 +2345,38 @@ pub mod pallet { >::insert(now, author, score_plus_20); >::mutate(now, |x| *x = x.saturating_add(20)); } + + /// Marks collators as inactive for the previous round if they received zero awarded points. + pub fn mark_collators_as_inactive(cur: RoundIndex) -> Weight { + // This function is called after round index increment, + // We don't need to saturate here because the genesis round is 1. + let prev = cur - 1; + + let mut collators_at_stake_count = 0u32; + for (account, _) in >::iter_prefix(prev) { + collators_at_stake_count = collators_at_stake_count.saturating_add(1u32); + if >::get(prev, &account).is_zero() { + >::insert(prev, account, ()); + } + } + + ::WeightInfo::mark_collators_as_inactive(collators_at_stake_count) + } + + /// Cleans up historical staking information that is older than MaxOfflineRounds + /// by removing entries from the WasIactive storage map. + fn cleanup_inactive_collator_info() { + let now = >::get().current; + let minimum_rounds_required = T::MaxOfflineRounds::get() + 1; + + if now < minimum_rounds_required { + return; + } + + let _ = >::iter_prefix(now - minimum_rounds_required) + .drain() + .next(); + } } impl nimbus_primitives::CanAuthor for Pallet { diff --git a/pallets/parachain-staking/src/mock.rs b/pallets/parachain-staking/src/mock.rs index 703effac14..4079b56f54 100644 --- a/pallets/parachain-staking/src/mock.rs +++ b/pallets/parachain-staking/src/mock.rs @@ -116,9 +116,13 @@ const GENESIS_BLOCKS_PER_ROUND: BlockNumber = 5; const GENESIS_COLLATOR_COMMISSION: Perbill = Perbill::from_percent(20); const GENESIS_PARACHAIN_BOND_RESERVE_PERCENT: Percent = Percent::from_percent(30); const GENESIS_NUM_SELECTED_CANDIDATES: u32 = 5; + +pub const POINTS_PER_BLOCK: u32 = 20; +pub const POINTS_PER_ROUND: u32 = GENESIS_BLOCKS_PER_ROUND * POINTS_PER_BLOCK; + parameter_types! { pub const MinBlocksPerRound: u32 = 3; - pub const MaxOfflineRounds: u32 = 1; + pub const MaxOfflineRounds: u32 = 2; pub const LeaveCandidatesDelay: u32 = 2; pub const CandidateBondLessDelay: u32 = 2; pub const LeaveDelegatorsDelay: u32 = 2; @@ -278,6 +282,7 @@ impl ExtBuilder { /// Rolls forward one block. Returns the new block number. fn roll_one_block() -> BlockNumber { + ParachainStaking::on_finalize(System::block_number()); Balances::on_finalize(System::block_number()); System::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); @@ -312,15 +317,31 @@ pub(crate) fn roll_blocks(num_blocks: u32) -> BlockNumber { /// This will complete the block in which the round change occurs. /// Returns the number of blocks played. pub(crate) fn roll_to_round_begin(round: BlockNumber) -> BlockNumber { - let block = (round - 1) * GENESIS_BLOCKS_PER_ROUND; - roll_to(block) + let r = ParachainStaking::round(); + + // Return 0 if target round has already passed + if round < r.current + 1 { + return 0; + } + + // Calculate target block by adding round length for each round difference + let target = r.first + (round - r.current) * r.length; + roll_to(target) } /// Rolls block-by-block to the end of the specified round. /// The block following will be the one in which the specified round change occurs. pub(crate) fn roll_to_round_end(round: BlockNumber) -> BlockNumber { - let block = round * GENESIS_BLOCKS_PER_ROUND - 1; - roll_to(block) + let r = ParachainStaking::round(); + + // Return 0 if target round has already passed + if round < r.current { + return 0; + } + + // Calculate target block by adding round length for each round difference + let target = r.first + (round - r.current + 1) * r.length - 1; + roll_to(target) } pub(crate) fn inflation_configs( diff --git a/pallets/parachain-staking/src/tests.rs b/pallets/parachain-staking/src/tests.rs index fd034e7345..acc6841f75 100644 --- a/pallets/parachain-staking/src/tests.rs +++ b/pallets/parachain-staking/src/tests.rs @@ -27,15 +27,16 @@ use crate::delegation_requests::{CancelledScheduledRequest, DelegationAction, Sc use crate::mock::{ inflation_configs, roll_blocks, roll_to, roll_to_round_begin, roll_to_round_end, set_author, set_block_author, AccountId, Balances, BlockNumber, ExtBuilder, ParachainStaking, RuntimeEvent, - RuntimeOrigin, Test, + RuntimeOrigin, Test, POINTS_PER_BLOCK, POINTS_PER_ROUND, }; use crate::{ assert_events_emitted, assert_events_emitted_match, assert_events_eq, assert_no_events, AtStake, Bond, CollatorStatus, DelegationScheduledRequests, DelegatorAdded, - EnableMarkingOffline, Error, Event, InflationDistributionInfo, Range, DELEGATOR_LOCK_ID, + EnableMarkingOffline, Error, Event, InflationDistributionInfo, Range, WasInactive, + DELEGATOR_LOCK_ID, }; use frame_support::traits::{Currency, ExistenceRequirement, WithdrawReasons}; -use frame_support::{assert_err, assert_noop, assert_ok, pallet_prelude::*, BoundedVec}; +use frame_support::{assert_err, assert_noop, assert_ok, BoundedVec}; use pallet_balances::{Event as BalancesEvent, PositiveImbalance}; use sp_runtime::{traits::Zero, DispatchError, ModuleError, Perbill, Percent}; // ~~ ROOT ~~ @@ -1173,8 +1174,78 @@ fn enable_marking_offline_fails_bad_origin() { }); } +#[test] +fn was_inactive_is_cleaned_up_after_max_offline_rounds() { + const ACTIVE_COLLATOR: AccountId = 1; + const INACTIVE_COLLATOR: AccountId = 2; + + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20)]) + .with_candidates(vec![(1, 20), (2, 20)]) + .build() + .execute_with(|| { + assert_eq!(::MaxOfflineRounds::get(), 2); + assert_eq!(::RewardPaymentDelay::get(), 2); + + // ACTIVE_COLLATOR authors all the blocks + set_block_author(ACTIVE_COLLATOR); + + // Round 2 + roll_to_round_begin(2); + + assert!(>::contains_key(1, ACTIVE_COLLATOR)); + assert!(!>::contains_key(1, ACTIVE_COLLATOR)); + + assert!(>::contains_key(1, INACTIVE_COLLATOR)); + assert!(>::contains_key(1, INACTIVE_COLLATOR)); + + // Round 3 + roll_to_round_begin(3); + + assert!(>::contains_key(2, ACTIVE_COLLATOR)); + assert!(!>::contains_key(2, ACTIVE_COLLATOR)); + + assert!(>::contains_key(2, INACTIVE_COLLATOR)); + assert!(>::contains_key(2, INACTIVE_COLLATOR)); + + // End of round 3 + roll_to_round_end(3); + + assert!( + !>::contains_key(1, ACTIVE_COLLATOR), + "Active collator should have no stake in round 1 due to the distribution of rewards" + ); + assert!( + !>::contains_key(1, INACTIVE_COLLATOR), + "Inactive collator should have no stake in round 1 due to the distribution of rewards" + ); + + assert!( + !>::contains_key(1, ACTIVE_COLLATOR), + "Active collator should not be in WasInactive for round 1" + ); + assert!( + >::contains_key(1, INACTIVE_COLLATOR), + "Inactive collator should still be in WasInactive for round 1" + ); + + // Round 4 + roll_to_round_end(4); + + assert!( + !>::contains_key(1, INACTIVE_COLLATOR), + "Round 1 WasInactive should be cleaned up after MaxOfflineRounds" + ); + assert!(>::contains_key(2, INACTIVE_COLLATOR)); + assert!(>::contains_key(3, INACTIVE_COLLATOR)); + }); +} + #[test] fn notify_inactive_collator_works() { + const INACTIVE_COLLATOR: AccountId = 1; + const ACTIVE_COLLATOR: AccountId = 2; + ExtBuilder::default() .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) @@ -1183,38 +1254,91 @@ fn notify_inactive_collator_works() { // Enable killswitch >::set(true); - // Round 2 + assert_eq!(::MaxOfflineRounds::get(), 2); + assert_eq!(::RewardPaymentDelay::get(), 2); + + // Round 2 - INACTIVE_COLLATOR authors blocks + set_block_author(INACTIVE_COLLATOR); roll_to_round_begin(2); // Change block author - set_block_author(1); + set_block_author(ACTIVE_COLLATOR); - // Finalize the first block of round 2 - ParachainStaking::on_finalize(5); - - // We don't produce blocks on round 3 - roll_to_round_begin(3); + // INACTIVE_COLLATOR does not produce blocks on round 2 and 3 + roll_to_round_begin(4); roll_blocks(1); - // We don't produce blocks on round 4 - roll_to_round_begin(4); + // On round 4 notify inactive collator + assert_ok!(ParachainStaking::notify_inactive_collator( + RuntimeOrigin::signed(1), + INACTIVE_COLLATOR + )); + + // Check the collator was marked as offline as it hasn't produced blocks + assert_events_eq!(Event::CandidateWentOffline { + candidate: INACTIVE_COLLATOR + },); + }); +} + +#[test] +fn notify_inactive_collator_succeeds_even_after_rewards_are_distributed() { + const INACTIVE_COLLATOR: AccountId = 1; + const ACTIVE_COLLATOR: AccountId = 2; + + ExtBuilder::default() + .with_balances(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .with_candidates(vec![(1, 20), (2, 20), (3, 20), (4, 20), (5, 20)]) + .build() + .execute_with(|| { + // Enable killswitch + >::set(true); + + // We need (strictly) more blocks per round than collators so rewards + // can be distributed before the end of a round + assert_ok!(ParachainStaking::set_blocks_per_round( + RuntimeOrigin::root(), + 6u32 + )); + + // ACTIVE_COLLATOR authors all the blocks while INACTIVE_COLLATOR stays inactive + set_block_author(ACTIVE_COLLATOR); + + // Round 2 + roll_to_round_begin(2); roll_blocks(1); - // Round 6 - notify the collator as inactive - roll_to_round_begin(6); + // INACTIVE_COLLATOR has a stake in round 1 + assert!(>::contains_key(1, INACTIVE_COLLATOR)); + + // Round 3 + roll_to_round_begin(3); roll_blocks(1); - assert_eq!(::MaxOfflineRounds::get(), 1); - assert_eq!(::RewardPaymentDelay::get(), 2); + // INACTIVE_COLLATOR has a stake in round 2 + assert!(>::contains_key(2, INACTIVE_COLLATOR)); - // Call 'notify_inactive_collator' extrinsic + // End of round 3 + roll_to_round_end(3); + + // INACTIVE_COLLATOR has a no stake in round 1 anymore due to the distribution of rewards + assert!(!>::contains_key(1, INACTIVE_COLLATOR)); + + // Call 'notify_inactive_collator' extrinsic on INACTIVE_COLLATOR assert_ok!(ParachainStaking::notify_inactive_collator( RuntimeOrigin::signed(1), - 1 + INACTIVE_COLLATOR )); - // Check the collator was marked as offline as it hasn't produced blocks - assert_events_eq!(Event::CandidateWentOffline { candidate: 1 },); + assert_events_eq!( + Event::Rewarded { + account: 2, + rewards: 0, + }, + Event::CandidateWentOffline { + candidate: INACTIVE_COLLATOR + }, + ); }); } @@ -1356,16 +1480,10 @@ fn notify_inactive_collator_fails_cannot_be_notified_as_inactive() { // Change block author set_block_author(1); - // Finalize the first block of round 2 - ParachainStaking::on_finalize(5); - // Round 3 roll_to_round_begin(3); roll_blocks(1); - // Finalize a block of round 3 - ParachainStaking::on_finalize(11); - // Round 4 roll_to_round_begin(4); roll_blocks(1); @@ -4147,14 +4265,14 @@ fn parachain_bond_inflation_reserve_matches_config() { ); assert_eq!(Balances::free_balance(&11), 1); // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); + set_author(2, 1, POINTS_PER_ROUND); roll_to_round_begin(4); // distribute total issuance to collator 1 and its delegators 6, 7, 19 assert_eq!(Balances::free_balance(&11), 16); - // ~ set block author as 1 for all blocks this round - set_author(3, 1, 100); - set_author(4, 1, 100); - set_author(5, 1, 100); + // ~ set block author as 1 for all blocks in rounds 3, 4, and 5 + set_author(3, 1, POINTS_PER_ROUND); + set_author(4, 1, POINTS_PER_ROUND); + set_author(5, 1, POINTS_PER_ROUND); // 1. ensure delegators are paid for 2 rounds after they leave assert_noop!( ParachainStaking::schedule_revoke_delegation(RuntimeOrigin::signed(66), 1), @@ -4443,7 +4561,7 @@ fn parachain_bond_inflation_reserve_matches_config() { new: inflation_configs(11, 50, 0, 0), }); // 6 won't be paid for this round because they left already - set_author(6, 1, 100); + set_author(6, 1, POINTS_PER_ROUND); roll_to_round_begin(8); // keep paying 6 assert_events_eq!( @@ -4505,7 +4623,7 @@ fn parachain_bond_inflation_reserve_matches_config() { }, ); assert_eq!(Balances::free_balance(&11), 95); - set_author(7, 1, 100); + set_author(7, 1, POINTS_PER_ROUND); roll_to_round_begin(9); // no more paying 6 assert_events_eq!( @@ -4567,7 +4685,7 @@ fn parachain_bond_inflation_reserve_matches_config() { }, ); assert_eq!(Balances::free_balance(&11), 127); - set_author(8, 1, 100); + set_author(8, 1, POINTS_PER_ROUND); roll_blocks(1); assert_ok!(ParachainStaking::delegate( RuntimeOrigin::signed(8), @@ -4644,8 +4762,8 @@ fn parachain_bond_inflation_reserve_matches_config() { }, ); assert_eq!(Balances::free_balance(&11), 160); - set_author(9, 1, 100); - set_author(10, 1, 100); + set_author(9, 1, POINTS_PER_ROUND); + set_author(10, 1, POINTS_PER_ROUND); roll_to_round_begin(11); // new delegation is still not rewarded yet assert_events_eq!( @@ -4867,7 +4985,7 @@ fn paid_collator_commission_matches_config() { }, ); // only reward author with id 4 - set_author(3, 4, 100); + set_author(3, 4, POINTS_PER_ROUND); roll_to_round_begin(5); // 20% of 10 is commission + due_portion (0) = 2 + 4 = 6 // all delegator payouts are 10-2 = 8 * stake_pct @@ -4894,15 +5012,15 @@ fn paid_collator_commission_matches_config() { assert_events_eq!( Event::Rewarded { account: 4, - rewards: 18, + rewards: 9, }, Event::Rewarded { account: 5, - rewards: 6, + rewards: 3, }, Event::Rewarded { account: 6, - rewards: 6, + rewards: 3, }, ); }); @@ -5124,7 +5242,7 @@ fn payout_distribution_to_solo_collators() { }, ); // ~ set block author as 1 for all blocks this round - set_author(2, 1, 100); + set_author(2, 1, POINTS_PER_ROUND); roll_to_round_begin(4); assert_events_eq!( Event::CollatorChosen { @@ -5158,12 +5276,12 @@ fn payout_distribution_to_solo_collators() { roll_blocks(3); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 205, + rewards: 102, }); // ~ set block author as 1 for 3 blocks this round - set_author(4, 1, 60); + set_author(4, 1, POINTS_PER_BLOCK * 3); // ~ set block author as 2 for 2 blocks this round - set_author(4, 2, 40); + set_author(4, 2, POINTS_PER_BLOCK * 2); roll_to_round_begin(6); // pay 60% total issuance to 1 and 40% total issuance to 2 assert_events_eq!( @@ -5197,18 +5315,18 @@ fn payout_distribution_to_solo_collators() { roll_blocks(3); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 129, + rewards: 63, }); roll_blocks(1); assert_events_eq!(Event::Rewarded { account: 2, - rewards: 86, + rewards: 42, },); - // ~ each collator produces 1 block this round - set_author(6, 1, 20); - set_author(6, 2, 20); - set_author(6, 3, 20); - set_author(6, 4, 20); + // ~ each collator produces at least 1 block this round + set_author(6, 1, POINTS_PER_BLOCK * 2); + set_author(6, 2, POINTS_PER_BLOCK); + set_author(6, 3, POINTS_PER_BLOCK); + set_author(6, 4, POINTS_PER_BLOCK); roll_to_round_begin(8); // pay 20% issuance for all collators assert_events_eq!( @@ -5242,22 +5360,22 @@ fn payout_distribution_to_solo_collators() { roll_blocks(1); assert_events_eq!(Event::Rewarded { account: 3, - rewards: 56, + rewards: 21, }); roll_blocks(1); assert_events_eq!(Event::Rewarded { account: 4, - rewards: 56, + rewards: 21, }); roll_blocks(1); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 56, + rewards: 43, }); roll_blocks(1); assert_events_eq!(Event::Rewarded { account: 2, - rewards: 56, + rewards: 21, }); // check that distributing rewards clears awarded pts assert!(ParachainStaking::awarded_pts(1, 1).is_zero()); @@ -5569,8 +5687,8 @@ fn payouts_follow_delegation_changes() { .build() .execute_with(|| { // ~ set block author as 1 for all blocks this round - set_author(1, 1, 100); - set_author(2, 1, 100); + set_author(1, 1, POINTS_PER_ROUND); + set_author(2, 1, POINTS_PER_ROUND); roll_to_round_begin(2); // chooses top TotalSelectedCandidates (5), in order assert_events_eq!( @@ -5602,8 +5720,8 @@ fn payouts_follow_delegation_changes() { }, ); - set_author(3, 1, 100); - set_author(4, 1, 100); + set_author(3, 1, POINTS_PER_ROUND); + set_author(4, 1, POINTS_PER_ROUND); roll_to_round_begin(4); // distribute total issuance to collator 1 and its delegators 6, 7, 19 @@ -5639,23 +5757,23 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 23, + rewards: 11, }, Event::Rewarded { account: 6, - rewards: 7, + rewards: 4, }, Event::Rewarded { account: 7, - rewards: 7, + rewards: 4, }, Event::Rewarded { account: 10, - rewards: 7, + rewards: 4, }, ); // ~ set block author as 1 for all blocks this round - set_author(5, 1, 100); + set_author(5, 1, POINTS_PER_ROUND); roll_blocks(1); // 1. ensure delegators are paid for 2 rounds after they leave @@ -5707,23 +5825,23 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 24, + rewards: 12, }, Event::Rewarded { account: 6, - rewards: 8, + rewards: 4, }, Event::Rewarded { account: 7, - rewards: 8, + rewards: 4, }, Event::Rewarded { account: 10, - rewards: 8, + rewards: 4, }, ); - set_author(6, 1, 100); + set_author(6, 1, POINTS_PER_ROUND); // keep paying 6 (note: inflation is in terms of total issuance so that's why 1 is 21) roll_to_round_begin(6); assert_ok!(ParachainStaking::execute_delegation_request( @@ -5778,23 +5896,23 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 26, + rewards: 12, }, Event::Rewarded { account: 6, - rewards: 8, + rewards: 4, }, Event::Rewarded { account: 7, - rewards: 8, + rewards: 4, }, Event::Rewarded { account: 10, - rewards: 8, + rewards: 4, }, ); // 6 won't be paid for this round because they left already - set_author(7, 1, 100); + set_author(7, 1, POINTS_PER_ROUND); roll_to_round_begin(7); // keep paying 6 assert_events_eq!( @@ -5829,18 +5947,18 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 31, + rewards: 14, }, Event::Rewarded { account: 7, - rewards: 10, + rewards: 5, }, Event::Rewarded { account: 10, - rewards: 10, + rewards: 5, }, ); - set_author(8, 1, 100); + set_author(8, 1, POINTS_PER_ROUND); roll_to_round_begin(8); assert_events_eq!( Event::CollatorChosen { @@ -5874,18 +5992,18 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 32, + rewards: 15, }, Event::Rewarded { account: 7, - rewards: 11, + rewards: 5, }, Event::Rewarded { account: 10, - rewards: 11, + rewards: 5, }, ); - set_author(9, 1, 100); + set_author(9, 1, POINTS_PER_ROUND); roll_to_round_begin(9); // no more paying 6 assert_events_eq!( @@ -5920,15 +6038,15 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 34, + rewards: 15, }, Event::Rewarded { account: 7, - rewards: 11, + rewards: 5, }, Event::Rewarded { account: 10, - rewards: 11, + rewards: 5, }, ); roll_blocks(1); @@ -5947,7 +6065,7 @@ fn payouts_follow_delegation_changes() { auto_compound: Percent::zero(), }); - set_author(10, 1, 100); + set_author(10, 1, POINTS_PER_ROUND); roll_to_round_begin(10); // new delegation is not rewarded yet assert_events_eq!( @@ -5982,15 +6100,15 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 36, + rewards: 15, }, Event::Rewarded { account: 7, - rewards: 12, + rewards: 5, }, Event::Rewarded { account: 10, - rewards: 12, + rewards: 5, }, ); roll_to_round_begin(11); @@ -6027,15 +6145,15 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 37, + rewards: 15, }, Event::Rewarded { account: 7, - rewards: 12, + rewards: 5, }, Event::Rewarded { account: 10, - rewards: 12, + rewards: 5, }, ); roll_to_round_begin(12); @@ -6073,19 +6191,19 @@ fn payouts_follow_delegation_changes() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 34, + rewards: 14, }, Event::Rewarded { account: 7, - rewards: 10, + rewards: 4, }, Event::Rewarded { account: 10, - rewards: 10, + rewards: 4, }, Event::Rewarded { account: 8, - rewards: 10, + rewards: 4, }, ); }); @@ -6491,11 +6609,9 @@ fn no_rewards_paid_until_after_reward_payment_delay() { .build() .execute_with(|| { // payouts for round 1 - set_author(1, 1, 1); - set_author(1, 2, 1); - set_author(1, 2, 1); - set_author(1, 3, 1); - set_author(1, 3, 1); + set_author(1, 1, POINTS_PER_BLOCK); + set_author(1, 2, POINTS_PER_BLOCK * 2); + set_author(1, 3, POINTS_PER_BLOCK * 2); roll_to_round_begin(2); assert_events_eq!( @@ -6556,7 +6672,7 @@ fn no_rewards_paid_until_after_reward_payment_delay() { roll_blocks(1); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 1, + rewards: 0, }); roll_blocks(1); @@ -6584,8 +6700,8 @@ fn deferred_payment_storage_items_are_cleaned_up() { .with_candidates(vec![(1, 20), (2, 20)]) .build() .execute_with(|| { - set_author(1, 1, 1); - set_author(1, 2, 1); + set_author(1, 1, POINTS_PER_BLOCK * 3); + set_author(1, 2, POINTS_PER_BLOCK * 2); // reflects genesis? assert!(>::contains_key(1, 1)); @@ -6666,16 +6782,16 @@ fn deferred_payment_storage_items_are_cleaned_up() { "DelayedPayouts should be populated after RewardPaymentDelay" ); assert!(>::contains_key(1)); - assert!(!>::contains_key(2)); + assert!(>::contains_key(2)); assert!( - !>::contains_key(2), - "We never rewarded points for round 2" + >::contains_key(2), + "We awarded points for round 2" ); assert!(!>::contains_key(3)); assert!( - !>::contains_key(3), - "We never awarded points for round 3" + >::contains_key(3), + "We awarded points for round 3" ); // collator 1 has been paid in this last block and associated storage cleaned up @@ -6690,7 +6806,7 @@ fn deferred_payment_storage_items_are_cleaned_up() { roll_blocks(1); assert_events_eq!(Event::Rewarded { account: 2, - rewards: 1, + rewards: 0, },); roll_to_round_begin(4); @@ -6736,8 +6852,8 @@ fn deferred_payment_and_at_stake_storage_items_cleaned_up_for_candidates_not_pro .build() .execute_with(|| { // candidate 3 will not produce blocks - set_author(1, 1, 1); - set_author(1, 2, 1); + set_author(1, 1, POINTS_PER_BLOCK * 3); + set_author(1, 2, POINTS_PER_BLOCK * 2); // reflects genesis? assert!(>::contains_key(1, 1)); @@ -6808,10 +6924,10 @@ fn deferred_payment_steady_state_event_flow() { .execute_with(|| { // convenience to set the round points consistently let set_round_points = |round: BlockNumber| { - set_author(round as BlockNumber, 1, 1); - set_author(round as BlockNumber, 2, 1); - set_author(round as BlockNumber, 3, 1); - set_author(round as BlockNumber, 4, 1); + set_author(round as BlockNumber, 1, 2 * POINTS_PER_ROUND); + set_author(round as BlockNumber, 2, POINTS_PER_ROUND); + set_author(round as BlockNumber, 3, POINTS_PER_ROUND); + set_author(round as BlockNumber, 4, POINTS_PER_ROUND); }; // grab initial issuance -- we will reset it before round issuance is calculated so that @@ -6892,15 +7008,15 @@ fn deferred_payment_steady_state_event_flow() { assert_events_eq!( Event::Rewarded { account: 3, - rewards: 19, + rewards: 13, }, Event::Rewarded { account: 22, - rewards: 6, + rewards: 4, }, Event::Rewarded { account: 33, - rewards: 6, + rewards: 4, }, ); @@ -6908,15 +7024,15 @@ fn deferred_payment_steady_state_event_flow() { assert_events_eq!( Event::Rewarded { account: 4, - rewards: 19, + rewards: 13, }, Event::Rewarded { account: 33, - rewards: 6, + rewards: 4, }, Event::Rewarded { account: 44, - rewards: 6, + rewards: 4, }, ); @@ -6924,15 +7040,15 @@ fn deferred_payment_steady_state_event_flow() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 19, + rewards: 27, }, Event::Rewarded { account: 11, - rewards: 6, + rewards: 9, }, Event::Rewarded { account: 44, - rewards: 6, + rewards: 9, }, ); @@ -6940,15 +7056,15 @@ fn deferred_payment_steady_state_event_flow() { assert_events_eq!( Event::Rewarded { account: 2, - rewards: 19, + rewards: 13, }, Event::Rewarded { account: 11, - rewards: 6, + rewards: 4, }, Event::Rewarded { account: 22, - rewards: 6, + rewards: 4, }, ); @@ -7085,7 +7201,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_for_previous_rounds_but_not_f .build() .execute_with(|| { // preset rewards for rounds 1, 2 and 3 - (1..=3).for_each(|round| set_author(round, 1, 1)); + (1..=3).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::schedule_revoke_delegation( RuntimeOrigin::signed(2), @@ -7113,7 +7229,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_for_previous_rounds_but_not_f assert_events_eq!( Event::Rewarded { account: 1, - rewards: 4, + rewards: 2, }, Event::Rewarded { account: 2, @@ -7126,7 +7242,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_for_previous_rounds_but_not_f roll_blocks(3); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 5, + rewards: 2, },); let collator_snapshot = ParachainStaking::at_stake(ParachainStaking::round().current, 1) @@ -7152,7 +7268,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_when_request_cancelled() { .build() .execute_with(|| { // preset rewards for rounds 2, 3 and 4 - (2..=4).for_each(|round| set_author(round, 1, 1)); + (2..=4).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::schedule_revoke_delegation( RuntimeOrigin::signed(2), @@ -7185,7 +7301,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_when_request_cancelled() { roll_blocks(3); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 5, + rewards: 2, },); let collator_snapshot = ParachainStaking::at_stake(ParachainStaking::round().current, 1) @@ -7206,7 +7322,7 @@ fn test_delegator_scheduled_for_revoke_is_rewarded_when_request_cancelled() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 4, + rewards: 1, }, Event::Rewarded { account: 2, @@ -7226,7 +7342,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_for_previous_rounds_bu .build() .execute_with(|| { // preset rewards for rounds 1, 2 and 3 - (1..=3).for_each(|round| set_author(round, 1, 1)); + (1..=3).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(2), @@ -7255,11 +7371,11 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_for_previous_rounds_bu assert_events_eq!( Event::Rewarded { account: 1, - rewards: 3, + rewards: 2, }, Event::Rewarded { account: 2, - rewards: 2, + rewards: 1, }, ); @@ -7269,7 +7385,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_for_previous_rounds_bu assert_events_eq!( Event::Rewarded { account: 1, - rewards: 4, + rewards: 1, }, Event::Rewarded { account: 2, @@ -7300,7 +7416,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_when_request_cancelled .build() .execute_with(|| { // preset rewards for rounds 2, 3 and 4 - (2..=4).for_each(|round| set_author(round, 1, 1)); + (2..=4).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::schedule_delegator_bond_less( RuntimeOrigin::signed(2), @@ -7335,7 +7451,7 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_when_request_cancelled assert_events_eq!( Event::Rewarded { account: 1, - rewards: 4, + rewards: 1, }, Event::Rewarded { account: 2, @@ -7361,11 +7477,11 @@ fn test_delegator_scheduled_for_bond_decrease_is_rewarded_when_request_cancelled assert_events_eq!( Event::Rewarded { account: 1, - rewards: 3, + rewards: 1, }, Event::Rewarded { account: 2, - rewards: 2, + rewards: 1, }, ); }); @@ -7380,7 +7496,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_for_previous_rounds_but_not_fo .build() .execute_with(|| { // preset rewards for rounds 1, 2 and 3 - (1..=3).for_each(|round| set_author(round, 1, 1)); + (1..=3).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::schedule_revoke_delegation( RuntimeOrigin::signed(2), @@ -7420,7 +7536,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_for_previous_rounds_but_not_fo assert_events_eq!( Event::Rewarded { account: 1, - rewards: 4, + rewards: 2, }, Event::Rewarded { account: 2, @@ -7433,7 +7549,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_for_previous_rounds_but_not_fo roll_blocks(3); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 5, + rewards: 2, },); let collator_snapshot = ParachainStaking::at_stake(ParachainStaking::round().current, 1) @@ -7459,7 +7575,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_when_request_cancelled() { .build() .execute_with(|| { // preset rewards for rounds 2, 3 and 4 - (2..=4).for_each(|round| set_author(round, 1, 1)); + (2..=4).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::schedule_revoke_delegation( RuntimeOrigin::signed(2), @@ -7508,7 +7624,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_when_request_cancelled() { roll_blocks(3); assert_events_eq!(Event::Rewarded { account: 1, - rewards: 5, + rewards: 2, },); let collator_snapshot = ParachainStaking::at_stake(ParachainStaking::round().current, 1) @@ -7529,7 +7645,7 @@ fn test_delegator_scheduled_for_leave_is_rewarded_when_request_cancelled() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 4, + rewards: 1, }, Event::Rewarded { account: 2, @@ -8187,7 +8303,7 @@ fn test_rewards_do_not_auto_compound_on_payment_if_delegation_scheduled_revoke_e .with_delegations(vec![(2, 1, 200), (3, 1, 200)]) .build() .execute_with(|| { - (2..=5).for_each(|round| set_author(round, 1, 1)); + (2..=5).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::set_auto_compound( RuntimeOrigin::signed(2), 1, @@ -8229,22 +8345,22 @@ fn test_rewards_do_not_auto_compound_on_payment_if_delegation_scheduled_revoke_e assert_events_eq!( Event::Rewarded { account: 1, - rewards: 9, + rewards: 4, }, // no compound since revoke request exists Event::Rewarded { account: 2, - rewards: 8, + rewards: 4, }, // 50% Event::Rewarded { account: 3, - rewards: 8, + rewards: 4, }, Event::Compounded { candidate: 1, delegator: 3, - amount: 4, + amount: 2, }, ); }); @@ -8258,7 +8374,7 @@ fn test_rewards_auto_compound_on_payment_as_per_auto_compound_config() { .with_delegations(vec![(2, 1, 200), (3, 1, 200), (4, 1, 200), (5, 1, 200)]) .build() .execute_with(|| { - (2..=6).for_each(|round| set_author(round, 1, 1)); + (2..=6).for_each(|round| set_author(round, 1, POINTS_PER_ROUND)); assert_ok!(ParachainStaking::set_auto_compound( RuntimeOrigin::signed(2), 1, @@ -8300,37 +8416,37 @@ fn test_rewards_auto_compound_on_payment_as_per_auto_compound_config() { assert_events_eq!( Event::Rewarded { account: 1, - rewards: 13, + rewards: 6, }, // 0% Event::Rewarded { account: 2, - rewards: 8, + rewards: 4, }, // 50% Event::Rewarded { account: 3, - rewards: 8, + rewards: 4, }, Event::Compounded { candidate: 1, delegator: 3, - amount: 4, + amount: 2, }, // 100% Event::Rewarded { account: 4, - rewards: 8, + rewards: 4, }, Event::Compounded { candidate: 1, delegator: 4, - amount: 8, + amount: 4, }, // no-config Event::Rewarded { account: 5, - rewards: 8, + rewards: 4, }, ); }); @@ -8849,10 +8965,10 @@ fn test_on_initialize_weights() { let weight = ParachainStaking::on_initialize(1); // TODO: build this with proper db reads/writes - assert_eq!(Weight::from_parts(277168000, 0), weight); + assert_eq!(Weight::from_parts(402168000, 0), weight); // roll to the end of the round, then run on_init again, we should see round change... - set_author(3, 1, 100); // must set some points for prepare_staking_payouts + set_author(3, 1, POINTS_PER_ROUND); // must set some points for prepare_staking_payouts roll_to_round_end(3); let block = System::block_number() + 1; let weight = ParachainStaking::on_initialize(block); @@ -8863,13 +8979,14 @@ fn test_on_initialize_weights() { // // following this assertion, we add individual weights together to show that we can // derive this number independently. - let expected_on_init = 2404547135; - assert_eq!(Weight::from_parts(expected_on_init, 32562), weight); + let expected_on_init = 3541628080; + assert_eq!(Weight::from_parts(expected_on_init, 51512), weight); // assemble weight manually to ensure it is well understood let mut expected_weight = 0u64; expected_weight += PalletWeights::::base_on_initialize().ref_time(); expected_weight += PalletWeights::::prepare_staking_payouts().ref_time(); + expected_weight += PalletWeights::::mark_collators_as_inactive(5).ref_time(); // TODO: this should be the same as >. I believe this relates to // genesis building @@ -8884,9 +9001,9 @@ fn test_on_initialize_weights() { // Round write, done in on-round-change code block inside on_initialize() expected_weight += RocksDbWeight::get().reads_writes(0, 1).ref_time(); // more reads/writes manually accounted for for on_finalize - expected_weight += RocksDbWeight::get().reads_writes(3, 2).ref_time(); + expected_weight += RocksDbWeight::get().reads_writes(4, 3).ref_time(); - assert_eq!(Weight::from_parts(expected_weight, 32562), weight); + assert_eq!(Weight::from_parts(expected_weight, 51512), weight); assert_eq!(expected_on_init, expected_weight); // magic number == independent accounting }); } diff --git a/pallets/parachain-staking/src/weights.rs b/pallets/parachain-staking/src/weights.rs index f614712c3f..42f01dd4e5 100644 --- a/pallets/parachain-staking/src/weights.rs +++ b/pallets/parachain-staking/src/weights.rs @@ -91,6 +91,7 @@ pub trait WeightInfo { fn delegate_with_auto_compound_worst() -> Weight; fn mint_collator_reward() -> Weight; fn notify_inactive_collator() -> Weight; + fn mark_collators_as_inactive(x: u32) -> Weight; } /// Weights for pallet_parachain_staking using the Substrate node and recommended hardware. @@ -918,6 +919,28 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } + + /// Storage: `ParachainStaking::AtStake` (r:52 w:0) + /// Proof: `ParachainStaking::AtStake` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::AwardedPts` (r:51 w:0) + /// Proof: `ParachainStaking::AwardedPts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::WasInactive` (r:0 w:51) + /// Proof: `ParachainStaking::WasInactive` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[0, 50]`. + fn mark_collators_as_inactive(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `108 + x * (104 ±0)` + // Estimated: `6050 + x * (2580 ±0)` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(27_982_315, 6050) + // Standard Error: 27_443 + .saturating_add(Weight::from_parts(11_819_726, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2580).saturating_mul(x.into())) + } } // For backwards compatibility and tests @@ -1743,4 +1766,26 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(10_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } + + /// Storage: `ParachainStaking::AtStake` (r:52 w:0) + /// Proof: `ParachainStaking::AtStake` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::AwardedPts` (r:51 w:0) + /// Proof: `ParachainStaking::AwardedPts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::WasInactive` (r:0 w:51) + /// Proof: `ParachainStaking::WasInactive` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[0, 50]`. + fn mark_collators_as_inactive(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `108 + x * (104 ±0)` + // Estimated: `6050 + x * (2580 ±0)` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(27_982_315, 6050) + // Standard Error: 27_443 + .saturating_add(Weight::from_parts(11_819_726, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(x.into()))) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2580).saturating_mul(x.into())) + } } diff --git a/runtime/moonbase/src/weights/pallet_parachain_staking.rs b/runtime/moonbase/src/weights/pallet_parachain_staking.rs index dc333d595a..697df3971f 100644 --- a/runtime/moonbase/src/weights/pallet_parachain_staking.rs +++ b/runtime/moonbase/src/weights/pallet_parachain_staking.rs @@ -872,4 +872,26 @@ impl pallet_parachain_staking::WeightInfo for WeightInf .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } + + /// Storage: `ParachainStaking::AtStake` (r:52 w:0) + /// Proof: `ParachainStaking::AtStake` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::AwardedPts` (r:51 w:0) + /// Proof: `ParachainStaking::AwardedPts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::WasInactive` (r:0 w:51) + /// Proof: `ParachainStaking::WasInactive` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[0, 50]`. + fn mark_collators_as_inactive(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `108 + x * (104 ±0)` + // Estimated: `6050 + x * (2580 ±0)` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(27_982_315, 6050) + // Standard Error: 27_443 + .saturating_add(Weight::from_parts(11_819_726, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2580).saturating_mul(x.into())) + } } diff --git a/runtime/moonbeam/src/weights/pallet_parachain_staking.rs b/runtime/moonbeam/src/weights/pallet_parachain_staking.rs index 88e69f21a5..e8bf9a8e95 100644 --- a/runtime/moonbeam/src/weights/pallet_parachain_staking.rs +++ b/runtime/moonbeam/src/weights/pallet_parachain_staking.rs @@ -874,4 +874,26 @@ impl pallet_parachain_staking::WeightInfo for WeightInf .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } + + /// Storage: `ParachainStaking::AtStake` (r:52 w:0) + /// Proof: `ParachainStaking::AtStake` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::AwardedPts` (r:51 w:0) + /// Proof: `ParachainStaking::AwardedPts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::WasInactive` (r:0 w:51) + /// Proof: `ParachainStaking::WasInactive` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[0, 50]`. + fn mark_collators_as_inactive(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `108 + x * (104 ±0)` + // Estimated: `6050 + x * (2580 ±0)` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(27_982_315, 6050) + // Standard Error: 27_443 + .saturating_add(Weight::from_parts(11_819_726, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2580).saturating_mul(x.into())) + } } diff --git a/runtime/moonriver/src/weights/pallet_parachain_staking.rs b/runtime/moonriver/src/weights/pallet_parachain_staking.rs index 461e6f7da1..a6d026688d 100644 --- a/runtime/moonriver/src/weights/pallet_parachain_staking.rs +++ b/runtime/moonriver/src/weights/pallet_parachain_staking.rs @@ -874,4 +874,26 @@ impl pallet_parachain_staking::WeightInfo for WeightInf .saturating_add(T::DbWeight::get().reads(10_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } + + /// Storage: `ParachainStaking::AtStake` (r:52 w:0) + /// Proof: `ParachainStaking::AtStake` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::AwardedPts` (r:51 w:0) + /// Proof: `ParachainStaking::AwardedPts` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `ParachainStaking::WasInactive` (r:0 w:51) + /// Proof: `ParachainStaking::WasInactive` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[0, 50]`. + fn mark_collators_as_inactive(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `108 + x * (104 ±0)` + // Estimated: `6050 + x * (2580 ±0)` + // Minimum execution time: 16_000_000 picoseconds. + Weight::from_parts(27_982_315, 6050) + // Standard Error: 27_443 + .saturating_add(Weight::from_parts(11_819_726, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(x.into()))) + .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(x.into()))) + .saturating_add(Weight::from_parts(0, 2580).saturating_mul(x.into())) + } }