IIP-59: cover block reward + snapshot-based voter list#73
Open
envestcc wants to merge 1 commit into
Open
Conversation
Amend IIP-59 so protocol-native distribution matches the two reward streams Hermes previously distributed (block + epoch), preserving voter net income at Hermes-era levels for the same commission rate. Foundation Bonus is explicitly out of scope (already zero on mainnet). Specification changes - Simple Summary / Abstract rewritten for dual stream. - New §3.1: block reward accumulates into a per-delegate pending pool during the epoch (O(1) per block, no per-voter work). - New §3.2: GrantEpochReward drains the pending pool and folds it into the single per-epoch voter distribution. - New §3.3: trailing drain for delegates that produced blocks but exited top-N before epoch end — bounded by candidate count (~100). - New §3.4: both commission rate and per-voter weight list are frozen at the previous epoch's PutPollResult; distribution reads from the frozen snapshot, not the live staking view. Gives voters a ~1.5-epoch reaction window on rate changes. Skeletons and supporting sections - §7.3 GrantBlockReward: route to pending pool when feature flag on and CommissionRate > 0; legacy credit path otherwise. - §7.4 GrantEpochReward: fold pending, call distributeToVoters reading the snapshot, then run orphan drain. - §7.5 Voter weight snapshot: per-candidate blob (21-byte key, sorted-by-voter proto), incremental write with byte-equality skip, DelState when voter list empties. Called from PutPollResult. - §7.6 GetActiveBucketsByCandidate marked as no longer needed — reward path reads only the snapshot. Rationale / Migration / Perf / Backwards Compatibility / Security / Test Cases updated for the dual-stream design: rate mapping from Hermes era is 1:1, per-block overhead is sub-millisecond, the snapshot determinism invariant (sorted encoding → byte-identical blobs) is called out, and three new test cases cover block-reward folding, non-top-N pending drain, and the snapshot reaction window. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced Jul 1, 2026
Closed
feat(rewarding,poll,staking): IIP-59 voter reward distribution (PR 4/5)
iotexproject/iotex-core#4864
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Amends IIP-59 so protocol-native distribution matches the two reward streams Hermes previously distributed — block reward + epoch reward — preserving voter net income at Hermes-era levels for the same commission rate. Foundation Bonus is explicitly out of scope (already zero on mainnet).
This is a spec-only change (touches
iip-59.md). No code in this PR.What changed
Specification (§3 split into 3.1–3.4)
GrantBlockRewardroutes to a per-delegate pending pool whenCommissionRate > 0. O(1) per block: one state read + one state write. No per-voter work at block time.GrantEpochRewarddrains each delegate's pending pool and folds it into the single per-epoch voter distribution call. Total voter income =(epochReward + Σ blockReward) × (1 − commission).GrantEpochRewarddrains pending pools for delegates that produced blocks but exited top-N mid-epoch. Bounded by candidate count (~100).PutPollResult; distribution reads the frozen snapshot, not the live staking view. Voters get a ~1.5-epoch reaction window on rate changes.Skeletons (§7)
GrantBlockReward— pending pool path + legacy path.GrantEpochReward— fold pending,distributeToVotersreading the snapshot, orphan drain.DelStatewhen a candidate's voter list empties.GetActiveBucketsByCandidatemarked as no longer needed — the reward path reads only the snapshot.Supporting sections
Test plan
🤖 Generated with Claude Code