# Builder-API post ePBS for Staked Builders
## Introduction
As the name suggests, ePBS (enshrined Proposer-Builder Separation) integrates a builder entity directly into the Ethereum L1 protocol. It separates execution block validation from consensus block validation, creating a cleaner architectural division.
Under ePBS, the proposer receives bids from both enshrined builders and external entities like relays, then commits to a specific `ExecutionPayloadBid`. The proposer releases a `BeaconBlock` containing the committed `ExecutionPayloadBid`, which is subsequently attested by validators.
The `ExecutionPayloadEnvelope` is broadcast to the PTC (Payload Timeliness Committee) by the builder/off-protocol relays. Simultaneously, blobs from the `BlobsBundle` are split into data columns and distributed to the network.
The PTC observes the `ExecutionPayloadEnvelope` and sends a `PayloadAttestation` which indicates whether the payload has been seen or not. It ensures that the payload has been released in a timely fashion by the builder.
With ePBS, Builders can be staked in protocol by staking a minimum of 1ETH and using a 0x03 withdraw credential. Builder entities are different from Validator entities. Builders are staked but they do not engage in validator duties
The ePBS spec defines a p2p gossip topic called [`execution_payload_bid` ](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/p2p-interface.md?plain=1#L270). Validators can listen to bids for the execution payloads from builders via this gossip topic.
The P2P gossip topic might not always be ideal to transmit bids to the proposer. The proposer might want to directly connect to the builder via a TCP connection to receive the `SignedExecutionPayloadBid`.
This doc aims to specify how such an API could look like.
## Builder-API definition
The Builder-API for staked builders should be fairly simple as it just involves the proposer requesting the execution payload bid from the builder.
### High Level Flows
The flow to get the bid would go like the following:
1. The proposer sends POST HTTP requests to builders querying the `SignedExecutionPayloadBid`. The proposer passes in the `SignedRequestAuth` with the bid to sign the request.
2. The builder returns a `SignedExecutionPayloadBid` indicating the value of the bid via either the `bid.value` field or the `bid.execution_payment` field.
3. The proposer embeds the chosen `SignedExecutionPayloadBid` into a `SignedBeaconBlock` and returns it to the builder. Both the proposer and the builder broadcast the `SignedBeaconBlock` to the network.
4. The builder will then construct and broadcast the `SignedExecutionPayloadEnvelope` corresponding to the `SignedExecutionPayloadBid` to the PTC commitee.

### Validator Registrations
The proposer can send `ValidatorRegistrations` to the connected builders to communicate their `fee_recipient`, `gas_limit` and whether they are willing to accept a trusted payment from the connected builder.
We can define a new `ValidatorRegistrationV2` like the below:
```python
class ValidatorRegistrationV2(Container):
validator_index: ValidatorIndex
fee_recipient: ExecutionAddress
proposal_slot: Slot
gas_limit: uint64
builder_preferences: BuilderPreferences
```
We can define a `BuilderPreferences` object like the below:
```python
class BuilderPreferences(Container):
max_trusted_bid: uint64
```
The `builder_index` is the index of the staked builder to which the validator is sending this registration. It is the index of the builder in the `builders` list in the `BeaconState`.
The `validator_index` is the index of the validator in the `validators` list in the `BeaconState`.
The `proposal_slot` is a slot at which the validator will be a proposer.
Validators send the registrations only if they are proposing in a slot in the upcoming epoch unlike today where all validators send their registrations every epoch.
### Request Authentication
Builders only want the proposer for the given slot to be able to query their `SignedExecutionPayloadBid`. Other builders could potentially DOS a given builder to get to know their bid valuations.
To prevent other builders from being able to query their bid, we define a `RequestAuth` container which essentially contains a ByteList field which we enforce to be the URL of the builder. The proposer has to sign over this container and send the signature along with the container with the request. We can define the container as below:
```python
class RequestAuth(Container):
url: ByteList[MAX_URL_BYTES]
```
```python
class SignedRequestAuth(Container):
message: RequestAuth
signature: BLSSignature
```
## API definitions
### Execution Payload Bid retrival
The proposer queries the staked builder for a `SignedExecutionPayloadBid`.
GET `/eth/v1/builder/execution_payload_bid`
### Execution Payload Bid commitment
If the proposer chooses the `SignedExecutionPayloadBid`, it embeds it in its `SignedBeaconBlock` and sends it to the builder. The builder is responsible for constructing and broadcasting the `SignedExecutionPayloadEnvelope` to the PTC commitee. Both the proposer and builder can broadcast the `SignedBeaconBlock` for maximal desimination.
POST `/eth/v1/builder/beacon_block`
### Send Validator Registration
Called by a validator every epoch if they will be proposing in the upcoming epoch.
POST `eth/v2/builder/validators`
## Notes
1. The builder can pay the proposer either via the execution payload or via the trustless payment mechanism. The proposer can know which payment method is being used by looking at the `bid.value` and `bid.execution_payment` fields are set.
2. The proposer will have to manually store the urls of the staked builder. They could pass it in as a cmd line flag or a config file.
3. We still will have validator registrations for staked builders. As builders would require the fee recipient in advance if they choose to pay the validator via the execution payload rather than trustless payments.
4. We can just have SSZ support for all these APIs.