-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/check unclaimed rewards 1969 #1972
Feat/check unclaimed rewards 1969 #1972
Conversation
148705a
to
75cc0ff
Compare
@@ -208,7 +208,7 @@ impl pallet_capacity::Config for Test { | |||
type CapacityPerToken = TestCapacityPerToken; | |||
type RewardEra = TestRewardEra; | |||
type EraLength = ConstU32<10>; | |||
type StakingRewardsPastErasMax = ConstU32<5>; | |||
type StakingRewardsPastErasMax = ConstU32<6>; // 5 for claiming rewards, 1 for current reward era |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change was needed, and it broke some other tests.
@@ -235,7 +235,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { | |||
let mut ext = sp_io::TestExternalities::new(t); | |||
ext.execute_with(|| { | |||
System::set_block_number(1); | |||
set_era_and_reward_pool_at_block(1, 0, 0); | |||
set_era_and_reward_pool(1, 1, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it made more sense to start at era 1 and have that start at block 1 instead of block 0, because block number is also 1. This broke different tests.
@@ -361,11 +362,33 @@ impl<T: Config> ProviderBoostHistory<T> { | |||
Some(self.count()) | |||
} | |||
|
|||
/// Return how much is staked for the given era. If there is no entry for that era, return None. | |||
pub fn get_staking_amount_for_era(&self, reward_era: &T::RewardEra) -> Option<&BalanceOf<T>> { | |||
/// A wrapper for the key/value retrieval of the BoundedBTreeMap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better name, better explanation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments and questions!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some quick thoughts
1699361
to
5a0ebce
Compare
InsufficientStakingAmount, | ||
/// Staker is attempting to stake a zero amount. | ||
StakingAmountBelowMinimum, | ||
/// Staker is attempting to stake a zero amount. DEPRECATED |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is still used by ensure_can_stake
, but you can tag it with a rust deprecated
attribute as well
/// Staker is attempting to stake a zero amount. DEPRECATED | |
/// Staker is attempting to stake a zero amount. | |
/// #[deprecated(since = "1.13.0", note = "Use ?? instead")] | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit lost in what is new and what is from main
, but I think I looked at it all. I think it is good to merge once the conflicts are resolved.
pallets/capacity/src/lib.rs
Outdated
current_era_info.era_index.saturating_sub(past_eras_max.into()).add(One::one()); | ||
StakingRewardPool::<T>::remove(earliest_era); // 1w | ||
} | ||
CurrentEraInfo::<T>::set(new_era_info); // 1w |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for this PR, but this line feels like it should go up by the creation of the new_era_info
. I kept trying to figure out why it mattered about past_eras_max
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll move it anyway since I'm adding the deprecation line.
pallets/README.template.md
Outdated
|
||
| Name | Description | Query | Runtime Added | | ||
| --------- | ------------------- | ------------------------ | ------------- | | ||
| {Query 1} | {Query Desctiption} | `{queryCallInCamelCase}` | 1 | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Desctiption -> Description
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this wasn't my change, sorry, it was from conflicting stuff from main.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@enddynayn I'll fix it in my upcoming docs PR
pallets/capacity/src/types.rs
Outdated
Some(()) | ||
} | ||
|
||
/// Decrease an MSA target Staking total and Capacity amount. | ||
pub fn withdraw(&mut self, amount: Balance, capacity: Balance) { | ||
/// If the amount would put you below the minimum, zero out the amount. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice!
…o old position for backward compatibility * FIX: Implement eligible reward amounts as originally designed, only for amounts staked the entire era. * Better moments
…f the account boosted earlier than the first era in the range. * On an unstake, Use upsert_boost_history and update reward pool in the same place, which is where the unstaking balance is decreased, not the capacity. * Rerun capacity benchmarks
23dcbd7
to
3187a83
Compare
Goal
The goal of this PR is to implement
list_unclaimed_rewards
, and also one that is lighter weight,has_unclaimed_rewards
, which returns abool
and whichunstake
extrinsic uses. Unstake now fails if there are any unclaimed rewards.Update: put back to draft since I realized I need to update the unstake benchmark for worst case data storage. Ok to review otherwise.
Closes #1969
Closes #1578
Discussion
Two issues
The smaller issue, originally in the design doc, one could not unstake without claiming all rewards. Now I am questioning whether we should require that, but I can still see reasons to support it, if only as a nudge to make sure people get all they're due.
With that said, I think the lightweight
has_unclaimed_rewards
("You've Got Unclaimed Rewards!") would be very useful to providers, and we should make a custom RPC out of it.I looked at different ways of making this more efficient in terms of storage reads/writes.
The current way stores Reward Pool history as a
StorageMap
byRewardEra
. This means on getting a list unclaimed rewards or actually claiming the rewards - if there are any - it's possible that all the past RewardPoolInfos will be accessed up to the history limit (31). In addition there are 4 more reads needed. The size of the entire pool history is about 12k bits since it's 3 * u128 (in production) * 31 items. If someone boosted and then left it for the limit ofRewardEras
without claiming anything, then checked for unclaimed or claimed rewards, the number of reads would be the maximum.However, at every boost and unstake, only a single
RewardPoolInfo
record is updated.If to save only the number of read/writes for checking and claiming rewards, the entire Reward Pool history is stored as a single record, that is a lot of data to read and write on every boost/unstake. This is also a big lift when a new Reward Era begins in
on_initialize
, because instead of 2 smaller records (the new one and the oldest one) the entire data set would also be read/written.With the current Provider Boost economics, the Reward Pool amount is a constant, so
total_reward_pool
isn't needed. Also, nobody has asked for any feature for theunclaimed_rewards
field. That field was put in the the design last year, well before the economics model was decided and there had to be some guesswork about it.I think the middle ground solution is, RewardPool storage should be changed in another PR to have only the one value of
total_staked
, but keep it as key/valueStorageMap
instead of changing it to aStorageValue
for aBoundedVec
, i.e. the entire Reward Pool history.Checklist