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,12 @@ impl BlobFactory {
236290 . await ;
237291 let partial_block_hash_components =
238292 PartialBlockHashComponents :: new ( & block_info, block_header_commitments) ;
293+ let parent_block_hash = self . parent_block_hash ( ) ;
294+ let parent_partial_block_hash_components = self . parent_partial_block_hash_components ( ) ;
239295 let block_hash = calculate_block_hash (
240296 & partial_block_hash_components,
241297 state_roots. global_root ( ) ,
242- self . parent_block_hash ( ) ,
298+ parent_block_hash,
243299 )
244300 . unwrap ( ) ;
245301
@@ -248,7 +304,9 @@ impl BlobFactory {
248304 block_context,
249305 transactions_with_receipts,
250306 partial_block_hash_components,
307+ parent_partial_block_hash_components,
251308 block_hash,
309+ parent_block_hash,
252310 state_maps,
253311 state_roots,
254312 } ) ;
@@ -258,11 +316,28 @@ impl BlobFactory {
258316 /// Creates blobs for all finalized blocks, and a preconfirmed block with the remaining txs that
259317 /// were not included in a block. See [Self::close_block] for details on how to close a block.
260318 async fn finalize ( self ) -> ( Vec < AerospikeBlob > , CendeWritePreconfirmedBlock ) {
261- // TODO(Dori): Create the blob vector.
262- let blobs = vec ! [ ] ;
319+ let preconfirmed_block_context = self . next_block_context ( ) ;
320+ let Self { blocks, class_manager, next_txs, state, .. } = self ;
321+ let mut blobs = vec ! [ ] ;
322+ let shared_class_manager = Arc :: new ( class_manager) ;
263323
264324 // For the last block, create a preconfirmed block.
265- let preconfirmed_block = self . make_preconfirmed_block_from_remaining_txs ( ) ;
325+ let preconfirmed_block = Self :: make_preconfirmed_block_from_remaining_txs (
326+ preconfirmed_block_context,
327+ next_txs,
328+ state,
329+ ) ;
330+
331+ for block in blocks. into_iter ( ) {
332+ blobs. push (
333+ AerospikeBlob :: from_blob_parameters_and_class_manager (
334+ block. into ( ) ,
335+ shared_class_manager. clone ( ) ,
336+ )
337+ . await
338+ . unwrap ( ) ,
339+ ) ;
340+ }
266341
267342 ( blobs, preconfirmed_block)
268343 }
@@ -271,6 +346,13 @@ impl BlobFactory {
271346 self . blocks . last ( ) . map ( |block| block. block_hash ) . unwrap_or ( BlockHash :: GENESIS_PARENT_HASH )
272347 }
273348
349+ fn parent_partial_block_hash_components ( & self ) -> Option < PartialBlockHashComponents > {
350+ self . blocks
351+ . last ( )
352+ . map ( |block| Some ( block. partial_block_hash_components . clone ( ) ) )
353+ . unwrap_or ( None )
354+ }
355+
274356 fn current_state_roots ( & self ) -> StateRoots {
275357 self . blocks . last ( ) . map ( |block| block. state_roots ) . unwrap_or_default ( )
276358 }
@@ -354,35 +436,28 @@ impl BlobFactory {
354436 )
355437 }
356438
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-
367439 /// Creates a preconfirmed block for the given block. Should be called for the last block only -
368440 /// no commitment is computed.
369- fn make_preconfirmed_block_from_remaining_txs ( & self ) -> CendeWritePreconfirmedBlock {
370- let block_context = self . next_block_context ( ) ;
441+ fn make_preconfirmed_block_from_remaining_txs (
442+ block_context : BlockContext ,
443+ txs : Vec < TxPair > ,
444+ state : DictStateReader ,
445+ ) -> CendeWritePreconfirmedBlock {
371446 let block_info = block_context. block_info ( ) . clone ( ) ;
372447 let mut transactions = vec ! [ ] ;
373448 let mut transaction_receipts = vec ! [ ] ;
374449 let mut transaction_state_diffs = vec ! [ ] ;
375450
376- for ( tx_index, ( executable, internal) ) in self . next_txs . iter ( ) . enumerate ( ) {
451+ for ( tx_index, ( executable, internal) ) in txs . into_iter ( ) . enumerate ( ) {
377452 let tx_hash = match & internal {
378453 InternalConsensusTransaction :: RpcTransaction ( tx) => tx. tx_hash ,
379454 InternalConsensusTransaction :: L1Handler ( _) => {
380455 panic ! ( "unexpected L1Handler in test" )
381456 }
382457 } ;
383458
384- let mut tx_state = CachedState :: new ( self . state . clone ( ) ) ;
385- let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable. clone ( ) )
459+ let mut tx_state = CachedState :: new ( state. clone ( ) ) ;
460+ let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable)
386461 . execute ( & mut tx_state, & block_context)
387462 . unwrap ( ) ;
388463
@@ -396,7 +471,7 @@ impl BlobFactory {
396471 ) ) ;
397472 let tx_state_diff = StarknetClientStateDiff :: from ( state_changes. state_maps ) . 0 ;
398473
399- transactions. push ( CendePreconfirmedTransaction :: from ( internal. clone ( ) ) ) ;
474+ transactions. push ( CendePreconfirmedTransaction :: from ( internal) ) ;
400475 transaction_receipts. push ( Some ( receipt) ) ;
401476 transaction_state_diffs. push ( Some ( tx_state_diff) ) ;
402477 }
0 commit comments