Lesson 21 — Custom payload builder — sequencer-mode block production
Question
Custom PayloadBuilder = sequencer-mode block production. Reth-as-sequencer (centralised L2) needs this. Read the customisation pattern.
Principle (minimum model)
- PayloadBuilder trait.
build_payload(attrs) -> Payload. Called by sequencer to mint a block. - Standard impl. Takes mempool txs; orders by gas price; builds block. Used by Eth nodes.
- Custom impl. Override to add: bundle txs from MEV searcher, drain pending fills (CLOB), system txs (L1 messages), priority queue (payment rail).
- Wire via NodeBuilder.
NodeBuilder::payload_builder(YourBuilder::default()). - Hot path. Called every 12 seconds (or your block time). Performance matters.
- Tests. Build a payload; assert it contains expected txs + system txs.
- Production examples. op-rbuilder (Flashbots) for OP Mainnet, Hyperliquid sequencer, Tempo sequencer.
- Sequencer mode = centralised. Trade-off: faster blocks vs decentralisation. Production L2s pick the trade-off explicitly.
Worked example + steps
Custom payload builder — sequencer-mode block production
For Ethereum mainnet, blocks are produced by validators running the consensus client and pulling proposed payloads from the execution client. For an L2 or any centralized-sequencer chain, the block-production model is different: the sequencer is the block producer, full stop. The payload builder is the component that knows how.
1. The trait surface
PayloadBuilder (and friends) is the slot in reth's NodeBuilder for "how to build a block." It takes:
- A parent block (where we're building from)
- Current chain state
- A pool of pending transactions
- A timestamp / slot
...and returns a built block (the "payload"). On mainnet, the validator's consensus client triggers this via the Engine API. On a sequencer L2, the sequencer triggers it directly.
2. Three production-relevant builders
The reth ecosystem has multiple payload builders to study:
| Builder | Where | Use case |
|---|---|---|
| Default Ethereum builder | crates/payload/builder/ | Mainnet validators |
| OP payload builder | crates/optimism/payload/ | OP Stack sequencer |
| op-rbuilder | flashbots/rbuilder | High-perf external block builder for OP Stack |
The first two are inside reth. op-rbuilder is a separate repo, more aggressive about MEV and ordering policy, and is the production builder several OP Stack chains use.
3. What an L2 builder does differently
Sequencer-mode block production typically:
- Force-includes deposit txs at the top of the block (from a known L1 oracle queue)
- Sorts the rest of the block by either FIFO (first-come-first-serve) or priority-fee
- Updates the L1 block oracle storage slot as the first state write
- Caps the block at the L2 gas limit (not the mainnet limit)
- Tags the block with the sequencer's signature (some L2s commit to sequencer identity)
Notice that several of these are not in the executor — they're in the builder. Why? Because the builder controls what goes into a block; the executor only runs what's in a block.
4. The MEV question
A sequencer that orders transactions can extract MEV in ways a validator can't (it has no consensus competitor inside its block).
Three positions a sequencer can take:
| Position | What it means | Examples |
|---|---|---|
| MEV-blind | Strict FIFO, no peeking into tx semantics | Some smaller L2s claim this |
| MEV-aware, public | Public order flow, builder accepts MEV-share-style bids | OP Stack with op-rbuilder |
| MEV-extracting | Sequencer runs internal searchers | (Often opaque; centralized chains can do whatever they want) |
The choice ends up in the payload builder's source code, gated by feature flags or external builder integrations. Reading a chain's payload builder is reading its MEV policy.
5. op-rbuilder — the production-grade reference
flashbots/rbuilder is the external builder Paradigm built for OP Stack. Worth studying because:
- It implements bundle merging (private order flow + public mempool)
- It supports sealing strategies (greedy, parallelizable algorithms)
- It exposes a builder API other parties can submit bundles to
- It's the closest thing in the open-source world to a "real" production block builder
If Tempo uses or extends op-rbuilder for sequencer-mode block production, this is the codebase to study first.
6. For Tempo specifically
Predictions:
- Tempo will have a payment-aware payload builder — payments may get priority over generic txs
- A merchant authorization filter at the builder level — only authorized merchants can submit certain tx types
- A rate limiter on per-merchant tx volume to prevent abuse
- Likely no public mempool at launch (sequencer-private)
Each of those is one trait impl in a payload-builder crate.
7. Practice
Open crates/optimism/payload/ and:
- Find the
PayloadBuildertrait impl - Trace how deposit txs get included at the top of the block
- Identify where the block gas cap is enforced
- Find the function that signs/seals the built block
Then read op-rbuilder's README for the "external builder" model.
Final check: in one sentence, what does the payload builder decide that the executor does not? If your answer doesn't include the word "ordering" or "selection," go back and re-read section 3.
Summary (3 lines)
- Custom PayloadBuilder = sequencer-mode block production. Override
build_payload. - Customisations: MEV bundles, CLOB fills, system txs, priority queue. Hot path; performance matters.
- Production: op-rbuilder (OP) + Hyperliquid + Tempo sequencers. Centralised; trade-off accepted.