@@ -26,6 +26,7 @@ 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:: committer_types:: RevertBlockResponse ;
2930use apollo_committer_types:: communication:: SharedCommitterClient ;
3031use apollo_infra:: component_definitions:: { default_component_start_fn, ComponentStarter } ;
3132use apollo_l1_provider_types:: errors:: { L1ProviderClientError , L1ProviderError } ;
@@ -35,7 +36,7 @@ use apollo_mempool_types::mempool_types::CommitBlockArgs;
3536use apollo_reverts:: revert_block;
3637use apollo_state_sync_types:: state_sync_types:: SyncBlock ;
3738use apollo_storage:: block_hash:: { BlockHashStorageReader , BlockHashStorageWriter } ;
38- use apollo_storage:: global_root:: GlobalRootStorageWriter ;
39+ use apollo_storage:: global_root:: { GlobalRootStorageReader , GlobalRootStorageWriter } ;
3940use apollo_storage:: global_root_marker:: {
4041 GlobalRootMarkerStorageReader ,
4142 GlobalRootMarkerStorageWriter ,
@@ -86,7 +87,11 @@ use crate::commitment_manager::commitment_manager_impl::{
8687 ApolloCommitmentManager ,
8788 CommitmentManager ,
8889} ;
89- use crate :: commitment_manager:: types:: FinalBlockCommitment ;
90+ use crate :: commitment_manager:: types:: {
91+ CommitmentTaskOutput ,
92+ FinalBlockCommitment ,
93+ RevertTaskOutput ,
94+ } ;
9095use crate :: metrics:: {
9196 register_metrics,
9297 ProposalMetricsHandle ,
@@ -478,6 +483,7 @@ impl Batcher {
478483 }
479484
480485 /// Clear all the proposals from the previous height.
486+ #[ cfg_attr( any( test, feature = "testing" ) , apollo_proc_macros:: make_visibility( pub ) ) ]
481487 async fn abort_active_height ( & mut self ) {
482488 self . abort_active_proposal ( ) . await ;
483489 self . executed_proposals . lock ( ) . await . clear ( ) ;
@@ -708,7 +714,7 @@ impl Batcher {
708714 . expect ( "The commitment offset unexpectedly doesn't match the given block height." ) ;
709715
710716 // Write ready commitments to storage.
711- self . write_commitment_results_to_storage ( ) . await ?;
717+ self . get_and_write_commitment_results_to_storage ( ) . await ?;
712718
713719 LAST_SYNCED_BLOCK_HEIGHT . set_lossy ( block_number. 0 ) ;
714720 SYNCED_TRANSACTIONS . increment (
@@ -773,7 +779,7 @@ impl Batcher {
773779 . expect ( "The commitment offset unexpectedly doesn't match the given block height." ) ;
774780
775781 // Write ready commitments to storage.
776- self . write_commitment_results_to_storage ( ) . await ?;
782+ self . get_and_write_commitment_results_to_storage ( ) . await ?;
777783
778784 let execution_infos = block_execution_artifacts
779785 . execution_data
@@ -1107,6 +1113,9 @@ impl Batcher {
11071113 self . abort_active_height ( ) . await ;
11081114 }
11091115
1116+ // Wait for the revert commitment to be completed before reverting the storage.
1117+ self . revert_commitment ( height) . await ;
1118+
11101119 self . storage_writer . revert_block ( height) ;
11111120 BUILDING_HEIGHT . decrement ( 1 ) ;
11121121 GLOBAL_ROOT_HEIGHT . decrement ( 1 ) ;
@@ -1156,8 +1165,17 @@ impl Batcher {
11561165 }
11571166
11581167 /// Writes the ready commitment results to storage.
1159- async fn write_commitment_results_to_storage ( & mut self ) -> BatcherResult < ( ) > {
1168+ async fn get_and_write_commitment_results_to_storage ( & mut self ) -> BatcherResult < ( ) > {
11601169 let commitment_results = self . commitment_manager . get_commitment_results ( ) . await ;
1170+ self . write_commitment_results_to_storage ( commitment_results) . await ?;
1171+ Ok ( ( ) )
1172+ }
1173+
1174+ /// Writes the given commitment results to storage.
1175+ async fn write_commitment_results_to_storage (
1176+ & mut self ,
1177+ commitment_results : Vec < CommitmentTaskOutput > ,
1178+ ) -> BatcherResult < ( ) > {
11611179 for commitment_task_output in commitment_results. into_iter ( ) {
11621180 let height = commitment_task_output. height ;
11631181 info ! ( "Writing commitment results to storage for height {}." , height) ;
@@ -1217,6 +1235,62 @@ impl Batcher {
12171235 Ok ( ( ) )
12181236 }
12191237
1238+ /// Reverts the commitment for the given height.
1239+ /// Adds a revert task to the commitment manager channel and waits for the result.
1240+ /// Writes commitment results to storage and handles the revert task result.
1241+ async fn revert_commitment ( & mut self , height : BlockNumber ) {
1242+ let reversed_state_diff = self
1243+ . storage_reader
1244+ . reversed_state_diff ( height)
1245+ . expect ( "Failed to get reversed state diff from storage." ) ;
1246+ self . commitment_manager
1247+ . add_revert_task ( height, reversed_state_diff)
1248+ . await
1249+ . expect ( "Failed to add revert task to commitment manager." ) ;
1250+ let ( commitment_results, revert_task_result) =
1251+ self . commitment_manager . wait_for_revert_result ( ) . await ;
1252+ self . write_commitment_results_to_storage ( commitment_results)
1253+ . await
1254+ . expect ( "Failed to write commitment results to storage." ) ;
1255+
1256+ info ! ( "Revert task result: {revert_task_result:?}" ) ;
1257+ self . validate_revert_task_result ( revert_task_result, height) . await ;
1258+ info ! ( "Reverted commitment for height {height}." ) ;
1259+ }
1260+
1261+ async fn validate_revert_task_result (
1262+ & self ,
1263+ revert_task_output : RevertTaskOutput ,
1264+ request_height_to_revert : BlockNumber ,
1265+ ) {
1266+ assert_eq ! (
1267+ revert_task_output. height, request_height_to_revert,
1268+ "The task output height does not match the request height."
1269+ ) ;
1270+
1271+ match revert_task_output. response {
1272+ RevertBlockResponse :: RevertedTo ( global_root)
1273+ | RevertBlockResponse :: AlreadyReverted ( global_root) => {
1274+ // Verify the global root matches the stored global root.
1275+ let new_latest_height = revert_task_output
1276+ . height
1277+ . prev ( )
1278+ . expect ( "Can't revert before the genesis block." ) ;
1279+ let stored_global_root = self
1280+ . storage_reader
1281+ . global_root ( new_latest_height)
1282+ . expect ( "Failed to get global root from storage." )
1283+ . expect ( "Global root is not set for height {new_latest_height}." ) ;
1284+ assert_eq ! (
1285+ global_root, stored_global_root,
1286+ "The given global root does not match the stored global root for height \
1287+ {new_latest_height}."
1288+ ) ;
1289+ }
1290+ RevertBlockResponse :: Uncommitted => { }
1291+ }
1292+ }
1293+
12201294 pub fn get_block_hash ( & self , block_number : BlockNumber ) -> BatcherResult < BlockHash > {
12211295 self . storage_reader
12221296 . get_block_hash ( block_number)
@@ -1341,6 +1415,8 @@ pub trait BatcherStorageReader: Send + Sync {
13411415 /// Returns the first height the committer has finished calculating commitments for.
13421416 fn global_root_height ( & self ) -> StorageResult < BlockNumber > ;
13431417
1418+ fn global_root ( & self , height : BlockNumber ) -> StorageResult < Option < GlobalRoot > > ;
1419+
13441420 fn get_state_diff ( & self , height : BlockNumber ) -> StorageResult < Option < ThinStateDiff > > ;
13451421
13461422 /// Returns the state diff that undoes the state diff at the given height.
@@ -1367,6 +1443,10 @@ impl BatcherStorageReader for StorageReader {
13671443 self . begin_ro_txn ( ) ?. get_global_root_marker ( )
13681444 }
13691445
1446+ fn global_root ( & self , height : BlockNumber ) -> StorageResult < Option < GlobalRoot > > {
1447+ self . begin_ro_txn ( ) ?. get_global_root ( & height)
1448+ }
1449+
13701450 fn get_state_diff ( & self , height : BlockNumber ) -> StorageResult < Option < ThinStateDiff > > {
13711451 self . begin_ro_txn ( ) ?. get_state_diff ( height)
13721452 }
0 commit comments