feat(message_validator): admit batched builder request auth partial signatures - #1302
Conversation
Allow a RequestAuth packet on Role::ProposerPreferences to carry 1 to 8 entries so a peer can gossip all of its builder auth shares for a proposal slot at once, as proposed for SIP-94 §5/§7 and already emitted by ssv-spec. Entries must share one signer and validator index; a packet naming two validators is a new Reject-class failure checked before the local-metadata membership rule. The distinct-root budget becomes set-based so a packet is admitted or ignored whole and an over-budget packet records nothing. Single-entry packets keep their exact previous classification, ProposerPreferences packets stay at one entry, and the sender still emits singletons.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## epbs #1302 +/- ##
=======================================
Coverage ? 80.22%
=======================================
Files ? 179
Lines ? 40595
Branches ? 0
=======================================
Hits ? 32567
Misses ? 8028
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Reviewed The receive-side change matches the current SIP-94 §5/§7 text: 1 to 8 auth entries, consistent signer and validator index, atomic distinct-root accounting, and independent preference/auth budgets. The collector test verifies that unmatched root C does not prevent A and B reconstructing. Checked the hosted CI logs: 986 debug and 986 release tests passed on the merge with current Two nonblocking notes: the PR description still says the SIP amendment is unwritten, but it is now in the linked text. Receiver support must also reach the whole network before batch sending is enabled; the current go-ssv ePBS branch still rejects multi-entry auth packets. This review establishes receive-side compliance, not mixed-client rollout readiness. Reviewed by GPT-6 Astra on high |
Problem, Evidence, and Context (Required)
RequestAuthPartialSigpacket to carry exactly one entry. Matheus proposed relaxing this on the SIP thread so an operator can gossip all of its builder auth shares for a proposal slot in one bounded packet, with per-builder isolation enforced by the receiving runner instead of by packet shape: ePBS (EIP-7732) Support ssvlabs/SIPs#94 (comment)Change Overview (Required)
RequestAuthpackets onRole::ProposerPreferenceswith 1 to 8 entries. Above 8 is a Reject, empty is still a Reject.ProposerPreferencespackets need no special case and there is still one enforcement site.ProposerPreferencespackets stay at one entry, every other role's packet rules, the sender (Anchor still emits one singleton packet per auth root), the signature collector, duty counting, and state retention. Configured-root matching stays in local collection, which already requests specific roots; gossip validation does not filter on private builder configuration.Risks, Trade-offs, and Mitigations (Required)
RequestAuthpackets on role 8. The risk is a classification slip (Accept/Ignore/Reject) or a budget slip on the batched path.Validation (Required)
cargo test -p message_validator: 161 passed (20 new). New tests cover singleton, two, and eight entry acceptance, empty and nine entry rejection, nine raw entries with repeated roots, twoProposerPreferencesentries still rejected, inner signer drift and inner-vs-outer disagreement, mixed validator indices with metadata present, with an unknown index, and with empty local metadata, all-known versus mixed known/new packets, repeated in-packet roots counted once, exact budget fit, over-budget recording nothing, forged outer signature recording nothing, independent kind budgets, one duty slot for a batch plus a preferences packet, and the pre-Gloas fork gate.cargo test -p signature_collector: 35 passed (1 new). The new test feeds three-entry auth packets for roots A, B, C from each remote operator and registers local collection for A and B only. Both reconstruct; C keeps a share-only collector and no local partial is published for it. This is the concrete case from the SIP thread: configuration agrees on A and B, differs on C, and C must not block A and B.make cargo-fmt-checkandmake lintpass.Rollback (Required for behavior or runtime changes; optional otherwise)
Blockers / Dependencies (Optional)
Additional Info / Next Steps (Optional)
sign_request_auth_v1is worth adding: with local entries for A and B only, both resolve while peer packets also carry C; with a local C entry whose data differs, only that local root fails to reach threshold.🤖 Generated with Claude Code