Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 51 additions & 30 deletions proposals/0123-block-revenue-distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,46 +137,67 @@ vote state field `pending_delegator_rewards` and added to the balance of vote
account. If either of these conditions is violated, the delegator rewards amount
MUST be burned.

### Runtime: Delegator Rewards Distribution
### Runtime: Block Revenue Distribution

When calculating stake delegation rewards for a particular completed reward
epoch, construct a list of all vote accounts that were initialized at the
beginning of the reward epoch and had a non-zero active stake delegation. For
each vote account, retrieve its state at the end of the reward epoch and check
the `pending_delegator_rewards` field in its vote state. Let this value be `P`.
If `P` is non-zero, use it to calculate rewards for each of the stake accounts
delegated to the vote account as follows:
At the beginning of each epoch, pending delegator rewards will be collected from
actively staked vote accounts into the epoch rewards sysvar account and then
distributed to stake accounts utilizing the existing partitioned rewards
distribution mechanism described in [SIMD-0118].

1. Sum all active stake delegated to the vote account during the reward epoch
epoch. Let this total be `A`.
#### Delegator Rewards Calculation

2. For each individual stake account, multiply its active stake from the
reward epoch by `P`, and divide the result by `A` using integer division.
Discard any fractional lamports.
Delegator rewards MUST be calculated during the beginning of the first block of
an epoch `N` where the first block is any block with a parent in the previous
epoch. Rewards MUST be recalculated if a node is restarted during the partitioned
rewards distribution period as described in [SIMD-0118].

After calculating all individual stake rewards, sum them to obtain `D`, the
total distribution amount. Because of integer division, the full amount `P` may
not be distributed so compute the amount to be burned, `B`, as the difference
between `P` and `D`.
For each vote account, get its total active stake delegation
during the reward epoch `N - 1`. Let this value be `A`.

If no blocks in the epoch following the completed reward epoch have been
processed yet, subtract `B` from both the vote account’s lamport balance and its
`pending_delegator_rewards` field and store the updated vote account. Finally,
the burn amount `B` should also be deducted from the cluster capitalization.
Then for each vote account, get its pending delegator rewards from the
`pending_delegator_rewards` field in the vote state at the end of reward epoch
`N - 1`. Let this value be `P`. If `P` is zero, skip this vote account as there
is nothing to be distributed.

Lastly, if this is the first block of epoch `N`, the vote state’s
`pending_delegator_rewards` field MUST be reset to `0`. Then, if `A` (active
stake) is zero, the delegator rewards will effectively returned to the voter
after the `pending_delegator_rewards` field is reset to `0`. Otherwise, if `A`
is non-zero, `P` lamports MUST be debited from the vote account’s lamport
balance and credited to the epoch rewards sysvar account’s lamport balance
before any transactions or votes are processed.

Note that unlike inflation rewards distribution, block revenue distribution will
not impact any internal epoch rewards sysvar state fields like `total_rewards`
or `distributed_rewards` since block revenue will instead be tracked via the
epoch rewards sysvar lamport balance.

#### Individual Delegator Reward

The stake reward distribution amounts for each stake account calculated above
can then be used to construct a list of stake reward entries which MUST be
partitioned and distributed according to [SIMD-0118].
For each individual stake account with an active non-zero delegation, multiply
its active stake in reward epoch `N - 1` by `P`, and divide the result by
`A` using integer division to get the individual stake account’s block revenue
reward distribution amount, truncating any sub-lamport portion.

#### Delegator Rewards Distribution

When reward entries are used to distribute rewards pool funds during partitioned
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.
The reward distribution amounts for each stake account can then be used to
construct a list of stake reward entries which MUST be partitioned according to
[SIMD-0118] which describes which stake rewards are distributed in each block
during the partitioned rewards distribution period.

During partitioned reward distribution for a given slot, when reward entries are
used to distribute block revenue rewards, the epoch rewards sysvar account’s
lamport balance MUST be debited by the block revenue reward distribution amount
to keep capitalization consistent.

[SIMD-0118]: https://github.com/solana-foundation/solana-improvement-documents/pull/118

#### Delegator Rewards Completion

After distributing all partitioned delegator rewards, the epoch rewards sysvar balance
MUST be reset to its rent exemption balance and any surplus lamports are burned.

### Vote Program

#### Withdraw
Expand Down Expand Up @@ -246,5 +267,5 @@ NA

## Backwards Compatibility

A feature gate will be used to enable block reward distribution at an epoch
boundary.
A feature gate will be used to enable block revenue reward distribution at an
epoch boundary.
Loading