-
Notifications
You must be signed in to change notification settings - Fork 286
SIMD-0392 / SIMD-0123: Adjust stake delegations during rewards payout due to rent #488
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
Changes from 9 commits
61bb898
1ee496d
bca917f
75d8e89
443a362
05313b8
0093d66
c8fa5c9
3245a58
8114d94
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,10 +45,15 @@ This proposal depends on the following previously accepted proposals: | |
| Introduces a new instruction type for setting commission rates in basis | ||
| points | ||
|
|
||
| [SIMD-0180]: https://github.com/solana-foundation/solana-improvement-documents/pull/180 | ||
| [SIMD-0185]: https://github.com/solana-foundation/solana-improvement-documents/pull/185 | ||
| [SIMD-0232]: https://github.com/solana-foundation/solana-improvement-documents/pull/232 | ||
| [SIMD-0291]: https://github.com/solana-foundation/solana-improvement-documents/pull/291 | ||
| - **[SIMD-0392]: Runtime Adjustments for Rent Increase** | ||
|
|
||
| Updates delegation calculation based on `Rent` sysvar parameters | ||
|
|
||
| [SIMD-0180]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0180-vote-account-leader-schedule.md | ||
| [SIMD-0185]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0185-vote-account-v4.md | ||
| [SIMD-0232]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0232-custom-commission-collector.md | ||
| [SIMD-0291]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0291-commission-rate-in-basis-points.md | ||
| [SIMD-0392]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0392-rent-increase-adaptations.md | ||
|
|
||
| ## Alternatives Considered | ||
|
|
||
|
|
@@ -61,7 +66,7 @@ they will have to manage themselves. [SIMD-0022] aims to make this experience | |
| better for stakers by allowing stake accounts to separately delegate any | ||
| unstaked balance in their accounts. | ||
|
|
||
| [SIMD-0022]: https://github.com/solana-foundation/solana-improvement-documents/pull/22 | ||
| [SIMD-0022]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0022-multi-stake.md | ||
|
|
||
| ### Out of protocol reward distribution | ||
|
|
||
|
|
@@ -175,7 +180,32 @@ rewards distribution, the delegated vote account for each rewarded stake account | |
| must have its `pending_delegator_rewards` field and its balance deducted with | ||
| the amount of rewards distributed to keep capitalization consistent. | ||
|
|
||
| [SIMD-0118]: https://github.com/solana-foundation/solana-improvement-documents/pull/118 | ||
| [SIMD-0118]: https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0118-partitioned-epoch-reward-distribution.md | ||
|
|
||
| #### Stake Delegation Adjustment | ||
|
|
||
| The new delegation amount for a stake account MUST account for individual | ||
| delegator rewards, by adapting the calculation from [SIMD-0392]: | ||
|
|
||
| ``` | ||
| post_delegation = min( | ||
| delegation + stake_rewards, | ||
| balance + stake_rewards + block_rewards - rent_exempt_reserve | ||
| ) | ||
| ``` | ||
|
|
||
| Where `block_rewards` represents the individual block rewards earned by the | ||
| stake account in that epoch. All other variables are the same as before: | ||
|
|
||
| - `post_delegation`: the account's post-reward delegated lamport amount | ||
| - `pre_delegation`: the account's pre-reward delegated lamport amount | ||
| - `stake_rewards`: the account's calculated stake reward lamport amount for the | ||
| past epoch | ||
| - `balance`: the account's pre-reward balance, in lamports | ||
| - `rent_exempt_reserve`: the minimum lamport balance required for the stake | ||
| account | ||
|
|
||
| All arithmetic operations MUST be saturating and use unsigned 64-bit integers. | ||
|
||
|
|
||
| ### Vote Program | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,8 +1,9 @@ | ||||||
| --- | ||||||
| simd: '0392' | ||||||
| title: Relax Post-Execution Minimum Balance Check | ||||||
| title: Adapt Runtime for Rent Increases | ||||||
| authors: | ||||||
| - Igor Durovic (anza) | ||||||
| - Jon C (anza) | ||||||
| category: Standard | ||||||
| type: Core | ||||||
| status: Idea | ||||||
|
|
@@ -12,15 +13,26 @@ feature: (fill in with feature key and github tracking issues once accepted) | |||||
|
|
||||||
| ## Summary | ||||||
|
|
||||||
| To allow for non-disruptive rent increases, relax post-execution account | ||||||
| minimum balance checks. The new lower-bound on post-exec balance is | ||||||
| To allow for non-disruptive rent increases, the Solana runtime relaxes | ||||||
| post-execution minimum balance checks and adjusts stake delegations during epoch | ||||||
| rewards calculations. | ||||||
|
|
||||||
| ### Relax Post-Execution Minimum Balance Check | ||||||
|
|
||||||
| During transaction execution, the new lower-bound on post-exec balance is | ||||||
| `min(acc.pre_exec_balance, calculate_min_balance(acc.size()))`. | ||||||
|
|
||||||
| This maintains the invariant that every account has a balance at or above the | ||||||
| minimum balance requirement calculated at any point since the most recent | ||||||
| allocation occurred. When enabled, only newly allocated accounts will be | ||||||
| subject to rent increases. | ||||||
|
|
||||||
| ### Adjust Stake Delegations during Reward Calculation | ||||||
|
|
||||||
| A new calculation is proposed to adjust stake delegation amounts during the | ||||||
| epoch rewards payout system, based on the `Rent` sysvar parameters at the | ||||||
| beginning of that epoch. | ||||||
|
|
||||||
| Sidenote: this proposal doesn't include any mechanism for increasing rent, | ||||||
| but when such a mechanism is added in the future it should cap the | ||||||
| effective rent-per-byte at the legacy rent-exempt per-byte rate. This | ||||||
|
|
@@ -31,11 +43,25 @@ need to be updated to be compatible. | |||||
|
|
||||||
| ## Motivation | ||||||
|
|
||||||
| This proposal is a prerequisite for | ||||||
| [SIMD-0438 (Rent Increase)](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0438-rent-increase-safeguard.md). | ||||||
|
|
||||||
| In order to safely reduce rent there must be a mechanism available for | ||||||
| non-disruptive rent increases. Without this change, a rent increase would | ||||||
| non-disruptive rent increases. Without these changes, a rent increase would | ||||||
| either place existing accounts in a gray area undefined by the protocol or | ||||||
| prevent write-locking all accounts with balances below the new rent value. | ||||||
|
|
||||||
| For stake accounts, any meaningful user (on-chain programs, dapps, etc) | ||||||
| typically assumes the following invariant: | ||||||
|
|
||||||
| ``` | ||||||
| balance - delegation - rent_exempt_reserve >= 0 lamports | ||||||
| ``` | ||||||
|
|
||||||
| If a rent lamport can also be a delegation lamport, at best programs or users | ||||||
| will abort operations due to incorrect values, at worst they might overestimate | ||||||
| the value of a stake account and create a loss-of-funds scenario. | ||||||
|
|
||||||
| ## New Terminology | ||||||
|
|
||||||
| - `calculate_min_balance(acc_size) = acc_size * current_rent_per_byte`. | ||||||
|
|
@@ -53,7 +79,9 @@ prevent write-locking all accounts with balances below the new rent value. | |||||
|
|
||||||
| ## Detailed Design | ||||||
|
|
||||||
| ### Current behavior | ||||||
| ### Post-Execution Balance Checks | ||||||
|
|
||||||
| #### Current behavior | ||||||
|
|
||||||
| For all write-locked accounts, post-execution account balance checks | ||||||
| currently verify: | ||||||
|
|
@@ -70,7 +98,7 @@ If the rent price is increased then existing accounts may become sub-exempt, | |||||
| which isn't currently allowed in the protocol as rent paying accounts have been | ||||||
| deprecated. | ||||||
|
|
||||||
| ### Proposed behavior | ||||||
| #### Proposed behavior | ||||||
|
|
||||||
| For all write-locked accounts, post-execution account balance checks MUST | ||||||
| verify: | ||||||
|
|
@@ -112,7 +140,7 @@ The owner check is intended to make reselling low-rent account state more | |||||
| difficult so a secondary market doesn't develop. See the security considerations | ||||||
| section for more details. | ||||||
|
|
||||||
| ### Implementation details | ||||||
| #### Implementation details | ||||||
|
|
||||||
| - The pre-execution balance MUST be captured before any state is modified | ||||||
| (e.g. before fee collection, instruction execution, etc). This same | ||||||
|
|
@@ -130,7 +158,7 @@ section for more details. | |||||
| `min()` clause. | ||||||
| - As before, 0 post-balance is allowed and equivalent to closing an account. | ||||||
|
|
||||||
| ### Edge cases | ||||||
| #### Edge cases | ||||||
|
|
||||||
| **Account creation:** | ||||||
|
|
||||||
|
|
@@ -163,6 +191,42 @@ section for more details. | |||||
| - If the account owner changes, always enforce the current rent-exempt minimum | ||||||
| for the post-exec size; the `min(pre_exec_balance, …)` clause does not apply. | ||||||
|
|
||||||
| ### Rent-Adjusted Stake Delegations | ||||||
|
|
||||||
| During the epoch rewards calculation phase, a stake's updated delegation MUST be | ||||||
| calculated with the following formula: | ||||||
|
|
||||||
| ``` | ||||||
| post_delegation = min( | ||||||
| pre_delegation + stake_rewards, | ||||||
| balance + stake_rewards - rent_exempt_reserve | ||||||
| ) | ||||||
| ``` | ||||||
|
|
||||||
| Where: | ||||||
|
|
||||||
| - `post_delegation`: the account's post-reward delegated lamport amount | ||||||
| - `pre_delegation`: the account's pre-reward delegated lamport amount | ||||||
| - `stake_rewards`: the account's calculated stake reward lamport amount for the | ||||||
| past epoch | ||||||
| - `balance`: the account's pre-reward balance, in lamports | ||||||
| - `rent_exempt_reserve`: the minimum lamport balance required for the stake | ||||||
| account | ||||||
|
||||||
| account | |
| account (see below) |
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.
do we need to consider updating block metadata to signal these occurrences since there will now be no onchain reference to the deactivation event nor easily accessible time of deactivation state snapshot?
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.
That's a very good question -- we could add a new bool field to Reward like instant_destake.
On the other hand, clients could figure it out based on the post_balance field and the rent parameters at the time of rewards payout. Is that clear enough?
Just to double-check, block metadata is out of protocol, correct?
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.
That's a very good question -- we could add a new bool field to
Rewardlikeinstant_destake.On the other hand, clients could figure it out based on the
post_balancefield and the rent parameters at the time of rewards payout. Is that clear enough?
we don't have the rent parameters either tho. even if we did, we don't necessarily know the data size of the stake account at that time.
i was originally thinking add the min_balance field for each account, but we don't have enough info to make sense of that either.
i think easiest would be a new RewardType variant StakingInactive or similar. we could also emit it on requested deactivation final reward epoch.
Just to double-check, block metadata is out of protocol, correct?
technically, tho that's almost certainly a mistake. staking and validator rewards must be the most numerous taxable events in the protocol and there is no record of them without this metadata
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 think easiest would be a new RewardType variant StakingInactive or similar. we could also emit it on requested deactivation final reward epoch.
I didn't like the idea of adding a new status for just this edge case, but I'm down if we do it for all deactivations
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.
way easier than changing layout 😅
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.
@jacobcreech can we add a lint to prevent simds from linking to pull requests like this? we only want simds merged referencing merged simds. if there's valuable context in the pr comments, that should make it to the simd text, not be left to be dug out of the conversation