@@ -91,6 +91,14 @@ struct CommitStateDiffOutput {
9191 pub global_root : GlobalRoot ,
9292}
9393
94+ /// Classification of a commit request's `height` w.r.t the committer offset.
95+ enum CommitBlockHeightPlan {
96+ /// `height` is already committed; return the stored global root without writing.
97+ Historical { global_root : GlobalRoot } ,
98+ /// `height` is the chain tip; inputs are validated and ready to commit.
99+ CommitTip { state_diff_commitment : StateDiffCommitment } ,
100+ }
101+
94102/// Apollo committer. Maintains the Starknet state tries in persistent storage.
95103pub struct Committer < S : Storage , ForestDB >
96104where
@@ -152,6 +160,63 @@ where
152160 "Received request to commit block number {height} with state diff \
153161 {state_diff_commitment:?}"
154162 ) ;
163+
164+ match self . commit_or_load ( & state_diff, state_diff_commitment, height) . await ? {
165+ CommitBlockHeightPlan :: Historical { global_root } => {
166+ Ok ( CommitBlockResponse { global_root } )
167+ }
168+ CommitBlockHeightPlan :: CommitTip { state_diff_commitment } => {
169+ // Happy flow. Commits the state diff and returns the computed global root.
170+ debug ! (
171+ "Committing block number {height} with state diff {state_diff_commitment:?}"
172+ ) ;
173+ let mut block_measurements = SingleBlockMeasurements :: default ( ) ;
174+ block_measurements. start_measurement ( Action :: EndToEnd ) ;
175+ let CommitStateDiffOutput { filled_forest, global_root, deleted_nodes } =
176+ self . commit_state_diff ( state_diff, & mut block_measurements) . await ?;
177+ let next_offset = height. unchecked_next ( ) ;
178+ let metadata = HashMap :: from ( [
179+ (
180+ ForestMetadataType :: CommitmentOffset ,
181+ DbValue ( DbBlockNumber ( next_offset) . serialize ( ) . to_vec ( ) ) ,
182+ ) ,
183+ (
184+ ForestMetadataType :: StateRoot ( DbBlockNumber ( height) ) ,
185+ serialize_felt_no_packing ( global_root. 0 ) ,
186+ ) ,
187+ (
188+ ForestMetadataType :: StateDiffHash ( DbBlockNumber ( height) ) ,
189+ serialize_felt_no_packing ( state_diff_commitment. 0 . 0 ) ,
190+ ) ,
191+ ] ) ;
192+ info ! (
193+ "For block number {height}, writing filled forest to storage with metadata: \
194+ {metadata:?}, delete {} nodes",
195+ deleted_nodes. len( )
196+ ) ;
197+ block_measurements. start_measurement ( Action :: Write ) ;
198+ let n_write_entries = self
199+ . forest_storage
200+ . write_with_metadata ( & filled_forest, metadata, deleted_nodes)
201+ . await
202+ . map_err ( |err| self . map_internal_error ( err) ) ?;
203+ block_measurements. attempt_to_stop_measurement ( Action :: Write , n_write_entries) . ok ( ) ;
204+ block_measurements. attempt_to_stop_measurement ( Action :: EndToEnd , 0 ) . ok ( ) ;
205+ update_metrics ( height, & block_measurements. block_measurement ) ;
206+ self . update_offset ( next_offset) ;
207+ Ok ( CommitBlockResponse { global_root } )
208+ }
209+ }
210+ }
211+
212+ /// Either load the committed global root for a past `height`, or validate inputs and return
213+ /// the state-diff commitment for committing the chain tip at `self.offset`.
214+ async fn commit_or_load (
215+ & mut self ,
216+ state_diff : & ThinStateDiff ,
217+ state_diff_commitment : Option < StateDiffCommitment > ,
218+ height : BlockNumber ,
219+ ) -> CommitterResult < CommitBlockHeightPlan > {
155220 if height > self . offset {
156221 // Request to commit a future height.
157222 // Returns an error, indicating the committer has a hole in the state diff series.
@@ -164,7 +229,7 @@ where
164229 let state_diff_commitment = match state_diff_commitment {
165230 Some ( commitment) => {
166231 if self . config . verify_state_diff_hash {
167- let calculated_commitment = calculate_state_diff_hash ( & state_diff) ;
232+ let calculated_commitment = calculate_state_diff_hash ( state_diff) ;
168233 if commitment != calculated_commitment {
169234 return Err ( CommitterError :: StateDiffHashMismatch {
170235 provided_commitment : commitment,
@@ -175,8 +240,9 @@ where
175240 }
176241 commitment
177242 }
178- None => calculate_state_diff_hash ( & state_diff) ,
243+ None => calculate_state_diff_hash ( state_diff) ,
179244 } ;
245+
180246 if height < self . offset {
181247 // Request to commit an old height.
182248 // Might be ok if the caller didn't get the results properly.
@@ -196,46 +262,10 @@ where
196262 }
197263 // Returns the precomputed global root.
198264 let db_global_root = self . load_global_root ( height) . await ?;
199- return Ok ( CommitBlockResponse { global_root : db_global_root } ) ;
265+ return Ok ( CommitBlockHeightPlan :: Historical { global_root : db_global_root } ) ;
200266 }
201267
202- // Happy flow. Commits the state diff and returns the computed global root.
203- debug ! ( "Committing block number {height} with state diff {state_diff_commitment:?}" ) ;
204- let mut block_measurements = SingleBlockMeasurements :: default ( ) ;
205- block_measurements. start_measurement ( Action :: EndToEnd ) ;
206- let CommitStateDiffOutput { filled_forest, global_root, deleted_nodes } =
207- self . commit_state_diff ( state_diff, & mut block_measurements) . await ?;
208- let next_offset = height. unchecked_next ( ) ;
209- let metadata = HashMap :: from ( [
210- (
211- ForestMetadataType :: CommitmentOffset ,
212- DbValue ( DbBlockNumber ( next_offset) . serialize ( ) . to_vec ( ) ) ,
213- ) ,
214- (
215- ForestMetadataType :: StateRoot ( DbBlockNumber ( height) ) ,
216- serialize_felt_no_packing ( global_root. 0 ) ,
217- ) ,
218- (
219- ForestMetadataType :: StateDiffHash ( DbBlockNumber ( height) ) ,
220- serialize_felt_no_packing ( state_diff_commitment. 0 . 0 ) ,
221- ) ,
222- ] ) ;
223- info ! (
224- "For block number {height}, writing filled forest to storage with metadata: \
225- {metadata:?}, delete {} nodes",
226- deleted_nodes. len( )
227- ) ;
228- block_measurements. start_measurement ( Action :: Write ) ;
229- let n_write_entries = self
230- . forest_storage
231- . write_with_metadata ( & filled_forest, metadata, deleted_nodes)
232- . await
233- . map_err ( |err| self . map_internal_error ( err) ) ?;
234- block_measurements. attempt_to_stop_measurement ( Action :: Write , n_write_entries) . ok ( ) ;
235- block_measurements. attempt_to_stop_measurement ( Action :: EndToEnd , 0 ) . ok ( ) ;
236- update_metrics ( height, & block_measurements. block_measurement ) ;
237- self . update_offset ( next_offset) ;
238- Ok ( CommitBlockResponse { global_root } )
268+ Ok ( CommitBlockHeightPlan :: CommitTip { state_diff_commitment } )
239269 }
240270
241271 /// Applies the given state diff to revert the changes of the given height.
0 commit comments