Skip to content

feat: integrate gossip validation spec tests (consensus-specs #4902)#3

Closed
lodekeeper wants to merge 4 commits intounstablefrom
feat/gossip-validation-tests
Closed

feat: integrate gossip validation spec tests (consensus-specs #4902)#3
lodekeeper wants to merge 4 commits intounstablefrom
feat/gossip-validation-tests

Conversation

@lodekeeper
Copy link
Copy Markdown
Owner

@lodekeeper lodekeeper commented Feb 27, 2026

Summary

Integrate executable gossip validation reference tests from ethereum/consensus-specs PR #4902 into Lodestar's spec test suite.

Result: 73/74 tests passing, 1 justified skip

Production Fixes

Two spec deviations found and fixed:

1. Missing isSlashableValidator check in attester slashing validation

  • File: packages/beacon-node/src/chain/validation/attesterSlashing.ts
  • Issue: Spec requires at least one validator in the intersection to be slashable at the current epoch. Lodestar accepted attester slashings targeting already-slashed validators.
  • Fix: Added isSlashableValidator check before signature verification.

2. Wrong gossip action for NOT_LATER_THAN_PARENT

  • File: packages/beacon-node/src/chain/validation/block.ts
  • Issue: [REJECT] The block is from a higher slot than its parent — Lodestar was using GossipAction.IGNORE instead of GossipAction.REJECT.
  • Fix: Changed to REJECT per spec.

Test Harness

New file: packages/beacon-node/test/spec/utils/gossipValidation.ts

  • Bootstraps real BeaconChain from genesis state (same pattern as fork_choice.test.ts)
  • Imports setup blocks via full state transition
  • Wires finalized checkpoint into fork-choice store
  • Tracks failed-block roots for pre-validation filtering
  • Supports all 6 gossip topics: beacon_block, beacon_attestation, beacon_aggregate_and_proof, proposer_slashing, attester_slashing, voluntary_exit
  • Custom clock with ms-aware gossip disparity

Skipped Test (1)

  • gossip_beacon_attestation__reject_invalid_signature: Lodestar classifies invalid attestation signatures as IGNORE on gossip (batch validation returns invalid sigs as ignored, not rejected). This is intentional behavior — the spec expects REJECT.

Test Fixtures

74 fixtures from consensus-specs PR ChainSafe#4902 placed at:
packages/beacon-node/spec-tests/tests/minimal/phase0/networking/gossip_*/


AI-assisted: Architecture design, test harness, and implementation done with Codex CLI (GPT-5.3). Reviewed and validated by Lodekeeper.

Integrate executable gossip validation reference tests from
ethereum/consensus-specs PR ChainSafe#4902 into Lodestar's spec test suite.

Test harness (gossipValidation.ts):
- Bootstrap real BeaconChain from genesis state
- Import setup blocks via state transition
- Wire finalized checkpoint into fork-choice store
- Track failed-block roots for pre-validation filtering
- Support all 6 gossip topics: beacon_block, beacon_attestation,
  beacon_aggregate_and_proof, proposer_slashing, attester_slashing,
  voluntary_exit
- Custom clock with ms-aware gossip disparity

Production fixes found by spec tests:
- attesterSlashing: add missing isSlashableValidator check
  (spec requires at least one intersecting validator is slashable)
- block: change NOT_LATER_THAN_PARENT from IGNORE to REJECT
  (spec says REJECT for block not from higher slot than parent)

Skipped tests (1):
- reject_invalid_signature (attestation): Lodestar intentionally
  classifies invalid attestation signatures as IGNORE on gossip

Co-authored-by: Lodekeeper <lodekeeper@users.noreply.github.com>
// process_attester_slashing requires at least one intersecting validator to be slashable.
const currentEpoch = state.epochCtx.epoch;
const validators = state.validators;
if (!intersectingIndices.some((index) => isSlashableValidator(validators.getReadonly(index), currentEpoch))) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't we validation that somewhere else already, can you please check and share which gossip rule this is with a reference to the spec

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked — this specific condition is not covered by . That helper validates slashable attestation data + indexed attestation validity/signatures, but it does not enforce that any intersecting validator is currently slashable.\n\nSpec reference: gossip requires all conditions to pass, and in we must end with after iterating intersecting indices. This check enforces that precondition on gossip path. I also added an inline code comment clarifying this.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up with exact refs (my previous comment dropped some formatting): this is from the gossip attester slashing validation flow in p2p-interface.md (validate_attester_slashing). After validating both indexed attestations, the rule requires finding at least one overlapping validator index where is_slashable_validator(...) is true; otherwise the object must be ignored/rejected by gossip validation. assertValidAttesterSlashing does not enforce that intersection+slashable condition, so this check is needed on the gossip path.

};
};

// ── Gossip validation skips ────────────────────────────────────────────
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these comments with the ------ look a bit strange, can we remove those

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — removed those section-heading comments and pushed in 85f8ab5.

@nflaig
Copy link
Copy Markdown

nflaig commented Feb 27, 2026

feel free to close this and consider it done, I have merged your changes separately into my branch

@lodekeeper
Copy link
Copy Markdown
Owner Author

Thanks — closed as requested since this is already merged in your branch.

@lodekeeper lodekeeper closed this Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants