EIP-7732 - Enshrined Proposer-Builder Separation

Created 2024-06-28
Status Draft
Category Core
Type Standards Track
Authors

Abstract

This EIP fundamentally changes the way an Ethereum block is validated by decoupling the execution validation from the consensus validation both logically as well as temporally. It does so by introducing a new optional attribution (being a builder) and a new duty (submitting payload timeliness attestations) to Ethereum validators. The ExecutionPayload field of the BeaconBlockBody is removed and instead it is replaced by a signed commitment (a SignedExecutionPayloadHeader object) from a builder to later reveal the corresponding execution payload. This commitment specifies in particular the blockhash of the execution block and a value to be paid to the beacon block proposer. When processing the BeaconBlock, the committed value is deducted from the builder's beacon chain balance and credited to the beacon block proposer. A subset of validators in the beacon committee is assigned to the Payload Timeliness Committee (PTC), these validators are tasked to attest (by broadcasting a PayloadAttestationMessage) to whether the corresponding builder has revealed the committed execution payload (with the right blockhash) in a timely fashion. PTC members are not required to validate the execution payload, execution validation is thus deferred until the next beacon block validation.

Motivation

This EIP solves a different set of unrelated important problems.

Specification

Execution Layer

No changes are required.

Consensus Layer

The full consensus changes can be found in the consensus-specs Github repository. They are split between:

A summary of the main changes is included below, the Rationale section contains explanation for most of the design decisions around these changes.

Beacon chain changes

Constants
Name Value
PAYLOAD_ABSENT uint8(0)
PAYLOAD_PRESENT uint8(1)
PAYLOAD_WITHHELD uint8(2)
PAYLOAD_INVALID_STATUS uint8(3)
Presets
Name Value
PTC_SIZE uint64(2**9) (=512)
DOMAIN_BEACON_BUILDER DomainType('0x1B000000')
DOMAIN_PTC_ATTESTER DomainType('0x0C000000')
MAX_PAYLOAD_ATTESTATIONS 2**2 (= 4)
Containers
class PayloadAttestationData(Container):
    beacon_block_root: Root
    slot: Slot
    payload_status: uint8
class PayloadAttestation(Container):
    aggregation_bits: Bitvector[PTC_SIZE]
    data: PayloadAttestationData
    signature: BLSSignature
class PayloadAttestationMessage(Container):
    validator_index: ValidatorIndex
    data: PayloadAttestationData
    signature: BLSSignature
class IndexedPayloadAttestation(Container):
    attesting_indices: List[ValidatorIndex, PTC_SIZE]
    data: PayloadAttestationData
    signature: BLSSignature
class SignedExecutionPayloadHeader(Container):
    message: ExecutionPayloadHeader
    signature: BLSSignature
class ExecutionPayloadEnvelope(Container):
    payload: ExecutionPayload
    builder_index: ValidatorIndex
    beacon_block_root: Root
    blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
    payload_withheld: boolean
    state_root: Root
class SignedExecutionPayloadEnvelope(Container):
    message: ExecutionPayloadEnvelope
    signature: BLSSignature

The BeaconState container is modified with the addition of:

The BeaconBlockBody is modified with the addition of:

The ExecutionPayloadHeader object is changed to only track the minimum information needed to commit to a builder's payload.

State transition logic is modified by:

Fork choice changes

Constants
Name Value
PAYLOAD_TIMELY_THRESHOLD PTC_SIZE/2 (=uint64(256))
INTERVALS_PER_SLOT 4
PROPOSER_SCORE_BOOST 20
PAYLOAD_WITHHOLD_BOOST 40
PAYLOAD_REVEAL_BOOST 40
Containers
class ChildNode(Container):
    root: Root
    slot: Slot
    is_payload_present: bool

The class LatestMessage is modified to track the slot instead of an epoch:

@dataclass(eq=True, frozen=True)
class LatestMessage(object):
    slot: Slot
    root: Root

The class Store is modified to track the following fields:

    execution_payload_states: Dict[Root, BeaconState] = field(default_factory=dict)
    ptc_vote: Dict[Root, Vector[uint8, PTC_SIZE]] = field(default_factory=dict)
    payload_withhold_boost_root: Root
    payload_withhold_boost_full: bool
    payload_reveal_boost_root: Root

P2P changes

Engine API

No changes needed.

Rationale

Staked builders

Being a builder is a new attribution of validators. As such builders are staked in the beacon chain. This allows for in-protocol trustless enforcement of the builder's payment to the proposer. Alternatively, payment could be enforced in the Execution Layer (EL) at the cost of adding the corresponding EL consensus-changing logic. Payments in the EL have the advantage of not requiring the builder to periodically submit deposit transactions to replenish their validator balance. Both systems require availability of funds before the payload is revealed: in the Consensus Layer (CL) this is done by getting builders to stake. In the EL this is done with a balance check and a payment transaction. This transaction can be checked without executing the payload only if it the first transaction of the block.

Delayed validation

The Payload Timeliness Committee members do not need to validate the execution payload before attesting to it. They perform basic checks such as verifying the builder's signature, and the correct blockhash is included. This takes away the full execution payload validation from the hot path of validation of an Ethereum block, giving the next proposer 6 seconds (SECONDS_PER_SLOT * 2 // INTERVALS_PER_SLOT) to validate the payload and every other validator 9 seconds (SECONDS_PER_SLOT * 3 // INTERVALS_PER_SLOT). From a user UX perspective, a transaction included in slot N by the builder is not widely validated until the proposer of slot N+1 releases their beacon block on top of block N first and the attesters of slot N+1 vote on this beacon block as the head of the chain.

(Block, Slot, Payload) - Fork choice

The following features of fork choice are guaranteed under specified margins of security:

Proposer unconditional payment refers to the following. An Ethereum slot can be either:

Proposer unconditional payment refers to the fact that in the third scenario the beacon block proposer received payment from the corresponding builder.

Builder reveal safety refers to the fact that if the builder acted honestly and revealed a payload in a timely fashion (as attested by the PTC) then the revealed payload will be included on-chain. This is enforced by the addition of a new BUILDER_REVEAL_BOOST to the LMD weight of the fork choice node that contains the payload.

Builder withhold safety refers to the fact that if some beacon block containing a builder's commitment is withheld and revealed late, then that beacon block root will not be the canonical head of the blockchain in the view of honest validators.

In order to enforce this, any attestation on a given slot N for a block from a previous slot, not only does not support the block of slot N, but actually counts against it. This is the content of (Block, Slot) voting. Similarly, if a consensus for slot N+1 has the consensus block for slot N as parent beacon block, but the execution payload revealed in N-1 as parent execution block (thus ignoring the execution payload that may have been revealed during slot N), then any attestation for this consensus block N+1 does not support a chain that descends from the execution payload committed in consensus block N, that is, from the full slot N. This is the content of (Block, Slot, Payload) voting.

Builder timeliness boosts

When a builder reveals an expected payload and the PTC achieved consensus that it was timely, that is, when at least PAYLOAD_TIMELY_THRESHOLD votes have been received for PAYLOAD_PRESENT, the forkchoice node containing the full slot (that is the consensus block together with its payload present) receives a boost equivalent to 40% of the beacon committee.

Similarly, when a builder reveals a payload withheld message and the PTC achieved consensus by having at least PAYLOAD_TIMELY_THRESHOLD votes for PAYLOAD_WITHHELD, then the parent consensus block receives a boost equivalent to 40% of the beacon committee. Given the (Block, Slot) nature of fork choice voting, this boost counts against the consensus block containing the builder's commitment.

Both these boosts are present to guarantee the Builder's reveal and withhold safety under the parameters described in the Security Considerations section.

PTC equivocations

There is no penalty for PTC nor payload equivocation (that is revealing the right payload and also a withheld message at the same time). A collusion of a builder controlling network partition with a single malicious PTC member could cause a split view by achieving consensus both on payload withheld and a payload present. This could be mitigated by setting PAYLOAD_TIMELY_THRESHOLD to be 2/3 of the PTC, in which case the malicious operator would have to control at least 33% of the PTC.

Another mitigation mechanism is to add new slashing conditions for payload equivocation or PTC equivocations (both are signed messages by validators).

Since this attack results in a split view at a cost for the builder (the payload is revealed and may not be included) this EIP opted for simplicity of implementation.

Withdrawals

Withdrawals from the beacon chain are complex in nature, they involve removing funds from one layer and crediting them on another, with different trigger mechanisms that can start from either layer. Before applying the consensus layer state transition function to a given beacon state pre_state and processing a given signed beacon block block, the set of withdrawals that are expected to be deducted from the beacon chain are completely determined by pre_state. Previous to this EIP the set of withdrawals that are credited on the execution layer are included in block. The block is deemed invalid if these withdrawals do not match. With the separation included in this EIP, these operations of deducting and crediting become asynchronous:

This asynchronous mechanism has some consequences as slots may be empty as defined above. In these cases, the consensus layer does not process any more withdrawals until an execution payload has fulfilled the outstanding ones. An alternative design would be to defer all of withdrawal processing to the execution payload validation phase (ie. process_execution_payload). This has the advantage of not needing to track the fulfilled withdrawals on the beacon chain. The logic changes when several payloads are missing, in which case balances on the beacon chain change and therefore a withdrawal that would be possible with the former mechanism may be different, or even impossible with the latter.

Three state transition functions

The current EIP adds an extra state transition function to the block processing in Ethereum. Processing a SignedBeaconBlock changes the consensus layer BeaconState. A SignedExecutionPayloadEnvelope changes both the execution layer state and the consensus layer one. As such, the envelope commits to the consensus layer post-state-transition beacon state root.

Compatible designs

Inclusion lists

This EIP is fully compatible with forward inclusion lists as specified in EIP-7547 or similar.

Slot auctions

A simple change to this EIP is to remove the blockhash commitment from the SignedExecutionPayloadHeader. This allows the builder to commit any payload to the slot. A preliminary security analysis shows that payload equivocation does not weaken fork choice's FFG. Some advantages of Slot auctions include:

Backwards Compatibility

This EIP introduces backward incompatible changes to the block validation rule set on the consensus layer and must be accompanied by a hard fork.

Security Considerations

Reorg resistance

PROPOSER_SCORE_BOOST is reduced from 40 to 20. This does not allow however a ex-ante reorg by a proposer with 20% of the total stake as the attacker's payload will also not be included. Proposers are protected against 1-slot sandwich reorgs by a colluding set of validators and builders controlling more than 20% of the total stake.

Builder safety

Malicious PTC

The expected time for a malicious attacker, controlling 35% of the total stake, to have a majority control on the PTC is 205 000 years.

Copyright

Copyright and related rights waived via CC0.