Gloas -- Honest Builder¶
Note: This document is a work-in-progress for researchers and implementers.
- Introduction
- Becoming a builder
- Builder withdrawal credentials
- Submit deposit
- Process deposit
- Builder index
- Activation
- 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¶
Builder withdrawal credentials¶
When submitting a deposit to the deposit contract, the withdrawal_credentials
field determines whether the staked actor will be a validator or a builder. To
be recognized as a builder, the withdrawal_credentials must use the
BUILDER_WITHDRAWAL_PREFIX.
The withdrawal_credentials field must be:
withdrawal_credentials[:1] == BUILDER_WITHDRAWAL_PREFIX(0x03)withdrawal_credentials[1:12] == b'\x00' * 11withdrawal_credentials[12:] == builder_execution_address
Where builder_execution_address is an execution-layer address that will
receive withdrawals.
Submit deposit¶
Builders follow the same deposit process as validators, but with the builder-specific withdrawal credentials. The deposit must include:
pubkey: The builder's BLS public key.withdrawal_credentials: With theBUILDER_WITHDRAWAL_PREFIX(0x03) prefix.amount: At leastMIN_DEPOSIT_AMOUNTgwei.signature: BLS signature over the deposit data.
Process deposit¶
The beacon chain processes builder deposits identically to validator deposits,
with the withdrawal credentials using BUILDER_WITHDRAWAL_PREFIX.
Builder index¶
Once the deposit is processed, 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 are active as soon as the deposit is processed on the consensus layer.
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 the current head of the execution chain (this can be obtained from the beacon state asstate.latest_block_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 samestateby 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_getPayloadV5. - 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. - Set
bid.fee_recipientto be an execution address to receive the payment. The proposer's preferred fee recipient can be obtained from theSignedProposerPreferencesassociated withbid.slot. - Set
bid.gas_limitto be the gas limit of the constructed payload. The proposer's preferred gas limit can be obtained from theSignedProposerPreferencesassociated withbid.slot. - Set
bid.builder_indexto be the index of the builder performing these actions. - 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.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_commitments_rootto be thehash_tree_rootof theblobsbundle.commitmentsfield returned byengine_getPayloadV5.
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
include the list of blob KZG commitments and 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.slotto beblock.slot. - Set
envelope.blob_kzg_commitmentsto be thecommitmentsfield of the blobs bundle constructed when constructing the bid. This field MUST have ahash_tree_rootequal tobid.blob_kzg_commitments_root.
After setting these parameters, the builder assembles
signed_execution_payload_envelope = SignedExecutionPayloadEnvelope(message=envelope, signature=BLSSignature()),
then verify that the envelope is valid with
process_execution_payload(state, signed_execution_payload_envelope, execution_engine, verify=False).
This function should not trigger an exception.
- Set
envelope.state_roottohash_tree_root(state).
After preparing the envelope the builder should sign the envelope 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.