Skip to main content

pathfinder_common/
l2.rs

1use std::collections::BTreeMap;
2use std::sync::{Arc, RwLock};
3
4use fake::Dummy;
5
6use crate::class_definition::{SerializedCasmDefinition, SerializedSierraDefinition};
7use crate::event::Event;
8use crate::receipt::Receipt;
9use crate::state_update::StateUpdateData;
10use crate::transaction::Transaction;
11use crate::{
12    BlockHash,
13    BlockHeader,
14    BlockNumber,
15    BlockTimestamp,
16    CasmHash,
17    EventCommitment,
18    GasPrice,
19    L1DataAvailabilityMode,
20    ReceiptCommitment,
21    SequencerAddress,
22    SierraHash,
23    StarknetVersion,
24    StateCommitment,
25    StateDiffCommitment,
26    TransactionCommitment,
27};
28
29pub enum L2BlockToCommit {
30    FromConsensus(ConsensusFinalizedL2Block),
31    FromFgw(L2Block),
32}
33
34#[derive(Clone, Debug, Default)]
35pub struct L2Block {
36    pub header: BlockHeader,
37    pub state_update: StateUpdateData,
38    pub transactions_and_receipts: Vec<(Transaction, Receipt)>,
39    pub events: Vec<Vec<Event>>,
40}
41
42/// [`ConsensusFinalizedL2Block`] which also includes the round in which it was
43/// decided upon.
44#[derive(Clone, Debug)]
45pub struct DecidedBlock {
46    pub round: u32,
47    pub block: ConsensusFinalizedL2Block,
48}
49
50/// A type alias for a `Sync` collection of [`DecidedBlock`]-s
51pub type DecidedBlocks = Arc<RwLock<BTreeMap<BlockNumber, DecidedBlock>>>;
52
53/// An [L2Block] that is the result of executing a consensus proposal. The only
54/// differences from an [L2Block] are:
55/// - the state tries have not been updated yet,
56/// - in consequence the block hash could not have been computed yet.
57#[derive(Clone, Debug, Default)]
58pub struct ConsensusFinalizedL2Block {
59    pub header: ConsensusFinalizedBlockHeader,
60    pub state_update: StateUpdateData,
61    pub transactions_and_receipts: Vec<(Transaction, Receipt)>,
62    pub events: Vec<Vec<Event>>,
63    pub declared_classes: Vec<DeclaredClass>,
64}
65
66/// An L2 [BlockHeader] that is the result of executing a consensus proposal
67/// that was decided upon. The only differences from a [BlockHeader] are:
68/// - the state tries have not been updated yet, so the state commitment is
69///   missing,
70/// - in consequence the block hash could not have been computed yet,
71/// - parent hash is updated when the header is transformed into a full
72///   [BlockHeader] to avoid additional DB lookup in consensus.
73
74#[derive(Debug, Clone, Default, PartialEq, Eq, Dummy)]
75pub struct ConsensusFinalizedBlockHeader {
76    pub number: BlockNumber,
77    pub timestamp: BlockTimestamp,
78    pub eth_l1_gas_price: GasPrice,
79    pub strk_l1_gas_price: GasPrice,
80    pub eth_l1_data_gas_price: GasPrice,
81    pub strk_l1_data_gas_price: GasPrice,
82    pub eth_l2_gas_price: GasPrice,
83    pub strk_l2_gas_price: GasPrice,
84    pub sequencer_address: SequencerAddress,
85    pub starknet_version: StarknetVersion,
86    pub event_commitment: EventCommitment,
87    pub transaction_commitment: TransactionCommitment,
88    pub transaction_count: usize,
89    pub event_count: usize,
90    pub l1_da_mode: L1DataAvailabilityMode,
91    pub receipt_commitment: ReceiptCommitment,
92    pub state_diff_commitment: StateDiffCommitment,
93    pub state_diff_length: u64,
94    pub l2_gas_consumed: u128,
95}
96
97#[derive(Clone, Debug, Default)]
98pub struct DeclaredClass {
99    pub sierra_hash: SierraHash,
100    pub casm_hash_v2: CasmHash,
101    pub sierra_def: SerializedSierraDefinition,
102    pub casm_def: SerializedCasmDefinition,
103}
104
105impl From<L2Block> for L2BlockToCommit {
106    fn from(block: L2Block) -> Self {
107        L2BlockToCommit::FromFgw(block)
108    }
109}
110
111impl From<ConsensusFinalizedL2Block> for L2BlockToCommit {
112    fn from(block: ConsensusFinalizedL2Block) -> Self {
113        L2BlockToCommit::FromConsensus(block)
114    }
115}
116
117impl L2BlockToCommit {
118    pub fn number(&self) -> BlockNumber {
119        match self {
120            L2BlockToCommit::FromConsensus(block) => block.header.number,
121            L2BlockToCommit::FromFgw(block) => block.header.number,
122        }
123    }
124
125    pub fn state_commitment(&self) -> Option<StateCommitment> {
126        match self {
127            L2BlockToCommit::FromConsensus(_) => None,
128            L2BlockToCommit::FromFgw(block) => Some(block.header.state_commitment),
129        }
130    }
131
132    pub fn state_update(&self) -> &StateUpdateData {
133        match self {
134            L2BlockToCommit::FromConsensus(block) => &block.state_update,
135            L2BlockToCommit::FromFgw(block) => &block.state_update,
136        }
137    }
138
139    pub fn starknet_version(&self) -> StarknetVersion {
140        match self {
141            L2BlockToCommit::FromConsensus(block) => block.header.starknet_version,
142            L2BlockToCommit::FromFgw(block) => block.header.starknet_version,
143        }
144    }
145}
146
147impl ConsensusFinalizedBlockHeader {
148    pub fn compute_hash(
149        self,
150        parent_hash: BlockHash,
151        state_commitment: StateCommitment,
152        block_hash_fn: impl Fn(&BlockHeader) -> BlockHash,
153    ) -> BlockHeader {
154        let mut header = BlockHeader {
155            // Intentionally set to zero, will be computed later.
156            hash: BlockHash::ZERO,
157            parent_hash,
158            number: self.number,
159            timestamp: self.timestamp,
160            eth_l1_gas_price: self.eth_l1_gas_price,
161            strk_l1_gas_price: self.strk_l1_gas_price,
162            eth_l1_data_gas_price: self.eth_l1_data_gas_price,
163            strk_l1_data_gas_price: self.strk_l1_data_gas_price,
164            eth_l2_gas_price: self.eth_l2_gas_price,
165            strk_l2_gas_price: self.strk_l2_gas_price,
166            sequencer_address: self.sequencer_address,
167            starknet_version: self.starknet_version,
168            event_commitment: self.event_commitment,
169            state_commitment,
170            transaction_commitment: self.transaction_commitment,
171            transaction_count: self.transaction_count,
172            event_count: self.event_count,
173            l1_da_mode: self.l1_da_mode,
174            receipt_commitment: self.receipt_commitment,
175            state_diff_commitment: self.state_diff_commitment,
176            state_diff_length: self.state_diff_length,
177        };
178        header.hash = block_hash_fn(&header);
179        header
180    }
181}