Skip to main content

pathfinder_common/
l2.rs

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