# ePBS for Block Builders This document helps Block Builders understand the ePBS hard fork and highlights key considerations for them. ## Contents 1. [Introduction](#Introduction) 2. [Builders in ePBS](#Builders-in-ePBS) 3. [Slot Structure](#Slot-Structure) 4. [Payload Timeliness Committee](#Payload-Timeliness-Committee) 5. [Beacon Block Lifecycle](#Beacon-Block-Lifecycle) 6. [Builder Bidding Avenues](#Builder-Bidding-Avenues) - [P2P Bid Pool](#P2P-Bid-Pool) - [Builder-API](#Builder-API) 7. [How to Determine the Head Execution Payload to Build On](#How-to-determine-the-Head-Execution-Payload-to-build-on) 8. [Trustless Payments](#Trustless-payments) 9. [Builder Onboarding During the Glamsterdam Hard Fork](#Builder-onboarding-during-the-Glamsterdam-Hard-Fork) ## Introduction [ePBS](https://eips.ethereum.org/EIPS/eip-7732) is the headliner EIP scheduled for the Glamsterdam hard fork. It introduces major changes to the Ethereum protocol: 1. Restructuring the slot 2. Separating the Execution Payload from the Beacon Block 3. Enshrining Builders into the Ethereum Protocol 4. Enabling Builders to pay proposers via a trustless mechanism Each of these changes has significant implications for the Ethereum Protocol and its users. This document explores each aspect in detail. ## Builders in ePBS Builders are now enshrined actors in ePBS. Enshrinement means that the protocol is aware of builders and can recognize them natively. A [Builder](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L189) is represented by the following data structure in the Ethereum Protocol: ```python class Builder(Container): pubkey: BLSPubkey version: uint8 execution_address: ExecutionAddress balance: Gwei deposit_epoch: Epoch withdrawable_epoch: Epoch ``` At a high level, a Builder is similar to a Validator, but creating a builder requires passing in a 0x03 type withdrawal credential. Here is a breakdown of each field: 1. **pubkey**: The BLS public key identifying the builder on the Beacon Chain. 2. **version**: A field for versioning the Builder data structure as it evolves. It is set to [BUILDER_WITHDRAWAL_PREFIX](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L145), which is 0x03. 3. **execution_address**: The execution layer address to which the builder's collateral is withdrawn when they exit. 4. **balance**: The amount of collateral the builder has staked. 5. **deposit_epoch**: The epoch at which the builder's deposit was processed and added to the on-chain builder registry. 6. **withdrawable_epoch**: The epoch after which a builder's collateral becomes withdrawable to the execution_address. Initially set to [FAR_FUTURE_EPOCH](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/phase0/beacon-chain.md#L191). When a builder exits, this is [set to](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L742) [MIN_BUILDER_WITHDRAWABILITY_DELAY](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L180) epochs from the current epoch (4096 epochs). The minimum collateral required to become a Builder is defined as [MIN_DEPOSIT_AMOUNT](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/phase0/beacon-chain.md#L255), set to 1 ETH in the specs. Becoming a Builder follows a similar process to becoming a Validator. A prospective builder submits a deposit to the deposit contract just like a validator would, but must provide a 0x03 withdrawal credential. Unlike validators, a builder's deposit activates immediately when the deposit request appears in the execution payload. For validators, the deposit request is appended to a queue of pending deposits, which is processed over multiple epochs depending on validator churn, after which the validator becomes eligible for activation. Once activated, a builder is added to the [on-chain builder registry](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L375) and assigned a unique uint64 identifier called the [BUILDER_INDEX](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L115). Each Builder container instance is associated with a unique builder index. A builder's staked collateral primarily enables trustless payments to proposers when the proposer includes the builder's bid in their Beacon Block. We explain how trustless payments work in a later section. At a high level, trustless payments involve the builder transferring payment to the proposer from their staked collateral. To continue making trustless payments, a builder must maintain a minimum collateral of [MIN_DEPOSIT_AMOUNT](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/phase0/beacon-chain.md#L255), plus enough to cover any pending withdrawals and proposer payments. If a builder's collateral runs low, they can top it up by sending another deposit request to the deposit contract, which activates immediately upon appearing in an execution payload. ### Important Points for Builders Builder activation and collateral updates are very fast, taking approximately 2–3 blocks. (24–36 seconds). ## Slot Structure ePBS restructures the slot by changing the deadlines for different events within it. Below is the slot structure before ePBS: ![Pre-ePbs-Slot-Structure](https://hackmd.io/_uploads/Hk3bIse8-x.png) Below is the slot structure with ePBS: ![ePBS-Slot-Structure](https://hackmd.io/_uploads/BJMRDjeIbx.png) Notice that the attestation deadline is reduced from 4 seconds to 3 seconds. As we will see in later sections, the Beacon Block is much smaller in ePBS because it no longer contains the Execution Payload. This makes Beacon Block propagation much faster. There is also a new deadline called the "Payload Attestation Deadline". This is when members of the Payload Timeliness Committee (PTC) must send their Payload Attestations to signal the availability of the Execution Payload for that slot's Beacon Block. We explain the PTC in more detail in a later section. ### Important Points for Builders Builders and Node Operators must ensure their beacon block reaches enough validators before the 3-second attestation deadline to maximize the block's weight. This should be easier with ePBS since the Beacon Block is smaller. Builders must also ensure the PTC sees their ExecutionPayload on time to receive a timely vote. Otherwise, the Execution Payload risks becoming non-canonical and getting re-orged out. The Beacon Block lifecycle is described in a later section. Note: Variable PTC deadlines may be introduced for ePBS. See https://github.com/ethereum/consensus-specs/pull/4843 ## Payload Timeliness Committee The Payload Timeliness Committee (PTC) is a per-slot committee of [PTC_SIZE](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L153) (512) validators. They vote on whether the Execution Payload arrived on time for the given slot's beacon block. Importantly, they do not execute the payload—they only attest to its timeliness. The PTC is [sampled](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L687) from validators in the beacon committees for the given slot. Selection is [weighted by effective balance](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L543). A validator with an effective balance of 2048 ETH will always be selected for the PTC if considered during sampling. PTC validators must send a Payload Attestation Message every slot. This message indicates whether the payload was seen in a timely manner for that slot. The fork choice rule [aggregates](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/fork-choice.md#L145) Payload Attestations for each beacon block to determine whether the execution payload was revealed on time and can be built upon by the next proposer. Here is the structure of a PayloadAttestationMessage: ```python class PayloadAttestationMessage(Container): validator_index: ValidatorIndex data: PayloadAttestationData signature: BLSSignature ``` The PayloadAttestationData contains the information needed to communicate whether the payload and blob data for a given slot have been seen: ```python class PayloadAttestationData(Container): beacon_block_root: Root slot: Slot payload_present: boolean blob_data_available: boolean ``` Field descriptions: 1. **beacon_block_root**: The hash tree root of the beacon block for this slot. 2. **slot**: The slot for which the attestation is being sent. 3. **payload_present**: Set to True if the validator has seen the payload for this slot. 4. **blob_data_available**: Set to True if the validator has custodied their required data columns for this slot. Builders must propagate their Execution Payload on the [execution_payload P2P gossip topic](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/p2p-interface.md#L237) to ensure it reaches PTC members. More details on the Execution Payload and bid structure follow in the next section. For a payload to be considered timely, at least [PAYLOAD_TIMELY_THRESHOLD](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/fork-choice.md#L62) (50% of the PTC) validators must vote that the payload is [present](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/fork-choice.md#L207). PTC members should send their Payload Attestations before the deadline. Late attestations may not be considered by the fork choice rule when determining whether the payload should be extended in the execution chain. Payload Attestations are only valid for their designated slot. A PTC member cannot send a payload attestation for a previous slot—the P2P layer will invalidate it. ### Important Points for Block Builders At least 50% of the PTC members (>256) must see the payload for it to be considered timely. Builders must therefore broadcast their payload promptly across the network. ## Beacon Block Lifecycle ePBS separates the Execution Payload from the Beacon Block. Instead of containing the execution payload directly, the beacon block contains a commitment called the `SignedExecutionPayloadBid`. Think of it as having separate execution and consensus blockchains. Here is the structure of the `BeaconBlockBody` and `SignedExecutionPayloadBid`: ```python class BeaconBlockBody(Container): randao_reveal: BLSSignature eth1_data: Eth1Data graffiti: Bytes32 proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS] attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS_ELECTRA] attestations: List[Attestation, MAX_ATTESTATIONS_ELECTRA] deposits: List[Deposit, MAX_DEPOSITS] voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] sync_aggregate: SyncAggregate # [Modified in Gloas:EIP7732] # Removed `execution_payload` bls_to_execution_changes: List[SignedBLSToExecutionChange, MAX_BLS_TO_EXECUTION_CHANGES] # [Modified in Gloas:EIP7732] # Removed `blob_kzg_commitments` # [Modified in Gloas:EIP7732] # Removed `execution_requests` # [New in Gloas:EIP7732] signed_execution_payload_bid: SignedExecutionPayloadBid # [New in Gloas:EIP7732] payload_attestations: List[PayloadAttestation, MAX_PAYLOAD_ATTESTATIONS] ``` The `blob_kzg_commitments`, `execution_requests`, and `execution_payload` fields have been removed and replaced with a `SignedExecutionPayloadBid`. This is central to separating the BeaconBlock from ExecutionPayloads. Here is the `ExecutionPayloadBid` structure: ```python class ExecutionPayloadBid(Container): parent_block_hash: Hash32 parent_block_root: Root block_hash: Hash32 prev_randao: Bytes32 fee_recipient: ExecutionAddress gas_limit: uint64 builder_index: BuilderIndex slot: Slot value: Gwei execution_payment: Gwei blob_kzg_commitments_root: Root ``` Note that the `ExecutionPayloadBid` contains no payload data—only a commitment to it via the `block_hash`. Field descriptions: 1. **parent_block_hash**: The block hash of the execution block on which the associated execution payload is built. Typically the head of the execution chain. 2. **parent_block_root**: The hash tree root of the beacon block on which the bid is built. Typically the head of the consensus chain. 3. **block_hash**: The hash of the execution payload associated with this bid. 4. **prev_randao**: The randao mix for the current epoch. 5. **fee_recipient**: The proposer's fee recipient address. The bid payment goes to this address. 6. **gas_limit**: The gas limit of the constructed execution payload. 7. **builder_index**: The index of the builder who constructed this bid and execution payload. 8. **slot**: The slot for which this payload is valid. Typically the current proposing slot. 9. **value**: The amount of ETH the builder commits to pay the proposer if the bid is included. Upon successful bid inclusion and payload reveal, payment is transferred via the beacon chain. More details in the trustless payments section. 10. **execution_payment**: The amount the builder commits to pay the proposer through off-protocol means. The protocol does not verify this payment—the proposer must trust the builder. For self-builds, the `builder_index` field is set to [BUILDER_INDEX_SELF_BUILD](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L137). Here is the `SignedExecutionPayloadBid` structure: ```python class SignedExecutionPayloadBid(Container): message: ExecutionPayloadBid signature: BLSSignature ``` This is a signature over the `ExecutionPayloadBid`, signed by the builder's BLS private key. For self-builds, the signature is set to `bls.G2_POINT_AT_INFINITY` and value must be 0. The full execution payload, along with `ExecutionRequests` and `BlobKZGCommitments`, is sent in an `ExecutionPayloadEnvelope`: ```python class ExecutionPayloadEnvelope(Container): payload: ExecutionPayload execution_requests: ExecutionRequests builder_index: BuilderIndex beacon_block_root: Root slot: Slot blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK] state_root: Root ``` Field descriptions: 1. **payload**: The full execution payload associated with the bid. 2. **execution_requests**: The execution requests associated with the bid. 3. **builder_index**: The builder index of the builder who constructed the execution payload and bid. 4. **slot**: The slot for which the payload is constructed. 5. **blob_kzg_commitments**: The blob KZG commitments associated with the payload. 6. **state_root**: The hash tree root of the resulting BeaconState after constructing the `ExecutionPayloadEnvelope` and running [process_execution_payload](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L1490) without signature verification. Here is the `SignedExecutionPayloadEnvelope` structure: ```python class SignedExecutionPayloadEnvelope(Container): message: ExecutionPayloadEnvelope signature: BLSSignature ``` This is a signature over the `ExecutionPayloadEnvelope`, signed by the builder who constructed the corresponding `SignedExecutionPayloadBid`. For self-built blocks, the proposer signs it. At the start of a slot, the proposer sources `SignedExecutionPayloadBids` from the Builder-API, the P2P Bidpool, or builds one locally. Once the proposer selects a preferred `SignedExecutionPayloadBid`, it is included in the `BeaconBlockBody` as described [above](https://hackmd.io/uB8IYIc1SA6uTDk8vevoYA?stext=9702%3A974%3A0%3A1769266154%3ALN3Gad&both=). The proposer then broadcasts the beacon block to beacon committees to collect attestations. The builder whose `SignedExecutionPayloadBid` was included must then broadcast the corresponding `SignedExecutionPayloadEnvelope` to the Payload Timeliness Committee, collecting enough Payload Attestations to ensure the payload's timeliness and that the next proposer will build on top of it. The builder broadcasts the payload via the [execution_payload gossip topic](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/p2p-interface.md#L237). PTC members listen on this topic to send their payload attestations. Other validators also listen to receive the execution payload and update their execution states. Validators execute [on_execution_payload](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/fork-choice.md#L758) when they receive the payload. This method checks for data availability and performs the state transition with this payload. A key distinction from pre-ePBS: previously, the beacon block arrived with the execution payload attached. In ePBS, they arrive separately. The beacon block arrives via the [beacon_block gossip topic](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/p2p-interface.md#L201) containing the bid (a commitment to the execution payload), while the execution payload arrives via the [execution_payload gossip topic](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/p2p-interface.md#L237). ![BeaconBlockLifecycle](https://hackmd.io/_uploads/S1kkRzHLWg.png) > When reading these diagrams, think of gossip topics as distributed queues. An arrow toward a gossip topic represents a push to the queue; an arrow away represents reading from it. Modeling P2P communication as asynchronous queue operations makes the diagrams easier to understand. > This pattern applies to all diagrams in this document. ### Important Points for Builders The [DOMAIN_BEACON_BUILDER](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L129) domain is used to sign both the `ExecutionPayloadBid` and `ExecutionPayloadEnvelope`. Builders should ideally broadcast the `SignedExecutionPayloadEnvelope` only when confident that the BeaconBlock containing their bid will receive sufficient attestations. Builders benefit from broadcasting the `SignedExecutionPayloadEnvelope` as widely as possible so all validators can access their payload. ## Builder Bidding Avenues As we have seen, the BeaconBlock no longer contains the Execution Payload directly—instead, it contains a commitment in the form of a `SignedExecutionPayloadBid`. Builders send these bids to proposers, competing to have their bid included in the proposer's block. Proposers can receive bids through two avenues: 1. The P2P Bidpool 2. The Builder-API A rational proposer will select the highest-value bid from both avenues. We describe each below. ### P2P Bid Pool The P2P Bidpool is a gossip topic through which builders propagate their `SignedExecutionPayloadBids` to proposers. The topic is named [execution_payload_bid](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/p2p-interface.md#L291). Builders can send bids for the current or next slot. Bids sent via the P2P bidpool [can only be paid through the trustless payment mechanism](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/p2p-interface.md#L304), since builders on the network are anonymous and potentially malicious. To construct a `SignedExecutionPayloadBid`, a builder must know the proposer's fee recipient and gas limit preferences. Validators communicate these preferences via `ProposerPreferences` on the [proposer_preferences gossip topic](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/p2p-interface.md#L328): ```python class ProposerPreferences(Container): proposal_slot: Slot validator_index: ValidatorIndex fee_recipient: ExecutionAddress gas_limit: uint64 ``` Field descriptions: 1. **proposal_slot**: The slot at which the validator will propose. 2. **validator_index**: The validator's index in the on-chain registry. 3. **fee_recipient**: The address where the validator prefers to receive bid payments. 4. **gas_limit**: The preferred execution payload gas limit. Here is the `SignedProposerPreferences` structure: ```python class SignedProposerPreferences(Container): message: ProposerPreferences signature: BLSSignature ``` The validator must sign the `ProposerPreferences`. A validator sends their `ProposerPreferences` if they will propose in the upcoming epoch. Using [state.proposer_lookahead](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/validator.md#L130), validators can check whether they are scheduled to propose and send their preferences with `proposal_slot` set accordingly. Builders must construct bids that respect the `ProposerPreferences` sent by proposers. ### Builder-API The Builder-API provides proposers with a direct TCP connection to builders, offering a faster avenue for receiving bids than the P2P bidpool. **Disclaimer**: The Builder-API [specification](https://github.com/ethereum/builder-specs/pull/138) is still under review, and details may change. To access builders via the Builder-API, proposers need the builder's URL. Proposers typically maintain a list of URLs for builders they want to receive bids from. Since adding a builder's URL is an intentional action requiring the proposer to vet the builder, proposers can accept trusted payments in the execution layer. Currently, builders pay proposers by placing a payment transaction to the proposer's fee recipient at the end of the payload. With ePBS, the trusted payment value is specified in [bid.execution_payment](https://hackmd.io/uB8IYIc1SA6uTDk8vevoYA?stext=12238%3A339%3A0%3A1769576638%3AEm7t8i&both=). The proposer trusts the builder to make this payment—the protocol does not verify it. Builders can also pay via the trustless mechanism by setting the payment value in [bid.value](https://hackmd.io/uB8IYIc1SA6uTDk8vevoYA?stext=12238%3A339%3A0%3A1769576638%3AEm7t8i&both=). Here is a high-level overview of how the Builder-API works with ePBS: 1. The proposer queries all listed builders for their best `SignedExecutionPayloadBid`. 2. The proposer selects the best bid and includes it in the BeaconBlock. (The proposer might receive a better bid via the P2P bidpool, but for simplicity, we assume they select from the Builder-API.) 3. The proposer sends the BeaconBlock back to the builder, who then constructs and broadcasts the corresponding `SignedExecutionPayloadEnvelope` to PTC members. The API endpoint for requesting a `SignedExecutionPayloadBid`: ``` POST /eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{parent_root}/{proposer_index} ``` This returns the builder's best `SignedExecutionPayloadBid`. Bids are now identified by slot, parent_hash, parent_root, and proposer_index. Pre-ePBS, bids were identified only by slot, parent_hash, and proposer_index. The addition of parent_root is necessary because beacon blocks and execution payloads are now separate. A proposer might build on a beacon block without extending its execution payload, so the parent_hash may correspond to an ancestor rather than the payload associated with the parent_root beacon block. The API endpoint for sending the `BeaconBlock` with the bid to the builder: ``` POST /eth/v1/builder/beacon_block ``` This sends the beacon block containing the bid to the builder. Both the proposer and builder can broadcast the block to maximize network dissemination. The builder then constructs the `SignedExecutionPayloadEnvelope` corresponding to the bid and beacon block, and broadcasts it to PTC members. We intentionally keep this section brief to avoid excessive length. For a deeper dive, see the design document at https://hackmd.io/J24hFHFvRl2DOZijvocukg. Below is a diagram of the P2P Bidpool and Builder-API bidding avenues: ![BiddingAvenueSVG](https://hackmd.io/_uploads/SkdXdmS8Ze.svg) #### Important Points for Builders Bids sent via the P2P Bidpool can only pay proposers through trustless payments. Off-protocol payments via [bid.execution_payment](https://hackmd.io/uB8IYIc1SA6uTDk8vevoYA?stext=12238%3A339%3A0%3A1769576638%3AEm7t8i&both=) are only possible through the Builder-API. ProposerPreferences are primarily intended for builders submitting bids via the P2P bidpool, but builders using the Builder-API can also use them to track proposer information. ValidatorRegistrations will continue to exist with the Builder-API, allowing validators to communicate per-builder preferences. A key new preference is `max_trusted_bid`, which specifies the maximum trusted payment amount a proposer will accept from a given builder. ## How to Determine the Head Execution Payload to Build On In ePBS, a valid beacon block may have no corresponding execution payload. We call these EMPTY beacon blocks, and they are entirely valid. Beacon blocks with a valid execution payload are called FULL beacon blocks. Pre-ePBS, when a proposer selected a Beacon Block to build on, they implicitly also selected the execution payload to build on. In ePBS, these are separate: a proposer can build on a beacon block while extending the execution payload of its parent, and this remains valid. We won't cover the intricacies of fork choice updates here, but we will explain how proposers choose which execution payload to build on. The decision has two stages: 1. First, the proposer selects the head beacon block using the LMD-GHOST algorithm, as today. 2. Then, the proposer decides whether to use the execution payload corresponding to that beacon block. Proposers generally want to use the execution payload corresponding to the head beacon block unless there is a compelling reason not to. Fork choice always prefers FULL beacon blocks (those with valid execution payloads). The most common reason to build on an EMPTY beacon block is when the execution payload was not revealed to the PTC and most validators have not seen it. An important consideration: if a proposer builds on an EMPTY beacon block, but the network majority has seen the corresponding execution payload and the PTC has voted for its timeliness, the proposer's block will likely get re-orged out. ![ForkChoice](https://hackmd.io/_uploads/BJ4v3_8IZg.svg) ### Important Points for Builders Builders should only build on an EMPTY beacon block if the majority of the network and the PTC have not seen the execution payload for that beacon block. If a builder has seen the execution payload corresponding to the head beacon block, it is almost always best to build on top of it. ## Trustless Payments ePBS enables builders to pay proposers trustlessly when their bid is accepted. This contrasts with the current system, where proposers trust relays to ensure builder payment. Currently, payments occur via an execution layer EOA transfer placed at the end of the block. Trustless payments are handled entirely on the beacon chain, with payment flowing from the builder's staked collateral to the proposer. Here is how trustless payments work in detail. When a builder's bid is included in a proposer's beacon block, a [pending payment is created](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L1102) for the builder on the beacon chain. The payment becomes withdrawable when either the beacon block gains sufficient attestations or the `SignedExecutionPayloadEnvelope` is successfully revealed for that slot. Here is the `BuilderPendingPayment` structure: ```python class BuilderPendingPayment(Container): weight: Gwei withdrawal: BuilderPendingWithdrawal ``` Field descriptions: 1. **weight**: The sum of effective balances of validators who voted for the block containing the bid requiring trustless payment. 2. **withdrawal**: The pending withdrawal details, described below. ```python class BuilderPendingWithdrawal(Container): fee_recipient: ExecutionAddress amount: Gwei builder_index: BuilderIndex ``` Field descriptions: 1. **fee_recipient**: The proposer's fee recipient address. 2. **amount**: The ETH amount being paid to the proposer. 3. **builder_index**: The index of the builder making the payment. As mentioned, builder payments become withdrawable when either: 1. The block receives a [quorum of attestations](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L728) (defined as 60%). 2. The execution payload envelope is successfully revealed. Once withdrawable, payments are processed in batches every block. If the execution payload envelope is successfully revealed, the payment [converts to a withdrawal](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L1564) in the same block and enters the withdrawal queue starting from the next block. If the execution payload envelope is NOT successfully revealed, [payments are evaluated at epoch end](https://github.com/ethereum/consensus-specs/blob/46c1199d6b4584ba484dec807f03b8e6211dd725/specs/gloas/beacon-chain.md#L820) and become withdrawable if they received sufficient attestations. With successful payload reveal, payment takes a minimum of 12 seconds (1 block) to arrive. The worst case depends on queue congestion, as only 15 withdrawals are processed per block. Without successful payload reveal, payment takes a minimum of approximately 33 blocks (1 epoch + 1 block). The worst case again depends on withdrawal queue congestion. ![TrustlessPayments](https://hackmd.io/_uploads/Hk_JEYUL-l.svg) ### Important Points for Builders Proposers still receive trustless payments even if the payload is not revealed, as long as the block gains sufficient attestations. When submitting a bid, builders must ensure they maintain at least 1 ETH balance and account for all pending payments and withdrawals. These amounts are only released from collateral once the withdrawal is processed. ## Builder Onboarding During the Glamsterdam Hard Fork TODO: This is still in flux; taking some time to understand it well.