EIP-7917 Deterministic proposer lookahead

Final · Consensus & staking · EIP status Final · created 2025-03-24

At the start of each epoch, the list of block proposers for the current and next epochs is precomputed and stored in the beacon state. Who will propose blocks in the next epoch is fixed in advance.

Why it is needed

Ethereum selects block proposers every epoch (a time interval of about 6.4 minutes) using RANDAO, a random seed. The seed itself can be known one epoch ahead, but proposer selection also uses each validator's effective balance. However, if slashing or penalties accumulate to 1 ETH or more, the effective balance can change in the middle of an epoch, and after EIP-7251 raised the maximum effective balance, balances can also change beyond 32 ETH through reward accumulation, validator consolidation, and additional deposits. As a result, the proposer schedule for the next epoch is not fixed in advance. This is an obstacle for based preconfirmation protocols, which only work if proposers are known in advance, and the possibility of validators deliberately adjusting their effective balance to disturb the proposer schedule also remained a hard problem to analyze. This EIP fills this long-standing design gap by precomputing the proposer schedule and storing it in the state.

What changes

Today

After EIP-7917

Who is affected

In depth

The proposer_lookahead field

A field proposer_lookahead: Vector[ValidatorIndex, (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH] is added to BeaconState. It holds the proposer indices for the entire visible lookahead range, from the start of the current epoch to MIN_SEED_LOOKAHEAD epochs later. For example, proposer_lookahead[0] is the validator index of the first proposer of the current epoch, and proposer_lookahead[SLOTS_PER_EPOCH + 4] is that of the fifth proposer of the next epoch.

Simplification of get_beacon_proposer_index

Previously the proposer index was computed on the fly for each slot, but now get_beacon_proposer_index only returns state.proposer_lookahead[state.slot % SLOTS_PER_EPOCH]. Because it becomes a lookup that reads a precomputed value, it is easier for a consensus client to learn the next proposers in advance, which can simplify implementation.

Epoch boundary update logic

process_proposer_lookahead is added to process_epoch. It first shifts the portion for the epoch that just passed (SLOTS_PER_EPOCH entries) out of the front of the vector, then computes the proposer indices for current epoch + MIN_SEED_LOOKAHEAD + 1 epochs with get_beacon_proposer_indices and fills the last segment. compute_proposer_indices picks each slot's proposer using a per-slot seed (hash(seed + uint_to_bytes(slot))), made by appending the slot number to the epoch seed and hashing. The first block after the fork computes all the lookahead up to MIN_SEED_LOOKAHEAD epochs ahead and initializes the field.

Alternative considered: caching effective balances

An alternative was also considered in which the effective balances at the start of epoch N are cached and used for the lookahead computation at the start of epoch N + MIN_SEED_LOOKAHEAD. But it was not adopted because it needs extra storage in the beacon state and cannot provide the proposer lookahead to the EVM through the beacon root.

Compatibility with SSLE

Single Secret Leader Election (SSLE), in which only the elected validator knows its own turn in advance, may be introduced in the future. Current SSLE designs also use a lookahead in encrypted form, so in that case the type of proposer_lookahead can be changed to something like List[EncryptedValidatorIndex] and reused. If the design removes the lookahead entirely, it can be left as an empty list, so this EIP is not an obstacle. The source also explains that APS (Attester Proposer Separation) envisions an execution proposer that is more resistant to DDoS, which may reduce the need for SSLE itself.

Epoch boundary computation cost

Previously only one proposer index had to be computed per slot, but after this EIP the proposer schedule for an entire epoch must be computed at the start of the epoch. Computing a proposer index is a light operation that samples until a validator with sufficient effective balance is picked, but the source says that testing is needed to confirm this additional computation does not become a bottleneck.

Security: manipulation possibilities shrink rather than grow

The RANDAO delay used for the lookahead does not change. The lookahead for epoch N is still determined by the RANDAO of epoch N - MIN_SEED_LOOKAHEAD - 1. What changes is the reference point for effective balance: it uses the effective balance at the start of epoch N - MIN_SEED_LOOKAHEAD instead of at the start of epoch N. Aligning the timing of RANDAO and effective balance this way removes at the root the possibility of an attack that adjusts effective balance after seeing the RANDAO result. No such attack has ever been found, but removing the possibility itself simplifies the security analysis.

Status and spec changes

This EIP is Final and is a consensus layer change, so the detailed specification is reflected in the Fulu beacon chain spec in consensus-specs. The spec tests are also in the Fulu test directory of consensus-specs. No backwards compatibility issues were found.

Original EIP · ← EIPs