EIP-7732 Enshrined Proposer-Builder Separation
No call decision · Consensus & staking · EIP status Last Call · created 2024-06-28
Separates the execution payload from the beacon block, splitting the block into a consensus part and an execution part, and lets the proposer pick a builder's bid inside the protocol and hand block production to that builder. This is proposer-builder separation without a trusted intermediary.
Why it is needed
Today most beacon block proposers outsource production of the execution part of the block to an external builder. This requires going through a trusted intermediary that converts the payload the builder committed to into an actual block and broadcasts it, so both the proposer and the builder must rely on the goodwill of each other and of the intermediary. Validators also have to finish consensus validation, execution validation and blob data availability checks, and then vote, all within the short window of one third of a slot after receiving the block. Propagation is also slow because the entire execution payload is carried in the beacon block. This EIP makes the builder a staked in-protocol entity, which guarantees, without an intermediary, that an honest proposer gets paid regardless of the builder's behavior and that an honest builder's payload becomes the head of the chain regardless of the proposer's behavior. Execution validation is deferred to later in the slot, which eases the burden in the critical window before voting. Builders can also broadcast blob data early, which reduces reorg risk from including blob transactions.
What changes
Today
- The proposer hands block production to a builder through a trusted intermediary
- Validators must finish consensus validation, execution validation and blob data checks within one third of a slot
- The entire execution payload is carried in the beacon block, so propagation is slow
- Both the builder's payment and payload inclusion depend on the other party's goodwill
After EIP-7732
- The builder becomes an in-protocol entity that stakes from 1 ETH, and the beacon block carries only the builder's signed bid
- Validators verify only the consensus part before voting and defer execution and data verification to later in the slot
- Builder payments are settled trustlessly from the beacon chain deposit, and a new committee (PTC) votes on the timeliness of payload reveal
- The proposer and builder exchange fairly without an intermediary
Who is affected
- Validators: It adds a new duty, the Payload Timeliness Committee (PTC), but reduces the verification burden before voting and means attesters no longer miss attestations when a builder submits an invalid payload.
- Builder: Becomes an in-protocol entity that stakes on the beacon chain and signs bids with a BLS key. The payment promised to the proposer is enforced from the deposit.
- Client teams: Requires implementing a large hard fork that changes the beacon block structure, state transition, fork choice and P2P.
- Users: A transaction included in slot N is widely verified only when the proposer of slot N+1 builds a block on top of it and attesters vote for it.
In depth
Builder registration and deposit path
A builder is a new staked entity recorded in a separate registry (builders) in the beacon state. Because it is not a validator, it does not take part in attestations or committees and is not subject to the validator deposit and exit churn queues, and it can deposit from a minimum of 1 ETH. Registration, top-ups and exits are done only through a newly deployed builder deposit contract and builder exit contract on the execution layer, and each request is delivered to the consensus layer as an EIP-7685 request type, BUILDER_DEPOSIT_REQUEST_TYPE = 0x03 and BUILDER_EXIT_REQUEST_TYPE = 0x04. A payload may carry up to MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD = 64 deposit requests and MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD = 16 exit requests. Deposit signatures use a dedicated domain, DOMAIN_BUILDER_DEPOSIT, so they cannot be reused with validator deposit signatures and vice versa. An exit is valid only if the request is sent from the builder's execution address, it is not allowed while pending payments or withdrawals remain, and the builder can withdraw only after MIN_BUILDER_WITHDRAWABILITY_DELAY (64 epochs) has passed following the exit. The index of a fully withdrawn builder is reused, so implementations that cache public keys or indices need to be careful.
Beacon block and state structure changes
execution_payload, blob_kzg_commitments and execution_requests are removed from BeaconBlockBody, and signed_execution_payload_bid, payload_attestations and parent_execution_requests are added. The existing ExecutionPayloadHeader is replaced by ExecutionPayloadBid, which carries only the minimum information needed to commit to a payload, such as parent_block_hash, block_hash, prev_randao, fee_recipient, gas_limit, builder_index, slot, value, blob_kzg_commitments and execution_requests_root. When the proposer builds the block itself, it uses BUILDER_INDEX_SELF_BUILD (UINT64_MAX) as builder_index, a value of 0, and the point-at-infinity signature. The builder later signs and publishes an ExecutionPayloadEnvelope containing the payload and execution requests. BeaconState gains builders, latest_block_hash, execution_payload_availability, builder_pending_payments, builder_pending_withdrawals, latest_execution_payload_bid, payload_expected_withdrawals, ptc_window and others.
Payload Timeliness Committee (PTC)
For each slot, the PTC is formed by drawing PTC_SIZE (512) members from the concatenation of the beacon committees using effective-balance-weighted sampling, and the assignment is cached in ptc_window. PTC members broadcast a PayloadAttestationMessage before PAYLOAD_ATTESTATION_DUE_BPS (7500bp) of the slot, reporting whether the builder revealed the payload for the committed block hash before PAYLOAD_DUE_BPS (5000bp) (payload_present) and whether the blob data is available (blob_data_available). They do not need to verify the execution payload itself and perform only basic checks such as the signature and block hash. A beacon block carries up to MAX_PAYLOAD_ATTESTATIONS (4) PTC attestations from the previous slot, which are processed by process_payload_attestation. In fork choice, votes exceeding PAYLOAD_TIMELY_THRESHOLD and DATA_AVAILABILITY_TIMELY_THRESHOLD (both PTC_SIZE // 2) are used to decide whether the previous slot's payload counts as included. There is no separate penalty for PTC equivocation; the source explains that it chose implementation simplicity because an attack imposes a cost on the builder.
Two-stage state transition and deferred processing
The state transition is split into processing a signed beacon block and processing a signed payload envelope. The beacon state is changed only by the beacon block, and the envelope is only checked by a pure verification function, verify_execution_payload_envelope. The consensus layer effects of the payload (settling the builder payment, processing deposit, withdrawal, consolidation, builder deposit and builder exit requests, recording the availability bit, and updating latest_block_hash) are applied by process_parent_execution_payload at the very start of processing the next beacon block, which checks the block's parent_execution_requests against the parent bid's execution_requests_root. Because a single beacon state is kept per block, clients do not need to store or regenerate separate empty and full post-states for the same block, and builders do not need to compute the consensus state transition. The tradeoff is that execution requests are processed in the slot of the child block rather than the parent. Withdrawals are an exception: they are deducted immediately when the beacon block is processed and recorded in payload_expected_withdrawals, so that the next payload is invalid unless it includes exactly the same list. This is because deferring the deduction could break the total supply invariant.
Builder payments and proposer protection
When processing a beacon block that contains a bid, process_execution_payload_bid checks that the builder is active and that the balance exceeds MIN_DEPOSIT_AMOUNT plus all pending payments and withdrawals by at least the bid value, then records a BuilderPendingPayment. There are two paths by which a payment becomes a withdrawal. Either the payload is included onchain, or, even if it is not included, the beacon block receives at least 60% of the per-slot active balance (BUILDER_PAYMENT_THRESHOLD_NUMERATOR/BUILDER_PAYMENT_THRESHOLD_DENOMINATOR = 6/10) in same-slot attestations, in which case the payment is made in process_builder_pending_payments at the epoch transition. This is an unconditional payment mechanism: if the block arrived on time, the proposer is paid regardless of what the builder does. Conversely, if the block containing the bid is revealed late, the builder does not pay the bid value (builder withhold safety). The pending payment of a slashed proposer is removed in slash_validator, and builder payment withdrawals are processed from the builder_pending_withdrawals queue before all other withdrawals. Besides in-protocol payments, trust-based payments in the form of promises fulfilled elsewhere are also accepted.
Fork choice changes
Fork choice nodes become (root, payload_status) pairs, and the status is one of PENDING, EMPTY, or FULL. Attestations vote on payload inclusion as well, using the index field of AttestationData, which has been unused since Electra. 0 means the current block or a past block without a payload, and 1 means a past block with a payload; this value must match the availability record in the beacon state for the attestation to receive the timely head flag. Whether the previous slot's payload is part of the canonical chain is decided by a tiebreaker, not by attestation weight. FULL is preferred if the payload has been verified locally and the PTC voted above the threshold on timeliness and data availability, or if a current block that received the proposer boost was built on top of it. The blob availability check is removed from on_block and handled by a new handler, on_execution_payload_envelope, while on_payload_attestation_message aggregates PTC votes. With this structure, proposer unconditional payment, builder reveal safety (a payload revealed on time is included), and builder withhold safety are guaranteed within the stated security margins.
P2P and role changes
Four new global topics are introduced. They are execution_payload_bid (builder bids; only the highest bid per slot and parent is forwarded, it must match the proposer's preferences, and it must not carry execution_payment), execution_payload (the signed envelope), payload_attestation_message (PTC votes), and proposer_preferences (the fee recipient address and target gas limit that the proposer announces in advance). Bids for slots with no preference announcement are not propagated. Attestations with an index greater than 1 are rejected, and attestations with an index of 1 are ignored until the corresponding payload has been seen. DataColumnSidecar drops the KZG commitments, block header, and inclusion proof and carries only slot and beacon_block_root, verifying against the bid's commitments, and the builder is responsible for producing and broadcasting it. A builder may withhold the payload if the beacon block containing its bid was late and is not the head from its point of view. The ExecutionPayloadEnvelopesByRange and ExecutionPayloadEnvelopesByRoot request and response methods are also added. The Engine API does not change apart from supporting the new execution request types.
Security considerations and status
An economically rational but malicious builder can withhold a payload when it is profitable (the free option problem), and preliminary simulation data suggests this could be noticeable. As a mitigation, a variable penalty for builders that fail to get their payload included has been proposed. A collusion of proposers and attesters holding consecutive blocks and at least 20% of total stake can reorg a builder's payload while making the builder pay the bid value. The expected time for an attacker with 35% of total stake to capture a PTC majority is 205,000 years. The source status is Last Call, and the deadline (last-call-deadline) is 2026-11-01, so details may still change before finalization. In the call records, at 07.02 ACDE #240 it was decided to include in Devnet 7 a safeguard that allows deposits to be turned off in the preliminary builder deposit contract (sys-asm PR #49), and the ePBS slot deadlines for Devnet 7 were set to 3 seconds for attestations, 6 seconds for the payload, and 9 seconds for the PTC, with final confirmation to be made at Monday's ACDT. It was also discussed at 08.29 AMA #14, but no decision was made.