Skip to content

Commit 998b3b0

Browse files
committed
Implement Staking Reward Eras basics (#1589)
Implement the basic functionality of tracking and rotating Reward Era. Closes #1567 Does not include anything to do with the Reward Pool. - [x] Chain spec updated - [x] Design doc(s) updated - [x] Tests added
1 parent fec46c7 commit 998b3b0

File tree

4 files changed

+70
-10
lines changed

4 files changed

+70
-10
lines changed

pallets/capacity/src/lib.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub use common_primitives::{
7070

7171
#[cfg(feature = "runtime-benchmarks")]
7272
use common_primitives::benchmarks::RegisterProviderBenchmarkHelper;
73-
use common_primitives::{capacity::StakingType, node::RewardEra};
73+
use common_primitives::capacity::StakingType;
7474

7575
pub use pallet::*;
7676
pub use types::*;
@@ -231,6 +231,12 @@ pub mod pallet {
231231
pub type EpochLength<T: Config> =
232232
StorageValue<_, T::BlockNumber, ValueQuery, EpochLengthDefault<T>>;
233233

234+
/// Information for the current era
235+
#[pallet::storage]
236+
#[pallet::getter(fn get_current_era)]
237+
pub type CurrentEraInfo<T: Config> =
238+
StorageValue<_, RewardEraInfo<T::RewardEra, T::BlockNumber>, ValueQuery>;
239+
234240
// Simple declaration of the `Pallet` type. It is placeholder we use to implement traits and
235241
// method.
236242
#[pallet::pallet]
@@ -325,6 +331,7 @@ pub mod pallet {
325331
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
326332
fn on_initialize(current: T::BlockNumber) -> Weight {
327333
Self::start_new_epoch_if_needed(current)
334+
.saturating_add(Self::start_new_reward_era_if_needed(current))
328335
}
329336
}
330337

@@ -631,7 +638,23 @@ impl<T: Config> Pallet<T> {
631638
.saturating_add(T::DbWeight::get().writes(2))
632639
} else {
633640
// 1 for get_current_epoch_info, 1 for get_epoch_length
634-
T::DbWeight::get().reads(2u64).saturating_add(RocksDbWeight::get().writes(1))
641+
T::DbWeight::get().reads(2).saturating_add(RocksDbWeight::get().writes(1))
642+
}
643+
}
644+
645+
fn start_new_reward_era_if_needed(current_block: T::BlockNumber) -> Weight {
646+
let current_era_info: RewardEraInfo<T::RewardEra, T::BlockNumber> = Self::get_current_era();
647+
if current_block.saturating_sub(current_era_info.era_start) >= T::EraLength::get().into() {
648+
CurrentEraInfo::<T>::set(RewardEraInfo {
649+
current_era: current_era_info.current_era.saturating_add(1u8.into()),
650+
era_start: current_block,
651+
});
652+
// TODO: modify reads/writes as needed when RewardPoolInfo stuff is added
653+
T::WeightInfo::on_initialize()
654+
.saturating_add(T::DbWeight::get().reads(1))
655+
.saturating_add(T::DbWeight::get().writes(1))
656+
} else {
657+
T::DbWeight::get().reads(2).saturating_add(RocksDbWeight::get().writes(1))
635658
}
636659
}
637660

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use super::mock::*;
2+
use crate::{
3+
tests::testing_utils::{run_to_block, system_run_to_block},
4+
Config, CurrentEraInfo, Error, Event, RewardEraInfo,
5+
};
6+
7+
use frame_support::traits::Get;
8+
9+
#[test]
10+
fn start_new_era_if_needed() {
11+
new_test_ext().execute_with(|| {
12+
CurrentEraInfo::<Test>::set(RewardEraInfo { current_era: 1, era_start: 0 });
13+
system_run_to_block(9);
14+
run_to_block(10);
15+
let mut current_era_info = CurrentEraInfo::<Test>::get();
16+
assert_eq!(current_era_info.current_era, 2u32);
17+
assert_eq!(current_era_info.era_start, 10u32);
18+
19+
system_run_to_block(19);
20+
run_to_block(20);
21+
current_era_info = CurrentEraInfo::<Test>::get();
22+
assert_eq!(current_era_info.current_era, 3u32);
23+
assert_eq!(current_era_info.era_start, 20u32);
24+
})
25+
}

pallets/capacity/src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod capacity_details_tests;
22
pub mod epochs_tests;
3+
mod eras_tests;
34
pub mod mock;
45
pub mod other_tests;
56
pub mod replenishment_tests;

pallets/capacity/src/types.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ pub struct StakingAccountDetails<T: Config> {
2929
/// What type of staking this account is doing
3030
pub staking_type: StakingType,
3131
/// The None or Some(number): never, or the last RewardEra that this account's rewards were claimed.
32-
pub last_rewards_claimed_at: Option<RewardEra>,
32+
pub last_rewards_claimed_at: Option<T::RewardEra>,
3333
/// Chunks that have been retargeted within T::UnstakingThawPeriod
3434
pub stake_change_unlocking:
35-
BoundedVec<UnlockChunk<BalanceOf<T>, RewardEra>, T::MaxUnlockingChunks>,
35+
BoundedVec<UnlockChunk<BalanceOf<T>, T::RewardEra>, T::MaxUnlockingChunks>,
3636
}
3737

3838
/// The type that is used to record a single request for a number of tokens to be unlocked.
@@ -260,25 +260,25 @@ pub struct StakingRewardClaim<T: Config> {
260260
/// The end state of the staking account if the operations are valid
261261
pub staking_account_end_state: StakingAccountDetails<T>,
262262
/// The starting era for the claimed reward period, inclusive
263-
pub from_era: RewardEra,
263+
pub from_era: T::RewardEra,
264264
/// The ending era for the claimed reward period, inclusive
265-
pub to_era: RewardEra,
265+
pub to_era: T::RewardEra,
266266
}
267267

268268
/// A trait that provides the Economic Model for Provider Boosting.
269269
pub trait StakingRewardsProvider<T: Config> {
270270
/// Return the size of the reward pool for the given era, in token
271271
/// Errors:
272272
/// - EraOutOfRange when `era` is prior to the history retention limit, or greater than the current Era.
273-
fn reward_pool_size(era: RewardEra) -> BalanceOf<T>;
273+
fn reward_pool_size(era: T::RewardEra) -> BalanceOf<T>;
274274

275275
/// Return the total unclaimed reward in token for `accountId` for `from_era` --> `to_era`, inclusive
276276
/// Errors:
277277
/// - EraOutOfRange when from_era or to_era are prior to the history retention limit, or greater than the current Era.
278278
fn staking_reward_total(
279-
account_id: AccountId,
280-
from_era: RewardEra,
281-
to_era: RewardEra,
279+
account_id: T::AccountId,
280+
from_era: T::RewardEra,
281+
to_era: T::RewardEra,
282282
) -> BalanceOf<T>;
283283

284284
/// Validate a payout claim for `accountId`, using `proof` and the provided `payload` StakingRewardClaim.
@@ -303,5 +303,16 @@ pub trait StakingRewardsProvider<T: Config> {
303303
fn payout_eligible(account_id: AccountId) -> bool;
304304
}
305305

306+
/// The information needed to track a Reward Era
307+
#[derive(
308+
PartialEq, Eq, Clone, Default, PartialOrd, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen,
309+
)]
310+
pub struct RewardEraInfo<RewardEra, BlockNumber> {
311+
/// the index of this era
312+
pub current_era: RewardEra,
313+
/// the starting block of this era
314+
pub era_start: BlockNumber,
315+
}
316+
306317
/// Needed data about a RewardPool for a given RewardEra.
307318
pub struct RewardPoolInfo {}

0 commit comments

Comments
 (0)