[Staking] Self stake incentive for Validators#11651
Conversation
kianenigma
left a comment
There was a problem hiding this comment.
I have some improvement suggestions for tests and naming and maintanability and so on, but all in all the logic is sounds.
I will approve, but will probably spend a day next week writing mroe tests, and personally auditing the entirety of this line of changes.
(have also triggered another deep audit in our intelligence tool, PTAL as well)
| era_reward_points.individual.get(&stash).copied().unwrap_or_else(Zero::zero); | ||
|
|
||
| // Nothing to do if they have no reward points. | ||
| if validator_reward_points.is_zero() { |
There was a problem hiding this comment.
Was thinking.. if the validator does no work, they aren't paid out any incentive either, as seen here. But the overall incentive summation value doesn't change when this happens, meaning the incentive payouts could be considered diluted for other validators. I'm getting 1/n instead of 1/(n-1)!
I back this design, as giving a validator an incentive for other validators to not show up sounds like a security risk, but I think it's something we may want to note as purposeful so others who may see it as a bug don't change it. New unit test and comment? Or just extend zero_reward_points_means_no_payout I suppose. Thoughts?
There was a problem hiding this comment.
Good point. I will add some documentation and test to point out this behaviour.
Extracted from #10844.
Builds on #11616.
Specs: https://hackmd.io/@jonasW3F/rkN6BXE2ex
Overview
Adds a separate validator self-stake incentive reward track. Validators receive an additional bonus from a dedicated
incentive pot, proportional to their self-stake weight. Payout is flat liquid. Vesting implementation will be in a follow-up PR.
Incentive Weight Curve
Each validator's share of the incentive pot is determined by a piecewise sqrt function:
w(s) = √sw(s) = √(T + k² × (s - T))(diminishing returns)Weights are calculated during era planning and stored per-validator. At payout, each validator's incentive =
(their_weight / total_weight) × era_incentive_budget, prorated across pages.Changes
New storage:
OptimumSelfStake,HardCapSelfStake,SelfStakeSlopeFactor,ErasValidatorIncentiveAllocation(era budget snapshot),ErasTotalValidatorWeight,ErasValidatorIncentive(per-validator weights).New extrinsic:
set_validator_self_stake_incentive_config: sets optimum, cap, and slope factor. Callable by StakingAdmin. Validates optimum ≤ cap.New event:
ValidatorIncentivePaid { era, validator_stash, dest, amount }Era lifecycle:
end_era_dapnow snapshots both staker reward and incentive pots. Era planning calculates and stores incentive weights for each elected validator. Pruning cleans upErasValidatorIncentivestorage.Payout:
do_payout_stakers_by_pagecallspay_validator_incentive_for_pageafter staker rewards. DirectCurrency::transferfrom incentive era pot to payout account.TODO