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_forkchoiceUpdatedV1
call from the BN -> EC and forward it to all connected relays to communicatefeeRecipient
. - mev-boost must begin polling connected relays for their
SignedMEVPayloadHeader
usingrelay_getPayloadHeaderV1
requests. - mev-boost must verify the returned
SignedMEVPayloadHeader
signature matches the BLS key associated with the IP of the relay and has a matchingpayloadId
. - upon receiving a
builder_getPayloadHeaderV1
request from the BN, mev-boost must return theExecutionPayloadHeaderV1
with 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
ExecutionPayloadHeaderV1
received to assemble and sign aSignedBlindedBeaconBlock
and return it to mev-boost usingbuilder_proposeBlindedBlockV1
. - mev-boost must forward the
SignedBlindedBeaconBlock
to all connected relays and attach the matchingSignedMEVPayloadHeader
usingrelay_proposeBlindedBlockV1
to inform the network of which relay created this payload. - if an
ExecutionPayloadV1
is returned, mev-boost must verify that the root of the transaction list matches the expected transaction root from theSignedBlindedBeaconBlock
before returning it to the BN.
required client modifications
- consensus client must implement blind transaction signing
API Docs
Methods are prefixed using the following convention:
engine
prefix indicates calls made to the execution client. These methods are specified in the execution engine APIs.builder
prefix indicates calls made to the mev-boost middleware.relay
prefix 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
:MEVPayloadHeader
signature
:BLSSignature
MEVPayloadHeader
payloadHeader
:ExecutionPayloadHeaderV1
feeRecipient
: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
:BlindedBeaconBlock
signature
: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