Skip to content

Commit bad84a1

Browse files
blockifier_reexecution: use StateReaderAndContractManager in reexecution crate
1 parent 77f12ea commit bad84a1

File tree

6 files changed

+126
-24
lines changed

6 files changed

+126
-24
lines changed

crates/blockifier_reexecution/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ license.workspace = true
77

88
[features]
99
blockifier_regression_https_testing = []
10+
cairo_native = ["blockifier/cairo_native"]
1011

1112
[dependencies]
1213
apollo_compile_to_casm.workspace = true

crates/blockifier_reexecution/src/main.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use std::fs;
22
use std::path::Path;
33

44
use apollo_gateway_config::config::RpcStateReaderConfig;
5+
use blockifier::blockifier::config::ContractClassManagerConfig;
6+
use blockifier::state::contract_class_manager::ContractClassManager;
57
use blockifier_reexecution::state_reader::cli::{
68
parse_block_numbers_args,
79
BlockifierReexecutionCliArgs,
@@ -50,24 +52,32 @@ async fn main() {
5052
+ RESOURCES_DIR
5153
};
5254

55+
// Initialize the contract class manager.
56+
let mut contract_class_manager_config = ContractClassManagerConfig::default();
57+
if cfg!(feature = "cairo_native") {
58+
contract_class_manager_config.cairo_native_run_config.wait_on_native_compilation = true;
59+
contract_class_manager_config.cairo_native_run_config.run_cairo_native = true;
60+
}
61+
let contract_class_manager = ContractClassManager::start(contract_class_manager_config);
62+
5363
match args.command {
5464
Command::RpcTest { block_number, rpc_args } => {
5565
println!(
5666
"Running RPC test for block number {block_number} using node url {}.",
5767
rpc_args.node_url
5868
);
5969

60-
let config = RpcStateReaderConfig::from_url(rpc_args.node_url.clone());
61-
70+
let rpc_state_reader_config = RpcStateReaderConfig::from_url(rpc_args.node_url.clone());
6271
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
6372
// for details), so should be executed in a blocking thread.
6473
// TODO(Aner): make only the RPC calls blocking, not the whole function.
6574
tokio::task::spawn_blocking(move || {
6675
reexecute_and_verify_correctness(ConsecutiveTestStateReaders::new(
6776
BlockNumber(block_number - 1),
68-
Some(config),
77+
Some(rpc_state_reader_config),
6978
rpc_args.parse_chain_id(),
7079
false,
80+
contract_class_manager,
7181
))
7282
})
7383
.await
@@ -92,11 +102,17 @@ async fn main() {
92102

93103
let (node_url, chain_id) = (rpc_args.node_url.clone(), rpc_args.parse_chain_id());
94104

95-
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
105+
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn_blocking)
96106
// for details), so should be executed in a blocking thread.
97107
// TODO(Aner): make only the RPC calls blocking, not the whole function.
98108
tokio::task::spawn_blocking(move || {
99-
execute_single_transaction(BlockNumber(block_number), node_url, chain_id, tx_input)
109+
execute_single_transaction(
110+
BlockNumber(block_number),
111+
node_url,
112+
chain_id,
113+
tx_input,
114+
contract_class_manager,
115+
)
100116
})
101117
.await
102118
.unwrap()
@@ -115,6 +131,8 @@ async fn main() {
115131
for block_number in block_numbers {
116132
let full_file_path = block_full_file_path(directory_path.clone(), block_number);
117133
let (node_url, chain_id) = (rpc_args.node_url.clone(), rpc_args.parse_chain_id());
134+
let contract_class_manager = contract_class_manager.clone();
135+
118136
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
119137
// for details), so should be executed in a blocking thread.
120138
// TODO(Aner): make only the RPC calls blocking, not the whole function.
@@ -126,6 +144,7 @@ async fn main() {
126144
full_file_path,
127145
node_url,
128146
chain_id,
147+
contract_class_manager,
129148
)
130149
})
131150
.await
@@ -144,9 +163,14 @@ async fn main() {
144163
let mut task_set = tokio::task::JoinSet::new();
145164
for block in block_numbers {
146165
let full_file_path = block_full_file_path(directory_path.clone(), block);
166+
let contract_class_manager = contract_class_manager.clone();
147167
task_set.spawn(async move {
148168
reexecute_and_verify_correctness(
149-
OfflineConsecutiveStateReaders::new_from_file(&full_file_path).unwrap(),
169+
OfflineConsecutiveStateReaders::new_from_file(
170+
&full_file_path,
171+
contract_class_manager,
172+
)
173+
.unwrap(),
150174
);
151175
println!("Reexecution test for block {block} passed successfully.");
152176
});

crates/blockifier_reexecution/src/state_reader/offline_state_reader.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ use blockifier::bouncer::BouncerConfig;
88
use blockifier::context::BlockContext;
99
use blockifier::execution::contract_class::RunnableCompiledClass;
1010
use blockifier::state::cached_state::{CommitmentStateDiff, StateMaps};
11+
use blockifier::state::contract_class_manager::ContractClassManager;
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::{
16+
FetchCompiledClasses,
17+
StateReaderAndContractManager,
18+
};
1519
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
1620
use serde::{Deserialize, Serialize};
1721
use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockInfo, BlockNumber, StarknetVersion};
@@ -213,14 +217,23 @@ impl OfflineStateReader {
213217
self,
214218
block_context_next_block: BlockContext,
215219
transaction_executor_config: Option<TransactionExecutorConfig>,
216-
) -> ReexecutionResult<TransactionExecutor<OfflineStateReader>> {
220+
contract_class_manager: &ContractClassManager,
221+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<OfflineStateReader>>>
222+
{
217223
let old_block_number = BlockNumber(
218224
block_context_next_block.block_info().block_number.0
219225
- constants::STORED_BLOCK_HASH_BUFFER,
220226
);
221227
let hash = self.old_block_hash;
222-
Ok(TransactionExecutor::<OfflineStateReader>::pre_process_and_create(
228+
// We don't collect class cache metrics for the reexecution.
229+
let class_cache_metrics = None;
230+
let state_reader_and_contract_manager = StateReaderAndContractManager::new(
223231
self,
232+
contract_class_manager.clone(),
233+
class_cache_metrics,
234+
);
235+
Ok(TransactionExecutor::<StateReaderAndContractManager<OfflineStateReader>>::pre_process_and_create(
236+
state_reader_and_contract_manager,
224237
block_context_next_block,
225238
Some(BlockHashAndNumber { number: old_block_number, hash }),
226239
transaction_executor_config.unwrap_or_default(),
@@ -233,13 +246,17 @@ pub struct OfflineConsecutiveStateReaders {
233246
pub block_context_next_block: BlockContext,
234247
pub transactions_next_block: Vec<BlockifierTransaction>,
235248
pub state_diff_next_block: CommitmentStateDiff,
249+
contract_class_manager: ContractClassManager,
236250
}
237251

238252
impl OfflineConsecutiveStateReaders {
239-
pub fn new_from_file(full_file_path: &str) -> ReexecutionResult<Self> {
253+
pub fn new_from_file(
254+
full_file_path: &str,
255+
contract_class_manager: ContractClassManager,
256+
) -> ReexecutionResult<Self> {
240257
let serializable_offline_reexecution_data =
241258
SerializableOfflineReexecutionData::read_from_file(full_file_path)?;
242-
Ok(Self::new(serializable_offline_reexecution_data.into()))
259+
Ok(Self::new(serializable_offline_reexecution_data.into(), contract_class_manager))
243260
}
244261

245262
pub fn new(
@@ -249,23 +266,31 @@ impl OfflineConsecutiveStateReaders {
249266
transactions_next_block,
250267
state_diff_next_block,
251268
}: OfflineReexecutionData,
269+
contract_class_manager: ContractClassManager,
252270
) -> Self {
253271
Self {
254272
offline_state_reader_prev_block,
255273
block_context_next_block,
256274
transactions_next_block,
257275
state_diff_next_block,
276+
contract_class_manager,
258277
}
259278
}
260279
}
261280

262-
impl ConsecutiveReexecutionStateReaders<OfflineStateReader> for OfflineConsecutiveStateReaders {
281+
impl ConsecutiveReexecutionStateReaders<StateReaderAndContractManager<OfflineStateReader>>
282+
for OfflineConsecutiveStateReaders
283+
{
263284
fn pre_process_and_create_executor(
264285
self,
265286
transaction_executor_config: Option<TransactionExecutorConfig>,
266-
) -> ReexecutionResult<TransactionExecutor<OfflineStateReader>> {
267-
self.offline_state_reader_prev_block
268-
.get_transaction_executor(self.block_context_next_block, transaction_executor_config)
287+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<OfflineStateReader>>>
288+
{
289+
self.offline_state_reader_prev_block.get_transaction_executor(
290+
self.block_context_next_block,
291+
transaction_executor_config,
292+
&self.contract_class_manager,
293+
)
269294
}
270295

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

crates/blockifier_reexecution/src/state_reader/rpc_https_test.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use apollo_gateway::rpc_objects::BlockId;
1616
use apollo_gateway::rpc_state_reader::RpcStateReader;
1717
use apollo_gateway_config::config::RpcStateReaderConfig;
1818
use assert_matches::assert_matches;
19+
use blockifier::blockifier::config::ContractClassManagerConfig;
20+
use blockifier::state::contract_class_manager::ContractClassManager;
1921
use rstest::{fixture, rstest};
2022
use starknet_api::block::{BlockInfo, BlockNumber};
2123
use starknet_api::class_hash;
@@ -115,11 +117,23 @@ pub fn last_constructed_block(test_block_number: BlockNumber) -> BlockNumber {
115117
BlockNumber(test_block_number.0 - 1)
116118
}
117119

120+
#[fixture]
121+
pub fn contract_class_manager() -> ContractClassManager {
122+
ContractClassManager::start(ContractClassManagerConfig::default())
123+
}
124+
118125
#[fixture]
119126
pub fn test_state_readers_last_and_current_block(
120127
last_constructed_block: BlockNumber,
128+
contract_class_manager: ContractClassManager,
121129
) -> ConsecutiveTestStateReaders {
122-
ConsecutiveTestStateReaders::new(last_constructed_block, None, ChainId::Mainnet, false)
130+
ConsecutiveTestStateReaders::new(
131+
last_constructed_block,
132+
None,
133+
ChainId::Mainnet,
134+
false,
135+
contract_class_manager,
136+
)
123137
}
124138

125139
/// Test that the block info can be retrieved from the RPC server.

crates/blockifier_reexecution/src/state_reader/test_state_reader.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ use blockifier::bouncer::BouncerConfig;
1414
use blockifier::context::BlockContext;
1515
use blockifier::execution::contract_class::RunnableCompiledClass;
1616
use blockifier::state::cached_state::CommitmentStateDiff;
17+
use blockifier::state::contract_class_manager::ContractClassManager;
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::{
22+
FetchCompiledClasses,
23+
StateReaderAndContractManager,
24+
};
2125
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
2226
use serde::Serialize;
2327
use serde_json::{json, to_value};
@@ -289,14 +293,23 @@ impl TestStateReader {
289293
self,
290294
block_context_next_block: BlockContext,
291295
transaction_executor_config: Option<TransactionExecutorConfig>,
292-
) -> ReexecutionResult<TransactionExecutor<TestStateReader>> {
296+
contract_class_manager: &ContractClassManager,
297+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<TestStateReader>>>
298+
{
293299
let old_block_number = BlockNumber(
294300
block_context_next_block.block_info().block_number.0
295301
- constants::STORED_BLOCK_HASH_BUFFER,
296302
);
297303
let old_block_hash = self.get_old_block_hash(old_block_number)?;
298-
Ok(TransactionExecutor::<TestStateReader>::pre_process_and_create(
304+
// We don't collect class cache metrics for the reexecution.
305+
let class_cache_metrics = None;
306+
let state_reader_and_contract_manager = StateReaderAndContractManager::new(
299307
self,
308+
contract_class_manager.clone(),
309+
class_cache_metrics,
310+
);
311+
Ok(TransactionExecutor::<StateReaderAndContractManager<TestStateReader>>::pre_process_and_create(
312+
state_reader_and_contract_manager,
300313
block_context_next_block,
301314
Some(BlockHashAndNumber { number: old_block_number, hash: old_block_hash }),
302315
transaction_executor_config.unwrap_or_default(),
@@ -395,6 +408,7 @@ impl ReexecutionStateReader for TestStateReader {
395408
pub struct ConsecutiveTestStateReaders {
396409
pub last_block_state_reader: TestStateReader,
397410
pub next_block_state_reader: TestStateReader,
411+
contract_class_manager: ContractClassManager,
398412
}
399413

400414
impl ConsecutiveTestStateReaders {
@@ -403,6 +417,7 @@ impl ConsecutiveTestStateReaders {
403417
config: Option<RpcStateReaderConfig>,
404418
chain_id: ChainId,
405419
dump_mode: bool,
420+
contract_class_manager: ContractClassManager,
406421
) -> Self {
407422
let config = config.unwrap_or(get_rpc_state_reader_config());
408423
Self {
@@ -418,6 +433,7 @@ impl ConsecutiveTestStateReaders {
418433
last_constructed_block_number.next().expect("Overflow in block number"),
419434
dump_mode,
420435
),
436+
contract_class_manager,
421437
}
422438
}
423439

@@ -457,14 +473,18 @@ impl ConsecutiveTestStateReaders {
457473
}
458474
}
459475

460-
impl ConsecutiveReexecutionStateReaders<TestStateReader> for ConsecutiveTestStateReaders {
476+
impl ConsecutiveReexecutionStateReaders<StateReaderAndContractManager<TestStateReader>>
477+
for ConsecutiveTestStateReaders
478+
{
461479
fn pre_process_and_create_executor(
462480
self,
463481
transaction_executor_config: Option<TransactionExecutorConfig>,
464-
) -> ReexecutionResult<TransactionExecutor<TestStateReader>> {
482+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<TestStateReader>>>
483+
{
465484
self.last_block_state_reader.get_transaction_executor(
466485
self.next_block_state_reader.get_block_context()?,
467486
transaction_executor_config,
487+
&self.contract_class_manager,
468488
)
469489
}
470490

0 commit comments

Comments
 (0)