Skip to content

Commit

Permalink
test(hints): get_block_mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
0xLucqs committed Oct 18, 2023
1 parent ee015e1 commit 3137cd3
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 2 deletions.
1 change: 1 addition & 0 deletions scripts/setup-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ cairo-compile tests/programs/bad_output.cairo --output build/programs/bad_output
cairo-compile tests/programs/fact.cairo --output build/programs/fact.json
cairo-compile tests/programs/load_deprecated_class.cairo --output build/programs/load_deprecated_class.json --cairo_path cairo-lang/src
cairo-compile tests/programs/initialize_state_changes.cairo --output build/programs/initialize_state_changes.json --cairo_path cairo-lang/src
cairo-compile tests/programs/get_block_mapping.cairo --output build/programs/get_block_mapping.json --cairo_path cairo-lang/src

# compile os with debug info
cairo-compile cairo-lang/src/starkware/starknet/core/os/os.cairo --output build/os_debug.json --cairo_path cairo-lang/src
Expand Down
36 changes: 35 additions & 1 deletion src/hints/block_context.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use core::panic;
use std::any::Any;
use std::collections::hash_map::IntoIter;
use std::collections::HashMap;

use blockifier::block_context::BlockContext;
use cairo_felt::Felt252;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{insert_value_from_var_name, insert_value_into_ap};
use cairo_vm::hint_processor::builtin_hint_processor::dict_manager::Dictionary;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{
get_ptr_from_var_name, insert_value_from_var_name, insert_value_into_ap,
};
use cairo_vm::hint_processor::hint_processor_definition::HintReference;
use cairo_vm::serde::deserialize_program::ApTracking;
use cairo_vm::types::exec_scope::ExecutionScopes;
Expand Down Expand Up @@ -183,3 +187,33 @@ pub fn sequencer_address(
MaybeRelocatable::Int(Felt252::from_bytes_be(os_input.general_config.sequencer_address.0.key().bytes())),
)
}

/// Implements hint:
///
/// ids.state_entry = __dict_manager.get_dict(ids.contract_state_changes)[
/// ids.BLOCK_HASH_CONTRACT_ADDRESS
/// ]
pub fn get_block_mapping(
vm: &mut VirtualMachine,
exec_scopes: &mut ExecutionScopes,
ids_data: &HashMap<String, HintReference>,
ap_tracking: &ApTracking,
constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let key = constants
.get("starkware.starknet.core.os.constants.BLOCK_HASH_CONTRACT_ADDRESS")
.expect("BLOCK_HASH_CONTRACT_ADDRESS should be in the context");
let dict_ptr = get_ptr_from_var_name("contract_state_changes", vm, ids_data, ap_tracking)?;
// def get_dict(self, dict_ptr) -> dict:
// Gets the python dict that corresponds to dict_ptr.
// return self.get_tracker(dict_ptr).data
let val = match exec_scopes.get_dict_manager()?.borrow().get_tracker(dict_ptr)?.data.clone() {
Dictionary::SimpleDictionary(dict) => {
dict.get(&MaybeRelocatable::Int(key.clone())).expect("State changes dictionnary shouldn't be None").clone()
}
Dictionary::DefaultDictionary { dict: _d, default_value: _v } => {
panic!("State changes dict shouldn't be a default dict")
}
};
insert_value_from_var_name("state_entry", val, vm, ids_data, ap_tracking)
}
3 changes: 3 additions & 0 deletions src/hints/hints_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ pub const INITIALIZE_STATE_CHANGES: &str = "from starkware.python.utils import f
os_input.contracts.items()\n}";

pub const INITIALIZE_CLASS_HASHES: &str = "initial_dict = os_input.class_hash_to_compiled_class_hash";

pub const GET_BLOCK_MAPPING: &str =
"ids.state_entry = __dict_manager.get_dict(ids.contract_state_changes)[\n ids.BLOCK_HASH_CONTRACT_ADDRESS\n]";
26 changes: 25 additions & 1 deletion tests/hints.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod common;

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

Expand All @@ -10,7 +11,9 @@ use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::*;
use common::load_input;
use common::utils::check_output_vs_python;
use rstest::{fixture, rstest};
use snos::hints::block_context::{load_deprecated_class_facts, load_deprecated_inner, sequencer_address};
use snos::hints::block_context::{
get_block_mapping, load_deprecated_class_facts, load_deprecated_inner, sequencer_address,
};
use snos::hints::hints_raw::*;
use snos::hints::{check_deprecated_class_hash, initialize_class_hashes, initialize_state_changes, starknet_os_input};
use snos::io::StarknetOsInput;
Expand Down Expand Up @@ -88,3 +91,24 @@ fn initialize_state_changes_test(mut os_input_hint_processor: BuiltinHintProcess
);
check_output_vs_python(run_output, program, true);
}

#[rstest]
fn get_block_mapping_test(mut os_input_hint_processor: BuiltinHintProcessor) {
let program = "build/programs/get_block_mapping.json";

let initialize_state_changes_hint = HintFunc(Box::new(initialize_state_changes));
os_input_hint_processor.add_hint(String::from(INITIALIZE_STATE_CHANGES), Rc::new(initialize_state_changes_hint));

let initialize_class_hashes_hint = HintFunc(Box::new(initialize_class_hashes));
os_input_hint_processor.add_hint(String::from(INITIALIZE_CLASS_HASHES), Rc::new(initialize_class_hashes_hint));

let get_block_mapping_hint = HintFunc(Box::new(get_block_mapping));
os_input_hint_processor.add_hint(String::from(GET_BLOCK_MAPPING), Rc::new(get_block_mapping_hint));

let run_output = cairo_run(
&fs::read(program).unwrap(),
&CairoRunConfig { layout: "starknet", relocate_mem: true, trace_enabled: true, ..Default::default() },
&mut os_input_hint_processor,
);
check_output_vs_python(run_output, program, true);
}
61 changes: 61 additions & 0 deletions tests/programs/get_block_mapping.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
%builtins output

from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.segments import relocate_segment
from starkware.starknet.core.os.output import OsCarriedOutputs
from starkware.cairo.common.dict import dict_new, dict_read
from starkware.cairo.common.dict_access import DictAccess
from starkware.starknet.core.os.state import StateEntry
from starkware.cairo.common.serialize import serialize_word

from starkware.starknet.core.os.constants import BLOCK_HASH_CONTRACT_ADDRESS

func main{output_ptr: felt*}() {
alloc_locals;

let (initial_carried_outputs: OsCarriedOutputs*) = alloc();
%{
from starkware.starknet.core.os.os_input import StarknetOsInput
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()
%}

%{
from starkware.python.utils import from_bytes
initial_dict = {
address: segments.gen_arg(
(from_bytes(contract.contract_hash), segments.add(), contract.nonce))
for address, contract in os_input.contracts.items()
}
%}

// A dictionary from contract address to a dict of storage changes of type StateEntry.
let (contract_state_changes: DictAccess*) = dict_new();

%{ initial_dict = os_input.class_hash_to_compiled_class_hash %}

let (state_entry: StateEntry*) = dict_read{dict_ptr=contract_state_changes}(
key=1470089414715992704702781317133162679047468004062084455026636858461958198968
);

assert state_entry.nonce = 2;

relocate_segment(src_ptr=initial_carried_outputs.messages_to_l1, dest_ptr=output_ptr);
relocate_segment(src_ptr=initial_carried_outputs.messages_to_l2, dest_ptr=output_ptr);
// Import this from starkware.starknet.core.os.constants import BLOCK_HASH_CONTRACT_ADDRESS
// When it works in the rust VM
local state_entry: StateEntry*;
%{
ids.state_entry = __dict_manager.get_dict(ids.contract_state_changes)[
ids.BLOCK_HASH_CONTRACT_ADDRESS
]
%}
assert [output_ptr] = state_entry.nonce;
assert [output_ptr + 1] = state_entry.class_hash;
let output_ptr = output_ptr + 2;
return ();
}

0 comments on commit 3137cd3

Please sign in to comment.