Skip to content

Commit 497a582

Browse files
starknet_os_runner: add hints to casm from contract class
1 parent 4edddf8 commit 497a582

File tree

6 files changed

+56
-8
lines changed

6 files changed

+56
-8
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/starknet_os_runner/Cargo.toml

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

3535
[dev-dependencies]
3636
blockifier = { workspace = true, features = ["testing"] }
37+
blockifier_test_utils.workspace = true
3738
rstest.workspace = true
3839

3940
[lints]

crates/starknet_os_runner/src/classes_provider.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ use std::collections::{BTreeMap, HashMap, HashSet};
22
use std::sync::Arc;
33

44
use async_trait::async_trait;
5-
use blockifier::execution::contract_class::{CompiledClassV1, RunnableCompiledClass};
5+
use blockifier::execution::contract_class::{
6+
program_hints_to_casm_hints,
7+
CompiledClassV1,
8+
RunnableCompiledClass,
9+
};
610
use blockifier::state::state_api::StateReader;
711
use blockifier::state::state_reader_and_contract_manager::{
812
FetchCompiledClasses,
@@ -20,9 +24,10 @@ use crate::errors::ClassesProviderError;
2024
/// Converts a `CompiledClassV1` to a `CasmContractClass` for OS execution.
2125
/// Note: Some fields are not preserved in `CompiledClassV1` and are set to default values:
2226
/// - `compiler_version`: Set to empty string
23-
/// - `hints`: Set to empty (OS doesn't use them from this struct for Cairo 1 contracts)
2427
/// - `pythonic_hints`: Set to None
25-
fn compiled_class_v1_to_casm(class: &CompiledClassV1) -> CasmContractClass {
28+
pub(crate) fn compiled_class_v1_to_casm(
29+
class: &CompiledClassV1,
30+
) -> Result<CasmContractClass, ClassesProviderError> {
2631
// TODO(Aviv): Consider using dummy prime since it is not used in the OS.
2732
let prime = Felt::prime();
2833

@@ -35,15 +40,15 @@ fn compiled_class_v1_to_casm(class: &CompiledClassV1) -> CasmContractClass {
3540
})
3641
.collect();
3742

38-
CasmContractClass {
43+
Ok(CasmContractClass {
3944
prime,
4045
compiler_version: String::new(),
4146
bytecode,
4247
bytecode_segment_lengths: Some(class.bytecode_segment_felt_sizes().into()),
43-
hints: Vec::new(),
48+
hints: program_hints_to_casm_hints(&class.program.shared_program_data.hints_collection)?,
4449
pythonic_hints: None,
4550
entry_points_by_type: (&class.entry_points_by_type).into(),
46-
}
51+
})
4752
}
4853

4954
/// Fetch class from the state reader and contract manager.
@@ -65,13 +70,13 @@ where
6570
Err(ClassesProviderError::DeprecatedContractError(class_hash))
6671
}
6772
RunnableCompiledClass::V1(compiled_class_v1) => {
68-
let casm = compiled_class_v1_to_casm(&compiled_class_v1);
73+
let casm = compiled_class_v1_to_casm(&compiled_class_v1)?;
6974
Ok((compiled_class_hash, casm))
7075
}
7176
#[cfg(feature = "cairo_native")]
7277
RunnableCompiledClass::V1Native(compiled_class_v1_native) => {
7378
let compiled_class_v1 = compiled_class_v1_native.casm();
74-
let casm = compiled_class_v1_to_casm(&compiled_class_v1);
79+
let casm = compiled_class_v1_to_casm(&compiled_class_v1)?;
7580
Ok((compiled_class_hash, casm))
7681
}
7782
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use blockifier::execution::contract_class::CompiledClassV1;
2+
use blockifier::test_utils::contracts::FeatureContractTrait;
3+
use blockifier_test_utils::cairo_versions::{CairoVersion, RunnableCairo1};
4+
use blockifier_test_utils::contracts::FeatureContract;
5+
use starknet_api::contract_class::ContractClass;
6+
7+
use crate::classes_provider::compiled_class_v1_to_casm;
8+
9+
/// Tests the round-trip conversion: CasmContractClass -> CompiledClassV1 -> CasmContractClass
10+
/// Verifies that all relevant fields are preserved (except compiler_version and pythonic_hints
11+
/// which are not loaded to the OS).
12+
#[test]
13+
fn test_compiled_class_v1_to_casm_round_trip() {
14+
// Get a test contract that has hints and entry points.
15+
let feature_contract =
16+
FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm));
17+
let (mut original_casm, sierra_version) = match feature_contract.get_class() {
18+
ContractClass::V1(versioned_casm) => versioned_casm,
19+
_ => panic!("Expected ContractClass::V1"),
20+
};
21+
22+
// Ignore fields that are not loaded to the OS.
23+
original_casm.compiler_version = String::new();
24+
original_casm.pythonic_hints = None;
25+
26+
// Convert CasmContractClass to CompiledClassV1.
27+
let compiled_class_v1 = CompiledClassV1::try_from((original_casm.clone(), sierra_version))
28+
.expect("Failed to convert CasmContractClass to CompiledClassV1");
29+
30+
// Convert back to CasmContractClass using compiled_class_v1_to_casm.
31+
let round_tripped_casm = compiled_class_v1_to_casm(&compiled_class_v1)
32+
.expect("Failed to convert CompiledClassV1 back to CasmContractClass");
33+
34+
// Verify that the round-tripped CasmContractClass is equal to the original.
35+
assert_eq!(round_tripped_casm, original_casm);
36+
}

crates/starknet_os_runner/src/errors.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use blockifier::state::errors::StateError;
22
use blockifier_reexecution::errors::ReexecutionError;
3+
use cairo_vm::types::errors::program_errors::ProgramError;
34
use starknet_api::core::ClassHash;
45
use starknet_os::errors::StarknetOsError;
56
use starknet_rust::providers::ProviderError;
@@ -49,4 +50,6 @@ pub enum ClassesProviderError {
4950
DeprecatedContractError(ClassHash),
5051
#[error(transparent)]
5152
StateError(#[from] StateError),
53+
#[error(transparent)]
54+
HintsConversionError(#[from] ProgramError),
5255
}

crates/starknet_os_runner/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ pub mod storage_proofs;
55
pub mod tools;
66
pub mod virtual_block_executor;
77

8+
#[cfg(test)]
9+
mod classes_provider_test;
810
#[cfg(test)]
911
mod storage_proofs_test;
1012
#[cfg(test)]

0 commit comments

Comments
 (0)