Skip to content

Validator client: support Electra, Fulu and Gloas only; drop Lean and pre-Electra fork handling #790

Open

Description

@MegaRedHand

The validator client (crates/validator) should support Electra, Fulu and Gloas only, and stop carrying code for ForkName::Lean and the pre-Electra forks.

Why

The client already only works from Electra on. It submits SingleAttestations to /eth/v2/beacon/pool/attestations at every fork. It also refuses pre-Electra blocks (ProducedBlock::from_ssz) and aggregates ("electra is the earliest supported"). Every network we run against (mainnet, Sepolia, Hoodi, Platåberget) is past Electra.

The code still handles the earlier forks anyway, and Lean shows up only because ForkName is shared with the lean chain in ethlambda-types. Config::fork_at_epoch never returns Lean. Each of these branches guards a state that can't occur, but a reviewer still has to reason about it. The review of #789 spent several comments on this: whether the Lean arm's error is retryable, and whether committee 0 is right before Electra.

Line numbers below are as of 9be2506:

  • Arms that exist only to fail. Phase0 | Altair | Bellatrix | Capella | Deneb | Lean arms appear in beacon_node/block_contents.rs:316 and beacon_node/http.rs:881. fix(validator): slashing-protection review follow-ups: attestation index check, exit on a poisoned record #789 adds highest_attestation_index with a pre-Electra arm and a Lean arm, which returns a retryable InconsistentResponse after the request was already made.
  • Pre-Gloas attestation data is requested under the slot's own fork, as far back as Phase0. a_pre_gloas_slot_is_asked_about_under_its_own_fork asserts ForkName::Phase0. attestation_data_path sends committee_index=0 before Gloas, and every validator signs that same data. That would also be wrong before Electra, where data.index must be the attester's own committee.
  • The sync committee subscription gate checks < ForkName::Altair (lib.rs:817).
  • Tests pinned to the Phase0/Altair boundary: attestation.rs:769-818 (the Eth-Consensus-Version header test) and the boundary tests in signing.rs (around lines 461, 621 and 703).

Proposal

  1. Refuse to start before Electra. If the beacon node's schedule (from /eth/v1/config/spec) puts the current epoch before Electra, stop at startup with one clear error.
  2. Give the client its own fork type, e.g. enum ValidatorFork { Electra, Fulu, Gloas } with TryFrom<ForkName>. Convert once, where fork_at_epoch is called, so every match in the client has three arms and no Lean or pre-Electra ones. A fork added after Gloas still breaks every match until someone decides what it means.
  3. Remove the pre-Electra branches: the < Altair sync gate, the pre-Electra and Lean arms in block and aggregate decoding and in highest_attestation_index, and comments that describe pre-Electra semantics (e.g. the index as a committee).
  4. Move the boundary tests from Phase0/Altair to the Electra/Fulu or Fulu/Gloas boundary, so they still check that headers and domains follow the right epoch.

Consider dropping Electra too

Every network the client targets is already past Fulu:

  • mainnet: Fulu at epoch 411392, December 2025
  • Sepolia: epoch 272640
  • Hoodi: epoch 50688
  • Platåberget and the kurtosis battery (tooling/kurtosis-assertoor/network_params.yaml): Fulu from genesis

Supporting only Fulu and Gloas would remove the code that exists for Electra alone. That mainly means the per-blob-proof block contents (ProducedBlock::from_ssz's Electra arm and Contents::WithBlobProofs, which Fulu's cell proofs replaced) and whatever publishes them. It would also move the many tests that use Electra as their default fork over to Fulu. The startup check in step 1 would then refuse anything before Fulu, and the client's fork type would have two variants.

The cost is losing any network that is still on Electra, such as a local devnet configured with Electra at genesis and a later Fulu epoch. Worth deciding before step 2, since it changes the enum.

Out of scope

  • config_from_spec_response keeps parsing the whole fork schedule. Fork versions and epochs are configuration, not fork handling.
  • The altair:: sync committee containers stay. They are the containers in use today, not pre-Electra support.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions