Skip to content

Commit

Permalink
Feat/staking rewards rewards provider #1572 (#1598)
Browse files Browse the repository at this point in the history
The goal of this PR is to implement a really basic version of the
StakingRewardsProvider in the Capacity pallet and in the test mock,
neither of which is actively used.

Closes #1572

Does not include anything to do with setting and storing RewardPoolInfo
when each new Era starts.

- [x] Design doc(s) updated
- [x] Tests added
  • Loading branch information
shannonwells committed Jul 18, 2024
1 parent 5da4e63 commit 7ad5c9a
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 35 deletions.
2 changes: 1 addition & 1 deletion common/primitives/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub type Signature = MultiSignature;
/// Index of a transaction in the chain.
pub type Index = u32;

/// the time period in blocks that Staking Rewards are based upon
/// the type used for the index of the Staking Reward time period
pub type RewardEra = u32;

/// A hash of some data used by the chain.
Expand Down
14 changes: 6 additions & 8 deletions pallets/capacity/src/tests/eras_tests.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
use super::mock::*;
use crate::{
tests::testing_utils::{run_to_block, system_run_to_block},
Config, CurrentEraInfo, Error, Event, RewardEraInfo,
CurrentEraInfo, RewardEraInfo,
};

use frame_support::traits::Get;

#[test]
fn start_new_era_if_needed() {
new_test_ext().execute_with(|| {
CurrentEraInfo::<Test>::set(RewardEraInfo { current_era: 1, era_start: 0 });
CurrentEraInfo::<Test>::set(RewardEraInfo { era_index: 1, started_at: 0 });
system_run_to_block(9);
run_to_block(10);
let mut current_era_info = CurrentEraInfo::<Test>::get();
assert_eq!(current_era_info.current_era, 2u32);
assert_eq!(current_era_info.era_start, 10u32);
assert_eq!(current_era_info.era_index, 2u32);
assert_eq!(current_era_info.started_at, 10u32);

system_run_to_block(19);
run_to_block(20);
current_era_info = CurrentEraInfo::<Test>::get();
assert_eq!(current_era_info.current_era, 3u32);
assert_eq!(current_era_info.era_start, 20u32);
assert_eq!(current_era_info.era_index, 3u32);
assert_eq!(current_era_info.started_at, 20u32);
})
}
62 changes: 38 additions & 24 deletions pallets/capacity/src/tests/mock.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate as pallet_capacity;

use crate::{BalanceOf, Config, StakingRewardClaim, StakingRewardsProvider};
use common_primitives::{
node::{AccountId, ProposalProvider},
node::{AccountId, Balance, Hash, Header, ProposalProvider},
schema::{SchemaId, SchemaValidator},
};
use frame_support::{
Expand All @@ -14,9 +15,6 @@ use sp_runtime::{
traits::{BlakeTwo256, Convert, IdentityLookup},
AccountId32, BuildStorage, DispatchError, Perbill,
};
// use common_primitives::node::{Balance, Hash, RewardEra};
use common_primitives::node::RewardEra;
// use crate::{BalanceOf, StakingRewardClaim, StakingRewardsProvider};

type Block = frame_system::mocking::MockBlockU32<Test>;

Expand Down Expand Up @@ -132,24 +130,40 @@ impl pallet_msa::Config for Test {
type MaxSignaturesStored = ConstU32<8000>;
}

// pub struct TestStakingRewardsProvider {}
// impl StakingRewardsProvider<Test> for TestStakingRewardsProvider {
// fn reward_pool_size(era: RewardEra) -> BalanceOf<Test> {
// Balance::from(10_000u64);
// }
//
// fn staking_reward_total(account_id: AccountId, from_era: RewardEra, to_era: RewardEra) -> BalanceOf<Test> {
// Balance::from(10u64)
// }
//
// fn validate_staking_reward_claim(account_id: AccountId, proof: Hash, payload: StakingRewardClaim<Test>) -> bool {
// true
// }
//
// fn payout_eligible(account_id: AccountId) -> bool {
// true
// }
// }
// not used yet
pub struct TestStakingRewardsProvider {}

type TestRewardEra = u32;

impl StakingRewardsProvider<Test> for TestStakingRewardsProvider {
type AccountId = u64;
type RewardEra = TestRewardEra;
type Hash = Hash; // use what's in common_primitives::node

fn reward_pool_size() -> Result<BalanceOf<Test>, DispatchError> {
Ok(1000u64)
}

fn staking_reward_total(
account_id: Self::AccountId,
_from_era: Self::RewardEra,
_to_era: Self::RewardEra,
) -> Result<BalanceOf<Test>, DispatchError> {
if account_id > 2u64 {
Ok(10u64)
} else {
Ok(1u64)
}
}

fn validate_staking_reward_claim(
_account_id: Self::AccountId,
_proof: Self::Hash,
_payload: StakingRewardClaim<Test>,
) -> bool {
true
}
}

// Needs parameter_types! for the Perbill
parameter_types! {
Expand All @@ -173,10 +187,10 @@ impl pallet_capacity::Config for Test {
type MaxEpochLength = ConstU32<100>;
type EpochNumber = u32;
type CapacityPerToken = TestCapacityPerToken;
type RewardEra = u32;
type RewardEra = TestRewardEra;
type EraLength = ConstU32<10>;
type StakingRewardsPastErasMax = ConstU32<5>;
// type RewardsProvider = TestStakingRewardsProvider;
type RewardsProvider = TestStakingRewardsProvider;
}

pub fn new_test_ext() -> sp_io::TestExternalities {
Expand Down
81 changes: 81 additions & 0 deletions pallets/capacity/src/tests/rewards_provider_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use super::mock::*;
use crate::{
tests::testing_utils::{run_to_block, system_run_to_block},
Config, CurrentEraInfo, Error, Event, RewardEraInfo, RewardPoolInfo, StakingAccountDetails,
StakingRewardClaim, StakingRewardPool, StakingRewardsProvider,
};
use frame_support::assert_err;

use common_primitives::capacity::StakingType::MaximumCapacity;
use sp_core::H256;

#[test]
fn test_staking_reward_total_happy_path() {
new_test_ext().execute_with(|| {
CurrentEraInfo::<Test>::set(RewardEraInfo { era_index: 11, started_at: 100 });
// this calls the implementation in the pallet
assert_eq!(Ok(5u64), Capacity::staking_reward_total(1, 5u32, 10u32));
let proof = H256::random();
let payload: StakingRewardClaim<Test> = StakingRewardClaim {
claimed_reward: 1,
staking_account_end_state: StakingAccountDetails {
active: 1,
total: 1,
unlocking: Default::default(),
staking_type: MaximumCapacity,
last_rewards_claimed_at: None,
stake_change_unlocking: Default::default(),
},
from_era: 1,
to_era: 5,
};
assert!(Capacity::validate_staking_reward_claim(4, proof, payload));
})
}

#[test]
fn test_payout_eligible() {
new_test_ext().execute_with(|| {
let is_eligible = Capacity::payout_eligible(1);
assert!(!is_eligible);
})
}

#[test]
fn test_reward_pool_size_happy_path() {
struct TestCase {
total_staked: u64,
expected_reward_pool: u64,
}
new_test_ext().execute_with(|| {
let test_cases: Vec<TestCase> = vec![
TestCase { total_staked: 0, expected_reward_pool: 0 },
TestCase { total_staked: 4, expected_reward_pool: 0 },
TestCase { total_staked: 10, expected_reward_pool: 1 },
TestCase { total_staked: 333, expected_reward_pool: 33 },
];
let era = 20u32;
CurrentEraInfo::<Test>::set(RewardEraInfo { era_index: era, started_at: 200u32 });
for tc in test_cases {
StakingRewardPool::<Test>::insert(
era,
RewardPoolInfo {
total_staked_token: tc.total_staked,
total_reward_pool: 0u64,
unclaimed_balance: 0u64,
},
);
assert_eq!(Ok(tc.expected_reward_pool), Capacity::reward_pool_size());
}
})
}

#[test]
fn test_staking_reward_total_era_out_of_range() {
new_test_ext().execute_with(|| {
CurrentEraInfo::<Test>::set(RewardEraInfo { era_index: 10, started_at: 100 });
assert_err!(Capacity::staking_reward_total(1, 5u32, 4u32), Error::<Test>::EraOutOfRange);
assert_err!(Capacity::staking_reward_total(1, 15u32, 5u32), Error::<Test>::EraOutOfRange);
assert_err!(Capacity::staking_reward_total(1, 5u32, 13u32), Error::<Test>::EraOutOfRange);
});
}
1 change: 1 addition & 0 deletions pallets/frequency-tx-payment/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ impl pallet_capacity::Config for Test {
type RewardEra = u32;
type EraLength = ConstU32<5>;
type StakingRewardsPastErasMax = ConstU32<2>;
type RewardsProvider = Capacity;
}

use pallet_balances::Call as BalancesCall;
Expand Down
3 changes: 1 addition & 2 deletions runtime/frequency/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ pub use common_runtime::{
};
use frame_support::traits::Contains;

// use common_primitives::capacity::StakingRewardsProvider;
#[cfg(feature = "try-runtime")]
use frame_support::traits::{TryStateSelect, UpgradeCheckSelect};

Expand Down Expand Up @@ -519,7 +518,7 @@ impl pallet_capacity::Config for Runtime {
type RewardEra = RewardEra;
type EraLength = ConstU32<{ 14 * DAYS }>;
type StakingRewardsPastErasMax = ConstU32<26u32>; // 1 year
// type RewardsProvider = StakingRewardsProvider;
type RewardsProvider = Capacity;
}

impl pallet_schemas::Config for Runtime {
Expand Down

0 comments on commit 7ad5c9a

Please sign in to comment.