Skip to content

Commit 4edddf8

Browse files
starknet_os_runner: contract class hints to casm hints (#11527)
1 parent 6c958f7 commit 4edddf8

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

crates/blockifier/src/execution/contract_class.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use cairo_vm::serde::deserialize_program::{
2020
};
2121
use cairo_vm::types::builtin_name::BuiltinName;
2222
use cairo_vm::types::errors::program_errors::ProgramError;
23-
use cairo_vm::types::program::Program;
23+
use cairo_vm::types::program::{HintsCollection, Program};
2424
use cairo_vm::types::relocatable::MaybeRelocatable;
2525
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
2626
use itertools::Itertools;
@@ -709,6 +709,29 @@ fn hint_to_hint_params(hint: &Hint) -> Result<HintParams, ProgramError> {
709709
})
710710
}
711711

712+
/// Converts `HintParams` back to `Hint` by deserializing the JSON code.
713+
/// This is the reverse of `hint_to_hint_params`.
714+
fn hint_params_to_hint(hint_params: &HintParams) -> Result<Hint, ProgramError> {
715+
Ok(serde_json::from_str(&hint_params.code)?)
716+
}
717+
718+
/// Converts `BTreeMap<usize, Vec<HintParams>>` back to `Vec<(usize, Vec<Hint>)>`.
719+
/// This is the reverse of the conversion done in `TryFrom<VersionedCasm> for CompiledClassV1`.
720+
pub fn program_hints_to_casm_hints(
721+
program_hints: &HintsCollection,
722+
) -> Result<Vec<(usize, Vec<Hint>)>, ProgramError> {
723+
let program_hints: BTreeMap<usize, Vec<HintParams>> = program_hints.into();
724+
let mut casm_hints: Vec<(usize, Vec<Hint>)> = Vec::new();
725+
for (i, hint_params_list) in program_hints.iter() {
726+
let hints: Vec<Hint> = hint_params_list
727+
.iter()
728+
.map(hint_params_to_hint)
729+
.collect::<Result<Vec<Hint>, ProgramError>>()?;
730+
casm_hints.push((*i, hints));
731+
}
732+
Ok(casm_hints)
733+
}
734+
712735
fn convert_entry_points_v1(external: &[CasmContractEntryPoint]) -> Vec<EntryPointV1> {
713736
external
714737
.iter()

crates/blockifier/src/execution/contract_class_test.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use starknet_types_core::felt::Felt;
1919
use starknet_types_core::hash::Blake2Felt252;
2020

2121
use crate::execution::contract_class::{
22+
program_hints_to_casm_hints,
2223
CompiledClassV1,
2324
ContractClassV1Inner,
2425
EntryPointV1,
@@ -236,3 +237,32 @@ fn test_entry_points_round_trip(#[case] original: CasmContractEntryPoints) {
236237

237238
assert_eq!(round_tripped, original);
238239
}
240+
241+
#[rstest]
242+
fn test_hints_round_trip() {
243+
// Get a test contract that has hints.
244+
let feature_contract =
245+
FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm));
246+
let (casm, sierra_version) = match feature_contract.get_class() {
247+
ContractClass::V1(versioned_casm) => versioned_casm,
248+
_ => panic!("Expected ContractClass::V1"),
249+
};
250+
251+
// Panic if the contract has no hints - we need hints to test the roundtrip.
252+
assert!(!casm.hints.is_empty(), "Test contract must have hints for roundtrip test");
253+
254+
// Get original hints from the CasmContractClass.
255+
let original_hints = casm.hints.clone();
256+
257+
// Forward conversion: Convert CasmContractClass convert the hints from Vec<(usize, Vec<Hint>)>
258+
// to HashMap<usize, Vec<HintParams>>.
259+
let compiled_class = CompiledClassV1::try_from((casm, sierra_version)).unwrap();
260+
261+
// Reverse conversion: Access the hints from the VM program and convert back.
262+
// The program stores hints as a HintsCollection, which can be converted to BTreeMap.
263+
let program_hints = &compiled_class.program.shared_program_data.hints_collection;
264+
let round_tripped_hints = program_hints_to_casm_hints(program_hints).unwrap();
265+
266+
// Compare with original.
267+
assert_eq!(round_tripped_hints, original_hints);
268+
}

0 commit comments

Comments
 (0)