Skip to content

Commit

Permalink
Merge pull request #4645 from starkware-libs/nimrod/hints/compiled_cl…
Browse files Browse the repository at this point in the history
…ass/load_class

feat(starknet_os): implement load class hint
  • Loading branch information
nimrod-starkware authored Mar 4, 2025
2 parents 7f33038 + 2c76485 commit 0c755e3
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 34 deletions.
26 changes: 13 additions & 13 deletions crates/starknet_os/src/hints/enum_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,19 @@ define_hint_enum!(
r#"memory[ap] = to_felt_or_relocatable(ids.request_block_number > \
ids.current_block_number - ids.STORED_BLOCK_HASH_BUFFER)"#
),
(
LoadClass,
load_class,
indoc! {r#"
vm_exit_scope()
computed_hash = ids.hash
expected_hash = ids.compiled_class_fact.hash
assert computed_hash == expected_hash, (
"Computed compiled_class_hash is inconsistent with the hash in the os_input. "
f"Computed hash = {computed_hash}, Expected hash = {expected_hash}.")"#
}
),
(
LoadClassInner,
load_class_inner,
Expand Down Expand Up @@ -1760,19 +1773,6 @@ if da_path is not None:

define_hint_extension_enum!(
HintExtension,
(
LoadClass,
load_class,
indoc! {r#"
vm_exit_scope()
computed_hash = ids.hash
expected_hash = ids.compiled_class_fact.hash
assert computed_hash == expected_hash, (
"Computed compiled_class_hash is inconsistent with the hash in the os_input. "
f"Computed hash = {computed_hash}, Expected hash = {expected_hash}.")"#
}
),
(
LoadDeprecatedClass,
load_deprecated_class,
Expand Down
27 changes: 15 additions & 12 deletions crates/starknet_os/src/hints/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use blockifier::state::errors::StateError;
use cairo_vm::hint_processor::hint_processor_definition::HintExtension;
use cairo_vm::serde::deserialize_program::Identifier;
use cairo_vm::types::errors::math_errors::MathError;
use cairo_vm::vm::errors::exec_scope_errors::ExecScopeError;
use cairo_vm::vm::errors::hint_errors::HintError as VmHintError;
use cairo_vm::vm::errors::memory_errors::MemoryError;
use cairo_vm::vm::errors::vm_errors::VirtualMachineError;
Expand All @@ -20,31 +21,33 @@ pub enum OsHintError {
BooleanIdExpected { id: Ids, felt: Felt },
#[error("Failed to convert {variant:?} felt value {felt:?} to type {ty}: {reason:?}.")]
ConstConversionError { variant: Const, felt: Felt, ty: String, reason: String },
#[error(transparent)]
ExecutionScopes(#[from] ExecScopeError),
#[error("The identifier {0:?} has no full name.")]
IdentifierHasNoFullName(Box<Identifier>),
#[error("The identifier {0:?} has no members.")]
IdentifierHasNoMembers(Box<Identifier>),
#[error(
"Inconsistent block numbers: {actual}, {expected}. The constant STORED_BLOCK_HASH_BUFFER \
is probably out of sync."
)]
InconsistentBlockNumber { actual: BlockNumber, expected: BlockNumber },
#[error(transparent)]
MathError(#[from] MathError),
#[error(transparent)]
MemoryError(#[from] MemoryError),
#[error("{error:?} for json value {value}.")]
SerdeJsonError { error: serde_json::Error, value: serde_json::value::Value },
#[error(transparent)]
StateError(#[from] StateError),
#[error(transparent)]
VmError(#[from] VirtualMachineError),
#[error(transparent)]
VmHintError(#[from] VmHintError),
#[error("Convert {n_bits} bits for {type_name}.")]
StatelessCompressionOverflow { n_bits: usize, type_name: String },
#[error("Unknown hint string: {0}")]
UnknownHint(String),
#[error("The identifier {0:?} has no full name.")]
IdentifierHasNoFullName(Box<Identifier>),
#[error("The identifier {0:?} has no members.")]
IdentifierHasNoMembers(Box<Identifier>),
#[error(transparent)]
MathError(#[from] MathError),
VmError(#[from] VirtualMachineError),
#[error(transparent)]
MemoryError(#[from] MemoryError),
#[error("Convert {n_bits} bits for {type_name}.")]
StatelessCompressionOverflow { n_bits: usize, type_name: String },
VmHintError(#[from] VmHintError),
}

/// `OsHintError` and the VM's `HintError` must have conversions in both directions, as execution
Expand Down
39 changes: 30 additions & 9 deletions crates/starknet_os/src/hints/hint_implementation/compiled_class.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use blockifier::state::state_api::StateReader;
use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::get_integer_from_var_name;

use crate::hints::error::{OsHintExtensionResult, OsHintResult};
use crate::hints::error::{OsHintError, OsHintResult};
use crate::hints::types::HintArgs;
use crate::hints::vars::{CairoStruct, Ids};
use crate::vm_utils::get_address_of_nested_fields;

pub(crate) fn assign_bytecode_segments<S: StateReader>(
HintArgs { .. }: HintArgs<'_, S>,
Expand All @@ -26,6 +29,32 @@ pub(crate) fn iter_current_segment_info<S: StateReader>(
todo!()
}

pub(crate) fn load_class<S: StateReader>(
HintArgs { exec_scopes, ids_data, ap_tracking, vm, hint_processor, .. }: HintArgs<'_, S>,
) -> OsHintResult {
exec_scopes.exit_scope()?;
let expected_hash_address = get_address_of_nested_fields(
ids_data,
Ids::CompiledClassFact,
CairoStruct::CompiledClassFact,
vm,
ap_tracking,
&["hash".to_string()],
&hint_processor.execution_helper.os_program,
)?;
let expected_hash = vm.get_integer(expected_hash_address)?;
let computed_hash = get_integer_from_var_name(Ids::Hash.into(), vm, ids_data, ap_tracking)?;
if &computed_hash != expected_hash.as_ref() {
return Err(OsHintError::AssertionFailed {
message: format!(
"Computed compiled_class_hash is inconsistent with the hash in the os_input. \
Computed hash = {computed_hash}, Expected hash = {expected_hash}."
),
});
}

Ok(())
}
pub(crate) fn load_class_inner<S: StateReader>(HintArgs { .. }: HintArgs<'_, S>) -> OsHintResult {
todo!()
}
Expand All @@ -41,11 +70,3 @@ pub(crate) fn validate_compiled_class_facts_post_execution<S: StateReader>(
) -> OsHintResult {
todo!()
}

// Hint extension implementations.

pub(crate) fn load_class<S: StateReader>(
HintArgs { .. }: HintArgs<'_, S>,
) -> OsHintExtensionResult {
todo!()
}
6 changes: 6 additions & 0 deletions crates/starknet_os/src/hints/vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub enum Ids {
ContractStateChanges,
DictPtr,
FullOutput,
Hash,
NCompiledClassFacts,
NextAvailableAlias,
OldBlockHash,
Expand All @@ -76,6 +77,7 @@ impl From<Ids> for &'static str {
Ids::ContractStateChanges => "contract_state_changes",
Ids::DictPtr => "dict_ptr",
Ids::FullOutput => "full_output",
Ids::Hash => "hash",
Ids::NCompiledClassFacts => "n_compiled_class_facts",
Ids::NextAvailableAlias => "next_available_alias",
Ids::OldBlockHash => "old_block_hash",
Expand Down Expand Up @@ -146,6 +148,7 @@ impl Const {
}
}
pub enum CairoStruct {
CompiledClassFact,
DeprecatedCompiledClass,
DeprecatedCompiledClassFact,
DictAccess,
Expand All @@ -155,6 +158,9 @@ pub enum CairoStruct {
impl From<CairoStruct> for &'static str {
fn from(struct_name: CairoStruct) -> Self {
match struct_name {
CairoStruct::CompiledClassFact => {
"starkware.starknet.core.os.contract_class.compiled_class.CompiledClassFact"
}
CairoStruct::DeprecatedCompiledClass => {
"starkware.starknet.core.os.contract_class.deprecated_compiled_class.\
DeprecatedCompiledClass"
Expand Down

0 comments on commit 0c755e3

Please sign in to comment.