diff --git a/proposals/0123-block-revenue-distribution.md b/proposals/0123-block-revenue-distribution.md index 735403a65..317c9c73f 100644 --- a/proposals/0123-block-revenue-distribution.md +++ b/proposals/0123-block-revenue-distribution.md @@ -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,25 @@ 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, as described in +[SIMD-0392](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0392-rent-increase-adaptations.md#rent-adjusted-stake-delegations). ### Vote Program diff --git a/proposals/0392-relax-minimum-balance-check.md b/proposals/0392-rent-increase-adaptations.md similarity index 72% rename from proposals/0392-relax-minimum-balance-check.md rename to proposals/0392-rent-increase-adaptations.md index 214842e0d..855a48aaf 100644 --- a/proposals/0392-relax-minimum-balance-check.md +++ b/proposals/0392-rent-increase-adaptations.md @@ -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,8 +13,13 @@ 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 @@ -21,6 +27,12 @@ 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`.