---
# System prepended metadata

title: Builder-API Designs for Unstaked Builder

---

# Builder-API designs for Unstaked Builders

We document 2 potential designs for the Builder-API if we have unstaked builders. 

## Type definitions

We define some of the types we will be frequently using in our discussion of the API.

```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: ValidatorIndex
    slot: Slot
    value: Gwei
    execution_payment: Gwei
    blob_kzg_commitments_root: Root
```

```python
class SignedExecutionPayloadBid(Container):
    message: ExecutionPayloadBid
    signature: BLSSignature
```

```python
class ExecutionPayloadEnvelope(Container):
    payload: ExecutionPayload
    execution_requests: ExecutionRequests
    builder_index: ValidatorIndex
    beacon_block_root: Root
    slot: Slot
    blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
    state_root: Root
```

```python
class SignedExecutionPayloadEnvelope(Container):
    message: ExecutionPayloadEnvelope
    signature: BLSSignature
```

```python
class BlindedExecutionPayloadEnvelope(Container):
    payload: Root
    execution_requests: Root
    builder_index: ValidatorIndex
    beacon_block_root: Root
    slot: Slot
    blob_kzg_commitments: Root
    state_root: Root
```

```python
class SignedBlindedExecutionPayloadEnvelope(Container):
    message: BlindedExecutionPayloadEnvelope
    signature: BLSSignature
```

## Design 1

On a high level, the proposer<>relay/builder interactions could look like the following:

1. The proposer sends a `getHeader` request to the relay. It receives the `ExecutionPayloadBid` along with the `ExecutionPayloadHeader`, `ExecutionRequests` and `BlobKZGCommitments`. Similar to the data sent in the `getHeader` call today : https://github.com/ethereum/builder-specs/blob/main/types/electra/bid.yaml
2. If the proposer accepts this bid, it creates a `SignedBeaconBlock` with the `ExecutionPayloadBid` embedded into it. It also creates a `SignedBlindedExecutionPayloadEnvelope`. The proposer will have enough information to run a modified version of [process_execution_payload](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-process_execution_payload). More details on this in an upcoming section.
3. The proposer sends the relay back the `SignedBeaconBlock` and `SignedBlindedExecutionPayloadEnvelope`. The relay and proposer can both broadcast the `SignedBeaconBlock`. The relay can construct a `SignedExecutionPayloadEnvelope` and broadcast it to the PTC commitee.

The API is generally unopinionated about how the builder pays the proposer but we can assume the status quo as today where the builder inserts a payment transaction at the end of the block to the proposer's fee recipient. 

### API definitions

#### Execution Payload Bid retrival

The proposer queries this API and receives the `SignedExecutionPayloadBid` along with the `ExecutionPayloadHeader`, `ExecutionRequests` and `BlobKZGCommitments` for this slot.

GET `/eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{pub_key}`

#### Execution Payload Bid commitment

The proposer commits to the `ExecutionPayloadBid` by sending back to the relay, the `SignedBeaconBlock` which embeds the `ExecutionPayloadBid`. It also sends a `SignedBlindedExecutionPayloadEnvelope` to the relay which it has constructed.

POST `/eth/v1/builder/beacon_block`

### Sequence Diagram

![BuilderApiV2](https://hackmd.io/_uploads/B1_mScVzbg.png)


### Creating the BlindedExecutionPayloadEnvelope

The proposer receives the `ExecutionPayloadBid`, `ExecutionPayloadHeader`, `ExecutionRequests` and `BlobKZGCommitments` from the relay. 

The proposer can run a modified version of `process_execution_payload` without the engine_api invocation to validate the payload. The proposer runs `process_execution_payload` on the post-state after creating the `SignedBeaconBlock`

To create a `BlindedExecutionPayloadEnvelope`, the proposer can set the fields in the `BlindedExecutionPayloadEnvelope` as the following:
- *payload*: This is the hash tree root of the `ExecutionPayloadHeader` sent by the relay.
- *execution_requests*: This is the hash tree root of the `ExecutionRequests` sent by the relay
- *builder_index*: This is to be set to the index of the validator.
- *beacon_block_root*: This is the hash tree root of the `SignedBeaconBlock` with the `SignedExecutionPayload` embedded in it. 
- *slot*: This is the slot of the proposing block.
- *blob_kzg_commitments*: This is the hash tree root of the blob kzg commitments
- *state_root*: This is the state root of the beacon state post processing the `SignedBeaconBlock`.


## Design 2


On a high level, the proposer<>relay/builder interactions could look like the following:

1. The proposer queries the relay for an `ExecutionPayloadBid`. The relay sends an `ExecutionPayloadBid` and sets the `execution_payment` field to the value of the bid.
2. If the proposer accepts this bid, it sends a `SignedBeaconBlock` with the `ExecutionPayloadBid` embedded into it to the relay via a POST request.
3. The relay now has enough information to construct the `ExecutionPayloadEnvelope` from the `SignedBeaconBlock` sent. We detail more about constructing the `ExecutionPayloadEnvelope` in an upcoming section. 
4. The proposer queries the relay for the `BlindedExecutionPayloadEnvelope` corresponding to the `ExecutionPayloadBid`. The relay returns the corresponding `BlindedExecutionPayloadEnvelope`.
5. The proposer signs it and sends the `SignedBlindedExecutionPayloadEnvelope` back to the relay.
6. The relay is responsible for broadcasting the `SignedExecutionPayloadEnvelope` to the PTC commitee.

The API is generally unopinionated about how the builder pays the proposer but we can assume the status quo as today where the builder inserts a payment transaction at the end of the block to the proposer's fee recipient. 

### API definitions

#### Execution Payload Bid retrival

The proposer queries this API and receives the `SignedExecutionPayloadBid` for this slot.
GET `/eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{pub_key}`

#### Execution Payload Bid commitment

The proposer commits to the `ExecutionPayloadBid` by sending back to the relay, the `SignedBeaconBlock` which embeds the `ExecutionPayloadBid`.

POST `/eth/v1/builder/beacon_block`

### BlindedExecutionPayloadEnvelope Retrival

The proposer queries this API and receives the blinded execution payload envelope corresponding to the execution payload bid. 

GET `/eth/v1/builder/blinded_execution_payload_env`

#### BlindedExecutionPayloadEnvelope Commitment

The proposer signs the `BlindedExecutionPayloadEnvelope` and sends it to the relay. The relay is responsible for broadcasting the `SignedExecutionPayloadEnvelope` to the PTC commitee.

### Sequence Diagram

![BuilderApiUnstakedBuilders](https://hackmd.io/_uploads/BkiKb74fZe.png)


### Creating the ExecutionPayloadEnvelope

When the relay receives the beacon block from the proposer via `sendSignedBeaconBlock`, they need to construct the `ExecutionPayloadEnvelope`. 
The `payload`, `execution_requests` and `blob_kzg_commitments` will be available to the relay since they are part of the block submitted by the builder to the relay.
The `beacon_block_root` will be available from the signed beacon block submitted by the proposer. 
The latest `slot` will be available to the relay.
The relay will have to compute the `state_root` of the `ExecutionPayloadEnvelope`.

It will have to compute this state root by running [process_execution_payload](https://github.com/ethereum/consensus-specs/blob/master/specs/gloas/beacon-chain.md#new-process_execution_payload) on the beacon state after running STF on the beacon block with `beacon_block_root`.