Rollup Boost
Rollup Boost is a lightweight sidecar for rollups that enables rollup extensions. These extensions provide an efficient, decentralized, and verifiable block building platform for rollups.
What is Rollup Boost?
Rollup Boost is a sequencer sidecar that uses the Engine API in the Optimism stack to enable its rollup extensions. Its scalable modules allow for faster confirmation times, stronger user guarantees, and more.
It requires no modification to the OP stack software and allows rollup operators to connect to an external builder.
It is designed and developed by Flashbots under a MIT license. We invite developers, rollup operators, and researchers to join in developing this open-source software to achieve efficiency and decentralization in the rollup ecosystem.
Who is this for?
Rollup Boost is designed for:
-
Rollup Operators: Teams running OP Stack or compatible rollups who want to improve efficiency, reduce confirmation times and have more control over block construction.
-
Rollup Developers: Engineers building on rollups to unlock new use cases with rollup extensions.
-
Block Builders: Teams focused on MEV who want to offer specialized block building services for rollups.
-
Researchers: Those exploring new approaches to MEV and block production strategies.
What are the design goals of Rollup Boost?
Simplicity
Rollup Boost was designed with minimal complexity, maintaining a lightweight setup that avoids additional latency.
By focusing on simplicity, Rollup Boost integrates smoothly into the OP stack without disrupting existing op-node and execution engine communication.
This way, we prioritize the reliability of the block proposal hot path over feature richness. We achieve this by striving for a stateless design and limit scope creep.
Modularity
Recognizing that rollups have varying needs, Rollup Boost was built with extensibility in mind. It is designed to support custom block-building features, allowing operators to implement modifications for custom block selection rules.
Liveness Protection
To safeguard against liveness risks, Rollup Boost offers a local block production fallback if there is a failure in the external builder.
Rollup Boost also guards against invalid blocks from the builder by validating the blocks against the local execution engine. This ensures the proposer always have a fallback path and minimizes liveness risks of the chain.
All modules in Rollup Boost are designed and tested with a fallback scenario in mind to maintain high performance and uptime.
Compatibility
Rollup Boost allows operators to continue using the standard op-node
and op-geth
/ op-reth
software without any custom forks.
It is also compatible with op-conductor
when running sequencers with a high availability setup.
It aims to be on parity with the performance of using a vanilla proposer setup without Rollup Boost.
For more details on the design philosophy and testing strategy of Rollup Boost, see this doc.
Is it secure?
Rollup Boost underwent a security audit on May 11, 2025, with Nethermind. See the full report here.
In addition to the audit, we have an extensive suite of integration and kurtosis tests in our CI to ensure the whole flow works end-to-end with the OP stack as well as with external builders.
Getting Help
- GitHub Issues: Open an issue for bugs or feature requests
- Forum: Join the forum for development updates and research discussions
Sections
Here are some useful sections to jump to:
- Run Rollup Boost with the full Op stack setup locally by following this guide.
- Read about how flashblocks work in Rollup Boost
- Query the JSON-RPC of a flashblocks enabled node Foundry's
cast
orcurl
.
Architecture
External Block Building
Much like mev-boost on Ethereum layer 1, rollup-boost is a sidecar that runs alongside the sequencer in Optimism chains to source blocks from external block builders. Unlike mev-boost, there are no code changes or extra config to support external block building in the consensus node as rollup-boost reuses the existing Engine API to source external blocks.
Instead of pointing to the local execution client, the rollup operator simply needs to point the consensus node to rollup-boost and configure rollup-boost to connect to both the local execution client and the external block builder.
To read more about the design, check out the design doc for how rollup-boost integrates into the Optimism stack.
Architecture Overview
Rollup Boost modifies the workflow of the Engine API to enable block building and flashblocks. It uses the JWT token in the Engine API as authentication for the builder and multiplexes the RPC calls to the builder to source external blocks.
Core System Workflow
rollup-boost
receives anengine_FCU
with the attributes to initiate block building:- It relays the call to proposer
op-geth
as usual and multiplexes the call to builder. - The FCU call returns the proposer payload id and internally maps the builder payload id to proposer payload id in the case the payload ids are not the same.
- It relays the call to proposer
- When
rollup-boost
receives anengine_getPayload
:- It queries proposer
op-geth
for a fallback block. - In parallel, it queries builder for a block.
- It queries proposer
- Upon receiving the builder block:
rollup-boost
validates the block with proposerop-geth
usingengine_newPayload
.- This validation ensures the block will be valid for proposer
op-geth
, preventing network stalls due to invalid blocks. - If the external block is valid, it is returned to the proposer
op-node
. Otherwise,rollup-boost
will return the fallback block.
- The proposer
op-node
sends aengine_newPayload
request torollup-boost
and anotherengine_FCU
without attributes to update chain state.rollup-boost
just relays the calls to proposerop-geth
.- Note that since we already called
engine_newPayload
on the proposerop-geth
in the previous step, the block should be cached and add minimal latency. - The builder
op-node
will receive blocks via p2p gossip and keep the builder node in sync via the engine api.
%%{init: {'theme': 'base', 'themeVariables': { 'background': '#f4f4f4', 'primaryColor': '#2c3e50', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#34495e', 'lineColor': '#34495e', 'secondaryColor': '#ecf0f1', 'tertiaryColor': '#bdc3c7'}}}%% sequenceDiagram box Proposer participant op-node participant rollup-boost participant op-geth end box Builder participant builder-op-node as op-node participant builder-op-geth as builder end Note over op-node, builder-op-geth: 1. Triggering Block Building op-node->>rollup-boost: engine_FCU (with attrs) rollup-boost->>op-geth: engine_FCU (with attrs) rollup-boost->>builder-op-geth: engine_FCU (with attrs) rollup-boost->>op-node: proposer payload id Note over op-node, builder-op-geth: 2. Get Local and Builder Blocks op-node->>rollup-boost: engine_getPayload rollup-boost->>op-geth: engine_getPayload rollup-boost->>builder-op-geth: engine_getPayload Note over op-node, builder-op-geth: 3. Validating and Returning Builder Block rollup-boost->>op-geth: engine_newPayload op-geth->>rollup-boost: block validity rollup-boost->>op-node: block payload Note over op-node, builder-op-geth: 4. Updating Chain State op-node->>rollup-boost: engine_newPayload rollup-boost->>op-geth: engine_newPayload op-node->>rollup-boost: engine_FCU (without attrs) rollup-boost->>op-geth: engine_FCU (without attrs)
RPC Calls
By default, rollup-boost
will proxy all RPC calls from the proposer op-node
to its local op-geth
node. These are the list of RPC calls that are proxied to both the proposer and the builder execution engines:
engine_forkchoiceUpdated
: this call is only multiplexed to the builder if the call contains payload attributes and the no_tx_pool attribute is false.engine_getPayload
: this is used to get the builder block.miner_*
: this allows the builder to be aware of changes in effective gas price, extra data, and DA throttling requests from the batcher.eth_sendRawTransaction*
: this forwards transactions the proposer receives to the builder for block building. This call may not come from the proposerop-node
, but directly from the rollup's rpc engine.
Boost Sync
rollup-boost
will use boost sync by default to sync directly with the proposer op-node
via the Engine API. Boost sync improves the performance of keeping the builder in sync with the tip of the chain by removing the need to receive chain updates via p2p from the builder op-node
once the builder is synced. This entails additional engine api calls that are multiplexed to the builder from rollup-boost:
engine_forkchoiceUpdated
: this call will be multiplexed to the builder regardless of whether the call contains payload attributes or not.engine_newPayload
: ensures the builder has the latest block if the local payload was used.
Reorgs
Rollup-boost remains unaffected by blockchain reorganizations due to its stateless design as a pure proxy layer between the consensus layer (op-node) and execution engines.
When reorgs impact the sequencing epoch derivation or cause drift in the L2 chain state, rollup-boost simply proxies all Engine API calls—including fork choice updates reflecting the new canonical chain and payload requests for reorg recovery—directly to both the builder and local execution client without maintaining any state about the reorganization. The actual reorg handling, including re-deriving the correct L2 blocks from the updated sequencing windows and managing any resulting drift, is performed by the underlying execution engines (e.g op-geth, op-reth) which receive these reorg signals through the standard Engine API methods that rollup-boost forwards.
Rollup Boost Modules
Flashblocks
Flashblocks is a rollup-boost module that enables fast confirmation times by breaking down block construction into smaller, incremental sections. This feature allows for pre-confirmations and improved user experience through faster block finalization.
Architecture
The Flashblocks setup consists of three main components:
- rollup-boost: The main service with Flashblocks enabled
- op-rbuilder: A builder with Flashblocks support
- op-reth: A fallback builder (standard EL node)
It utilizes WebSockets to stream Flashblocks from the builder to rollup-boost to minimize the latency between the Flashblocks and the sequencer.
Flashblocks Workflow
flowchart LR subgraph Sequencer ON[OP Node] RB[Rollup Boost] FEL[Fallback EL] BB[Block Builder] end subgraph Network WSP[WebSocket Proxy] end subgraph Clients RPC[RPC Providers] Users[End Users] end ON --> RB RB --> FEL RB <--> BB RB --> WSP WSP --> RPC RPC --> Users
- WebSocket Communication: Flashblocks utilizes WebSockets to stream Flashblocks from the builder to rollup-boost once it's constructed to minimize the latency between the Flashblocks and the sequencer.
- WebSocket Proxy: rollup-boost caches these Flashblocks and streams them to a WebSocket proxy. The proxy then fans out the Flashblocks to downstream RPC providers.
- RPC Overlay: Once RPC providers receive these Flashblocks from the proxy, clients need to run a modified node that supports serving RPC requests with the Flashblocks preconfirmation state.
- Full Block: At the end of the slot, the proposer requests a full block from rollup-boost. If rollup-boost does not have the Flashblocks cached due to a lost connection, it will fall back to the getPayload call to both the local execution client and the builder.
See the specs for the full design details for Flashblocks.
Flashtestations
Flashtestations is a rollup-boost module that provides onchain TEE (Trusted Execution Environment) attestations and block proofs to verifiably prove that blocks were built inside a TEE. This provides user guarantees such as priority ordering.
Architecture
+-------------------------+ +---------------------+
| TDX VM | | Onchain Verifier |
| | Attestation | |
| +-----------------+ | Quote | +-----------------+ |
| | TEE Workload | | ---------------> | | DCAP Attestation| |
| | | | | | Verifier | |
| | (measurements) | | | | | |
| +-----------------+ | | +--------+--------+ |
| | | | |
+-------------------------+ | v |
| +-----------------+ |
+-------------------------+ | | Intel | |
| Consumer Contract | | | Endorsements | |
| | | | | |
| +-----------------+ | | +--------+--------+ |
| | Operation | | | | |
| | Authorization | | | v |
| +-----------------+ | | +-----------------+ |
| | | | | Registration | |
+---------+---------------+ | | Logic | |
| | +--------+--------+ |
| +----------+----------+
| |
+---------+---------------+ v
| Policy | +---------------------------+
| | isValid | Flashtestation Registry |
| +---------------------+ | Query | |
| | allowedWorkloadIds[]| | <--------------> | {teeAddress: registration}|
| | {registration: | | | map |
| | workloadId} map | | | |
| +---------------------+ | +---------------------------+
+-------------------------+
Core Components
- Onchain Verifier: Validates TDX attestation quotes against current Intel endorsements. Provides cryptographic proof that a TEE-controlled address is generated within genuine TDX hardware
- Flashtestation Registry: Tracks TEE-controlled addresses with valid attestations
- Policy Registry: Defines which workloads are acceptable for specific operations
- Transparency Log: Records all attestation events and endorsement changes
Flashtestations Workflow
Flashtestations involve two main workflows:
- Registering the block builder's TEE attestation
- Block builder TEE proof
TEE Attestation Registration
- TEE Environment Setup: The builder runs in a TDX environment with specific measurement registers. These are measurements of a reproducible build for a specific builder code commit and config.
- TEE Key Generation: The builder generates a key pair on startup that never leaves the TEE environment
- Quote Generation: The TEE generates an attestation quote containing:
- Measurement registers
- Report data with TEE-controlled address and any extra registration data
- Onchain Verification: The quote is submitted onchain by the builder to the registry contract. The contract verifies that the quote is valid and the TEE address from the report data
Policy Layer
The policy layer provides authorization for TEE services. This allows operators to authorize that only builders running a specific commit and config can submit TEE block proofs.
Upon registration, a workloadId is derived from the measurements in the quote and operators can manage which workload ids are considered valid for a specific rollup.
The Policy Registry can store metadata linking workload IDs to source code:
struct WorkloadMetadata {
string commitHash; // Git commit hash of source code
string[] sourceLocators; // URIs pointing to source code (https://, git://, ipfs://)
}
Block Builder TEE Proofs
If the builder has registered successfully with an authorized workload id, builders can append a verification transaction to each block.
The block proof will be signed by the generated TEE address. Since the TEE address never leaves the TEE environment, we can ensure that block proofs signed by that key mean that the block was built inside a TEE.
The builder will submit a transaction containing a block content hash, which is computed as:
function ComputeBlockContentHash(block, transactions) {
transactionHashes = []
for each tx in transactions:
txHash = keccak256(rlp_encode(tx))
transactionHashes.append(txHash)
return keccak256(abi.encode(
block.parentHash,
block.number,
block.timestamp,
transactionHashes
))
}
Security Considerations
Critical Security Assumptions
- Private Key Management: TEE private keys must never leave the TEE boundaries
- Attestation Integrity: TEEs must not allow external control over
ReportData
field - Reproducible Builds: Workloads must be built using reproducible processes
Security Properties
- Block Authenticity: Cryptographic proof that blocks were produced by authorized TEEs with specific guarantees with the workload id
- Auditability: All proofs are recorded onchain for transparency
References
- Intel TDX Specifications
- Intel DCAP Quoting Library API
- Automata DCAP Attestation Contract
- Automata On-chain PCCS
For Rollup Operators
Running Rollup Boost in Production
Running Rollup Boost Locally
To run a local development network, you can use either Kurtosis or builder-playground to spin up the op-stack with rollup-boost.
Builder Playground
Builder playground is a tool to deploy an end-to-end block builder environment locally. It can be used to test both L1 and OP Stack block builders.
This will include deploying an OP Stack chain with:
- A complete L1 setup (CL/EL)
- A complete L2 sequencer (op-geth/op-node/op-batcher)
- Op-rbuilder as the external block builder with Flashblocks support
builder-playground cook opstack --external-builder op-rbuilder
Flags:
--enable-latest-fork
(int): Enables the latest fork (isthmus) at startup (0) or n blocks after genesis.
--flashblocks
: Enables rollup-boost with Flashblocks enabled for pre-confirmations
In this setup, there is a prefunded test account to send test transactions to:
- address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
- private key: ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
Kurtosis
Kurtosis is a tool to manage containerized services. To run rollup-boost in an op-stack devnet, first make sure you have just and kurtosis-cli installed.
This would include spinning up:
- sequencer
op-node
andop-geth
- builder
op-node
andop-rbuilder
- rollup boost
rollup-boost
- ethereum l1 devnet with l2 contracts deployed
op-proposer
andop-batcher
Then run the following command to start the devnet:
just devnet-up
To stop the devnet run:
just devnet-down
To run a stress test against the devnet with contender, first make sure you have Docker installed.
Then run the following command:
just stress-test
See the optimism package for additional configuration options.
Running Rollup Boost in Production
Regular Sequencer Setup
To run rollup-boost with a regular sequencer setup, change the --l2
flag in the proposer op-node
to point to the rollup-boost RPC endpoint.
To configure rollup-boost, set the L2 URL to the URL of the proposer auth RPC endpoint and the builder URL to the builder auth RPC endpoint. Separate JWT tokens will be needed for the two endpoints.
You can also set the options using environment variables. See .env.example
to use the default values.
cargo run --bin rollup-boost -- \
--l2-jwt-token your_jwt_token \
--l2-url http://localhost:8545 \
--builder-jwt-token your_jwt_token \
--builder-url http://localhost:8546
To set up a builder, you can use op-rbuilder
with an op-node instance and have rollup-boost point to the builder auth RPC endpoint.
Flashblocks
To launch rollup-boost with Flashblocks enabled:
cargo run --bin rollup-boost -- \
--l2-url http://localhost:5555 \
--builder-url http://localhost:4445 \
--l2-jwt-token 688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a \
--builder-jwt-token 688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a \
--rpc-port 4444 \
--flashblocks \
--log-level info
This command uses the default Flashblocks configuration. For custom configurations, see the Flashblocks Configuration section below.
Default Port Configuration
4444
: rollup-boost RPC port4445
: op-rbuilder auth RPC port (matches rollup-boost builder URL)5555
: op-reth auth RPC port (matches rollup-boost L2 URL)3030
: op-rbuilder P2P port3131
: op-reth P2P port
Flashblocks Configuration
rollup-boost provides several configuration options for Flashblocks functionality:
Basic Flashblocks Flag
--flashblocks
: Enable Flashblocks client (required)- Environment variable:
FLASHBLOCKS
- Environment variable:
WebSocket Connection Settings
-
--flashblocks-builder-url <URL>
: Flashblocks Builder WebSocket URL- Environment variable:
FLASHBLOCKS_BUILDER_URL
- Default:
ws://127.0.0.1:1111
- Environment variable:
-
--flashblocks-host <HOST>
: Flashblocks WebSocket host for outbound connections- Environment variable:
FLASHBLOCKS_HOST
- Default:
127.0.0.1
- Environment variable:
-
--flashblocks-port <PORT>
: Flashblocks WebSocket port for outbound connections- Environment variable:
FLASHBLOCKS_PORT
- Default:
1112
- Environment variable:
Connection Management
--flashblock-builder-ws-reconnect-ms <MILLISECONDS>
: Timeout duration if builder disconnects- Environment variable:
FLASHBLOCK_BUILDER_WS_RECONNECT_MS
- No default value specified
- Environment variable:
Execution mode
ExecutionMode
is a configuration setting that controls how rollup-boost
interacts with the external builder during block production. Execution mode can be set either at startup via CLI flags or dynamically modified at runtime through the Debug API.
Operators can use ExecutionMode
to selectively forward or bypass builder interactions, enabling dry runs during deployments or fully disabling external block production during emergencies.
The available execution modes are:
-
Enabled
rollup-boost
forwards all Engine API requests to both the builder and default execution client.- Optimistically selects the builder’s payload for validation and block publication.
- Falls back to the local execution client only if the builder fails to produce a payload or the payload is invalid.
- Default setting for normal external block production.
-
DryRun
rollup-boost
forwards all Engine API requests to both the builder and default execution client.- Builder payloads are validated with the local execution client but the default execution client block will always be returned to
op-node
to propagate to the network. - Useful during deployments, dry runs, or to validate builder behavior without publishing builder blocks to the network.
-
Disabled
rollup-boost
does not forward any Engine API requests to the builder.- Block construction is handled exclusively by the default execution client.
- Useful as an emergency shutoff switch in the case of critical failures/emergencies.
#![allow(unused)] fn main() { pub enum ExecutionMode { /// Forward Engine API requests to the builder, validate builder payloads and propagate to the network Enabled, /// Forward Engine API requests to the builder, validate builder payloads but /// fallback to default execution payload DryRun, // Do not forward Engine API requests to the builder Disabled, } }
Debug API
rollup-boost
exposes a Debug API that allows operators to inspect and modify the current execution mode at runtime without restarting the service. This provides flexibility to dynamically enable, disable, or dry-run external block production based on builder behavior or network conditions. The Debug API is served over HTTP using JSON RPC and consists of the following endpoints:
debug_setExecutionMode
Sets the current execution mode for rollup-boost
.
Request:
{
"method": "debug_setExecutionMode",
"params": [ "enabled" | "dry_run" | "disabled" ],
"id": 1,
"jsonrpc": "2.0"
}
Response:
{
"result": null,
"id": 1,
"jsonrpc": "2.0"
}
debug_getExecutionMode
Retrieves the current execution mode.
Request:
{
"method": "debug_getExecutionMode",
"params": [],
"id": 1,
"jsonrpc": "2.0"
}
Response:
{
"result": "enabled" | "dry_run" | "disabled",
"id": 1,
"jsonrpc": "2.0"
}
Observability
Metrics
To enable metrics, you can set the --metrics
flag. This will start a metrics server which will run on port 9090 by default. To see the list of metrics, you can check out metrics.rs and ping the metrics endpoint:
curl http://localhost:9090/metrics
All spans create duration histogram metrics with the name "{span_name}_duration". Currently, this list includes:
- fork_choice_updated_duration
- get_payload_duration
- new_payload_duration
Additionally, execution engines such as op-rbuilder have RPC metrics exposed to check if engine_getPayloadV4
requests have been received. To check if the builder blocks are landing on-chain, the builder can be configured to include a builder transaction in the block, which is captured as part of the builder metrics. To see more details about observability in the op-builder, you can check op-rbuilder's README.
Flashblocks
There are metrics and observability in all the services supporting Flashblocks. In rollup-boost:
messages_processed
- number of messages processed from the Flashblocks WebSocket streamflashblocks_counter
- number of Flashblocks proposedflashblocks_missing_counter
- number of Flashblocks missed from the expected number of Flashblocks
Additionally, the builder transaction can also be observed in the last Flashblock to determine if the number of expected Flashblocks has been included on-chain.
Tracing
Tracing is enabled by setting the --tracing
flag. This will start exporting traces to the otlp endpoint specified in the --otlp-endpoint
flag. This endpoint is set to http://localhost:4317
by default.
Traces use the payload id to track the block building lifecycle. A distributed tracing system such as Jaeger can be used to visualize when the proposer triggers block building via engine_forkchoiceUpdated
and retrieve the block with engine_getPayload
.
Troubleshooting Builder Responses
Invalid Builder Payloads
If there are logs around the builder payload being invalid, it is likely there is an issue with the builder and you will need to contact the builder operator to resolve it. In this case rollup-boost will use the local payload and chain liveness will not be affected. You can also manually set rollup-boost to dry run mode using the debug api to stop payload requests to the builder, silencing the error logs.
It is also possible that either the builder or the proposer execution engine are not running on compatible hard fork versions. Please check that the clients are running on compatible versions of the op-stack.
Builder Syncing
Alternatively, the builder may be syncing with the chain and not have a block to respond with. You can see in the logs the builder is syncing by checking whether the payload_status of builder calls is SYNCING
.
This is expected if the builder is still syncing with the chain. Chain liveness will not be affected as rollup-boost will use the local payload. Contact the builder operator if the sync status persists as the builder op-node may be offline or not peered correctly with the network.
High Availability Setup
The current OP Stack sequencer HA design relies on op-conductor
to manage a cluster of sequencers. In the rollup-boost HA setup, each sequencer connects to its own builder instance. In the event of sequencer failover, op-conductor
elects a new leader, promoting a different op-node
along with its associated rollup-boost
and builder instance.
If the builder produces undesirable but valid blocks, operators must either manually disable external block production via the rollup-boost
debug API, disable the block builder directly (causing health checks to fail), or manually select a new sequencer leader.
See the design doc for more detail on the design principles for the HA setup with rollup-boost.
Health Checks
In high availability deployments, op-conductor
must assess the full health of the block production path. Rollup Boost will expose a composite /healthz
endpoint to report on both builder synchronization and payload production status. These checks allow op-conductor
to detect degraded block building conditions and make informed leadership decisions.
Rollup Boost will continuously monitor two independent conditions to inform the health of the builder and the default execution client:
-
Builder Synchronization:
A background task periodically queries the builder’s latest unsafe block viaengine_getBlockByNumber
. The task compares the timestamp of the returned block to the local system time. If the difference exceeds a configured maximum unsafe interval (max_unsafe_interval
), the builder is considered out of sync. Failure to fetch a block from the builder or detection of an outdated block timestamp results in the health status being downgraded to Partial. If the builder is responsive and the block timestamp is within the acceptable interval, the builder is considered synchronized and healthy. Alternatively, instead of periodic polling, builder synchronization can be inferred if the builder returns aVALID
response to anewPayload
call forwarded from Rollup Boost. -
Payload Production:
During eachget_payload
request, Rollup Boost will verify payload availability from both the builder and the execution client. If the builder fails to deliver a payload, Rollup Boost will report partial health. If the execution client fails to deliver a payload, Rollup Boost will report unhealthy.
op-conductor
should also be configurable in how it interprets health status for failover decisions. This allows chain operators to define thresholds based on their risk tolerance and operational goals. For example, operators may choose to maintain leadership with a sequencer reporting 206 Partial Content
to avoid unnecessary failovers or they may configure op-conductor
to immediately fail over when any degradation is detected. This flexibility allows the chain operator to configure a failover policy that aligns with network performance expectations and builder reliability.
Condition | Health Status |
---|---|
Builder is synced and both execution client and builder return payloads | 200 OK (Healthy) |
Builder is out of sync | 206 Partial Content (Partially Healthy) |
Builder fails to return payload on get_payload request | 206 Partial Content (Partially Healthy) |
Execution client fails to return payload on get_payload request | 503 Service Unavailable (Unhealthy) |
op-conductor
should query the /healthz
endpoint exposed by Rollup Boost in addition to the existing execution client health checks. Health should be interpreted as follows:
200 OK
(Healthy): The node is fully healthy and eligible for leadership.206 Partial Content
(Partially Healthy): The node is degraded but may be considered for leadership if configured by operator503 Service Unavailable
(Unhealthy): The node is unhealthy and must be excluded from leadership.
During normal operation and leadership transfers, op-conductor
should prioritize sequencer candidates in the following order:
- Prefer nodes reporting
200 OK
. - Nodes that return
503 Service Unavailable
are treated as unhealthy and must not be eligible for sequencer leadership.op-conductor
should offer a configuration option to treat nodes returning206 Partial Content
as either healthy or unhealthy.
Rollup Boost instances that are not actively sequencing rely on the builder sync check to report health, as they are not producing blocks. This behavior mirrors the existing op-conductor
health checks for inactive sequencers and ensures readiness during failover without compromising network liveness guarantees. Note that op-conductor
will still evaluate existing sequencer health checks to determine overall sequencer health.
Note that in the case where the builder is unhealthy, rollup-boost
should bypass forwarding block production requests to the builder entirely and immediately use the default execution client for payload construction. This avoids introducing unnecessary latency while waiting for the builder response to timeout.
When builder health is restored, normal request forwarding and payload selection behavior will resume.
Failure Scenarios
Below is a high level summary of how each failure scenario is handled. All existing failure modes assumed by upstream op-conductor
are maintained:
Failure Scenario | Category | Scenario and Solution |
---|---|---|
Leader Sequencer Execution Client Fails | Sequencer Failure | op-conductor will detect an unhealthy status from both rollup-boost and pre-existing sequencer health checks, causing Conductor to elect a new leader. Once the default execution client has recovered, rollup-boost will update its health status to 200 and the sequencer will continue operating normally as a follower. |
Follower Sequencer Execution Client Fails | Sequencer Failure | Both rollup-boost and pre-existing sequencer health checks will report "unhealthy". Once the default execution client has recovered, rollup-boost will update its health status to 200 and the sequencer will continue operating normally as a follower. In the event of leadership transfer, this sequencer instance will not be considered for leadership. |
Leader rollup-boost Fails | Rollup Boost Failure | Leader sequencer rollup-boost becomes unhealthy, causing op-conductor 's sequencer health checks to fail and attempt to elect a new leader. This failure mode is the same as a typical leader sequencer failure. Once the sequencer recovers, it will continue to participate in the cluster as a follower |
Follower rollup-boost Fails | Rollup Boost Failure | Follower sequencer rollup-boost becomes unhealthy. The leader sequencer is unaffected. Once the sequencer recovers, it will continue to participate in the cluster as a follower. |
Leader Builder Stops Producing Blocks | Builder Failure | The builder associated with the sequencer leader stops producing new payloads. rollup-boost will detect the builder failure via background health checks and downgrade its health status to partial. This will result in rollup-boost ignoring the builder and selecting the default execution client's payload for block production. If op-conductor is configured to failover upon partial rollup-boost health, a new leader will attempt to be elected. Once the builder recovers and resumes payload production, rollup-boost will update its health to 200 and resume with normal operation. |
Leader Builder Falls Out of Sync | Builder Failure | The builder associated with the sequencer leader falls out of sync with the chain head. rollup-boost will detect the unsynced state via the background health checks and downgrade its health status to partial. This will result in rollup-boost ignoring builder payloads and selecting the default execution client payload for block until the builder is resynced. If op-conductor is configured to failover upon partial rollup-boost health, a new leader will attempt to be elected. Once the builder recovers, rollup-boost will update its health to 200 and resume with normal operation. |
Follower Builder Falls Out of Sync | Builder Failure | The builder associated with a follower sequencer falls out of sync with the chain head. Block production is unaffected while the node remains a follower. In the event a leader election occurs and op-conductor is configured to treat partial health as "unhealthy", this instance will not be eligible for leadership. Once the builder recovers, rollup-boost will report 200 OK and resume normal operation. |
Leader Builder Producing Bad Blocks | Builder Failure | In this scenario, the builder is "healthy" but producing bad blocks (eg. empty blocks). If the builder block passes validation via a new_payload call to the default execution client, it will be proposed to the network. Manual intervention is needed to either switch to a different sequencer or shutoff the builder. Further mitigation can be introduced via block selection policy allowing rollup-boost to select the "healthiest" block. Currently, it is unclear what block selection policy would provide the strongest guarantees. |
For DApp Developers
Flashblocks Data over JSON RPC
Reading Flashblocks Data over Ethereum JSON RPC
The Flashblocks RPC implementation provides preconfirmation data through modified Ethereum JSON-RPC endpoints using the pending
tag. This allows applications to access transaction and state information from Flashblocks before they are finalized on the blockchain.
Quick Start
To run a node capable of serving Flashblocks, run the flashblocks-rpc
crate inside the rollup-boost repository.
Build:
cargo build --release
Run:
./target/release/flashblocks-rpc \
--flashblocks.enabled=true \
--flashblocks.websocket-url=ws://localhost:8080/flashblocks \
--chain=optimism \
--http \
--http.port=8545
Supported RPC Endpoints
The following Ethereum JSON-RPC endpoints are modified to support Flashblocks data when queried with the pending
tag:
eth_getBlockByNumber
Retrieves block information including transactions from the pending Flashblock.
Request:
{
"method": "eth_getBlockByNumber",
"params": ["pending", true],
"id": 1,
"jsonrpc": "2.0"
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"hash": "0x0",
"parentHash": "0x...",
"stateRoot": "0x...",
"transactionsRoot": "0x...",
"receiptsRoot": "0x...",
"number": "0x...",
"gasUsed": "0x...",
"gasLimit": "0x...",
"timestamp": "0x...",
"extraData": "0x...",
"mixHash": "0x...",
"nonce": "0x...",
"transactions": [
{
"hash": "0x...",
"nonce": "0x...",
"blockHash": "0x0",
"blockNumber": null,
"transactionIndex": "0x0",
"from": "0x...",
"to": "0x...",
"value": "0x...",
"gas": "0x...",
"gasPrice": "0x...",
"input": "0x...",
"v": "0x...",
"r": "0x...",
"s": "0x..."
}
]
}
}
Notes:
- Returns an empty hash (
0x0
) as the block hash since the block is not yet finalized - Includes all transactions from received Flashblocks
- Implements an append-only pattern - multiple queries show expanding transaction lists
eth_getTransactionReceipt
Retrieves transaction receipt information from the pending Flashblock.
Request:
{
"method": "eth_getTransactionReceipt",
"params": ["0x..."],
"id": 1,
"jsonrpc": "2.0"
}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"transactionHash": "0x...",
"transactionIndex": "0x0",
"blockHash": "0x0",
"blockNumber": null,
"from": "0x...",
"to": "0x...",
"cumulativeGasUsed": "0x...",
"gasUsed": "0x...",
"contractAddress": null,
"logs": [],
"status": "0x1",
"logsBloom": "0x...",
"effectiveGasPrice": "0x..."
}
}
Notes:
- Returns receipt data for transactions in the pending Flashblock
blockHash
is0x0
andblockNumber
isnull
since the block is not finalized- Includes gas usage and execution status information
eth_getBalance
Retrieves account balance from the pending state.
Request:
{
"method": "eth_getBalance",
"params": ["0x...", "pending"],
"id": 1,
"jsonrpc": "2.0"
}
Response:
"0x..."
Notes:
- Returns balance reflecting all changes from preconfirmed transactions
- Uses cached state changes from Flashblocks metadata
- Falls back to standard RPC if no pending data is available
eth_getTransactionCount
Retrieves the transaction count (nonce) for an account from the pending state.
Request:
{
"method": "eth_getTransactionCount",
"params": ["0x...", "pending"],
"id": 1,
"jsonrpc": "2.0"
}
Response:
"0x..."
Notes:
- Returns nonce reflecting all preconfirmed transactions
- Combines latest confirmed nonce with pending transaction count
- Useful for determining the next valid nonce for the next Flashblock
Data Flow
The Flashblocks RPC implementation follows this data flow:
- WebSocket Connection: Establishes connection to rollup-boost Flashblocks endpoint
- Payload Reception: Receives
FlashblocksPayloadV1
messages containing transaction batches - Cache Processing: Updates in-memory cache with new transaction and state data
- RPC Queries: Responds to client requests using cached pending data
- State Management: Maintains consistency between confirmed and pending states
Flashblocks Payload Structure
Flashblocks payloads contain the following information:
pub struct FlashblocksPayloadV1 {
pub version: PayloadVersion,
pub execution_payload: OpExecutionPayloadEnvelope,
pub metadata: Metadata,
}
pub struct Metadata {
pub receipts: HashMap<String, OpReceipt>,
pub new_account_balances: HashMap<String, String>,
pub block_number: u64,
}
CLI Reference
rollup-boost
Command-line Options
--l2-jwt-token <TOKEN>
: JWT token for L2 authentication (required)--l2-jwt-path <PATH>
: Path to the L2 JWT secret file (required if--l2-jwt-token
is not provided)--l2-url <URL>
: URL of the local L2 execution engine (required)--builder-url <URL>
: URL of the builder execution engine (required)--builder-jwt-token <TOKEN>
: JWT token for builder authentication (required)--builder-jwt-path <PATH>
: Path to the builder JWT secret file (required if--builder-jwt-token
is not provided)--rpc-host <HOST>
: Host to run the server on (default: 127.0.0.1)--rpc-port <PORT>
: Port to run the server on (default: 8081)--tracing
: Enable tracing (default: false)--log-level <LEVEL>
: Log level (default: info)--log-format <FORMAT>
: Log format (default: text)--metrics
: Enable metrics (default: false)--metrics-host <METRICS_HOST>
: Host to run the metrics server on (default: 127.0.0.1)--debug-host <HOST>
: Host to run the server on (default: 127.0.0.1)--debug-server-port <PORT>
: Port to run the debug server on (default: 5555)
websocket-proxy
Command-line Options
Connection Configuration
--listen-addr <ADDRESS>
: The address and port to listen on for incoming connections (default: 0.0.0.0:8545)--upstream-ws <URI>
: WebSocket URI of the upstream server to connect to (required, can specify multiple with comma separation)
Rate Limiting
--instance-connection-limit <LIMIT>
: Maximum number of concurrently connected clients per instance (default: 100)--per-ip-connection-limit <LIMIT>
: Maximum number of concurrently connected clients per IP (default: 10)--redis-url <URL>
: Redis URL for distributed rate limiting (e.g., redis://localhost:6379). If not provided, in-memory rate limiting will be used--redis-key-prefix <PREFIX>
: Prefix for Redis keys (default: flashblocks)
Message Handling
--message-buffer-size <SIZE>
: Number of messages to buffer for lagging clients (default: 20)--enable-compression
: Enable Brotli compression on messages to downstream clients (default: false)--ip-addr-http-header <HEADER>
: Header to use to determine the client's origin IP (default: X-Forwarded-For)
Authentication
--api-keys <KEYS>
: API keys to allow in format<app1>:<apiKey1>,<app2>:<apiKey2>
. If not provided, the endpoint will be unauthenticated
Logging
--log-level <LEVEL>
: Log level (default: info)--log-format <FORMAT>
: Format for logs, can be json or text (default: text)
Metrics
--metrics
: Enable Prometheus metrics (default: true)--metrics-addr <ADDRESS>
: Address to run the metrics server on (default: 0.0.0.0:9000)--metrics-global-labels <LABELS>
: Tags to add to every metrics emitted in formatlabel1=value1,label2=value2
(default: "")--metrics-host-label
: Add the hostname as a label to all Prometheus metrics (default: false)
Upstream Connection Management
--subscriber-max-interval-ms <MS>
: Maximum backoff allowed for upstream connections in milliseconds (default: 20000)--subscriber-ping-interval-ms <MS>
: Interval in milliseconds between ping messages sent to upstream servers to detect unresponsive connections (default: 2000)--subscriber-pong-timeout-ms <MS>
: Timeout in milliseconds to wait for pong responses from upstream servers before considering the connection dead (default: 4000)
Client Health Checks
--client-ping-enabled
: Enable ping/pong client health checks (default: false)--client-ping-interval-ms <MS>
: Interval in milliseconds to send ping messages to clients (default: 15000)--client-pong-timeout-ms <MS>
: Timeout in milliseconds to wait for pong response from clients (default: 30000)
flashblocks-rpc
Command Line Options
flashblocks.enabled
: Enable Flashblocks functionality (default: false)flashblocks.websocket-url
: WebSocket URL for Flashblocks stream- Standard reth/OP Stack options for chain and RPC configuration