Repository navigation
fix(ssv_types): pin Gloas block proposer index in the proposer value check - #1314
Conversation
…check SIP-94 §4 requires the proposer value check at Gloas slots to reject a value whose block proposer_index is not the duty validator. Operators sign the block root with the duty validator's key and the beacon node verifies it against proposer_index, so without the pin a foreign index loses the slot at publication instead of forcing a QBFT round change. Lighthouse's own proposer-index check only covers the locally produced block, not the decided one. The pin runs after the block-slot pin and before the slashing check, and is Gloas-only to match SIP-94, ssv-spec and go-ssv.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## epbs #1314 +/- ##
=======================================
Coverage ? 80.73%
=======================================
Files ? 179
Lines ? 41053
Branches ? 0
=======================================
Hits ? 33146
Misses ? 7907
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:
|
|
Fresh-eyes pass at 967d735 by Claude Fable 5.1 (autonomous review, posted from my account), no findings. Checked the pin's scope, order and comparison target against SIP-94 §4, ssv-spec Considered and dropped: applying the pin at every fork. Low leverage, since all three references scope it to Gloas and LH's local gate already covers the honest leader pre-Gloas. |
Problem, Evidence, and Context (Required)
SIP-94 §4 requires the Gloas proposer value check to reject a value unless
block.proposer_index == duty.ValidatorIndex.validate_block_proposalpins the version, block slot and payload root, but never readsproposer_index.For example, if a round leader proposes a Gloas block whose
proposer_indexis not the duty validator, Anchor operators accept and sign it. The beacon node then rejects the signature at publication and the slot is lost with no retry. Lighthouse's proposer-index check covers only the locally produced block before QBFT, not the decided one. ssv-spec (value_check.go#L215) and go-ssv ssvlabs/ssv#2901 (713d014,protocol/v2/ssv/value_check.go:383) already enforce it.Change Overview (Required)
BlockProposerIndexMismatchinvalidate_block_proposal, after the block-slot pin and before the slashing check, at Gloas slots only.Risks, Trade-offs, and Mitigations (Required)
An honest Gloas value can mismatch only when the duty went stale after a reorg. That block cannot be published anyway, and Lighthouse already refuses it locally, so no publishable block is rejected. Applying the pin at every fork was considered and rejected: it would change live pre-Gloas value checks with no observed failure.
Validation (Required)
BlockProposerIndexMismatchbefore the slashing check (tested with slashing protection off and on).Executed:
cargo test -p ssv_types --lib: 138 passed.cargo test -p anchor_validator_store: 171 passed.cargo +nightly fmt --all -- --check,make lint,git diff --check: passed.Not exercised: a QBFT-level test driving the rejection. Anchor's spec tests do not run ssv-spec's value-check vectors.
Rollback (Required for behavior or runtime changes; optional otherwise)
Revert the commit. No config, data or wire-format impact.
🤖 Generated with Claude Code