Repository navigation
Fix Leader Schedule Slot Assignment #580
Replies: 5 comments 2 replies
|
I think this is a great idea at a high level and I think that the method described is great as well. I can't see anything but upside to this proposal. |
|
One question though: what about validators with weight less than rotation_weight at the beginning of the process? They will not be eligible to receive slots during Phase 1. During Phase 2, they are eligible. But they cannot ever achieve more than 1 leader slot group per epoch. Does the math show that they achieve a number of slots commensurate with their stake weight over a large number of epochs? Or are they penalized because they are only ever awarded stake in the "remainder draw" phase with no replacement? Furthermore, won't small validators only ever get leader slots towards the ends of epochs? Any validator which only gets slots in Phase 2 will always get their slots at the end. I think it's bad if certain validators are more likely to get slots at certain times during epochs. |
|
I support this, it's better this way |
|
Yeah I support this proposal, i have seen my validator go through mood swings in terms of leader slots assigned, oftentimes seeing that i get less leader slots than someone with half my stake amount, so making this more structured would be useful. Calculators like https://calculator.decentra.cloud/ can also become more accurate when it starts to include this fixed leader schedule info and can let folks know their true revenue numbers. Missing out on high chain activity in one epoch can sometimes be the difference between staying online and shutting down |
|
Alpenglow will make this issue even more apparent once half of inflation rewards are earned by the number of leader slots a validator has been assigned in an epoch. It's better for validator operators and stake delegators to have more steady predictable income. The current algorithm is too variable as @Jotatavo has pointed out. cc @AshwinSekar |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Fix Leader Schedule Slot Assignment
Summary
The leader scheduler assigns slots via 108,000 independent stake-weighted draws with replacement, which creates large per-epoch variance in slot counts. This proposal replaces that sampling so every vote account gets floor × 4 or (floor + 1) × 4 slots — within ±4 slots of its stake-proportional share — while keeping schedule generation deterministic and locally verifiable.
Count assignment is two-phase: give every account its deterministic floor, then hand out the leftover rotations by weighted sampling on remainder stake (at most one extra per account). Ordering is separate: once each account’s rotation count is known, expand into a full rotation list and randomly permute it (Fisher–Yates with the same epoch-seeded ChaCha RNG used today). That way counts stay tight, but leaders are not laid down in phase-1-then-phase-2 order.
Motivation
Leader slots drive block rewards and MEV income. Operators forecast epoch revenue from stake, but under the current algorithm that forecast has large per-epoch error: variance from sampling noise, not performance or stake changes.
Ten consecutive epochs for one operator at ~0.056% stake (~240K SOL):
Single-epoch deviations here reach ±58 slots; the proposed algorithm caps each epoch to ±4 slots (±1 rotation).
Network-wide evidence (epoch 996)
Stake from epoch 995 (
activated_stake); actual slots from epoch 996 (leader_slots). Trillium.Expected slots =
(stake / total_stake) × 432,000. Schedule for epoch N+1 uses the stake snapshot from epoch N.Under the proposed rule, every vote account lands within ±4 slots of its proportional share every epoch.
Largest deviations (epoch 996):
Proposal
Let
rotation_weight = total_stake / 108,000(stake per rotation), withtotal_stakethe sum ofactivated_stakeover staked vote accounts.Phase 1 — floors (no randomness).
Assign every account
floor(activated_stake / rotation_weight)rotations outright. That is exactly the integer floor of its proportional share.Phase 2 — remainders.
After floors,
remaining = 108,000 − sum(floors)rotations are still unassigned. Each account keeps a leftover weight (activated_stakeminus floors × rotation_weight). Distribute those leftovers one at a time without replacement, weighted by leftover weight, using the same epoch-seeded ChaCha RNG family as today. Each win grants one extra rotation and clears that account’s remainder (at most one +1 per account).Final counts are therefore always floor or floor + 1.
Ordering — shuffle after counts, not phase order.
An earlier version of this proposal wrote the schedule in assignment order (floors, then remainder winners). Remainder winners are disproportionately smaller validators, who also tend to have higher skip rates. Parking them in a contiguous tail of the epoch concentrates skip risk and can amplify fork pressure.
So after counts are fixed, build the multiset of rotations (each leader repeated by its count) and randomly permute the whole list with Fisher–Yates, seeded from the same epoch ChaCha stream.
Schedule construction. Expand each shuffled rotation to 4 consecutive slots, same structure as today.
Worked example
432,000 slots ⇒ 108,000 rotations. Vote account at ~0.056% stake (~240K SOL);
rotation_weight ≈ 3,966 SOL:What stays the same
Stake snapshot timing at epoch boundaries. Four consecutive slots per rotation. Any node can recompute the schedule from public stake + epoch seed. No new accounts, RPC changes, or consensus-rule changes beyond schedule generation.
Comparison
Overshoots above proportional share are capped at +1 rotation. Small validators are not systematically queued at the end of the epoch.
All reactions