Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -523,11 +523,11 @@ alloy-transport-ws = { version = "1.0.41", default-features = false }
# op
alloy-op-evm = { version = "0.23.0", default-features = false }
alloy-op-hardforks = "0.4.4"
op-alloy-rpc-types = { version = "0.22.0", default-features = false }
op-alloy-rpc-types-engine = { version = "0.22.0", default-features = false }
op-alloy-network = { version = "0.22.0", default-features = false }
op-alloy-consensus = { version = "0.22.0", default-features = false }
op-alloy-rpc-jsonrpsee = { version = "0.22.0", default-features = false }
op-alloy-rpc-types = { version = "0.22.1", default-features = false }
op-alloy-rpc-types-engine = { version = "0.22.1", default-features = false }
op-alloy-network = { version = "0.22.1", default-features = false }
op-alloy-consensus = { version = "0.22.1", default-features = false }
op-alloy-rpc-jsonrpsee = { version = "0.22.1", default-features = false }
op-alloy-flz = { version = "0.13.1", default-features = false }

# misc
Expand Down
14 changes: 14 additions & 0 deletions crates/optimism/evm/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub use alloy_op_evm::{
spec as revm_spec, spec_by_timestamp_after_bedrock as revm_spec_by_timestamp_after_bedrock,
};
use op_alloy_rpc_types_engine::OpFlashblockPayloadBase;
use revm::primitives::{Address, Bytes, B256};

/// Context relevant for execution of a next block w.r.t OP.
Expand Down Expand Up @@ -35,3 +36,16 @@ impl<H: alloy_consensus::BlockHeader> reth_rpc_eth_api::helpers::pending_block::
}
}
}

impl From<OpFlashblockPayloadBase> for OpNextBlockEnvAttributes {
fn from(base: OpFlashblockPayloadBase) -> Self {
Self {
timestamp: base.timestamp,
suggested_fee_recipient: base.fee_recipient,
prev_randao: base.prev_randao,
gas_limit: base.gas_limit,
parent_beacon_block_root: Some(base.parent_beacon_block_root),
extra_data: base.extra_data,
}
}
}
6 changes: 3 additions & 3 deletions crates/optimism/flashblocks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ workspace = true
[dependencies]
# reth
reth-optimism-primitives = { workspace = true, features = ["serde"] }
reth-optimism-evm.workspace = true
reth-chain-state = { workspace = true, features = ["serde"] }
reth-primitives-traits = { workspace = true, features = ["serde"] }
reth-engine-primitives = { workspace = true, features = ["std"] }
Expand All @@ -30,15 +29,16 @@ reth-metrics.workspace = true

# alloy
alloy-eips = { workspace = true, features = ["serde"] }
alloy-serde.workspace = true
alloy-primitives = { workspace = true, features = ["serde"] }
alloy-rpc-types-engine = { workspace = true, features = ["serde"] }
alloy-consensus.workspace = true

# op-alloy
op-alloy-rpc-types-engine.workspace = true

# io
tokio.workspace = true
tokio-tungstenite = { workspace = true, features = ["rustls-tls-native-roots"] }
serde.workspace = true
serde_json.workspace = true
url.workspace = true
futures-util.workspace = true
Expand Down
16 changes: 9 additions & 7 deletions crates/optimism/flashblocks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,25 @@
use reth_primitives_traits::NodePrimitives;
use std::sync::Arc;

pub use payload::{
ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1, FlashBlock, FlashBlockDecoder,
Metadata,
};
pub use service::{FlashBlockBuildInfo, FlashBlockService};
pub use ws::{WsConnect, WsFlashBlockStream};
// Included to enable serde feature for OpReceipt type used transitively
use reth_optimism_primitives as _;

mod consensus;
pub use consensus::FlashBlockConsensusClient;

mod payload;
pub use payload::PendingFlashBlock;
pub use payload::{FlashBlock, PendingFlashBlock};

mod sequence;
pub use sequence::{FlashBlockCompleteSequence, FlashBlockPendingSequence};

mod service;
pub use service::{FlashBlockBuildInfo, FlashBlockService};

mod worker;

mod ws;
pub use ws::{WsConnect, WsFlashBlockStream};

/// Receiver of the most recent [`PendingFlashBlock`] built out of [`FlashBlock`]s.
///
Expand Down
149 changes: 3 additions & 146 deletions crates/optimism/flashblocks/src/payload.rs
Original file line number Diff line number Diff line change
@@ -1,154 +1,11 @@
use alloy_consensus::BlockHeader;
use alloy_eips::eip4895::Withdrawal;
use alloy_primitives::{bytes, Address, Bloom, Bytes, B256, U256};
use alloy_rpc_types_engine::PayloadId;
use alloy_primitives::B256;
use derive_more::Deref;
use reth_optimism_evm::OpNextBlockEnvAttributes;
use reth_optimism_primitives::OpReceipt;
use reth_primitives_traits::NodePrimitives;
use reth_rpc_eth_types::PendingBlock;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;

/// Represents a Flashblock, a real-time block-like structure emitted by the Base L2 chain.
///
/// A Flashblock provides a snapshot of a block’s effects before finalization,
/// allowing faster insight into state transitions, balance changes, and logs.
/// It includes a diff of the block’s execution and associated metadata.
///
/// See: [Base Flashblocks Documentation](https://docs.base.org/chain/flashblocks)
#[derive(Default, Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct FlashBlock {
/// The unique payload ID as assigned by the execution engine for this block.
pub payload_id: PayloadId,
/// A sequential index that identifies the order of this Flashblock.
pub index: u64,
/// A subset of block header fields.
pub base: Option<ExecutionPayloadBaseV1>,
/// The execution diff representing state transitions and transactions.
pub diff: ExecutionPayloadFlashblockDeltaV1,
/// Additional metadata about the block such as receipts and balances.
pub metadata: Metadata,
}

impl FlashBlock {
/// Returns the block number of this flashblock.
pub const fn block_number(&self) -> u64 {
self.metadata.block_number
}

/// Returns the first parent hash of this flashblock.
pub fn parent_hash(&self) -> Option<B256> {
Some(self.base.as_ref()?.parent_hash)
}

/// Returns the receipt for the given transaction hash.
pub fn receipt_by_hash(&self, hash: &B256) -> Option<&OpReceipt> {
self.metadata.receipt_by_hash(hash)
}
}

/// A trait for decoding flashblocks from bytes.
pub trait FlashBlockDecoder: Send + 'static {
/// Decodes `bytes` into a [`FlashBlock`].
fn decode(&self, bytes: bytes::Bytes) -> eyre::Result<FlashBlock>;
}

/// Default implementation of the decoder.
impl FlashBlockDecoder for () {
fn decode(&self, bytes: bytes::Bytes) -> eyre::Result<FlashBlock> {
FlashBlock::decode(bytes)
}
}

/// Provides metadata about the block that may be useful for indexing or analysis.
// Note: this uses mixed camel, snake case: <https://github.com/flashbots/rollup-boost/blob/dd12e8e8366004b4758bfa0cfa98efa6929b7e9f/crates/flashblocks-rpc/src/cache.rs#L31>
#[derive(Default, Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Metadata {
/// The number of the block in the L2 chain.
pub block_number: u64,
/// A map of addresses to their updated balances after the block execution.
/// This represents balance changes due to transactions, rewards, or system transfers.
pub new_account_balances: BTreeMap<Address, U256>,
/// Execution receipts for all transactions in the block.
/// Contains logs, gas usage, and other EVM-level metadata.
pub receipts: BTreeMap<B256, OpReceipt>,
}

impl Metadata {
/// Returns the receipt for the given transaction hash.
pub fn receipt_by_hash(&self, hash: &B256) -> Option<&OpReceipt> {
self.receipts.get(hash)
}
}

/// Represents the base configuration of an execution payload that remains constant
/// throughout block construction. This includes fundamental block properties like
/// parent hash, block number, and other header fields that are determined at
/// block creation and cannot be modified.
#[derive(Clone, Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
pub struct ExecutionPayloadBaseV1 {
/// Ecotone parent beacon block root
pub parent_beacon_block_root: B256,
/// The parent hash of the block.
pub parent_hash: B256,
/// The fee recipient of the block.
pub fee_recipient: Address,
/// The previous randao of the block.
pub prev_randao: B256,
/// The block number.
#[serde(with = "alloy_serde::quantity")]
pub block_number: u64,
/// The gas limit of the block.
#[serde(with = "alloy_serde::quantity")]
pub gas_limit: u64,
/// The timestamp of the block.
#[serde(with = "alloy_serde::quantity")]
pub timestamp: u64,
/// The extra data of the block.
pub extra_data: Bytes,
/// The base fee per gas of the block.
pub base_fee_per_gas: U256,
}

/// Represents the modified portions of an execution payload within a flashblock.
/// This structure contains only the fields that can be updated during block construction,
/// such as state root, receipts, logs, and new transactions. Other immutable block fields
/// like parent hash and block number are excluded since they remain constant throughout
/// the block's construction.
#[derive(Clone, Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
pub struct ExecutionPayloadFlashblockDeltaV1 {
/// The state root of the block.
pub state_root: B256,
/// The receipts root of the block.
pub receipts_root: B256,
/// The logs bloom of the block.
pub logs_bloom: Bloom,
/// The gas used of the block.
#[serde(with = "alloy_serde::quantity")]
pub gas_used: u64,
/// The block hash of the block.
pub block_hash: B256,
/// The transactions of the block.
pub transactions: Vec<Bytes>,
/// Array of [`Withdrawal`] enabled with V2
pub withdrawals: Vec<Withdrawal>,
/// The withdrawals root of the block.
pub withdrawals_root: B256,
}

impl From<ExecutionPayloadBaseV1> for OpNextBlockEnvAttributes {
fn from(value: ExecutionPayloadBaseV1) -> Self {
Self {
timestamp: value.timestamp,
suggested_fee_recipient: value.fee_recipient,
prev_randao: value.prev_randao,
gas_limit: value.gas_limit,
parent_beacon_block_root: Some(value.parent_beacon_block_root),
extra_data: value.extra_data,
}
}
}
/// Type alias for the Optimism flashblock payload.
pub type FlashBlock = op_alloy_rpc_types_engine::OpFlashblockPayload;

/// The pending block built with all received Flashblocks alongside the metadata for the last added
/// Flashblock.
Expand Down
Loading
Loading