Skip to content

Commit

Permalink
Design documents first versions
Browse files Browse the repository at this point in the history
updates to design docs to use a capacity rewards interface
Prototypes, make check working
refinements to design doc

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.

Feat/staking rewards rewards provider #1572 (#1598)

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.

change staking target extrinsic, closes #1570 (#1623)

comments, capacity boost fn added to StakingRewardsProvider trait

* Refactor staking type to go in StakingTargetDetails
* Make some functions pass by reference (performance)
* fix broken tests & calls

use capacity_boost and StakingType to adjust capacity generation, add/adjust tests

* Check from/to aren't the same when retargeting
* Performance: move non-db checks to top when retargeting
* Lots more tests
* Fix a bug where we weren't setting the staking type on a retarget
* Remove staking type from StakingAccountDetails
* Fix broken tests from last commit

Feat/reward pool history (#1710)
Closes #1710

Feat/split stake extrinsic #1699 (#1717)

The goal of this PR is to split the `stake` extrinsic into two: `stake` and `provider_boost`
Closes #1707

Feat/split storage #1726 (#1744)

The goal of this PR is to split up storage of boosting and maximized staking accounts,
as well as store retarget history separately, which can store retargeting events for
any type of staking.

Closes #1726

fix e2e tests, correction to implementation design doc

initialize storage for ProviderBoost on runtime upgrade

Set ProviderBoost capacity generated and fix tests (#1947)

* set the amount of capacity generated by a provider boost to the final amount, 50% of what is generated by MaximizedCapacity staking.
* Also Fixes some tests broken from the last rebase with main.
Closes #1569

Update reward pool on `provider_boost` or `unstake` #1699 (#1948)

The goal of this PR is to update the StakingRewardPool on a `provider_boost` or `unstake` extrinsic call.

Closes #1699

Implement rewards calculation formula #1941 (#1956)

The goal of this PR is to implement (but not really use yet) the chosen
formula for calculation of a reward in a single Provider Boost Reward
Era.

Closes #1941

updates after rebase

upsert staking history #1699 (#1963)

The goal of this PR is to add and use storage for individual staking history so that rewards can be calculated and paid out.  Benchmarks run to update capacity weights.

Relates to #1699

Chores/update capacity benchmarks #1949 (#1966)

The goal of this PR is to update the benchmark for `on_initialize` to include the weight when a new RewardEra must be created.

Closes #1949

Feat/check unclaimed rewards 1969 (#1972)

The goal of this PR is to implement `list_unclaimed_rewards`, and also
one that is lighter weight, `has_unclaimed_rewards`, which returns a
`bool` and which `unstake` extrinsic uses. Unstake now fails if there
are any unclaimed rewards.

Closes #1969
Closes #1578

Feat/reward pool refactor #1976 (#2005)

The goal of this PR is to implement a "chunk" version of the overall
reward pool history to reduce read/write load and hence weight for
transactions and `on_initialize` when a new `RewardEra` needs to start.

Part of #1976

Co-authored-by: Wil Wade <wil.wade@amplica.io>

Revise Provider Boost implementation design doc #2016 (#2020)

The goal of this PR is to review and update the implementation design doc in light of the chosen economic model, and to reflect some changes in behavior.  Review of the design doc also fed back into the code itself. Some code
is no longer needed.

Closes #2016

Co-authored-by: Aramik <aramikm@gmail.com>

E2e for new extrinsics (#2067)

The goal of this PR is to add some e2e tests for the `provider_boost` extrinsic, and update the `change_staking_target` extrinsic after a rebase with main.

Refactor reward era (#2069)

The goal of this PR is primarily to pull RewardEra out of the Capacity Config and make it the same type everywhere.

`claim_staking_rewards` extrinsic (#2080)
Closes #1970

Capacity runtime api with list_unclaimed_rewards endpoint (#2088)
The goal of this PR is to implement a capacity runtime api for the `list_unclaimed_rewards` endpoint.
Closes #1698

Update Capacity README

address the lint failure.  updates after rebase with main

Remove TODO since it's already been addressed.
Add a minor test case to unstaking tests
Add new extrinsics to Capacity README
  • Loading branch information
shannonwells committed Oct 25, 2024
1 parent e923165 commit bd14ad6
Show file tree
Hide file tree
Showing 48 changed files with 5,062 additions and 1,772 deletions.
2,214 changes: 938 additions & 1,276 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,6 @@ benchmarks-multi:
benchmarks-multi-local:
./scripts/run_benchmarks.sh -t bench-dev $(PALLETS)

benchmarks-capacity:
./scripts/run_benchmark.sh -p capacity

.PHONY: docs
docs:
RUSTC_BOOTSTRAP=1 RUSTDOCFLAGS="--enable-index-page -Zunstable-options" cargo doc --no-deps --workspace --features frequency
Expand Down
41 changes: 35 additions & 6 deletions common/primitives/src/capacity.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use crate::msa::MessageSourceId;
use frame_support::traits::tokens::Balance;
use scale_info::TypeInfo;
use sp_core::{Decode, Encode, MaxEncodedLen, RuntimeDebug};
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 All @@ -15,19 +20,24 @@ impl TargetValidator for () {
}
}

/// A trait for Non-transferable asset.
/// A trait for Non-transferable asset
pub trait Nontransferable {
/// Scalar type for representing balance of an account.
type Balance: Balance;

/// The balance Capacity for an MSA account.
/// The balance Capacity for an MSA.
fn balance(msa_id: MessageSourceId) -> Self::Balance;

/// Reduce Capacity of an MSA account by amount.
fn deduct(msa_id: MessageSourceId, amount: Self::Balance) -> Result<(), DispatchError>;
/// Reduce Capacity of an MSA by amount.
fn deduct(msa_id: MessageSourceId, capacity_amount: Self::Balance)
-> Result<(), DispatchError>;

/// Increase Capacity of an MSA account by an amount.
fn deposit(msa_id: MessageSourceId, amount: Self::Balance) -> Result<(), DispatchError>;
/// Increase Staked Token + Capacity amounts of an MSA. (unused)
fn deposit(
msa_id: MessageSourceId,
token_amount: Self::Balance,
capacity_amount: Self::Balance,
) -> Result<(), DispatchError>;
}

/// A trait for replenishing Capacity.
Expand All @@ -47,3 +57,22 @@ pub trait Replenishable {
/// Checks if an account can be replenished.
fn can_replenish(msa_id: MessageSourceId) -> bool;
}

/// Result of checking a Boost History item to see if it's eligible for a reward.
#[derive(
Copy, Clone, Default, Encode, Eq, Decode, RuntimeDebug, MaxEncodedLen, PartialEq, TypeInfo,
)]

pub struct UnclaimedRewardInfo<Balance, BlockNumber> {
/// The Reward Era for which this reward was earned
pub reward_era: RewardEra,
/// When this reward expires, i.e. can no longer be claimed
pub expires_at_block: BlockNumber,
/// The total staked in this era as of the current block
pub staked_amount: Balance,
/// The amount staked in this era that is eligible for rewards. Does not count additional amounts
/// staked in this era.
pub eligible_amount: Balance,
/// The amount in token of the reward (only if it can be calculated using only on chain data)
pub earned_amount: Balance,
}
6 changes: 3 additions & 3 deletions designdocs/capacity.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Stakes some amount of tokens to the network and generates Capacity.
///
/// - Returns Error::InsufficientBalance if the sender does not have free balance amount needed to stake.
/// - Returns Error::InvalidTarget if attempting to stake to an invalid target.
/// - Returns Error::InsufficientStakingAmount if attempting to stake an amount below the minimum amount.
/// - Returns Error::StakingAmountBelowMinimum if attempting to stake an amount below the minimum amount.
/// - Returns Error::BalanceTooLowtoStake if the sender does not have
/// free balance amount > MinimumTokenBalance after staking.
pub fn stake(origin: OriginFor<T>, target: MessageSourceId, amount: BalanceOf<T>) -> DispatchResult {}
Expand Down Expand Up @@ -211,7 +211,7 @@ pub enum Error<T> {
/// Capacity is not available for the given MSA.
InsufficientBalance,
/// Staker is attempting to stake an amount below the minimum amount.
InsufficientStakingAmount,
StakingAmountBelowMinimum,
/// Staker is attempting to stake a zero amount.
ZeroAmountNotAllowed,
/// Origin has no Staking Account
Expand Down Expand Up @@ -825,7 +825,7 @@ Note that Capacity transactions do not get refunded for overcharges.

## Non-goals

Staking rewards and re-staking are left for another design document.
Rewards and re-staking are left for another design document.

## Benefits and Risk

Expand Down
84 changes: 0 additions & 84 deletions designdocs/capacity_staking_rewards.md

This file was deleted.

8 changes: 5 additions & 3 deletions designdocs/provider_boosting_economic_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ This document does not:

### Formula

The Provider Boost reward in FRQCY tokens for a given Era <i>e</i> is
The Provider Boost reward in FRQCY tokens for a given Era <i>e</i> is a simple interest model, with the following formula:

R = <i>min</i>(R<sub>era</sub>*L<sub>u</sub>/L<sub>T</sub>, L<sub>u</sub>*P<sub>max</sub>)

Put into words, if the pool of Rewards per Era is R<sub>era</sub> FRQCY, then the Reward amount in FRQCY earned by a given Provider Booster will be proportional to how much they've locked for Provider Boosting out of the total, OR P<sub>max</sub> times the amount locked, whichever is less.
Put into words, if the pool of Rewards per Era is

R<sub>era</sub> FRQCY, then the Reward amount in FRQCY earned by a given Provider Booster will be proportional to how much they've locked for Provider Boosting out of the total OR P<sub>max</sub> times the amount locked, whichever is less.

Put another way, there is a fixed number of tokens to be rewarded each Era (R<sub>era</sub>), split up according to each Provider Boost account holder's percentage of the locked total. However, the reward return each Era for every individual account (P<sub>max</sub>) is capped at some rate, for example, 10%.

Expand All @@ -93,4 +95,4 @@ Rewards are not prorated; they are calculated only for balances held for an enti
- Provider Boost Rewards are not minted until they are explicitly <i>claimed</i> by the Provider Boost account holder, by calling a non-free extrinsic.
- Rewards must be claimed within a certain number of Provider Boost Eras.
- When claimed, all available, unexpired Rewards for each previous Era are minted and transferred to the same account that locked them.
- **Is there a cap on how much can be claimed at once?**
- Currently there is no cap on how much can be claimed at once.
Loading

0 comments on commit bd14ad6

Please sign in to comment.