@@ -26,30 +26,38 @@ use apollo_batcher_types::batcher_types::{
2626use apollo_batcher_types:: errors:: BatcherError ;
2727use apollo_class_manager_types:: transaction_converter:: TransactionConverter ;
2828use apollo_class_manager_types:: SharedClassManagerClient ;
29+ use apollo_committer_types:: communication:: SharedCommitterClient ;
2930use apollo_infra:: component_definitions:: { default_component_start_fn, ComponentStarter } ;
3031use apollo_l1_provider_types:: errors:: { L1ProviderClientError , L1ProviderError } ;
3132use apollo_l1_provider_types:: { SessionState , SharedL1ProviderClient } ;
3233use apollo_mempool_types:: communication:: SharedMempoolClient ;
3334use apollo_mempool_types:: mempool_types:: CommitBlockArgs ;
3435use apollo_reverts:: revert_block;
3536use apollo_state_sync_types:: state_sync_types:: SyncBlock ;
37+ use apollo_storage:: block_hash_marker:: BlockHashMarkerStorageReader ;
3638use apollo_storage:: metrics:: BATCHER_STORAGE_OPEN_READ_TRANSACTIONS ;
3739use apollo_storage:: partial_block_hash:: PartialBlockHashComponentsStorageWriter ;
3840use apollo_storage:: state:: { StateStorageReader , StateStorageWriter } ;
39- use apollo_storage:: { open_storage_with_metric, StorageReader , StorageResult , StorageWriter } ;
41+ use apollo_storage:: {
42+ open_storage_with_metric,
43+ StorageError ,
44+ StorageReader ,
45+ StorageResult ,
46+ StorageWriter ,
47+ } ;
4048use async_trait:: async_trait;
4149use blockifier:: concurrency:: worker_pool:: WorkerPool ;
4250use blockifier:: state:: contract_class_manager:: ContractClassManager ;
4351use futures:: FutureExt ;
44- use indexmap:: IndexSet ;
52+ use indexmap:: { IndexMap , IndexSet } ;
4553#[ cfg( test) ]
4654use mockall:: automock;
47- use starknet_api:: block:: { BlockHeaderWithoutHash , BlockNumber } ;
55+ use starknet_api:: block:: BlockNumber ;
4856use starknet_api:: block_hash:: block_hash_calculator:: PartialBlockHashComponents ;
4957use starknet_api:: block_hash:: state_diff_hash:: calculate_state_diff_hash;
5058use starknet_api:: consensus_transaction:: InternalConsensusTransaction ;
5159use starknet_api:: core:: { ContractAddress , Nonce } ;
52- use starknet_api:: state:: ThinStateDiff ;
60+ use starknet_api:: state:: { StateNumber , ThinStateDiff } ;
5361use starknet_api:: transaction:: TransactionHash ;
5462use tokio:: sync:: Mutex ;
5563use tracing:: { debug, error, info, instrument, trace, Instrument } ;
@@ -108,6 +116,7 @@ pub struct Batcher {
108116 pub config : BatcherConfig ,
109117 pub storage_reader : Arc < dyn BatcherStorageReader > ,
110118 pub storage_writer : Box < dyn BatcherStorageWriter > ,
119+ pub committer_client : SharedCommitterClient ,
111120 pub l1_provider_client : SharedL1ProviderClient ,
112121 pub mempool_client : SharedMempoolClient ,
113122 pub transaction_converter : TransactionConverter ,
@@ -156,6 +165,7 @@ impl Batcher {
156165 config : BatcherConfig ,
157166 storage_reader : Arc < dyn BatcherStorageReader > ,
158167 storage_writer : Box < dyn BatcherStorageWriter > ,
168+ committer_client : SharedCommitterClient ,
159169 l1_provider_client : SharedL1ProviderClient ,
160170 mempool_client : SharedMempoolClient ,
161171 transaction_converter : TransactionConverter ,
@@ -166,6 +176,7 @@ impl Batcher {
166176 config,
167177 storage_reader,
168178 storage_writer,
179+ committer_client,
169180 l1_provider_client,
170181 mempool_client,
171182 transaction_converter,
@@ -582,8 +593,10 @@ impl Batcher {
582593 state_diff,
583594 account_transaction_hashes,
584595 l1_transaction_hashes,
585- block_header_without_hash : BlockHeaderWithoutHash { block_number, .. } ,
596+ block_header_without_hash,
597+ block_header_commitments,
586598 } = sync_block;
599+ let block_number = block_header_without_hash. block_number ;
587600
588601 let height = self . get_height_from_storage ( ) ?;
589602 if height != block_number {
@@ -599,13 +612,31 @@ impl Batcher {
599612 }
600613
601614 let address_to_nonce = state_diff. nonces . iter ( ) . map ( |( k, v) | ( * k, * v) ) . collect ( ) ;
615+ let partial_block_hash_components =
616+ if block_header_without_hash. starknet_version . has_partial_block_hash_components ( ) {
617+ match block_header_commitments {
618+ Some ( header_commitments) => Some ( PartialBlockHashComponents {
619+ header_commitments,
620+ block_number,
621+ l1_gas_price : block_header_without_hash. l1_gas_price ,
622+ l1_data_gas_price : block_header_without_hash. l1_data_gas_price ,
623+ l2_gas_price : block_header_without_hash. l2_gas_price ,
624+ sequencer : block_header_without_hash. sequencer ,
625+ timestamp : block_header_without_hash. timestamp ,
626+ starknet_version : block_header_without_hash. starknet_version ,
627+ } ) ,
628+ None => return Err ( BatcherError :: MissingHeaderCommitments { block_number } ) ,
629+ }
630+ } else {
631+ None
632+ } ;
602633 self . commit_proposal_and_block (
603634 height,
604635 state_diff,
605636 address_to_nonce,
606637 l1_transaction_hashes. iter ( ) . copied ( ) . collect ( ) ,
607638 Default :: default ( ) ,
608- None ,
639+ partial_block_hash_components ,
609640 )
610641 . await ?;
611642 LAST_SYNCED_BLOCK_HEIGHT . set_lossy ( block_number. 0 ) ;
@@ -694,8 +725,8 @@ impl Batcher {
694725 } )
695726 }
696727
697- // The `partial_block_hash_components` is optional as it's not needed for blocks coming from
698- // sync as they contain the full block hash .
728+ // The `partial_block_hash_components` is optional as it doesn't exist for old blocks coming
729+ // from sync .
699730 async fn commit_proposal_and_block (
700731 & mut self ,
701732 height : BlockNumber ,
@@ -1041,6 +1072,7 @@ fn log_txs_execution_result(
10411072
10421073pub fn create_batcher (
10431074 config : BatcherConfig ,
1075+ committer_client : SharedCommitterClient ,
10441076 mempool_client : SharedMempoolClient ,
10451077 l1_provider_client : SharedL1ProviderClient ,
10461078 class_manager_client : SharedClassManagerClient ,
@@ -1074,6 +1106,7 @@ pub fn create_batcher(
10741106 config,
10751107 storage_reader,
10761108 storage_writer,
1109+ committer_client,
10771110 l1_provider_client,
10781111 mempool_client,
10791112 transaction_converter,
@@ -1087,19 +1120,92 @@ pub trait BatcherStorageReader: Send + Sync {
10871120 /// Returns the next height that the batcher should work on.
10881121 fn height ( & self ) -> StorageResult < BlockNumber > ;
10891122
1123+ /// Returns the next height the batcher should store block hash for.
1124+ fn block_hash_height ( & self ) -> StorageResult < BlockNumber > ;
1125+
10901126 fn get_state_diff ( & self , height : BlockNumber ) -> StorageResult < Option < ThinStateDiff > > ;
1127+
1128+ /// Returns the state diff that undoes the state diff at the given height.
1129+ /// Ignores deprecated_declared_classes.
1130+ fn reversed_state_diff (
1131+ & self ,
1132+ height : BlockNumber ,
1133+ ) -> apollo_storage:: StorageResult < ThinStateDiff > ;
10911134}
10921135
10931136impl BatcherStorageReader for StorageReader {
10941137 fn height ( & self ) -> StorageResult < BlockNumber > {
10951138 self . begin_ro_txn ( ) ?. get_state_marker ( )
10961139 }
10971140
1098- fn get_state_diff (
1141+ fn block_hash_height ( & self ) -> StorageResult < BlockNumber > {
1142+ self . begin_ro_txn ( ) ?. get_block_hash_marker ( )
1143+ }
1144+
1145+ fn get_state_diff ( & self , height : BlockNumber ) -> StorageResult < Option < ThinStateDiff > > {
1146+ self . begin_ro_txn ( ) ?. get_state_diff ( height)
1147+ }
1148+
1149+ fn reversed_state_diff (
10991150 & self ,
11001151 height : BlockNumber ,
1101- ) -> apollo_storage:: StorageResult < Option < ThinStateDiff > > {
1102- self . begin_ro_txn ( ) ?. get_state_diff ( height)
1152+ ) -> apollo_storage:: StorageResult < ThinStateDiff > {
1153+ let state_target = StateNumber :: right_before_block ( height) ;
1154+ let txn = self . begin_ro_txn ( ) ?;
1155+
1156+ let ThinStateDiff {
1157+ deployed_contracts,
1158+ storage_diffs,
1159+ class_hash_to_compiled_class_hash,
1160+ nonces,
1161+ ..
1162+ } = txn. get_state_diff ( height) ?. ok_or_else ( || StorageError :: MissingObject {
1163+ object_name : "state diff" . to_string ( ) ,
1164+ height,
1165+ } ) ?;
1166+
1167+ let state_reader = txn. get_state_reader ( ) ?;
1168+
1169+ // In the following maps, set empty values to zero.
1170+ let mut reversed_deployed_contracts = IndexMap :: new ( ) ;
1171+ for contract_address in deployed_contracts. keys ( ) {
1172+ let class_hash =
1173+ state_reader. get_class_hash_at ( state_target, contract_address) ?. unwrap_or_default ( ) ;
1174+ reversed_deployed_contracts. insert ( * contract_address, class_hash) ;
1175+ }
1176+
1177+ let mut reversed_storage_diffs = IndexMap :: new ( ) ;
1178+ for ( contract_address, contract_diffs) in storage_diffs {
1179+ let mut reversed_contract_diffs = IndexMap :: new ( ) ;
1180+ for key in contract_diffs. keys ( ) {
1181+ let value = state_reader. get_storage_at ( state_target, & contract_address, key) ?;
1182+ reversed_contract_diffs. insert ( * key, value) ;
1183+ }
1184+ reversed_storage_diffs. insert ( contract_address, reversed_contract_diffs) ;
1185+ }
1186+
1187+ let mut reversed_class_hash_to_compiled_class_hash = IndexMap :: new ( ) ;
1188+ for class_hash in class_hash_to_compiled_class_hash. keys ( ) {
1189+ let compiled_class_hash = state_reader
1190+ . get_compiled_class_hash_at ( state_target, class_hash) ?
1191+ . unwrap_or_default ( ) ;
1192+ reversed_class_hash_to_compiled_class_hash. insert ( * class_hash, compiled_class_hash) ;
1193+ }
1194+
1195+ let mut reversed_nonces = IndexMap :: new ( ) ;
1196+ for contract_address in nonces. keys ( ) {
1197+ let nonce =
1198+ state_reader. get_nonce_at ( state_target, contract_address) ?. unwrap_or_default ( ) ;
1199+ reversed_nonces. insert ( * contract_address, nonce) ;
1200+ }
1201+
1202+ Ok ( ThinStateDiff {
1203+ deployed_contracts : reversed_deployed_contracts,
1204+ storage_diffs : reversed_storage_diffs,
1205+ class_hash_to_compiled_class_hash : reversed_class_hash_to_compiled_class_hash,
1206+ nonces : reversed_nonces,
1207+ deprecated_declared_classes : Default :: default ( ) ,
1208+ } )
11031209 }
11041210}
11051211
0 commit comments