Skip to content

Commit c765f73

Browse files
blockifier_reexecution: use StateReaderAndContractManager in reexecution crate
1 parent c6dfa24 commit c765f73

File tree

6 files changed

+65
-22
lines changed

6 files changed

+65
-22
lines changed

crates/blockifier_reexecution/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ apollo_gateway_config.workspace = true
1616
apollo_rpc_execution.workspace = true
1717
apollo_sierra_compilation_config.workspace = true
1818
assert_matches.workspace = true
19-
blockifier = { workspace = true, features = ["reexecution"] }
19+
blockifier = { workspace = true, features = ["reexecution", "cairo_native"] }
2020
clap = { workspace = true, features = ["cargo", "derive"] }
2121
flate2.workspace = true
2222
google-cloud-storage.workspace = true

crates/blockifier_reexecution/src/main.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,19 @@ async fn main() {
197197
rpc_args.node_url
198198
);
199199

200-
let config = RpcStateReaderConfig::from_url(rpc_args.node_url.clone());
200+
let rpc_state_reader_config = RpcStateReaderConfig::from_url(rpc_args.node_url.clone());
201+
let contract_class_manager = create_contract_class_manager();
201202

202203
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
203204
// for details), so should be executed in a blocking thread.
204205
// TODO(Aner): make only the RPC calls blocking, not the whole function.
205206
tokio::task::spawn_blocking(move || {
206207
reexecute_and_verify_correctness(ConsecutiveTestStateReaders::new(
207208
BlockNumber(block_number - 1),
208-
Some(config),
209+
Some(rpc_state_reader_config),
209210
rpc_args.parse_chain_id(),
210211
false,
211-
))
212+
), &contract_class_manager)
212213
})
213214
.await
214215
.unwrap();
@@ -227,6 +228,8 @@ async fn main() {
227228

228229
let (node_url, chain_id) = (rpc_args.node_url.clone(), rpc_args.parse_chain_id());
229230

231+
let contract_class_manager = create_contract_class_manager();
232+
230233
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
231234
// for details), so should be executed in a blocking thread.
232235
// TODO(Aner): make only the RPC calls blocking, not the whole function.
@@ -236,6 +239,7 @@ async fn main() {
236239
node_url,
237240
chain_id,
238241
transaction_path,
242+
&contract_class_manager,
239243
)
240244
})
241245
.await
@@ -251,10 +255,14 @@ async fn main() {
251255
let block_numbers = parse_block_numbers_args(block_numbers);
252256
println!("Computing reexecution data for blocks {block_numbers:?}.");
253257

258+
let contract_class_manager = Arc::new(create_contract_class_manager());
259+
254260
let mut task_set = tokio::task::JoinSet::new();
255261
for block_number in block_numbers {
256262
let full_file_path = block_full_file_path(directory_path.clone(), block_number);
257263
let (node_url, chain_id) = (rpc_args.node_url.clone(), rpc_args.parse_chain_id());
264+
let contract_class_manager_shared = Arc::clone(&contract_class_manager);
265+
258266
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
259267
// for details), so should be executed in a blocking thread.
260268
// TODO(Aner): make only the RPC calls blocking, not the whole function.
@@ -266,6 +274,7 @@ async fn main() {
266274
full_file_path,
267275
node_url,
268276
chain_id,
277+
&contract_class_manager_shared,
269278
)
270279
})
271280
.await
@@ -281,12 +290,16 @@ async fn main() {
281290
let block_numbers = parse_block_numbers_args(block_numbers);
282291
println!("Reexecuting blocks {block_numbers:?}.");
283292

293+
let contract_class_manager = Arc::new(create_contract_class_manager());
294+
284295
let mut task_set = tokio::task::JoinSet::new();
285296
for block in block_numbers {
286297
let full_file_path = block_full_file_path(directory_path.clone(), block);
298+
let contract_class_manager_shared = Arc::clone(&contract_class_manager);
287299
task_set.spawn(async move {
288300
reexecute_and_verify_correctness(
289301
OfflineConsecutiveStateReaders::new_from_file(&full_file_path).unwrap(),
302+
&contract_class_manager_shared,
290303
);
291304
println!("Reexecution test for block {block} passed successfully.");
292305
});

crates/blockifier_reexecution/src/state_reader/offline_state_reader.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ use blockifier::blockifier_versioned_constants::VersionedConstants;
77
use blockifier::bouncer::BouncerConfig;
88
use blockifier::context::BlockContext;
99
use blockifier::execution::contract_class::RunnableCompiledClass;
10+
use blockifier::state::contract_class_manager::ContractClassManager;
1011
use blockifier::state::cached_state::{CommitmentStateDiff, StateMaps};
1112
use blockifier::state::errors::StateError;
1213
use blockifier::state::global_cache::CompiledClasses;
1314
use blockifier::state::state_api::{StateReader, StateResult};
14-
use blockifier::state::state_reader_and_contract_manager::FetchCompiledClasses;
15+
use blockifier::state::state_reader_and_contract_manager::{FetchCompiledClasses, StateReaderAndContractManager};
1516
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
1617
use serde::{Deserialize, Serialize};
1718
use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockInfo, BlockNumber, StarknetVersion};
@@ -209,14 +210,19 @@ impl OfflineStateReader {
209210
self,
210211
block_context_next_block: BlockContext,
211212
transaction_executor_config: Option<TransactionExecutorConfig>,
212-
) -> ReexecutionResult<TransactionExecutor<OfflineStateReader>> {
213+
contract_class_manager: &ContractClassManager,
214+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<OfflineStateReader>>> {
213215
let old_block_number = BlockNumber(
214216
block_context_next_block.block_info().block_number.0
215217
- constants::STORED_BLOCK_HASH_BUFFER,
216218
);
217219
let hash = self.old_block_hash;
218-
Ok(TransactionExecutor::<OfflineStateReader>::pre_process_and_create(
219-
self,
220+
let state_reader_and_contract_manager = StateReaderAndContractManager {
221+
state_reader: self,
222+
contract_class_manager: contract_class_manager.clone(),
223+
};
224+
Ok(TransactionExecutor::<StateReaderAndContractManager<OfflineStateReader>>::pre_process_and_create(
225+
state_reader_and_contract_manager,
220226
block_context_next_block,
221227
Some(BlockHashAndNumber { number: old_block_number, hash }),
222228
transaction_executor_config.unwrap_or_default(),
@@ -255,13 +261,14 @@ impl OfflineConsecutiveStateReaders {
255261
}
256262
}
257263

258-
impl ConsecutiveReexecutionStateReaders<OfflineStateReader> for OfflineConsecutiveStateReaders {
264+
impl ConsecutiveReexecutionStateReaders<StateReaderAndContractManager<OfflineStateReader>> for OfflineConsecutiveStateReaders {
259265
fn pre_process_and_create_executor(
260266
self,
261267
transaction_executor_config: Option<TransactionExecutorConfig>,
262-
) -> ReexecutionResult<TransactionExecutor<OfflineStateReader>> {
268+
contract_class_manager: &ContractClassManager,
269+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<OfflineStateReader>>> {
263270
self.offline_state_reader_prev_block
264-
.get_transaction_executor(self.block_context_next_block, transaction_executor_config)
271+
.get_transaction_executor(self.block_context_next_block, transaction_executor_config, contract_class_manager)
265272
}
266273

267274
fn get_next_block_txs(&self) -> ReexecutionResult<Vec<BlockifierTransaction>> {

crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use blockifier::blockifier::config::TransactionExecutorConfig;
33
use blockifier::blockifier::transaction_executor::TransactionExecutor;
44
use blockifier::state::cached_state::CommitmentStateDiff;
55
use blockifier::state::errors::StateError;
6+
use blockifier::state::contract_class_manager::ContractClassManager;
67
use blockifier::state::global_cache::CompiledClasses;
78
use blockifier::state::state_api::{StateReader, StateResult};
89
use blockifier::transaction::account_transaction::ExecutionFlags;
@@ -131,6 +132,7 @@ pub trait ConsecutiveReexecutionStateReaders<S: StateReader> {
131132
fn pre_process_and_create_executor(
132133
self,
133134
transaction_executor_config: Option<TransactionExecutorConfig>,
135+
contract_class_manager: &ContractClassManager,
134136
) -> ReexecutionResult<TransactionExecutor<S>>;
135137

136138
fn get_next_block_txs(&self) -> ReexecutionResult<Vec<BlockifierTransaction>>;

crates/blockifier_reexecution/src/state_reader/test_state_reader.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ use blockifier::blockifier::config::TransactionExecutorConfig;
1111
use blockifier::blockifier::transaction_executor::TransactionExecutor;
1212
use blockifier::blockifier_versioned_constants::VersionedConstants;
1313
use blockifier::bouncer::BouncerConfig;
14+
use blockifier::state::contract_class_manager::ContractClassManager;
1415
use blockifier::context::BlockContext;
1516
use blockifier::execution::contract_class::RunnableCompiledClass;
1617
use blockifier::state::cached_state::CommitmentStateDiff;
1718
use blockifier::state::errors::StateError;
1819
use blockifier::state::global_cache::CompiledClasses;
1920
use blockifier::state::state_api::{StateReader, StateResult};
20-
use blockifier::state::state_reader_and_contract_manager::FetchCompiledClasses;
21+
use blockifier::state::state_reader_and_contract_manager::{FetchCompiledClasses, StateReaderAndContractManager};
2122
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
2223
use serde::Serialize;
2324
use serde_json::{json, to_value};
@@ -285,14 +286,19 @@ impl TestStateReader {
285286
self,
286287
block_context_next_block: BlockContext,
287288
transaction_executor_config: Option<TransactionExecutorConfig>,
288-
) -> ReexecutionResult<TransactionExecutor<TestStateReader>> {
289+
contract_class_manager: &ContractClassManager,
290+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<TestStateReader>>> {
289291
let old_block_number = BlockNumber(
290292
block_context_next_block.block_info().block_number.0
291293
- constants::STORED_BLOCK_HASH_BUFFER,
292294
);
293295
let old_block_hash = self.get_old_block_hash(old_block_number)?;
294-
Ok(TransactionExecutor::<TestStateReader>::pre_process_and_create(
295-
self,
296+
let state_reader_and_contract_manager = StateReaderAndContractManager {
297+
state_reader: self,
298+
contract_class_manager: contract_class_manager.clone(),
299+
};
300+
Ok(TransactionExecutor::<StateReaderAndContractManager<TestStateReader>>::pre_process_and_create(
301+
state_reader_and_contract_manager,
296302
block_context_next_block,
297303
Some(BlockHashAndNumber { number: old_block_number, hash: old_block_hash }),
298304
transaction_executor_config.unwrap_or_default(),
@@ -453,14 +459,16 @@ impl ConsecutiveTestStateReaders {
453459
}
454460
}
455461

456-
impl ConsecutiveReexecutionStateReaders<TestStateReader> for ConsecutiveTestStateReaders {
462+
impl ConsecutiveReexecutionStateReaders<StateReaderAndContractManager<TestStateReader>> for ConsecutiveTestStateReaders {
457463
fn pre_process_and_create_executor(
458464
self,
459465
transaction_executor_config: Option<TransactionExecutorConfig>,
460-
) -> ReexecutionResult<TransactionExecutor<TestStateReader>> {
466+
contract_class_manager: &ContractClassManager,
467+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<TestStateReader>>> {
461468
self.last_block_state_reader.get_transaction_executor(
462469
self.next_block_state_reader.get_block_context()?,
463470
transaction_executor_config,
471+
contract_class_manager,
464472
)
465473
}
466474

crates/blockifier_reexecution/src/state_reader/utils.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use apollo_gateway_config::config::RpcStateReaderConfig;
77
use apollo_rpc_execution::{ETH_FEE_CONTRACT_ADDRESS, STRK_FEE_CONTRACT_ADDRESS};
88
use assert_matches::assert_matches;
99
use blockifier::context::{ChainInfo, FeeTokenAddresses};
10+
use blockifier::state::contract_class_manager::ContractClassManager;
11+
use blockifier::blockifier::config::ContractClassManagerConfig;
1012
use blockifier::state::cached_state::{CachedState, CommitmentStateDiff, StateMaps};
1113
use blockifier::state::state_api::StateReader;
1214
use indexmap::IndexMap;
@@ -39,6 +41,13 @@ pub static RPC_NODE_URL: LazyLock<String> = LazyLock::new(|| {
3941
.unwrap_or_else(|_| "https://free-rpc.nethermind.io/mainnet-juno/".to_string())
4042
});
4143

44+
pub fn create_contract_class_manager() -> ContractClassManager {
45+
let mut contract_class_manager_config = ContractClassManagerConfig::default();
46+
contract_class_manager_config.cairo_native_run_config.run_cairo_native = true;
47+
contract_class_manager_config.cairo_native_run_config.wait_on_native_compilation = true;
48+
ContractClassManager::start(contract_class_manager_config)
49+
}
50+
4251
pub fn guess_chain_id_from_node_url(node_url: &str) -> ReexecutionResult<ChainId> {
4352
match (
4453
node_url.contains("mainnet"),
@@ -223,17 +232,18 @@ impl From<CommitmentStateDiff> for ComparableStateDiff {
223232
}
224233

225234
pub fn reexecute_and_verify_correctness<
226-
S: StateReader + Send + Sync + Clone + 'static,
235+
S: StateReader + Send + Sync + 'static,
227236
T: ConsecutiveReexecutionStateReaders<S>,
228237
>(
229238
consecutive_state_readers: T,
239+
contract_class_manager: &ContractClassManager,
230240
) -> Option<CachedState<S>> {
231241
let expected_state_diff = consecutive_state_readers.get_next_block_state_diff().unwrap();
232242

233243
let all_txs_in_next_block = consecutive_state_readers.get_next_block_txs().unwrap();
234244

235245
let mut transaction_executor =
236-
consecutive_state_readers.pre_process_and_create_executor(None).unwrap();
246+
consecutive_state_readers.pre_process_and_create_executor(None, contract_class_manager).unwrap();
237247

238248
let execution_results = transaction_executor.execute_txs(&all_txs_in_next_block, None);
239249
// Verify all transactions executed successfully.
@@ -257,6 +267,7 @@ pub fn reexecute_block_for_testing(block_number: u64) {
257267

258268
reexecute_and_verify_correctness(
259269
OfflineConsecutiveStateReaders::new_from_file(&full_file_path).unwrap(),
270+
&create_contract_class_manager(),
260271
);
261272

262273
println!("Reexecution test for block {block_number} passed successfully.");
@@ -267,6 +278,7 @@ pub fn write_block_reexecution_data_to_file(
267278
full_file_path: String,
268279
node_url: String,
269280
chain_id: ChainId,
281+
contract_class_manager: &ContractClassManager,
270282
) {
271283
let config = RpcStateReaderConfig::from_url(node_url);
272284

@@ -283,10 +295,10 @@ pub fn write_block_reexecution_data_to_file(
283295
let old_block_hash = consecutive_state_readers.get_old_block_hash().unwrap();
284296

285297
// Run the reexecution test and get the state maps and contract class mapping.
286-
let block_state = reexecute_and_verify_correctness(consecutive_state_readers).unwrap();
298+
let block_state = reexecute_and_verify_correctness(consecutive_state_readers, contract_class_manager).unwrap();
287299
let serializable_data_prev_block = SerializableDataPrevBlock {
288300
state_maps: block_state.get_initial_reads().unwrap().into(),
289-
contract_class_mapping: block_state.state.get_contract_class_mapping_dumper().unwrap(),
301+
contract_class_mapping: block_state.state.state_reader.get_contract_class_mapping_dumper().unwrap(),
290302
};
291303

292304
// Write the reexecution data to a json file.
@@ -309,6 +321,7 @@ pub fn execute_single_transaction_from_json(
309321
node_url: String,
310322
chain_id: ChainId,
311323
transaction_json_path: String,
324+
contract_class_manager: &ContractClassManager,
312325
) -> ReexecutionResult<()> {
313326
// Load transaction from a JSON file.
314327
let json_content = read_to_string(&transaction_json_path).unwrap_or_else(|_| {
@@ -341,7 +354,7 @@ pub fn execute_single_transaction_from_json(
341354

342355
// Create transaction executor.
343356
let mut transaction_executor =
344-
consecutive_state_readers.pre_process_and_create_executor(None)?;
357+
consecutive_state_readers.pre_process_and_create_executor(None, contract_class_manager)?;
345358

346359
// Execute transaction (should be single element).
347360
let execution_results = transaction_executor.execute_txs(&blockifier_tx, None);

0 commit comments

Comments
 (0)