Skip to content

Commit 9c9a688

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

File tree

6 files changed

+135
-26
lines changed

6 files changed

+135
-26
lines changed

crates/blockifier_reexecution/Cargo.toml

Lines changed: 2 additions & 1 deletion
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
@@ -16,7 +17,7 @@ apollo_gateway_config.workspace = true
1617
apollo_rpc_execution.workspace = true
1718
apollo_sierra_compilation_config.workspace = true
1819
assert_matches.workspace = true
19-
blockifier = { workspace = true, features = ["reexecution"] }
20+
blockifier = { workspace = true, features = ["reexecution", "testing"] }
2021
clap = { workspace = true, features = ["cargo", "derive"] }
2122
flate2.workspace = true
2223
google-cloud-storage.workspace = true

crates/blockifier_reexecution/src/main.rs

Lines changed: 45 additions & 5 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,
@@ -57,17 +59,23 @@ async fn main() {
5759
rpc_args.node_url
5860
);
5961

60-
let config = RpcStateReaderConfig::from_url(rpc_args.node_url.clone());
62+
let rpc_state_reader_config = RpcStateReaderConfig::from_url(rpc_args.node_url.clone());
63+
let contract_class_manager =
64+
ContractClassManager::start(ContractClassManagerConfig::create_for_testing(
65+
cfg!(feature = "cairo_native"),
66+
cfg!(feature = "cairo_native"),
67+
));
6168

6269
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
6370
// for details), so should be executed in a blocking thread.
6471
// TODO(Aner): make only the RPC calls blocking, not the whole function.
6572
tokio::task::spawn_blocking(move || {
6673
reexecute_and_verify_correctness(ConsecutiveTestStateReaders::new(
6774
BlockNumber(block_number - 1),
68-
Some(config),
75+
Some(rpc_state_reader_config),
6976
rpc_args.parse_chain_id(),
7077
false,
78+
contract_class_manager,
7179
))
7280
})
7381
.await
@@ -92,11 +100,23 @@ async fn main() {
92100

93101
let (node_url, chain_id) = (rpc_args.node_url.clone(), rpc_args.parse_chain_id());
94102

95-
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
103+
let contract_class_manager =
104+
ContractClassManager::start(ContractClassManagerConfig::create_for_testing(
105+
cfg!(feature = "cairo_native"),
106+
cfg!(feature = "cairo_native"),
107+
));
108+
109+
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn_blocking)
96110
// for details), so should be executed in a blocking thread.
97111
// TODO(Aner): make only the RPC calls blocking, not the whole function.
98112
tokio::task::spawn_blocking(move || {
99-
execute_single_transaction(BlockNumber(block_number), node_url, chain_id, tx_input)
113+
execute_single_transaction(
114+
BlockNumber(block_number),
115+
node_url,
116+
chain_id,
117+
tx_input,
118+
contract_class_manager,
119+
)
100120
})
101121
.await
102122
.unwrap()
@@ -111,10 +131,18 @@ async fn main() {
111131
let block_numbers = parse_block_numbers_args(block_numbers);
112132
println!("Computing reexecution data for blocks {block_numbers:?}.");
113133

134+
let contract_class_manager =
135+
ContractClassManager::start(ContractClassManagerConfig::create_for_testing(
136+
cfg!(feature = "cairo_native"),
137+
cfg!(feature = "cairo_native"),
138+
));
139+
114140
let mut task_set = tokio::task::JoinSet::new();
115141
for block_number in block_numbers {
116142
let full_file_path = block_full_file_path(directory_path.clone(), block_number);
117143
let (node_url, chain_id) = (rpc_args.node_url.clone(), rpc_args.parse_chain_id());
144+
let contract_class_manager = contract_class_manager.clone();
145+
118146
// RPC calls are "synchronous IO" (see, e.g., https://stackoverflow.com/questions/74547541/when-should-you-use-tokios-spawn-blocking)
119147
// for details), so should be executed in a blocking thread.
120148
// TODO(Aner): make only the RPC calls blocking, not the whole function.
@@ -126,6 +154,7 @@ async fn main() {
126154
full_file_path,
127155
node_url,
128156
chain_id,
157+
contract_class_manager,
129158
)
130159
})
131160
.await
@@ -141,12 +170,23 @@ async fn main() {
141170
let block_numbers = parse_block_numbers_args(block_numbers);
142171
println!("Reexecuting blocks {block_numbers:?}.");
143172

173+
let contract_class_manager =
174+
ContractClassManager::start(ContractClassManagerConfig::create_for_testing(
175+
cfg!(feature = "cairo_native"),
176+
cfg!(feature = "cairo_native"),
177+
));
178+
144179
let mut task_set = tokio::task::JoinSet::new();
145180
for block in block_numbers {
146181
let full_file_path = block_full_file_path(directory_path.clone(), block);
182+
let contract_class_manager = contract_class_manager.clone();
147183
task_set.spawn(async move {
148184
reexecute_and_verify_correctness(
149-
OfflineConsecutiveStateReaders::new_from_file(&full_file_path).unwrap(),
185+
OfflineConsecutiveStateReaders::new_from_file(
186+
&full_file_path,
187+
contract_class_manager,
188+
)
189+
.unwrap(),
150190
);
151191
println!("Reexecution test for block {block} passed successfully.");
152192
});

crates/blockifier_reexecution/src/state_reader/offline_state_reader.rs

Lines changed: 30 additions & 10 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,18 @@ 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(
223-
self,
228+
let state_reader_and_contract_manager =
229+
StateReaderAndContractManager::new(self, contract_class_manager.clone(), None);
230+
Ok(TransactionExecutor::<StateReaderAndContractManager<OfflineStateReader>>::pre_process_and_create(
231+
state_reader_and_contract_manager,
224232
block_context_next_block,
225233
Some(BlockHashAndNumber { number: old_block_number, hash }),
226234
transaction_executor_config.unwrap_or_default(),
@@ -233,13 +241,17 @@ pub struct OfflineConsecutiveStateReaders {
233241
pub block_context_next_block: BlockContext,
234242
pub transactions_next_block: Vec<BlockifierTransaction>,
235243
pub state_diff_next_block: CommitmentStateDiff,
244+
contract_class_manager: ContractClassManager,
236245
}
237246

238247
impl OfflineConsecutiveStateReaders {
239-
pub fn new_from_file(full_file_path: &str) -> ReexecutionResult<Self> {
248+
pub fn new_from_file(
249+
full_file_path: &str,
250+
contract_class_manager: ContractClassManager,
251+
) -> ReexecutionResult<Self> {
240252
let serializable_offline_reexecution_data =
241253
SerializableOfflineReexecutionData::read_from_file(full_file_path)?;
242-
Ok(Self::new(serializable_offline_reexecution_data.into()))
254+
Ok(Self::new(serializable_offline_reexecution_data.into(), contract_class_manager))
243255
}
244256

245257
pub fn new(
@@ -249,23 +261,31 @@ impl OfflineConsecutiveStateReaders {
249261
transactions_next_block,
250262
state_diff_next_block,
251263
}: OfflineReexecutionData,
264+
contract_class_manager: ContractClassManager,
252265
) -> Self {
253266
Self {
254267
offline_state_reader_prev_block,
255268
block_context_next_block,
256269
transactions_next_block,
257270
state_diff_next_block,
271+
contract_class_manager,
258272
}
259273
}
260274
}
261275

262-
impl ConsecutiveReexecutionStateReaders<OfflineStateReader> for OfflineConsecutiveStateReaders {
276+
impl ConsecutiveReexecutionStateReaders<StateReaderAndContractManager<OfflineStateReader>>
277+
for OfflineConsecutiveStateReaders
278+
{
263279
fn pre_process_and_create_executor(
264280
self,
265281
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)
282+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<OfflineStateReader>>>
283+
{
284+
self.offline_state_reader_prev_block.get_transaction_executor(
285+
self.block_context_next_block,
286+
transaction_executor_config,
287+
&self.contract_class_manager,
288+
)
269289
}
270290

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

crates/blockifier_reexecution/src/state_reader/rpc_https_test.rs

Lines changed: 18 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,26 @@ 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::create_for_testing(
123+
cfg!(feature = "cairo_native"),
124+
cfg!(feature = "cairo_native"),
125+
))
126+
}
127+
118128
#[fixture]
119129
pub fn test_state_readers_last_and_current_block(
120130
last_constructed_block: BlockNumber,
131+
contract_class_manager: ContractClassManager,
121132
) -> ConsecutiveTestStateReaders {
122-
ConsecutiveTestStateReaders::new(last_constructed_block, None, ChainId::Mainnet, false)
133+
ConsecutiveTestStateReaders::new(
134+
last_constructed_block,
135+
None,
136+
ChainId::Mainnet,
137+
false,
138+
contract_class_manager,
139+
)
123140
}
124141

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

crates/blockifier_reexecution/src/state_reader/test_state_reader.rs

Lines changed: 21 additions & 6 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,18 @@ 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(
299-
self,
304+
let state_reader_and_contract_manager =
305+
StateReaderAndContractManager::new(self, contract_class_manager.clone(), None);
306+
Ok(TransactionExecutor::<StateReaderAndContractManager<TestStateReader>>::pre_process_and_create(
307+
state_reader_and_contract_manager,
300308
block_context_next_block,
301309
Some(BlockHashAndNumber { number: old_block_number, hash: old_block_hash }),
302310
transaction_executor_config.unwrap_or_default(),
@@ -395,6 +403,7 @@ impl ReexecutionStateReader for TestStateReader {
395403
pub struct ConsecutiveTestStateReaders {
396404
pub last_block_state_reader: TestStateReader,
397405
pub next_block_state_reader: TestStateReader,
406+
contract_class_manager: ContractClassManager,
398407
}
399408

400409
impl ConsecutiveTestStateReaders {
@@ -403,6 +412,7 @@ impl ConsecutiveTestStateReaders {
403412
config: Option<RpcStateReaderConfig>,
404413
chain_id: ChainId,
405414
dump_mode: bool,
415+
contract_class_manager: ContractClassManager,
406416
) -> Self {
407417
let config = config.unwrap_or(get_rpc_state_reader_config());
408418
Self {
@@ -418,6 +428,7 @@ impl ConsecutiveTestStateReaders {
418428
last_constructed_block_number.next().expect("Overflow in block number"),
419429
dump_mode,
420430
),
431+
contract_class_manager,
421432
}
422433
}
423434

@@ -457,14 +468,18 @@ impl ConsecutiveTestStateReaders {
457468
}
458469
}
459470

460-
impl ConsecutiveReexecutionStateReaders<TestStateReader> for ConsecutiveTestStateReaders {
471+
impl ConsecutiveReexecutionStateReaders<StateReaderAndContractManager<TestStateReader>>
472+
for ConsecutiveTestStateReaders
473+
{
461474
fn pre_process_and_create_executor(
462475
self,
463476
transaction_executor_config: Option<TransactionExecutorConfig>,
464-
) -> ReexecutionResult<TransactionExecutor<TestStateReader>> {
477+
) -> ReexecutionResult<TransactionExecutor<StateReaderAndContractManager<TestStateReader>>>
478+
{
465479
self.last_block_state_reader.get_transaction_executor(
466480
self.next_block_state_reader.get_block_context()?,
467481
transaction_executor_config,
482+
&self.contract_class_manager,
468483
)
469484
}
470485

0 commit comments

Comments
 (0)