# 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).