Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion crates/blockifier/src/execution/contract_class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use cairo_vm::serde::deserialize_program::{
};
use cairo_vm::types::builtin_name::BuiltinName;
use cairo_vm::types::errors::program_errors::ProgramError;
use cairo_vm::types::program::Program;
use cairo_vm::types::program::{HintsCollection, Program};
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use itertools::Itertools;
Expand Down Expand Up @@ -709,6 +709,29 @@ fn hint_to_hint_params(hint: &Hint) -> Result<HintParams, ProgramError> {
})
}

/// Converts `HintParams` back to `Hint` by deserializing the JSON code.
/// This is the reverse of `hint_to_hint_params`.
fn hint_params_to_hint(hint_params: &HintParams) -> Result<Hint, ProgramError> {
Ok(serde_json::from_str(&hint_params.code)?)
}

/// Converts `BTreeMap<usize, Vec<HintParams>>` back to `Vec<(usize, Vec<Hint>)>`.
/// This is the reverse of the conversion done in `TryFrom<VersionedCasm> for CompiledClassV1`.
pub fn program_hints_to_casm_hints(
program_hints: &HintsCollection,
) -> Result<Vec<(usize, Vec<Hint>)>, ProgramError> {
let program_hints: BTreeMap<usize, Vec<HintParams>> = program_hints.into();
let mut casm_hints: Vec<(usize, Vec<Hint>)> = Vec::new();
for (i, hint_params_list) in program_hints.iter() {
let hints: Vec<Hint> = hint_params_list
.iter()
.map(hint_params_to_hint)
.collect::<Result<Vec<Hint>, ProgramError>>()?;
casm_hints.push((*i, hints));
}
Ok(casm_hints)
}

fn convert_entry_points_v1(external: &[CasmContractEntryPoint]) -> Vec<EntryPointV1> {
external
.iter()
Expand Down
30 changes: 30 additions & 0 deletions crates/blockifier/src/execution/contract_class_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use starknet_types_core::felt::Felt;
use starknet_types_core::hash::Blake2Felt252;

use crate::execution::contract_class::{
program_hints_to_casm_hints,
CompiledClassV1,
ContractClassV1Inner,
EntryPointV1,
Expand Down Expand Up @@ -236,3 +237,32 @@ fn test_entry_points_round_trip(#[case] original: CasmContractEntryPoints) {

assert_eq!(round_tripped, original);
}

#[rstest]
fn test_hints_round_trip() {
// Get a test contract that has hints.
let feature_contract =
FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm));
let (casm, sierra_version) = match feature_contract.get_class() {
ContractClass::V1(versioned_casm) => versioned_casm,
_ => panic!("Expected ContractClass::V1"),
};

// Panic if the contract has no hints - we need hints to test the roundtrip.
assert!(!casm.hints.is_empty(), "Test contract must have hints for roundtrip test");

// Get original hints from the CasmContractClass.
let original_hints = casm.hints.clone();

// Forward conversion: Convert CasmContractClass convert the hints from Vec<(usize, Vec<Hint>)>
// to HashMap<usize, Vec<HintParams>>.
let compiled_class = CompiledClassV1::try_from((casm, sierra_version)).unwrap();

// Reverse conversion: Access the hints from the VM program and convert back.
// The program stores hints as a HintsCollection, which can be converted to BTreeMap.
let program_hints = &compiled_class.program.shared_program_data.hints_collection;
let round_tripped_hints = program_hints_to_casm_hints(program_hints).unwrap();

// Compare with original.
assert_eq!(round_tripped_hints, original_hints);
}
Loading