Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Bound RewardPoints in pallet-staking #12125

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ impl pallet_staking::Config for Runtime {
type OnStakerSlash = NominationPools;
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
type BenchmarkingConfig = StakingBenchmarkingConfig;
type MaxRewardPoints = ConstU32<300>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The number of keys in this map is the number of validators -- staking should have a single MaxValidators, and use that as the bound for this type as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was wondering about that, thanks!

}

parameter_types! {
Expand Down
18 changes: 9 additions & 9 deletions frame/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub fn create_validator_with_nominators<T: Config>(
// Clean up any existing state.
clear_validators_and_nominators::<T>();
let mut points_total = 0;
let mut points_individual = Vec::new();
let mut points_individual = BoundedBTreeMap::<T::AccountId, u32, T::MaxRewardPoints>::new();

let (v_stash, v_controller) = create_stash_controller::<T>(0, 100, destination.clone())?;
let validator_prefs =
Expand All @@ -86,7 +86,7 @@ pub fn create_validator_with_nominators<T: Config>(
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();

Expand Down Expand Up @@ -117,9 +117,9 @@ pub fn create_validator_with_nominators<T: Config>(
assert_ne!(Nominators::<T>::count(), 0);

// Give Era Points
let reward = EraRewardPoints::<T::AccountId> {
let reward = EraRewardPoints::<T> {
total: points_total,
individual: points_individual.into_iter().collect(),
individual: points_individual,
};

let current_era = CurrentEra::<T>::get().unwrap();
Expand Down Expand Up @@ -670,7 +670,7 @@ benchmarks! {
<ErasStakersClipped<T>>::insert(i, dummy(), Exposure::<T::AccountId, BalanceOf<T>>::default());
<ErasValidatorPrefs<T>>::insert(i, dummy(), ValidatorPrefs::default());
<ErasValidatorReward<T>>::insert(i, BalanceOf::<T>::one());
<ErasRewardPoints<T>>::insert(i, EraRewardPoints::<T::AccountId>::default());
<ErasRewardPoints<T>>::insert(i, EraRewardPoints::<T>::default());
<ErasTotalStake<T>>::insert(i, BalanceOf::<T>::one());
ErasStartSessionIndex::<T>::insert(i, i);
}
Expand Down Expand Up @@ -747,19 +747,19 @@ benchmarks! {

let current_era = CurrentEra::<T>::get().unwrap();
let mut points_total = 0;
let mut points_individual = Vec::new();
let mut points_individual = BoundedBTreeMap::<T::AccountId, u32, T::MaxRewardPoints>::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::<T::AccountId> {
let reward = EraRewardPoints::<T> {
total: points_total,
individual: points_individual.into_iter().collect(),
individual: points_individual,
};

ErasRewardPoints::<T>::insert(current_era, reward);
Expand Down
29 changes: 20 additions & 9 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(_);
Expand All @@ -177,7 +178,9 @@
//! #[pallet::weight(0)]
//! pub fn reward_myself(origin: OriginFor<T>) -> DispatchResult {
//! let reported = ensure_signed(origin)?;
//! <staking::Pallet<T>>::reward_by_ids(vec![(reported, 10)]);
//! let mut validator_point = BoundedBTreeMap::new();
//! validator_point.try_insert(reported, 10).map_err(|_| staking::Error::<T>::MaxRewardPointsReached)?;
//! <staking::Pallet<T>>::reward_by_ids(validator_point);
//! Ok(())
//! }
//! }
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<T> = <T as Config>::CurrencyBalance;
Expand Down Expand Up @@ -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<AccountId: Ord> {
/// 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<T: Config> {
/// 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<AccountId, RewardPoint>,
pub individual: BoundedBTreeMap<T::AccountId, u32, T::MaxRewardPoints>,
}

impl<AccountId: Ord> Default for EraRewardPoints<AccountId> {
impl<T: Config> Default for EraRewardPoints<T> {
fn default() -> Self {
EraRewardPoints { total: Default::default(), individual: BTreeMap::new() }
EraRewardPoints { total: Default::default(), individual: BoundedBTreeMap::new() }
}
}

Expand Down
8 changes: 6 additions & 2 deletions frame/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ impl crate::pallet::pallet::Config for Test {
type OnStakerSlash = OnStakerSlashMock<Test>;
type BenchmarkingConfig = TestBenchmarkingConfig;
type WeightInfo = ();
type MaxRewardPoints = ConstU32<300>;
}

pub(crate) type StakingCall = crate::Call<Test>;
Expand Down Expand Up @@ -769,9 +770,12 @@ pub(crate) fn reward_time_per_era() -> u64 {
}

pub(crate) fn reward_all_elected() {
let rewards = <Test as Config>::SessionInterface::validators().into_iter().map(|v| (v, 1));
let mut rewards = BoundedBTreeMap::new(); // = <Test as Config>::SessionInterface::validators().into_iter().map(|v| (v, 1));

<Pallet<Test>>::reward_by_ids(rewards)
for validator in <Test as Config>::SessionInterface::validators().iter() {
rewards.try_insert(validator.clone(), 1).expect("Maximum points for validator reached");
};
<Pallet<Test>>::reward_by_ids(rewards.clone());
}

pub(crate) fn validator_controllers() -> Vec<AccountId> {
Expand Down
24 changes: 19 additions & 5 deletions frame/staking/src/pallet/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -623,11 +624,16 @@ impl<T: Config> Pallet<T> {
/// 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<Item = (T::AccountId, u32)>) {
pub fn reward_by_ids(validators_points: BoundedBTreeMap<T::AccountId, u32, T::MaxRewardPoints>) {
if let Some(active_era) = Self::active_era() {
<ErasRewardPoints<T>>::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;
}
});
Expand Down Expand Up @@ -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) = <pallet_authorship::Pallet<T>>::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");
}
Expand Down
9 changes: 7 additions & 2 deletions frame/staking/src/pallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u32>;
}

#[pallet::type_value]
Expand Down Expand Up @@ -399,7 +402,7 @@ pub mod pallet {
#[pallet::storage]
#[pallet::getter(fn eras_reward_points)]
pub type ErasRewardPoints<T: Config> =
StorageMap<_, Twox64Concat, EraIndex, EraRewardPoints<T::AccountId>, ValueQuery>;
StorageMap<_, Twox64Concat, EraIndex, EraRewardPoints<T>, 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.
Expand Down Expand Up @@ -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,
Expand All @@ -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]
Expand Down
Loading