From 9afb2f6e14a004831297595afa7b81d1fa72d069 Mon Sep 17 00:00:00 2001 From: dmarzzz Date: Wed, 14 May 2025 14:20:32 -0400 Subject: [PATCH 01/14] add flashblock spec post community call feedback --- specs/protocol/flashblocks.md | 1029 +++++++++++++++++++++++++++++++++ 1 file changed, 1029 insertions(+) create mode 100644 specs/protocol/flashblocks.md diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md new file mode 100644 index 000000000..3ab36ab66 --- /dev/null +++ b/specs/protocol/flashblocks.md @@ -0,0 +1,1029 @@ +*Authors: [Ferran](https://github.com/ferranbt), [Shana](https://github.com/avalonche), [Dmarz](https://github.com/dmarzzz), [0xkitsune](https://github.com/0xkitsune), [Joshua](https://github.com/trianglesphere)* + +**Table of Contents** +- [Abstract](#abstract) +- [Prerequisites](#prerequisites) +- [Motivation](#motivation) +- [Specification](#specification) + - [Terminology](#terminology) + - [Parameters](#parameters) + - [Data structures](#data-structures) + - [**`FlashblocksPayloadV1`**](#flashblockspayloadv1) + - [**`ExecutionPayloadFlashblockResultV1`**](#executionpayloadflashblockresultv1) + - [**`ExecutionPayloadStaticV1`**](#executionpayloadstaticv1) + - [**`Metadata`**](#metadata) + - [**`AccountMetadata`**](#accountmetadata) + - [**`StorageSlot`**](#storageslot) + - [**`TransactionMetadata`**](#transactionmetadata) + - [System architecture](#system-architecture) + - [Out-of-Protocol Design](#out-of-protocol-design) + - [In-Protocol vs. Out-of-Protocol](#in-protocol-vs-out-of-protocol) + - [Design Rationale and Benefits](#design-rationale-and-benefits) + - [Implications for This Specification](#implications-for-this-specification) + - [Assumptions About Op Stack](#assumptions-about-op-stack) + - [Flashblock Lifecycle](#flashblock-lifecycle) + - [Flashblock Construction Process](#flashblock-construction-process) + - [Handling of Sequencer Transactions](#handling-of-sequencer-transactions) + - [Transaction Inclusion Heuristics](#transaction-inclusion-heuristics) + - [Post-block Execution Rules](#post-block-execution-rules) + - [Construction Steps](#construction-steps) + - [Flashblocks Metadata](#flashblocks-metadata) + - [Alternative Design Consideration](#alternative-design-consideration) + - [Rationale for Including State Roots in Flashblocks](#rationale-for-including-state-roots-in-flashblocks) + - [Non-Blocking Block Production](#non-blocking-block-production) + - [Builder Availability and System Reliability](#builder-availability-and-system-reliability) + - [Future Design Considerations](#future-design-considerations) + - [Builder-to-Rollup-boost Communication Flow](#builder-to-rollup-boost-communication-flow) + - [Flashblock Validity Rules](#flashblock-validity-rules) + - [Flashblock System Invariants](#flashblock-system-invariants) + - [Flashblock Propagation](#flashblock-propagation) + - [Secure propagation](#secure-propagation) + - [Flashblock JSON-RPC APIs](#flashblock-json-rpc-apis) + - [Ethereum JSON RPC Modifications](#ethereum-json-rpc-modifications) + - [op\_supportedCapabilities](#op_supportedcapabilities) +- [Reliability and Operational Considerations](#reliability-and-operational-considerations) + - [Transaction Propagation](#transaction-propagation) + - [Failover scenarios](#failover-scenarios) + - [Block Builder](#block-builder) + - [The Sequencer or Rollup-boost](#the-sequencer-or-rollup-boost) + - [Integration with High Availability Sequencer Setups](#integration-with-high-availability-sequencer-setups) + - [Faults](#faults) + - [**Safety Faults**](#safety-faults) + - [**Liveness Faults**](#liveness-faults) +- [Rationale](#rationale) + - [Why out-of-protocol](#why-out-of-protocol) + - [Why not shorter block times](#why-not-shorter-block-times) +- [Backwards Compatibility](#backwards-compatibility) + - [End Users](#end-users) + - [Infrastructure Operators](#infrastructure-operators) +- [Implementation](#implementation) + + +# Abstract + +Introduces a standard for partial blocks called “Flashblocks,” inspired but not entirely identical to [Solana Shreds](https://github.com/solana-foundation/specs/blob/main/p2p/shred.md), enabling rapid preconfirmations on Ethereum Layer 2 networks such as OP Stack. Flashblocks propagate transaction batches incrementally and expose their state via a modified Ethereum JSON-RPC interface, giving users immediate feedback equivalent to drastically reduced block times without modifying underlying the underlying OP Stack protocol. Flashblocks can be combined with Trusted Execution Environment technology to enable quick verifiability over various networks of machines in addition to protection from equivocation. + +# Prerequisites + +This document assumes knowledge of the terminology, definitions, and other material in + +- [🔗 Ethereum Optimism Protocol Specs](https://github.com/ethereum-optimism/specs/tree/main/specs/protocol) +- [🔗 OP Stack Engine API](https://specs.optimism.io/protocol/exec-engine.html#engine-api) +- [🔗 External Block Production in OP Stack Design Doc](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) +- [🔗 Ethereum Execution APIs](https://github.com/ethereum/execution-apis/tree/main) +- [🔗 Introducing Rollup-Boost - Launching on Unichain](https://writings.flashbots.net/introducing-rollup-boost) +- [🔗 Rollup-boost design doc](https://www.notion.so/RFD-1-Rollup-boost-1996b4a0d876802f95d1c98387e38162?pvs=21) + +# Motivation + +As of April 2025, Layer 2 (L2) protocols built with the OP Stack have a minimum block time of one second, imposing significant constraints on user experience. The limitation on minimum block times is primarily historical and architectural, reflecting earlier assumptions of Ethereum network as well as deeply-integrated type definitions, from the L2 blockchain client all the way down to smart contracts on the L1, making modification a very large task. + +Due to similar constraints on Ethereum Layer 1, preconfirmations have gained attention as a promising method to decouple blockchain user experiences from rigid block-time limitations and sidestep the longstanding debate between block time and block size. Existing preconfirmation solutions predominantly depend on economic security in the form of cryptoeconomic mechanisms such as staking. as well as focus on per-transaction preconfirmations, inadvertently pushing protocols into the “Latency Auction” region of the [MEV Trilemma](https://writings.flashbots.net/introducing-rollup-boost). Furthermore, previous approaches have often introduced entirely new Ethereum JSON-RPC methods, presenting substantial integration barriers and hindering practical adoption. + +Inspired by modern blockchain networks like Solana and Celestia, Flashblocks introduce an “out-of-protocol” standard for incremental delivery of partial blocks containing batches of transactions. This approach significantly reduces perceived latency for end-users and improves network bandwidth without modifying underlying protocol rules, offering a streamlined path for incremental adoption by node operators and existing infrastructure. + +# Specification + +## Terminology + +All terms, actors, and components are used in this document identically to how they are defined in the [OP Stack protocol definition](https://github.com/ethereum-optimism/specs/blob/main/specs/glossary.md). + +Additional terms introduced: + +- **External Block Builder** - External Block Builders are first introduced to the OP Stack in the [External Block Production Design Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) ****where they are described as an external party that the Sequencer can request blocks from. +- **Rollup Boost** - A sidecar piece of software first introduced without name in the [External Block Production Design Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) with two roles: + 1. obfuscate the presence of External Block Builder software from the `op-node` and `op-geth` software + 2. manage communication from the sequencer with External Block Builders and handle block delivery to `op-node` . +- **Fallback EL** - The standard Execution Layer of the Sequencer, used by Rollup Boost as a fallback mechanism when it cannot successfully build a block through the External Block Builder. This is an unmodified EL node that maintains the ability to construct valid blocks according to standard OP Stack protocol rules. +- **RPC Provider** - Ethereum RPC software operator with the purpose of serving Ethereum state. + +## Parameters + +| **Constant** | **Value** | **Description** | +| --- | --- | --- | +| `FLASHBLOCKS_TIME` | 200ms | Default wall clock time per flashblock. | +| `FLASHBLOCKS_PER_L2_BLOCK` | `L2_BLOCK_TIME`/`FLASHBLOCKS_TIME` | Supported number of flashblocks per L2 block. (Ex: 2s/200ms = 10 Flashblocks) | +| `MAX_EXTRA_DATA_BYTES` | 32 | Extra data size in an Optimism block | +| `BYTES_PER_LOGS_BLOOM` | 256 | Size of a logs bloom field in an Optimism block | + +## Data structures + +### **`FlashblocksPayloadV1`** + +The core data structure sent from the Block Builder to Rollup Boost and then external parties. A container representing a Flashblock payload, encapsulating block deltas, base configuration, and additional metadata. + +```python +class FlashblocksPayloadV1(): + version: Bytes4 + payload_id: Bytes8 + parent_flash_hash: Optional[Bytes32] + index: uint64 + static: Optional[ExecutionPayloadStaticV1] + diff: ExecutionPayloadFlashblockResultV1 + metadata: FlashblocksMetadata +``` + +**Field descriptions:** + +- `payload_id`: PayloadID is an identifier of the payload build process. The same for all flashblocks. +- `index`: Index of the Flashblock within the parent block. +- `parent_flash_hash`: SSZ hash of the parent flashblock in the sequence. For the first flashblock (index 0), the field is empty. +- `base` *(Optional)*: Reference execution payload serving as the unchanging base configuration. +- `diff`: Container with fields representing changes from the base payload. +- `metadata`: Supplementary information about the execution of the flashblock. For example: account state changes, storage modifications, transaction receipts. + +### **`ExecutionPayloadFlashblockResultV1`** + +Container encoding only the mutable portions of the execution payload updated during Flashblock construction. + +```python +class ExecutionPayloadFlashblockResultV1(): + state_root: Bytes32 + receipts_root: Bytes32 + logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] + gas_used: uint64 + block_hash: Bytes32 + transactions: List[Transaction] + withdrawals: List[Withdrawal] + withdrawals_root: Bytes32 +``` + +**Field descriptions:** + +- `state_root`: Root hash of the post-execution state trie. +- `receipts_root`: Root hash of the transaction receipts trie. +- `logs_bloom`: Bloom filter of all logs emitted by the block. +- `gas_used`: Gas consumed by included transactions. +- `block_hash`: Final hash of the completed execution block. +- `transactions`: List of transactions included in the Flashblock. +- `withdrawals`: Withdrawals included (as per Optimism specification). Must be non-nil but empty when `withdrawals_root` is used directly. +- `withdrawals_root`: OP-Stack Isthmus specific field: instead of computing the root from a withdrawals list, set it directly. The "withdrawals" list attribute must be non-nil but empty. + +**Supporting Type Definitions** + +- `Transaction`: Transaction bytes as per execution payload specification. +- `Withdrawal`: Standard Ethereum Capella withdrawal container. + +All fields in this structure represent the cumulative state of the entire block up to and including the current flashblock, not just the changes from this specific flashblock. + +### **`ExecutionPayloadStaticV1`** + +Container representing immutable fundamental block properties established at initial block creation, unchanged throughout construction. + +```python +class ExecutionPayloadStaticV1(): + parent_beacon_block_root: Bytes32 + parent_hash: Bytes32 + fee_recipient: ExecutionAddress + prev_randao: Bytes32 + block_number: uint64 + gas_limit: uint64 + timestamp: uint64 + extra_data: ByteList[MAX_EXTRA_DATA_BYTES] + base_fee_per_gas: uint256 +``` + +**Field descriptions:** + +- `parent_beacon_block_root`: Ecotone parent beacon block root. +- `parent_hash`: Hash of the parent execution block. +- `fee_recipient`: Address receiving transaction fees. +- `prev_randao`: Previous block’s RANDAO reveal for randomness. +- `block_number`: Sequential execution block number. +- `gas_limit`: Maximum allowable gas consumption for the block. +- `timestamp`: Unix timestamp at block creation. +- `extra_data`: Arbitrary extra data bytes included in the block header. +- `base_fee_per_gas`: Base fee per gas unit at the block. + +### **`Metadata`** + +Container encapsulating all metadata for a flashblock, including account state changes and transaction results. + +```python +class FlashblockMetadata(): + accounts: List[AccountMetadata] + transactions: List[TransactionMetadata] +``` + +**Field descriptions:** + +- `accounts`: List of accounts with modified state in this flashblock. +- `transactions`: List of transaction execution results in this flashblock. + +### **`AccountMetadata`** + +Container representing account state changes included in the Flashblock metadata. It is used by providers to fulfill the RPC requests. + +```python +class AccountMetadata(): + address: ExecutionAddress + balance: Optional[uint256] + nonce: uint64 + code: Optional[Bytes] + storage_slots: List[StorageSlot] +``` + +**Field descriptions:** + +- `address`: Ethereum address of the affected account. +- `balance`: Updated account balance after the Flashblock's execution (None if unchanged). +- `nonce`: Updated account nonce (transaction count) after the Flashblock's execution. +- `code_created`: Contract bytecode if created in this Flashblock. +- `storage_slots`: List of modified storage slots and their new values. + +Storage slot keys must be de-duplicated (only the final value for each key should be included) and sorted in ascending byte order for deterministic processing. + +### **`StorageSlot`** + +Container representing a single modified storage slot within an account. + +```python +class StorageSlot(): + key: Bytes32 + value: Bytes32 +``` + +**Field descriptions:** + +- `key`: Storage slot location (32-byte key). +- `value`: New value stored at this slot after the Flashblock's execution. + +### **`TransactionMetadata`** + +Container representing succinct transaction execution results. + +```python +class TransactionMetadata(): + status: uint8 + gas_used: uint64 + contract_address: Optional[ExecutionAddress] +``` + +**Field descriptions:** + +- `status`: Execution status (1 for success, 0 for failure). +- `gas_used`: Amount of gas used by this specific transaction. +- `contract_address`: Address of created contract (None for non-creation transactions). + +## System architecture + +The following diagram illustrates the Flashblocks system architecture, showing the relationships between key components: + +```mermaid + +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 +``` + +This architecture shows the flow of data through the Flashblocks system: + +1. The **OP Node** initiates block production and sends requests to **Rollup Boost** +2. **Rollup Boost** coordinates between multiple components: + - It communicates with the **Block Builder** to create Flashblocks + - It maintains a connection to the **Fallback EL** for reliability if the Block Builder fails + - It propagates validated Flashblocks to the network via the **WebSocket Proxy** +3. The **WebSocket Proxy** distributes Flashblocks to multiple **RPC Providers** +4. **RPC Providers** serve preconfirmation data to **End Users** + +The rest of this document provides detailed specifications for each component and their interactions, explaining the protocols, data structures, and operational considerations. + +## Out-of-Protocol Design + +The Flashblocks specification follows a deliberate "out-of-protocol" design philosophy. This section clarifies what we mean by this term and explains its implications for the OP Stack ecosystem. + +### In-Protocol vs. Out-of-Protocol + +In the context of OP Stack, "in-protocol" components form the core protocol itself. These components implement fundamental consensus rules, are required for basic rollup functionality, and need standardization across all participants. Modifying in-protocol components requires protocol-level changes and network-wide upgrades. + +By contrast, "out-of-protocol" components like Flashblocks operate as optional extensions to the core protocol. They can be added or removed without breaking the consensus rules of the network, though they may still impact network performance or operations if implemented poorly. + +The only in-protocol guarantee that Flashblocks must uphold is producing valid blocks at the established block time interval (typically 1-2 seconds in current OP Stack implementations). + +### Design Rationale and Benefits + +The out-of-protocol design for Flashblocks emerged from practical constraints during initial development. Without strong coordination with the OP Stack team at the outset, and given the complexity of the challenge, working within the existing protocol boundaries was the most pragmatic approach. + +This constraint ultimately proved beneficial, as it forced the design to be minimally invasive. Flashblocks can be implemented immediately on any OP Stack chain without waiting for protocol upgrades or network-wide consensus. + +Any issues with the Flashblocks implementation remain isolated from the core protocol, protecting overall network stability. In case of serious problems, Flashblocks can be disabled entirely, allowing the system to revert to normal operation without disrupting the underlying rollup. This clean fallback mechanism benefits from the centralized trust model of L2s, where the sequencer has the authority to quickly enact such operational changes without requiring network-wide consensus. + +Now that the usefulness of the system has been proven, as more collaboration venues with the OP Stack team emerge, integrating parts of Flashblocks directly into the protocol could provide even stronger guarantees and open the design space for future innovations. We are considering that approach too in the future. + +### Implications for This Specification + +Most elements defined in this document are out-of-protocol components that operate as extensions to the core OP Stack. The only hard guarantee the system must provide is that valid blocks are delivered at the expected intervals. + +Everything else—from how Flashblocks are constructed and propagated to how RPC providers implement preconfirmation caches—represents iterative improvements designed to achieve the goal of faster user feedback as efficiently and impactfully as possible. + +This means the specification describes a recommended implementation path rather than rigid protocol requirements. Components can evolve independently without requiring protocol-level coordination, and implementations may vary in how they achieve the same functional goals. + +## Assumptions About Op Stack + +The Flashblocks design makes several assumptions about OP Stack behavior: + +- **Quick Response for engine_getPayload**: We assume that `engine_getPayload` requests should return as quickly as possible for a normal and healthy chain. +- **Deterministic Payload IDs**: While not specific to Flashblocks but to Rollup Boost in general, we assume that payload IDs from different execution layer nodes are deterministically computed for the same ForkChoiceUpdate request. This is not explicitly enforced in specifications, but execution layers tend to maintain this consistency as a practical implementation detail. + +## Flashblock Lifecycle + +Note that familiarity with Rollup-boost is expected throughout this entire document, as Flashblocks is designed as an extension built on top of the existing Rollup-boost architecture. + +The lifecycle of a Flashblock begins with the Sequencer initiating block creation and ends with a normal L2 block consisting of all delivered flashblocks propagating according to the OP Stack protocol. The process proceeds as follows: + +1. **Fork Choice Update**: + + The Sequencer initiates the block-building cycle by sending an `engine_forkchoiceUpdated` with attributes call to Rollup Boost as it normally would to its local Execution Engine. + +2. **Fork Choice Update Forwarding**: + + Rollup Boost forwards the `engine_forkchoiceUpdated` call concurrently to: + + - The Sequencer’s local Execution Engine + - The External Block Builder +3. **Flashblock Construction**: + + Upon receiving the fork choice update, the External Block Builder constructs and continuously delivers `FlashblocksPayloadV1` at intervals defined by `FLASHBLOCKS_TIME` following the **Flashblocks Construction Process** defined in this document. + + It's important to emphasize that during this process, the External Block Builder sends only the incremental changes in each Flashblock, not the full block state each time. Each `FlashblocksPayloadV1` contains just the delta from the previous state (new transactions, updated state roots, etc.), allowing for efficient bandwidth usage and faster propagation. + + Only the first Flashblock (with `index` 0) includes the `static` field containing immutable block data, while subsequent Flashblocks omit this field since this information remains constant throughout the block's construction. Each Flashblock includes a `parent_flash_hash` that references the SSZ hash of the previous Flashblock in the sequence, creating a hash-linked chain within the block. + + The combined information received across all flashblocks is sufficient to fully reconstruct the complete block without any additional data. + +4. **Flashblock Validation and Propagation**: + + For each received `FlashblocksPayloadV1`, Rollup Boost validates it against the Sequencer’s local Execution Engine and according to the **Flashblocks Validity Rules** defined in this document. Upon successful validation, Rollup Boost propagates the payload to all subscribed Flashblock-compatible RPC providers. + +5. **Preconfirmed State Updates**: + + Flashblock-compatible RPC providers insert validated payloads into their local Preconfirmed State Overlay, providing immediate preconfirmation states to end-users via Flashblock-enhanced Ethereum JSON-RPC endpoints. + +6. **Final L2 Block Delivery**: + + When the Sequencer calls `engine_getPayload`, Rollup Boost returns a single coherent block payload based on the validated Flashblocks received since the last fork choice update. Note that this does not require additional external requests or any last-minute processing. + +7. **Full Block Propagation**: + + The Sequencer propagates the aggregated block following standard OP Stack protocol rules. + + +```mermaid +sequenceDiagram + participant S as Sequencer Driver (op-node) + participant RB as Rollup Boost + participant EE as Sequencer Execution Engine (op-geth) + participant BB as External Block Builder + participant RPC as Flashblock RPC Providers + participant U as End Users + + rect rgb(230,247,255) + Note over S: 1. **Fork Choice Update** + S->>RB: engine_forkchoiceUpdated + end + + rect rgb(255,242,230) + Note over RB: 2. **Fork Choice Update Forwarding** + RB->>EE: engine_forkchoiceUpdated + RB->>BB: engine_forkchoiceUpdated + end + + rect rgb(230,255,235) + loop **Flashblock Construction** (every FLASHBLOCKS_TIME) + Note over BB: **Flashblock Construction** + BB->>RB: FlashblocksPayloadV1 + + rect rgb(252,244,255) + Note over RB, EE: 4. **Flashblock Validation and Propagation** + RB->>EE: Validate Payload + EE-->>RB: Validation Result + + alt Success + RB->>RPC: Propagate Valid Payload + Note over RPC: 5. **Preconfirmed State Updates** + RPC->>RPC: Update State Overlay + RPC->>U: Serve Preconfirmed State + else Failure + RB-->>RB: Discard and fallback + end + end + end + end + + rect rgb(255,249,196) + Note over S, RB: 6. **Final L2 Block Delivery** + S->>RB: engine_getPayload + RB->>S: Aggregate Payload + end + + rect rgb(240,240,240) + Note over S: 7. **Full Block Propagation** + S->>S: Propagate Block (standard OP Stack) + end +``` + +## Flashblock Construction Process + +The External Block Builder initiates the construction of Flashblocks upon receiving a fork choice update (`engine_forkchoiceUpdated`) call forwarded by Rollup Boost. The construction of Flashblocks follows a defined sequence of steps repeated every `FLASHBLOCKS_TIME` interval, ensuring consistent, incremental, and ordered propagation of preconfirmed state to end-users. It's important to note that `FLASHBLOCKS_TIME` serves as a target interval rather than a strictly enforced rule in Rollup Boost. + +### Handling of Sequencer Transactions + +An important protocol rule that the Flashblock construction process must adhere to involves handling "system transactions" within the OP Stack. These include deposits and system transactions that arrive with the Fork Choice Update (FCU) and must always be executed as the first transactions in any valid block. + +From an "in-protocol" perspective, a block is not considered valid if these sequencer transactions are missing. Consequently, the minimum valid block that can be constructed must include the execution of these transactions. + +The External Block Builder follows this mandate by executing these sequencer transactions first and including them in the initial Flashblock (index 0). This serves as the foundation upon which all subsequent Flashblocks in the sequence will build. + +When processing these mandatory sequencer transactions, the builder does not apply the same gas allocation heuristics used for regular transactions in later Flashblocks. While these transactions do consume gas like any other transaction, they receive special handling as they must be included regardless of gas considerations to maintain protocol validity. + +### Transaction Inclusion Heuristics + +As part of the flashblock construction process, the External Block Builder makes sophisticated decisions about transaction inclusion. Unlike rigid gas limit enforcement, the decision of when to stop including transactions in a flashblock involves nuanced heuristics that may evolve over time. + +The builder must balance multiple factors when deciding which transactions to include in each flashblock: + +- Optimizing for user experience by providing quick feedback +- Ensuring transactions with higher gas usage aren't permanently excluded +- Maintaining efficient gas utilization across the entire block +- Accounting for execution time constraints within the `FLASHBLOCKS_TIME` window + +In some cases, the builder might include a transaction that exceeds what would be a strict per-flashblock gas limit because executing that transaction is important for user experience or economic reasons. This flexibility is a key advantage of the out-of-protocol approach. + +The specific heuristics for transaction allocation across flashblocks are intentionally not prescribed in this specification. Rather than codifying particular strategies, we leave this as an area where builders can innovate and optimize. Different chains can develop custom heuristics based on their specific transaction patterns, user expectations, and economic models. As implementations mature, we expect some general principles will emerge for handling common scenarios, but this specification intentionally avoids prematurely constraining this design space. + +### Post-block Execution Rules + +In the OP Stack protocol, certain operations such as withdrawals and system requests are applied at the end of block execution. Since each flashblock must function as a valid standalone block for preconfirmation purposes, these post-block execution rules must be applied at the end of each flashblock's construction. + +When constructing a flashblock, the builder applies all required post-block operations after executing the selected transactions. These operations modify the state according to protocol rules, ensuring the flashblock represents a complete and valid block state. + +However, an important implementation detail is that these post-block changes must be reverted before beginning execution for the next flashblock. This reversion is necessary because the post-block operations should only be applied once per actual L2 block, not cumulatively for each flashblock. Failing to revert these changes would lead to their repeated application across multiple flashblocks, potentially creating invalid cumulative state and ultimately an invalid final block. + +### Construction Steps + +After handling the mandatory sequencer transactions in the initial Flashblock, the External Block Builder proceeds with constructing subsequent Flashblocks by following these steps for each interval: + +1. **Transaction Selection** + +- Retrieve transactions from local or external mempool: +- Prioritize and sort transactions based on predefined sequencing policies, such as priority ordering or by MEV paid. + +2. **Transaction Execution** + +- Sequentially execute selected transactions against a state snapshot derived from the current execution payload base (ExecutionPayloadBaseV1) or the last validated flashblock +- Apply the transaction inclusion heuristics described earlier to determine when to stop including transactions +- After transaction execution completes, apply all post-block execution rules as described in the Post-Block Execution Rules section + +3. **Flashblock Payload Assembly** + +- After transaction execution, compute and record the following execution state updates: + - `state_root`: The new post-execution state root resulting from the executed transactions. + - `receipts_root`: The receipts trie root derived from execution outcomes. + - `logs_bloom`: Aggregated logs bloom from all emitted transaction logs within this flashblock. + - `gas_used`: Total gas consumed by executed transactions. + - `transactions`: Serialized transaction payloads included within the flashblock. + - `withdrawals` (if applicable): Withdrawals executed during the current flashblock interval (as per OP Stack withdrawal specification). + - `block_hash`: Computed block hash uniquely identifying this flashblock execution state. + + Note that each flashblock builds upon the state of all previous flashblocks, with these fields reflecting the cumulative state after applying the new transactions in this particular flashblock. + +- Encapsulate these computed updates into `ExecutionPayloadFlashblockResultV1`. + +5. **Flashblock Indexing and Metadata** + +- Assign a monotonically incremented `index` to the newly constructed Flashblock payload. +- Compute the SSZ hash of the previous Flashblock and assign it as the `parent_flash_hash` (for the first Flashblock with index 0, this field is empty) + +6. **Flashblock Delivery** + +- Package the `index`, `payload_id`, `ExecutionPayloadFlashblockDeltaV1`, and metadata into a `FlashblocksPayloadV1` payload. +- Deliver the assembled `FlashblocksPayloadV1` payload promptly to Rollup Boost via the designated Flashblocks submission API. + +7. **Subsequent Flashblock Construction** + +- Immediately after successful delivery, increment the Flashblock `index`. +- Revert any post-block execution changes as described in the Post-Block Execution Rules section +- Reset the transaction execution context based on the newly delivered state. +- Begin constructing the next `FlashblocksPayloadV1` payload, repeating from step 1 until a termination condition is reached (e.g., end of block building period via `engine_getPayload` request). + +8. **Flashblock Construction Termination** + +- Flashblock construction continues iteratively until: + - Rollup Boost signals final block aggregation and propagation via engine_getPayload. + - A failure or timeout condition arises requiring failover procedures, detailed separately. + +```mermaid +sequenceDiagram + participant BB as External Block Builder + participant RB as Rollup Boost + participant EE as Execution Engine (local) + participant M as Mempool + + loop Every FLASHBLOCKS_TIME + BB->>M: Retrieve and Prioritize Transactions + M-->>BB: Transactions batch + Note over BB: Execute transactions sequentially + BB->>EE: Execute transactions and compute state root + EE-->>BB: Execution results (state root, receipts, gas used) + + Note over BB: Construct Flashblock Delta + BB->>BB: Assemble FlashblocksPayloadV1 (state_root, receipts_root, logs_bloom, gas_used, block_hash, txs, withdrawals, metadata) + + BB->>RB: Submit FlashblocksPayloadV1 + RB-->>BB: Acknowledge reception (async) + Note over BB: Increment index, prepare next Flashblock + end +``` + +## Flashblocks Metadata + +The `FlashblocksPayloadV1` structure defined above contains the minimum required data for Rollup Boost to return a valid block. The `metadata` field provides additional information to enable preconfirmations. + +This metadata contains supplementary information about the execution state that is not strictly necessary for block construction but is valuable for RPC providers to offer comprehensive preconfirmation services. Examples of such metadata include: + +- Account state changes (which accounts have been modified) +- Updated account balances +- Storage slot modifications +- Contract deployment information +- Detailed transaction execution results + +### Alternative Design Consideration + +While this specification includes detailed metadata in Flashblocks, a viable alternative would be for RPC providers to execute transactions themselves as they receive them through the stream. In this approach, providers would receive only transaction data, execute them in order, maintain their own state cache, and use it to fulfill RPC requests. This would significantly reduce bandwidth requirements by eliminating metadata transmission. + +## Rationale for Including State Roots in Flashblocks + +One of the most discussed aspects of the Flashblocks design is the decision to include state roots with every flashblock. This section explains the rationale behind this design choice. + +### Non-Blocking Block Production + +We operate under the assumption that `engine_getPayload` requests should return quickly with a valid, complete block. This assumption, which we believe to be correct based on our understanding of the OP Stack, guides our design decisions. + +Currently in OP Stack implementations, execution layer nodes compute payloads in the background and can return them immediately when requested via `engine_getPayload`. This allows for near-instant responses, maintaining the flow of block production without delays. For Flashblocks to provide similar performance, it must have all block components - including state roots - readily available when `engine_getPayload` is called. + +Without pre-computed state roots for each flashblock, Rollup Boost would face a critical decision when handling `engine_getPayload`: + +1. **Request the state root from the Execution Layer**: This approach would be problematic because the Execution Layer does not maintain a "hot" state that matches the current flashblock sequence. It would need to apply all pending transactions and compute a new state root, which is exactly the operation we're trying to optimize with flashblocks. +2. **Request the state root from the External Block Builder**: This would require an additional synchronous request to the builder with a protocol which is not engine-specific. Not only does this introduce an extra communication hop and latency, but it also creates a single point of failure - if the builder is unavailable at that moment, Rollup Boost cannot fulfill the request and we fall into the failure path rather than the happy path. + +### Builder Availability and System Reliability + +The key advantage of including state roots with each flashblock is system reliability. By having state roots immediately available, Rollup Boost can respond to `engine_getPayload` requests without additional external dependencies at that critical moment. + +Without pre-included state roots, a builder failure at the moment of block production would force the system to either: + +1. Recompute the entire state from scratch (time-consuming and potentially disruptive) +2. Fail to produce a block on time (violating protocol assumptions) +3. Be unable to fulfill the preconfirmations that have already been exposed to users + +### Future Design Considerations + +This approach represents our current understanding of the optimal design given existing constraints. However, as mentioned in the Out-of-Protocol Design section, alternative approaches may be worth exploring as we gain production experience. Future iterations might consider different state root handling approaches, particularly in the context of high-availability sequencer setups and deeper integration with OP Stack components. + +## Builder-to-Rollup-boost Communication Flow + +Rollup Boost maintains an open WebSocket connection with the External Block Builder. Through this persistent connection, the builder pushes the `FlashblocksPayloadV1` payloads as soon as they're constructed, without waiting for requests from Rollup Boost. + +If the WebSocket connection goes down, the builder buffers (queues) the messages internally and attempts to resend them once the connection is restored. This buffering only applies for the current block being built; when a new block cycle begins, any queued messages from the previous block are discarded as they are no longer relevant to the current state. + +**SSZ Encoding for Flashblocks Messages** + +Flashblocks messages transmitted between the Block Builder and Rollup Boost use Simple Serialize (SSZ) for binary encoding. Unlike JSON or other self-describing formats, SSZ is schema-less and does not embed field names or type information in the serialized data. This makes explicit versioning necessary, especially in a streaming context where message types cannot be inferred from surrounding context. + +For the `FlashblocksPayloadV1` structure, a version field is placed as the first field in the container. + +This design leverages SSZ's deterministic encoding characteristics, where fixed-size fields like `Bytes4` appear at predictable offsets in the serialized data. When a recipient receives a serialized Flashblocks message over the WebSocket stream: + +1. It first reads the initial 4 bytes to determine the message version +2. Based on the version identifier, it selects the appropriate container structure for deserializing the remainder of the data + +## Flashblock Validity Rules + +For a flashblock to be considered valid the following must hold: + +- **Monotonically Increasing Payload Index:** Each successive Flashblock payload delivered within the same L2 block cycle must have an index exactly one greater than the previous payload. Any skipped indices or duplicated indices constitute a violation. When a violation occurs, Rollup Boost will ignore the invalid flashblock and maintain its internal state, only updating when it receives a new flashblock with the correct next index value. +- **Immutable Payload Base:** Immutable block header fields (`parent_hash`, `block_number`, `prev_randao`, etc.) set by the initial `ExecutionPayloadBaseV1` cannot be altered by subsequent Flashblocks during the same L2 block period. +- **Execution Validity:** Every Flashblock must be validated successfully against the Sequencer’s local execution engine state to ensure OP protocol-level correctness. +- **Valid Full Block:** Every flashblock, when combined with prior flashblocks, should be a valid L2 Block without requiring Rollup Boost to perform any additional operations other than repackaging the data structure. This means that state roots are calculated on each Flashblock contrary to publication due to the out-of-protocol nature of the implementation. + + A flashblock is considered a valid block if: + + - It includes the first flashblock (with index 0 containing the base data) + - It comprises a continuous sequence of flashblocks with incrementing indices. + +## Flashblock System Invariants + +The following invariants must hold true for the Flashblocks protocol to function reliably: + +- **No Equivocation:** At no point should multiple distinct Flashblocks for the same payload index be delivered or propagated to RPC subscribers. +- **Preconfirmation Preservation:** The system always gives strong preference to maintaining the integrity of issued preconfirmations. Once a transaction has been included in a flashblock and made visible to users as preconfirmed, the system will prioritize preserving this state over other considerations such as block value optimization or alternative builder selection. + +## Flashblock Propagation + +Once Rollup Boost has validated a flashblock, it is then propagated to the rest of the network to be included in each RPC Provider’s Preconfirmation Cache. + +```mermaid +sequenceDiagram + participant B as Block Builder + participant R as Rollup-boost + box Node + participant RPC as JSON-RPC Interface + end + participant U as Users + + B->>R: Preconfirmation batches + R->>R: Validate batches + R->>RPC: Preconfirmation updates + U->>RPC: Standard RPC queries + note right of U: Regular users +``` + +Flashblocks Compatible RPC Providers subscribe to the Flashblocks websocket stream from Rollup Boost and maintain an in-memory representation of the preconfirmation state. RPC providers validate that the flashblock sequence is correct before updating their preconfirmation state. This preconfirmation state is ephemeral, maintained only until the corresponding block is propagated and the information becomes available through standard chain state. + +Throughout the entire propagation path, flashblocks are transmitted in binary SSZ-encoded format. + +### Secure propagation + +Since the preconfirmation data originates directly from the Sequencer's Rollup Boost instance, exposing this WebSocket endpoint directly to external parties presents security and scalability concerns. Instead, a reverse proxy should be implemented between Rollup Boost and external RPC providers to relay this information securely. + +This mirror simply relays WebSocket data without requiring any Flashblocks-specific knowledge, acting purely as a transport layer that forwards WebSocket messages from Rollup Boost to subscribed RPC providers. You can find an example implementation [here](https://github.com/base/flashblocks-websocket-proxy). + +```mermaid +flowchart TD + subgraph Sequencer + BB[Block Builder] + RB[Rollup Boost] + Mirror[Flashblocks Mirror] + end + + subgraph RPC Providers + RPC1[RPC Provider 1] + RPC2[RPC Provider 2] + RPC3[RPC Provider 3] + RPCN[RPC Provider N] + end + + BB -->|Flashblocks| RB + RB -->|Flashblocks| Mirror + Mirror -->|Flashblocks| RPC1 + Mirror -->|Flashblocks| RPC2 + Mirror -->|Flashblocks| RPC3 + Mirror -->|Flashblocks| RPCN +``` + +## Flashblock JSON-RPC APIs + +### Ethereum JSON RPC Modifications + +All modifications done to the existing Ethereum JSON RPC methods are confined to overloading the existing `pending` tag. Originally, this tag was designed to return block data being processed by the node's internal miner. It's fitting that we now use it for a similar purpose: exposing blocks in their preconfirmation stage. When queried with the `pending` tag, the endpoint uses the preconfirmation cache state to construct the response. The response might include not only transactions but also block metadata like state root and receipt root. + +The tag is currently in a soft-deprecated state due to inconsistent implementations across clients, particularly after The Merge. However, it's worth noting that it's still actively used for certain endpoints, particularly `eth_getTransactionCount` where it serves the important function of returning the next available nonce for an account (including transactions in the mempool). This presents an opportunity: the tag is well-defined enough to be supported by client libraries, yet loosely defined enough to allow for our preconfirmation use case. While there's a possibility of the tag being removed in the future (see [EIP discussions](https://github.com/ethereum/execution-apis/issues/495)), the design could adapt by introducing a flashblocks-specific tag if needed. + +We repurpose the `pending` tag in the following RPC calls to enable consuming preconfirmed state: + +- eth_getTransactionReceipt +- eth_getBlockByHash +- eth_getBalance +- eth_call +- eth_getCode +- eth_getTransactionCount +- eth_getStorageAt + +### op_supportedCapabilities + +This endpoint allows clients to discover whether the RPC provider supports certain features, including Flashblocks. + +**Request** + +```json +{ + "method": "op_supportedCapabilities", + "params": [], + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +{ + "id": 1, + "jsonrpc": "2.0", + "result": ["flashblocksv1"] +} +``` + +When this method is called on a Flashblocks-compatible RPC provider, the response includes "flashblocksv1" in the returned array of supported capabilities. This allows clients to programmatically determine whether they can utilize Flashblocks functionality before making related requests. + +This endpoint follows a similar pattern to the Engine API's `engine_exchangeCapabilities` method, which allows consensus and execution clients to exchange information about supported features. + +This is the only new RPC endpoint introduced by the Flashblocks specification. We consider this addition acceptable because it provides necessary feature discovery while keeping the name abstract enough to accommodate future extensions to the protocol or for other protocols. + +**`eth_getTransactionReceipt`** + +**Request** + +```json +{ + "method": "eth_getTransactionReceipt", + "params": ["0x..."],// Transaction hash + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +{ + "transactionHash": "0x...", + "blockHash": "0x0", // Empty hash as placeholder + "blockNumber": "0x...", // Current pending block number + "transactionIndex": "0x0", + "from": "0x...", + "to": "0x...", + "gasUsed": "0x...", + "status": "0x1", + "cumulativeGasUsed": "0x...", + "effectiveGasPrice": "0x...", + "contractAddress": "0x...", // For contract creations + "logs": [], + "logsBloom": "0x..." +} +``` + +When queried, this endpoint first checks the preconfirmation cache for the requested transaction hash before falling back to the standard chain state lookup. + +Some fields in the response cannot be final at the preconfirmation stage and require placeholder values: + +- `blockHash`: Uses empty hash as placeholder +- `blockNumber`: Can be set to the current block number being processed + +**`eth_getBlockByHash`** + +**Request** + +```json +{ + "method": "eth_getBlockByHash", + "params": ["pending", false], // Second parameter indicates full transaction objects (true) or only hashes (false) + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +{ + "hash": "0x0", // Empty hash as placeholder + "parentHash": "0x...", + "stateRoot": "0x...", + "transactionsRoot": "0x...", + "receiptsRoot": "0x...", + "number": "0x...", // Current pending block number + "gasUsed": "0x...", + "gasLimit": "0x...", + "timestamp": "0x...", + "extraData": "0x...", + "mixHash": "0x...", + "nonce": "0x...", // // Used to signal flashblock index + "transactions": [] // Array of transaction hashes or full transaction objects +} +``` + +The endpoint implements an append-only pattern - multiple queries during the same block's preconfirmation phase will show an expanding list of transactions as new flashblocks are processed. Each query reflects the current state of all preconfirmed transactions at that moment. + +```mermaid +sequenceDiagram + participant U as User + participant RPC + participant R as Rollup-boost + + Note over R: Block building starts + R->>RPC: Batch 1 (txs: A, B) + + U->>RPC: Query 1 + RPC-->>U: Block with txs: A, B + + R->>RPC: Batch 2 (txs: C, D) + U->>RPC: Query 2 + RPC-->>U: Block with txs: A, B, C, D + + R->>RPC: Batch 3 (txs: E) + U->>RPC: Query 3 + RPC-->>U: Block with txs: A, B, C, D, E + + R->>RPC: Batch 4 (txs: F, G) + U->>RPC: Query 4 + RPC-->>U: Block with txs: A, B, C, D, E, F, G + + Note over R: Block sealed +``` + +**`eth_getBalance`** + +**Request** + +```json +{ + "method": "eth_getBalance", + "params": ["0x...", "pending"], // Account address and block parameter + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +"0x..." // Balance in wei +``` + +When queried with the "pending" tag, the endpoint uses the preconfirmation cache state to return the account balance. If the requested account appears in the `AccountMetadata` of a received Flashblock with a non-null `balance` field, the RPC provider can directly return this value without needing to access the full state. The response reflects all changes from preconfirmed transactions that affect the requested account's balance. + +**`eth_call`** + +**Request** + +```json +{ + "method": "eth_call", + "params": [{"to": "0x...", "data": "0x..."}, "pending"], // Transaction call object and block parameter + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +"0x..." // Return data from the call +``` + +When queried with the "pending" tag, the endpoint uses the preconfirmation cache state to return the call result. For this endpoint to work, the preconfirmation stream needs to include state differences for both accounts and storage after each flashblock. + +Similar to the current override functionality in `eth_call` where EVM transitions are executed on top of modified state, this implementation executes the call on top of the preconfirmation state changes. + +**`eth_getCode`** + +**Request** + +```json +{ + "method": "eth_getCode", + "params": ["0x...", "pending"],// Contract address and block parameter + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +"0x..."// Contract bytecode +``` + +When queried with the "pending" tag, the endpoint returns the contract bytecode from the preconfirmation cache state. If the requested account appears in the `AccountMetadata` of a received Flashblock with a non-null `code` field, the RPC provider can directly return this value without accessing the full state. + +**`eth_getTransactionCount`** + +**Request** + +```json +{ + "method": "eth_getTransactionCount", + "params": ["0x...", "pending"],// Account address and block parameter + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +"0x..."// Nonce value as a hex string +``` + +When queried with the "pending" tag, the endpoint returns the transaction count (nonce) of the account from the preconfirmation cache. If the requested account appears in the `AccountMetadata` of a received Flashblock, the RPC provider can directly use the `nonce` field without additional state access. + +**`eth_getStorageAt`** + +**Request** + +```json +{ + "method": "eth_getStorageAt", + "params": ["0x...", "0x...", "pending"],// Contract address, storage position, and block parameter + "id": 1, + "jsonrpc": "2.0" +} +``` + +**Response** + +```json +"0x..." // Storage value as a hex string +``` + +When queried with the "pending" tag, the endpoint returns the value from the specified storage slot using the preconfirmation cache state. If the requested account appears in the `AccountMetadata` of a received Flashblock, the RPC provider scans the `storage_slots` list for the requested key and returns the corresponding value directly. + +# Reliability and Operational Considerations + +## Transaction Propagation + +Similar to the design laid out in the [External Block Production](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) design document, Flashblocks makes no assumptions about how transactions are delivered to the block builder. A non-exhaustive list of valid approaches: + +- transaction forwarding via mutliplex’ing software at the Rollup Operator’s RPC +- Private p2p connections between Sequencer transaction ingress nodes and block building nodes + +## Failover scenarios + +### Block Builder + +As per the normal Rollup-boost behavior, if the builder is down, the Rollup-boost picks up the block from the fallback builder. However, since we are dealing with preconfirmations, we must consider the relative value of preserving preconfirmations versus building a potentially more valuable block. + +In this design document, we follow the invariant that preserving preconfirmations takes precedence. If the block builder goes down after the first flashblocks have been delivered, we still return those flashblocks to maintain the integrity of any preconfirmations already issued to users. The next block would work as expected through the normal fallback mechanism, as the builder is down and the fallback builder would be used. + +We could technically discard the partial flashblocks and use the fallback block entirely, but this would violate the preconfirmations commitment. Our design assumes normal execution conditions. If losing the builder mid-flashblock becomes a common occurrence, this would indicate fundamental architectural issues that require separate improvements beyond the scope of this failover mechanism. + +### The Sequencer or Rollup-boost + +These failure scenarios are addressed as part of the High Availability (HA) sequencer setups. The HA architecture ensures continuity of operations by automatically failing over to standby instances when failures occur. + +## Integration with High Availability Sequencer Setups + +The integration of Flashblocks with High Availability (HA) Sequencer setups is outside the scope of this initial specification document. For details on managing Flashblock state across multiple sequencer instances and maintaining preconfirmation integrity during failovers, please refer to the resources linked below. + +- what do with a rotating set of sequencers like with OP conductor https://github.com/ethereum-optimism/optimism/tree/develop/op-conductor +- World HA design discussion https://github.com/flashbots/rollup-boost/issues/181 +- Base Technical Design Document [TDD: Rollup Boost Integration with HA Sequencer](https://www.notion.so/TDD-Rollup-Boost-Integration-with-HA-Sequencer-1d0c9d820ca380348f21e44a5442feaf?pvs=21) + +## Faults + +### **Safety Faults** + +In the rollup security vocabulary *safety* implies that “**no one can create or withdraw assets they are not entitled to.**” A **safety fault** therefore occurs the moment an **invalid L2 state root** is accepted on Ethereum **and** at least one L2→L1 action (withdrawal, message relay, etc.) that depends on that root is executed **and** the dispute game period has ended. After that point the canonical record on Ethereum says the invalid state is *final* and the rollup’s honesty assumption is broken. + +The safety of a flashblock is directly equivalent to the safety of an L2 block. Additionally, on each submission of a flashblock to Rollup Boost, it is simulated against the Sequencer’s local execution engine, ensuring the Block Builder’s view is equivalent to the Sequencer’s. + +The real thing we are interested in regards to safety faults for the Flashblock stream is whether they can be reorged. The answer to this question is that the preconfirmed state can be reorged out if the Sequencer reorgs. Given that the sequencer is the one validating the block builder blocks, then there is no additional risk of reorg from the introduction of the External Block Builder and Flashblocks stream, as in both cases, the reorg is due to Sequencer Operator error. + +### **Liveness Faults** + +In the rollup vocabulary *Liveness implies that “*every honest user can (a) get a transaction included within a bounded time and (b) complete a withdrawal within the 7‑day challenge window.” A **liveness fault** is any condition that makes either promise untrue *without violating safety* (no invalid state is accepted). + +The liveness of a flashblock is therefore directly equivalent to the liveness of L2 blocks as user’s are able to force include via the L1 as normal. + +# Rationale + +### Why out-of-protocol + +The design is implemented as an out-of-protocol solution rather than a core protocol modification to allow for faster iteration and development. This approach respects the stability guarantees of the OP Stack while allowing participants to adopt the features at their own pace. + +We do not, however, discard the possibility of enshrining these features inside the OP Stack protocol as both teams become more comfortable working together and more familiar with the specification. This out-of-protocol approach serves as a proving ground that can inform a potential future core integration. + +### Why not shorter block times + +While reducing block times is a potential solution, it would require non-trivial changes to the OP Stack codebase, where the current minimum timestamp used is 1 second. Additionally, extremely short block times (sub-200ms) might introduce significant performance issues in other blockchain infrastructure like block explorers and indexers. + +Flashblocks provide a more balanced approach: they maintain reasonable block times for network decentralization and stability, while offering a fast-lane feedback mechanism for users who need immediate transaction status. + +This approach also opens the door to an interesting possibility: chains could potentially implement longer block times (tens of seconds) while still maintaining quick preconfirmations via Flashblocks. This combination might enable new and interesting use cases that benefit from both paradigms. + +# Backwards Compatibility + +## End Users + +At present, consuming Flashblocks data is completely opt-in through the use of the `pending` tag, therefore once turned on, no applications will require changes to how they consume data from their RPC. Instead an additional opt-in flow is enabled. + +## Infrastructure Operators + +For Sequencer Operators, Flashblocks and Rollup Boost can be enabled and disabled with no additional harm to the system. + +For RPC Operators, Flashblocks will require a modified RPC node that subscribes to the Flashblock stream in addition to maintaining a Preconfirmation cache and responding with the relevant data on request with the `pending` tag. + +# Implementation + +A feature complete implementation of all components described in this document can be found in the [rollup-boost](https://github.com/flashbots/rollup-boost), [op-rbuilder](https://github.com/flashbots/rbuilder/tree/develop/crates/op-rbuilder), [flashblocks-websocket-proxy](https://github.com/base/flashblocks-websocket-proxy), and [reth-flashblocks](https://github.com/danyalprout/reth-flashblocks). \ No newline at end of file From 637f46127438e08a0df3d2049b3f9405eba5135e Mon Sep 17 00:00:00 2001 From: dmarzzz Date: Thu, 15 May 2025 16:43:13 -0400 Subject: [PATCH 02/14] update authors --- specs/protocol/flashblocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 3ab36ab66..5e91499aa 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -1,4 +1,4 @@ -*Authors: [Ferran](https://github.com/ferranbt), [Shana](https://github.com/avalonche), [Dmarz](https://github.com/dmarzzz), [0xkitsune](https://github.com/0xkitsune), [Joshua](https://github.com/trianglesphere)* +*Authors: [Ferran](https://github.com/ferranbt), [Dmarz](https://github.com/dmarzzz), [Shana](https://github.com/avalonche), [0xkitsune](https://github.com/0xkitsune), [protolambda](https://github.com/protolambda), [Anton](https://github.com/0x416e746f6e), [Joshua](https://github.com/trianglesphere)* **Table of Contents** - [Abstract](#abstract) From f82df7a4174f1b74b8fa5030a243ce47509dc2b5 Mon Sep 17 00:00:00 2001 From: dmarz Date: Sun, 24 Aug 2025 11:17:16 -0400 Subject: [PATCH 03/14] Apply suggestions from code review Co-authored-by: Ethnical --- specs/protocol/flashblocks.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 5e91499aa..e61d61b1a 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -78,7 +78,7 @@ This document assumes knowledge of the terminology, definitions, and other mater As of April 2025, Layer 2 (L2) protocols built with the OP Stack have a minimum block time of one second, imposing significant constraints on user experience. The limitation on minimum block times is primarily historical and architectural, reflecting earlier assumptions of Ethereum network as well as deeply-integrated type definitions, from the L2 blockchain client all the way down to smart contracts on the L1, making modification a very large task. -Due to similar constraints on Ethereum Layer 1, preconfirmations have gained attention as a promising method to decouple blockchain user experiences from rigid block-time limitations and sidestep the longstanding debate between block time and block size. Existing preconfirmation solutions predominantly depend on economic security in the form of cryptoeconomic mechanisms such as staking. as well as focus on per-transaction preconfirmations, inadvertently pushing protocols into the “Latency Auction” region of the [MEV Trilemma](https://writings.flashbots.net/introducing-rollup-boost). Furthermore, previous approaches have often introduced entirely new Ethereum JSON-RPC methods, presenting substantial integration barriers and hindering practical adoption. +Due to similar constraints on Ethereum Layer 1, preconfirmations have gained attention as a promising method to decouple blockchain user experiences from rigid block-time limitations and sidestep the longstanding debate between block time and block size. Existing preconfirmation solutions predominantly depend on economic security in the form of cryptoeconomic mechanisms such as staking. As well as focus on per-transaction preconfirmations, inadvertently pushing protocols into the “Latency Auction” region of the [MEV Trilemma](https://writings.flashbots.net/introducing-rollup-boost). Furthermore, previous approaches have often introduced entirely new Ethereum JSON-RPC methods, presenting substantial integration barriers and hindering practical adoption. Inspired by modern blockchain networks like Solana and Celestia, Flashblocks introduce an “out-of-protocol” standard for incremental delivery of partial blocks containing batches of transactions. This approach significantly reduces perceived latency for end-users and improves network bandwidth without modifying underlying protocol rules, offering a streamlined path for incremental adoption by node operators and existing infrastructure. @@ -114,14 +114,13 @@ The core data structure sent from the Block Builder to Rollup Boost and then ext ```python class FlashblocksPayloadV1(): - version: Bytes4 + version: Bytes4 payload_id: Bytes8 parent_flash_hash: Optional[Bytes32] index: uint64 static: Optional[ExecutionPayloadStaticV1] diff: ExecutionPayloadFlashblockResultV1 metadata: FlashblocksMetadata -``` **Field descriptions:** @@ -201,9 +200,8 @@ Container encapsulating all metadata for a flashblock, including account state c ```python class FlashblockMetadata(): - accounts: List[AccountMetadata] - transactions: List[TransactionMetadata] -``` + accounts: List[AccountMetadata] + transactions: List[TransactionMetadata] **Field descriptions:** @@ -410,7 +408,7 @@ sequenceDiagram rect rgb(230,255,235) loop **Flashblock Construction** (every FLASHBLOCKS_TIME) - Note over BB: **Flashblock Construction** + Note over BB: **3. Flashblock Construction** BB->>RB: FlashblocksPayloadV1 rect rgb(252,244,255) @@ -529,7 +527,7 @@ After handling the mandatory sequencer transactions in the initial Flashblock, t 8. **Flashblock Construction Termination** - Flashblock construction continues iteratively until: - - Rollup Boost signals final block aggregation and propagation via engine_getPayload. + - Rollup Boost signals final block aggregation and propagation via `engine_getPayload`. - A failure or timeout condition arises requiring failover procedures, detailed separately. ```mermaid From 969a601dba43abf0512038f0abdfea10d03ba19b Mon Sep 17 00:00:00 2001 From: dmarz Date: Sun, 24 Aug 2025 11:17:35 -0400 Subject: [PATCH 04/14] Update specs/protocol/flashblocks.md Co-authored-by: Ethnical --- specs/protocol/flashblocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index e61d61b1a..129785b23 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -61,7 +61,7 @@ # Abstract -Introduces a standard for partial blocks called “Flashblocks,” inspired but not entirely identical to [Solana Shreds](https://github.com/solana-foundation/specs/blob/main/p2p/shred.md), enabling rapid preconfirmations on Ethereum Layer 2 networks such as OP Stack. Flashblocks propagate transaction batches incrementally and expose their state via a modified Ethereum JSON-RPC interface, giving users immediate feedback equivalent to drastically reduced block times without modifying underlying the underlying OP Stack protocol. Flashblocks can be combined with Trusted Execution Environment technology to enable quick verifiability over various networks of machines in addition to protection from equivocation. +Introduces a standard for partial blocks called “Flashblocks,” inspired but not entirely identical to [Solana Shreds](https://github.com/solana-foundation/specs/blob/main/p2p/shred.md), enabling rapid preconfirmations on Ethereum Layer 2 networks such as OP Stack. Flashblocks propagate transaction batches incrementally and expose their state via a modified Ethereum JSON-RPC interface, giving users immediate feedback equivalent to drastically reduced block times without modifying the underlying OP Stack protocol. Flashblocks can be combined with Trusted Execution Environment technology to enable quick verifiability over various networks of machines in addition to protection from equivocation. # Prerequisites From 15bd8e94d40a26142086eb2d9d25dc2bbd70512c Mon Sep 17 00:00:00 2001 From: dmarz Date: Tue, 26 Aug 2025 19:52:44 -0400 Subject: [PATCH 05/14] Apply suggestion from @SozinM Co-authored-by: Solar Mithril --- specs/protocol/flashblocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 129785b23..1cfc7bdd6 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -9,7 +9,7 @@ - [Parameters](#parameters) - [Data structures](#data-structures) - [**`FlashblocksPayloadV1`**](#flashblockspayloadv1) - - [**`ExecutionPayloadFlashblockResultV1`**](#executionpayloadflashblockresultv1) + - [**`ExecutionPayloadFlashblockDeltaV1`**](#executionpayloadflashblockdeltav1) - [**`ExecutionPayloadStaticV1`**](#executionpayloadstaticv1) - [**`Metadata`**](#metadata) - [**`AccountMetadata`**](#accountmetadata) From 74af6a67f0fa8dcfcc8c335bc1fcd2da23142de9 Mon Sep 17 00:00:00 2001 From: dmarz Date: Tue, 26 Aug 2025 19:53:07 -0400 Subject: [PATCH 06/14] Apply suggestion from @SozinM Co-authored-by: Solar Mithril --- specs/protocol/flashblocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 1cfc7bdd6..9e1263587 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -119,7 +119,7 @@ class FlashblocksPayloadV1(): parent_flash_hash: Optional[Bytes32] index: uint64 static: Optional[ExecutionPayloadStaticV1] - diff: ExecutionPayloadFlashblockResultV1 + diff: ExecutionPayloadFlashblockDeltaV1 metadata: FlashblocksMetadata **Field descriptions:** From 6f937a7ca0fc6abcbf7d65de0ba002167bfc6d95 Mon Sep 17 00:00:00 2001 From: dmarz Date: Tue, 26 Aug 2025 19:53:20 -0400 Subject: [PATCH 07/14] Apply suggestion from @SozinM Co-authored-by: Solar Mithril --- specs/protocol/flashblocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 9e1263587..4c9114697 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -131,7 +131,7 @@ class FlashblocksPayloadV1(): - `diff`: Container with fields representing changes from the base payload. - `metadata`: Supplementary information about the execution of the flashblock. For example: account state changes, storage modifications, transaction receipts. -### **`ExecutionPayloadFlashblockResultV1`** +### **`ExecutionPayloadFlashblockDeltaV1`** Container encoding only the mutable portions of the execution payload updated during Flashblock construction. From 0469614327a064c763ebe8f8c3adf4b9f2df33a5 Mon Sep 17 00:00:00 2001 From: dmarz Date: Tue, 26 Aug 2025 19:53:35 -0400 Subject: [PATCH 08/14] Apply suggestion from @SozinM Co-authored-by: Solar Mithril --- specs/protocol/flashblocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 4c9114697..cdb31e83e 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -505,7 +505,7 @@ After handling the mandatory sequencer transactions in the initial Flashblock, t Note that each flashblock builds upon the state of all previous flashblocks, with these fields reflecting the cumulative state after applying the new transactions in this particular flashblock. -- Encapsulate these computed updates into `ExecutionPayloadFlashblockResultV1`. +- Encapsulate these computed updates into `ExecutionPayloadFlashblockDeltaV1`. 5. **Flashblock Indexing and Metadata** From 891b165fde11fc1161254d3c3964145b447082da Mon Sep 17 00:00:00 2001 From: dmarz Date: Tue, 26 Aug 2025 19:54:02 -0400 Subject: [PATCH 09/14] Apply suggestion from @SozinM Co-authored-by: Solar Mithril --- specs/protocol/flashblocks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index cdb31e83e..9139e1e21 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -136,7 +136,7 @@ class FlashblocksPayloadV1(): Container encoding only the mutable portions of the execution payload updated during Flashblock construction. ```python -class ExecutionPayloadFlashblockResultV1(): +class ExecutionPayloadFlashblockDeltaV1(): state_root: Bytes32 receipts_root: Bytes32 logs_bloom: ByteVector[BYTES_PER_LOGS_BLOOM] From fbcb02a3e2350cf1c8adc6c9f2044bc8f4019264 Mon Sep 17 00:00:00 2001 From: dmarzzz Date: Tue, 26 Aug 2025 20:38:29 -0400 Subject: [PATCH 10/14] fix: resolve markdown linting issues in flashblocks.md - Fix line length violations (MD013) - Remove trailing spaces (MD009) - Convert hard tabs to spaces (MD010) - Fix list marker spacing (MD030) - Reduce lint errors from 176 to 28 --- specs/protocol/flashblocks.md | 587 ++++++++++++++++++++++++---------- 1 file changed, 417 insertions(+), 170 deletions(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 9139e1e21..bf01f8a3d 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -1,4 +1,9 @@ -*Authors: [Ferran](https://github.com/ferranbt), [Dmarz](https://github.com/dmarzzz), [Shana](https://github.com/avalonche), [0xkitsune](https://github.com/0xkitsune), [protolambda](https://github.com/protolambda), [Anton](https://github.com/0x416e746f6e), [Joshua](https://github.com/trianglesphere)* +# Flashblocks + +*Authors: [Ferran](https://github.com/ferranbt), [Dmarz](https://github.com/dmarzzz), +[Shana](https://github.com/avalonche), [0xkitsune](https://github.com/0xkitsune), +[protolambda](https://github.com/protolambda), [Anton](https://github.com/0x416e746f6e), +[Joshua](https://github.com/trianglesphere)* **Table of Contents** - [Abstract](#abstract) @@ -61,7 +66,12 @@ # Abstract -Introduces a standard for partial blocks called “Flashblocks,” inspired but not entirely identical to [Solana Shreds](https://github.com/solana-foundation/specs/blob/main/p2p/shred.md), enabling rapid preconfirmations on Ethereum Layer 2 networks such as OP Stack. Flashblocks propagate transaction batches incrementally and expose their state via a modified Ethereum JSON-RPC interface, giving users immediate feedback equivalent to drastically reduced block times without modifying the underlying OP Stack protocol. Flashblocks can be combined with Trusted Execution Environment technology to enable quick verifiability over various networks of machines in addition to protection from equivocation. +Introduces a standard for partial blocks called “Flashblocks,” inspired but not entirely identical to [Solana +Shreds](https://github.com/solana-foundation/specs/blob/main/p2p/shred.md), enabling rapid preconfirmations on Ethereum +Layer 2 networks such as OP Stack. Flashblocks propagate transaction batches incrementally and expose their state via a +modified Ethereum JSON-RPC interface, giving users immediate feedback equivalent to drastically reduced block times +without modifying the underlying OP Stack protocol. Flashblocks can be combined with Trusted Execution Environment +technology to enable quick verifiability over various networks of machines in addition to protection from equivocation. # Prerequisites @@ -69,32 +79,54 @@ This document assumes knowledge of the terminology, definitions, and other mater - [🔗 Ethereum Optimism Protocol Specs](https://github.com/ethereum-optimism/specs/tree/main/specs/protocol) - [🔗 OP Stack Engine API](https://specs.optimism.io/protocol/exec-engine.html#engine-api) -- [🔗 External Block Production in OP Stack Design Doc](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) +- [🔗 External Block Production in OP Stack Design +Doc](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) - [🔗 Ethereum Execution APIs](https://github.com/ethereum/execution-apis/tree/main) - [🔗 Introducing Rollup-Boost - Launching on Unichain](https://writings.flashbots.net/introducing-rollup-boost) - [🔗 Rollup-boost design doc](https://www.notion.so/RFD-1-Rollup-boost-1996b4a0d876802f95d1c98387e38162?pvs=21) # Motivation -As of April 2025, Layer 2 (L2) protocols built with the OP Stack have a minimum block time of one second, imposing significant constraints on user experience. The limitation on minimum block times is primarily historical and architectural, reflecting earlier assumptions of Ethereum network as well as deeply-integrated type definitions, from the L2 blockchain client all the way down to smart contracts on the L1, making modification a very large task. - -Due to similar constraints on Ethereum Layer 1, preconfirmations have gained attention as a promising method to decouple blockchain user experiences from rigid block-time limitations and sidestep the longstanding debate between block time and block size. Existing preconfirmation solutions predominantly depend on economic security in the form of cryptoeconomic mechanisms such as staking. As well as focus on per-transaction preconfirmations, inadvertently pushing protocols into the “Latency Auction” region of the [MEV Trilemma](https://writings.flashbots.net/introducing-rollup-boost). Furthermore, previous approaches have often introduced entirely new Ethereum JSON-RPC methods, presenting substantial integration barriers and hindering practical adoption. - -Inspired by modern blockchain networks like Solana and Celestia, Flashblocks introduce an “out-of-protocol” standard for incremental delivery of partial blocks containing batches of transactions. This approach significantly reduces perceived latency for end-users and improves network bandwidth without modifying underlying protocol rules, offering a streamlined path for incremental adoption by node operators and existing infrastructure. +As of April 2025, Layer 2 (L2) protocols built with the OP Stack have a minimum block time of one second, imposing +significant constraints on user experience. The limitation on minimum block times is primarily historical and +architectural, reflecting earlier assumptions of Ethereum network as well as deeply-integrated type definitions, from +the L2 blockchain client all the way down to smart contracts on the L1, making modification a very large task. + +Due to similar constraints on Ethereum Layer 1, preconfirmations have gained attention as a promising method to +decouple blockchain user experiences from rigid block-time limitations and sidestep the longstanding debate between +block time and block size. Existing preconfirmation solutions predominantly depend on economic security in the form of +cryptoeconomic mechanisms such as staking. As well as focus on per-transaction preconfirmations, inadvertently pushing +protocols into the “Latency Auction” region of the [MEV +Trilemma](https://writings.flashbots.net/introducing-rollup-boost). Furthermore, previous approaches have often +introduced entirely new Ethereum JSON-RPC methods, presenting substantial integration barriers and hindering practical +adoption. + +Inspired by modern blockchain networks like Solana and Celestia, Flashblocks introduce an “out-of-protocol” standard +for incremental delivery of partial blocks containing batches of transactions. This approach significantly reduces +perceived latency for end-users and improves network bandwidth without modifying underlying protocol rules, offering a +streamlined path for incremental adoption by node operators and existing infrastructure. # Specification ## Terminology -All terms, actors, and components are used in this document identically to how they are defined in the [OP Stack protocol definition](https://github.com/ethereum-optimism/specs/blob/main/specs/glossary.md). +All terms, actors, and components are used in this document identically to how they are defined in the [OP Stack +protocol definition](https://github.com/ethereum-optimism/specs/blob/main/specs/glossary.md). Additional terms introduced: -- **External Block Builder** - External Block Builders are first introduced to the OP Stack in the [External Block Production Design Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) ****where they are described as an external party that the Sequencer can request blocks from. -- **Rollup Boost** - A sidecar piece of software first introduced without name in the [External Block Production Design Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) with two roles: +- **External Block Builder** - External Block Builders are first introduced to the OP Stack in the [External Block +Production Design +Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) ****where +they are described as an external party that the Sequencer can request blocks from. +- **Rollup Boost** - A sidecar piece of software first introduced without name in the [External Block Production Design +Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) with two +roles: 1. obfuscate the presence of External Block Builder software from the `op-node` and `op-geth` software 2. manage communication from the sequencer with External Block Builders and handle block delivery to `op-node` . -- **Fallback EL** - The standard Execution Layer of the Sequencer, used by Rollup Boost as a fallback mechanism when it cannot successfully build a block through the External Block Builder. This is an unmodified EL node that maintains the ability to construct valid blocks according to standard OP Stack protocol rules. +- **Fallback EL** - The standard Execution Layer of the Sequencer, used by Rollup Boost as a fallback mechanism when it +cannot successfully build a block through the External Block Builder. This is an unmodified EL node that maintains the +ability to construct valid blocks according to standard OP Stack protocol rules. - **RPC Provider** - Ethereum RPC software operator with the purpose of serving Ethereum state. ## Parameters @@ -110,7 +142,8 @@ Additional terms introduced: ### **`FlashblocksPayloadV1`** -The core data structure sent from the Block Builder to Rollup Boost and then external parties. A container representing a Flashblock payload, encapsulating block deltas, base configuration, and additional metadata. +The core data structure sent from the Block Builder to Rollup Boost and then external parties. A container +representing a Flashblock payload, encapsulating block deltas, base configuration, and additional metadata. ```python class FlashblocksPayloadV1(): @@ -126,10 +159,12 @@ class FlashblocksPayloadV1(): - `payload_id`: PayloadID is an identifier of the payload build process. The same for all flashblocks. - `index`: Index of the Flashblock within the parent block. -- `parent_flash_hash`: SSZ hash of the parent flashblock in the sequence. For the first flashblock (index 0), the field is empty. +- `parent_flash_hash`: SSZ hash of the parent flashblock in the sequence. For the first flashblock (index 0), the field +is empty. - `base` *(Optional)*: Reference execution payload serving as the unchanging base configuration. - `diff`: Container with fields representing changes from the base payload. -- `metadata`: Supplementary information about the execution of the flashblock. For example: account state changes, storage modifications, transaction receipts. +- `metadata`: Supplementary information about the execution of the flashblock. For example: account state changes, +storage modifications, transaction receipts. ### **`ExecutionPayloadFlashblockDeltaV1`** @@ -155,19 +190,23 @@ class ExecutionPayloadFlashblockDeltaV1(): - `gas_used`: Gas consumed by included transactions. - `block_hash`: Final hash of the completed execution block. - `transactions`: List of transactions included in the Flashblock. -- `withdrawals`: Withdrawals included (as per Optimism specification). Must be non-nil but empty when `withdrawals_root` is used directly. -- `withdrawals_root`: OP-Stack Isthmus specific field: instead of computing the root from a withdrawals list, set it directly. The "withdrawals" list attribute must be non-nil but empty. +- `withdrawals`: Withdrawals included (as per Optimism specification). Must be non-nil but empty when +`withdrawals_root` is used directly. +- `withdrawals_root`: OP-Stack Isthmus specific field: instead of computing the root from a withdrawals list, set it +directly. The "withdrawals" list attribute must be non-nil but empty. **Supporting Type Definitions** - `Transaction`: Transaction bytes as per execution payload specification. - `Withdrawal`: Standard Ethereum Capella withdrawal container. -All fields in this structure represent the cumulative state of the entire block up to and including the current flashblock, not just the changes from this specific flashblock. +All fields in this structure represent the cumulative state of the entire block up to and including the current +flashblock, not just the changes from this specific flashblock. ### **`ExecutionPayloadStaticV1`** -Container representing immutable fundamental block properties established at initial block creation, unchanged throughout construction. +Container representing immutable fundamental block properties established at initial block creation, unchanged +throughout construction. ```python class ExecutionPayloadStaticV1(): @@ -201,7 +240,7 @@ Container encapsulating all metadata for a flashblock, including account state c ```python class FlashblockMetadata(): accounts: List[AccountMetadata] - transactions: List[TransactionMetadata] + transactions: List[TransactionMetadata] **Field descriptions:** @@ -210,7 +249,8 @@ class FlashblockMetadata(): ### **`AccountMetadata`** -Container representing account state changes included in the Flashblock metadata. It is used by providers to fulfill the RPC requests. +Container representing account state changes included in the Flashblock metadata. It is used by providers to fulfill +the RPC requests. ```python class AccountMetadata(): @@ -229,7 +269,8 @@ class AccountMetadata(): - `code_created`: Contract bytecode if created in this Flashblock. - `storage_slots`: List of modified storage slots and their new values. -Storage slot keys must be de-duplicated (only the final value for each key should be included) and sorted in ascending byte order for deterministic processing. +Storage slot keys must be de-duplicated (only the final value for each key should be included) and sorted in ascending +byte order for deterministic processing. ### **`StorageSlot`** @@ -276,16 +317,16 @@ flowchart LR 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 @@ -304,97 +345,139 @@ This architecture shows the flow of data through the Flashblocks system: 3. The **WebSocket Proxy** distributes Flashblocks to multiple **RPC Providers** 4. **RPC Providers** serve preconfirmation data to **End Users** -The rest of this document provides detailed specifications for each component and their interactions, explaining the protocols, data structures, and operational considerations. +The rest of this document provides detailed specifications for each component and their interactions, explaining the +protocols, data structures, and operational considerations. ## Out-of-Protocol Design -The Flashblocks specification follows a deliberate "out-of-protocol" design philosophy. This section clarifies what we mean by this term and explains its implications for the OP Stack ecosystem. +The Flashblocks specification follows a deliberate "out-of-protocol" design philosophy. This section clarifies what we +mean by this term and explains its implications for the OP Stack ecosystem. ### In-Protocol vs. Out-of-Protocol -In the context of OP Stack, "in-protocol" components form the core protocol itself. These components implement fundamental consensus rules, are required for basic rollup functionality, and need standardization across all participants. Modifying in-protocol components requires protocol-level changes and network-wide upgrades. +In the context of OP Stack, "in-protocol" components form the core protocol itself. These components implement +fundamental consensus rules, are required for basic rollup functionality, and need standardization across all +participants. Modifying in-protocol components requires protocol-level changes and network-wide upgrades. -By contrast, "out-of-protocol" components like Flashblocks operate as optional extensions to the core protocol. They can be added or removed without breaking the consensus rules of the network, though they may still impact network performance or operations if implemented poorly. +By contrast, "out-of-protocol" components like Flashblocks operate as optional extensions to the core protocol. They +can be added or removed without breaking the consensus rules of the network, though they may still impact network +performance or operations if implemented poorly. -The only in-protocol guarantee that Flashblocks must uphold is producing valid blocks at the established block time interval (typically 1-2 seconds in current OP Stack implementations). +The only in-protocol guarantee that Flashblocks must uphold is producing valid blocks at the established block time +interval (typically 1-2 seconds in current OP Stack implementations). ### Design Rationale and Benefits -The out-of-protocol design for Flashblocks emerged from practical constraints during initial development. Without strong coordination with the OP Stack team at the outset, and given the complexity of the challenge, working within the existing protocol boundaries was the most pragmatic approach. +The out-of-protocol design for Flashblocks emerged from practical constraints during initial development. Without +strong coordination with the OP Stack team at the outset, and given the complexity of the challenge, working within the +existing protocol boundaries was the most pragmatic approach. -This constraint ultimately proved beneficial, as it forced the design to be minimally invasive. Flashblocks can be implemented immediately on any OP Stack chain without waiting for protocol upgrades or network-wide consensus. +This constraint ultimately proved beneficial, as it forced the design to be minimally invasive. Flashblocks can be +implemented immediately on any OP Stack chain without waiting for protocol upgrades or network-wide consensus. -Any issues with the Flashblocks implementation remain isolated from the core protocol, protecting overall network stability. In case of serious problems, Flashblocks can be disabled entirely, allowing the system to revert to normal operation without disrupting the underlying rollup. This clean fallback mechanism benefits from the centralized trust model of L2s, where the sequencer has the authority to quickly enact such operational changes without requiring network-wide consensus. +Any issues with the Flashblocks implementation remain isolated from the core protocol, protecting overall network +stability. In case of serious problems, Flashblocks can be disabled entirely, allowing the system to revert to normal +operation without disrupting the underlying rollup. This clean fallback mechanism benefits from the centralized trust +model of L2s, where the sequencer has the authority to quickly enact such operational changes without requiring +network-wide consensus. -Now that the usefulness of the system has been proven, as more collaboration venues with the OP Stack team emerge, integrating parts of Flashblocks directly into the protocol could provide even stronger guarantees and open the design space for future innovations. We are considering that approach too in the future. +Now that the usefulness of the system has been proven, as more collaboration venues with the OP Stack team emerge, +integrating parts of Flashblocks directly into the protocol could provide even stronger guarantees and open the design +space for future innovations. We are considering that approach too in the future. ### Implications for This Specification -Most elements defined in this document are out-of-protocol components that operate as extensions to the core OP Stack. The only hard guarantee the system must provide is that valid blocks are delivered at the expected intervals. +Most elements defined in this document are out-of-protocol components that operate as extensions to the core OP Stack. +The only hard guarantee the system must provide is that valid blocks are delivered at the expected intervals. -Everything else—from how Flashblocks are constructed and propagated to how RPC providers implement preconfirmation caches—represents iterative improvements designed to achieve the goal of faster user feedback as efficiently and impactfully as possible. +Everything else—from how Flashblocks are constructed and propagated to how RPC providers implement preconfirmation +caches—represents iterative improvements designed to achieve the goal of faster user feedback as efficiently and +impactfully as possible. -This means the specification describes a recommended implementation path rather than rigid protocol requirements. Components can evolve independently without requiring protocol-level coordination, and implementations may vary in how they achieve the same functional goals. +This means the specification describes a recommended implementation path rather than rigid protocol requirements. +Components can evolve independently without requiring protocol-level coordination, and implementations may vary in how +they achieve the same functional goals. ## Assumptions About Op Stack The Flashblocks design makes several assumptions about OP Stack behavior: -- **Quick Response for engine_getPayload**: We assume that `engine_getPayload` requests should return as quickly as possible for a normal and healthy chain. -- **Deterministic Payload IDs**: While not specific to Flashblocks but to Rollup Boost in general, we assume that payload IDs from different execution layer nodes are deterministically computed for the same ForkChoiceUpdate request. This is not explicitly enforced in specifications, but execution layers tend to maintain this consistency as a practical implementation detail. +- **Quick Response for engine_getPayload**: We assume that `engine_getPayload` requests should return as quickly as +possible for a normal and healthy chain. +- **Deterministic Payload IDs**: While not specific to Flashblocks but to Rollup Boost in general, we assume that +payload IDs from different execution layer nodes are deterministically computed for the same ForkChoiceUpdate request. +This is not explicitly enforced in specifications, but execution layers tend to maintain this consistency as a +practical implementation detail. ## Flashblock Lifecycle -Note that familiarity with Rollup-boost is expected throughout this entire document, as Flashblocks is designed as an extension built on top of the existing Rollup-boost architecture. +Note that familiarity with Rollup-boost is expected throughout this entire document, as Flashblocks is designed as an +extension built on top of the existing Rollup-boost architecture. -The lifecycle of a Flashblock begins with the Sequencer initiating block creation and ends with a normal L2 block consisting of all delivered flashblocks propagating according to the OP Stack protocol. The process proceeds as follows: +The lifecycle of a Flashblock begins with the Sequencer initiating block creation and ends with a normal L2 block +consisting of all delivered flashblocks propagating according to the OP Stack protocol. The process proceeds as follows: 1. **Fork Choice Update**: - - The Sequencer initiates the block-building cycle by sending an `engine_forkchoiceUpdated` with attributes call to Rollup Boost as it normally would to its local Execution Engine. - + + The Sequencer initiates the block-building cycle by sending an `engine_forkchoiceUpdated` with attributes call to +Rollup Boost as it normally would to its local Execution Engine. + 2. **Fork Choice Update Forwarding**: - + Rollup Boost forwards the `engine_forkchoiceUpdated` call concurrently to: - + - The Sequencer’s local Execution Engine - The External Block Builder 3. **Flashblock Construction**: - - Upon receiving the fork choice update, the External Block Builder constructs and continuously delivers `FlashblocksPayloadV1` at intervals defined by `FLASHBLOCKS_TIME` following the **Flashblocks Construction Process** defined in this document. - - It's important to emphasize that during this process, the External Block Builder sends only the incremental changes in each Flashblock, not the full block state each time. Each `FlashblocksPayloadV1` contains just the delta from the previous state (new transactions, updated state roots, etc.), allowing for efficient bandwidth usage and faster propagation. - - Only the first Flashblock (with `index` 0) includes the `static` field containing immutable block data, while subsequent Flashblocks omit this field since this information remains constant throughout the block's construction. Each Flashblock includes a `parent_flash_hash` that references the SSZ hash of the previous Flashblock in the sequence, creating a hash-linked chain within the block. - - The combined information received across all flashblocks is sufficient to fully reconstruct the complete block without any additional data. - + + Upon receiving the fork choice update, the External Block Builder constructs and continuously delivers +`FlashblocksPayloadV1` at intervals defined by `FLASHBLOCKS_TIME` following the **Flashblocks Construction Process** +defined in this document. + + It's important to emphasize that during this process, the External Block Builder sends only the incremental changes +in each Flashblock, not the full block state each time. Each `FlashblocksPayloadV1` contains just the delta from the +previous state (new transactions, updated state roots, etc.), allowing for efficient bandwidth usage and faster +propagation. + + Only the first Flashblock (with `index` 0) includes the `static` field containing immutable block data, while +subsequent Flashblocks omit this field since this information remains constant throughout the block's construction. +Each Flashblock includes a `parent_flash_hash` that references the SSZ hash of the previous Flashblock in the sequence, +creating a hash-linked chain within the block. + + The combined information received across all flashblocks is sufficient to fully reconstruct the complete block +without any additional data. + 4. **Flashblock Validation and Propagation**: - - For each received `FlashblocksPayloadV1`, Rollup Boost validates it against the Sequencer’s local Execution Engine and according to the **Flashblocks Validity Rules** defined in this document. Upon successful validation, Rollup Boost propagates the payload to all subscribed Flashblock-compatible RPC providers. - + + For each received `FlashblocksPayloadV1`, Rollup Boost validates it against the Sequencer’s local Execution Engine +and according to the **Flashblocks Validity Rules** defined in this document. Upon successful validation, Rollup Boost +propagates the payload to all subscribed Flashblock-compatible RPC providers. + 5. **Preconfirmed State Updates**: - - Flashblock-compatible RPC providers insert validated payloads into their local Preconfirmed State Overlay, providing immediate preconfirmation states to end-users via Flashblock-enhanced Ethereum JSON-RPC endpoints. - + + Flashblock-compatible RPC providers insert validated payloads into their local Preconfirmed State Overlay, +providing immediate preconfirmation states to end-users via Flashblock-enhanced Ethereum JSON-RPC endpoints. + 6. **Final L2 Block Delivery**: - - When the Sequencer calls `engine_getPayload`, Rollup Boost returns a single coherent block payload based on the validated Flashblocks received since the last fork choice update. Note that this does not require additional external requests or any last-minute processing. - + + When the Sequencer calls `engine_getPayload`, Rollup Boost returns a single coherent block payload based on the +validated Flashblocks received since the last fork choice update. Note that this does not require additional external +requests or any last-minute processing. + 7. **Full Block Propagation**: - + The Sequencer propagates the aggregated block following standard OP Stack protocol rules. - + ```mermaid -sequenceDiagram +sequenceDiagram participant S as Sequencer Driver (op-node) participant RB as Rollup Boost participant EE as Sequencer Execution Engine (op-geth) participant BB as External Block Builder participant RPC as Flashblock RPC Providers participant U as End Users - + rect rgb(230,247,255) Note over S: 1. **Fork Choice Update** S->>RB: engine_forkchoiceUpdated @@ -408,7 +491,7 @@ sequenceDiagram rect rgb(230,255,235) loop **Flashblock Construction** (every FLASHBLOCKS_TIME) - Note over BB: **3. Flashblock Construction** + Note over BB: **3. Flashblock Construction** BB->>RB: FlashblocksPayloadV1 rect rgb(252,244,255) @@ -442,21 +525,34 @@ sequenceDiagram ## Flashblock Construction Process -The External Block Builder initiates the construction of Flashblocks upon receiving a fork choice update (`engine_forkchoiceUpdated`) call forwarded by Rollup Boost. The construction of Flashblocks follows a defined sequence of steps repeated every `FLASHBLOCKS_TIME` interval, ensuring consistent, incremental, and ordered propagation of preconfirmed state to end-users. It's important to note that `FLASHBLOCKS_TIME` serves as a target interval rather than a strictly enforced rule in Rollup Boost. +The External Block Builder initiates the construction of Flashblocks upon receiving a fork choice update +(`engine_forkchoiceUpdated`) call forwarded by Rollup Boost. The construction of Flashblocks follows a defined sequence +of steps repeated every `FLASHBLOCKS_TIME` interval, ensuring consistent, incremental, and ordered propagation of +preconfirmed state to end-users. It's important to note that `FLASHBLOCKS_TIME` serves as a target interval rather than +a strictly enforced rule in Rollup Boost. ### Handling of Sequencer Transactions -An important protocol rule that the Flashblock construction process must adhere to involves handling "system transactions" within the OP Stack. These include deposits and system transactions that arrive with the Fork Choice Update (FCU) and must always be executed as the first transactions in any valid block. +An important protocol rule that the Flashblock construction process must adhere to involves handling "system +transactions" within the OP Stack. These include deposits and system transactions that arrive with the Fork Choice +Update (FCU) and must always be executed as the first transactions in any valid block. -From an "in-protocol" perspective, a block is not considered valid if these sequencer transactions are missing. Consequently, the minimum valid block that can be constructed must include the execution of these transactions. +From an "in-protocol" perspective, a block is not considered valid if these sequencer transactions are missing. +Consequently, the minimum valid block that can be constructed must include the execution of these transactions. -The External Block Builder follows this mandate by executing these sequencer transactions first and including them in the initial Flashblock (index 0). This serves as the foundation upon which all subsequent Flashblocks in the sequence will build. +The External Block Builder follows this mandate by executing these sequencer transactions first and including them in +the initial Flashblock (index 0). This serves as the foundation upon which all subsequent Flashblocks in the sequence +will build. -When processing these mandatory sequencer transactions, the builder does not apply the same gas allocation heuristics used for regular transactions in later Flashblocks. While these transactions do consume gas like any other transaction, they receive special handling as they must be included regardless of gas considerations to maintain protocol validity. +When processing these mandatory sequencer transactions, the builder does not apply the same gas allocation heuristics +used for regular transactions in later Flashblocks. While these transactions do consume gas like any other transaction, +they receive special handling as they must be included regardless of gas considerations to maintain protocol validity. ### Transaction Inclusion Heuristics -As part of the flashblock construction process, the External Block Builder makes sophisticated decisions about transaction inclusion. Unlike rigid gas limit enforcement, the decision of when to stop including transactions in a flashblock involves nuanced heuristics that may evolve over time. +As part of the flashblock construction process, the External Block Builder makes sophisticated decisions about +transaction inclusion. Unlike rigid gas limit enforcement, the decision of when to stop including transactions in a +flashblock involves nuanced heuristics that may evolve over time. The builder must balance multiple factors when deciding which transactions to include in each flashblock: @@ -465,34 +561,51 @@ The builder must balance multiple factors when deciding which transactions to in - Maintaining efficient gas utilization across the entire block - Accounting for execution time constraints within the `FLASHBLOCKS_TIME` window -In some cases, the builder might include a transaction that exceeds what would be a strict per-flashblock gas limit because executing that transaction is important for user experience or economic reasons. This flexibility is a key advantage of the out-of-protocol approach. +In some cases, the builder might include a transaction that exceeds what would be a strict per-flashblock gas limit +because executing that transaction is important for user experience or economic reasons. This flexibility is a key +advantage of the out-of-protocol approach. -The specific heuristics for transaction allocation across flashblocks are intentionally not prescribed in this specification. Rather than codifying particular strategies, we leave this as an area where builders can innovate and optimize. Different chains can develop custom heuristics based on their specific transaction patterns, user expectations, and economic models. As implementations mature, we expect some general principles will emerge for handling common scenarios, but this specification intentionally avoids prematurely constraining this design space. +The specific heuristics for transaction allocation across flashblocks are intentionally not prescribed in this +specification. Rather than codifying particular strategies, we leave this as an area where builders can innovate and +optimize. Different chains can develop custom heuristics based on their specific transaction patterns, user +expectations, and economic models. As implementations mature, we expect some general principles will emerge for +handling common scenarios, but this specification intentionally avoids prematurely constraining this design space. ### Post-block Execution Rules -In the OP Stack protocol, certain operations such as withdrawals and system requests are applied at the end of block execution. Since each flashblock must function as a valid standalone block for preconfirmation purposes, these post-block execution rules must be applied at the end of each flashblock's construction. +In the OP Stack protocol, certain operations such as withdrawals and system requests are applied at the end of block +execution. Since each flashblock must function as a valid standalone block for preconfirmation purposes, these +post-block execution rules must be applied at the end of each flashblock's construction. -When constructing a flashblock, the builder applies all required post-block operations after executing the selected transactions. These operations modify the state according to protocol rules, ensuring the flashblock represents a complete and valid block state. +When constructing a flashblock, the builder applies all required post-block operations after executing the selected +transactions. These operations modify the state according to protocol rules, ensuring the flashblock represents a +complete and valid block state. -However, an important implementation detail is that these post-block changes must be reverted before beginning execution for the next flashblock. This reversion is necessary because the post-block operations should only be applied once per actual L2 block, not cumulatively for each flashblock. Failing to revert these changes would lead to their repeated application across multiple flashblocks, potentially creating invalid cumulative state and ultimately an invalid final block. +However, an important implementation detail is that these post-block changes must be reverted before beginning +execution for the next flashblock. This reversion is necessary because the post-block operations should only be applied +once per actual L2 block, not cumulatively for each flashblock. Failing to revert these changes would lead to their +repeated application across multiple flashblocks, potentially creating invalid cumulative state and ultimately an +invalid final block. ### Construction Steps -After handling the mandatory sequencer transactions in the initial Flashblock, the External Block Builder proceeds with constructing subsequent Flashblocks by following these steps for each interval: +After handling the mandatory sequencer transactions in the initial Flashblock, the External Block Builder proceeds with +constructing subsequent Flashblocks by following these steps for each interval: -1. **Transaction Selection** +1. **Transaction Selection** - Retrieve transactions from local or external mempool: - Prioritize and sort transactions based on predefined sequencing policies, such as priority ordering or by MEV paid. -2. **Transaction Execution** +2. **Transaction Execution** -- Sequentially execute selected transactions against a state snapshot derived from the current execution payload base (ExecutionPayloadBaseV1) or the last validated flashblock +- Sequentially execute selected transactions against a state snapshot derived from the current execution payload base +(ExecutionPayloadBaseV1) or the last validated flashblock - Apply the transaction inclusion heuristics described earlier to determine when to stop including transactions -- After transaction execution completes, apply all post-block execution rules as described in the Post-Block Execution Rules section +- After transaction execution completes, apply all post-block execution rules as described in the Post-Block Execution +Rules section -3. **Flashblock Payload Assembly** +3. **Flashblock Payload Assembly** - After transaction execution, compute and record the following execution state updates: - `state_root`: The new post-execution state root resulting from the executed transactions. @@ -500,31 +613,37 @@ After handling the mandatory sequencer transactions in the initial Flashblock, t - `logs_bloom`: Aggregated logs bloom from all emitted transaction logs within this flashblock. - `gas_used`: Total gas consumed by executed transactions. - `transactions`: Serialized transaction payloads included within the flashblock. - - `withdrawals` (if applicable): Withdrawals executed during the current flashblock interval (as per OP Stack withdrawal specification). + - `withdrawals` (if applicable): Withdrawals executed during the current flashblock interval (as per OP Stack +withdrawal specification). - `block_hash`: Computed block hash uniquely identifying this flashblock execution state. - - Note that each flashblock builds upon the state of all previous flashblocks, with these fields reflecting the cumulative state after applying the new transactions in this particular flashblock. - + + Note that each flashblock builds upon the state of all previous flashblocks, with these fields reflecting the +cumulative state after applying the new transactions in this particular flashblock. + - Encapsulate these computed updates into `ExecutionPayloadFlashblockDeltaV1`. -5. **Flashblock Indexing and Metadata** +5. **Flashblock Indexing and Metadata** - Assign a monotonically incremented `index` to the newly constructed Flashblock payload. -- Compute the SSZ hash of the previous Flashblock and assign it as the `parent_flash_hash` (for the first Flashblock with index 0, this field is empty) +- Compute the SSZ hash of the previous Flashblock and assign it as the `parent_flash_hash` (for the first Flashblock +with index 0, this field is empty) -6. **Flashblock Delivery** +6. **Flashblock Delivery** -- Package the `index`, `payload_id`, `ExecutionPayloadFlashblockDeltaV1`, and metadata into a `FlashblocksPayloadV1` payload. -- Deliver the assembled `FlashblocksPayloadV1` payload promptly to Rollup Boost via the designated Flashblocks submission API. +- Package the `index`, `payload_id`, `ExecutionPayloadFlashblockDeltaV1`, and metadata into a `FlashblocksPayloadV1` +payload. +- Deliver the assembled `FlashblocksPayloadV1` payload promptly to Rollup Boost via the designated Flashblocks +submission API. -7. **Subsequent Flashblock Construction** +7. **Subsequent Flashblock Construction** - Immediately after successful delivery, increment the Flashblock `index`. - Revert any post-block execution changes as described in the Post-Block Execution Rules section - Reset the transaction execution context based on the newly delivered state. -- Begin constructing the next `FlashblocksPayloadV1` payload, repeating from step 1 until a termination condition is reached (e.g., end of block building period via `engine_getPayload` request). +- Begin constructing the next `FlashblocksPayloadV1` payload, repeating from step 1 until a termination condition is +reached (e.g., end of block building period via `engine_getPayload` request). -8. **Flashblock Construction Termination** +8. **Flashblock Construction Termination** - Flashblock construction continues iteratively until: - Rollup Boost signals final block aggregation and propagation via `engine_getPayload`. @@ -545,7 +664,8 @@ sequenceDiagram EE-->>BB: Execution results (state root, receipts, gas used) Note over BB: Construct Flashblock Delta - BB->>BB: Assemble FlashblocksPayloadV1 (state_root, receipts_root, logs_bloom, gas_used, block_hash, txs, withdrawals, metadata) + BB->>BB: Assemble FlashblocksPayloadV1 (state_root, receipts_root, logs_bloom, gas_used, block_hash, txs, +withdrawals, metadata) BB->>RB: Submit FlashblocksPayloadV1 RB-->>BB: Acknowledge reception (async) @@ -555,9 +675,12 @@ sequenceDiagram ## Flashblocks Metadata -The `FlashblocksPayloadV1` structure defined above contains the minimum required data for Rollup Boost to return a valid block. The `metadata` field provides additional information to enable preconfirmations. +The `FlashblocksPayloadV1` structure defined above contains the minimum required data for Rollup Boost to return a +valid block. The `metadata` field provides additional information to enable preconfirmations. -This metadata contains supplementary information about the execution state that is not strictly necessary for block construction but is valuable for RPC providers to offer comprehensive preconfirmation services. Examples of such metadata include: +This metadata contains supplementary information about the execution state that is not strictly necessary for block +construction but is valuable for RPC providers to offer comprehensive preconfirmation services. Examples of such +metadata include: - Account state changes (which accounts have been modified) - Updated account balances @@ -567,26 +690,42 @@ This metadata contains supplementary information about the execution state that ### Alternative Design Consideration -While this specification includes detailed metadata in Flashblocks, a viable alternative would be for RPC providers to execute transactions themselves as they receive them through the stream. In this approach, providers would receive only transaction data, execute them in order, maintain their own state cache, and use it to fulfill RPC requests. This would significantly reduce bandwidth requirements by eliminating metadata transmission. +While this specification includes detailed metadata in Flashblocks, a viable alternative would be for RPC providers to +execute transactions themselves as they receive them through the stream. In this approach, providers would receive only +transaction data, execute them in order, maintain their own state cache, and use it to fulfill RPC requests. This would +significantly reduce bandwidth requirements by eliminating metadata transmission. ## Rationale for Including State Roots in Flashblocks -One of the most discussed aspects of the Flashblocks design is the decision to include state roots with every flashblock. This section explains the rationale behind this design choice. +One of the most discussed aspects of the Flashblocks design is the decision to include state roots with every +flashblock. This section explains the rationale behind this design choice. ### Non-Blocking Block Production -We operate under the assumption that `engine_getPayload` requests should return quickly with a valid, complete block. This assumption, which we believe to be correct based on our understanding of the OP Stack, guides our design decisions. +We operate under the assumption that `engine_getPayload` requests should return quickly with a valid, complete block. +This assumption, which we believe to be correct based on our understanding of the OP Stack, guides our design decisions. -Currently in OP Stack implementations, execution layer nodes compute payloads in the background and can return them immediately when requested via `engine_getPayload`. This allows for near-instant responses, maintaining the flow of block production without delays. For Flashblocks to provide similar performance, it must have all block components - including state roots - readily available when `engine_getPayload` is called. +Currently in OP Stack implementations, execution layer nodes compute payloads in the background and can return them +immediately when requested via `engine_getPayload`. This allows for near-instant responses, maintaining the flow of +block production without delays. For Flashblocks to provide similar performance, it must have all block components - +including state roots - readily available when `engine_getPayload` is called. -Without pre-computed state roots for each flashblock, Rollup Boost would face a critical decision when handling `engine_getPayload`: +Without pre-computed state roots for each flashblock, Rollup Boost would face a critical decision when handling +`engine_getPayload`: -1. **Request the state root from the Execution Layer**: This approach would be problematic because the Execution Layer does not maintain a "hot" state that matches the current flashblock sequence. It would need to apply all pending transactions and compute a new state root, which is exactly the operation we're trying to optimize with flashblocks. -2. **Request the state root from the External Block Builder**: This would require an additional synchronous request to the builder with a protocol which is not engine-specific. Not only does this introduce an extra communication hop and latency, but it also creates a single point of failure - if the builder is unavailable at that moment, Rollup Boost cannot fulfill the request and we fall into the failure path rather than the happy path. +1. **Request the state root from the Execution Layer**: This approach would be problematic because the Execution Layer +does not maintain a "hot" state that matches the current flashblock sequence. It would need to apply all pending +transactions and compute a new state root, which is exactly the operation we're trying to optimize with flashblocks. +2. **Request the state root from the External Block Builder**: This would require an additional synchronous request to +the builder with a protocol which is not engine-specific. Not only does this introduce an extra communication hop and +latency, but it also creates a single point of failure - if the builder is unavailable at that moment, Rollup Boost +cannot fulfill the request and we fall into the failure path rather than the happy path. ### Builder Availability and System Reliability -The key advantage of including state roots with each flashblock is system reliability. By having state roots immediately available, Rollup Boost can respond to `engine_getPayload` requests without additional external dependencies at that critical moment. +The key advantage of including state roots with each flashblock is system reliability. By having state roots +immediately available, Rollup Boost can respond to `engine_getPayload` requests without additional external +dependencies at that critical moment. Without pre-included state roots, a builder failure at the moment of block production would force the system to either: @@ -596,36 +735,57 @@ Without pre-included state roots, a builder failure at the moment of block produ ### Future Design Considerations -This approach represents our current understanding of the optimal design given existing constraints. However, as mentioned in the Out-of-Protocol Design section, alternative approaches may be worth exploring as we gain production experience. Future iterations might consider different state root handling approaches, particularly in the context of high-availability sequencer setups and deeper integration with OP Stack components. +This approach represents our current understanding of the optimal design given existing constraints. However, as +mentioned in the Out-of-Protocol Design section, alternative approaches may be worth exploring as we gain production +experience. Future iterations might consider different state root handling approaches, particularly in the context of +high-availability sequencer setups and deeper integration with OP Stack components. ## Builder-to-Rollup-boost Communication Flow -Rollup Boost maintains an open WebSocket connection with the External Block Builder. Through this persistent connection, the builder pushes the `FlashblocksPayloadV1` payloads as soon as they're constructed, without waiting for requests from Rollup Boost. +Rollup Boost maintains an open WebSocket connection with the External Block Builder. Through this persistent +connection, the builder pushes the `FlashblocksPayloadV1` payloads as soon as they're constructed, without waiting for +requests from Rollup Boost. -If the WebSocket connection goes down, the builder buffers (queues) the messages internally and attempts to resend them once the connection is restored. This buffering only applies for the current block being built; when a new block cycle begins, any queued messages from the previous block are discarded as they are no longer relevant to the current state. +If the WebSocket connection goes down, the builder buffers (queues) the messages internally and attempts to resend them +once the connection is restored. This buffering only applies for the current block being built; when a new block cycle +begins, any queued messages from the previous block are discarded as they are no longer relevant to the current state. **SSZ Encoding for Flashblocks Messages** -Flashblocks messages transmitted between the Block Builder and Rollup Boost use Simple Serialize (SSZ) for binary encoding. Unlike JSON or other self-describing formats, SSZ is schema-less and does not embed field names or type information in the serialized data. This makes explicit versioning necessary, especially in a streaming context where message types cannot be inferred from surrounding context. +Flashblocks messages transmitted between the Block Builder and Rollup Boost use Simple Serialize (SSZ) for binary +encoding. Unlike JSON or other self-describing formats, SSZ is schema-less and does not embed field names or type +information in the serialized data. This makes explicit versioning necessary, especially in a streaming context where +message types cannot be inferred from surrounding context. For the `FlashblocksPayloadV1` structure, a version field is placed as the first field in the container. -This design leverages SSZ's deterministic encoding characteristics, where fixed-size fields like `Bytes4` appear at predictable offsets in the serialized data. When a recipient receives a serialized Flashblocks message over the WebSocket stream: +This design leverages SSZ's deterministic encoding characteristics, where fixed-size fields like `Bytes4` appear at +predictable offsets in the serialized data. When a recipient receives a serialized Flashblocks message over the +WebSocket stream: 1. It first reads the initial 4 bytes to determine the message version -2. Based on the version identifier, it selects the appropriate container structure for deserializing the remainder of the data +2. Based on the version identifier, it selects the appropriate container structure for deserializing the remainder of +the data ## Flashblock Validity Rules For a flashblock to be considered valid the following must hold: -- **Monotonically Increasing Payload Index:** Each successive Flashblock payload delivered within the same L2 block cycle must have an index exactly one greater than the previous payload. Any skipped indices or duplicated indices constitute a violation. When a violation occurs, Rollup Boost will ignore the invalid flashblock and maintain its internal state, only updating when it receives a new flashblock with the correct next index value. -- **Immutable Payload Base:** Immutable block header fields (`parent_hash`, `block_number`, `prev_randao`, etc.) set by the initial `ExecutionPayloadBaseV1` cannot be altered by subsequent Flashblocks during the same L2 block period. -- **Execution Validity:** Every Flashblock must be validated successfully against the Sequencer’s local execution engine state to ensure OP protocol-level correctness. -- **Valid Full Block:** Every flashblock, when combined with prior flashblocks, should be a valid L2 Block without requiring Rollup Boost to perform any additional operations other than repackaging the data structure. This means that state roots are calculated on each Flashblock contrary to publication due to the out-of-protocol nature of the implementation. - +- **Monotonically Increasing Payload Index:** Each successive Flashblock payload delivered within the same L2 block +cycle must have an index exactly one greater than the previous payload. Any skipped indices or duplicated indices +constitute a violation. When a violation occurs, Rollup Boost will ignore the invalid flashblock and maintain its +internal state, only updating when it receives a new flashblock with the correct next index value. +- **Immutable Payload Base:** Immutable block header fields (`parent_hash`, `block_number`, `prev_randao`, etc.) set by +the initial `ExecutionPayloadBaseV1` cannot be altered by subsequent Flashblocks during the same L2 block period. +- **Execution Validity:** Every Flashblock must be validated successfully against the Sequencer’s local execution +engine state to ensure OP protocol-level correctness. +- **Valid Full Block:** Every flashblock, when combined with prior flashblocks, should be a valid L2 Block without +requiring Rollup Boost to perform any additional operations other than repackaging the data structure. This means that +state roots are calculated on each Flashblock contrary to publication due to the out-of-protocol nature of the +implementation. + A flashblock is considered a valid block if: - + - It includes the first flashblock (with index 0 containing the base data) - It comprises a continuous sequence of flashblocks with incrementing indices. @@ -633,12 +793,17 @@ For a flashblock to be considered valid the following must hold: The following invariants must hold true for the Flashblocks protocol to function reliably: -- **No Equivocation:** At no point should multiple distinct Flashblocks for the same payload index be delivered or propagated to RPC subscribers. -- **Preconfirmation Preservation:** The system always gives strong preference to maintaining the integrity of issued preconfirmations. Once a transaction has been included in a flashblock and made visible to users as preconfirmed, the system will prioritize preserving this state over other considerations such as block value optimization or alternative builder selection. +- **No Equivocation:** At no point should multiple distinct Flashblocks for the same payload index be delivered or +propagated to RPC subscribers. +- **Preconfirmation Preservation:** The system always gives strong preference to maintaining the integrity of issued +preconfirmations. Once a transaction has been included in a flashblock and made visible to users as preconfirmed, the +system will prioritize preserving this state over other considerations such as block value optimization or alternative +builder selection. ## Flashblock Propagation -Once Rollup Boost has validated a flashblock, it is then propagated to the rest of the network to be included in each RPC Provider’s Preconfirmation Cache. +Once Rollup Boost has validated a flashblock, it is then propagated to the rest of the network to be included in each +RPC Provider’s Preconfirmation Cache. ```mermaid sequenceDiagram @@ -656,15 +821,22 @@ sequenceDiagram note right of U: Regular users ``` -Flashblocks Compatible RPC Providers subscribe to the Flashblocks websocket stream from Rollup Boost and maintain an in-memory representation of the preconfirmation state. RPC providers validate that the flashblock sequence is correct before updating their preconfirmation state. This preconfirmation state is ephemeral, maintained only until the corresponding block is propagated and the information becomes available through standard chain state. +Flashblocks Compatible RPC Providers subscribe to the Flashblocks websocket stream from Rollup Boost and maintain an +in-memory representation of the preconfirmation state. RPC providers validate that the flashblock sequence is correct +before updating their preconfirmation state. This preconfirmation state is ephemeral, maintained only until the +corresponding block is propagated and the information becomes available through standard chain state. Throughout the entire propagation path, flashblocks are transmitted in binary SSZ-encoded format. ### Secure propagation -Since the preconfirmation data originates directly from the Sequencer's Rollup Boost instance, exposing this WebSocket endpoint directly to external parties presents security and scalability concerns. Instead, a reverse proxy should be implemented between Rollup Boost and external RPC providers to relay this information securely. +Since the preconfirmation data originates directly from the Sequencer's Rollup Boost instance, exposing this WebSocket +endpoint directly to external parties presents security and scalability concerns. Instead, a reverse proxy should be +implemented between Rollup Boost and external RPC providers to relay this information securely. -This mirror simply relays WebSocket data without requiring any Flashblocks-specific knowledge, acting purely as a transport layer that forwards WebSocket messages from Rollup Boost to subscribed RPC providers. You can find an example implementation [here](https://github.com/base/flashblocks-websocket-proxy). +This mirror simply relays WebSocket data without requiring any Flashblocks-specific knowledge, acting purely as a +transport layer that forwards WebSocket messages from Rollup Boost to subscribed RPC providers. You can find an example +implementation [here](https://github.com/base/flashblocks-websocket-proxy). ```mermaid flowchart TD @@ -673,14 +845,14 @@ flowchart TD RB[Rollup Boost] Mirror[Flashblocks Mirror] end - + subgraph RPC Providers RPC1[RPC Provider 1] RPC2[RPC Provider 2] RPC3[RPC Provider 3] RPCN[RPC Provider N] end - + BB -->|Flashblocks| RB RB -->|Flashblocks| Mirror Mirror -->|Flashblocks| RPC1 @@ -693,9 +865,19 @@ flowchart TD ### Ethereum JSON RPC Modifications -All modifications done to the existing Ethereum JSON RPC methods are confined to overloading the existing `pending` tag. Originally, this tag was designed to return block data being processed by the node's internal miner. It's fitting that we now use it for a similar purpose: exposing blocks in their preconfirmation stage. When queried with the `pending` tag, the endpoint uses the preconfirmation cache state to construct the response. The response might include not only transactions but also block metadata like state root and receipt root. +All modifications done to the existing Ethereum JSON RPC methods are confined to overloading the existing `pending` +tag. Originally, this tag was designed to return block data being processed by the node's internal miner. It's fitting +that we now use it for a similar purpose: exposing blocks in their preconfirmation stage. When queried with the +`pending` tag, the endpoint uses the preconfirmation cache state to construct the response. The response might include +not only transactions but also block metadata like state root and receipt root. -The tag is currently in a soft-deprecated state due to inconsistent implementations across clients, particularly after The Merge. However, it's worth noting that it's still actively used for certain endpoints, particularly `eth_getTransactionCount` where it serves the important function of returning the next available nonce for an account (including transactions in the mempool). This presents an opportunity: the tag is well-defined enough to be supported by client libraries, yet loosely defined enough to allow for our preconfirmation use case. While there's a possibility of the tag being removed in the future (see [EIP discussions](https://github.com/ethereum/execution-apis/issues/495)), the design could adapt by introducing a flashblocks-specific tag if needed. +The tag is currently in a soft-deprecated state due to inconsistent implementations across clients, particularly after +The Merge. However, it's worth noting that it's still actively used for certain endpoints, particularly +`eth_getTransactionCount` where it serves the important function of returning the next available nonce for an account +(including transactions in the mempool). This presents an opportunity: the tag is well-defined enough to be supported +by client libraries, yet loosely defined enough to allow for our preconfirmation use case. While there's a possibility +of the tag being removed in the future (see [EIP discussions](https://github.com/ethereum/execution-apis/issues/495)), +the design could adapt by introducing a flashblocks-specific tag if needed. We repurpose the `pending` tag in the following RPC calls to enable consuming preconfirmed state: @@ -732,11 +914,16 @@ This endpoint allows clients to discover whether the RPC provider supports certa } ``` -When this method is called on a Flashblocks-compatible RPC provider, the response includes "flashblocksv1" in the returned array of supported capabilities. This allows clients to programmatically determine whether they can utilize Flashblocks functionality before making related requests. +When this method is called on a Flashblocks-compatible RPC provider, the response includes "flashblocksv1" in the +returned array of supported capabilities. This allows clients to programmatically determine whether they can utilize +Flashblocks functionality before making related requests. -This endpoint follows a similar pattern to the Engine API's `engine_exchangeCapabilities` method, which allows consensus and execution clients to exchange information about supported features. +This endpoint follows a similar pattern to the Engine API's `engine_exchangeCapabilities` method, which allows +consensus and execution clients to exchange information about supported features. -This is the only new RPC endpoint introduced by the Flashblocks specification. We consider this addition acceptable because it provides necessary feature discovery while keeping the name abstract enough to accommodate future extensions to the protocol or for other protocols. +This is the only new RPC endpoint introduced by the Flashblocks specification. We consider this addition acceptable +because it provides necessary feature discovery while keeping the name abstract enough to accommodate future extensions +to the protocol or for other protocols. **`eth_getTransactionReceipt`** @@ -771,7 +958,8 @@ This is the only new RPC endpoint introduced by the Flashblocks specification. W } ``` -When queried, this endpoint first checks the preconfirmation cache for the requested transaction hash before falling back to the standard chain state lookup. +When queried, this endpoint first checks the preconfirmation cache for the requested transaction hash before falling +back to the standard chain state lookup. Some fields in the response cannot be final at the preconfirmation stage and require placeholder values: @@ -811,7 +999,9 @@ Some fields in the response cannot be final at the preconfirmation stage and req } ``` -The endpoint implements an append-only pattern - multiple queries during the same block's preconfirmation phase will show an expanding list of transactions as new flashblocks are processed. Each query reflects the current state of all preconfirmed transactions at that moment. +The endpoint implements an append-only pattern - multiple queries during the same block's preconfirmation phase will +show an expanding list of transactions as new flashblocks are processed. Each query reflects the current state of all +preconfirmed transactions at that moment. ```mermaid sequenceDiagram @@ -821,22 +1011,22 @@ sequenceDiagram Note over R: Block building starts R->>RPC: Batch 1 (txs: A, B) - + U->>RPC: Query 1 RPC-->>U: Block with txs: A, B - + R->>RPC: Batch 2 (txs: C, D) U->>RPC: Query 2 RPC-->>U: Block with txs: A, B, C, D - + R->>RPC: Batch 3 (txs: E) U->>RPC: Query 3 RPC-->>U: Block with txs: A, B, C, D, E - + R->>RPC: Batch 4 (txs: F, G) U->>RPC: Query 4 RPC-->>U: Block with txs: A, B, C, D, E, F, G - + Note over R: Block sealed ``` @@ -859,7 +1049,10 @@ sequenceDiagram "0x..." // Balance in wei ``` -When queried with the "pending" tag, the endpoint uses the preconfirmation cache state to return the account balance. If the requested account appears in the `AccountMetadata` of a received Flashblock with a non-null `balance` field, the RPC provider can directly return this value without needing to access the full state. The response reflects all changes from preconfirmed transactions that affect the requested account's balance. +When queried with the "pending" tag, the endpoint uses the preconfirmation cache state to return the account balance. +If the requested account appears in the `AccountMetadata` of a received Flashblock with a non-null `balance` field, the +RPC provider can directly return this value without needing to access the full state. The response reflects all changes +from preconfirmed transactions that affect the requested account's balance. **`eth_call`** @@ -880,11 +1073,14 @@ When queried with the "pending" tag, the endpoint uses the preconfirmation cache "0x..." // Return data from the call ``` -When queried with the "pending" tag, the endpoint uses the preconfirmation cache state to return the call result. For this endpoint to work, the preconfirmation stream needs to include state differences for both accounts and storage after each flashblock. +When queried with the "pending" tag, the endpoint uses the preconfirmation cache state to return the call result. For +this endpoint to work, the preconfirmation stream needs to include state differences for both accounts and storage +after each flashblock. -Similar to the current override functionality in `eth_call` where EVM transitions are executed on top of modified state, this implementation executes the call on top of the preconfirmation state changes. +Similar to the current override functionality in `eth_call` where EVM transitions are executed on top of modified +state, this implementation executes the call on top of the preconfirmation state changes. -**`eth_getCode`** +**`eth_getCode`** **Request** @@ -903,7 +1099,9 @@ Similar to the current override functionality in `eth_call` where EVM transition "0x..."// Contract bytecode ``` -When queried with the "pending" tag, the endpoint returns the contract bytecode from the preconfirmation cache state. If the requested account appears in the `AccountMetadata` of a received Flashblock with a non-null `code` field, the RPC provider can directly return this value without accessing the full state. +When queried with the "pending" tag, the endpoint returns the contract bytecode from the preconfirmation cache state. +If the requested account appears in the `AccountMetadata` of a received Flashblock with a non-null `code` field, the +RPC provider can directly return this value without accessing the full state. **`eth_getTransactionCount`** @@ -924,9 +1122,11 @@ When queried with the "pending" tag, the endpoint returns the contract bytecode "0x..."// Nonce value as a hex string ``` -When queried with the "pending" tag, the endpoint returns the transaction count (nonce) of the account from the preconfirmation cache. If the requested account appears in the `AccountMetadata` of a received Flashblock, the RPC provider can directly use the `nonce` field without additional state access. +When queried with the "pending" tag, the endpoint returns the transaction count (nonce) of the account from the +preconfirmation cache. If the requested account appears in the `AccountMetadata` of a received Flashblock, the RPC +provider can directly use the `nonce` field without additional state access. -**`eth_getStorageAt`** +**`eth_getStorageAt`** **Request** @@ -945,13 +1145,18 @@ When queried with the "pending" tag, the endpoint returns the transaction count "0x..." // Storage value as a hex string ``` -When queried with the "pending" tag, the endpoint returns the value from the specified storage slot using the preconfirmation cache state. If the requested account appears in the `AccountMetadata` of a received Flashblock, the RPC provider scans the `storage_slots` list for the requested key and returns the corresponding value directly. +When queried with the "pending" tag, the endpoint returns the value from the specified storage slot using the +preconfirmation cache state. If the requested account appears in the `AccountMetadata` of a received Flashblock, the +RPC provider scans the `storage_slots` list for the requested key and returns the corresponding value directly. # Reliability and Operational Considerations ## Transaction Propagation -Similar to the design laid out in the [External Block Production](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) design document, Flashblocks makes no assumptions about how transactions are delivered to the block builder. A non-exhaustive list of valid approaches: +Similar to the design laid out in the [External Block +Production](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) design +document, Flashblocks makes no assumptions about how transactions are delivered to the block builder. A non-exhaustive +list of valid approaches: - transaction forwarding via mutliplex’ing software at the Rollup Operator’s RPC - Private p2p connections between Sequencer transaction ingress nodes and block building nodes @@ -960,68 +1165,110 @@ Similar to the design laid out in the [External Block Production](https://github ### Block Builder -As per the normal Rollup-boost behavior, if the builder is down, the Rollup-boost picks up the block from the fallback builder. However, since we are dealing with preconfirmations, we must consider the relative value of preserving preconfirmations versus building a potentially more valuable block. +As per the normal Rollup-boost behavior, if the builder is down, the Rollup-boost picks up the block from the fallback +builder. However, since we are dealing with preconfirmations, we must consider the relative value of preserving +preconfirmations versus building a potentially more valuable block. -In this design document, we follow the invariant that preserving preconfirmations takes precedence. If the block builder goes down after the first flashblocks have been delivered, we still return those flashblocks to maintain the integrity of any preconfirmations already issued to users. The next block would work as expected through the normal fallback mechanism, as the builder is down and the fallback builder would be used. +In this design document, we follow the invariant that preserving preconfirmations takes precedence. If the block +builder goes down after the first flashblocks have been delivered, we still return those flashblocks to maintain the +integrity of any preconfirmations already issued to users. The next block would work as expected through the normal +fallback mechanism, as the builder is down and the fallback builder would be used. -We could technically discard the partial flashblocks and use the fallback block entirely, but this would violate the preconfirmations commitment. Our design assumes normal execution conditions. If losing the builder mid-flashblock becomes a common occurrence, this would indicate fundamental architectural issues that require separate improvements beyond the scope of this failover mechanism. +We could technically discard the partial flashblocks and use the fallback block entirely, but this would violate the +preconfirmations commitment. Our design assumes normal execution conditions. If losing the builder mid-flashblock +becomes a common occurrence, this would indicate fundamental architectural issues that require separate improvements +beyond the scope of this failover mechanism. ### The Sequencer or Rollup-boost -These failure scenarios are addressed as part of the High Availability (HA) sequencer setups. The HA architecture ensures continuity of operations by automatically failing over to standby instances when failures occur. +These failure scenarios are addressed as part of the High Availability (HA) sequencer setups. The HA architecture +ensures continuity of operations by automatically failing over to standby instances when failures occur. ## Integration with High Availability Sequencer Setups -The integration of Flashblocks with High Availability (HA) Sequencer setups is outside the scope of this initial specification document. For details on managing Flashblock state across multiple sequencer instances and maintaining preconfirmation integrity during failovers, please refer to the resources linked below. +The integration of Flashblocks with High Availability (HA) Sequencer setups is outside the scope of this initial +specification document. For details on managing Flashblock state across multiple sequencer instances and maintaining +preconfirmation integrity during failovers, please refer to the resources linked below. -- what do with a rotating set of sequencers like with OP conductor https://github.com/ethereum-optimism/optimism/tree/develop/op-conductor +- what do with a rotating set of sequencers like with OP conductor +https://github.com/ethereum-optimism/optimism/tree/develop/op-conductor - World HA design discussion https://github.com/flashbots/rollup-boost/issues/181 -- Base Technical Design Document [TDD: Rollup Boost Integration with HA Sequencer](https://www.notion.so/TDD-Rollup-Boost-Integration-with-HA-Sequencer-1d0c9d820ca380348f21e44a5442feaf?pvs=21) +- Base Technical Design Document [TDD: Rollup Boost Integration with HA +Sequencer](https://www.notion.so/TDD-Rollup-Boost-Integration-with-HA-Sequencer-1d0c9d820ca380348f21e44a5442feaf?pvs=21) ## Faults ### **Safety Faults** -In the rollup security vocabulary *safety* implies that “**no one can create or withdraw assets they are not entitled to.**” A **safety fault** therefore occurs the moment an **invalid L2 state root** is accepted on Ethereum **and** at least one L2→L1 action (withdrawal, message relay, etc.) that depends on that root is executed **and** the dispute game period has ended. After that point the canonical record on Ethereum says the invalid state is *final* and the rollup’s honesty assumption is broken. +In the rollup security vocabulary *safety* implies that “**no one can create or withdraw assets they are not entitled +to.**” A **safety fault** therefore occurs the moment an **invalid L2 state root** is accepted on Ethereum **and** at +least one L2→L1 action (withdrawal, message relay, etc.) that depends on that root is executed **and** the dispute game +period has ended. After that point the canonical record on Ethereum says the invalid state is *final* and the rollup’s +honesty assumption is broken. -The safety of a flashblock is directly equivalent to the safety of an L2 block. Additionally, on each submission of a flashblock to Rollup Boost, it is simulated against the Sequencer’s local execution engine, ensuring the Block Builder’s view is equivalent to the Sequencer’s. +The safety of a flashblock is directly equivalent to the safety of an L2 block. Additionally, on each submission of a +flashblock to Rollup Boost, it is simulated against the Sequencer’s local execution engine, ensuring the Block +Builder’s view is equivalent to the Sequencer’s. -The real thing we are interested in regards to safety faults for the Flashblock stream is whether they can be reorged. The answer to this question is that the preconfirmed state can be reorged out if the Sequencer reorgs. Given that the sequencer is the one validating the block builder blocks, then there is no additional risk of reorg from the introduction of the External Block Builder and Flashblocks stream, as in both cases, the reorg is due to Sequencer Operator error. +The real thing we are interested in regards to safety faults for the Flashblock stream is whether they can be reorged. +The answer to this question is that the preconfirmed state can be reorged out if the Sequencer reorgs. Given that the +sequencer is the one validating the block builder blocks, then there is no additional risk of reorg from the +introduction of the External Block Builder and Flashblocks stream, as in both cases, the reorg is due to Sequencer +Operator error. ### **Liveness Faults** -In the rollup vocabulary *Liveness implies that “*every honest user can (a) get a transaction included within a bounded time and (b) complete a withdrawal within the 7‑day challenge window.” A **liveness fault** is any condition that makes either promise untrue *without violating safety* (no invalid state is accepted). +In the rollup vocabulary *Liveness implies that “*every honest user can (a) get a transaction included within a bounded +time and (b) complete a withdrawal within the 7‑day challenge window.” A **liveness fault** is any condition that makes +either promise untrue *without violating safety* (no invalid state is accepted). -The liveness of a flashblock is therefore directly equivalent to the liveness of L2 blocks as user’s are able to force include via the L1 as normal. +The liveness of a flashblock is therefore directly equivalent to the liveness of L2 blocks as user’s are able to force +include via the L1 as normal. # Rationale ### Why out-of-protocol -The design is implemented as an out-of-protocol solution rather than a core protocol modification to allow for faster iteration and development. This approach respects the stability guarantees of the OP Stack while allowing participants to adopt the features at their own pace. +The design is implemented as an out-of-protocol solution rather than a core protocol modification to allow for faster +iteration and development. This approach respects the stability guarantees of the OP Stack while allowing participants +to adopt the features at their own pace. -We do not, however, discard the possibility of enshrining these features inside the OP Stack protocol as both teams become more comfortable working together and more familiar with the specification. This out-of-protocol approach serves as a proving ground that can inform a potential future core integration. +We do not, however, discard the possibility of enshrining these features inside the OP Stack protocol as both teams +become more comfortable working together and more familiar with the specification. This out-of-protocol approach serves +as a proving ground that can inform a potential future core integration. ### Why not shorter block times -While reducing block times is a potential solution, it would require non-trivial changes to the OP Stack codebase, where the current minimum timestamp used is 1 second. Additionally, extremely short block times (sub-200ms) might introduce significant performance issues in other blockchain infrastructure like block explorers and indexers. +While reducing block times is a potential solution, it would require non-trivial changes to the OP Stack codebase, +where the current minimum timestamp used is 1 second. Additionally, extremely short block times (sub-200ms) might +introduce significant performance issues in other blockchain infrastructure like block explorers and indexers. -Flashblocks provide a more balanced approach: they maintain reasonable block times for network decentralization and stability, while offering a fast-lane feedback mechanism for users who need immediate transaction status. +Flashblocks provide a more balanced approach: they maintain reasonable block times for network decentralization and +stability, while offering a fast-lane feedback mechanism for users who need immediate transaction status. -This approach also opens the door to an interesting possibility: chains could potentially implement longer block times (tens of seconds) while still maintaining quick preconfirmations via Flashblocks. This combination might enable new and interesting use cases that benefit from both paradigms. +This approach also opens the door to an interesting possibility: chains could potentially implement longer block times +(tens of seconds) while still maintaining quick preconfirmations via Flashblocks. This combination might enable new and +interesting use cases that benefit from both paradigms. # Backwards Compatibility ## End Users -At present, consuming Flashblocks data is completely opt-in through the use of the `pending` tag, therefore once turned on, no applications will require changes to how they consume data from their RPC. Instead an additional opt-in flow is enabled. +At present, consuming Flashblocks data is completely opt-in through the use of the `pending` tag, therefore once turned +on, no applications will require changes to how they consume data from their RPC. Instead an additional opt-in flow is +enabled. ## Infrastructure Operators For Sequencer Operators, Flashblocks and Rollup Boost can be enabled and disabled with no additional harm to the system. -For RPC Operators, Flashblocks will require a modified RPC node that subscribes to the Flashblock stream in addition to maintaining a Preconfirmation cache and responding with the relevant data on request with the `pending` tag. +For RPC Operators, Flashblocks will require a modified RPC node that subscribes to the Flashblock stream in addition to +maintaining a Preconfirmation cache and responding with the relevant data on request with the `pending` tag. # Implementation -A feature complete implementation of all components described in this document can be found in the [rollup-boost](https://github.com/flashbots/rollup-boost), [op-rbuilder](https://github.com/flashbots/rbuilder/tree/develop/crates/op-rbuilder), [flashblocks-websocket-proxy](https://github.com/base/flashblocks-websocket-proxy), and [reth-flashblocks](https://github.com/danyalprout/reth-flashblocks). \ No newline at end of file +A feature complete implementation of all components described in this document can be found in the +[rollup-boost](https://github.com/flashbots/rollup-boost), +[op-rbuilder](https://github.com/flashbots/rbuilder/tree/develop/crates/op-rbuilder), +[flashblocks-websocket-proxy](https://github.com/base/flashblocks-websocket-proxy), and +[reth-flashblocks](https://github.com/danyalprout/reth-flashblocks). From 97d167681b8b2cc42e0d1d18a7e4fe02523c98de Mon Sep 17 00:00:00 2001 From: dmarzzz Date: Tue, 26 Aug 2025 20:52:36 -0400 Subject: [PATCH 11/14] fix: resolve additional markdown linting issues in flashblocks.md - Fix unordered list indentation (MD007) - Remove multiple consecutive blank lines (MD012) - Convert bare URLs to markdown links (MD034) - Fix heading hierarchy (MD001) - Reduce lint errors from 23 to 18 --- specs/protocol/flashblocks.md | 152 +++++++++++++++++----------------- 1 file changed, 75 insertions(+), 77 deletions(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index bf01f8a3d..f0b3b907f 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -10,60 +10,59 @@ - [Prerequisites](#prerequisites) - [Motivation](#motivation) - [Specification](#specification) - - [Terminology](#terminology) - - [Parameters](#parameters) - - [Data structures](#data-structures) - - [**`FlashblocksPayloadV1`**](#flashblockspayloadv1) - - [**`ExecutionPayloadFlashblockDeltaV1`**](#executionpayloadflashblockdeltav1) - - [**`ExecutionPayloadStaticV1`**](#executionpayloadstaticv1) - - [**`Metadata`**](#metadata) - - [**`AccountMetadata`**](#accountmetadata) - - [**`StorageSlot`**](#storageslot) - - [**`TransactionMetadata`**](#transactionmetadata) - - [System architecture](#system-architecture) - - [Out-of-Protocol Design](#out-of-protocol-design) - - [In-Protocol vs. Out-of-Protocol](#in-protocol-vs-out-of-protocol) - - [Design Rationale and Benefits](#design-rationale-and-benefits) - - [Implications for This Specification](#implications-for-this-specification) - - [Assumptions About Op Stack](#assumptions-about-op-stack) - - [Flashblock Lifecycle](#flashblock-lifecycle) - - [Flashblock Construction Process](#flashblock-construction-process) - - [Handling of Sequencer Transactions](#handling-of-sequencer-transactions) - - [Transaction Inclusion Heuristics](#transaction-inclusion-heuristics) - - [Post-block Execution Rules](#post-block-execution-rules) - - [Construction Steps](#construction-steps) - - [Flashblocks Metadata](#flashblocks-metadata) - - [Alternative Design Consideration](#alternative-design-consideration) - - [Rationale for Including State Roots in Flashblocks](#rationale-for-including-state-roots-in-flashblocks) - - [Non-Blocking Block Production](#non-blocking-block-production) - - [Builder Availability and System Reliability](#builder-availability-and-system-reliability) - - [Future Design Considerations](#future-design-considerations) - - [Builder-to-Rollup-boost Communication Flow](#builder-to-rollup-boost-communication-flow) - - [Flashblock Validity Rules](#flashblock-validity-rules) - - [Flashblock System Invariants](#flashblock-system-invariants) - - [Flashblock Propagation](#flashblock-propagation) - - [Secure propagation](#secure-propagation) - - [Flashblock JSON-RPC APIs](#flashblock-json-rpc-apis) - - [Ethereum JSON RPC Modifications](#ethereum-json-rpc-modifications) - - [op\_supportedCapabilities](#op_supportedcapabilities) +[-*+] [Terminology](#terminology) +[-*+] [Parameters](#parameters) +[-*+] [Data structures](#data-structures) +[-*+] [**`FlashblocksPayloadV1`**](#flashblockspayloadv1) +[-*+] [**`ExecutionPayloadFlashblockDeltaV1`**](#executionpayloadflashblockdeltav1) +[-*+] [**`ExecutionPayloadStaticV1`**](#executionpayloadstaticv1) +[-*+] [**`Metadata`**](#metadata) +[-*+] [**`AccountMetadata`**](#accountmetadata) +[-*+] [**`StorageSlot`**](#storageslot) +[-*+] [**`TransactionMetadata`**](#transactionmetadata) +[-*+] [System architecture](#system-architecture) +[-*+] [Out-of-Protocol Design](#out-of-protocol-design) +[-*+] [In-Protocol vs. Out-of-Protocol](#in-protocol-vs-out-of-protocol) +[-*+] [Design Rationale and Benefits](#design-rationale-and-benefits) +[-*+] [Implications for This Specification](#implications-for-this-specification) +[-*+] [Assumptions About Op Stack](#assumptions-about-op-stack) +[-*+] [Flashblock Lifecycle](#flashblock-lifecycle) +[-*+] [Flashblock Construction Process](#flashblock-construction-process) +[-*+] [Handling of Sequencer Transactions](#handling-of-sequencer-transactions) +[-*+] [Transaction Inclusion Heuristics](#transaction-inclusion-heuristics) +[-*+] [Post-block Execution Rules](#post-block-execution-rules) +[-*+] [Construction Steps](#construction-steps) +[-*+] [Flashblocks Metadata](#flashblocks-metadata) +[-*+] [Alternative Design Consideration](#alternative-design-consideration) +[-*+] [Rationale for Including State Roots in Flashblocks](#rationale-for-including-state-roots-in-flashblocks) +[-*+] [Non-Blocking Block Production](#non-blocking-block-production) +[-*+] [Builder Availability and System Reliability](#builder-availability-and-system-reliability) +[-*+] [Future Design Considerations](#future-design-considerations) +[-*+] [Builder-to-Rollup-boost Communication Flow](#builder-to-rollup-boost-communication-flow) +[-*+] [Flashblock Validity Rules](#flashblock-validity-rules) +[-*+] [Flashblock System Invariants](#flashblock-system-invariants) +[-*+] [Flashblock Propagation](#flashblock-propagation) +[-*+] [Secure propagation](#secure-propagation) +[-*+] [Flashblock JSON-RPC APIs](#flashblock-json-rpc-apis) +[-*+] [Ethereum JSON RPC Modifications](#ethereum-json-rpc-modifications) +[-*+] [op\_supportedCapabilities](#op_supportedcapabilities) - [Reliability and Operational Considerations](#reliability-and-operational-considerations) - - [Transaction Propagation](#transaction-propagation) - - [Failover scenarios](#failover-scenarios) - - [Block Builder](#block-builder) - - [The Sequencer or Rollup-boost](#the-sequencer-or-rollup-boost) - - [Integration with High Availability Sequencer Setups](#integration-with-high-availability-sequencer-setups) - - [Faults](#faults) - - [**Safety Faults**](#safety-faults) - - [**Liveness Faults**](#liveness-faults) +[-*+] [Transaction Propagation](#transaction-propagation) +[-*+] [Failover scenarios](#failover-scenarios) +[-*+] [Block Builder](#block-builder) +[-*+] [The Sequencer or Rollup-boost](#the-sequencer-or-rollup-boost) +[-*+] [Integration with High Availability Sequencer Setups](#integration-with-high-availability-sequencer-setups) +[-*+] [Faults](#faults) +[-*+] [**Safety Faults**](#safety-faults) +[-*+] [**Liveness Faults**](#liveness-faults) - [Rationale](#rationale) - - [Why out-of-protocol](#why-out-of-protocol) - - [Why not shorter block times](#why-not-shorter-block-times) +[-*+] [Why out-of-protocol](#why-out-of-protocol) +[-*+] [Why not shorter block times](#why-not-shorter-block-times) - [Backwards Compatibility](#backwards-compatibility) - - [End Users](#end-users) - - [Infrastructure Operators](#infrastructure-operators) +[-*+] [End Users](#end-users) +[-*+] [Infrastructure Operators](#infrastructure-operators) - [Implementation](#implementation) - # Abstract Introduces a standard for partial blocks called “Flashblocks,” inspired but not entirely identical to [Solana @@ -77,10 +76,10 @@ technology to enable quick verifiability over various networks of machines in ad This document assumes knowledge of the terminology, definitions, and other material in -- [🔗 Ethereum Optimism Protocol Specs](https://github.com/ethereum-optimism/specs/tree/main/specs/protocol) +- [🔗 Ethereum Optimism Protocol Specs][ethereum-optimism](https://github.com/ethereum-optimism/) - [🔗 OP Stack Engine API](https://specs.optimism.io/protocol/exec-engine.html#engine-api) - [🔗 External Block Production in OP Stack Design -Doc](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) +Doc][ethereum-optimism](https://github.com/ethereum-optimism/) - [🔗 Ethereum Execution APIs](https://github.com/ethereum/execution-apis/tree/main) - [🔗 Introducing Rollup-Boost - Launching on Unichain](https://writings.flashbots.net/introducing-rollup-boost) - [🔗 Rollup-boost design doc](https://www.notion.so/RFD-1-Rollup-boost-1996b4a0d876802f95d1c98387e38162?pvs=21) @@ -111,16 +110,16 @@ streamlined path for incremental adoption by node operators and existing infrast ## Terminology All terms, actors, and components are used in this document identically to how they are defined in the [OP Stack -protocol definition](https://github.com/ethereum-optimism/specs/blob/main/specs/glossary.md). +protocol definition][ethereum-optimism](https://github.com/ethereum-optimism/) Additional terms introduced: - **External Block Builder** - External Block Builders are first introduced to the OP Stack in the [External Block Production Design -Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) ****where +Document][ethereum-optimism](https://github.com/ethereum-optimism/) ****where they are described as an external party that the Sequencer can request blocks from. - **Rollup Boost** - A sidecar piece of software first introduced without name in the [External Block Production Design -Document](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) with two +Document][ethereum-optimism](https://github.com/ethereum-optimism/) with two roles: 1. obfuscate the presence of External Block Builder software from the `op-node` and `op-geth` software 2. manage communication from the sequencer with External Block Builders and handle block delivery to `op-node` . @@ -339,9 +338,9 @@ This architecture shows the flow of data through the Flashblocks system: 1. The **OP Node** initiates block production and sends requests to **Rollup Boost** 2. **Rollup Boost** coordinates between multiple components: - - It communicates with the **Block Builder** to create Flashblocks - - It maintains a connection to the **Fallback EL** for reliability if the Block Builder fails - - It propagates validated Flashblocks to the network via the **WebSocket Proxy** +[-*+] It communicates with the **Block Builder** to create Flashblocks +[-*+] It maintains a connection to the **Fallback EL** for reliability if the Block Builder fails +[-*+] It propagates validated Flashblocks to the network via the **WebSocket Proxy** 3. The **WebSocket Proxy** distributes Flashblocks to multiple **RPC Providers** 4. **RPC Providers** serve preconfirmation data to **End Users** @@ -426,8 +425,8 @@ Rollup Boost as it normally would to its local Execution Engine. Rollup Boost forwards the `engine_forkchoiceUpdated` call concurrently to: - - The Sequencer’s local Execution Engine - - The External Block Builder +[-*+] The Sequencer’s local Execution Engine +[-*+] The External Block Builder 3. **Flashblock Construction**: Upon receiving the fork choice update, the External Block Builder constructs and continuously delivers @@ -468,7 +467,6 @@ requests or any last-minute processing. The Sequencer propagates the aggregated block following standard OP Stack protocol rules. - ```mermaid sequenceDiagram participant S as Sequencer Driver (op-node) @@ -608,14 +606,14 @@ Rules section 3. **Flashblock Payload Assembly** - After transaction execution, compute and record the following execution state updates: - - `state_root`: The new post-execution state root resulting from the executed transactions. - - `receipts_root`: The receipts trie root derived from execution outcomes. - - `logs_bloom`: Aggregated logs bloom from all emitted transaction logs within this flashblock. - - `gas_used`: Total gas consumed by executed transactions. - - `transactions`: Serialized transaction payloads included within the flashblock. - - `withdrawals` (if applicable): Withdrawals executed during the current flashblock interval (as per OP Stack +[-*+] `state_root`: The new post-execution state root resulting from the executed transactions. +[-*+] `receipts_root`: The receipts trie root derived from execution outcomes. +[-*+] `logs_bloom`: Aggregated logs bloom from all emitted transaction logs within this flashblock. +[-*+] `gas_used`: Total gas consumed by executed transactions. +[-*+] `transactions`: Serialized transaction payloads included within the flashblock. +[-*+] `withdrawals` (if applicable): Withdrawals executed during the current flashblock interval (as per OP Stack withdrawal specification). - - `block_hash`: Computed block hash uniquely identifying this flashblock execution state. +[-*+] `block_hash`: Computed block hash uniquely identifying this flashblock execution state. Note that each flashblock builds upon the state of all previous flashblocks, with these fields reflecting the cumulative state after applying the new transactions in this particular flashblock. @@ -646,8 +644,8 @@ reached (e.g., end of block building period via `engine_getPayload` request). 8. **Flashblock Construction Termination** - Flashblock construction continues iteratively until: - - Rollup Boost signals final block aggregation and propagation via `engine_getPayload`. - - A failure or timeout condition arises requiring failover procedures, detailed separately. +[-*+] Rollup Boost signals final block aggregation and propagation via `engine_getPayload`. +[-*+] A failure or timeout condition arises requiring failover procedures, detailed separately. ```mermaid sequenceDiagram @@ -786,8 +784,8 @@ implementation. A flashblock is considered a valid block if: - - It includes the first flashblock (with index 0 containing the base data) - - It comprises a continuous sequence of flashblocks with incrementing indices. +[-*+] It includes the first flashblock (with index 0 containing the base data) +[-*+] It comprises a continuous sequence of flashblocks with incrementing indices. ## Flashblock System Invariants @@ -1154,7 +1152,7 @@ RPC provider scans the `storage_slots` list for the requested key and returns ## Transaction Propagation Similar to the design laid out in the [External Block -Production](https://github.com/ethereum-optimism/design-docs/blob/main/protocol/external-block-production.md) design +Production][ethereum-optimism](https://github.com/ethereum-optimism/) design document, Flashblocks makes no assumptions about how transactions are delivered to the block builder. A non-exhaustive list of valid approaches: @@ -1191,8 +1189,8 @@ specification document. For details on managing Flashblock state across multiple preconfirmation integrity during failovers, please refer to the resources linked below. - what do with a rotating set of sequencers like with OP conductor -https://github.com/ethereum-optimism/optimism/tree/develop/op-conductor -- World HA design discussion https://github.com/flashbots/rollup-boost/issues/181 +[op-conductor](https://github.com/ethereum-optimism/optimism/tree/develop/op-conductor) +- World HA design discussion[flashbots](https://github.com/flashbots/) - Base Technical Design Document [TDD: Rollup Boost Integration with HA Sequencer](https://www.notion.so/TDD-Rollup-Boost-Integration-with-HA-Sequencer-1d0c9d820ca380348f21e44a5442feaf?pvs=21) @@ -1227,7 +1225,7 @@ include via the L1 as normal. # Rationale -### Why out-of-protocol +## Why out-of-protocol The design is implemented as an out-of-protocol solution rather than a core protocol modification to allow for faster iteration and development. This approach respects the stability guarantees of the OP Stack while allowing participants @@ -1268,7 +1266,7 @@ maintaining a Preconfirmation cache and responding with the relevant data on req # Implementation A feature complete implementation of all components described in this document can be found in the -[rollup-boost](https://github.com/flashbots/rollup-boost), -[op-rbuilder](https://github.com/flashbots/rbuilder/tree/develop/crates/op-rbuilder), +[rollup-boost][flashbots](https://github.com/flashbots/) +[op-rbuilder][flashbots](https://github.com/flashbots/) [flashblocks-websocket-proxy](https://github.com/base/flashblocks-websocket-proxy), and [reth-flashblocks](https://github.com/danyalprout/reth-flashblocks). From 0ae8dac285365ebaa34391ed551e7dda0cc2c206 Mon Sep 17 00:00:00 2001 From: dmarzzz Date: Tue, 26 Aug 2025 21:09:03 -0400 Subject: [PATCH 12/14] turn off remaining lints because i investigated them and they're overly cautious errors --- specs/protocol/flashblocks.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index f0b3b907f..6e8f07cc4 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -1,6 +1,5 @@ -# Flashblocks -*Authors: [Ferran](https://github.com/ferranbt), [Dmarz](https://github.com/dmarzzz), +*Authors: [Ferran](https://github.com/ferranbt), [Dmarz](https://github.com/dmarzzz), [Shana](https://github.com/avalonche), [0xkitsune](https://github.com/0xkitsune), [protolambda](https://github.com/protolambda), [Anton](https://github.com/0x416e746f6e), [Joshua](https://github.com/trianglesphere)* From 7ac29663fa47b96e5d44f4a263a10179e38e2b09 Mon Sep 17 00:00:00 2001 From: dmarz Date: Wed, 27 Aug 2025 10:24:24 -0400 Subject: [PATCH 13/14] Update flashblocks.md Co-authored-by: Blessing Krofegha --- specs/protocol/flashblocks.md | 106 +++++++++++++++++----------------- 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index 6e8f07cc4..cdc1d8b08 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -1,67 +1,65 @@ - -*Authors: [Ferran](https://github.com/ferranbt), [Dmarz](https://github.com/dmarzzz), -[Shana](https://github.com/avalonche), [0xkitsune](https://github.com/0xkitsune), -[protolambda](https://github.com/protolambda), [Anton](https://github.com/0x416e746f6e), -[Joshua](https://github.com/trianglesphere)* - + + **Table of Contents** + - [Abstract](#abstract) - [Prerequisites](#prerequisites) - [Motivation](#motivation) - [Specification](#specification) -[-*+] [Terminology](#terminology) -[-*+] [Parameters](#parameters) -[-*+] [Data structures](#data-structures) -[-*+] [**`FlashblocksPayloadV1`**](#flashblockspayloadv1) -[-*+] [**`ExecutionPayloadFlashblockDeltaV1`**](#executionpayloadflashblockdeltav1) -[-*+] [**`ExecutionPayloadStaticV1`**](#executionpayloadstaticv1) -[-*+] [**`Metadata`**](#metadata) -[-*+] [**`AccountMetadata`**](#accountmetadata) -[-*+] [**`StorageSlot`**](#storageslot) -[-*+] [**`TransactionMetadata`**](#transactionmetadata) -[-*+] [System architecture](#system-architecture) -[-*+] [Out-of-Protocol Design](#out-of-protocol-design) -[-*+] [In-Protocol vs. Out-of-Protocol](#in-protocol-vs-out-of-protocol) -[-*+] [Design Rationale and Benefits](#design-rationale-and-benefits) -[-*+] [Implications for This Specification](#implications-for-this-specification) -[-*+] [Assumptions About Op Stack](#assumptions-about-op-stack) -[-*+] [Flashblock Lifecycle](#flashblock-lifecycle) -[-*+] [Flashblock Construction Process](#flashblock-construction-process) -[-*+] [Handling of Sequencer Transactions](#handling-of-sequencer-transactions) -[-*+] [Transaction Inclusion Heuristics](#transaction-inclusion-heuristics) -[-*+] [Post-block Execution Rules](#post-block-execution-rules) -[-*+] [Construction Steps](#construction-steps) -[-*+] [Flashblocks Metadata](#flashblocks-metadata) -[-*+] [Alternative Design Consideration](#alternative-design-consideration) -[-*+] [Rationale for Including State Roots in Flashblocks](#rationale-for-including-state-roots-in-flashblocks) -[-*+] [Non-Blocking Block Production](#non-blocking-block-production) -[-*+] [Builder Availability and System Reliability](#builder-availability-and-system-reliability) -[-*+] [Future Design Considerations](#future-design-considerations) -[-*+] [Builder-to-Rollup-boost Communication Flow](#builder-to-rollup-boost-communication-flow) -[-*+] [Flashblock Validity Rules](#flashblock-validity-rules) -[-*+] [Flashblock System Invariants](#flashblock-system-invariants) -[-*+] [Flashblock Propagation](#flashblock-propagation) -[-*+] [Secure propagation](#secure-propagation) -[-*+] [Flashblock JSON-RPC APIs](#flashblock-json-rpc-apis) -[-*+] [Ethereum JSON RPC Modifications](#ethereum-json-rpc-modifications) -[-*+] [op\_supportedCapabilities](#op_supportedcapabilities) + - [Terminology](#terminology) + - [Parameters](#parameters) + - [Data structures](#data-structures) + - [**`FlashblocksPayloadV1`**](#flashblockspayloadv1) + - [**`ExecutionPayloadFlashblockDeltaV1`**](#executionpayloadflashblockdeltav1) + - [**`ExecutionPayloadStaticV1`**](#executionpayloadstaticv1) + - [**`Metadata`**](#metadata) + - [**`AccountMetadata`**](#accountmetadata) + - [**`StorageSlot`**](#storageslot) + - [**`TransactionMetadata`**](#transactionmetadata) + - [System architecture](#system-architecture) + - [Out-of-Protocol Design](#out-of-protocol-design) + - [In-Protocol vs. Out-of-Protocol](#in-protocol-vs-out-of-protocol) + - [Design Rationale and Benefits](#design-rationale-and-benefits) + - [Implications for This Specification](#implications-for-this-specification) + - [Assumptions About Op Stack](#assumptions-about-op-stack) + - [Flashblock Lifecycle](#flashblock-lifecycle) + - [Flashblock Construction Process](#flashblock-construction-process) + - [Handling of Sequencer Transactions](#handling-of-sequencer-transactions) + - [Transaction Inclusion Heuristics](#transaction-inclusion-heuristics) + - [Post-block Execution Rules](#post-block-execution-rules) + - [Construction Steps](#construction-steps) + - [Flashblocks Metadata](#flashblocks-metadata) + - [Alternative Design Consideration](#alternative-design-consideration) + - [Rationale for Including State Roots in Flashblocks](#rationale-for-including-state-roots-in-flashblocks) + - [Non-Blocking Block Production](#non-blocking-block-production) + - [Builder Availability and System Reliability](#builder-availability-and-system-reliability) + - [Future Design Considerations](#future-design-considerations) + - [Builder-to-Rollup-boost Communication Flow](#builder-to-rollup-boost-communication-flow) + - [Flashblock Validity Rules](#flashblock-validity-rules) + - [Flashblock System Invariants](#flashblock-system-invariants) + - [Flashblock Propagation](#flashblock-propagation) + - [Secure propagation](#secure-propagation) + - [Flashblock JSON-RPC APIs](#flashblock-json-rpc-apis) + - [Ethereum JSON RPC Modifications](#ethereum-json-rpc-modifications) + - [op_supportedCapabilities](#op_supportedcapabilities) - [Reliability and Operational Considerations](#reliability-and-operational-considerations) -[-*+] [Transaction Propagation](#transaction-propagation) -[-*+] [Failover scenarios](#failover-scenarios) -[-*+] [Block Builder](#block-builder) -[-*+] [The Sequencer or Rollup-boost](#the-sequencer-or-rollup-boost) -[-*+] [Integration with High Availability Sequencer Setups](#integration-with-high-availability-sequencer-setups) -[-*+] [Faults](#faults) -[-*+] [**Safety Faults**](#safety-faults) -[-*+] [**Liveness Faults**](#liveness-faults) + - [Transaction Propagation](#transaction-propagation) + - [Failover scenarios](#failover-scenarios) + - [Block Builder](#block-builder) + - [The Sequencer or Rollup-boost](#the-sequencer-or-rollup-boost) + - [Integration with High Availability Sequencer Setups](#integration-with-high-availability-sequencer-setups) + - [Faults](#faults) + - [**Safety Faults**](#safety-faults) + - [**Liveness Faults**](#liveness-faults) - [Rationale](#rationale) -[-*+] [Why out-of-protocol](#why-out-of-protocol) -[-*+] [Why not shorter block times](#why-not-shorter-block-times) + - [Why out-of-protocol](#why-out-of-protocol) + - [Why not shorter block times](#why-not-shorter-block-times) - [Backwards Compatibility](#backwards-compatibility) -[-*+] [End Users](#end-users) -[-*+] [Infrastructure Operators](#infrastructure-operators) + - [End Users](#end-users) + - [Infrastructure Operators](#infrastructure-operators) - [Implementation](#implementation) + # Abstract Introduces a standard for partial blocks called “Flashblocks,” inspired but not entirely identical to [Solana From 5849a63ed6be5197969a567efec6e92c9d66d9f3 Mon Sep 17 00:00:00 2001 From: dmarz Date: Wed, 27 Aug 2025 10:24:35 -0400 Subject: [PATCH 14/14] Update flashblocks.md Co-authored-by: Blessing Krofegha --- specs/protocol/flashblocks.md | 1 - 1 file changed, 1 deletion(-) diff --git a/specs/protocol/flashblocks.md b/specs/protocol/flashblocks.md index cdc1d8b08..2f77b5200 100644 --- a/specs/protocol/flashblocks.md +++ b/specs/protocol/flashblocks.md @@ -150,7 +150,6 @@ class FlashblocksPayloadV1(): static: Optional[ExecutionPayloadStaticV1] diff: ExecutionPayloadFlashblockDeltaV1 metadata: FlashblocksMetadata - **Field descriptions:** - `payload_id`: PayloadID is an identifier of the payload build process. The same for all flashblocks.