# Ethereum proposer lookahead
See also ["Preconf Lookahead and MaxEB"](https://hackmd.io/@linoscope/preconf-lookahead) by Lin Oshitani.
### Pre-electra
- Each slot, the proposer is calculated based on the `BeaconState` ([see `get_beacon_proposer_index`](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_beacon_proposer_index)).
- The key function call is [`compute_proposer_index`](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_proposer_index). Before EIP-7251, a candidate proposer selected based on their effective balance by comparing their effective balance with a randomly sampled byte (which is an integer, $\text{random_byte} = [0,255]$) using the following condition:
```python
if effective_balance * MAX_RANDOM_BYTE >= MAX_EFFECTIVE_BALANCE * random_byte:
return candidate_index
```
- This ensures that a validator with a <32 ETH balance is selected with a lower probability (e.g., a 16 ETH validator is only selected half as often as a 32 ETH validator because $16\cdot 255 \geq 32 \cdot \text{random_byte}$ if $\text{random_byte} < 128$). Note that with a 32 ETH validator, the if statement is always satisfied, and the validator is never skipped.
### Post-electra
- [`compute_proposer_index`](https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#modified-process_epoch) is changed in Electra (because of EIP-7251). The random byte is now 16 bits ($\text{random_byte} = [0,65535]$) and [`MAX_EFFECTIVE_BALANCE_ELECTRA`](https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#gwei-values) is 2048 ETH. Thus, the proposer loops through validator indices and checks the following condition:
```python
if effective_balance * MAX_RANDOM_VALUE >= MAX_EFFECTIVE_BALANCE_ELECTRA * random_value:
return candidate_index
```
- This is similar to before, but now a validator needs the full 2048 ETH balance to ensure the condition is true. For the "normal" 32 ETH validator, this condition is only true with probability 1/64 because $32 \cdot 65535 \geq 2048 \cdot \text{random_byte}$ if $\text{random_byte} < 1024$. This is the desired behavior because a 2048 ETH validator should be selected 64 times more often than a 32 ETH validator.
### How electra impacts the lookahead
As mentioned in [Lin's doc](https://hackmd.io/@linoscope/preconf-lookahead#Problem-Lookahead-in-Epoch-Boundries), the epoch N-2 RANDAO is used as input to the proposer selection in epoch N ([see `get_seed`](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_seed)). As such, during epoch N-1 (once the epoch N-2 RANDAO is fixed) predicting the proposers for epoch N should be feasible. However, at epoch boundaries, effective balances (which are still in 1 ETH increments) are now more likely to change through reward accrual (for compounding validators with >32 ETH balances), consolidations, and deposits ([see `process epoch`](https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#modified-process_epoch)). Why does this matter? Imagine the following scenario:
- During epoch N-1:
- A validator has a balance of 32 ETH and is selected as a candidate proposer for a slot in epoch N.
- Let $\text{random_byte}=2000$.
- Thus $32 \cdot 65535 \ngeq 2048 \cdot 2000$ and they are not selected as the proposer.
- A deposit adding 32 ETH to the validator's balance occurs at the end of epoch N-1.
- During epoch N:
- The validator now has a balance of 64 ETH.
- $\text{random_byte}=2000$ still.
- Now $64 \cdot 65535 \geq 2048 \cdot 2000$ and they *are selected* as the proposer.
Before electra, effective balance changes could still occur in many ways (e.g., due to an inactive validator balance decreasing or a full withdrawal taking place). After electra, there are simply more ways the effective balance can change, leading to a more difficult-to-predict leader schedule.