reth_optimism_flashblocks/
payload.rs

1use alloy_eips::eip4895::Withdrawal;
2use alloy_primitives::{Address, Bloom, Bytes, B256, U256};
3use alloy_rpc_types_engine::PayloadId;
4use reth_optimism_evm::OpNextBlockEnvAttributes;
5use reth_optimism_primitives::OpReceipt;
6use serde::{Deserialize, Serialize};
7use std::collections::BTreeMap;
8
9/// Represents a Flashblock, a real-time block-like structure emitted by the Base L2 chain.
10///
11/// A Flashblock provides a snapshot of a block’s effects before finalization,
12/// allowing faster insight into state transitions, balance changes, and logs.
13/// It includes a diff of the block’s execution and associated metadata.
14///
15/// See: [Base Flashblocks Documentation](https://docs.base.org/chain/flashblocks)
16#[derive(Default, Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
17pub struct FlashBlock {
18    /// The unique payload ID as assigned by the execution engine for this block.
19    pub payload_id: PayloadId,
20    /// A sequential index that identifies the order of this Flashblock.
21    pub index: u64,
22    /// A subset of block header fields.
23    pub base: Option<ExecutionPayloadBaseV1>,
24    /// The execution diff representing state transitions and transactions.
25    pub diff: ExecutionPayloadFlashblockDeltaV1,
26    /// Additional metadata about the block such as receipts and balances.
27    pub metadata: Metadata,
28}
29
30impl FlashBlock {
31    /// Returns the block number of this flashblock.
32    pub const fn block_number(&self) -> u64 {
33        self.metadata.block_number
34    }
35
36    /// Returns the first parent hash of this flashblock.
37    pub fn parent_hash(&self) -> Option<B256> {
38        Some(self.base.as_ref()?.parent_hash)
39    }
40}
41
42/// Provides metadata about the block that may be useful for indexing or analysis.
43#[derive(Default, Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
44pub struct Metadata {
45    /// The number of the block in the L2 chain.
46    pub block_number: u64,
47    /// A map of addresses to their updated balances after the block execution.
48    /// This represents balance changes due to transactions, rewards, or system transfers.
49    pub new_account_balances: BTreeMap<Address, U256>,
50    /// Execution receipts for all transactions in the block.
51    /// Contains logs, gas usage, and other EVM-level metadata.
52    pub receipts: BTreeMap<B256, OpReceipt>,
53}
54
55/// Represents the base configuration of an execution payload that remains constant
56/// throughout block construction. This includes fundamental block properties like
57/// parent hash, block number, and other header fields that are determined at
58/// block creation and cannot be modified.
59#[derive(Clone, Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
60pub struct ExecutionPayloadBaseV1 {
61    /// Ecotone parent beacon block root
62    pub parent_beacon_block_root: B256,
63    /// The parent hash of the block.
64    pub parent_hash: B256,
65    /// The fee recipient of the block.
66    pub fee_recipient: Address,
67    /// The previous randao of the block.
68    pub prev_randao: B256,
69    /// The block number.
70    #[serde(with = "alloy_serde::quantity")]
71    pub block_number: u64,
72    /// The gas limit of the block.
73    #[serde(with = "alloy_serde::quantity")]
74    pub gas_limit: u64,
75    /// The timestamp of the block.
76    #[serde(with = "alloy_serde::quantity")]
77    pub timestamp: u64,
78    /// The extra data of the block.
79    pub extra_data: Bytes,
80    /// The base fee per gas of the block.
81    pub base_fee_per_gas: U256,
82}
83
84/// Represents the modified portions of an execution payload within a flashblock.
85/// This structure contains only the fields that can be updated during block construction,
86/// such as state root, receipts, logs, and new transactions. Other immutable block fields
87/// like parent hash and block number are excluded since they remain constant throughout
88/// the block's construction.
89#[derive(Clone, Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
90pub struct ExecutionPayloadFlashblockDeltaV1 {
91    /// The state root of the block.
92    pub state_root: B256,
93    /// The receipts root of the block.
94    pub receipts_root: B256,
95    /// The logs bloom of the block.
96    pub logs_bloom: Bloom,
97    /// The gas used of the block.
98    #[serde(with = "alloy_serde::quantity")]
99    pub gas_used: u64,
100    /// The block hash of the block.
101    pub block_hash: B256,
102    /// The transactions of the block.
103    pub transactions: Vec<Bytes>,
104    /// Array of [`Withdrawal`] enabled with V2
105    pub withdrawals: Vec<Withdrawal>,
106    /// The withdrawals root of the block.
107    pub withdrawals_root: B256,
108}
109
110impl From<ExecutionPayloadBaseV1> for OpNextBlockEnvAttributes {
111    fn from(value: ExecutionPayloadBaseV1) -> Self {
112        Self {
113            timestamp: value.timestamp,
114            suggested_fee_recipient: value.fee_recipient,
115            prev_randao: value.prev_randao,
116            gas_limit: value.gas_limit,
117            parent_beacon_block_root: Some(value.parent_beacon_block_root),
118            extra_data: value.extra_data,
119        }
120    }
121}