-
Notifications
You must be signed in to change notification settings - Fork 150
Boole hardening: partial-sig size cap, checked runner assertions, role-mapper lockstep test (#2978 items 3, 4, 7) #2989
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: stage
Are you sure you want to change the base?
Changes from 3 commits
83200f6
98986ed
6efc025
947b954
0b6c0c5
9a706e9
0a77e30
723c907
cdedff8
5b5d257
83498dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,10 +30,10 @@ func (mv *messageValidator) validatePartialSignatureMessage( | |
| ) { | ||
| ssvMessage := signedSSVMessage.SSVMessage | ||
|
|
||
| if len(ssvMessage.Data) > maxEncodedPartialSignatureSize { | ||
| if maxSize := mv.currentMaxEncodedPartialSignatureSize(); len(ssvMessage.Data) > maxSize { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test coverage. The codecov bot flags this file's uncovered lines; the untested one is this rejection branch (
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 723c907 — added the end-to-end case you suggested: a payload sized between the two caps is rejected against the pre-fork cap pre-fork (asserting the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update: the fork-aware cap was dropped in 83498dd (see PR conversation). The end-to-end case survives in trimmed form: an oversized payload is rejected, one at the cap passes the gate and fails at decode. |
||
| e := ErrSSVDataTooBig | ||
| e.got = len(ssvMessage.Data) | ||
| e.want = maxEncodedPartialSignatureSize | ||
| e.want = maxSize | ||
| return nil, e | ||
| } | ||
|
|
||
|
|
@@ -79,6 +79,20 @@ func (mv *messageValidator) validatePartialSignatureMessage( | |
| return partialSignatureMessages, nil | ||
| } | ||
|
|
||
| // currentMaxEncodedPartialSignatureSize returns the acceptance cap for encoded | ||
| // partial-signature message data. The post-fork (boole AggregatorCommittee) worst case is | ||
| // ~5x the pre-fork one, so pre-fork the smaller cap is enforced to keep the decode DoS | ||
| // surface at its pre-boole size. The cap is enforced before decoding, when the message's | ||
| // own slot is not yet known, so unlike the other fork gates in this package the switch is | ||
| // wall-clock based — and flips one epoch before boole activation so that messages for | ||
| // post-fork slots arriving early (clock skew) are never rejected against the smaller cap. | ||
| func (mv *messageValidator) currentMaxEncodedPartialSignatureSize() int { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Finding 2 · [MINOR] Use the receivedAt already threaded into the validator instead of a fresh wall-clock read
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 9a706e9. The fork-gate test builds fixtures from a fixed epoch, which also eliminates the dual-read flake iurii flagged.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update: 83498dd drops the fork-aware cap entirely (see PR conversation), so the selector is gone. |
||
| if mv.netCfg.BooleForkAtEpoch(mv.netCfg.EstimatedCurrentEpoch() + 1) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Finding 1 · [MINOR] Reuse networkconfig's prior-window constant instead of hardcoding + 1 The gate hardcodes a one-epoch lead — Since
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 0b6c0c5. A future widening of the prior window moves the cap flip with it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update: 83498dd drops the fork-aware cap entirely (see PR conversation), so the wrapper helper is gone too. |
||
| return maxEncodedPartialSignatureSize | ||
| } | ||
| return preForkMaxEncodedPartialSignatureSize | ||
| } | ||
|
|
||
| func (mv *messageValidator) validatePartialSignatureMessageSemantics( | ||
| signedSSVMessage *spectypes.SignedSSVMessage, | ||
| partialSignatureMessages *spectypes.PartialSignatureMessages, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -563,9 +563,17 @@ func (c *Committee) createRunner( | |
|
|
||
| switch duty := duty.(type) { | ||
| case *spectypes.CommitteeDuty: | ||
| c.Runners[duty.DutySlot()] = r.(*runner.CommitteeRunner) | ||
| cr, ok := r.(*runner.CommitteeRunner) | ||
| if !ok { | ||
| return nil, fmt.Errorf("BUG: runner created for committee duty has type %T, expected *runner.CommitteeRunner", r) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new type-mismatch errors begin with Context Used: CLAUDE.md (source) Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The BUG: prefix is deliberate here — it marks invariant violations and matches the existing |
||
| } | ||
| c.Runners[duty.DutySlot()] = cr | ||
| case *spectypes.AggregatorCommitteeDuty: | ||
| c.AggregatorRunners[duty.DutySlot()] = r.(*runner.AggregatorCommitteeRunner) | ||
| ar, ok := r.(*runner.AggregatorCommitteeRunner) | ||
| if !ok { | ||
| return nil, fmt.Errorf("BUG: runner created for aggregator committee duty has type %T, expected *runner.AggregatorCommitteeRunner", r) | ||
| } | ||
| c.AggregatorRunners[duty.DutySlot()] = ar | ||
| default: | ||
| c.logger.Panic("BUG: attempt to create committee runner with non-committee duty type", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional / non-blocking. The two runner type-mismatch cases above now return errors, but this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 5b5d257. |
||
| zap.String("type", fmt.Sprintf("%T", duty))) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit (doc clarity). The parenthetical "217748 bytes" is the spec's SSZ value (
20 + 1512·144), whereaspreForkMaxPartialSignatureMsgsSizeon line 63 evaluates to 217744 — it omits the 4-byte SSZ offset for the dynamicMessagesfield. Harmless (the encoding-overhead margin absorbs it, and it matches howmaxPartialSignatureMsgsSizeis computed), but a reader diffing 217748 vs 217744 may pause. A half-sentence noting the local figure is pre-offset would help.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 5b5d257 — the comment now notes the spec's 217748 includes the 4-byte SSZ offset of the dynamic Messages field, which the local pre-offset figure (217744) deliberately omits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: the pre-fork constants and this comment were removed in 83498dd. The fork-aware cap was dropped for the static post-fork bound (see PR conversation).