Skip to content

Commit 529826d

Browse files
blockifier_reexecution: impl FetchedCompiledClass for test and offline state readers
1 parent 055fa4e commit 529826d

File tree

9 files changed

+119
-2
lines changed

9 files changed

+119
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/blockifier/src/state/errors.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ pub enum StateError {
3232
/// Represents all unexpected errors that may occur while reading from state.
3333
#[error("Failed to read from state: {0}.")]
3434
StateReadError(String),
35-
#[error("Missing Sierra class for CASM class with hash {:#066x}.", **.0)]
36-
MissingSierra(ClassHash),
3735
#[error("Missing compiled class hash v2 for class with hash {:#064x}.", **.0)]
3836
MissingCompiledClassHashV2(ClassHash),
3937
}

crates/blockifier/src/state/global_cache.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use std::sync::Arc;
22

33
use starknet_api::class_cache::GlobalContractCache;
4+
use starknet_api::contract_class::ContractClass;
45
use starknet_api::state::SierraContractClass;
56

67
use crate::execution::contract_class::{CompiledClassV0, CompiledClassV1, RunnableCompiledClass};
78
#[cfg(feature = "cairo_native")]
89
use crate::execution::native::contract_class::NativeCompiledClassV1;
10+
use crate::state::state_api::StateResult;
911

1012
pub const GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST: usize = 600;
1113

@@ -36,6 +38,30 @@ impl CompiledClasses {
3638
},
3739
}
3840
}
41+
42+
/// Converts a [`starknet_api::contract_class::ContractClass`] into the corresponding
43+
/// [`CompiledClasses`].
44+
///
45+
/// For `V1` (Cairo 1) classes, a matching `SierraContractClass` must be provided.
46+
/// For `V0` classes, this argument should be `None`.
47+
pub fn from_contract_class(
48+
contract_class: &ContractClass,
49+
sierra_contract_class: Option<SierraContractClass>,
50+
) -> StateResult<CompiledClasses> {
51+
match contract_class {
52+
ContractClass::V0(deprecated_class) => {
53+
Ok(CompiledClasses::V0(CompiledClassV0::try_from(deprecated_class.clone())?))
54+
}
55+
ContractClass::V1(versioned_casm) => {
56+
let sierra_contract_class =
57+
sierra_contract_class.expect("V1 contract class requires Sierra class");
58+
Ok(CompiledClasses::V1(
59+
CompiledClassV1::try_from(versioned_casm.clone())?,
60+
Arc::new(sierra_contract_class.clone()),
61+
))
62+
}
63+
}
64+
}
3965
}
4066

4167
pub type RawClassCache = GlobalContractCache<CompiledClasses>;

crates/blockifier_reexecution/src/state_reader/offline_state_reader.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use blockifier::context::BlockContext;
99
use blockifier::execution::contract_class::RunnableCompiledClass;
1010
use blockifier::state::cached_state::{CommitmentStateDiff, StateMaps};
1111
use blockifier::state::errors::StateError;
12+
use blockifier::state::global_cache::CompiledClasses;
1213
use blockifier::state::state_api::{StateReader, StateResult};
14+
use blockifier::state::state_reader_and_contract_manager::FetchCompiledClasses;
1315
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
1416
use serde::{Deserialize, Serialize};
1517
use starknet_api::block::{BlockHash, BlockHashAndNumber, BlockInfo, BlockNumber, StarknetVersion};
@@ -192,6 +194,20 @@ impl ReexecutionStateReader for OfflineStateReader {
192194
}
193195
}
194196

197+
impl FetchCompiledClasses for OfflineStateReader {
198+
fn get_compiled_classes(&self, class_hash: ClassHash) -> StateResult<CompiledClasses> {
199+
let contract_class = self.get_contract_class(&class_hash)?;
200+
self.starknet_core_contract_class_to_compiled_classes(&contract_class)
201+
}
202+
203+
/// This check is not needed anymore do to a similar check in ApolloReader.
204+
/// TODO(Yonatank): Remove this after removing is_declared method from FetchedCompiledClasses
205+
/// trait.
206+
fn is_declared(&self, _class_hash: ClassHash) -> StateResult<bool> {
207+
Ok(true)
208+
}
209+
}
210+
195211
impl OfflineStateReader {
196212
pub fn get_transaction_executor(
197213
self,

crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ use apollo_rpc_execution::DEPRECATED_CONTRACT_SIERRA_SIZE;
22
use blockifier::blockifier::config::TransactionExecutorConfig;
33
use blockifier::blockifier::transaction_executor::TransactionExecutor;
44
use blockifier::state::cached_state::CommitmentStateDiff;
5+
use blockifier::state::global_cache::CompiledClasses;
56
use blockifier::state::state_api::{StateReader, StateResult};
67
use blockifier::transaction::account_transaction::ExecutionFlags;
78
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
89
use starknet_api::block::{BlockHash, BlockNumber};
910
use starknet_api::contract_class::{ClassInfo, SierraVersion};
1011
use starknet_api::core::ClassHash;
12+
use starknet_api::state::SierraContractClass;
1113
use starknet_api::test_utils::MAX_FEE;
1214
use starknet_api::transaction::{Transaction, TransactionHash};
1315
use starknet_core::types::ContractClass as StarknetContractClass;
@@ -92,6 +94,26 @@ pub trait ReexecutionStateReader {
9294
}
9395

9496
fn get_old_block_hash(&self, old_block_number: BlockNumber) -> ReexecutionResult<BlockHash>;
97+
98+
/// Converts a `starknet_core::types::ContractClass` to `CompiledClasses`.
99+
fn starknet_core_contract_class_to_compiled_classes(
100+
&self,
101+
contract_class: &StarknetContractClass,
102+
) -> StateResult<CompiledClasses> {
103+
match contract_class {
104+
StarknetContractClass::Sierra(flat_sierra) => {
105+
let (class_v1, _) = sierra_to_versioned_contract_class_v1(flat_sierra.clone())?;
106+
let sierra = SierraContractClass::from(flat_sierra.clone());
107+
108+
Ok(CompiledClasses::from_contract_class(&class_v1, Some(sierra))?)
109+
}
110+
StarknetContractClass::Legacy(legacy) => {
111+
let class_v0 = legacy_to_contract_class_v0(legacy.clone())?;
112+
113+
Ok(CompiledClasses::from_contract_class(&class_v0, None)?)
114+
}
115+
}
116+
}
95117
}
96118

97119
/// Trait of the functions \ queries required for reexecution.

crates/blockifier_reexecution/src/state_reader/test_state_reader.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use blockifier::context::BlockContext;
1515
use blockifier::execution::contract_class::RunnableCompiledClass;
1616
use blockifier::state::cached_state::CommitmentStateDiff;
1717
use blockifier::state::errors::StateError;
18+
use blockifier::state::global_cache::CompiledClasses;
1819
use blockifier::state::state_api::{StateReader, StateResult};
20+
use blockifier::state::state_reader_and_contract_manager::FetchCompiledClasses;
1921
use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction;
2022
use serde::Serialize;
2123
use serde_json::{json, to_value};
@@ -153,6 +155,22 @@ impl StateReader for TestStateReader {
153155
}
154156
}
155157

158+
impl FetchCompiledClasses for TestStateReader {
159+
fn get_compiled_classes(&self, class_hash: ClassHash) -> StateResult<CompiledClasses> {
160+
let contract_class =
161+
retry_request!(self.retry_config, || self.get_contract_class(&class_hash))?;
162+
163+
self.starknet_core_contract_class_to_compiled_classes(&contract_class)
164+
}
165+
166+
/// This check is not needed anymore do to a similar check in ApolloReader.
167+
/// TODO(Yonatank): Remove this after removing is_declared method from FetchedCompiledClasses
168+
/// trait.
169+
fn is_declared(&self, _class_hash: ClassHash) -> StateResult<bool> {
170+
Ok(true)
171+
}
172+
}
173+
156174
impl TestStateReader {
157175
pub fn new(
158176
config: &RpcStateReaderConfig,

crates/starknet_api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ semver.workspace = true
3434
serde = { workspace = true, features = ["derive", "rc"] }
3535
serde_json.workspace = true
3636
sha3.workspace = true
37+
starknet-core.workspace = true
3738
starknet-crypto.workspace = true
3839
starknet-types-core = { workspace = true, features = ["hash"] }
3940
strum = { workspace = true, features = ["derive"] }

crates/starknet_api/src/rpc_transaction.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::collections::HashMap;
77
use apollo_sizeof::SizeOf;
88
use cairo_lang_starknet_classes::contract_class::ContractEntryPoints as CairoLangContractEntryPoints;
99
use serde::{Deserialize, Serialize};
10+
use starknet_core::types::EntryPointsByType as StarknetCoreEntryPointsByType;
1011
use strum::EnumVariantNames;
1112
use strum_macros::{EnumDiscriminants, EnumIter, IntoStaticStr};
1213

@@ -680,6 +681,16 @@ impl From<CairoLangContractEntryPoints> for EntryPointByType {
680681
}
681682
}
682683

684+
impl From<StarknetCoreEntryPointsByType> for EntryPointByType {
685+
fn from(value: StarknetCoreEntryPointsByType) -> Self {
686+
Self {
687+
constructor: value.constructor.into_iter().map(EntryPoint::from).collect(),
688+
external: value.external.into_iter().map(EntryPoint::from).collect(),
689+
l1handler: value.l1_handler.into_iter().map(EntryPoint::from).collect(),
690+
}
691+
}
692+
}
693+
683694
impl EntryPointByType {
684695
pub fn from_hash_map(entry_points_by_type: HashMap<EntryPointType, Vec<EntryPoint>>) -> Self {
685696
macro_rules! get_entrypoint_by_type {

crates/starknet_api/src/state.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use cairo_lang_starknet_classes::contract_class::ContractEntryPoint as CairoLang
99
use indexmap::IndexMap;
1010
use serde::{Deserialize, Serialize};
1111
use sha3::Digest;
12+
use starknet_core::types::{FlattenedSierraClass, SierraEntryPoint};
1213
use starknet_types_core::felt::Felt;
1314
use starknet_types_core::hash::{Poseidon, StarkHash as SNTypsCoreStarkHash};
1415

@@ -270,6 +271,17 @@ impl SierraContractClass {
270271
}
271272
}
272273

274+
impl From<FlattenedSierraClass> for SierraContractClass {
275+
fn from(flattened_sierra: FlattenedSierraClass) -> Self {
276+
Self {
277+
sierra_program: flattened_sierra.sierra_program,
278+
contract_class_version: flattened_sierra.contract_class_version,
279+
entry_points_by_type: flattened_sierra.entry_points_by_type.into(),
280+
abi: flattened_sierra.abi,
281+
}
282+
}
283+
}
284+
273285
#[derive(Clone, Debug, Deserialize)]
274286
pub struct ContractClassComponentHashes {
275287
contract_class_version: Felt,
@@ -327,6 +339,18 @@ impl From<CairoLangContractEntryPoint> for EntryPoint {
327339
}
328340
}
329341

342+
impl From<SierraEntryPoint> for EntryPoint {
343+
fn from(entry_point: SierraEntryPoint) -> Self {
344+
Self {
345+
function_idx: FunctionIndex(
346+
usize::try_from(entry_point.function_idx)
347+
.expect("Function index should fit in a usize"),
348+
),
349+
selector: EntryPointSelector(entry_point.selector),
350+
}
351+
}
352+
}
353+
330354
#[derive(
331355
Debug, Copy, Clone, Default, Eq, PartialEq, Hash, Deserialize, Serialize, PartialOrd, Ord,
332356
)]

0 commit comments

Comments
 (0)