Ethereum Just Fired Its Middleman
Zakaria Saif7 min read·Just now--
How EIP-7732 replaces trusted relays with cryptoeconomics — and what it took to implement it from scratch.
Code: https://github.com/EIPs-CodeLab/EIP-7732
There is a dirty secret at the heart of Ethereum’s block production. More than 90% of blocks today are not built by the validator assigned to propose them. They are built by specialized third parties called builders — entities with powerful hardware, sophisticated MEV extraction, and access to private order flow that a normal validator simply cannot compete with.
The current solution is MEV-Boost: an off-chain protocol that introduced a trusted intermediary called a relay. The relay holds the builder’s payload on one side and the proposer’s signed commitment on the other, releasing both atomically to enforce the exchange.
It works. But it has one serious problem: you have to trust the relay. A compromised relay can censor transactions, withhold payloads, or become a single point of failure for the entire network’s block production. At peak times, a handful of relays process the majority of Ethereum’s blocks.
EIP-7732 moves the entire exchange in-protocol. No relay. No trusted middleware. The Ethereum protocol itself enforces the deal.
This is EIP-7732 — Enshrined Proposer-Builder Separation, or ePBS. It is one of the most structurally significant proposals heading into Ethereum’s Glamsterdam upgrade. And I just built a reference implementation of it.
The Core Idea: Split the Block in Two
An Ethereum block contains two logically distinct things. The consensus part — beacon block header, attestations, deposits — is small and fast to validate. The execution part — full transaction payload, EVM state transitions — is large and computationally expensive.
Before ePBS, these were bundled together. Every attester had to validate both within a 4-second window from slot start. That is tight. It constrains how many blobs can safely be included, requires powerful hardware from validators on the hot path, and forces the entire validator set to process the EL within the attestation deadline.
After ePBS, the timeline looks like this:
t = 0s — Proposer broadcasts BeaconBlock. Contains only a signed commitment from the builder. No full payload. Attesters validate only the CL state transition.
t = 4s — Attestation deadline. Validators have voted. Builder broadcasts the full ExecutionPayloadEnvelope containing the actual transactions.
t = 6s — PTC deadline. 512 Payload Timeliness Committee members have voted: did the builder reveal in time? Were blobs available?
t = 9s — Execution validation complete. All validators have had 9 seconds to validate the full payload. Nearly double the previous window.
t = 12s — Slot N+1 starts.
The critical attestation path now only requires the lightweight CL state transition. Execution is deferred. This directly improves Ethereum’s resilience to invalid payloads and opens the door to including more blobs per block without increasing reorg risk.
How the Payment Works Without a Relay
In MEV-Boost, the relay is the escrow. In ePBS, the beacon chain is the escrow.
Builders become in-protocol staked entities. They deposit ETH into the beacon chain using a new withdrawal credential prefix (0x03). Their balance is tracked directly in BeaconState.builders[]. When a builder submits a bid for a slot, they commit to a specific block_hash and a value in Gwei to pay the proposer.
The moment that bid is included in a beacon block — before any payload arrives — the committed value is immediately deducted from the builder’s balance and queued as a BuilderPendingPayment. This happens inside process_execution_payload_bid, one of the new state transition functions introduced by EIP-7732.
From that point on, the proposer’s payment is guaranteed regardless of what the builder does next. If the builder reveals their payload in time, the pending payment converts into a real withdrawal credited to the proposer’s execution layer address. If the builder never reveals — the proposer still gets paid.
This produces three possible slot states:
FULL — Beacon block and payload both canonical. Builder paid. Normal operation.
EMPTY — Beacon block canonical, payload never revealed. Proposer still paid. Builder forfeits their bid value.
SKIPPED — No beacon block. Validator offline. No builder involved.
The Empty case is the key innovation. It is the cryptoeconomic replacement for relay trust. A builder who withholds their payload doesn’t escape payment — they’ve already been charged. The only way for a builder to avoid payment is if the beacon block itself is withheld first, which is an attack on the proposer, not the builder.
The Payload Timeliness Committee
The PTC is the part of EIP-7732 I found most elegant when reading the spec. The protocol needs a way to determine whether the builder revealed in time. But it doesn’t want to force all 500,000+ validators to make that determination before the attestation deadline.
The solution: designate exactly 512 validators per slot — drawn randomly from the beacon committee — whose only job is to attest to payload timeliness. They check two things: did a SignedExecutionPayloadEnvelope arrive with the correct block_hash? Are the blob sidecars available? That's it. No EVM execution. No state root checks. This takes milliseconds.
The threshold for a PTC decision is 60% — 307 of 512 members. If reached, fork choice knows whether the slot is Full or Empty.
Security is solid. An attacker controlling 35% of total stake needs on average 205,000 years to achieve majority control of the PTC for a single slot.
What the Implementation Taught Me
I built the reference implementation in Rust, targeting Reth. Here is what the spec doesn’t make obvious until you’re deep in the code.
The Async Withdrawal Problem
Before ePBS, withdrawals were synchronous: the CL determined which validators should receive withdrawals, included them in the execution payload, and the EL credited them in the same processing step. After ePBS, the payload arrives on a completely separate P2P path from the beacon block.
The solution is a two-phase commit. When the beacon block is processed, the CL deducts the next batch of withdrawals from validator balances and commits the list to state.payload_expected_withdrawals. When the execution payload later arrives, it must contain exactly that list — or it is invalid. If a slot is Empty and no payload arrives, the withdrawal list persists and stalls all further withdrawal processing until a future payload honors it.
This is subtle. A real client needs to monitor consecutive empty slots carefully.
The state_root Circular Dependency
The ExecutionPayloadEnvelope commits to the CL post-state-transition beacon state root. But to compute that state root, you need to process the payload. And to broadcast the envelope, you need the state root in it first.
The resolution is that the builder must run the CL state transition function themselves — or use a trusted CL client API — to compute state_root before broadcasting. Validators then re-run the same transition and verify. This requires builders to either run a full CL client or trust a CL client endpoint — a meaningful new operational requirement that the spec doesn't highlight loudly.
The HonestBuilder Lifecycle
I modeled the builder as a state machine. Each slot, a builder moves through: Idle → BidSubmitted → BidIncluded → EnvelopeRevealed → Paid or Unpaid. This made the reveal timing logic much cleaner — the builder should only reveal their envelope when in BidIncluded state, and the machine enforces that.
What Changed in the Containers
The BeaconBlockBody changes are the most visible consequence of ePBS for anyone working on client code. Three fields disappear, two are added:
Removed: execution_payload, blob_kzg_commitments, execution_requests
Added: signed_execution_payload_bid, payload_attestations
The removed fields move to ExecutionPayloadEnvelope, which travels separately on P2P. The ExecutionPayloadHeader type is renamed to ExecutionPayloadBid — tracking only the minimum information needed to commit to a payload: blockhash, fee recipient, gas limit, value, and KZG commitments.
The BeaconState gains six new fields to track the builder registry, pending payments, withdrawal expectations, and slot payload availability history. The Engine API requires zero changes — the execution layer receives the payload in the same format as before.
Three New P2P Topics
EIP-7732 adds three new global gossip topics to the Ethereum P2P layer:
signed_execution_payload_bid — builders broadcast their bids when ready to commit to a slot.
payload_attestation_message — PTC members broadcast their timeliness attestations after the builder's reveal window.
proposer_preferences — proposers advertise their preferences for builder selection.
The Implementation
The full reference implementation is open on GitHub under EIPs-CodeLab — the organization I created to translate EIP and ERC specifications into working code.
github.com/EIPs-CodeLab/EIP-7732 Enshrined Proposer-Builder Separation — Rust reference implementation · Targeting Reth · Apache-2.0 · Glamsterdam
The repository covers the complete specification surface: all new SSZ containers, process_execution_payload_bid, process_payload_attestation, the async withdrawal split, a full fork-choice store with the three slot states, the honest builder lifecycle as a state machine, all three new P2P topics, and 28 tests across unit and integration suites.
It also ships with two simulations you can run immediately. make sim-builder runs a full ePBS round — proposer includes a bid, builder reveals, PTC votes, fork choice records the result. make sim-ptc runs four PTC scenarios including the split-view edge case. A CLI inspector lets you examine constants, containers, and slot states interactively.
There is also a docs/spec-gaps.md that documents every place where the spec is ambiguous or requires a judgment call — eight documented gaps including the state_root circular dependency, the PTC equivocation handling decision, and the withdrawal stall edge case. No other public implementation of EIP-7732 has this.
What Comes Next
ePBS is headed into Glamsterdam with devnet testing already underway. The scope freeze is targeted for Q2 2026. The next step for this implementation is wiring the BLS signature stubs to the blst crate, integrating proper tree_hash SSZ roots, and adding a cross-client Go implementation targeting Geth — the same EIP, two clients, one organization.
If you’re working on a client, a builder, or tooling that touches block production, the reference implementation and spec-gaps document are there for you. Open an issue if you find a discrepancy. The spec is still a draft and more gaps will surface as Glamsterdam devnets mature.
The relay isn’t going away overnight. But after ePBS, it becomes optional — a convenience layer on top of protocol-enforced guarantees, rather than the trust anchor for the whole system.
That is a meaningful shift. And it is coming soon.