11use std:: path:: PathBuf ;
2- use std:: sync:: LazyLock ;
2+ use std:: sync:: { Arc , LazyLock } ;
33use std:: { env, fs} ;
44
55use apollo_batcher:: cende_client_types:: {
@@ -12,17 +12,19 @@ use apollo_batcher::cende_client_types::{
1212use apollo_batcher:: pre_confirmed_cende_client:: CendeWritePreconfirmedBlock ;
1313use apollo_batcher_types:: batcher_types:: Round ;
1414use apollo_class_manager_types:: MockClassManagerClient ;
15+ use apollo_consensus:: types:: ProposalCommitment ;
1516use apollo_consensus_orchestrator:: cende:: {
1617 AerospikeBlob ,
1718 BlobParameters ,
1819 InternalTransactionWithReceipt ,
1920} ;
21+ use apollo_consensus_orchestrator:: fee_market:: FeeMarketInfo ;
2022use apollo_infra_utils:: compile_time_cargo_manifest_dir;
2123use blockifier:: abi:: constants:: STORED_BLOCK_HASH_BUFFER ;
2224use blockifier:: blockifier:: config:: TransactionExecutorConfig ;
2325use blockifier:: blockifier:: transaction_executor:: TransactionExecutor ;
2426use blockifier:: blockifier_versioned_constants:: VersionedConstants ;
25- use blockifier:: bouncer:: BouncerConfig ;
27+ use blockifier:: bouncer:: { BouncerConfig , BouncerWeights , CasmHashComputationData } ;
2628use blockifier:: context:: { BlockContext , ChainInfo } ;
2729use blockifier:: state:: cached_state:: { CachedState , CommitmentStateDiff , StateMaps } ;
2830use blockifier:: state:: state_api:: UpdatableState ;
@@ -44,6 +46,7 @@ use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockInfo, BlockNumber,
4446use starknet_api:: block_hash:: block_hash_calculator:: {
4547 calculate_block_commitments,
4648 calculate_block_hash,
49+ PartialBlockHash ,
4750 PartialBlockHashComponents ,
4851 TransactionHashingData ,
4952} ;
@@ -113,16 +116,67 @@ fn blobs_object_path(generation: usize) -> String {
113116 format ! ( "{generation}/{BLOBS_FILE_NAME}" )
114117}
115118
116- #[ expect( dead_code) ]
117119struct BlockData {
118120 block_context : BlockContext ,
119121 transactions_with_receipts : Vec < InternalTransactionWithReceipt > ,
120122 partial_block_hash_components : PartialBlockHashComponents ,
123+ parent_partial_block_hash_components : Option < PartialBlockHashComponents > ,
121124 block_hash : BlockHash ,
125+ parent_block_hash : BlockHash ,
122126 state_maps : StateMaps ,
123127 state_roots : StateRoots ,
124128}
125129
130+ impl From < BlockData > for BlobParameters {
131+ /// If this is not the first block, also sets the parent proposal commitment and populates the
132+ /// recent block hashes only with the last block hash (of the previous block).
133+ fn from ( block : BlockData ) -> Self {
134+ let commitment_state_diff = CommitmentStateDiff :: from ( block. state_maps . clone ( ) ) ;
135+ let state_diff = ThinStateDiff :: from ( commitment_state_diff. clone ( ) ) ;
136+ let block_info = block. block_context . block_info ( ) . clone ( ) ;
137+ let proposal_commitment = ProposalCommitment (
138+ PartialBlockHash :: from_partial_block_hash_components (
139+ & block. partial_block_hash_components ,
140+ )
141+ . unwrap ( )
142+ . 0 ,
143+ ) ;
144+
145+ let ( recent_block_hashes, parent_proposal_commitment) = if block_info. block_number . 0 > 0 {
146+ (
147+ vec ! [ BlockHashAndNumber {
148+ number: BlockNumber ( block_info. block_number. 0 - 1 ) ,
149+ hash: block. parent_block_hash,
150+ } ] ,
151+ Some ( ProposalCommitment (
152+ PartialBlockHash :: from_partial_block_hash_components (
153+ & block. parent_partial_block_hash_components . unwrap ( ) ,
154+ )
155+ . unwrap ( )
156+ . 0 ,
157+ ) ) ,
158+ )
159+ } else {
160+ ( vec ! [ ] , None )
161+ } ;
162+
163+ Self {
164+ block_info,
165+ state_diff,
166+ compressed_state_diff : Some ( commitment_state_diff) ,
167+ transactions_with_execution_infos : block. transactions_with_receipts ,
168+ bouncer_weights : BouncerWeights :: default ( ) ,
169+ fee_market_info : FeeMarketInfo :: default ( ) ,
170+ casm_hash_computation_data_sierra_gas : CasmHashComputationData :: default ( ) ,
171+ casm_hash_computation_data_proving_gas : CasmHashComputationData :: default ( ) ,
172+ compiled_class_hashes_for_migration : vec ! [ ] ,
173+ proposal_commitment,
174+ parent_proposal_commitment,
175+ recent_block_hashes,
176+ }
177+ }
178+ }
179+
126180struct BlobFactory {
127181 chain_info : ChainInfo ,
128182 class_manager : MockClassManagerClient ,
@@ -233,10 +287,13 @@ impl BlobFactory {
233287 . await ;
234288 let partial_block_hash_components =
235289 PartialBlockHashComponents :: new ( & block_info, block_header_commitments) ;
290+ let parent_block_hash = self . last_finalized_block_hash ( ) ;
291+ let parent_partial_block_hash_components =
292+ self . last_finalized_partial_block_hash_components ( ) ;
236293 let block_hash = calculate_block_hash (
237294 & partial_block_hash_components,
238295 state_roots. global_root ( ) ,
239- self . last_finalized_block_hash ( ) ,
296+ parent_block_hash ,
240297 )
241298 . unwrap ( ) ;
242299
@@ -245,7 +302,9 @@ impl BlobFactory {
245302 block_context,
246303 transactions_with_receipts,
247304 partial_block_hash_components,
305+ parent_partial_block_hash_components,
248306 block_hash,
307+ parent_block_hash,
249308 state_maps,
250309 state_roots,
251310 } ) ;
@@ -254,11 +313,28 @@ impl BlobFactory {
254313 /// Creates blobs for all finalized blocks, and a preconfirmed block with the remaining txs that
255314 /// were not included in a block. See [Self::close_block] for details on how to close a block.
256315 async fn finalize ( self ) -> ( Vec < AerospikeBlob > , CendeWritePreconfirmedBlock ) {
257- // TODO(Dori): Create the blob vector.
258- let blobs = vec ! [ ] ;
316+ let preconfirmed_block_context = self . next_block_context ( ) ;
317+ let Self { blocks, class_manager, next_txs, state, .. } = self ;
318+ let mut blobs = vec ! [ ] ;
319+ let shared_class_manager = Arc :: new ( class_manager) ;
259320
260321 // For the last block, create a preconfirmed block.
261- let preconfirmed_block = self . make_preconfirmed_block_from_remaining_txs ( ) ;
322+ let preconfirmed_block = Self :: make_preconfirmed_block_from_remaining_txs (
323+ preconfirmed_block_context,
324+ next_txs,
325+ state,
326+ ) ;
327+
328+ for block in blocks. into_iter ( ) {
329+ blobs. push (
330+ AerospikeBlob :: from_blob_parameters_and_class_manager (
331+ block. into ( ) ,
332+ shared_class_manager. clone ( ) ,
333+ )
334+ . await
335+ . unwrap ( ) ,
336+ ) ;
337+ }
262338
263339 ( blobs, preconfirmed_block)
264340 }
@@ -267,6 +343,10 @@ impl BlobFactory {
267343 self . blocks . last ( ) . map ( |block| block. block_hash ) . unwrap_or ( BlockHash :: GENESIS_PARENT_HASH )
268344 }
269345
346+ fn last_finalized_partial_block_hash_components ( & self ) -> Option < PartialBlockHashComponents > {
347+ self . blocks . last ( ) . map ( |block| block. partial_block_hash_components . clone ( ) )
348+ }
349+
270350 fn last_finalized_state_roots ( & self ) -> StateRoots {
271351 self . blocks . last ( ) . map ( |block| block. state_roots ) . unwrap_or_default ( )
272352 }
@@ -350,27 +430,19 @@ impl BlobFactory {
350430 )
351431 }
352432
353- /// Creates a blob for the given block.
354- /// If this is not the first block, also sets the parent proposal commitment and populates the
355- /// recent block hashes with the last block hash (of the previous block).
356- /// Returns the current proposal commitment and the block hash components (for use in block hash
357- /// computation of the current block).
358- #[ expect( dead_code) ]
359- async fn make_blob_parameters ( & self , _block : & BlockData ) -> BlobParameters {
360- unimplemented ! ( )
361- }
362-
363433 /// Creates a preconfirmed block for the given block. Should be called for the last block only -
364434 /// no commitment is computed.
365- fn make_preconfirmed_block_from_remaining_txs ( self ) -> CendeWritePreconfirmedBlock {
366- let block_context = self . next_block_context ( ) ;
435+ fn make_preconfirmed_block_from_remaining_txs (
436+ block_context : BlockContext ,
437+ txs : Vec < TxPair > ,
438+ mut state : DictStateReader ,
439+ ) -> CendeWritePreconfirmedBlock {
367440 let block_info = block_context. block_info ( ) . clone ( ) ;
368441 let mut transactions = vec ! [ ] ;
369442 let mut transaction_receipts = vec ! [ ] ;
370443 let mut transaction_state_diffs = vec ! [ ] ;
371- let Self { mut state, next_txs, .. } = self ;
372444
373- for ( tx_index, ( executable, internal) ) in next_txs . into_iter ( ) . enumerate ( ) {
445+ for ( tx_index, ( executable, internal) ) in txs . into_iter ( ) . enumerate ( ) {
374446 let tx_hash = match & internal {
375447 InternalConsensusTransaction :: RpcTransaction ( tx) => tx. tx_hash ,
376448 InternalConsensusTransaction :: L1Handler ( _) => {
@@ -379,7 +451,7 @@ impl BlobFactory {
379451 } ;
380452
381453 let mut tx_state = CachedState :: new ( state. clone ( ) ) ;
382- let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable. clone ( ) )
454+ let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable)
383455 . execute ( & mut tx_state, & block_context)
384456 . unwrap ( ) ;
385457
@@ -393,7 +465,7 @@ impl BlobFactory {
393465 ) ) ;
394466 let tx_state_diff = StarknetClientStateDiff :: from ( state_changes. state_maps ) . 0 ;
395467
396- transactions. push ( CendePreconfirmedTransaction :: from ( internal. clone ( ) ) ) ;
468+ transactions. push ( CendePreconfirmedTransaction :: from ( internal) ) ;
397469 transaction_receipts. push ( Some ( receipt) ) ;
398470 transaction_state_diffs. push ( Some ( tx_state_diff) ) ;
399471
0 commit comments