Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(starknet_os): create panicking cached state #4554

Merged
merged 1 commit into from
Mar 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
64 changes: 57 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,15 @@
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 starknet_api::contract_class::SierraVersion;

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 +19,58 @@ 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, class) in state_input.compiled_classes.into_iter() {
// It doesn't matter which version is used.
let sierra_version = SierraVersion::LATEST;
contract_classes
.insert(class_hash, RunnableCompiledClass::V1((class, sierra_version).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
15 changes: 14 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,10 @@ 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::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 +61,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 +79,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, CasmContractClass>,
}
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)
}
Loading