# Flashbots Milestone 1 for Consensus Clients
This document describes the changes required for consensus clients to be compatible with [Milestone 1](https://github.com/flashbots/mev-boost#milestone-1---kintsugi-testnet) of Flashbots [`mev_boost`](https://github.com/flashbots/mev-boost).
Flashbots `mev_boost` is an application that builds `ExecutionPayloads` for post-merge Beacon Chain validators. In short, does all the fancy MEV stuff for PoS Ethereum that Flashbots already does for PoW Ethereum.
## The Flashbots Scheme
In Flashbots, there is a series of entities invovled in producing an `ExecutionPayload`. These include *searchers/users* who find transactions, *builders* who collate these transactions into an `ExecutionPayload` and *relays* who transmit an `ExecutionPayload` to validators.
From a consensus client perspective, a consensus node will interact with `mev_boost`, a component which abstracts away searchers/users, builders and relays. There is only one factor which necessarily leaks into the consensus engine, hiding the payload `transactions` from the validator.
In the Flashbots scheme, a validator must commit to a set of transactions without knowing those transactions. This prevents a validator from "stealing" transactions and breaking the Flashbots economic model.
This commitment can be achieved by having the validator sign over a block which contains only the *root* of the transactions. This means the validator doesn't know the transactions, but will be slashable if they produce a conflicting block. We call this *blind transaction signing*.
### Avoiding Central Points of Failure
The simplest integration method for `mev_boost` is for it to act as "middlware" between a beacon node (BN) and execution engine (EE). Hypothetically, if BNs support EEs that only provide an `ExecutionPayloadHeader` rather than a full `ExecutionPayload` then we have everything we need to support `mev_boost` (at milestone 1, at least).
However, using `mev_boost` as middleware means that the safety and liveness of the Beacon Chain rests upon it alone. This is a central point of failure.
A better solution, in my opinion, is to introduce the concept of a *payload-builder* to consensus engines. In such a scheme, a consensus engine will support a regular EE *and* a payload-builder.
When *producing* a block, a consensus engine queries the payload-builder for a payload. If the payload-builder doesn't respond, the consensus engine will defer to the EE to produce the payload.
When *verifying* a block, the consensus engine always defers to the EE. Consensus engines do not trust the payload-builder to verify payloads. Furthermore, if a local payload-builder is found to produce invalid payloads then it is excommunicated.
With this separate payload-builder and EE scheme, it's only possible for `mev_boost` to *temporarily* halt the chain but it's not possible for `mev_boost` to finalize invalid payloads (i.e., a correctness failure).
The rest of this document will assume the separate payload-builder and EE scheme.
## Changes for Consensus Clients
I assume a separate beacon node (BN) and validator client (VC) architecture, with comms via the [Standard Beacon Node API](https://ethereum.github.io/beacon-APIs/).
The `mev_boost` API is documented here: https://github.com/flashbots/mev-boost/tree/d2f1d861e1acb5c067f02d3eeb70aa9b30ea1ed7#api-docs
### Changes for Beacon Nodes
#### New Beacon API Endpoints
1. Add a `GET eth/v1/validator/blinded_block` which returns a `BeaconBlockHeader`.
1. Add a `POST eth/v1/beacon/blinded_block` which accepts a `BeaconBlockHeader`.
#### Add the Payload Builder
1. Provide a `--payload-builder` flag which accepts a HTTP endpoint.
1. Whenever an `engine_forkchoiceUpdatedV1` message is being issued to the EE, also issue that message to the payload builder (PB).
1. When producing a block, issue a `engine_getPayloadHeaderV1` (TODO: confirm with Flashbots API) to the PB. If the PB fails to return an `ExecutionPayloadHeader`, request an `ExecutionPayload` from the EE.
1. *Do not* use the `engine_executePayloadV1` endpoint on the PB to verify payloads. *Always* use the EE. There is no requirement to call `engine_executePayloadV1` on the PB.
1. If an EE indicates that an `ExecutionPayload` produced by the PB is invalid, log an error to the user and disable the PB until next restart. This requires the BN to store a list of block roots roots which have been produced by a local PB.
2. If the `--payload-builder` flag is supplied, any request to `GET eth/v1/validator/blinded_block` should attempt to use the PB. Without the flag supplied, use the EE.
2. If the `--payload-builder` flag is supplied, any request to `POST eth/v1/beacon/blinded_block` should send the the blinded block to the PB via `relay_proposePayloadV1` (TODO: propose payload needs a different type on the Flashbots API).
### Changes for Validator Clients
1. Add a `--blinded-payload-builder` flag which, when supplied, causes the VC to use the `validator/blinded_block` and `beacon/blinded_block` endpoints (rather than thier full `block` counterparts).