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,74 @@ 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 hash of the previous block.
133+ fn from ( block : BlockData ) -> Self {
134+ let BlockData {
135+ block_context,
136+ transactions_with_receipts,
137+ partial_block_hash_components,
138+ parent_partial_block_hash_components,
139+ parent_block_hash,
140+ state_maps,
141+ ..
142+ } = block;
143+ let commitment_state_diff = CommitmentStateDiff :: from ( state_maps) ;
144+ let state_diff = ThinStateDiff :: from ( commitment_state_diff. clone ( ) ) ;
145+ let block_info = block_context. block_info ( ) . clone ( ) ;
146+ let proposal_commitment = ProposalCommitment (
147+ PartialBlockHash :: from_partial_block_hash_components ( & partial_block_hash_components)
148+ . unwrap ( )
149+ . 0 ,
150+ ) ;
151+
152+ let ( recent_block_hashes, parent_proposal_commitment) = if block_info. block_number . 0 > 0 {
153+ (
154+ vec ! [ BlockHashAndNumber {
155+ number: BlockNumber ( block_info. block_number. 0 - 1 ) ,
156+ hash: parent_block_hash,
157+ } ] ,
158+ Some ( ProposalCommitment (
159+ PartialBlockHash :: from_partial_block_hash_components (
160+ & parent_partial_block_hash_components. unwrap ( ) ,
161+ )
162+ . unwrap ( )
163+ . 0 ,
164+ ) ) ,
165+ )
166+ } else {
167+ ( vec ! [ ] , None )
168+ } ;
169+
170+ Self {
171+ block_info,
172+ state_diff,
173+ compressed_state_diff : Some ( commitment_state_diff) ,
174+ transactions_with_execution_infos : transactions_with_receipts,
175+ bouncer_weights : BouncerWeights :: default ( ) ,
176+ fee_market_info : FeeMarketInfo :: default ( ) ,
177+ casm_hash_computation_data_sierra_gas : CasmHashComputationData :: default ( ) ,
178+ casm_hash_computation_data_proving_gas : CasmHashComputationData :: default ( ) ,
179+ compiled_class_hashes_for_migration : vec ! [ ] ,
180+ proposal_commitment,
181+ parent_proposal_commitment,
182+ recent_block_hashes,
183+ }
184+ }
185+ }
186+
126187struct BlobFactory {
127188 chain_info : ChainInfo ,
128189 class_manager : MockClassManagerClient ,
@@ -233,10 +294,13 @@ impl BlobFactory {
233294 . await ;
234295 let partial_block_hash_components =
235296 PartialBlockHashComponents :: new ( & block_info, block_header_commitments) ;
297+ let parent_block_hash = self . last_finalized_block_hash ( ) ;
298+ let parent_partial_block_hash_components =
299+ self . last_finalized_partial_block_hash_components ( ) ;
236300 let block_hash = calculate_block_hash (
237301 & partial_block_hash_components,
238302 state_roots. global_root ( ) ,
239- self . last_finalized_block_hash ( ) ,
303+ parent_block_hash ,
240304 )
241305 . unwrap ( ) ;
242306
@@ -245,7 +309,9 @@ impl BlobFactory {
245309 block_context,
246310 transactions_with_receipts,
247311 partial_block_hash_components,
312+ parent_partial_block_hash_components,
248313 block_hash,
314+ parent_block_hash,
249315 state_maps,
250316 state_roots,
251317 } ) ;
@@ -254,11 +320,28 @@ impl BlobFactory {
254320 /// Creates blobs for all finalized blocks, and a preconfirmed block with the remaining txs that
255321 /// were not included in a block. See [Self::close_block] for details on how to close a block.
256322 async fn finalize ( self ) -> ( Vec < AerospikeBlob > , CendeWritePreconfirmedBlock ) {
257- // TODO(Dori): Create the blob vector.
258- let blobs = vec ! [ ] ;
323+ let preconfirmed_block_context = self . next_block_context ( ) ;
324+ let Self { blocks, class_manager, next_txs, state, .. } = self ;
325+ let mut blobs = vec ! [ ] ;
326+ let shared_class_manager = Arc :: new ( class_manager) ;
259327
260328 // For the last block, create a preconfirmed block.
261- let preconfirmed_block = self . make_preconfirmed_block_from_remaining_txs ( ) ;
329+ let preconfirmed_block = Self :: make_preconfirmed_block_from_remaining_txs (
330+ preconfirmed_block_context,
331+ next_txs,
332+ state,
333+ ) ;
334+
335+ for block in blocks. into_iter ( ) {
336+ blobs. push (
337+ AerospikeBlob :: from_blob_parameters_and_class_manager (
338+ block. into ( ) ,
339+ shared_class_manager. clone ( ) ,
340+ )
341+ . await
342+ . unwrap ( ) ,
343+ ) ;
344+ }
262345
263346 ( blobs, preconfirmed_block)
264347 }
@@ -267,6 +350,10 @@ impl BlobFactory {
267350 self . blocks . last ( ) . map ( |block| block. block_hash ) . unwrap_or ( BlockHash :: GENESIS_PARENT_HASH )
268351 }
269352
353+ fn last_finalized_partial_block_hash_components ( & self ) -> Option < PartialBlockHashComponents > {
354+ self . blocks . last ( ) . map ( |block| block. partial_block_hash_components . clone ( ) )
355+ }
356+
270357 fn last_finalized_state_roots ( & self ) -> StateRoots {
271358 self . blocks . last ( ) . map ( |block| block. state_roots ) . unwrap_or_default ( )
272359 }
@@ -350,27 +437,19 @@ impl BlobFactory {
350437 )
351438 }
352439
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-
363440 /// Creates a preconfirmed block for the given block. Should be called for the last block only -
364441 /// no commitment is computed.
365- fn make_preconfirmed_block_from_remaining_txs ( self ) -> CendeWritePreconfirmedBlock {
366- let block_context = self . next_block_context ( ) ;
442+ fn make_preconfirmed_block_from_remaining_txs (
443+ block_context : BlockContext ,
444+ txs : Vec < TxPair > ,
445+ mut state : DictStateReader ,
446+ ) -> CendeWritePreconfirmedBlock {
367447 let block_info = block_context. block_info ( ) . clone ( ) ;
368448 let mut transactions = vec ! [ ] ;
369449 let mut transaction_receipts = vec ! [ ] ;
370450 let mut transaction_state_diffs = vec ! [ ] ;
371- let Self { mut state, next_txs, .. } = self ;
372451
373- for ( tx_index, ( executable, internal) ) in next_txs . into_iter ( ) . enumerate ( ) {
452+ for ( tx_index, ( executable, internal) ) in txs . into_iter ( ) . enumerate ( ) {
374453 let tx_hash = match & internal {
375454 InternalConsensusTransaction :: RpcTransaction ( tx) => tx. tx_hash ,
376455 InternalConsensusTransaction :: L1Handler ( _) => {
@@ -379,7 +458,7 @@ impl BlobFactory {
379458 } ;
380459
381460 let mut tx_state = CachedState :: new ( state. clone ( ) ) ;
382- let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable. clone ( ) )
461+ let execution_info = BlockifierAccountTx :: new_for_sequencing ( executable)
383462 . execute ( & mut tx_state, & block_context)
384463 . unwrap ( ) ;
385464
@@ -393,7 +472,7 @@ impl BlobFactory {
393472 ) ) ;
394473 let tx_state_diff = StarknetClientStateDiff :: from ( state_changes. state_maps ) . 0 ;
395474
396- transactions. push ( CendePreconfirmedTransaction :: from ( internal. clone ( ) ) ) ;
475+ transactions. push ( CendePreconfirmedTransaction :: from ( internal) ) ;
397476 transaction_receipts. push ( Some ( receipt) ) ;
398477 transaction_state_diffs. push ( Some ( tx_state_diff) ) ;
399478
0 commit comments