Skip to content

Conversation

@bharath-123
Copy link
Collaborator

@bharath-123 bharath-123 commented Nov 28, 2025

This PR begins work and discussions on the builder-spec for ePBS for staked builders.

ePBS introduces the following protocol upgrades:

  1. Enshrining of builders into the protocol by allowing them to stake collateral(used for trustless payments)
  2. Decoupling BeaconBlock validation and ExecutionPayload validation.

A high level description of the design is available at: https://hackmd.io/J24hFHFvRl2DOZijvocukg?view

We introduce 2 new APIs(we have room for bikeshedding these names):

  1. getExecutionPayloadBid: GET /eth/v1/builder/execution_payload_bid
    This API is called by the proposer to the builder/relay. The proposer sends the fee_recipient as a header along with the request. The builder/relay returns an execution payload bid with the execution_payment directed to the sent fee_recipient.

  2. submitSignedBeaconBlock: POST /eth/v1/builder/beacon_block
    This API is called by the proposer to the builder/relay when the proposer commits to the bid received from getExecutionPayloadBid. The proposer sends the signed beacon block with the execution payload bid embedded to it.

We introduce ValidatorRegistrationV2 which contains the following new fields:

  1. builder_index: This is the index of the builder to which the registration is being sent.
  2. validator_index: This is the index of the validator to which the registration is being sent.
  3. builder_preferences: This contains the per builder preferences per validator. Currently the only builder preference supported is execution_payment_accepted.
  4. proposal_slot: This slot in which this validator will be proposing.

In gloas, All the validators will not send validator registrations every epoch like how it worked till Fulu. A validator will send it's registration in the epoch prior to which it will propose.
e.g, let's say a validator will propose in epoch E+1, it will send it's validator registrations at epoch E.

This spec is based on: ethereum/consensus-specs#4788 which is not yet merged.

Closes: #137

@bharath-123 bharath-123 changed the title Builder API updates for Glamsterdam Off-Protocol Builder API updates for Glamsterdam Dec 3, 2025
@bharath-123 bharath-123 changed the title Off-Protocol Builder API updates for Glamsterdam Builder API updates for Glamsterdam Dec 3, 2025
@bharath-123
Copy link
Collaborator Author

bharath-123 commented Dec 12, 2025

Open questions:

  1. How is the fee_recipient communicated to the builder? Do we keep ValidatorRegistrations or do we send the fee_recipient along as a header while receiving the bid. Or we can use the ProposerPreferences gossip topic as specified in: Add specs for proposer preferences consensus-specs#4777
  2. The API currently assumes all builders are staked. do we have to also support builders who choose to not stake?

@@ -0,0 +1,38 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What else can we spec out here?

@@ -0,0 +1,34 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What else can we spec out here?

This API is applicable from Glamsterdam fork onwards.
tags:
- Builder
parameters:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are no longer passing in the slot, parent_hash and pubkey as params in the path. I am unsure if we need to submit that data anymore since the validator already checks if the latest slot and parent_hash match from state while processing the ExecutionPayloadBid

required: false
description: |
Optional header containing the proposer's timeout for the request in milliseconds.
Relays should use this header to adjust the amount of time by which they delay getBid
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Relays should use this header to adjust the amount of time by which they delay getBid
Builders should use this header to adjust the amount of time by which they delay getBid

type: integer
format: int64
example: 10000
- name: X-Fee-Recipient
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently speccing it out to support sending the fee_recipient while sending the request to get the bid

@bharath-123
Copy link
Collaborator Author

Spellcheck fixes are trivial and shuoldn't block any feedback.


This document documents the builder behaviour with the Builder-API.

### `ValidatorRegistrationV1` are deprecated
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to deprecate ValidatorRegistrationV1 going forward for gloas? or do builders want to keep it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be value keeping validator registrations for validators to communicate per builder preference.

@bharath-123
Copy link
Collaborator Author

Note: We want the response to the get the bid to be signed by the validator on the builder pub key and slot. This is so that the builder won't get spammed by other builders to reveal their bid.

@bharath-123 bharath-123 changed the title Builder API updates for Glamsterdam Staked Builder API for Glamsterdam Dec 15, 2025
@bharath-123 bharath-123 marked this pull request as ready for review December 16, 2025 09:58
timestamp: uint64
pubkey: BLSPubkey
can_accept_trusted_payment: bool
proposal_epoch: Epoch
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we now suggest validator to send the registration only if they will be proposing in the upcoming epoch. This might be useful information to have?


```python
class ValidatorRegistrationV2(Container):
builder_pubkey: BLSPubkey ## is this needed?
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

primary use of validator registrations with gloas is to indicate per builder preferences. Maybe this can be helpful for the builder to identify if the registration is indeed indicated for them.

This specification suggests validators re-submit registrations only if they will be proposing in the upcoming epoch(E+1).
This is to avoid sending a lot of `ValidatorRegistrations` every epoch. This can potentially help reduce the load
Validators are expected to perform this check at every epoch boundary. Validators can send their registrations even though
they won't be proposing in the upcoming epoch.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't want to have a very strong enforcement on validators to send registrations only when they are proposing in epoch E+1 but we recommend them to do this.

def verify_registration_signature(state: BeaconState, signed_registration: SignedValidatorRegistrationV2) -> bool:
validator = state.validators[signed_registration.message.validator_index]
pubkey = validator.pubkey
domain = compute_domain(DOMAIN_APPLICATION_BUILDER)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to update the domain as we are introducing a new type of registration?


```python
class BuilderPreferences(Container):
execution_payment_accepted: boolean
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we allow validators to express arbitrary preferences here? That might be useful for proposers and builders alike. But the proposer and builders will have to agree on the scheme for preferences ahead of time. And on the other hand, hard coding preferences into BuilderPreferences will have to involve a co-ordinated rollout amongst clients.

assert signed_bid.prev_randao == get_randao_mix(state, get_current_epoch(state))
assert is_builder(state, builder.pubkey)

if signed_bid.value > 0:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might not be necessary for a builder to use the execution_payment field to pay the bid even through the builder-api.


```python
def is_eligible_for_bid(state: BeaconState,
registrations: Dict[BLSPubkey, ValidatorRegistrationV2],
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it shouldn't be relevant to use whether registrations are a Dict from BLSPubKey -> ValidatorRegistrationV2 or ValidatorIndex -> ValidatorRegistrationV2? or maybe it does?

description: Root of the beacon block the proposer will build on.
schema:
$ref: "../../builder-oapi.yaml#/components/schemas/Root"
- name: proposer_index
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we stick with the proposer pubkey or use proposer index?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Evaluate how Builder-API is going to change with ePBS

2 participants