fix(fork-choice): add same-slot index=0 validation for Gloas attestations#14
fix(fork-choice): add same-slot index=0 validation for Gloas attestations#14lodekeeper wants to merge 3 commits intounstablefrom
Conversation
|
@lodekeeper is this already correctly handled by ChainSafe#9177? |
|
Partially. ChainSafe#9177 covers validation #2 (index=1 requires known payload — their |
|
@lodekeeper can you check if this PR is still relevant with latest |
|
Checked against latest Current
So yes, this PR is still relevant. Happy to rebase onto the latest |
@lodekeeper yes please rebase |
c469b34 to
641e74b
Compare
|
Rebased onto latest unstable ( During rebase I found that upstream ChainSafe#9177 already landed the same attestation validation logic (index 0/1 check, same-slot handling, FULL variant existence check). So I dropped the duplicated code changes — this PR now only adds the 7 test cases for Gloas attestation validation that upstream doesn't have yet. Diff is now 1 file: |
|
@lodekeeper please check the github diff, your branch shows unrelated commits/changes |
|
@nflaig Root cause: Fix: synced |
|
@lodekeeper the pr diff is not clean yet
|
|
@nflaig Fixed — the stale GitHub merge base was the issue, not the branch content. Closed and reopened the PR to force recalculation. Diff is now clean: 1 file, 1 commit (just the test file Also updated the PR title/description since the validation logic already landed in ChainSafe#9177 — this PR now correctly scopes as test-only coverage for those rules. |
|
@lodekeeper this PR only contains tests now, what about this: do we already have that now on latest unstable? |
Add 7 tests for Gloas-specific attestation index validation: - same-slot index=0 succeeds (PENDING) - same-slot index=1 throws INVALID_DATA_INDEX - later-slot index=1 without FULL variant throws UNKNOWN_PAYLOAD_STATUS - later-slot index=1 with FULL variant succeeds (FULL) - same-slot index=1 throws even when FULL variant is known - later-slot index=1 succeeds after FULL variant arrives (retry) - later-slot index=0 maps to EMPTY 🤖 Generated with AI assistance Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ions Spec rule: if block_slot == attestation.data.slot, index must be 0. This was missing from upstream ChainSafe#9177 — same-slot attestations with index=1 were silently accepted and treated as PENDING instead of being rejected. Also adds non-Gloas block test to verify index validation only applies to Gloas blocks. 🤖 Generated with AI assistance Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1e19f43 to
73a98e0
Compare
|
@nflaig Good catch — the same-slot Same-slot attestations with Fixed: added the validation check + rebased onto latest |
|
|
||
| // Same-slot attestations must use index 0 — cannot vote FULL for same-slot block | ||
| // Spec: if block_slot == attestation.data.slot: assert attestation.data.index == 0 | ||
| if (isGloasBlock(block) && block.slot === slot && attestationData.index !== 0) { |
There was a problem hiding this comment.
@lodekeeper can this be combined with the condition above, isGloasBlock is checked for both cases
There was a problem hiding this comment.
Done — combined all three isGloasBlock checks under a single outer if (isGloasBlock(block)) block.
Collapse three separate `if (isGloasBlock(block) && ...)` guards into a single outer `if (isGloasBlock(block))` block, removing the redundant check repetition. 🤖 Generated with AI assistance
|
@lodekeeper I brought this to lodestar separately, thanks for taking a look, feel free to close this PR and consider it done |
|
Closing as requested — brought to lodestar separately. Thanks! |

Summary
Adds the missing same-slot attestation validation for Gloas blocks, plus comprehensive test coverage:
index = 0— spec:if block_slot == attestation.data.slot: assert attestation.data.index == 0index = 1(FULL) attestations requireFULLpayload status — already in upstream fix: only allow attestations for known payload statuses ChainSafe/lodestar#9177, tests added hereThe validation logic was missing from upstream ChainSafe#9177 — same-slot attestations with
index = 1were silently accepted and treated as PENDING instead of being rejected.Changes
packages/fork-choice/src/forkChoice/forkChoice.ts— adds same-slot index=0 check invalidateAttestationDatapackages/fork-choice/test/unit/forkChoice/forkChoice.test.ts— 8 test cases covering all Gloas attestation validation pathsTest plan
INVALID_DATA_INDEXUNKNOWN_PAYLOAD_STATUS🤖 Generated with AI assistance