From d721afe4e7234b936e9c5b6ed0fc3baeec09ad5a Mon Sep 17 00:00:00 2001 From: doordashcon Date: Fri, 26 Aug 2022 23:10:45 +0100 Subject: [PATCH 1/2] needs work --- bin/node/runtime/src/lib.rs | 1 + frame/staking/src/benchmarking.rs | 18 ++-- frame/staking/src/lib.rs | 29 ++++-- frame/staking/src/mock.rs | 8 +- frame/staking/src/pallet/impls.rs | 24 ++++- frame/staking/src/pallet/mod.rs | 9 +- frame/staking/src/tests.rs | 154 ++++++++++++++++++++++-------- 7 files changed, 175 insertions(+), 68 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index ff793a49b5ce6..700ee348aa1b7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -569,6 +569,7 @@ impl pallet_staking::Config for Runtime { type OnStakerSlash = NominationPools; type WeightInfo = pallet_staking::weights::SubstrateWeight; type BenchmarkingConfig = StakingBenchmarkingConfig; + type MaxRewardPoints = ConstU32<300>; } parameter_types! { diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 2d5943b51758d..88e091b227698 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -77,7 +77,7 @@ pub fn create_validator_with_nominators( // Clean up any existing state. clear_validators_and_nominators::(); let mut points_total = 0; - let mut points_individual = Vec::new(); + let mut points_individual = BoundedBTreeMap::::new(); let (v_stash, v_controller) = create_stash_controller::(0, 100, destination.clone())?; let validator_prefs = @@ -86,7 +86,7 @@ pub fn create_validator_with_nominators( let stash_lookup = T::Lookup::unlookup(v_stash.clone()); points_total += 10; - points_individual.push((v_stash.clone(), 10)); + points_individual.try_insert(v_stash.clone(), 10).map_err(|_| "Error, are your legs discombubulated").unwrap(); //TODO: Create custom error. let mut nominators = Vec::new(); @@ -117,9 +117,9 @@ pub fn create_validator_with_nominators( assert_ne!(Nominators::::count(), 0); // Give Era Points - let reward = EraRewardPoints:: { + let reward = EraRewardPoints:: { total: points_total, - individual: points_individual.into_iter().collect(), + individual: points_individual, }; let current_era = CurrentEra::::get().unwrap(); @@ -670,7 +670,7 @@ benchmarks! { >::insert(i, dummy(), Exposure::>::default()); >::insert(i, dummy(), ValidatorPrefs::default()); >::insert(i, BalanceOf::::one()); - >::insert(i, EraRewardPoints::::default()); + >::insert(i, EraRewardPoints::::default()); >::insert(i, BalanceOf::::one()); ErasStartSessionIndex::::insert(i, i); } @@ -747,19 +747,19 @@ benchmarks! { let current_era = CurrentEra::::get().unwrap(); let mut points_total = 0; - let mut points_individual = Vec::new(); + let mut points_individual = BoundedBTreeMap::::new(); let mut payout_calls_arg = Vec::new(); for validator in new_validators.iter() { points_total += 10; - points_individual.push((validator.clone(), 10)); + points_individual.try_insert(validator.clone(), 10).map_err(|_| "error, walk your direction").unwrap(); //TODO: Create custom error.; payout_calls_arg.push((validator.clone(), current_era)); } // Give Era Points - let reward = EraRewardPoints:: { + let reward = EraRewardPoints:: { total: points_total, - individual: points_individual.into_iter().collect(), + individual: points_individual, }; ErasRewardPoints::::insert(current_era, reward); diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 38466c8cb1d62..2aeffcde919cd 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -164,6 +164,7 @@ //! use super::*; //! use frame_support::pallet_prelude::*; //! use frame_system::pallet_prelude::*; +//! use frame_support::BoundedBTreeMap; //! //! #[pallet::pallet] //! pub struct Pallet(_); @@ -177,7 +178,9 @@ //! #[pallet::weight(0)] //! pub fn reward_myself(origin: OriginFor) -> DispatchResult { //! let reported = ensure_signed(origin)?; -//! >::reward_by_ids(vec![(reported, 10)]); +//! let mut validator_point = BoundedBTreeMap::new(); +//! validator_point.try_insert(reported, 10).map_err(|_| staking::Error::::MaxRewardPointsReached)?; +//! >::reward_by_ids(validator_point); //! Ok(()) //! } //! } @@ -299,9 +302,11 @@ pub mod weights; mod pallet; -use codec::{Decode, Encode, HasCompact}; +use codec::{Decode, Encode, HasCompact}; // {Decode, Encode, use frame_support::{ parameter_types, + pallet_prelude::{MaxEncodedLen, CloneNoBound}, + storage::bounded_btree_map::BoundedBTreeMap, traits::{Currency, Defensive, Get}, weights::Weight, BoundedVec, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, @@ -335,7 +340,6 @@ macro_rules! log { } /// Counter for the number of "reward" points earned by a given validator. -pub type RewardPoint = u32; /// The balance type of this pallet. pub type BalanceOf = ::CurrencyBalance; @@ -368,17 +372,24 @@ pub struct ActiveEraInfo { /// Reward points of an era. Used to split era total payout between validators. /// /// This points will be used to reward validators and their respective nominators. -#[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -pub struct EraRewardPoints { +/// TODO: this need more comments? +// #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] +// check if i need DefaultnoBound as is in the lib.rs file for nomination_pool +// MaxEncodedLen was also removed from this +#[derive(Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebugNoBound, CloneNoBound)] +#[cfg_attr(feature = "std", derive(frame_support::PartialEqNoBound))] +#[codec(mel_bound(T: Config))] +#[scale_info(skip_type_params(T))] +pub struct EraRewardPoints { /// Total number of points. Equals the sum of reward points for each validator. - pub total: RewardPoint, + pub total: u32, /// The reward points earned by a given validator. - pub individual: BTreeMap, + pub individual: BoundedBTreeMap, } -impl Default for EraRewardPoints { +impl Default for EraRewardPoints { fn default() -> Self { - EraRewardPoints { total: Default::default(), individual: BTreeMap::new() } + EraRewardPoints { total: Default::default(), individual: BoundedBTreeMap::new() } } } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 7911428b3337c..c58e2fd42177b 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -302,6 +302,7 @@ impl crate::pallet::pallet::Config for Test { type OnStakerSlash = OnStakerSlashMock; type BenchmarkingConfig = TestBenchmarkingConfig; type WeightInfo = (); + type MaxRewardPoints = ConstU32<300>; } pub(crate) type StakingCall = crate::Call; @@ -769,9 +770,12 @@ pub(crate) fn reward_time_per_era() -> u64 { } pub(crate) fn reward_all_elected() { - let rewards = ::SessionInterface::validators().into_iter().map(|v| (v, 1)); + let mut rewards = BoundedBTreeMap::new(); // = ::SessionInterface::validators().into_iter().map(|v| (v, 1)); - >::reward_by_ids(rewards) + for validator in ::SessionInterface::validators().iter() { + rewards.try_insert(validator.clone(), 1).expect("Maximum points for validator reached"); + }; + >::reward_by_ids(rewards.clone()); } pub(crate) fn validator_controllers() -> Vec { diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index 68aa97db8a324..97ec6b281b88b 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -23,6 +23,7 @@ use frame_election_provider_support::{ }; use frame_support::{ pallet_prelude::*, + storage::bounded_btree_map::BoundedBTreeMap, traits::{ Currency, CurrencyToVote, Defensive, EstimateNextNewSession, Get, Imbalance, LockableCurrency, OnUnbalanced, UnixTime, WithdrawReasons, @@ -623,11 +624,16 @@ impl Pallet { /// relatively to their points. /// /// COMPLEXITY: Complexity is `number_of_validator_to_reward x current_elected_len`. - pub fn reward_by_ids(validators_points: impl IntoIterator) { + pub fn reward_by_ids(validators_points: BoundedBTreeMap) { if let Some(active_era) = Self::active_era() { >::mutate(active_era.index, |era_rewards| { - for (validator, points) in validators_points.into_iter() { - *era_rewards.individual.entry(validator).or_default() += points; + for (validator, points) in validators_points.iter() { + let mut indie_points: u32 = 0; + if let Some(prev_indie_points) = era_rewards.individual.remove(&validator) { + indie_points = prev_indie_points; + } + indie_points += points; + era_rewards.individual.try_insert(validator.clone(), indie_points); era_rewards.total += points; } }); @@ -1128,12 +1134,20 @@ where T: Config + pallet_authorship::Config + pallet_session::Config, { fn note_author(author: T::AccountId) { - Self::reward_by_ids(vec![(author, 20)]) + // vec![(author, 20)] + let mut validator_points = BoundedBTreeMap::new(); + validator_points.try_insert(author, 20); + Self::reward_by_ids(validator_points); } fn note_uncle(uncle_author: T::AccountId, _age: T::BlockNumber) { // defensive-only: block author must exist. + // vec![(block_author, 2), (uncle_author, 1)] + let mut validator_points = BoundedBTreeMap::new(); + if let Some(block_author) = >::author() { - Self::reward_by_ids(vec![(block_author, 2), (uncle_author, 1)]) + validator_points.try_insert(block_author, 2); + validator_points.try_insert(uncle_author, 1); + Self::reward_by_ids(validator_points); } else { crate::log!(warn, "block author not set, this should never happen"); } diff --git a/frame/staking/src/pallet/mod.rs b/frame/staking/src/pallet/mod.rs index 1f11f0ff00ac1..1c42abdce855c 100644 --- a/frame/staking/src/pallet/mod.rs +++ b/frame/staking/src/pallet/mod.rs @@ -200,6 +200,9 @@ pub mod pallet { /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; + + // Maximum reward points for each validator. + type MaxRewardPoints: Get; } #[pallet::type_value] @@ -399,7 +402,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn eras_reward_points)] pub type ErasRewardPoints = - StorageMap<_, Twox64Concat, EraIndex, EraRewardPoints, ValueQuery>; + StorageMap<_, Twox64Concat, EraIndex, EraRewardPoints, ValueQuery>; /// The total amount staked for the last `HISTORY_DEPTH` eras. /// If total hasn't been set or has been removed then 0 stake is returned. @@ -683,7 +686,7 @@ pub mod pallet { AlreadyClaimed, /// Incorrect previous history depth input provided. IncorrectHistoryDepth, - /// Incorrect number of slashing spans provided. + /// Incorrect number Bound RewardPointsin pallet-staking #12039 of slashing spans provided. IncorrectSlashingSpans, /// Internal state has become somehow corrupted and the operation cannot continue. BadState, @@ -701,6 +704,8 @@ pub mod pallet { TooManyValidators, /// Commission is too low. Must be at least `MinCommission`. CommissionTooLow, + /// Maximum reward points for given validator reached. + MaxRewardPointsReached, } #[pallet::hooks] diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index 485a9dc3ae66a..d7474089b9667 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -252,6 +252,8 @@ fn change_controller_works() { }) } +// TODO: test instances that show when the specified bound is exceeded. + #[test] fn rewards_should_work() { ExtBuilder::default().nominate(true).session_per_era(3).build_and_execute(|| { @@ -261,20 +263,27 @@ fn rewards_should_work() { let init_balance_21 = Balances::total_balance(&21); let init_balance_100 = Balances::total_balance(&100); let init_balance_101 = Balances::total_balance(&101); + let mut validator_1_era_0 = BoundedBTreeMap::new(); + validator_1_era_0.try_insert(11, 50); + let mut validator_2_era_0 = BoundedBTreeMap::new(); + validator_2_era_0.try_insert(21, 50); // Set payees Payee::::insert(11, RewardDestination::Controller); Payee::::insert(21, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - Pallet::::reward_by_ids(vec![(11, 50)]); - Pallet::::reward_by_ids(vec![(11, 50)]); + Pallet::::reward_by_ids(validator_1_era_0.clone()); + Pallet::::reward_by_ids(validator_1_era_0.clone()); // This is the second validator of the current elected set. - Pallet::::reward_by_ids(vec![(21, 50)]); + Pallet::::reward_by_ids(validator_2_era_0); // Compute total payout now for whole duration of the session. let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); let maximum_payout = maximum_payout_for_duration(reward_time_per_era()); + let mut validator_points_era_0 = BoundedBTreeMap::new(); + validator_points_era_0.try_insert(11, 100); + validator_points_era_0.try_insert(21, 50); start_session(1); assert_eq_uvec!(Session::validators(), vec![11, 21]); @@ -287,10 +296,10 @@ fn rewards_should_work() { assert_eq!(Balances::total_balance(&101), init_balance_101); assert_eq!( Staking::eras_reward_points(active_era()), - EraRewardPoints { + EraRewardPoints:: { total: 50 * 3, - individual: vec![(11, 100), (21, 50)].into_iter().collect(), - } + individual: validator_points_era_0, + }, ); let part_for_10 = Perbill::from_rational::(1000, 1125); let part_for_20 = Perbill::from_rational::(1000, 1375); @@ -310,6 +319,8 @@ fn rewards_should_work() { Event::EraPaid(0, total_payout_0, maximum_payout - total_payout_0) ); mock::make_all_reward_payment(0); + let mut validator_1_era_1 = BoundedBTreeMap::new(); + validator_1_era_1.try_insert(11, 1); assert_eq_error_rate!( Balances::total_balance(&10), @@ -333,7 +344,7 @@ fn rewards_should_work() { assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); assert_eq_uvec!(Session::validators(), vec![11, 21]); - Pallet::::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(validator_1_era_1); // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); @@ -570,8 +581,12 @@ fn nominating_and_rewards_should_work() { // the total reward for era 0 let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(vec![(41, 1)]); - Pallet::::reward_by_ids(vec![(21, 1)]); + let mut validator_1_era_0 = BoundedBTreeMap::new(); + validator_1_era_0.try_insert(41, 1); + let mut validator_2_era_0 = BoundedBTreeMap::new(); + validator_2_era_0.try_insert(21, 1); + Pallet::::reward_by_ids(validator_1_era_0); + Pallet::::reward_by_ids(validator_2_era_0); mock::start_active_era(1); @@ -612,8 +627,12 @@ fn nominating_and_rewards_should_work() { // the total reward for era 1 let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(vec![(21, 2)]); - Pallet::::reward_by_ids(vec![(11, 1)]); + let mut validator_2_era_1 = BoundedBTreeMap::new(); + validator_2_era_1.try_insert(21, 2); + let mut validator_3_era_1 = BoundedBTreeMap::new(); + validator_3_era_1.try_insert(11, 1); + Pallet::::reward_by_ids(validator_2_era_1); + Pallet::::reward_by_ids(validator_3_era_1); mock::start_active_era(2); @@ -993,7 +1012,9 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(vec![(11, 1)]); + let mut validator_1 = BoundedBTreeMap::new(); + validator_1.try_insert(11, 1); + Pallet::::reward_by_ids(validator_1.clone()); mock::start_active_era(1); mock::make_all_reward_payment(0); @@ -1019,7 +1040,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(validator_1.clone()); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -1050,7 +1071,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_2 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(validator_1.clone()); mock::start_active_era(3); mock::make_all_reward_payment(2); @@ -1097,7 +1118,9 @@ fn validator_payment_prefs_work() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); let exposure_1 = Staking::eras_stakers(active_era(), 11); - Pallet::::reward_by_ids(vec![(11, 1)]); + let mut validator_1_era_1 = BoundedBTreeMap::new(); + validator_1_era_1.try_insert(11, 1); + Pallet::::reward_by_ids(validator_1_era_1); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -1663,8 +1686,12 @@ fn reward_to_stake_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(vec![(11, 1)]); - Pallet::::reward_by_ids(vec![(21, 1)]); + let mut validator_1_era_0 = BoundedBTreeMap::new(); + validator_1_era_0.try_insert(11, 1); + let mut validator_2_era_0 = BoundedBTreeMap::new(); + validator_2_era_0.try_insert(21, 1); + Pallet::::reward_by_ids(validator_1_era_0); + Pallet::::reward_by_ids(validator_2_era_0); // New era --> rewards are paid --> stakes are changed mock::start_active_era(1); @@ -2055,15 +2082,19 @@ fn reward_validator_slashing_validator_does_not_overflow() { let reward_slash = u64::MAX as Balance * 2; // Assert multiplication overflows in balance arithmetic. + // vec![(11, 1)].into_iter() assert!(stake.checked_mul(reward_slash).is_none()); // Set staker let _ = Balances::make_free_balance_be(&11, stake); + + let mut validator_1 = BoundedBTreeMap::new(); + validator_1.try_insert(11, 1); let exposure = Exposure:: { total: stake, own: stake, others: vec![] }; - let reward = EraRewardPoints:: { + let reward = EraRewardPoints:: { total: 1, - individual: vec![(11, 1)].into_iter().collect(), + individual: validator_1, }; // Check reward @@ -2122,11 +2153,14 @@ fn reward_from_authorship_event_handler_works() { // 21 is rewarded as an uncle producer // 11 is rewarded as a block producer and uncle referencer and uncle producer + let mut validator_points = BoundedBTreeMap::new(); + validator_points.try_insert(11, 23); + validator_points.try_insert(21, 1); assert_eq!( ErasRewardPoints::::get(active_era()), - EraRewardPoints { - individual: vec![(11, 20 + 2 * 2 + 1), (21, 1)].into_iter().collect(), - total: 26, + EraRewardPoints:: { + individual: validator_points, + total: 24, }, ); }) @@ -2136,15 +2170,29 @@ fn reward_from_authorship_event_handler_works() { fn add_reward_points_fns_works() { ExtBuilder::default().build_and_execute(|| { // Not mandatory but must be coherent with rewards + // vec![(11, 4), (21, 2)].into_iter() + // vec![(21, 1), (11, 1), (11, 1)] assert_eq_uvec!(Session::validators(), vec![21, 11]); - Pallet::::reward_by_ids(vec![(21, 1), (11, 1), (11, 1)]); + let mut validator_1_era_0 = BoundedBTreeMap::new(); + validator_1_era_0.try_insert(21, 1); + + let mut validator_2_era_0 = BoundedBTreeMap::new(); + validator_2_era_0.try_insert(11, 1); - Pallet::::reward_by_ids(vec![(21, 1), (11, 1), (11, 1)]); + Pallet::::reward_by_ids(validator_1_era_0.clone()); + Pallet::::reward_by_ids(validator_2_era_0.clone()); + Pallet::::reward_by_ids(validator_2_era_0.clone()); + Pallet::::reward_by_ids(validator_1_era_0); + Pallet::::reward_by_ids(validator_2_era_0.clone()); + Pallet::::reward_by_ids(validator_2_era_0); + let mut validator_points = BoundedBTreeMap::new(); + validator_points.try_insert(11, 4); + validator_points.try_insert(21, 2); assert_eq!( ErasRewardPoints::::get(active_era()), - EraRewardPoints { individual: vec![(11, 4), (21, 2)].into_iter().collect(), total: 6 }, + EraRewardPoints:: { individual: validator_points, total: 6 }, ); }) } @@ -3320,17 +3368,20 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { let part_for_10 = Perbill::from_rational::(1000, 1125); let part_for_100 = Perbill::from_rational::(125, 1125); + let mut validator_point = BoundedBTreeMap::new(); + validator_point.try_insert(11, 1); + // Check state Payee::::insert(11, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - Pallet::::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(validator_point.clone()); // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(1); - Pallet::::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(validator_point.clone()); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3339,7 +3390,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { mock::start_active_era(2); - Pallet::::reward_by_ids(vec![(11, 1)]); + Pallet::::reward_by_ids(validator_point); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3429,6 +3480,10 @@ fn six_session_delay() { let val_set = Session::validators(); let init_session = Session::current_index(); let init_active_era = active_era(); + let mut validator_1_point = BoundedBTreeMap::new(); + validator_1_point.try_insert(11, 1); + let mut validator_2_point = BoundedBTreeMap::new(); + validator_2_point.try_insert(21, 2); // pallet-session is delaying session by one, thus the next session to plan is +2. assert_eq!(>::new_session(init_session + 2), None); @@ -3452,7 +3507,7 @@ fn six_session_delay() { assert_eq!(active_era(), init_active_era); // Reward current era - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_1_point); // New active era is triggered here. >::end_session(init_session + 2); @@ -3468,7 +3523,7 @@ fn six_session_delay() { assert_eq!(active_era(), init_active_era + 1); // Reward current era - Staking::reward_by_ids(vec![(21, 2)]); + Staking::reward_by_ids(validator_2_point); // New active era is triggered here. >::end_session(init_session + 5); @@ -3499,7 +3554,9 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( } mock::start_active_era(1); - Pallet::::reward_by_ids(vec![(11, 1)]); + let mut validator_1_era_1 = BoundedBTreeMap::new(); + validator_1_era_1.try_insert(11, 1); + Pallet::::reward_by_ids(validator_1_era_1); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); @@ -3548,6 +3605,10 @@ fn test_payout_stakers() { let mut total_exposure = balance; // Track the exposure of the validator and the nominators that will get paid out. let mut payout_exposure = balance; + + let mut validator_point = BoundedBTreeMap::new(); + validator_point.try_insert(11, 1); + // Create a validator: bond_validator(11, 10, balance); // Default(64) assert_eq!(Validators::::count(), 1); @@ -3564,7 +3625,7 @@ fn test_payout_stakers() { let payout_exposure_part = Perbill::from_rational(payout_exposure, total_exposure); mock::start_active_era(1); - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point.clone()); // compute and ensure the reward amount is greater than zero. let payout = current_total_payout_for_duration(reward_time_per_era()); @@ -3606,7 +3667,7 @@ fn test_payout_stakers() { ); for i in 3..16 { - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point.clone()); // compute and ensure the reward amount is greater than zero. let payout = current_total_payout_for_duration(reward_time_per_era()); @@ -3637,7 +3698,7 @@ fn test_payout_stakers() { ); for i in 16..100 { - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point.clone()); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(i); @@ -3681,6 +3742,8 @@ fn payout_stakers_handles_basic_errors() { // Consumed weight for all payout_stakers dispatches that fail let err_weight = weights::SubstrateWeight::::payout_stakers_alive_staked(0); + let mut validator_point = BoundedBTreeMap::new(); + validator_point.try_insert(11, 1); // Same setup as the test above let balance = 1000; bond_validator(11, 10, balance); // Default(64) @@ -3691,7 +3754,7 @@ fn payout_stakers_handles_basic_errors() { } mock::start_active_era(1); - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point.clone()); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); @@ -3710,7 +3773,7 @@ fn payout_stakers_handles_basic_errors() { ); for i in 3..100 { - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point.clone()); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(i); @@ -3769,8 +3832,11 @@ fn payout_stakers_handles_weight_refund() { // Era 1 start_active_era(1); + let mut validator_point = BoundedBTreeMap::new(); + validator_point.try_insert(11, 1); + // Reward just the validator. - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point.clone()); // Add some `half_max_nom_rewarded` nominators who will start backing the validator in the // next era. @@ -3804,7 +3870,7 @@ fn payout_stakers_handles_weight_refund() { assert_eq!(extract_actual_weight(&result, &info), zero_nom_payouts_weight); // Reward the validator and its nominators. - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point.clone()); // Era 4 start_active_era(4); @@ -3828,7 +3894,7 @@ fn payout_stakers_handles_weight_refund() { // We now have `max_nom_rewarded` nominators actively nominating our validator. // Reward the validator so we can collect for everyone in the next era. - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point); // Era 6 start_active_era(6); @@ -3941,6 +4007,10 @@ fn offences_weight_calculated_correctly() { fn payout_creates_controller() { ExtBuilder::default().has_stakers(false).build_and_execute(|| { let balance = 1000; + + let mut validator_point = BoundedBTreeMap::new(); + validator_point.try_insert(11, 1); + // Create a validator: bond_validator(11, 10, balance); @@ -3952,7 +4022,7 @@ fn payout_creates_controller() { assert_eq!(Balances::free_balance(1337), 0); mock::start_active_era(1); - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(2); @@ -3967,6 +4037,8 @@ fn payout_creates_controller() { fn payout_to_any_account_works() { ExtBuilder::default().has_stakers(false).build_and_execute(|| { let balance = 1000; + let mut validator_point = BoundedBTreeMap::new(); + validator_point.try_insert(11, 1); // Create a validator: bond_validator(11, 10, balance); // Default(64) @@ -3980,7 +4052,7 @@ fn payout_to_any_account_works() { assert_eq!(Balances::free_balance(42), 0); mock::start_active_era(1); - Staking::reward_by_ids(vec![(11, 1)]); + Staking::reward_by_ids(validator_point); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(2); From 71c84eda34f1dfc50ada7dd4c5465985d37d440e Mon Sep 17 00:00:00 2001 From: doordashcon Date: Mon, 29 Aug 2022 22:39:12 +0100 Subject: [PATCH 2/2] needs more work --- bin/node/runtime/src/lib.rs | 2 +- frame/staking/README.md | 8 +- frame/staking/src/benchmarking.rs | 8 +- frame/staking/src/lib.rs | 41 ++++++++-- frame/staking/src/mock.rs | 6 +- frame/staking/src/pallet/impls.rs | 31 +++---- frame/staking/src/pallet/mod.rs | 5 +- frame/staking/src/tests.rs | 132 +++++++++++++++--------------- 8 files changed, 128 insertions(+), 105 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 700ee348aa1b7..bbe234bb1b63e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -569,7 +569,7 @@ impl pallet_staking::Config for Runtime { type OnStakerSlash = NominationPools; type WeightInfo = pallet_staking::weights::SubstrateWeight; type BenchmarkingConfig = StakingBenchmarkingConfig; - type MaxRewardPoints = ConstU32<300>; + type MaxValidators = ConstU32<3072>; } parameter_types! { diff --git a/frame/staking/README.md b/frame/staking/README.md index bbd5bd18f6e81..96a24c7417a90 100644 --- a/frame/staking/README.md +++ b/frame/staking/README.md @@ -152,9 +152,11 @@ pub mod pallet { /// Reward a validator. #[pallet::weight(0)] pub fn reward_myself(origin: OriginFor) -> DispatchResult { - let reported = ensure_signed(origin)?; - >::reward_by_ids(vec![(reported, 10)]); - Ok(()) + let reported = ensure_signed(origin)?; + let mut validator_point = BoundedBTreeMap::new(); + validator_point.try_insert(reported, 10).map_err(|_| staking::Error::::MaxRewardPointsReached)?; + >::reward_by_ids(validator_point); + Ok(()) } } } diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index 88e091b227698..ea8b475852b57 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -77,7 +77,7 @@ pub fn create_validator_with_nominators( // Clean up any existing state. clear_validators_and_nominators::(); let mut points_total = 0; - let mut points_individual = BoundedBTreeMap::::new(); + let mut points_individual = BoundedBTreeMap::new(); let (v_stash, v_controller) = create_stash_controller::(0, 100, destination.clone())?; let validator_prefs = @@ -85,8 +85,8 @@ pub fn create_validator_with_nominators( Staking::::validate(RawOrigin::Signed(v_controller).into(), validator_prefs)?; let stash_lookup = T::Lookup::unlookup(v_stash.clone()); + points_individual.try_insert(v_stash.clone(), 10).expect("maximum reward points reached"); points_total += 10; - points_individual.try_insert(v_stash.clone(), 10).map_err(|_| "Error, are your legs discombubulated").unwrap(); //TODO: Create custom error. let mut nominators = Vec::new(); @@ -747,12 +747,12 @@ benchmarks! { let current_era = CurrentEra::::get().unwrap(); let mut points_total = 0; - let mut points_individual = BoundedBTreeMap::::new(); + let mut points_individual = BoundedBTreeMap::new(); let mut payout_calls_arg = Vec::new(); for validator in new_validators.iter() { points_total += 10; - points_individual.try_insert(validator.clone(), 10).map_err(|_| "error, walk your direction").unwrap(); //TODO: Create custom error.; + points_individual.try_insert(validator.clone(), 10).expect("maximum reward points reached"); payout_calls_arg.push((validator.clone(), current_era)); } diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 2aeffcde919cd..c2d8e43b0be10 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -180,8 +180,8 @@ //! let reported = ensure_signed(origin)?; //! let mut validator_point = BoundedBTreeMap::new(); //! validator_point.try_insert(reported, 10).map_err(|_| staking::Error::::MaxRewardPointsReached)?; -//! >::reward_by_ids(validator_point); -//! Ok(()) +//! >::reward_by_ids(validator_point)?; +//! Ok(()) //! } //! } //! } @@ -302,9 +302,9 @@ pub mod weights; mod pallet; -use codec::{Decode, Encode, HasCompact}; // {Decode, Encode, +use codec::{Decode, Encode, HasCompact}; use frame_support::{ - parameter_types, + defensive, parameter_types, pallet_prelude::{MaxEncodedLen, CloneNoBound}, storage::bounded_btree_map::BoundedBTreeMap, traits::{Currency, Defensive, Get}, @@ -372,10 +372,6 @@ pub struct ActiveEraInfo { /// Reward points of an era. Used to split era total payout between validators. /// /// This points will be used to reward validators and their respective nominators. -/// TODO: this need more comments? -// #[derive(PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)] -// check if i need DefaultnoBound as is in the lib.rs file for nomination_pool -// MaxEncodedLen was also removed from this #[derive(Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebugNoBound, CloneNoBound)] #[cfg_attr(feature = "std", derive(frame_support::PartialEqNoBound))] #[codec(mel_bound(T: Config))] @@ -384,12 +380,39 @@ pub struct EraRewardPoints { /// Total number of points. Equals the sum of reward points for each validator. pub total: u32, /// The reward points earned by a given validator. - pub individual: BoundedBTreeMap, + pub individual: BoundedBTreeMap, } impl Default for EraRewardPoints { fn default() -> Self { EraRewardPoints { total: Default::default(), individual: BoundedBTreeMap::new() } + } +} + +impl EraRewardPoints { + fn add_points(&mut self, validator: T::AccountId, reward_points: u32) -> Result<(), Error> { + let mut points = self.individual.get(&validator).map(|x| *x).unwrap_or_default(); + points += reward_points; + if points < T::MaxValidators::get() { + match self.individual.get_mut(&validator) { + Some(current_reward_points) => + *current_reward_points = + current_reward_points.saturating_add(reward_points), + None => self + .individual + .try_insert(validator.clone(), reward_points.clone()) + .map(|old| { + if old.is_some() { + defensive!("value checked to not exist in the map"); + } + }) + .map_err(|_| Error::::TooManyValidators)?, + } + self.total += reward_points; + Ok(()) + } else { + Err(Error::::TooManyValidators) + } } } diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index c58e2fd42177b..a1e44e16d4cc7 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -302,7 +302,7 @@ impl crate::pallet::pallet::Config for Test { type OnStakerSlash = OnStakerSlashMock; type BenchmarkingConfig = TestBenchmarkingConfig; type WeightInfo = (); - type MaxRewardPoints = ConstU32<300>; + type MaxValidators = ConstU32<3072>; } pub(crate) type StakingCall = crate::Call; @@ -770,12 +770,12 @@ pub(crate) fn reward_time_per_era() -> u64 { } pub(crate) fn reward_all_elected() { - let mut rewards = BoundedBTreeMap::new(); // = ::SessionInterface::validators().into_iter().map(|v| (v, 1)); + let mut rewards = BoundedBTreeMap::new(); for validator in ::SessionInterface::validators().iter() { rewards.try_insert(validator.clone(), 1).expect("Maximum points for validator reached"); }; - >::reward_by_ids(rewards.clone()); + >::reward_by_ids(rewards.clone()).unwrap(); } pub(crate) fn validator_controllers() -> Vec { diff --git a/frame/staking/src/pallet/impls.rs b/frame/staking/src/pallet/impls.rs index 97ec6b281b88b..df57be330f601 100644 --- a/frame/staking/src/pallet/impls.rs +++ b/frame/staking/src/pallet/impls.rs @@ -624,20 +624,16 @@ impl Pallet { /// relatively to their points. /// /// COMPLEXITY: Complexity is `number_of_validator_to_reward x current_elected_len`. - pub fn reward_by_ids(validators_points: BoundedBTreeMap) { + pub fn reward_by_ids(validators_points: BoundedBTreeMap) -> DispatchResult { if let Some(active_era) = Self::active_era() { - >::mutate(active_era.index, |era_rewards| { + >::try_mutate(active_era.index, |era_rewards| -> DispatchResult { for (validator, points) in validators_points.iter() { - let mut indie_points: u32 = 0; - if let Some(prev_indie_points) = era_rewards.individual.remove(&validator) { - indie_points = prev_indie_points; - } - indie_points += points; - era_rewards.individual.try_insert(validator.clone(), indie_points); - era_rewards.total += points; + era_rewards.add_points(validator.clone(), points.clone())?; } - }); - } + Ok(()) + })?; + } + Ok(()) } /// Ensures that at the end of the current session there will be a new era. @@ -1134,20 +1130,19 @@ where T: Config + pallet_authorship::Config + pallet_session::Config, { fn note_author(author: T::AccountId) { - // vec![(author, 20)] let mut validator_points = BoundedBTreeMap::new(); - validator_points.try_insert(author, 20); - Self::reward_by_ids(validator_points); + validator_points.try_insert(author, 20).unwrap_or_default(); + + Self::reward_by_ids(validator_points).unwrap(); } fn note_uncle(uncle_author: T::AccountId, _age: T::BlockNumber) { // defensive-only: block author must exist. - // vec![(block_author, 2), (uncle_author, 1)] let mut validator_points = BoundedBTreeMap::new(); if let Some(block_author) = >::author() { - validator_points.try_insert(block_author, 2); - validator_points.try_insert(uncle_author, 1); - Self::reward_by_ids(validator_points); + validator_points.try_insert(block_author, 2).unwrap_or_default(); + validator_points.try_insert(uncle_author, 1).unwrap_or_default(); + Self::reward_by_ids(validator_points).unwrap(); } else { crate::log!(warn, "block author not set, this should never happen"); } diff --git a/frame/staking/src/pallet/mod.rs b/frame/staking/src/pallet/mod.rs index 1c42abdce855c..966a81d3e2658 100644 --- a/frame/staking/src/pallet/mod.rs +++ b/frame/staking/src/pallet/mod.rs @@ -201,8 +201,9 @@ pub mod pallet { /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; - // Maximum reward points for each validator. - type MaxRewardPoints: Get; + // Maximum number of validators. + #[pallet::constant] + type MaxValidators: Get; } #[pallet::type_value] diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index d7474089b9667..268a2f113a368 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -264,26 +264,28 @@ fn rewards_should_work() { let init_balance_100 = Balances::total_balance(&100); let init_balance_101 = Balances::total_balance(&101); let mut validator_1_era_0 = BoundedBTreeMap::new(); - validator_1_era_0.try_insert(11, 50); let mut validator_2_era_0 = BoundedBTreeMap::new(); - validator_2_era_0.try_insert(21, 50); + validator_2_era_0.try_insert(21, 50).unwrap_or_default(); + validator_1_era_0.try_insert(11, 50).unwrap_or_default(); + validator_1_era_0.try_insert(11, 50).unwrap_or_default(); // Set payees Payee::::insert(11, RewardDestination::Controller); Payee::::insert(21, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - Pallet::::reward_by_ids(validator_1_era_0.clone()); - Pallet::::reward_by_ids(validator_1_era_0.clone()); + Pallet::::reward_by_ids(validator_1_era_0.clone()).unwrap(); + Pallet::::reward_by_ids(validator_1_era_0.clone()).unwrap(); + // This is the second validator of the current elected set. - Pallet::::reward_by_ids(validator_2_era_0); + Pallet::::reward_by_ids(validator_2_era_0).unwrap(); // Compute total payout now for whole duration of the session. let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); let maximum_payout = maximum_payout_for_duration(reward_time_per_era()); let mut validator_points_era_0 = BoundedBTreeMap::new(); - validator_points_era_0.try_insert(11, 100); - validator_points_era_0.try_insert(21, 50); + validator_points_era_0.try_insert(11, 100).unwrap_or_default(); + validator_points_era_0.try_insert(21, 50).unwrap_or_default(); start_session(1); assert_eq_uvec!(Session::validators(), vec![11, 21]); @@ -320,7 +322,7 @@ fn rewards_should_work() { ); mock::make_all_reward_payment(0); let mut validator_1_era_1 = BoundedBTreeMap::new(); - validator_1_era_1.try_insert(11, 1); + validator_1_era_1.try_insert(11, 1).unwrap_or_default(); assert_eq_error_rate!( Balances::total_balance(&10), @@ -344,7 +346,7 @@ fn rewards_should_work() { assert_eq_error_rate!(Balances::total_balance(&101), init_balance_101, 2); assert_eq_uvec!(Session::validators(), vec![11, 21]); - Pallet::::reward_by_ids(validator_1_era_1); + Pallet::::reward_by_ids(validator_1_era_1).unwrap(); // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); @@ -582,11 +584,11 @@ fn nominating_and_rewards_should_work() { // the total reward for era 0 let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); let mut validator_1_era_0 = BoundedBTreeMap::new(); - validator_1_era_0.try_insert(41, 1); + validator_1_era_0.try_insert(41, 1).unwrap_or_default(); let mut validator_2_era_0 = BoundedBTreeMap::new(); - validator_2_era_0.try_insert(21, 1); - Pallet::::reward_by_ids(validator_1_era_0); - Pallet::::reward_by_ids(validator_2_era_0); + validator_2_era_0.try_insert(21, 1).unwrap_or_default(); + Pallet::::reward_by_ids(validator_1_era_0).unwrap(); + Pallet::::reward_by_ids(validator_2_era_0).unwrap(); mock::start_active_era(1); @@ -628,11 +630,11 @@ fn nominating_and_rewards_should_work() { // the total reward for era 1 let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); let mut validator_2_era_1 = BoundedBTreeMap::new(); - validator_2_era_1.try_insert(21, 2); + validator_2_era_1.try_insert(21, 2).unwrap_or_default(); let mut validator_3_era_1 = BoundedBTreeMap::new(); - validator_3_era_1.try_insert(11, 1); - Pallet::::reward_by_ids(validator_2_era_1); - Pallet::::reward_by_ids(validator_3_era_1); + validator_3_era_1.try_insert(11, 1).unwrap_or_default(); + Pallet::::reward_by_ids(validator_2_era_1).unwrap(); + Pallet::::reward_by_ids(validator_3_era_1).unwrap(); mock::start_active_era(2); @@ -1013,8 +1015,8 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); let mut validator_1 = BoundedBTreeMap::new(); - validator_1.try_insert(11, 1); - Pallet::::reward_by_ids(validator_1.clone()); + validator_1.try_insert(11, 1).unwrap(); + Pallet::::reward_by_ids(validator_1.clone()).unwrap(); mock::start_active_era(1); mock::make_all_reward_payment(0); @@ -1040,7 +1042,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(validator_1.clone()); + Pallet::::reward_by_ids(validator_1.clone()).unwrap(); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -1071,7 +1073,7 @@ fn reward_destination_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_2 = current_total_payout_for_duration(reward_time_per_era()); - Pallet::::reward_by_ids(validator_1.clone()); + Pallet::::reward_by_ids(validator_1.clone()).unwrap(); mock::start_active_era(3); mock::make_all_reward_payment(2); @@ -1119,8 +1121,8 @@ fn validator_payment_prefs_work() { let total_payout_1 = current_total_payout_for_duration(reward_time_per_era()); let exposure_1 = Staking::eras_stakers(active_era(), 11); let mut validator_1_era_1 = BoundedBTreeMap::new(); - validator_1_era_1.try_insert(11, 1); - Pallet::::reward_by_ids(validator_1_era_1); + validator_1_era_1.try_insert(11, 1).unwrap(); + Pallet::::reward_by_ids(validator_1_era_1).unwrap(); mock::start_active_era(2); mock::make_all_reward_payment(1); @@ -1687,11 +1689,11 @@ fn reward_to_stake_works() { // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); let mut validator_1_era_0 = BoundedBTreeMap::new(); - validator_1_era_0.try_insert(11, 1); + validator_1_era_0.try_insert(11, 1).unwrap(); let mut validator_2_era_0 = BoundedBTreeMap::new(); - validator_2_era_0.try_insert(21, 1); - Pallet::::reward_by_ids(validator_1_era_0); - Pallet::::reward_by_ids(validator_2_era_0); + validator_2_era_0.try_insert(21, 1).unwrap(); + Pallet::::reward_by_ids(validator_1_era_0).unwrap(); + Pallet::::reward_by_ids(validator_2_era_0).unwrap(); // New era --> rewards are paid --> stakes are changed mock::start_active_era(1); @@ -2090,7 +2092,7 @@ fn reward_validator_slashing_validator_does_not_overflow() { let mut validator_1 = BoundedBTreeMap::new(); - validator_1.try_insert(11, 1); + validator_1.try_insert(11, 1).unwrap(); let exposure = Exposure:: { total: stake, own: stake, others: vec![] }; let reward = EraRewardPoints:: { total: 1, @@ -2154,8 +2156,8 @@ fn reward_from_authorship_event_handler_works() { // 21 is rewarded as an uncle producer // 11 is rewarded as a block producer and uncle referencer and uncle producer let mut validator_points = BoundedBTreeMap::new(); - validator_points.try_insert(11, 23); - validator_points.try_insert(21, 1); + validator_points.try_insert(11, 23).unwrap(); + validator_points.try_insert(21, 1).unwrap(); assert_eq!( ErasRewardPoints::::get(active_era()), EraRewardPoints:: { @@ -2175,21 +2177,21 @@ fn add_reward_points_fns_works() { assert_eq_uvec!(Session::validators(), vec![21, 11]); let mut validator_1_era_0 = BoundedBTreeMap::new(); - validator_1_era_0.try_insert(21, 1); + validator_1_era_0.try_insert(21, 1).unwrap(); let mut validator_2_era_0 = BoundedBTreeMap::new(); - validator_2_era_0.try_insert(11, 1); + validator_2_era_0.try_insert(11, 1).unwrap(); - Pallet::::reward_by_ids(validator_1_era_0.clone()); - Pallet::::reward_by_ids(validator_2_era_0.clone()); - Pallet::::reward_by_ids(validator_2_era_0.clone()); - Pallet::::reward_by_ids(validator_1_era_0); - Pallet::::reward_by_ids(validator_2_era_0.clone()); - Pallet::::reward_by_ids(validator_2_era_0); + Pallet::::reward_by_ids(validator_1_era_0.clone()).unwrap(); + Pallet::::reward_by_ids(validator_2_era_0.clone()).unwrap(); + Pallet::::reward_by_ids(validator_2_era_0.clone()).unwrap(); + Pallet::::reward_by_ids(validator_1_era_0).unwrap(); + Pallet::::reward_by_ids(validator_2_era_0.clone()).unwrap(); + Pallet::::reward_by_ids(validator_2_era_0).unwrap(); let mut validator_points = BoundedBTreeMap::new(); - validator_points.try_insert(11, 4); - validator_points.try_insert(21, 2); + validator_points.try_insert(11, 4).unwrap(); + validator_points.try_insert(21, 2).unwrap(); assert_eq!( ErasRewardPoints::::get(active_era()), EraRewardPoints:: { individual: validator_points, total: 6 }, @@ -3369,19 +3371,19 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { let part_for_100 = Perbill::from_rational::(125, 1125); let mut validator_point = BoundedBTreeMap::new(); - validator_point.try_insert(11, 1); + validator_point.try_insert(11, 1).unwrap(); // Check state Payee::::insert(11, RewardDestination::Controller); Payee::::insert(101, RewardDestination::Controller); - Pallet::::reward_by_ids(validator_point.clone()); + Pallet::::reward_by_ids(validator_point.clone()).unwrap(); // Compute total payout now for whole duration as other parameter won't change let total_payout_0 = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(1); - Pallet::::reward_by_ids(validator_point.clone()); + Pallet::::reward_by_ids(validator_point.clone()).unwrap(); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3390,7 +3392,7 @@ fn claim_reward_at_the_last_era_and_no_double_claim_and_invalid_claim() { mock::start_active_era(2); - Pallet::::reward_by_ids(validator_point); + Pallet::::reward_by_ids(validator_point).unwrap(); // Change total issuance in order to modify total payout let _ = Balances::deposit_creating(&999, 1_000_000_000); // Compute total payout now for whole duration as other parameter won't change @@ -3481,9 +3483,9 @@ fn six_session_delay() { let init_session = Session::current_index(); let init_active_era = active_era(); let mut validator_1_point = BoundedBTreeMap::new(); - validator_1_point.try_insert(11, 1); + validator_1_point.try_insert(11, 1).unwrap(); let mut validator_2_point = BoundedBTreeMap::new(); - validator_2_point.try_insert(21, 2); + validator_2_point.try_insert(21, 2).unwrap(); // pallet-session is delaying session by one, thus the next session to plan is +2. assert_eq!(>::new_session(init_session + 2), None); @@ -3507,7 +3509,7 @@ fn six_session_delay() { assert_eq!(active_era(), init_active_era); // Reward current era - Staking::reward_by_ids(validator_1_point); + Staking::reward_by_ids(validator_1_point).unwrap(); // New active era is triggered here. >::end_session(init_session + 2); @@ -3523,7 +3525,7 @@ fn six_session_delay() { assert_eq!(active_era(), init_active_era + 1); // Reward current era - Staking::reward_by_ids(validator_2_point); + Staking::reward_by_ids(validator_2_point).unwrap(); // New active era is triggered here. >::end_session(init_session + 5); @@ -3555,8 +3557,8 @@ fn test_max_nominator_rewarded_per_validator_and_cant_steal_someone_else_reward( mock::start_active_era(1); let mut validator_1_era_1 = BoundedBTreeMap::new(); - validator_1_era_1.try_insert(11, 1); - Pallet::::reward_by_ids(validator_1_era_1); + validator_1_era_1.try_insert(11, 1).unwrap(); + Pallet::::reward_by_ids(validator_1_era_1).unwrap(); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); @@ -3607,7 +3609,7 @@ fn test_payout_stakers() { let mut payout_exposure = balance; let mut validator_point = BoundedBTreeMap::new(); - validator_point.try_insert(11, 1); + validator_point.try_insert(11, 1).unwrap(); // Create a validator: bond_validator(11, 10, balance); // Default(64) @@ -3625,7 +3627,7 @@ fn test_payout_stakers() { let payout_exposure_part = Perbill::from_rational(payout_exposure, total_exposure); mock::start_active_era(1); - Staking::reward_by_ids(validator_point.clone()); + Staking::reward_by_ids(validator_point.clone()).unwrap(); // compute and ensure the reward amount is greater than zero. let payout = current_total_payout_for_duration(reward_time_per_era()); @@ -3667,7 +3669,7 @@ fn test_payout_stakers() { ); for i in 3..16 { - Staking::reward_by_ids(validator_point.clone()); + Staking::reward_by_ids(validator_point.clone()).unwrap(); // compute and ensure the reward amount is greater than zero. let payout = current_total_payout_for_duration(reward_time_per_era()); @@ -3698,7 +3700,7 @@ fn test_payout_stakers() { ); for i in 16..100 { - Staking::reward_by_ids(validator_point.clone()); + Staking::reward_by_ids(validator_point.clone()).unwrap(); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(i); @@ -3743,7 +3745,7 @@ fn payout_stakers_handles_basic_errors() { let err_weight = weights::SubstrateWeight::::payout_stakers_alive_staked(0); let mut validator_point = BoundedBTreeMap::new(); - validator_point.try_insert(11, 1); + validator_point.try_insert(11, 1).unwrap(); // Same setup as the test above let balance = 1000; bond_validator(11, 10, balance); // Default(64) @@ -3754,7 +3756,7 @@ fn payout_stakers_handles_basic_errors() { } mock::start_active_era(1); - Staking::reward_by_ids(validator_point.clone()); + Staking::reward_by_ids(validator_point.clone()).unwrap(); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); @@ -3773,7 +3775,7 @@ fn payout_stakers_handles_basic_errors() { ); for i in 3..100 { - Staking::reward_by_ids(validator_point.clone()); + Staking::reward_by_ids(validator_point.clone()).unwrap(); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(i); @@ -3833,10 +3835,10 @@ fn payout_stakers_handles_weight_refund() { start_active_era(1); let mut validator_point = BoundedBTreeMap::new(); - validator_point.try_insert(11, 1); + validator_point.try_insert(11, 1).unwrap(); // Reward just the validator. - Staking::reward_by_ids(validator_point.clone()); + Staking::reward_by_ids(validator_point.clone()).unwrap(); // Add some `half_max_nom_rewarded` nominators who will start backing the validator in the // next era. @@ -3870,7 +3872,7 @@ fn payout_stakers_handles_weight_refund() { assert_eq!(extract_actual_weight(&result, &info), zero_nom_payouts_weight); // Reward the validator and its nominators. - Staking::reward_by_ids(validator_point.clone()); + Staking::reward_by_ids(validator_point.clone()).unwrap(); // Era 4 start_active_era(4); @@ -3894,7 +3896,7 @@ fn payout_stakers_handles_weight_refund() { // We now have `max_nom_rewarded` nominators actively nominating our validator. // Reward the validator so we can collect for everyone in the next era. - Staking::reward_by_ids(validator_point); + Staking::reward_by_ids(validator_point).unwrap(); // Era 6 start_active_era(6); @@ -4009,7 +4011,7 @@ fn payout_creates_controller() { let balance = 1000; let mut validator_point = BoundedBTreeMap::new(); - validator_point.try_insert(11, 1); + validator_point.try_insert(11, 1).unwrap(); // Create a validator: bond_validator(11, 10, balance); @@ -4022,7 +4024,7 @@ fn payout_creates_controller() { assert_eq!(Balances::free_balance(1337), 0); mock::start_active_era(1); - Staking::reward_by_ids(validator_point); + Staking::reward_by_ids(validator_point).unwrap(); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(2); @@ -4038,7 +4040,7 @@ fn payout_to_any_account_works() { ExtBuilder::default().has_stakers(false).build_and_execute(|| { let balance = 1000; let mut validator_point = BoundedBTreeMap::new(); - validator_point.try_insert(11, 1); + validator_point.try_insert(11, 1).unwrap(); // Create a validator: bond_validator(11, 10, balance); // Default(64) @@ -4052,7 +4054,7 @@ fn payout_to_any_account_works() { assert_eq!(Balances::free_balance(42), 0); mock::start_active_era(1); - Staking::reward_by_ids(validator_point); + Staking::reward_by_ids(validator_point).unwrap(); // compute and ensure the reward amount is greater than zero. let _ = current_total_payout_for_duration(reward_time_per_era()); mock::start_active_era(2);