feat(rewarding): add DelegateDistributed batched log encoder (IIP-59 PR 4.7)#4923
Draft
envestcc wants to merge 1 commit into
Draft
feat(rewarding): add DelegateDistributed batched log encoder (IIP-59 PR 4.7)#4923envestcc wants to merge 1 commit into
envestcc wants to merge 1 commit into
Conversation
…PR 4.7) Introduces the encoder primitives for IIP-59 §3.2's per-delegate batched receipt log. distributeToVoters (PR 3', upcoming) calls Pack once per delegate at epoch close and wraps the returned (topics, data) into an *action.Log; the batching keeps total epoch-last-block logs bounded by |topDelegates| + |orphanDrain| (~200) regardless of voter count, avoiding receipt-trie bloat under load (top 100 delegates × ~2k voters each). New package action/protocol/rewarding/distributedlog: - Pack(EventArgs) → (action.Topics, []byte, error) encodes the event in the exact wire layout an EVM-emitted DelegateDistributed would produce, so eth_getLogs clients (and PR #45's off-chain verifier) can decode with stock ethers.js / web3.py against the same ABI. - EventArgs mirrors §3.2's Solidity signature field-for-field: Epoch(indexed) + Delegate(indexed) + RewardAddr + TotalCommission + TotalVoterPool + SnapshotHash + Voters[] + Amounts[] + Routings[]. - Routings[] reuses autodeposit.Route verbatim — PR 4.6's enum is the single source of truth for the credit/compound wire encoding. - SnapshotHash(voters, weights) computes the bytes32 digest of a delegate's frozen voter list, domain-separated ("iip59.delegatedistributed.snapshot.v1") so verifiers can pin the exact bytes and the value cannot collide with same-layout hashes from other contexts. Empty-list case is well-defined and asserted. - Hard-errors on caller-side wiring bugs (nil address, nil *big.Int, parallel-array length mismatch) — the encoder is not a consensus path so there is no per-item to degrade; loud failure surfaces PR 3' bugs. Empty voter list is NOT an error: a delegate with zero voters still emits a log for observability, per §3.2's "one log per delegate". - Structurally mirrors PR 4.5's delegateprofile.Bridge and PR 4.6's autodeposit.Bridge minimal-ABI package shape. Deliberately does NOT construct *action.Log; block context (height, action hash, protocol address) belongs to PR 3', keeping this package unit-testable in isolation. 15 tests cover: happy path, zero voters, both parallel-length mismatches, nil-field variants (delegate/reward/commission/pool/per-voter), selector-pin (golden 32 bytes for verifier stability), full byte-level round-trip via the same ABI, and SnapshotHash determinism / empty-list constant / truncation semantics.
|
This was referenced Jul 13, 2026
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
Adds the encoder primitives for IIP-59 §3.2's per-delegate batched
DelegateDistributedreceipt log.distributeToVoters(PR 3', upcoming) will callPackonce per delegate at epoch close and wrap the returned(topics, data)into an*action.Log.Batching keeps total epoch-last-block logs bounded by
|topDelegates| + |orphanDrain|(~200) regardless of voter count, avoiding receipt-trie bloat under load (top 100 delegates × ~2k voters each).Structural sibling of PR 4.5 (`delegateprofile`) and PR 4.6 (`autodeposit`) — same minimal-ABI package shape, same discipline about where the seam lands.
What lands
New package `action/protocol/rewarding/distributedlog`
Semantics
Hard-error on caller-side wiring bugs:
The encoder is not a consensus path, so there is no per-item to degrade — loud failure surfaces PR 3' bugs. Empty voter list is NOT an error: a delegate with zero voters still emits a log for observability, per §3.2's "one log per delegate".
Explicit non-goals
Test plan
Test coverage: happy path, zero voters, both parallel-length mismatch variants, nil-field variants (delegate/reward/commission/pool/per-voter address/per-voter amount), selector pin (golden 32 bytes so external verifiers can hard-code the same signature hash), full byte-level round-trip via the same ABI, and `SnapshotHash` determinism + empty-list constant + truncation semantics.
Stack
Branched on top of `iip-59/pr4.6-autodeposit-bridge` (#4922) because this PR imports `autodeposit.Route` at the Go-module level. Once PR 4.6 merges to `master`, the base of this PR can be flipped to `master` without conflict.
🤖 Generated with Claude Code