Skip to content

Commit

Permalink
test(os hint): load compiled classes
Browse files Browse the repository at this point in the history
  • Loading branch information
0xLucqs committed Oct 11, 2023
1 parent 7fef19f commit 4c44c66
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 28 deletions.
1 change: 1 addition & 0 deletions scripts/setup-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ cairo-compile cairo-lang/src/starkware/starknet/core/os/os.cairo --output build/
cairo-compile tests/programs/different_output.cairo --output build/different_output.json
cairo-compile tests/programs/fact.cairo --output build/fact.json
cairo-compile tests/programs/hint.cairo --output build/hint.json
cairo-compile tests/programs/load_compiled_classes.cairo --output build/load_compiled_classes.json
6 changes: 6 additions & 0 deletions src/hints/hints_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ os_input = StarknetOsInput.load(data=program_input)
ids.initial_carried_outputs.messages_to_l1 = segments.add_temp_segment()
ids.initial_carried_outputs.messages_to_l2 = segments.add_temp_segment()"#;

pub const LOAD_COMPILED_CLASS_FACTS: &str = r#"ids.compiled_class_facts = segments.add()
ids.n_compiled_class_facts = len(os_input.compiled_classes)
vm_enter_scope({
'compiled_class_facts': iter(os_input.compiled_classes.items()),
})"#;

pub const _VM_ENTER_SCOPE: &str = "
# This hint shouldn't be whitelisted.
vm_enter_scope(dict(
Expand Down
64 changes: 60 additions & 4 deletions src/hints/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
use std::any::Any;
use std::collections::HashMap;

use cairo_vm::felt::Felt252;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_ptr_from_var_name;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{
get_ptr_from_var_name, insert_value_from_var_name,
};
use cairo_vm::hint_processor::hint_processor_definition::HintReference;
mod hints_raw;

use crate::io::StarknetOsInput;
use cairo_vm::serde::deserialize_program::ApTracking;
use cairo_vm::types::exec_scope::ExecutionScopes;
use cairo_vm::types::relocatable::MaybeRelocatable;
use cairo_vm::vm::{errors::hint_errors::HintError, vm_core::VirtualMachine};
use std::rc::Rc;

use crate::io::StarknetOsInput;
use std::rc::Rc;

use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{
BuiltinHintProcessor, HintFunc,
};

pub mod hints_raw;

pub fn sn_hint_processor() -> BuiltinHintProcessor {
let mut hint_processor = BuiltinHintProcessor::new_empty();

Expand Down Expand Up @@ -63,3 +68,54 @@ pub fn starknet_os_input(

Ok(())
}

/*
Implements hint:
%{
ids.compiled_class_facts = segments.add()
ids.n_compiled_class_facts = len(os_input.compiled_classes)
vm_enter_scope({
'compiled_class_facts': iter(os_input.compiled_classes.items()),
})
%}
*/
pub fn load_compiled_class_facts(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
// ids.compiled_class_facts = segments.add()
insert_value_from_var_name(
"compiled_class_facts",
vm.add_memory_segment(),
vm,
ids_data,
ap_tracking,
)?;
// Access the value of os_input which was loaded in a previous hint like that
// %{ os_input = ... %}
// Can't directly get os_input.compiled_classes so we need to get the whole os_input
let compiled_class_facts = exec_scopes
.get_ref::<StarknetOsInput>("os_input")?
.compiled_classes()
.clone();
// ids.n_compiled_class_facts = len(os_input.compiled_classes)
insert_value_from_var_name(
"n_compiled_class_facts",
MaybeRelocatable::Int(Felt252::new(compiled_class_facts.len())),
vm,
ids_data,
ap_tracking,
)?;
// vm_enter_scope({
// 'compiled_class_facts': iter(os_input.compiled_classes.items()),
// })
let boxed_compiled_classes: Box<dyn Any> = Box::new(compiled_class_facts.into_iter());
exec_scopes.enter_scope(HashMap::from_iter(vec![(
"compiled_class_facts".to_string(),
boxed_compiled_classes,
)]));
Ok(())
}
5 changes: 5 additions & 0 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ pub struct StarknetOsInput {
#[serde(deserialize_with = "deserialize_felt_hex")]
block_hash: Felt252,
}
impl StarknetOsInput {
pub fn compiled_classes(&self) -> &HashMap<Felt252, Felt252> {
&self.compiled_classes
}
}

impl StarknetOsInput {
pub fn load(path: &str) -> Self {
Expand Down
17 changes: 17 additions & 0 deletions tests/contracts/load_compiled_classes.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
%builtins output

func main(output_ptr: felt*) -> (output_ptr: felt*) {
alloc_locals;
local compiled_class_facts;
local n_compiled_class_facts;
%{
ids.compiled_class_facts = segments.add()
ids.n_compiled_class_facts = len(os_input.compiled_classes)
vm_enter_scope({
'compiled_class_facts': iter(os_input.compiled_classes.items()),
})
%}
// When entering a scope we need to exit it afterwards otherwise the vm panics.
%{ vm_exit_scope() %}
return(output_ptr = output_ptr);
}
6 changes: 3 additions & 3 deletions tests/pie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,19 @@ fn pie_execution_resources_ok(setup_pie: CairoPie) {
fn pie_version_ok(setup_pie: CairoPie) {
let version = setup_pie.version;

let version_s = serde_json::to_value(&version).unwrap();
let version_s = serde_json::to_value(version).unwrap();
assert_eq!(version_s, json!({"cairo_pie": "1.1"}));
}

#[rstest]
fn pie_memory_ok(setup_pie: CairoPie) {
let pie_s = serde_json::to_value(&setup_pie).unwrap();
let pie_s = serde_json::to_value(setup_pie).unwrap();
assert_eq!(pie_s["memory"], "00000000000000800080ff7f018006400000000000000000000000000000000000000000000000000100000000000080640000000000000000000000000000000000000000000000000000000000000002000000000000800080fd7f0080024800000000000000000000000000000000000000000000000003000000000000800080ff7f018006400000000000000000000000000000000000000000000000000400000000000080c80000000000000000000000000000000000000000000000000000000000000005000000000000800080fd7f0180024800000000000000000000000000000000000000000000000006000000000000800080ff7f0180064000000000000000000000000000000000000000000000000007000000000000802c0100000000000000000000000000000000000000000000000000000000000008000000000000800080fd7f0280024800000000000000000000000000000000000000000000000009000000000000800080fd7f018026480000000000000000000000000000000000000000000000000a0000000000008003000000000000000000000000000000000000000000000000000000000000000b00000000000080fe7fff7fff7f8b20000000000000000000000000000000000000000000000000000000000080008000000000000001000000000000000000000000000000000000000000000000800100000000800080000000000080010000000000000000000000000000000000000000000000008002000000008000800000000000000200000000000000000000000000000000000000000000000080030000000080008064000000000000000000000000000000000000000000000000000000000000000400000000800080c80000000000000000000000000000000000000000000000000000000000000005000000008000802c0100000000000000000000000000000000000000000000000000000000000006000000008000800300000000000100000000000000000000000000000000000000000000000080000000000000018064000000000000000000000000000000000000000000000000000000000000000100000000000180c80000000000000000000000000000000000000000000000000000000000000002000000000001802c01000000000000000000000000000000000000000000000000000000000000");
}

#[rstest]
fn prepare_pie_ok(setup_pie: CairoPie) {
let disk_b64 = encode_pie(setup_pie.clone(), &Path::new("build/test.zip"));
let disk_b64 = encode_pie(setup_pie.clone(), Path::new("build/test.zip"));
assert!(disk_b64.is_ok());

let mem_b64 = encode_pie_mem(setup_pie);
Expand Down
2 changes: 0 additions & 2 deletions tests/programs/hint.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ func main(output_ptr: felt*) -> (output_ptr: felt*) {
tempvar a = 17;
a = [output_ptr], ap++;
// Use custom hint to print the value of a
%{ print(ids.a) %}
let output_ptr = output_ptr + 1;
return(output_ptr = output_ptr);
Expand Down
17 changes: 17 additions & 0 deletions tests/programs/load_compiled_classes.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
%builtins output

func main(output_ptr: felt*) -> (output_ptr: felt*) {
alloc_locals;
local compiled_class_facts;
local n_compiled_class_facts;
%{
ids.compiled_class_facts = segments.add()
ids.n_compiled_class_facts = len(os_input.compiled_classes)
vm_enter_scope({
'compiled_class_facts': iter(os_input.compiled_classes.items()),
})
%}
// When entering a scope we need to exit it afterwards otherwise the vm panics.
%{ vm_exit_scope() %}
return(output_ptr = output_ptr);
}
2 changes: 1 addition & 1 deletion tests/sharp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ fn sharp_client_status() {
let submit_resp = sharp_client.get_status(TEST_CAIRO_JOB_ID).unwrap();

assert_eq!(submit_resp.version.unwrap(), 1);
assert_eq!(submit_resp.validation_done.unwrap(), true);
assert!(submit_resp.validation_done.unwrap());
}
34 changes: 16 additions & 18 deletions tests/snos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ use starknet_api::core::{ContractAddress, PatriciaKey};
use starknet_api::hash::{StarkFelt, StarkHash};
use starknet_api::{contract_address, patricia_key, stark_felt};

use snos::hints::hints_raw::*;
use snos::hints::load_compiled_class_facts;

use std::fs;
use std::rc::Rc;

Expand Down Expand Up @@ -73,18 +76,13 @@ fn prepared_os_test(mut prepare_os_test: SharedState<DictStateReader>) {
}

#[rstest]
fn custom_hint_ok() {
#[should_panic(expected = "Output #0 is different")]
fn test_different_outputs() {
let program_content = fs::read("build/hint.json").unwrap();

// Wrap the Rust hint implementation in a Box smart pointer inside a HintFunc
let hint = HintFunc(Box::new(print_a_hint));

//Instantiate the hint processor
let mut hint_processor = BuiltinHintProcessor::new_empty();

//Add the custom hint, together with the Python code
hint_processor.add_hint(String::from("print(ids.a)"), Rc::new(hint));

//Run the cairo program
let (_cairo_runner, virtual_machine) = cairo_run(
&program_content,
Expand All @@ -95,22 +93,22 @@ fn custom_hint_ok() {
&mut hint_processor,
)
.expect("Couldn't run program");
check_output_vs_python("build/hint.json", virtual_machine);
check_output_vs_python("build/different_output.json", virtual_machine);
}

#[rstest]
#[should_panic(expected = "Output #0 is different")]
fn test_different_outputs() {
let program_content = fs::read("build/hint.json").unwrap();
fn load_compiled_classes_facts_test() {
let program_path = "build/load_compiled_classes.json";

// Wrap the Rust hint implementation in a Box smart pointer inside a HintFunc
let hint = HintFunc(Box::new(print_a_hint));

//Instantiate the hint processor
// Instantiate the hint processor
let mut hint_processor = BuiltinHintProcessor::new_empty();

//Add the custom hint, together with the Python code
hint_processor.add_hint(String::from("print(ids.a)"), Rc::new(hint));
hint_processor.add_hint(
LOAD_COMPILED_CLASS_FACTS.to_owned(),
Rc::new(HintFunc(Box::new(load_compiled_class_facts))),
);

let program_content = fs::read(program_path).unwrap();

//Run the cairo program
let (_cairo_runner, virtual_machine) = cairo_run(
Expand All @@ -122,5 +120,5 @@ fn test_different_outputs() {
&mut hint_processor,
)
.expect("Couldn't run program");
check_output_vs_python("build/different_output.json", virtual_machine);
check_output_vs_python(program_path, virtual_machine);
}

0 comments on commit 4c44c66

Please sign in to comment.