-
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
base: main
Are you sure you want to change the base?
Changes from all 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 |
|---|---|---|
| @@ -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 (more information below) | ||
|
|
||
| All arithmetic operations MUST be saturating and use unsigned 64-bit integers. | ||
|
|
||
| The `rent_exempt_reserve` calculation MUST use current `Rent` sysvar parameters. | ||
| Any updates to the `Rent` sysvar values MUST take place before epoch rewards | ||
| calculation takes place. | ||
|
|
||
| During distribution, the `delegation.stake` field (absolute offset `[156,164)`) | ||
| in the stake account's data MUST be set to the new delegation amount, expressed | ||
| as a little-endian unsigned 64-bit integer. | ||
|
|
||
| If the new delegation amount is 0, then `delegation.deactivation_epoch` | ||
| (absolute offset `[172,180)`) MUST be set to the rewarded epoch, expressed as a | ||
| little-endian unsigned 64-bit integer. | ||
|
|
||
| ## Alternatives Considered | ||
|
|
||
| ### Always enforce current rent price post-execution | ||
|
|
@@ -183,6 +247,13 @@ can be made stricter: every account's balance is bounded below by the rent | |
| price at the most recent allocation rather than the minimum rent price *since* | ||
| the last allocation. | ||
|
|
||
| ### Fix Minimum Balance for Stake Accounts | ||
|
|
||
| We could fix the minimum balance for stake accounts to the current minimum | ||
| balance for 200 bytes. This approach breaks any existing on-chain programs or | ||
| tooling that use the Rent sysvar to calculate the minimum balance of a stake | ||
| account. | ||
|
|
||
| ## Impact | ||
|
|
||
| - Dapp developers: Enables non-disruptive rent increases. Existing accounts are | ||
|
|
@@ -215,10 +286,19 @@ the last allocation. | |
|
|
||
| ## Backwards Compatibility | ||
|
|
||
| This is a **relaxation** of existing constraints: | ||
| For post-execution balance checks, this is a **relaxation** of existing | ||
| constraints: | ||
|
|
||
| - The change makes the balance check less strict by allowing accounts to retain | ||
| their original rent price when not upwards reallocating. | ||
| - This is backwards compatible in the sense that transactions that currently | ||
| succeed will continue to succeed. | ||
| - However, it changes consensus rules and must be activated behind a feature gate. | ||
|
|
||
| For stake accounts: | ||
|
|
||
| - A stake delegation MAY decrease between epochs, so consumers MUST relax | ||
| assumptions that delegation amounts only increase or stay the same. | ||
| - Consumers MUST allow for stake accounts to become inactive as a result of | ||
| reward distribution, without an explicit call to `Deactivate` or | ||
| `DeactivateDelinquent`. | ||
|
Comment on lines
+303
to
+304
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 On the other hand, clients could figure it out based on the Just to double-check, block metadata is out of protocol, correct?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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
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
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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