Milestone 1 - kintsugi testnet
This initial milestone provides simple middleware logic with minimal consensus client changes, simple networking, no validator authentication, and manual safety mechanism
Architecture
Block Proposal
participant consensus
participant mev_boost
participant execution
participant relays
Title: Block Proposal
Note over consensus: wait for allocated slot
consensus->mev_boost: engine_forkchoiceUpdatedV1
mev_boost->execution: engine_forkchoiceUpdatedV1
mev_boost->relays: engine_forkchoiceUpdatedV1
Note over mev_boost: begin polling
mev_boost->relays: relay_getPayloadHeaderV1
consensus->mev_boost: builder_getPayloadHeaderV1
mev_boost->execution: engine_getPayloadV1
Note over mev_boost: select best payload
mev_boost-->consensus: builder_getPayloadHeaderV1 response
Note over consensus: sign the block
consensus->mev_boost: builder_proposeBlindedBlockV1
Note over mev_boost: identify payload source
mev_boost->relays: relay_proposeBlindedBlockV1
Note over relays: validate signature
relays-->mev_boost: relay_proposeBlindedBlockV1 response
mev_boost-->consensus: builder_proposeBlindedBlockV1 response
Specification
- mev-boost must be initialized with a list of (
BLSPublicKey,RelayURI) pairs representing trusted relays. - mev-boost must intercept
engine_forkchoiceUpdatedV1call from the BN -> EC and forward it to all connected relays to communicatefeeRecipient. - mev-boost must begin polling connected relays for their
SignedMEVPayloadHeaderusingrelay_getPayloadHeaderV1requests. - mev-boost must verify the returned
SignedMEVPayloadHeadersignature matches the BLS key associated with the IP of the relay and has a matchingpayloadId. - upon receiving a
builder_getPayloadHeaderV1request from the BN, mev-boost must return theExecutionPayloadHeaderV1with the highest associatedfeeRecipientBalance. If no eligible payload is received from a relay, mev-boost must request and return a payload from the local execution client usingengine_getPayloadV1. - the BN must use the
ExecutionPayloadHeaderV1received to assemble and sign aSignedBlindedBeaconBlockand return it to mev-boost usingbuilder_proposeBlindedBlockV1. - mev-boost must forward the
SignedBlindedBeaconBlockto all connected relays and attach the matchingSignedMEVPayloadHeaderusingrelay_proposeBlindedBlockV1to inform the network of which relay created this payload. - if an
ExecutionPayloadV1is returned, mev-boost must verify that the root of the transaction list matches the expected transaction root from theSignedBlindedBeaconBlockbefore returning it to the BN.
required client modifications
- consensus client must implement blind transaction signing
API Docs
Methods are prefixed using the following convention:
engineprefix indicates calls made to the execution client. These methods are specified in the execution engine APIs.builderprefix indicates calls made to the mev-boost middleware.relayprefix indicates calls made to a relay.
engine_forkchoiceUpdatedV1
See engine_forkchoiceUpdatedV1.
engine_getPayloadV1
See engine_getPayloadV1.
builder_getPayloadHeaderV1
Request
- method:
builder_getPayloadHeaderV1 - params:
payloadId:DATA, 8 Bytes - Identifier of the payload build process
Response
- result:
ExecutionPayloadHeaderV1 - error: code and message set in case an exception happens while getting the payload.
builder_proposeBlindedBlockV1
Request
- method:
builder_proposeBlindedBlockV1 - params:
Response
- result:
ExecutionPayloadV1 - error: code and message set in case an exception happens while proposing the payload.
Technically, this call only needs to return the transactions field of ExecutionPayloadV1, but we return the full payload for simplicity.
relay_getPayloadHeaderV1
Request
- method:
relay_getPayloadHeaderV1 - params:
payloadId:DATA, 8 Bytes - Identifier of the payload build process
Response
- result:
SignedMEVPayloadHeader - error: code and message set in case an exception happens while getting the payload.
relay_proposeBlindedBlockV1
Request
- method:
relay_proposeBlindedBlockV1 - params:
Response
- result:
ExecutionPayloadV1 - error: code and message set in case an exception happens while proposing the payload.
Technically, this call only needs to return the transactions field of ExecutionPayloadV1, but we return the full payload for simplicity.
Types
SignedMEVPayloadHeader
See here for the definition of fields like BLSSignature
message:MEVPayloadHeadersignature:BLSSignature
MEVPayloadHeader
payloadHeader:ExecutionPayloadHeaderV1feeRecipient:Data, 20 Bytes - the fee recipient address requested by the validatorfeeRecipientBalance:Quantity, 256 Bits - the ending balance of the feeRecipient address
Note: the feeRecipient must match the suggestedFeeRecipient address provided in the PayloadAttributesV1 of the associated engine_forkchoiceUpdatedV1 request.
SignedBlindedBeaconBlock
See here for the definition of fields like BLSSignature
message:BlindedBeaconBlocksignature:BLSSignature
BlindedBeaconBlock
This is forked from here with body replaced with BlindedBeaconBlockBody
class BlindedBeaconBlock(Container):
slot: Slot
proposer_index: ValidatorIndex
parent_root: Root
state_root: Root
body: BlindedBeaconBlockBody
BlindedBeaconBlockBody
This is forked from here with execution_payload replaced with execution_payload_header
class BlindedBeaconBlockBody(Container):
randao_reveal: BLSSignature
eth1_data: Eth1Data
graffiti: Bytes32
proposer_slashings: List[ProposerSlashing, MAX_PROPOSER_SLASHINGS]
attester_slashings: List[AttesterSlashing, MAX_ATTESTER_SLASHINGS]
attestations: List[Attestation, MAX_ATTESTATIONS]
deposits: List[Deposit, MAX_DEPOSITS]
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
sync_aggregate: SyncAggregate
execution_payload_header: ExecutionPayloadHeader