Skip to content

Commit 92f0f04

Browse files
committed
Nearly done with LOAD_CLASS_FACTS
1 parent 49e8cd1 commit 92f0f04

File tree

5 files changed

+51
-43
lines changed

5 files changed

+51
-43
lines changed

crates/starknet-os-types/src/casm_contract_class.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use cairo_vm::types::relocatable::MaybeRelocatable;
12
use once_cell::sync::OnceCell;
23
use std::sync::Arc;
34

@@ -103,6 +104,11 @@ impl GenericCasmContractClass {
103104
pub fn class_hash(&self) -> Result<GenericClassHash, ContractClassError> {
104105
self.class_hash.get_or_try_init(|| self.compute_class_hash()).copied()
105106
}
107+
108+
pub fn bytecode_len(&self) -> Result<usize, ContractClassError> {
109+
let cairo_lang_class = self.get_cairo_lang_contract_class()?;
110+
Ok(cairo_lang_class.bytecode.len())
111+
}
106112
}
107113

108114
impl Serialize for GenericCasmContractClass {

crates/starknet-os/src/cairo_types/structs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub struct ExecutionContext {
2222
#[derive(FieldOffsetGetters)]
2323
pub struct CompiledClassFact {
2424
pub hash: Felt252,
25-
pub compiled_class: Felt252,
25+
pub compiled_class: Relocatable,
2626
}
2727

2828
#[allow(unused)]

crates/starknet-os/src/hints/compiled_class.rs

+41-40
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ use std::collections::HashMap;
22
use std::collections::hash_map::IntoIter;
33
use std::rc::Rc;
44

5-
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{get_integer_from_var_name, get_ptr_from_var_name, insert_value_from_var_name, insert_value_into_ap};
6-
use cairo_vm::hint_processor::hint_processor_definition::HintReference;
5+
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::{get_integer_from_var_name, get_ptr_from_var_name, get_relocatable_from_var_name, insert_value_from_var_name, insert_value_into_ap};
6+
use cairo_vm::hint_processor::hint_processor_definition::{HintExtension, HintProcessor, HintReference};
77
use cairo_vm::serde::deserialize_program::ApTracking;
88
use cairo_vm::types::exec_scope::ExecutionScopes;
9-
use cairo_vm::types::relocatable::MaybeRelocatable;
9+
use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable};
1010
use cairo_vm::vm::errors::hint_errors::HintError;
1111
use cairo_vm::vm::vm_core::VirtualMachine;
1212
use cairo_vm::{any_box, Felt252};
1313
use indoc::indoc;
14+
use pathfinder_crypto::Felt;
1415
use starknet_os_types::casm_contract_class::GenericCasmContractClass;
1516

1617
use crate::cairo_types::structs::{CompiledClass, CompiledClassFact};
@@ -105,12 +106,12 @@ pub const LOAD_CLASS_FACTS: &str = indoc! {r#"
105106
compiled_class.get_runnable_program(entrypoint_builtins=[]), bytecode_ptr)"#
106107
};
107108
pub fn load_class_facts(
109+
_hint_processor: &dyn HintProcessor,
108110
vm: &mut VirtualMachine,
109111
exec_scopes: &mut ExecutionScopes,
110112
ids_data: &HashMap<String, HintReference>,
111113
ap_tracking: &ApTracking,
112-
_constants: &HashMap<String, Felt252>,
113-
) -> Result<(), HintError> {
114+
) -> Result<HintExtension, HintError> {
114115
let os_input: Rc<StarknetOsInput> = exec_scopes.get::<Rc<StarknetOsInput>>(vars::scopes::OS_INPUT)?.clone();
115116

116117
// ids.n_compiled_class_facts = len(os_input.compiled_classes)
@@ -126,6 +127,9 @@ pub fn load_class_facts(
126127
let compiled_class_facts_ptr = vm.add_memory_segment();
127128
insert_value_from_var_name(vars::ids::COMPILED_CLASS_FACTS, compiled_class_facts_ptr, vm, ids_data, ap_tracking)?;
128129

130+
let builtin_costs = get_ptr_from_var_name(vars::ids::BUILTIN_COSTS, vm, ids_data, ap_tracking)?;
131+
let mut hint_extension = HintExtension::new();
132+
129133
for (i, (compiled_class_hash, class)) in os_input.compiled_classes.iter().enumerate() {
130134

131135
// Load the compiled class.
@@ -142,54 +146,51 @@ pub fn load_class_facts(
142146
// add a memory segment corresponding to the gen_arg(cairo_contract) call
143147
let class_base = vm.add_memory_segment();
144148

145-
// TODO: we need to pass the full class bytecode into write_class
146-
// `cairo-lang-starknet-classes` crate's `CasmContractClass` has `pub bytecode: Vec<BigUintAsHex>`
147-
// blockifier has `self.program` which has `Arc<SharedProgramData` which has `data: Vec<MaybeRelocatable>`
148-
// ...cairo-lang seems like the win here
149-
//
150149
// TODO: write_class used to return a single BytecodeSegmentStructureImpl, but these are now handled in a different hint
151150
// as "bytecode_segment_structures"
152-
let bytecode_segment_structure = write_class(vm, class_base, class.clone(), class.bytecode())?; // TODO: can we avoid this clone here?
151+
let bytecode_segment_structure = write_class(vm, class_base, cairo_contract.clone(), None)?; // TODO: can we avoid this clone here?
153152

154153
let offset = CompiledClassFact::cairo_size() * i;
155154
let data = [
156155
MaybeRelocatable::Int(*compiled_class_hash),
157156
MaybeRelocatable::RelocatableValue(class_base)
158157
];
159-
vm.load_data((compiled_class_facts_ptr + offset)?, &data)?;
160-
}
158+
let compiled_class_fact_ptr = (compiled_class_facts_ptr + offset)?;
159+
vm.load_data(compiled_class_facts_ptr, &data)?;
161160

162-
/*
163-
for i, (compiled_class_hash, compiled_class) in enumerate(
164-
os_input.compiled_classes.items()
165-
):
166-
# Load the compiled class.
167-
cairo_contract = get_compiled_class_struct(
168-
identifiers=ids._context.identifiers,
169-
compiled_class=compiled_class,
170-
# Load the entire bytecode - the unaccessed segments will be overriden and skipped
171-
# after the execution, in `validate_compiled_class_facts_post_execution`.
172-
bytecode=compiled_class.bytecode,
173-
)
174-
segments.load_data(
175-
ptr=ids.compiled_class_facts[i].address_,
176-
data=(compiled_class_hash, segments.gen_arg(cairo_contract))
177-
)
161+
// bytecode_ptr = ids.compiled_class_facts[i].compiled_class.bytecode_ptr
162+
let offset = CompiledClassFact::compiled_class_offset() + CompiledClass::bytecode_ptr_offset();
163+
let bytecode_ptr = (compiled_class_fact_ptr + offset)?;
178164

179-
bytecode_ptr = ids.compiled_class_facts[i].compiled_class.bytecode_ptr
180-
# Compiled classes are expected to end with a `ret` opcode followed by a pointer to
181-
# the builtin costs.
182-
segments.load_data(
183-
ptr=bytecode_ptr + cairo_contract.bytecode_length,
184-
data=[0x208b7fff7fff7ffe, ids.builtin_costs]
185-
)
165+
// Compiled classes are expected to end with a `ret` opcode followed by a pointer to
166+
// the builtin costs.
167+
let ret_opcode= Felt252::from_hex("0x208b7fff7fff7ffe").unwrap();
168+
let data = [
169+
MaybeRelocatable::Int(ret_opcode),
170+
MaybeRelocatable::RelocatableValue(builtin_costs)
171+
];
172+
let bytecode_len = cairo_contract.bytecode_len().unwrap(); // TODO: unwrap
173+
vm.load_data((bytecode_ptr + bytecode_len)?, &data)?;
186174

187-
# Load hints and debug info.
175+
// Load hints and debug info.
176+
/*
177+
* TODO:
178+
*
188179
vm_load_program(
189-
compiled_class.get_runnable_program(entrypoint_builtins=[]), bytecode_ptr)"#
190-
*/
180+
compiled_class.get_runnable_program(entrypoint_builtins=[]), bytecode_ptr)
181+
*/
191182

192-
Ok(())
183+
// TODO: avoid clone
184+
let cairo_lang_class = cairo_contract.clone().to_cairo_lang_contract_class().map_err(|e| custom_hint_error(e.to_string()))?;
185+
186+
for (rel_pc, hints) in cairo_lang_class.hints.into_iter() {
187+
let abs_pc = Relocatable::from((bytecode_ptr.segment_index, rel_pc));
188+
hint_extension.insert(abs_pc, hints.iter().map(|h| any_box!(h.clone())).collect());
189+
}
190+
191+
}
192+
193+
Ok(hint_extension)
193194
}
194195

195196
pub const ITER_CURRENT_SEGMENT_INFO: &str = indoc! {r#"

crates/starknet-os/src/hints/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ fn hints<PCS>() -> HashMap<String, HintImpl> where
9797
hints.insert(builtins::UPDATE_BUILTIN_PTRS.into(), builtins::update_builtin_ptrs);
9898
hints.insert(compiled_class::ASSIGN_BYTECODE_SEGMENTS.into(), compiled_class::assign_bytecode_segments);
9999
hints.insert(compiled_class::ASSERT_END_OF_BYTECODE_SEGMENTS.into(), compiled_class::assert_end_of_bytecode_segments);
100-
hints.insert(compiled_class::LOAD_CLASS_FACTS.into(), compiled_class::load_class_facts);
101100
hints.insert(compiled_class::ITER_CURRENT_SEGMENT_INFO.into(), compiled_class::iter_current_segment_info);
102101
hints.insert(compiled_class::PREPARE_CLASS_FACT_VALIDATION.into(), compiled_class::prepare_class_fact_validation);
103102
hints.insert(deprecated_compiled_class::LOAD_DEPRECATED_CLASS_FACTS.into(), deprecated_compiled_class::load_deprecated_class_facts);
@@ -275,9 +274,10 @@ type ExtensiveHintImpl = fn(
275274
&ApTracking,
276275
) -> Result<HintExtension, HintError>;
277276

278-
static EXTENSIVE_HINTS: [(&str, ExtensiveHintImpl); 2] = [
277+
static EXTENSIVE_HINTS: [(&str, ExtensiveHintImpl); 3] = [
279278
(block_context::LOAD_CLASS, block_context::load_class),
280279
(deprecated_compiled_class::LOAD_DEPRECATED_CLASS, deprecated_compiled_class::load_deprecated_class),
280+
(compiled_class::LOAD_CLASS_FACTS, compiled_class::load_class_facts),
281281
];
282282

283283
pub struct SnosHintProcessor<PCS>

crates/starknet-os/src/hints/vars.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub mod ids {
4444
pub const BLOB_LENGTH: &str = "starkware.starknet.core.os.data_availability.commitment.BLOB_LENGTH";
4545
pub const BUILTIN_PARAMS: &str = "builtin_params";
4646
pub const BUILTIN_PTRS: &str = "builtin_ptrs";
47+
pub const BUILTIN_COSTS: &str = "builtin_costs";
4748
pub const CALL_RESPONSE: &str = "call_response";
4849
pub const CALLDATA: &str = "calldata";
4950
pub const CHILD_BIT: &str = "child_bit";

0 commit comments

Comments
 (0)