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}
80
81#[derive(Clone, Debug)]
82pub struct DeclaredClass {
83    pub sierra_hash: SierraHash,
84    pub casm_hash_v2: CasmHash,
85    pub sierra_def: Vec<u8>,
86    pub casm_def: Vec<u8>,
87}
88
89impl From<L2Block> for L2BlockToCommit {
90    fn from(block: L2Block) -> Self {
91        L2BlockToCommit::FromFgw(block)
92    }
93}
94
95impl From<ConsensusFinalizedL2Block> for L2BlockToCommit {
96    fn from(block: ConsensusFinalizedL2Block) -> Self {
97        L2BlockToCommit::FromConsensus(block)
98    }
99}
100
101impl L2BlockToCommit {
102    pub fn number(&self) -> BlockNumber {
103        match self {
104            L2BlockToCommit::FromConsensus(block) => block.header.number,
105            L2BlockToCommit::FromFgw(block) => block.header.number,
106        }
107    }
108
109    pub fn state_commitment(&self) -> Option<StateCommitment> {
110        match self {
111            L2BlockToCommit::FromConsensus(_) => None,
112            L2BlockToCommit::FromFgw(block) => Some(block.header.state_commitment),
113        }
114    }
115
116    pub fn state_update(&self) -> &StateUpdateData {
117        match self {
118            L2BlockToCommit::FromConsensus(block) => &block.state_update,
119            L2BlockToCommit::FromFgw(block) => &block.state_update,
120        }
121    }
122
123    pub fn starknet_version(&self) -> StarknetVersion {
124        match self {
125            L2BlockToCommit::FromConsensus(block) => block.header.starknet_version,
126            L2BlockToCommit::FromFgw(block) => block.header.starknet_version,
127        }
128    }
129}
130
131impl ConsensusFinalizedBlockHeader {
132    pub fn compute_hash(
133        self,
134        parent_hash: BlockHash,
135        state_commitment: StateCommitment,
136        block_hash_fn: impl Fn(&BlockHeader) -> BlockHash,
137    ) -> BlockHeader {
138        let mut header = BlockHeader {
139            // Intentionally set to zero, will be computed later.
140            hash: BlockHash::ZERO,
141            parent_hash,
142            number: self.number,
143            timestamp: self.timestamp,
144            eth_l1_gas_price: self.eth_l1_gas_price,
145            strk_l1_gas_price: self.strk_l1_gas_price,
146            eth_l1_data_gas_price: self.eth_l1_data_gas_price,
147            strk_l1_data_gas_price: self.strk_l1_data_gas_price,
148            eth_l2_gas_price: self.eth_l2_gas_price,
149            strk_l2_gas_price: self.strk_l2_gas_price,
150            sequencer_address: self.sequencer_address,
151            starknet_version: self.starknet_version,
152            event_commitment: self.event_commitment,
153            state_commitment,
154            transaction_commitment: self.transaction_commitment,
155            transaction_count: self.transaction_count,
156            event_count: self.event_count,
157            l1_da_mode: self.l1_da_mode,
158            receipt_commitment: self.receipt_commitment,
159            state_diff_commitment: self.state_diff_commitment,
160            state_diff_length: self.state_diff_length,
161        };
162        header.hash = block_hash_fn(&header);
163        header
164    }
165}