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

Commit 9cbae9d

Browse files
committed
address comments
1 parent bf65044 commit 9cbae9d

File tree

2 files changed

+31
-34
lines changed

2 files changed

+31
-34
lines changed

srml/staking/src/lib.rs

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,15 @@ const STAKING_ID: LockIdentifier = *b"staking ";
305305
/// Counter for the number of eras that have passed.
306306
pub type EraIndex = u32;
307307

308+
/// Reward of an era.
309+
#[derive(Encode, Decode, Default)]
310+
pub struct EraRewards {
311+
total: u32,
312+
/// Reward at one index correspond to reward for validator in current_elected of this index.
313+
/// Thus this reward vec is only valid for one elected set.
314+
rewards: Vec<u32>,
315+
}
316+
308317
/// Indicates the initial status of the staker.
309318
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
310319
pub enum StakerStatus<AccountId> {
@@ -483,8 +492,6 @@ decl_storage! {
483492
/// Minimum number of staking participants before emergency conditions are imposed.
484493
pub MinimumValidatorCount get(minimum_validator_count) config():
485494
u32 = DEFAULT_MINIMUM_VALIDATOR_COUNT;
486-
/// Maximum reward, per validator, that is provided per acceptable session.
487-
pub SessionReward get(session_reward) config(): Perbill = Perbill::from_parts(60);
488495
/// Slash, per validator that is taken for the first time they are found to be offline.
489496
pub OfflineSlash get(offline_slash) config(): Perbill = Perbill::from_millionths(1000);
490497
/// Number of instances of offline reports before slashing begins for validators.
@@ -531,14 +538,11 @@ decl_storage! {
531538
/// The current era index.
532539
pub CurrentEra get(current_era) config(): EraIndex;
533540

534-
/// The accumulated reward for the current era. Reset to zero at the beginning of the era and
535-
/// increased for every successfully finished session.
541+
/// The start of the current era.
536542
pub CurrentEraStart get(current_era_start): T::Moment;
537543

538-
/// A vec of validator to reward and their associated number of points.
539-
/// A validator can appear in many elements of this vec.
540-
// TODO TODO: should we use such a structure ? aggregate with an existing one ? use a map ?
541-
pub CurrentEraRewards: Vec<(T::AccountId, u32)>;
544+
/// Rewards for the current era. Using indices of current elected set.
545+
pub CurrentEraRewards: EraRewards;
542546

543547
/// The amount of balance actively at stake for each validator slot, currently.
544548
///
@@ -905,8 +909,18 @@ decl_module! {
905909
///
906910
/// At the end of the era each the total payout will be distributed among validator
907911
/// relatively to their points.
908-
fn add_reward_points_to_validators(add: Vec<(T::AccountId, u32)>) {
909-
<CurrentEraRewards<T>>::append(&add[..]).unwrap();
912+
fn add_reward_points_to_validator(validator: T::AccountId, points: u32) {
913+
<Module<T>>::current_elected().iter()
914+
.position(|elected| *elected == validator)
915+
.map(|index| {
916+
<CurrentEraRewards<T>>::mutate(|rewards| {
917+
if let Some(new_total) = rewards.total.checked_add(points) {
918+
rewards.total = new_total;
919+
rewards.rewards.resize(index + 1, 0);
920+
rewards.rewards[index] += points; // Addition is less than total
921+
}
922+
})
923+
});
910924
}
911925
}
912926
}
@@ -1018,8 +1032,6 @@ impl<T: Trait> Module<T> {
10181032

10191033
/// Session has just ended. Provide the validator set for the next session if it's an era-end.
10201034
fn new_session(session_index: SessionIndex) -> Option<Vec<T::AccountId>> {
1021-
// TODO TODO: previous implementation was accumulating reward here, should we accumulate
1022-
// duration in a way ?
10231035
if <ForceNewEra<T>>::take() || session_index % T::SessionsPerEra::get() == 0 {
10241036
Self::new_era()
10251037
} else {
@@ -1045,34 +1057,21 @@ impl<T: Trait> Module<T> {
10451057
let validator_len: BalanceOf<T> = (validators.len() as u32).into();
10461058
let total_rewarded_stake = Self::slot_stake() * validator_len;
10471059

1048-
let mut total_points = 0u32;
1049-
let mut points_for_validator = BTreeMap::new();
1050-
for (validator, reward) in rewards {
1051-
// If the total number of points exceed u32::MAX then they are dismissed
1052-
// TODO TODO: if this is a problem we can use u64
1053-
if let Some(p) = total_points.checked_add(reward) {
1054-
total_points = p;
1055-
1056-
// Cannot overflow as inferior to total_points
1057-
*points_for_validator.entry(validator).or_insert(0) += reward;
1058-
}
1059-
}
1060-
1061-
// TODO TODO: does this should be generic ?
10621060
let total_payout = inflation::compute_total_payout(
10631061
total_rewarded_stake.clone(),
10641062
T::Currency::total_issuance(),
10651063
<BalanceOf<T>>::from(
1066-
// Era of duration more than u32::MAX is rewarded as u32::max_value.
1064+
// Era of duration more than u32::MAX is rewarded as u32::MAX.
10671065
TryInto::<u32>::try_into(era_duration).unwrap_or(u32::max_value())
10681066
),
10691067
);
10701068

10711069
let mut total_imbalance = <PositiveImbalanceOf<T>>::zero();
10721070

1073-
for v in validators.iter() {
1074-
if let Some(&points) = points_for_validator.get(v) {
1075-
let reward = multiply_by_fraction(total_payout, points, total_points);
1071+
let total_points = rewards.total;
1072+
for (v, points) in validators.iter().zip(rewards.rewards.into_iter()) {
1073+
if points != 0 {
1074+
let reward = multiply_by_rational(total_payout, points, total_points);
10761075
total_imbalance.subsume(Self::reward_validator(v, reward));
10771076
}
10781077
}
@@ -1289,7 +1288,7 @@ impl<T: Trait> OnFreeBalanceZero<T::AccountId> for Module<T> {
12891288

12901289
// This is guarantee not to overflow on whatever values.
12911290
// `num` must be inferior to `den` otherwise it will be reduce to `den`.
1292-
fn multiply_by_fraction<N>(value: N, num: u32, den: u32) -> N
1291+
fn multiply_by_rational<N>(value: N, num: u32, den: u32) -> N
12931292
where N: SimpleArithmetic + Clone
12941293
{
12951294
let num = num.min(den);
@@ -1303,8 +1302,7 @@ fn multiply_by_fraction<N>(value: N, num: u32, den: u32) -> N
13031302
let rem_u32 = rem.saturated_into::<u32>();
13041303

13051304
// Multiplication fits into u64 as both term are u32
1306-
let rem_part = rem_u32 as u64 * num as u64
1307-
/ den as u64;
1305+
let rem_part = rem_u32 as u64 * num as u64 / den as u64;
13081306

13091307
// Result fits into u32 as num < total_points
13101308
(rem_part as u32).into()

srml/staking/src/mock.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,6 @@ impl ExtBuilder {
235235
],
236236
validator_count: self.validator_count,
237237
minimum_validator_count: self.minimum_validator_count,
238-
session_reward: Perbill::from_millionths((1000000 * self.reward / balance_factor) as u32),
239238
offline_slash: Perbill::from_percent(5),
240239
current_session_reward: self.reward,
241240
offline_slash_grace: 0,

0 commit comments

Comments
 (0)