Gloas -- Honest Builder¶
Note: This document is a work-in-progress for researchers and implementers.
- Introduction
- Becoming a builder
- Submit deposit
- Process deposit
- Builder index
- Activation
- Exiting
- Builder activities
- Constructing the
SignedExecutionPayloadBid - Constructing the
DataColumnSidecars - Constructing the
SignedExecutionPayloadEnvelope - Honest payload withheld messages
Introduction¶
This is an accompanying document which describes the expected actions of a "builder" participating in the Ethereum proof-of-stake protocol.
With the Gloas upgrade, the protocol introduces a new type of staked actor (not a validator) called a builder. Since builders are not validators, they do not perform validator duties (e.g., attesting and proposing) and therefore do not earn yield on their stake. Builders have the option to produce execution payloads by submitting bids. This document is a collection of guidelines for builders.
Becoming a builder¶
Submit deposit¶
Builders are created by submitting a builder deposit request to the builder deposit contract on the execution layer, as defined in EIP-8282. The request must include:
pubkey: The builder's BLS public key.withdrawal_credentials: The withdrawal credentials, where the first byte is the builder version and the last 20 bytes are the execution-layer address that will receive withdrawals. For the version, execution payload builders should usePAYLOAD_BUILDER_VERSION.amount: At leastMIN_DEPOSIT_AMOUNTgwei.signature: BLS proof of possession over the correspondingDepositMessageunderDOMAIN_BUILDER_DEPOSIT.
Note: Builders may be onboarded at the fork by submitting a deposit to the
validator deposit contract with a 0x03 withdrawal credential. This must be
done late enough that the deposit is still pending at the fork, but early enough
that the slot in which the deposit is added to the pending deposit queue is
finalized so that the builder is considered active. Such a deposit signs over
DepositMessage under DOMAIN_DEPOSIT, with withdrawal credentials of the form
BUILDER_WITHDRAWAL_PREFIX + b"\x00" * 11 + execution_address.
Process deposit¶
A builder deposit request for a new pubkey registers a builder. A request for an existing builder's pubkey tops up its balance.
Builder index¶
When the deposit is processed on the beacon chain, the builder is assigned a
unique builder_index within the builder registry. This index is used to
identify the builder in execution payload bids and envelopes.
Activation¶
Builders become active once the epoch in which they were registered (assigned an index) has been finalized. Since registrations occur as soon as deposits reach the beacon chain, builders typically become active two epochs after submitting their deposit.
Note: At the fork, pending deposits with the BUILDER_WITHDRAWAL_PREFIX are
applied to the builder registry. The builder's deposit_epoch is set to the
epoch of the pending deposit, not the fork epoch. Therefore, if that epoch is
finalized at the fork, the builder will be immediately active. See
onboard_builders_from_pending_deposits for details.
Exiting¶
A builder exits by submitting a builder exit request to the builder exit
contract on the execution layer, as defined in EIP-8282. The request contains
the builder's pubkey and is authorized by the builder's execution_address
(the transaction sender), not the BLS key.
The consensus layer initiates the exit only if the builder is active, the
request's source_address matches the builder's execution_address, and the
builder has no pending balance to withdraw. Otherwise the request is consumed
without effect and must be resubmitted once those conditions hold.
Builder activities¶
Builders have two optional activities: submitting bids and submitting payloads.
Builders can submit bids to produce execution payloads. They can broadcast these
bids in the form of SignedExecutionPayloadBid objects. These objects encode a
commitment to reveal an execution payload in exchange for a payment. When their
bids are chosen by the corresponding proposer, builders are expected to
broadcast an accompanying SignedExecutionPayloadEnvelope object honoring the
commitment. If a proposer accepts a builder's bid, the builder will pay the
proposer what it promised whether it submits the payload or not.
Constructing the SignedExecutionPayloadBid¶
Builders can broadcast a payload bid for the current or the next slot's proposer
to include. They produce a SignedExecutionPayloadBid as follows.
- Set
bid.parent_block_hashto be the parent hash of the constructed payload, that ispayload.parent_hash. - Set
bid.parent_block_rootto be the head of the consensus chain. This can be obtained from the beacon state ashash_tree_root(state.latest_block_header). Theparent_block_rootandparent_block_hashmust be compatible, in the sense that they both should come from the samestateandstoreby the method described in this and the previous point. - Construct an execution payload. This can be performed with an external
execution engine via a call to
engine_getPayloadV6. - Set
bid.block_hashto be the block hash of the constructed payload, that ispayload.block_hash. - Set
bid.prev_randaoto be the previous RANDAO of the constructed payload, that ispayload.prev_randao. This value MUST equalget_randao_mix(parent_state, get_current_epoch(parent_state)), whereparent_stateis the post-state ofbid.parent_block_root. - Set
bid.slotto be the slot for which this bid is aimed. This slot MUST be either the current slot or the next slot. - Set
bid.fee_recipientto be an execution address to receive the payment. The proposer's preferred fee recipient is obtained from theSignedProposerPreferenceswhosemessage.proposal_slotmatchesbid.slotand whosemessage.dependent_rootmatchesget_shuffling_dependent_root(store, bid.parent_block_root, compute_epoch_at_slot(bid.slot)), wherestoreis the fork choice store. - Set
bid.gas_limitto be the gas limit of the constructed payload, which MUST satisfyis_gas_limit_target_compatible(parent_gas_limit, bid.gas_limit, target_gas_limit), whereparent_gas_limitis thegas_limitof the parent execution payload andtarget_gas_limitis thetarget_gas_limitin theSignedProposerPreferencesreferenced in step 7. - Set
bid.builder_indexto be the index of the builder performing these actions. - Set
bid.valueto be the value (in gwei) that the builder will pay the proposer if the bid is accepted. The builder MUST have enough excess balance to fulfill this bid and all pending payments. - Set
bid.execution_paymentto zero. A non-zero value indicates a trusted execution-layer payment. Bids with non-zeroexecution_paymentMUST NOT be broadcast to theexecution_payload_bidgossip topic. - Set
bid.blob_kzg_commitmentsto be theblobsbundle.commitmentsfield returned byengine_getPayloadV6. - Set
bid.execution_requests_roottohash_tree_root(execution_requests), whereexecution_requestsis theExecutionRequestsfield returned byengine_getPayloadV6.
After building the bid, the builder obtains a signature of the bid by using:
Then the builder assembles
signed_execution_payload_bid = SignedExecutionPayloadBid(message=bid, signature=signature)
and broadcasts it on the execution_payload_bid global gossip topic.
Constructing the DataColumnSidecars¶
Modified get_data_column_sidecars¶
Modified get_data_column_sidecars_from_block¶
Note: The function get_data_column_sidecars_from_block is modified to use
beacon_block_root instead of header and inclusion proof computations.
Constructing the SignedExecutionPayloadEnvelope¶
When the proposer publishes a valid SignedBeaconBlock containing a signed
commitment by the builder, the builder is later expected to broadcast the
corresponding SignedExecutionPayloadEnvelope that fulfills this commitment.
See below for a special case of an honestly withheld payload.
To construct the ExecutionPayloadEnvelope the builder must perform the
following steps. We alias block to be the corresponding BeaconBlock and
alias bid to be the committed ExecutionPayloadBid in
block.body.signed_execution_payload_bid.message.
- Set
envelope.payloadto be theExecutionPayloadconstructed when creating the corresponding bid. This payload MUST have the same block hash asbid.block_hash. - Set
envelope.execution_requeststo be theExecutionRequestsassociated withpayload. - Set
envelope.builder_indexto be the index of the builder performing these steps. This field MUST bebid.builder_index. - Set
envelope.beacon_block_rootto behash_tree_root(block). - Set
envelope.parent_beacon_block_rootto beblock.parent_root.
After preparing the envelope the builder signs it using:
Then the builder assembles
signed_execution_payload_envelope = SignedExecutionPayloadEnvelope(message=envelope, signature=signature)
and broadcasts it on the execution_payload global gossip topic.
Honest payload withheld messages¶
An honest builder that has seen a SignedBeaconBlock referencing his signed
bid, but that block was not timely and thus it is not the head of the builder's
chain, may choose to withhold their execution payload. For this, the builder
should act as if no block was produced and not broadcast the payload.