Skip to content

Commit

Permalink
feat(starknet_os): create panicking cached state
Browse files Browse the repository at this point in the history
  • Loading branch information
nimrod-starkware committed Mar 3, 2025
1 parent 7a4087d commit c20b5ef
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 12 deletions.
2 changes: 1 addition & 1 deletion crates/blockifier/src/state/cached_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub struct CachedState<S: StateReader> {
// Invariant: read/write access is managed by CachedState.
// Using interior mutability to update caches during `State`'s immutable getters.
pub(crate) cache: RefCell<StateCache>,
pub(crate) class_hash_to_class: RefCell<ContractClassMapping>,
pub class_hash_to_class: RefCell<ContractClassMapping>,
}

impl<S: StateReader> CachedState<S> {
Expand Down
61 changes: 54 additions & 7 deletions crates/starknet_os/src/hint_processor/execution_helper.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use blockifier::state::cached_state::CachedState;
use std::collections::HashMap;

use blockifier::execution::contract_class::RunnableCompiledClass;
use blockifier::state::cached_state::{CachedState, StateMaps};
use blockifier::state::state_api::StateReader;
#[cfg(any(feature = "testing", test))]
use blockifier::test_utils::dict_state_reader::DictStateReader;
use cairo_vm::types::program::Program;

use crate::io::os_input::StarknetOsInput;
use crate::errors::StarknetOsError;
use crate::io::os_input::{CachedStateInput, StarknetOsInput};

/// A helper struct that provides access to the OS state and commitments.
pub struct OsExecutionHelper<S: StateReader> {
Expand All @@ -14,13 +18,56 @@ pub struct OsExecutionHelper<S: StateReader> {
}

impl<S: StateReader> OsExecutionHelper<S> {
pub fn new(os_input: StarknetOsInput, os_program: Program) -> Self {
Self { cached_state: Self::initialize_cached_state(&os_input), os_input, os_program }
pub fn new(
os_input: StarknetOsInput,
os_program: Program,
state_reader: S,
state_input: CachedStateInput,
) -> Result<Self, StarknetOsError> {
Ok(Self {
cached_state: Self::initialize_cached_state(state_reader, state_input)?,
os_input,
os_program,
})
}

// TODO(Dori): Create a cached state with all initial read values from the OS input.
fn initialize_cached_state(_os_input: &StarknetOsInput) -> CachedState<S> {
todo!()
fn initialize_cached_state(
state_reader: S,
state_input: CachedStateInput,
) -> Result<CachedState<S>, StarknetOsError> {
let mut empty_cached_state = CachedState::new(state_reader);
let mut state_maps = StateMaps::default();
let mut contract_classes = HashMap::new();

// Insert contracts.
for (class_hash, deprecated_class) in state_input.deprecated_compiled_classes.into_iter() {
contract_classes
.insert(class_hash, RunnableCompiledClass::V0(deprecated_class.try_into()?));
}
for (class_hash, versioned_class) in state_input.compiled_classes.into_iter() {
contract_classes
.insert(class_hash, RunnableCompiledClass::V1(versioned_class.try_into()?));
}

// Insert storage.
for (contract_address, storage) in state_input.storage.into_iter() {
for (key, value) in storage.into_iter() {
state_maps.storage.insert((contract_address, key), value);
}
}
// Insert nonces.
state_maps.nonces = state_input.address_to_nonce;

// Insert class hashes.
state_maps.class_hashes = state_input.address_to_class_hash;

// Insert compiled class hashes.
state_maps.compiled_class_hashes = state_input.class_hash_to_compiled_class_hash;

// Update the cached state.
empty_cached_state.update_cache(&state_maps, contract_classes);

Ok(empty_cached_state)
}
}

Expand Down
16 changes: 15 additions & 1 deletion crates/starknet_os/src/io/os_input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ use blockifier::context::ChainInfo;
use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass;
use shared_execution_objects::central_objects::CentralTransactionExecutionInfo;
use starknet_api::block::{BlockHash, BlockInfo, BlockNumber};
use starknet_api::core::{ClassHash, ContractAddress};
use starknet_api::contract_class::VersionedCasm;
use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce};
use starknet_api::deprecated_contract_class::ContractClass;
use starknet_api::executable_transaction::Transaction;
use starknet_api::state::StorageKey;
use starknet_patricia::hash::hash_trait::HashOutput;
use starknet_patricia::patricia_merkle_tree::types::SubTreeHeight;
use starknet_types_core::felt::Felt;
Expand Down Expand Up @@ -60,6 +62,7 @@ pub struct StarknetOsInput {
_contract_state_commitment_info: CommitmentInfo,
pub address_to_storage_commitment_info: HashMap<ContractAddress, CommitmentInfo>,
_contract_class_commitment_info: CommitmentInfo,
// TODO(Nimrod): Remove these two field once they move to `CachedStateInput`.
pub deprecated_compiled_classes: HashMap<ClassHash, ContractClass>,
_compiled_classes: HashMap<ClassHash, CasmContractClass>,
pub(crate) chain_info: ChainInfo,
Expand All @@ -77,3 +80,14 @@ pub struct StarknetOsInput {
_debug_mode: bool,
pub(crate) full_output: bool,
}

#[derive(Default)]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub struct CachedStateInput {
pub(crate) storage: HashMap<ContractAddress, HashMap<StorageKey, Felt>>,
pub(crate) address_to_class_hash: HashMap<ContractAddress, ClassHash>,
pub(crate) address_to_nonce: HashMap<ContractAddress, Nonce>,
pub(crate) class_hash_to_compiled_class_hash: HashMap<ClassHash, CompiledClassHash>,
pub(crate) deprecated_compiled_classes: HashMap<ClassHash, ContractClass>,
pub(crate) compiled_classes: HashMap<ClassHash, VersionedCasm>,
}
11 changes: 8 additions & 3 deletions crates/starknet_os/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ use crate::hint_processor::snos_hint_processor::{
SnosHintProcessor,
SyscallHintProcessor,
};
use crate::io::os_input::StarknetOsInput;
use crate::io::os_input::{CachedStateInput, StarknetOsInput};
use crate::io::os_output::StarknetOsRunnerOutput;

pub fn run_os<S: StateReader>(
compiled_os: &[u8],
layout: LayoutName,
os_input: StarknetOsInput,
state_reader: S,
) -> Result<StarknetOsRunnerOutput, StarknetOsError> {
// Init CairoRunConfig.
let cairo_run_config =
Expand All @@ -40,8 +41,12 @@ pub fn run_os<S: StateReader>(
// Init the Cairo VM.
let end = cairo_runner.initialize(allow_missing_builtins)?;

// TODO(Nimrod): Get `cached_state_input` as input.
let cached_state_input = CachedStateInput::default();

// Create execution helper.
let execution_helper = OsExecutionHelper::<S>::new(os_input, os_program);
let execution_helper =
OsExecutionHelper::new(os_input, os_program, state_reader, cached_state_input)?;

// Create syscall handlers.
let syscall_handler = SyscallHintProcessor::new();
Expand Down Expand Up @@ -79,5 +84,5 @@ pub fn run_os_stateless(
layout: LayoutName,
os_input: StarknetOsInput,
) -> Result<StarknetOsRunnerOutput, StarknetOsError> {
run_os::<PanickingStateReader>(compiled_os, layout, os_input)
run_os(compiled_os, layout, os_input, PanickingStateReader)
}

0 comments on commit c20b5ef

Please sign in to comment.