Skip to content

Commit

Permalink
EraRewardSpan
Browse files Browse the repository at this point in the history
  • Loading branch information
Dinonard committed Oct 12, 2023
1 parent 655c280 commit 0a7c519
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 14 deletions.
10 changes: 10 additions & 0 deletions pallets/dapp-staking-v3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,16 @@ pub mod pallet {

Ok(())
}

/// TODO
#[pallet::call_index(11)]
#[pallet::weight(Weight::zero())]
pub fn claim_staker_reward(origin: OriginFor<T>) -> DispatchResult {
Self::ensure_pallet_enabled()?;
let account = ensure_signed(origin)?;

Check failure on line 935 in pallets/dapp-staking-v3/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `account`

error: unused variable: `account` --> pallets/dapp-staking-v3/src/lib.rs:935:17 | 935 | let account = ensure_signed(origin)?; | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_account` | = note: `-D unused-variables` implied by `-D warnings`

Ok(())
}
}

impl<T: Config> Pallet<T> {
Expand Down
137 changes: 123 additions & 14 deletions pallets/dapp-staking-v3/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,17 +695,6 @@ where
}
}

/// Rewards pool for stakers & dApps
#[derive(Encode, Decode, MaxEncodedLen, Copy, Clone, Debug, PartialEq, Eq, TypeInfo, Default)]
pub struct RewardInfo {
/// Rewards pool for accounts which have locked funds in dApp staking
#[codec(compact)]
pub participants: Balance,
/// Reward pool for dApps
#[codec(compact)]
pub dapps: Balance,
}

// TODO: it would be nice to implement add/subtract logic on this struct and use it everywhere
// we need to keep track of staking amount for periods. Right now I have logic duplication which is not good.
#[derive(Encode, Decode, MaxEncodedLen, Copy, Clone, Debug, PartialEq, Eq, TypeInfo, Default)]
Expand Down Expand Up @@ -776,8 +765,6 @@ impl StakeAmount {
/// Info about current era, including the rewards, how much is locked, unlocking, etc.
#[derive(Encode, Decode, MaxEncodedLen, Copy, Clone, Debug, PartialEq, Eq, TypeInfo, Default)]
pub struct EraInfo {
/// Info about era rewards
pub rewards: RewardInfo,
/// How much balance is considered to be locked in the current era.
/// This value influences the reward distribution.
#[codec(compact)]
Expand Down Expand Up @@ -850,7 +837,6 @@ impl EraInfo {
/// ## Args
/// `next_period_type` - `None` if no period type change, `Some(type)` if `type` is starting from the next era.
pub fn migrate_to_next_era(&mut self, next_period_type: Option<PeriodType>) {
self.rewards = Default::default();
self.active_era_locked = self.total_locked;
match next_period_type {
// If next era marks start of new voting period period, it means we're entering a new period
Expand Down Expand Up @@ -1262,3 +1248,126 @@ impl ContractStakingInfoSeries {
}
}
}

/// Information required for staker reward payout for a particular era.
#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo, Default)]
pub struct EraReward {
/// Total reward pool for staker rewards
#[codec(compact)]
staker_reward_pool: Balance,
/// Total amount which was staked at the end of an era
#[codec(compact)]
staked: Balance,
}

impl EraReward {
/// Create new instance of `EraReward` with specified `staker_reward_pool` and `staked` amounts.
pub fn new(staker_reward_pool: Balance, staked: Balance) -> Self {

Check failure on line 1265 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

associated function `new` is never used

error: associated function `new` is never used --> pallets/dapp-staking-v3/src/types.rs:1265:12 | 1265 | pub fn new(staker_reward_pool: Balance, staked: Balance) -> Self { | ^^^ | = note: `-D dead-code` implied by `-D warnings`
Self {
staker_reward_pool,
staked,
}
}

/// Total reward pool for staker rewards.
pub fn staker_reward_pool(&self) -> Balance {

Check failure on line 1273 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `staker_reward_pool` is never used

error: method `staker_reward_pool` is never used --> pallets/dapp-staking-v3/src/types.rs:1273:12 | 1273 | pub fn staker_reward_pool(&self) -> Balance { | ^^^^^^^^^^^^^^^^^^
self.staker_reward_pool
}

/// Total amount which was staked at the end of an era.
pub fn staked(&self) -> Balance {

Check failure on line 1278 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `staked` is never used

error: method `staked` is never used --> pallets/dapp-staking-v3/src/types.rs:1278:12 | 1278 | pub fn staked(&self) -> Balance { | ^^^^^^
self.staked
}
}

#[derive(Encode, Decode, MaxEncodedLen, Clone, Copy, Debug, PartialEq, Eq, TypeInfo)]
pub enum EraRewardSpanError {
/// Provided era is invalid. Must be exactly one era after the last one in the span.
InvalidEra,
/// Span has no more capacity for additional entries.
NoCapacity,
}

/// Used to efficiently store era span information.
#[derive(Encode, Decode, MaxEncodedLen, Clone, Debug, PartialEq, Eq, TypeInfo, Default)]
pub struct EraRewardSpan<SL: Get<u32>> {
/// Span of EraRewardInfo entries.
span: BoundedVec<EraReward, SL>,
/// The first era in the span.
#[codec(compact)]
first_era: EraNumber,
/// The final era in the span.
#[codec(compact)]
last_era: EraNumber,
}

impl<SL> EraRewardSpan<SL>
where
SL: Get<u32>,
{
/// Create new instance of the `EraRewardSpan`
pub fn new() -> Self {

Check failure on line 1309 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

associated function `new` is never used

error: associated function `new` is never used --> pallets/dapp-staking-v3/src/types.rs:1309:12 | 1309 | pub fn new() -> Self { | ^^^
Self {
span: Default::default(),
first_era: 0,
last_era: 0,
}
}

/// First era covered in the span.
pub fn first_era(&self) -> EraNumber {

Check failure on line 1318 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `first_era` is never used

error: method `first_era` is never used --> pallets/dapp-staking-v3/src/types.rs:1318:12 | 1318 | pub fn first_era(&self) -> EraNumber { | ^^^^^^^^^
self.first_era
}

/// Last era covered in the span
pub fn last_era(&self) -> EraNumber {

Check failure on line 1323 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `last_era` is never used

error: method `last_era` is never used --> pallets/dapp-staking-v3/src/types.rs:1323:12 | 1323 | pub fn last_era(&self) -> EraNumber { | ^^^^^^^^
self.last_era
}

/// Span length.
pub fn len(&self) -> usize {

Check failure on line 1328 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `len` is never used

error: method `len` is never used --> pallets/dapp-staking-v3/src/types.rs:1328:12 | 1328 | pub fn len(&self) -> usize { | ^^^
self.span.len()
}

/// `true` if span is empty, `false` otherwise.
pub fn is_empty(&self) -> bool {

Check failure on line 1333 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `is_empty` is never used

error: method `is_empty` is never used --> pallets/dapp-staking-v3/src/types.rs:1333:12 | 1333 | pub fn is_empty(&self) -> bool { | ^^^^^^^^
self.first_era == 0 && self.last_era == 0
}

/// Push new `EraReward` entry into the span.
/// If span is non-empty, the provided `era` must be exactly one era after the last one in the span.
pub fn push(

Check failure on line 1339 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `push` is never used

error: method `push` is never used --> pallets/dapp-staking-v3/src/types.rs:1339:12 | 1339 | pub fn push( | ^^^^
&mut self,
era: EraNumber,
era_reward: EraReward,
) -> Result<(), EraRewardSpanError> {
// First entry, no checks, just set eras to the provided value.
if self.span.is_empty() {
self.first_era = era;
self.last_era = era;
self.span
.try_push(era_reward)
.map_err(|_| EraRewardSpanError::NoCapacity)
} else {
// Defensive check to ensure next era rewards refers to era after the last one in the span.
if era != self.last_era.saturating_add(1) {
return Err(EraRewardSpanError::InvalidEra);
}

self.last_era = era;
self.span
.try_push(era_reward)
.map_err(|_| EraRewardSpanError::NoCapacity)
}
}

/// Get the `EraReward` entry for the specified `era`.
///
/// In case `era` is not covered by the span, `None` is returned.
pub fn get(&self, era: EraNumber) -> Option<&EraReward> {

Check failure on line 1367 in pallets/dapp-staking-v3/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

method `get` is never used

error: method `get` is never used --> pallets/dapp-staking-v3/src/types.rs:1367:12 | 1367 | pub fn get(&self, era: EraNumber) -> Option<&EraReward> { | ^^^
match self.first_era.checked_sub(era) {
Some(index) => self.span.get(index as usize),
None => None,
}
}
}

0 comments on commit 0a7c519

Please sign in to comment.