Skip to content

Commit 9c6fcc0

Browse files
central_systest_blobs: implement blob creation from blocks
1 parent eb6a3de commit 9c6fcc0

1 file changed

Lines changed: 102 additions & 23 deletions

File tree

crates/central_systest_blobs/src/cende_blob_regression_test.rs

Lines changed: 102 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::path::PathBuf;
2-
use std::sync::LazyLock;
2+
use std::sync::{Arc, LazyLock};
33
use std::{env, fs};
44

55
use apollo_batcher::cende_client_types::{
@@ -12,17 +12,19 @@ use apollo_batcher::cende_client_types::{
1212
use apollo_batcher::pre_confirmed_cende_client::CendeWritePreconfirmedBlock;
1313
use apollo_batcher_types::batcher_types::Round;
1414
use apollo_class_manager_types::MockClassManagerClient;
15+
use apollo_consensus::types::ProposalCommitment;
1516
use apollo_consensus_orchestrator::cende::{
1617
AerospikeBlob,
1718
BlobParameters,
1819
InternalTransactionWithReceipt,
1920
};
21+
use apollo_consensus_orchestrator::fee_market::FeeMarketInfo;
2022
use apollo_infra_utils::compile_time_cargo_manifest_dir;
2123
use blockifier::abi::constants::STORED_BLOCK_HASH_BUFFER;
2224
use blockifier::blockifier::config::TransactionExecutorConfig;
2325
use blockifier::blockifier::transaction_executor::TransactionExecutor;
2426
use blockifier::blockifier_versioned_constants::VersionedConstants;
25-
use blockifier::bouncer::BouncerConfig;
27+
use blockifier::bouncer::{BouncerConfig, BouncerWeights, CasmHashComputationData};
2628
use blockifier::context::{BlockContext, ChainInfo};
2729
use blockifier::state::cached_state::{CachedState, CommitmentStateDiff, StateMaps};
2830
use blockifier::state::state_api::UpdatableState;
@@ -44,6 +46,7 @@ use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockInfo, BlockNumber,
4446
use 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)]
117119
struct 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+
126187
struct 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

Comments
 (0)