Polkadot makes all stakers claim their rewards for past eras by submitting a transaction. This naturally leads to spreading out reward distribution, as people make transactions at disparate times, rather than updating the accounts of all stakers in a single block. Even if everyone submitted a reward claim at the same time, the fact that they are individual transactions would allow the block construction algorithm to process only a limited number per block and ensure that Polkadot maintains a constant block time.
Lazy payouts requires 1 transaction per staker per era to claim rewards, where a staker can be either a validator or a nominator. The reason Polkadot requires this is to avoid an attack where someone has several thousand accounts nominating a single validator. The major cost in reward distribution is mutating the accounts in storage, and Polkadot cannot pay out several thousand accounts in a single transaction.
Polkadot stores up to 84 eras of reward info like maps of era number to validator points, inflationary rewards, and nomination exposures.
In order to claim rewards, validators must submit a payout_validator(era: EraIndex)
transaction from their controller key, where era
is the era for which they are claiming rewards.
Nominators will need to submit a payout_nominator(era: EraIndex, validators: Vec<(T::AccountId, u32)>)
transaction from their controller key, where:
era
is the era for which that the nominator is claiming rewards.validators
is a list of tuples of:- Validator stash account IDs that the nominator was nominating during
era
, and - The nominator's index in the list of nominators for that validator for that era.
- Validator stash account IDs that the nominator was nominating during
Providing the index eliminates search and allows for a lower transaction fee.
- Caution: Once a user claims rewards for an era, all reward information for that user for previous eras is removed. Regular users should not construct these transactions themselves, but should use a wallet or front end that safely claims in the correct order.
- Rewards expire after 84 eras. On Polkadot, that's about 84 days. On Kusama, it is 21 days.
- Users must use their controller key to claim payouts. The stash key should remain in cold storage.
- Claiming rewards (or neglecting to claim rewards) does not affect nominations in any way. Nominations will persist after claiming rewards or the rewards expire.
- Polkadot provides a
batch
function under the Utility pallet that allows the user to batch several transactions into a single transaction from the same origin. Therefore, users can use this function to claim rewards for several eras for a single validator or nominator.
This scheme protects against malicious nominators, but is difficult for UX and especially hurts smaller nominators who would rather be passive participants and for whom the transaction fee could represent a non-trivial fraction of their rewards. We are actively investigating other solutions that would, for example, let a single user trigger the payout for all nominators of a single validator as long as that user is willing to pay the transaction fee.