Skip to content

Commit

Permalink
RewardEra refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
shannonwells committed Jul 11, 2024
1 parent da640fd commit 3c7851c
Show file tree
Hide file tree
Showing 19 changed files with 97 additions and 95 deletions.
3 changes: 3 additions & 0 deletions common/primitives/src/capacity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ use crate::msa::MessageSourceId;
use frame_support::traits::tokens::Balance;
use sp_runtime::DispatchError;

/// The type of a Reward Era
pub type RewardEra = u32;

/// A trait for checking that a target MSA can be staked to.
pub trait TargetValidator {
/// Checks if an MSA is a valid target.
Expand Down
9 changes: 5 additions & 4 deletions pallets/capacity/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use super::*;
use crate::Pallet as Capacity;

use crate::StakingType::*;
use frame_benchmarking::{account, benchmarks, whitelist_account};
use frame_support::{assert_ok, BoundedVec};
use frame_system::RawOrigin;
use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin};
use parity_scale_codec::alloc::vec::Vec;

const SEED: u32 = 0;
Expand Down Expand Up @@ -38,11 +39,11 @@ pub fn set_up_epoch<T: Config>(current_block: BlockNumberFor<T>, current_epoch:
}

pub fn set_era_and_reward_pool_at_block<T: Config>(
era_index: T::RewardEra,
era_index: RewardEra,
started_at: BlockNumberFor<T>,
total_staked_token: BalanceOf<T>,
) {
let era_info: RewardEraInfo<T::RewardEra, BlockNumberFor<T>> =
let era_info: RewardEraInfo<RewardEra, BlockNumberFor<T>> =
RewardEraInfo { era_index, started_at };
CurrentEraInfo::<T>::set(era_info);
CurrentEraProviderBoostTotal::<T>::set(total_staked_token)
Expand Down Expand Up @@ -149,7 +150,7 @@ benchmarks! {
let total_staked_token: BalanceOf<T> = 5_000u32.into();
let started_at: BlockNumberFor<T> = current_block.saturating_sub(<T as Config>::EraLength::get().into());

let current_era: T::RewardEra = (history_limit + 1u32).into();
let current_era: RewardEra = (history_limit + 1u32).into();
CurrentEraInfo::<T>::set(RewardEraInfo{ era_index: current_era, started_at });
fill_reward_pool_chunks::<T>();
}: {
Expand Down
55 changes: 20 additions & 35 deletions pallets/capacity/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use frame_support::{
},
weights::{constants::RocksDbWeight, Weight},
};

use frame_system::pallet_prelude::BlockNumberFor;
use sp_runtime::{
traits::{CheckedAdd, CheckedDiv, One, Saturating, Zero},
ArithmeticError, BoundedVec, DispatchError, Perbill, Permill,
Expand All @@ -50,7 +50,6 @@ pub use common_primitives::{

#[cfg(feature = "runtime-benchmarks")]
use common_primitives::benchmarks::RegisterProviderBenchmarkHelper;

pub use pallet::*;
pub use types::*;
pub use weights::*;
Expand All @@ -66,18 +65,23 @@ mod tests;
/// storage migrations
pub mod migration;
pub mod weights;
pub(crate) type BalanceOf<T> =
type BalanceOf<T> =
<<T as Config>::Currency as InspectFungible<<T as frame_system::Config>::AccountId>>::Balance;

use crate::StakingType::{MaximumCapacity, ProviderBoost};
use crate::StakingType::ProviderBoost;
use common_primitives::capacity::RewardEra;
use frame_system::pallet_prelude::*;

#[frame_support::pallet]
pub mod pallet {
use super::*;

use frame_support::{pallet_prelude::*, Twox64Concat};
use parity_scale_codec::EncodeLike;
use crate::StakingType::MaximumCapacity;
use common_primitives::capacity::RewardEra;
use frame_support::{
pallet_prelude::{StorageVersion, *},
Twox64Concat,
};
use sp_runtime::traits::{AtLeast32BitUnsigned, MaybeDisplay};

/// A reason for freezing funds.
Expand Down Expand Up @@ -153,24 +157,6 @@ pub mod pallet {
#[pallet::constant]
type CapacityPerToken: Get<Perbill>;

/// A period of `EraLength` blocks in which a Staking Pool applies and
/// when Provider Boost Rewards may be earned.
type RewardEra: Parameter
+ Member
+ MaybeSerializeDeserialize
+ MaybeDisplay
+ AtLeast32BitUnsigned
+ Default
+ Copy
+ sp_std::hash::Hash
+ MaxEncodedLen
+ EncodeLike
+ Into<BalanceOf<Self>>
+ Into<BlockNumberFor<Self>>
+ Into<u32>
+ EncodeLike<u32>
+ TypeInfo;

/// The number of blocks in a RewardEra
#[pallet::constant]
type EraLength: Get<u32>;
Expand Down Expand Up @@ -272,7 +258,7 @@ pub mod pallet {
#[pallet::whitelist_storage]
#[pallet::getter(fn get_current_era)]
pub type CurrentEraInfo<T: Config> =
StorageValue<_, RewardEraInfo<T::RewardEra, BlockNumberFor<T>>, ValueQuery>;
StorageValue<_, RewardEraInfo<RewardEra, BlockNumberFor<T>>, ValueQuery>;

/// Reward Pool history is divided into chunks of size RewardPoolChunkLength.
/// ProviderBoostHistoryLimit is the total number of items, the key is the
Expand Down Expand Up @@ -949,8 +935,7 @@ impl<T: Config> Pallet<T> {
}

fn start_new_reward_era_if_needed(current_block: BlockNumberFor<T>) -> Weight {
let current_era_info: RewardEraInfo<T::RewardEra, BlockNumberFor<T>> =
Self::get_current_era(); // 1r
let current_era_info: RewardEraInfo<RewardEra, BlockNumberFor<T>> = Self::get_current_era(); // 1r

if current_block.saturating_sub(current_era_info.started_at) >= T::EraLength::get().into() {
// 1r
Expand All @@ -976,7 +961,7 @@ impl<T: Config> Pallet<T> {
/// Returns:
/// Error::MaxRetargetsExceeded if they try to retarget too many times in one era.
fn update_retarget_record(staker: &T::AccountId) -> Result<(), DispatchError> {
let current_era: T::RewardEra = Self::get_current_era().era_index;
let current_era: RewardEra = Self::get_current_era().era_index;
let mut retargets = Self::get_retargets_for(staker).unwrap_or_default();
ensure!(retargets.update(current_era).is_some(), Error::<T>::MaxRetargetsExceeded);
Retargets::<T>::set(staker, Some(retargets));
Expand Down Expand Up @@ -1014,7 +999,7 @@ impl<T: Config> Pallet<T> {
/// pass 'false' for a decrease (unstake)
pub(crate) fn upsert_boost_history(
account: &T::AccountId,
current_era: T::RewardEra,
current_era: RewardEra,
boost_amount: BalanceOf<T>,
add: bool,
) -> Result<(), DispatchError> {
Expand Down Expand Up @@ -1113,7 +1098,7 @@ impl<T: Config> Pallet<T> {

// Returns the block number for the end of the provided era. Assumes `era` is at least this
// era or in the future
pub(crate) fn block_at_end_of_era(era: T::RewardEra) -> BlockNumberFor<T> {
pub(crate) fn block_at_end_of_era(era: RewardEra) -> BlockNumberFor<T> {
let current_era_info = Self::get_current_era();
let era_length: BlockNumberFor<T> = T::EraLength::get().into();

Expand All @@ -1127,8 +1112,8 @@ impl<T: Config> Pallet<T> {

// Figure out the history chunk that a given era is in and pull out the total stake for that era.
pub(crate) fn get_total_stake_for_past_era(
reward_era: T::RewardEra,
current_era: T::RewardEra,
reward_era: RewardEra,
current_era: RewardEra,
) -> Result<BalanceOf<T>, DispatchError> {
// Make sure that the past era is not too old
let era_range = current_era.saturating_sub(reward_era);
Expand All @@ -1153,7 +1138,7 @@ impl<T: Config> Pallet<T> {
/// - The second step is which chunk to add to:
/// - Divide the cycle by the chunk length and take the floor
/// - Floor(5 / 3) = 1
pub(crate) fn get_chunk_index_for_era(era: T::RewardEra) -> u32 {
pub(crate) fn get_chunk_index_for_era(era: RewardEra) -> u32 {
let history_limit: u32 = T::ProviderBoostHistoryLimit::get();
let chunk_len = T::RewardPoolChunkLength::get();
// Remove one because eras are 1 indexed
Expand All @@ -1170,7 +1155,7 @@ impl<T: Config> Pallet<T> {
// - [6], [2,3], [4,5]
// - [6,7], [2,3], [4,5]
// - [6,7], [8], [4,5]
pub(crate) fn update_provider_boost_reward_pool(era: T::RewardEra, boost_total: BalanceOf<T>) {
pub(crate) fn update_provider_boost_reward_pool(era: RewardEra, boost_total: BalanceOf<T>) {
// Current era is this era
let chunk_idx: u32 = Self::get_chunk_index_for_era(era);
let mut new_chunk =
Expand Down Expand Up @@ -1268,7 +1253,7 @@ impl<T: Config> Replenishable for Pallet<T> {

impl<T: Config> ProviderBoostRewardsProvider<T> for Pallet<T> {
type AccountId = T::AccountId;
type RewardEra = T::RewardEra;
type RewardEra = common_primitives::capacity::RewardEra;
type Hash = T::Hash;
type Balance = BalanceOf<T>;

Expand Down
3 changes: 2 additions & 1 deletion pallets/capacity/src/migration/provider_boost_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use frame_support::{
traits::{Get, OnRuntimeUpgrade},
};

use common_primitives::capacity::RewardEra;
#[cfg(feature = "try-runtime")]
use sp_std::vec::Vec;

Expand All @@ -15,7 +16,7 @@ impl<T: Config> OnRuntimeUpgrade for ProviderBoostInit<T> {
let current_era_info = CurrentEraInfo::<T>::get(); // 1r
if current_era_info.eq(&RewardEraInfo::default()) {
let current_block = frame_system::Pallet::<T>::block_number(); // Whitelisted
let era_index: T::RewardEra = 1u32.into();
let era_index: RewardEra = 1u32.into();
CurrentEraInfo::<T>::set(RewardEraInfo { era_index, started_at: current_block }); // 1w
CurrentEraProviderBoostTotal::<T>::set(0u32.into()); // 1w
T::DbWeight::get().reads_writes(2, 1)
Expand Down
15 changes: 7 additions & 8 deletions pallets/capacity/src/tests/change_staking_target_tests.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::{
mock::*,
testing_utils::{setup_provider, staking_events},
testing_utils::{capacity_events, setup_provider},
};
use crate::*;
use crate::{StakingType::*, *};
use common_primitives::msa::MessageSourceId;
use frame_support::{assert_noop, assert_ok, traits::Get};

Expand Down Expand Up @@ -229,7 +229,7 @@ fn change_staking_starget_emits_event_on_success() {
to_msa,
to_amount
));
let events = staking_events();
let events = capacity_events();

assert_eq!(
events.last().unwrap(),
Expand Down Expand Up @@ -425,7 +425,7 @@ fn impl_retarget_info_errors_when_attempt_to_update_past_bounded_max() {
TestCase { era: 1u32, retargets: 5u32, last_retarget: 1, expected: None },
] {
let mut retarget_info: RetargetInfo<Test> =
RetargetInfo { retarget_count: tc.retargets, last_retarget_at: tc.last_retarget };
RetargetInfo::new(tc.retargets, tc.last_retarget);
assert_eq!(retarget_info.update(tc.era), tc.expected);
}
})
Expand All @@ -448,7 +448,7 @@ fn impl_retarget_info_updates_values_correctly() {
TestCase { era: 1, retargets: 5, last_retarget: 1, expected_retargets: 5 },
] {
let mut retarget_info: RetargetInfo<Test> =
RetargetInfo { retarget_count: tc.retargets, last_retarget_at: tc.last_retarget };
RetargetInfo::new(tc.retargets, tc.last_retarget);
retarget_info.update(tc.era);
assert_eq!(retarget_info.retarget_count, tc.expected_retargets);
}
Expand All @@ -459,10 +459,9 @@ fn impl_retarget_info_updates_values_correctly() {
fn impl_retarget_chunks_cleanup_when_new_reward_era() {
new_test_ext().execute_with(|| {
let current_era = 2u32;
let mut retarget_info: RetargetInfo<Test> =
RetargetInfo { retarget_count: 5, last_retarget_at: 1 };
let mut retarget_info: RetargetInfo<Test> = RetargetInfo::new(5, 1);
assert!(retarget_info.update(current_era).is_some());
let expected: RetargetInfo<Test> = RetargetInfo { retarget_count: 1, last_retarget_at: 2 };
let expected: RetargetInfo<Test> = RetargetInfo::new(1, 2);
assert_eq!(retarget_info, expected);
});
}
9 changes: 4 additions & 5 deletions pallets/capacity/src/tests/eras_tests.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use super::mock::*;
use crate::{
tests::testing_utils::*, BalanceOf, Config, CurrentEraInfo, CurrentEraProviderBoostTotal,
RewardEraInfo,
tests::testing_utils::*, BalanceOf, CurrentEraInfo, CurrentEraProviderBoostTotal, RewardEraInfo,
};
use common_primitives::msa::MessageSourceId;
use common_primitives::{capacity::RewardEra, msa::MessageSourceId};
use frame_support::assert_ok;

pub fn boost_provider_and_run_to_end_of_era(
Expand Down Expand Up @@ -44,7 +43,7 @@ fn start_new_era_if_needed_updates_era_info() {
fn assert_chunk_is_full_and_has_earliest_era_total(
chunk_index: u32,
is_full: bool,
era: <Test as Config>::RewardEra,
era: RewardEra,
total: BalanceOf<Test>,
) {
let chunk = Capacity::get_reward_pool_chunk(chunk_index).unwrap();
Expand All @@ -55,7 +54,7 @@ fn assert_chunk_is_full_and_has_earliest_era_total(

// gets the last (i.e. latest non-current) stored reward pool era, which is in chunk 0.
// asserts that it is the same as `era`, and that it has amount `total`
fn assert_last_era_total(era: <Test as Config>::RewardEra, total: BalanceOf<Test>) {
fn assert_last_era_total(era: RewardEra, total: BalanceOf<Test>) {
let chunk_idx = Capacity::get_chunk_index_for_era(era);
let chunk_opt = Capacity::get_reward_pool_chunk(chunk_idx);
assert!(chunk_opt.is_some(), "No pool for Era: {:?} with chunk index: {:?}", era, chunk_idx);
Expand Down
3 changes: 1 addition & 2 deletions pallets/capacity/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ impl ProviderBoostRewardsProvider<Test> for TestRewardsProvider {
}

fn staking_reward_totals(
account_id: Self::AccountId,
_account_id: Self::AccountId,
) -> Result<
BoundedVec<UnclaimedRewardInfo<Test>, <Test as Config>::ProviderBoostHistoryLimit>,
DispatchError,
Expand Down Expand Up @@ -197,7 +197,6 @@ impl pallet_capacity::Config for Test {
type MaxEpochLength = ConstU32<100>;
type EpochNumber = u32;
type CapacityPerToken = TestCapacityPerToken;
type RewardEra = TestRewardEra;
type EraLength = ConstU32<10>;
type ProviderBoostHistoryLimit = ConstU32<12>;
type RewardsProvider = Capacity;
Expand Down
5 changes: 3 additions & 2 deletions pallets/capacity/src/tests/provider_boost_history_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
Config, ProviderBoostHistory,
StakingType::{MaximumCapacity, ProviderBoost},
};
use common_primitives::capacity::RewardEra;
use frame_support::assert_ok;
use sp_runtime::traits::{Get, Zero};

Expand Down Expand Up @@ -71,12 +72,12 @@ fn provider_boost_history_add_era_balance_adds_entries_and_deletes_old_if_full()
}
assert_eq!(pbh.count(), bound as usize);

let new_era: <Test as Config>::RewardEra = 99;
let new_era: RewardEra = 99;
pbh.add_era_balance(&new_era, &1000u64);
assert_eq!(pbh.count(), bound as usize);
assert!(pbh.get_entry_for_era(&new_era).is_some());

let first_era: <Test as Config>::RewardEra = 1;
let first_era: RewardEra = 1;
assert!(pbh.get_entry_for_era(&first_era).is_none());
}

Expand Down
2 changes: 1 addition & 1 deletion pallets/capacity/src/tests/provider_boost_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn provider_boost_works() {
let capacity_details = Capacity::get_capacity_for(target).unwrap();
assert_eq!(capacity_details.total_capacity_issued, capacity);

let events = staking_events();
let events = capacity_events();
assert_eq!(
events.first().unwrap(),
&Event::ProviderBoosted { account, target, amount, capacity }
Expand Down
3 changes: 2 additions & 1 deletion pallets/capacity/src/tests/reward_pool_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use crate::{
tests::{mock::*, testing_utils::set_era_and_reward_pool},
BalanceOf, Config, ProviderBoostRewardPools, RewardPoolHistoryChunk,
};
use common_primitives::capacity::RewardEra;
use frame_support::{assert_ok, traits::Get};
use std::ops::Add;

// Check eras_tests for how reward pool chunks are expected to be filled during
// runtime.
fn fill_reward_pool_history_chunk(
chunk_index: u32,
starting_era: <Test as Config>::RewardEra,
starting_era: RewardEra,
number_of_items: u32,
starting_total_stake: BalanceOf<Test>,
) {
Expand Down
10 changes: 5 additions & 5 deletions pallets/capacity/src/tests/rewards_provider_tests.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use super::mock::*;
use crate::{
Config, CurrentEraInfo, Error, ProviderBoostHistories, ProviderBoostHistory,
ProviderBoostRewardsProvider, RewardEraInfo, StakingDetails, StakingType::*,
UnclaimedRewardInfo,
Config, ProviderBoostHistories, ProviderBoostHistory, ProviderBoostRewardsProvider,
StakingType::*, UnclaimedRewardInfo,
};
use frame_support::{assert_err, assert_ok, traits::Len};
use frame_support::{assert_ok, traits::Len};
use frame_system::pallet_prelude::BlockNumberFor;

use crate::tests::testing_utils::{
run_to_block, set_era_and_reward_pool, setup_provider, system_run_to_block,
};
use common_primitives::msa::MessageSourceId;
use sp_core::{Get, H256};
use sp_core::Get;

// This tests Capacity implementation of the trait, but uses the mock's constants,
// to ensure that it's correctly specified in the pallet.
Expand Down
Loading

0 comments on commit 3c7851c

Please sign in to comment.