MEV-Boost & Relay Architecture
The trusted middleware in Ethereum's trustless system. Deep dive into the getHeader/getPayload flow, relay security, and the infrastructure that powers PBS.
🎯 What You'll Learn
- Understand the MEV-Boost protocol and its role in PBS
- Trace the getHeader and getPayload flow step-by-step
- Analyze relay trust assumptions and failure modes
- Evaluate builder-relay-proposer latency requirements
📚 Prerequisites
Before this lesson, you should understand:
The Trusted Middleware Problem
Ethereum is trustless. But for 12 seconds every slot, validators trust a single piece of software to deliver a block worth millions.
That software is MEV-Boost.
Without MEV-Boost: Validator builds own block → Gets ~0.05 ETH reward
With MEV-Boost: Builder builds block → Pays validator ~2 ETH for slot
This lesson explains how MEV-Boost works and why its failure has catastrophic consequences.
What You’ll Learn
By the end of this lesson, you’ll understand:
- MEV-Boost protocol - The software validators run to outsource block building
- Relay architecture - The trusted intermediary between builders and proposers
- getHeader/getPayload flow - The two-phase commit that prevents cheating
- Failure modes - What happens when relays go down or act maliciously
The Foundation: Why MEV-Boost Exists
Post-merge Ethereum validators can build their own blocks. But sophisticated builders can extract more MEV than validators can.
The problem: How can a validator accept a pre-built block without seeing it first (and stealing the MEV)?
The solution: A two-phase commit via a Relay.
┌─────────────┐
│ Builder │ Creates profitable block
└──────┬──────┘
│ submitBlock(block, bid)
▼
┌─────────────┐
│ Relay │ Validates block, stores it
└──────┬──────┘
│ getHeader() → returns bid + header
▼
┌─────────────┐
│ Proposer │ Signs header (commits to block)
└──────┬──────┘
│ getPayload(signed_header)
▼
┌─────────────┐
│ Relay │ Releases full block
└─────────────┘
The “Aha!” Moment
Here’s what makes MEV-Boost work:
The proposer signs the block header before seeing the block contents. Once signed, the proposer is cryptographically committed to that specific block. If the relay then refuses to release the block, the validator misses the slot entirely-but at least the builder can’t steal the MEV by having the validator build a different block.
The relay is the escrow agent in this transaction.
The Protocol: Step by Step
Phase 1: Builder Submits Block
// Builder sends to Relay
type SubmitBlockRequest struct {
Message BuilderBid
Signature BLSSignature // Builder signs their bid
Block ExecutionPayload
}
type BuilderBid struct {
Slot uint64
ParentHash [32]byte
BlockHash [32]byte
Value *big.Int // ETH paid to proposer
GasLimit uint64
GasUsed uint64
FeeRecipient Address // Builder's address for leftover
}
The relay:
- Validates the block (executes it)
- Stores the block indexed by header
- Makes the bid available via
getHeader()
Phase 2: Proposer Requests Header
// Proposer's MEV-Boost calls all relays
func getHeader(slot uint64, parentHash, pubkey []byte) *SignedBuilderBid {
// Call all registered relays in parallel
var bestBid *SignedBuilderBid
for _, relay := range registeredRelays {
bid, err := relay.GetHeader(slot, parentHash, pubkey)
if err != nil { continue }
if bid.Value > bestBid.Value {
bestBid = bid
}
}
return bestBid
}
The proposer receives:
BlockHash- Commitment to specific blockValue- ETH the proposer will receive- No block contents
Phase 3: Proposer Signs Header
// Proposer signs the header, committing to this block
signedHeader := bls.Sign(
proposerPrivateKey,
headerForSigning(bid),
)
This is the point of no return. The signed header can only be used with this exact block.
Phase 4: Proposer Requests Payload
// Proposer sends signed header to relay
func getPayload(signedHeader *SignedBlindedBeaconBlock) *ExecutionPayload {
return relay.GetPayload(signedHeader)
}
The relay:
- Verifies the signature matches the committed header
- Releases the full block
- Proposer broadcasts to network
Relay Trust Model
The relay is trusted to:
| Trust Assumption | What Happens If Violated |
|---|---|
| Validate blocks correctly | Invalid blocks get proposed, validator gets slashed |
| Store blocks reliably | Proposer signs header but payload never arrives (missed slot) |
| Release payload promptly | Late block propagation, potential missed attestations |
| Not front-run builders | Relay steals MEV by running its own builder |
| Remain available | Proposers can’t get bids, fall back to local building |
The “Data Availability” Attack
Malicious scenario:
1. Relay accepts builder's block
2. Relay gives proposer the header
3. Proposer signs and sends to relay
4. Relay refuses to release payload
5. → Proposer misses slot (loses rewards)
6. → Builder's MEV is "burned" (no one gets it)
Mitigation: Proposers register with multiple relays. If one fails, try others.
Code: MEV-Boost Registration
Validators register with relays before their slot:
# Validator registers with relay
def register_validator(relay_url: str, pubkey: str, fee_recipient: str):
registration = {
"message": {
"fee_recipient": fee_recipient,
"gas_limit": 30_000_000,
"timestamp": int(time.time()),
"pubkey": pubkey
}
}
registration["signature"] = sign_registration(registration["message"])
response = requests.post(
f"{relay_url}/eth/v1/builder/validators",
json=[registration]
)
return response.status_code == 200
Latency Requirements
Block building is a race. Every millisecond matters.
Slot timeline (12 seconds):
t=0: Slot starts
t=0-11: Builders construct blocks, submit to relays
t=11.8: MEV-Boost requests headers from relays
t=11.9: Proposer receives best bid
t=11.95: Proposer signs header
t=11.98: Proposer requests payload
t=12.0: Proposer broadcasts block
Latency budget:
- Relay response: <50ms
- Signature time: <10ms
- Payload delivery: <50ms
- Network propagation: remaining time
DevOps implications:
- Relays must be globally distributed (anycast)
- Direct peering with major cloud providers
- TCP/IP kernel tuning (see:
/learn/network-optimization-linux-latency)
Current Relay Landscape
| Relay | Operator | Market Share |
|---|---|---|
| Flashbots | Flashbots | ~30% |
| bloXroute Max Profit | bloXroute | ~25% |
| Ultrasound | Ultrasound Money | ~15% |
| Agnostic Gnosis | Gnosis | ~10% |
| Aestus | Aestus | ~5% |
Most validators register with multiple relays for redundancy.
Practice Exercises
Exercise 1: Trace a Block
Pick a recent Ethereum block on beaconcha.in.
1. Which relay delivered it?
2. What was the builder bid (in ETH)?
3. How much time before slot end was the block proposed?
Exercise 2: Failure Analysis
Scenario: Your relay returns 504 Gateway Timeout at t=11.9.
1. What happens if you have only one relay?
2. What's the fallback behavior in MEV-Boost?
3. How much ETH do you lose by building locally?
Exercise 3: Design a Relay
You're designing a new relay infrastructure.
Requirements:
- <50ms p99 latency globally
- Handle 1000 block submissions per slot
- Validate blocks in <100ms
What's your architecture? Consider:
- Geographic distribution
- Block validation parallelization
- DDoS protection
Key Takeaways
- MEV-Boost is trusted middleware - It’s the escrow in a trustless system
- Two-phase commit prevents cheating - Sign header first, get payload second
- Latency is critical - 100ms means losing bids
- Redundancy is essential - Register with multiple relays
What’s Next?
🎯 Continue learning: Trusted Execution Environments (TEE) - The future of trustless relays
🔬 Deep dive: The 100ms Tax
Now you understand how blocks flow from builders to validators. 🔄
Questions about this lesson? Working on related infrastructure?
Let's discuss