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 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+ BlobParameters {
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 ,
@@ -236,10 +290,13 @@ impl BlobFactory {
236290 . await ;
237291 let partial_block_hash_components =
238292 PartialBlockHashComponents :: new ( & block_info, block_header_commitments) ;
293+ let parent_block_hash = self . last_finalized_block_hash ( ) ;
294+ let parent_partial_block_hash_components =
295+ self . last_finalized_partial_block_hash_components ( ) ;
239296 let block_hash = calculate_block_hash (
240297 & partial_block_hash_components,
241298 state_roots. global_root ( ) ,
242- self . last_finalized_block_hash ( ) ,
299+ parent_block_hash ,
243300 )
244301 . unwrap ( ) ;
245302
@@ -248,7 +305,9 @@ impl BlobFactory {
248305 block_context,
249306 transactions_with_receipts,
250307 partial_block_hash_components,
308+ parent_partial_block_hash_components,
251309 block_hash,
310+ parent_block_hash,
252311 state_maps,
253312 state_roots,
254313 } ) ;
@@ -258,11 +317,28 @@ impl BlobFactory {
258317 /// Creates blobs for all finalized blocks, and a preconfirmed block with the remaining txs that
259318 /// were not included in a block. See [Self::close_block] for details on how to close a block.
260319 async fn finalize ( self ) -> ( Vec < AerospikeBlob > , CendeWritePreconfirmedBlock ) {
261- // TODO(Dori): Create the blob vector.
262- let blobs = vec ! [ ] ;
320+ let preconfirmed_block_context = self . next_block_context ( ) ;
321+ let Self { blocks, class_manager, next_txs, state, .. } = self ;
322+ let mut blobs = vec ! [ ] ;
323+ let shared_class_manager = Arc :: new ( class_manager) ;
263324
264325 // For the last block, create a preconfirmed block.
265- let preconfirmed_block = self . make_preconfirmed_block_from_remaining_txs ( ) ;
326+ let preconfirmed_block = Self :: make_preconfirmed_block_from_remaining_txs (
327+ preconfirmed_block_context,
328+ next_txs,
329+ state,
330+ ) ;
331+
332+ for block in blocks. into_iter ( ) {
333+ blobs. push (
334+ AerospikeBlob :: from_blob_parameters_and_class_manager (
335+ block. into ( ) ,
336+ shared_class_manager. clone ( ) ,
337+ )
338+ . await
339+ . unwrap ( ) ,
340+ ) ;
341+ }
266342
267343 ( blobs, preconfirmed_block)
268344 }
@@ -271,6 +347,10 @@ impl BlobFactory {
271347 self . blocks . last ( ) . map ( |block| block. block_hash ) . unwrap_or ( BlockHash :: GENESIS_PARENT_HASH )
272348 }
273349
350+ fn last_finalized_partial_block_hash_components ( & self ) -> Option < PartialBlockHashComponents > {
351+ self . blocks . last ( ) . map ( |block| block. partial_block_hash_components . clone ( ) )
352+ }
353+
274354 fn last_finalized_state_roots ( & self ) -> StateRoots {
275355 self . blocks . last ( ) . map ( |block| block. state_roots ) . unwrap_or_default ( )
276356 }
@@ -354,35 +434,28 @@ impl BlobFactory {
354434 )
355435 }
356436
357- /// Creates a blob for the given block.
358- /// If this is not the first block, also sets the parent proposal commitment and populates the
359- /// recent block hashes with the last block hash (of the previous block).
360- /// Returns the current proposal commitment and the block hash components (for use in block hash
361- /// computation of the current block).
362- #[ expect( dead_code) ]
363- async fn make_blob_parameters ( & self , _block : & BlockData ) -> BlobParameters {
364- unimplemented ! ( )
365- }
366-
367437 /// Creates a preconfirmed block for the given block. Should be called for the last block only -
368438 /// no commitment is computed.
369- fn make_preconfirmed_block_from_remaining_txs ( & self ) -> CendeWritePreconfirmedBlock {
370- let block_context = self . next_block_context ( ) ;
439+ fn make_preconfirmed_block_from_remaining_txs (
440+ block_context : BlockContext ,
441+ txs : Vec < TxPair > ,
442+ state : DictStateReader ,
443+ ) -> CendeWritePreconfirmedBlock {
371444 let block_info = block_context. block_info ( ) . clone ( ) ;
372445 let mut transactions = vec ! [ ] ;
373446 let mut transaction_receipts = vec ! [ ] ;
374447 let mut transaction_state_diffs = vec ! [ ] ;
375448
376- for ( tx_index, ( executable, internal) ) in self . next_txs . iter ( ) . enumerate ( ) {
449+ for ( tx_index, ( executable, internal) ) in txs . into_iter ( ) . enumerate ( ) {
377450 let tx_hash = match & internal {
378451 InternalConsensusTransaction :: RpcTransaction ( tx) => tx. tx_hash ,
379452 InternalConsensusTransaction :: L1Handler ( _) => {
380453 panic ! ( "unexpected L1Handler in test" )
381454 }
382455 } ;
383456
384- let mut tx_state = CachedState :: new ( self . state . clone ( ) ) ;
385- let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable. clone ( ) )
457+ let mut tx_state = CachedState :: new ( state. clone ( ) ) ;
458+ let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable)
386459 . execute ( & mut tx_state, & block_context)
387460 . unwrap ( ) ;
388461
@@ -396,7 +469,7 @@ impl BlobFactory {
396469 ) ) ;
397470 let tx_state_diff = StarknetClientStateDiff :: from ( state_changes. state_maps ) . 0 ;
398471
399- transactions. push ( CendePreconfirmedTransaction :: from ( internal. clone ( ) ) ) ;
472+ transactions. push ( CendePreconfirmedTransaction :: from ( internal) ) ;
400473 transaction_receipts. push ( Some ( receipt) ) ;
401474 transaction_state_diffs. push ( Some ( tx_state_diff) ) ;
402475 }
0 commit comments