diff --git a/crates/blockifier/src/blockifier/transaction_executor.rs b/crates/blockifier/src/blockifier/transaction_executor.rs index 14c13ed932..2f43a466b9 100644 --- a/crates/blockifier/src/blockifier/transaction_executor.rs +++ b/crates/blockifier/src/blockifier/transaction_executor.rs @@ -17,6 +17,7 @@ use crate::bouncer::{Bouncer, BouncerWeights}; #[cfg(feature = "concurrency")] use crate::concurrency::worker_logic::WorkerExecutor; use crate::context::BlockContext; +use crate::execution::contract_class::ContractClassExt; use crate::state::cached_state::{CachedState, CommitmentStateDiff, TransactionalState}; use crate::state::errors::StateError; use crate::state::state_api::StateReader; diff --git a/crates/blockifier/src/bouncer.rs b/crates/blockifier/src/bouncer.rs index 0aa83d08ad..968cf91a2c 100644 --- a/crates/blockifier/src/bouncer.rs +++ b/crates/blockifier/src/bouncer.rs @@ -10,6 +10,7 @@ use crate::blockifier::transaction_executor::{ TransactionExecutorResult, }; use crate::execution::call_info::ExecutionSummary; +use crate::execution::contract_class::ContractClassExt; use crate::fee::gas_usage::get_onchain_data_segment_length; use crate::state::cached_state::{StateChangesKeys, StorageEntry}; use crate::state::state_api::StateReader; diff --git a/crates/blockifier/src/concurrency/versioned_state.rs b/crates/blockifier/src/concurrency/versioned_state.rs index a6edb590ee..e245cbd3fc 100644 --- a/crates/blockifier/src/concurrency/versioned_state.rs +++ b/crates/blockifier/src/concurrency/versioned_state.rs @@ -1,13 +1,13 @@ use std::collections::{HashMap, HashSet}; use std::sync::{Arc, Mutex, MutexGuard}; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; use crate::concurrency::versioned_storage::VersionedStorage; use crate::concurrency::TxIndex; -use crate::execution::contract_class::ContractClass; use crate::state::cached_state::{ContractClassMapping, StateMaps}; use crate::state::errors::StateError; use crate::state::state_api::{StateReader, StateResult, UpdatableState}; diff --git a/crates/blockifier/src/execution/contract_class.rs b/crates/blockifier/src/execution/contract_class.rs index d155cefbaf..f9f947e843 100644 --- a/crates/blockifier/src/execution/contract_class.rs +++ b/crates/blockifier/src/execution/contract_class.rs @@ -1,35 +1,23 @@ use std::collections::{HashMap, HashSet}; -use std::ops::Deref; use std::sync::Arc; -use cairo_lang_casm; -use cairo_lang_casm::hints::Hint; -use cairo_lang_starknet_classes::casm_contract_class::{CasmContractClass, CasmContractEntryPoint}; +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use cairo_lang_starknet_classes::NestedIntList; -use cairo_vm::serde::deserialize_program::{ - ApTracking, - FlowTrackingData, - HintParams, - ReferenceManager, -}; use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::types::errors::program_errors::ProgramError; -use cairo_vm::types::program::Program; -use cairo_vm::types::relocatable::MaybeRelocatable; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use itertools::Itertools; -use serde::de::Error as DeserializationError; -use serde::{Deserialize, Deserializer}; -use starknet_api::core::EntryPointSelector; -use starknet_api::deprecated_contract_class::{ - sn_api_to_cairo_vm_program, - ContractClass as DeprecatedContractClass, - EntryPoint, - EntryPointOffset, - EntryPointType, - Program as DeprecatedProgram, +use starknet_api::contract_class::{ + ClassInfo, + ContractClass, + ContractClassV0, + ContractClassV0Inner, + ContractClassV1, + ContractClassV1Inner, + EntryPointV1, }; -use starknet_types_core::felt::Felt; +use starknet_api::core::EntryPointSelector; +use starknet_api::deprecated_contract_class::EntryPointType; use super::execution_utils::poseidon_hash_many_cost; use crate::abi::abi_utils::selector_from_name; @@ -50,39 +38,32 @@ pub mod test; pub type ContractClassResult = Result; -#[derive(Clone, Debug, Eq, PartialEq, derive_more::From)] -pub enum ContractClass { - V0(ContractClassV0), - V1(ContractClassV1), -} - -impl TryFrom for ContractClass { - type Error = ProgramError; - - fn try_from( - contract_class: starknet_api::contract_class::ContractClass, - ) -> Result { - let starknet_api::contract_class::ContractClass::V1(contract_class_v1) = contract_class; - Ok(ContractClass::V1(contract_class_v1.try_into()?)) - } +pub trait ContractClassExt { + fn constructor_selector(&self) -> Option; + fn estimate_casm_hash_computation_resources(&self) -> ExecutionResources; + fn get_visited_segments( + &self, + visited_pcs: &HashSet, + ) -> Result, TransactionExecutionError>; + fn bytecode_length(&self) -> usize; } -impl ContractClass { - pub fn constructor_selector(&self) -> Option { +impl ContractClassExt for ContractClass { + fn constructor_selector(&self) -> Option { match self { ContractClass::V0(class) => class.constructor_selector(), ContractClass::V1(class) => class.constructor_selector(), } } - pub fn estimate_casm_hash_computation_resources(&self) -> ExecutionResources { + fn estimate_casm_hash_computation_resources(&self) -> ExecutionResources { match self { ContractClass::V0(class) => class.estimate_casm_hash_computation_resources(), ContractClass::V1(class) => class.estimate_casm_hash_computation_resources(), } } - pub fn get_visited_segments( + fn get_visited_segments( &self, visited_pcs: &HashSet, ) -> Result, TransactionExecutionError> { @@ -94,7 +75,7 @@ impl ContractClass { } } - pub fn bytecode_length(&self) -> usize { + fn bytecode_length(&self) -> usize { match self { ContractClass::V0(class) => class.bytecode_length(), ContractClass::V1(class) => class.bytecode_length(), @@ -103,17 +84,13 @@ impl ContractClass { } // V0. -#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] -pub struct ContractClassV0(pub Arc); -impl Deref for ContractClassV0 { - type Target = ContractClassV0Inner; - - fn deref(&self) -> &Self::Target { - &self.0 - } +trait ContractClassV0Ext { + fn constructor_selector(&self) -> Option; + fn n_entry_points(&self) -> usize; + fn estimate_casm_hash_computation_resources(&self) -> ExecutionResources; } -impl ContractClassV0 { +impl ContractClassV0Ext for ContractClassV0 { fn constructor_selector(&self) -> Option { Some(self.entry_points_by_type[&EntryPointType::Constructor].first()?.selector) } @@ -136,51 +113,48 @@ impl ContractClassV0 { builtin_instance_counter: HashMap::from([(BuiltinName::pedersen, hashed_data_size)]), } } +} + +pub trait ContractClassV0PubExt { + fn n_builtins(&self) -> usize; + fn bytecode_length(&self) -> usize; + fn try_from_json_string(raw_contract_class: &str) -> Result; +} - pub fn n_builtins(&self) -> usize { +impl ContractClassV0PubExt for ContractClassV0 { + fn n_builtins(&self) -> usize { self.program.builtins_len() } - pub fn bytecode_length(&self) -> usize { + fn bytecode_length(&self) -> usize { self.program.data_len() } - pub fn try_from_json_string(raw_contract_class: &str) -> Result { + fn try_from_json_string(raw_contract_class: &str) -> Result { let contract_class: ContractClassV0Inner = serde_json::from_str(raw_contract_class)?; Ok(ContractClassV0(Arc::new(contract_class))) } } -#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] -pub struct ContractClassV0Inner { - #[serde(deserialize_with = "deserialize_program")] - pub program: Program, - pub entry_points_by_type: HashMap>, -} - -impl TryFrom for ContractClassV0 { - type Error = ProgramError; - - fn try_from(class: DeprecatedContractClass) -> Result { - Ok(Self(Arc::new(ContractClassV0Inner { - program: sn_api_to_cairo_vm_program(class.program)?, - entry_points_by_type: class.entry_points_by_type, - }))) - } -} - // V1. -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContractClassV1(pub Arc); -impl Deref for ContractClassV1 { - type Target = ContractClassV1Inner; +trait ContractClassV1Ext { + fn constructor_selector(&self) -> Option; + fn estimate_casm_hash_computation_resources(&self) -> ExecutionResources; + fn get_visited_segments( + &self, + visited_pcs: &HashSet, + ) -> Result, TransactionExecutionError>; +} - fn deref(&self) -> &Self::Target { - &self.0 - } +pub trait ContractClassV1PubExt { + fn bytecode_length(&self) -> usize; + fn get_entry_point(&self, call: &CallEntryPoint) -> Result; + fn try_from_json_string(raw_contract_class: &str) -> Result; + #[cfg(any(feature = "testing", test))] + fn empty_for_testing() -> Self; } -impl ContractClassV1 { +impl ContractClassV1Ext for ContractClassV1 { fn constructor_selector(&self) -> Option { Some(self.0.entry_points_by_type[&EntryPointType::Constructor].first()?.selector) } @@ -189,7 +163,7 @@ impl ContractClassV1 { /// This is an empiric measurement of several bytecode lengths, which constitutes as the /// dominant factor in it. fn estimate_casm_hash_computation_resources(&self) -> ExecutionResources { - estimate_casm_hash_computation_resources(&self.bytecode_segment_lengths) + estimate_casm_hash_computation_resources(self.bytecode_segment_lengths()) } // Returns the set of segments that were visited according to the given visited PCs. @@ -199,21 +173,15 @@ impl ContractClassV1 { visited_pcs: &HashSet, ) -> Result, TransactionExecutionError> { let mut reversed_visited_pcs: Vec<_> = visited_pcs.iter().cloned().sorted().rev().collect(); - get_visited_segments(&self.bytecode_segment_lengths, &mut reversed_visited_pcs, &mut 0) + get_visited_segments(self.bytecode_segment_lengths(), &mut reversed_visited_pcs, &mut 0) } - - pub fn bytecode_length(&self) -> usize { +} +impl ContractClassV1PubExt for ContractClassV1 { + fn bytecode_length(&self) -> usize { self.program.data_len() } - pub fn bytecode_segment_lengths(&self) -> &NestedIntList { - &self.bytecode_segment_lengths - } - - pub fn get_entry_point( - &self, - call: &CallEntryPoint, - ) -> Result { + fn get_entry_point(&self, call: &CallEntryPoint) -> Result { if call.entry_point_type == EntryPointType::Constructor && call.entry_point_selector != selector_from_name(CONSTRUCTOR_ENTRY_POINT_NAME) { @@ -236,22 +204,22 @@ impl ContractClassV1 { } } - pub fn try_from_json_string(raw_contract_class: &str) -> Result { + fn try_from_json_string(raw_contract_class: &str) -> Result { let casm_contract_class: CasmContractClass = serde_json::from_str(raw_contract_class)?; - let contract_class: ContractClassV1 = casm_contract_class.try_into()?; + let contract_class = casm_contract_class.try_into()?; Ok(contract_class) } /// Returns an empty contract class for testing purposes. #[cfg(any(feature = "testing", test))] - pub fn empty_for_testing() -> Self { - Self(Arc::new(ContractClassV1Inner { - program: Default::default(), - entry_points_by_type: Default::default(), - hints: Default::default(), - bytecode_segment_lengths: NestedIntList::Leaf(0), - })) + fn empty_for_testing() -> Self { + Self(Arc::new(ContractClassV1Inner::new_for_testing( + Default::default(), + Default::default(), + Default::default(), + NestedIntList::Leaf(0), + ))) } } @@ -346,198 +314,44 @@ fn get_visited_segments( Ok(res) } -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContractClassV1Inner { - pub program: Program, - pub entry_points_by_type: HashMap>, - pub hints: HashMap, - bytecode_segment_lengths: NestedIntList, -} - -#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] -pub struct EntryPointV1 { - pub selector: EntryPointSelector, - pub offset: EntryPointOffset, - pub builtins: Vec, -} - -impl EntryPointV1 { - pub fn pc(&self) -> usize { - self.offset.0 - } -} - -impl TryFrom for ContractClassV1 { - type Error = ProgramError; - - fn try_from( - contract_class: starknet_api::contract_class::ContractClassV1, - ) -> Result { - let starknet_api::contract_class::ContractClassV1::Casm(casm_contract_class) = - contract_class; - casm_contract_class.try_into() - } -} - -impl TryFrom for ContractClassV1 { - type Error = ProgramError; - - fn try_from(class: CasmContractClass) -> Result { - let data: Vec = class - .bytecode - .into_iter() - .map(|x| MaybeRelocatable::from(Felt::from(x.value))) - .collect(); - - let mut hints: HashMap> = HashMap::new(); - for (i, hint_list) in class.hints.iter() { - let hint_params: Result, ProgramError> = - hint_list.iter().map(hint_to_hint_params).collect(); - hints.insert(*i, hint_params?); - } - - // Collect a sting to hint map so that the hint processor can fetch the correct [Hint] - // for each instruction. - let mut string_to_hint: HashMap = HashMap::new(); - for (_, hint_list) in class.hints.iter() { - for hint in hint_list.iter() { - string_to_hint.insert(serde_json::to_string(hint)?, hint.clone()); - } - } - - let builtins = vec![]; // The builtins are initialize later. - let main = Some(0); - let reference_manager = ReferenceManager { references: Vec::new() }; - let identifiers = HashMap::new(); - let error_message_attributes = vec![]; - let instruction_locations = None; - - let program = Program::new( - builtins, - data, - main, - hints, - reference_manager, - identifiers, - error_message_attributes, - instruction_locations, - )?; - - let mut entry_points_by_type = HashMap::new(); - entry_points_by_type.insert( - EntryPointType::Constructor, - convert_entry_points_v1(class.entry_points_by_type.constructor), - ); - entry_points_by_type.insert( - EntryPointType::External, - convert_entry_points_v1(class.entry_points_by_type.external), - ); - entry_points_by_type.insert( - EntryPointType::L1Handler, - convert_entry_points_v1(class.entry_points_by_type.l1_handler), - ); - - let bytecode_segment_lengths = class - .bytecode_segment_lengths - .unwrap_or_else(|| NestedIntList::Leaf(program.data_len())); - - Ok(Self(Arc::new(ContractClassV1Inner { - program, - entry_points_by_type, - hints: string_to_hint, - bytecode_segment_lengths, - }))) - } -} - -// V0 utilities. - -/// Converts the program type from SN API into a Cairo VM-compatible type. -pub fn deserialize_program<'de, D: Deserializer<'de>>( - deserializer: D, -) -> Result { - let deprecated_program = DeprecatedProgram::deserialize(deserializer)?; - sn_api_to_cairo_vm_program(deprecated_program) - .map_err(|err| DeserializationError::custom(err.to_string())) -} - -// V1 utilities. - -// TODO(spapini): Share with cairo-lang-runner. -fn hint_to_hint_params(hint: &cairo_lang_casm::hints::Hint) -> Result { - Ok(HintParams { - code: serde_json::to_string(hint)?, - accessible_scopes: vec![], - flow_tracking_data: FlowTrackingData { - ap_tracking: ApTracking::new(), - reference_ids: HashMap::new(), - }, - }) -} - -fn convert_entry_points_v1(external: Vec) -> Vec { - external - .into_iter() - .map(|ep| EntryPointV1 { - selector: EntryPointSelector(Felt::from(ep.selector)), - offset: EntryPointOffset(ep.offset), - builtins: ep - .builtins - .into_iter() - .map(|builtin| BuiltinName::from_str(&builtin).expect("Unrecognized builtin.")) - .collect(), - }) - .collect() -} - -#[derive(Clone, Debug)] -// TODO(Ayelet,10/02/2024): Change to bytes. -pub struct ClassInfo { - contract_class: ContractClass, - sierra_program_length: usize, - abi_length: usize, -} - -impl TryFrom for ClassInfo { - type Error = ProgramError; - - fn try_from(class_info: starknet_api::contract_class::ClassInfo) -> Result { - let starknet_api::contract_class::ClassInfo { - contract_class, - sierra_program_length, - abi_length, - } = class_info; - - let contract_class: ContractClass = contract_class.try_into()?; - Ok(Self { contract_class, sierra_program_length, abi_length }) - } +pub trait ClassInfoExt: Sized { + fn bytecode_length(&self) -> usize; + fn contract_class(&self) -> ContractClass; + fn sierra_program_length(&self) -> usize; + fn abi_length(&self) -> usize; + fn code_size(&self) -> usize; + fn new( + contract_class: &ContractClass, + sierra_program_length: usize, + abi_length: usize, + ) -> ContractClassResult; } -impl ClassInfo { - pub fn bytecode_length(&self) -> usize { +impl ClassInfoExt for ClassInfo { + fn bytecode_length(&self) -> usize { self.contract_class.bytecode_length() } - pub fn contract_class(&self) -> ContractClass { + fn contract_class(&self) -> ContractClass { self.contract_class.clone() } - pub fn sierra_program_length(&self) -> usize { + fn sierra_program_length(&self) -> usize { self.sierra_program_length } - pub fn abi_length(&self) -> usize { + fn abi_length(&self) -> usize { self.abi_length } - pub fn code_size(&self) -> usize { + fn code_size(&self) -> usize { (self.bytecode_length() + self.sierra_program_length()) // We assume each felt is a word. * eth_gas_constants::WORD_WIDTH + self.abi_length() } - pub fn new( + fn new( contract_class: &ContractClass, sierra_program_length: usize, abi_length: usize, diff --git a/crates/blockifier/src/execution/contract_class_test.rs b/crates/blockifier/src/execution/contract_class_test.rs index 2bc8ab09a5..adc24c0bfa 100644 --- a/crates/blockifier/src/execution/contract_class_test.rs +++ b/crates/blockifier/src/execution/contract_class_test.rs @@ -4,17 +4,18 @@ use std::sync::Arc; use assert_matches::assert_matches; use cairo_lang_starknet_classes::NestedIntList; use rstest::rstest; +use starknet_api::contract_class::{ContractClassV1, ContractClassV1Inner}; -use crate::execution::contract_class::{ContractClassV1, ContractClassV1Inner}; +use crate::execution::contract_class::ContractClassV1Ext; use crate::transaction::errors::TransactionExecutionError; #[rstest] fn test_get_visited_segments() { - let test_contract = ContractClassV1(Arc::new(ContractClassV1Inner { - program: Default::default(), - entry_points_by_type: Default::default(), - hints: Default::default(), - bytecode_segment_lengths: NestedIntList::Node(vec![ + let test_contract = ContractClassV1(Arc::new(ContractClassV1Inner::new_for_testing( + Default::default(), + Default::default(), + Default::default(), + NestedIntList::Node(vec![ NestedIntList::Leaf(151), NestedIntList::Leaf(104), NestedIntList::Node(vec![NestedIntList::Leaf(170), NestedIntList::Leaf(225)]), @@ -26,7 +27,7 @@ fn test_get_visited_segments() { ])]), NestedIntList::Leaf(162), ]), - })); + ))); assert_eq!( test_contract diff --git a/crates/blockifier/src/execution/deprecated_entry_point_execution.rs b/crates/blockifier/src/execution/deprecated_entry_point_execution.rs index c5021fe5fb..4c4bab453a 100644 --- a/crates/blockifier/src/execution/deprecated_entry_point_execution.rs +++ b/crates/blockifier/src/execution/deprecated_entry_point_execution.rs @@ -5,6 +5,7 @@ use cairo_vm::types::layout_name::LayoutName; use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; use cairo_vm::vm::errors::vm_errors::VirtualMachineError; use cairo_vm::vm::runners::cairo_runner::{CairoArg, CairoRunner, ExecutionResources}; +use starknet_api::contract_class::ContractClassV0; use starknet_api::core::EntryPointSelector; use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::hash::StarkHash; @@ -13,7 +14,6 @@ use super::execution_utils::SEGMENT_ARENA_BUILTIN_SIZE; use crate::abi::abi_utils::selector_from_name; use crate::abi::constants::{CONSTRUCTOR_ENTRY_POINT_NAME, DEFAULT_ENTRY_POINT_SELECTOR}; use crate::execution::call_info::{CallExecution, CallInfo}; -use crate::execution::contract_class::ContractClassV0; use crate::execution::deprecated_syscalls::hint_processor::DeprecatedSyscallHintProcessor; use crate::execution::entry_point::{ CallEntryPoint, diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index a2b1482f53..f5bf293485 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -15,6 +15,7 @@ use crate::abi::constants; use crate::context::{BlockContext, TransactionContext}; use crate::execution::call_info::CallInfo; use crate::execution::common_hints::ExecutionMode; +use crate::execution::contract_class::ContractClassExt; use crate::execution::errors::{ ConstructorEntryPointExecutionError, EntryPointExecutionError, diff --git a/crates/blockifier/src/execution/entry_point_execution.rs b/crates/blockifier/src/execution/entry_point_execution.rs index 3ebae0ad8e..e62e7336ea 100644 --- a/crates/blockifier/src/execution/entry_point_execution.rs +++ b/crates/blockifier/src/execution/entry_point_execution.rs @@ -10,11 +10,12 @@ use cairo_vm::vm::runners::builtin_runner::BuiltinRunner; use cairo_vm::vm::runners::cairo_runner::{CairoArg, CairoRunner, ExecutionResources}; use cairo_vm::vm::security::verify_secure_runner; use num_traits::{ToPrimitive, Zero}; +use starknet_api::contract_class::{ContractClassV1, EntryPointV1}; use starknet_api::felt; use starknet_types_core::felt::Felt; use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; -use crate::execution::contract_class::{ContractClassV1, EntryPointV1}; +use crate::execution::contract_class::ContractClassV1PubExt; use crate::execution::entry_point::{ CallEntryPoint, EntryPointExecutionContext, diff --git a/crates/blockifier/src/execution/execution_utils.rs b/crates/blockifier/src/execution/execution_utils.rs index ad2f2ffeed..7828925f60 100644 --- a/crates/blockifier/src/execution/execution_utils.rs +++ b/crates/blockifier/src/execution/execution_utils.rs @@ -8,6 +8,7 @@ use cairo_vm::vm::errors::vm_errors::VirtualMachineError; use cairo_vm::vm::runners::cairo_runner::{CairoArg, CairoRunner, ExecutionResources}; use cairo_vm::vm::vm_core::VirtualMachine; use num_bigint::BigUint; +use starknet_api::contract_class::ContractClass; use starknet_api::core::ClassHash; use starknet_api::transaction::Calldata; use starknet_types_core::felt::Felt; @@ -15,7 +16,6 @@ use starknet_types_core::felt::Felt; use super::entry_point::ConstructorEntryPointExecutionResult; use super::errors::ConstructorEntryPointExecutionError; use crate::execution::call_info::{CallInfo, Retdata}; -use crate::execution::contract_class::ContractClass; use crate::execution::entry_point::{ execute_constructor_entry_point, CallEntryPoint, diff --git a/crates/blockifier/src/execution/syscalls/mod.rs b/crates/blockifier/src/execution/syscalls/mod.rs index 9e31c9ab9b..6ef879f591 100644 --- a/crates/blockifier/src/execution/syscalls/mod.rs +++ b/crates/blockifier/src/execution/syscalls/mod.rs @@ -2,6 +2,7 @@ use cairo_vm::types::relocatable::{MaybeRelocatable, Relocatable}; use cairo_vm::vm::vm_core::VirtualMachine; use num_traits::ToPrimitive; use starknet_api::block::{BlockHash, BlockNumber}; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ calculate_contract_address, ClassHash, @@ -37,7 +38,6 @@ use self::hint_processor::{ }; use crate::abi::constants; use crate::execution::call_info::{MessageToL1, OrderedEvent, OrderedL2ToL1Message}; -use crate::execution::contract_class::ContractClass; use crate::execution::deprecated_syscalls::DeprecatedSyscallSelector; use crate::execution::entry_point::{CallEntryPoint, CallType, ConstructorContext}; use crate::execution::execution_utils::{ diff --git a/crates/blockifier/src/fee/actual_cost_test.rs b/crates/blockifier/src/fee/actual_cost_test.rs index acddd480c1..5473ab8a3c 100644 --- a/crates/blockifier/src/fee/actual_cost_test.rs +++ b/crates/blockifier/src/fee/actual_cost_test.rs @@ -4,6 +4,7 @@ use starknet_types_core::felt::Felt; use crate::context::BlockContext; use crate::execution::call_info::{CallExecution, CallInfo, MessageToL1, OrderedL2ToL1Message}; +use crate::execution::contract_class::ClassInfoExt; use crate::fee::eth_gas_constants; use crate::fee::gas_usage::{ get_consumed_message_to_l2_emissions_cost, diff --git a/crates/blockifier/src/state/cached_state.rs b/crates/blockifier/src/state/cached_state.rs index 93201f3456..f82b50084e 100644 --- a/crates/blockifier/src/state/cached_state.rs +++ b/crates/blockifier/src/state/cached_state.rs @@ -3,13 +3,13 @@ use std::collections::{HashMap, HashSet}; use derive_more::IntoIterator; use indexmap::IndexMap; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; use crate::abi::abi_utils::get_fee_token_var_address; use crate::context::TransactionContext; -use crate::execution::contract_class::ContractClass; use crate::state::errors::StateError; use crate::state::state_api::{State, StateReader, StateResult, UpdatableState}; use crate::transaction::objects::TransactionExecutionInfo; diff --git a/crates/blockifier/src/state/global_cache.rs b/crates/blockifier/src/state/global_cache.rs index 54d71a1fac..12970d8956 100644 --- a/crates/blockifier/src/state/global_cache.rs +++ b/crates/blockifier/src/state/global_cache.rs @@ -1,10 +1,9 @@ use std::sync::{Arc, Mutex, MutexGuard}; use cached::{Cached, SizedCache}; +use starknet_api::contract_class::ContractClass; use starknet_api::core::ClassHash; -use crate::execution::contract_class::ContractClass; - // Note: `ContractClassLRUCache` key-value types must align with `ContractClassMapping`. type ContractClassLRUCache = SizedCache; pub type LockedContractClassCache<'a> = MutexGuard<'a, ContractClassLRUCache>; diff --git a/crates/blockifier/src/state/state_api.rs b/crates/blockifier/src/state/state_api.rs index 5d3c308e2f..66dcd14cd1 100644 --- a/crates/blockifier/src/state/state_api.rs +++ b/crates/blockifier/src/state/state_api.rs @@ -1,5 +1,6 @@ use std::collections::{HashMap, HashSet}; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; @@ -7,7 +8,6 @@ use starknet_types_core::felt::Felt; use super::cached_state::{ContractClassMapping, StateMaps}; use crate::abi::abi_utils::get_fee_token_var_address; use crate::abi::sierra_types::next_storage_key; -use crate::execution::contract_class::ContractClass; use crate::state::errors::StateError; pub type StateResult = Result; diff --git a/crates/blockifier/src/test_utils/contracts.rs b/crates/blockifier/src/test_utils/contracts.rs index 81c736e681..f780093335 100644 --- a/crates/blockifier/src/test_utils/contracts.rs +++ b/crates/blockifier/src/test_utils/contracts.rs @@ -1,3 +1,4 @@ +use starknet_api::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use starknet_api::core::{ ClassHash, CompiledClassHash, @@ -17,8 +18,8 @@ use strum_macros::EnumIter; use crate::abi::abi_utils::selector_from_name; use crate::abi::constants::CONSTRUCTOR_ENTRY_POINT_NAME; -use crate::execution::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use crate::test_utils::cairo_compile::{cairo0_compile, cairo1_compile}; +use crate::test_utils::struct_impls::FromFileExt; use crate::test_utils::{get_raw_contract_class, CairoVersion}; // This file contains featured contracts, used for tests. Use the function 'test_state' in diff --git a/crates/blockifier/src/test_utils/declare.rs b/crates/blockifier/src/test_utils/declare.rs index 6973d18ca7..568c434d6c 100644 --- a/crates/blockifier/src/test_utils/declare.rs +++ b/crates/blockifier/src/test_utils/declare.rs @@ -1,3 +1,4 @@ +use starknet_api::contract_class::ClassInfo; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::transaction::{ @@ -14,7 +15,6 @@ use starknet_api::transaction::{ TransactionVersion, }; -use crate::execution::contract_class::ClassInfo; use crate::test_utils::default_testing_resource_bounds; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::transactions::DeclareTransaction; diff --git a/crates/blockifier/src/test_utils/dict_state_reader.rs b/crates/blockifier/src/test_utils/dict_state_reader.rs index 54fcd890e2..87ec871cd9 100644 --- a/crates/blockifier/src/test_utils/dict_state_reader.rs +++ b/crates/blockifier/src/test_utils/dict_state_reader.rs @@ -1,10 +1,10 @@ use std::collections::HashMap; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; -use crate::execution::contract_class::ContractClass; use crate::state::cached_state::StorageEntry; use crate::state::errors::StateError; use crate::state::state_api::{StateReader, StateResult}; diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs index 664041671c..f0f7c7f9a2 100644 --- a/crates/blockifier/src/test_utils/struct_impls.rs +++ b/crates/blockifier/src/test_utils/struct_impls.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use serde_json::Value; use starknet_api::block::{BlockNumber, BlockTimestamp}; +use starknet_api::contract_class::{ContractClassV0, ContractClassV1}; use starknet_api::core::{ChainId, ContractAddress, Nonce, PatriciaKey}; use starknet_api::transaction::{Calldata, Fee, TransactionHash, TransactionVersion}; use starknet_api::{calldata, contract_address, felt, patricia_key}; @@ -14,7 +15,7 @@ use crate::blockifier::block::{BlockInfo, GasPrices}; use crate::bouncer::{BouncerConfig, BouncerWeights}; use crate::context::{BlockContext, ChainInfo, FeeTokenAddresses, TransactionContext}; use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; -use crate::execution::contract_class::{ContractClassV0, ContractClassV1}; +use crate::execution::contract_class::{ContractClassV0PubExt, ContractClassV1PubExt}; use crate::execution::entry_point::{ CallEntryPoint, EntryPointExecutionContext, @@ -220,15 +221,19 @@ impl CallExecution { // Contract loaders. -impl ContractClassV0 { - pub fn from_file(contract_path: &str) -> Self { +pub trait FromFileExt { + fn from_file(contract_path: &str) -> Self; +} + +impl FromFileExt for ContractClassV0 { + fn from_file(contract_path: &str) -> Self { let raw_contract_class = get_raw_contract_class(contract_path); Self::try_from_json_string(&raw_contract_class).unwrap() } } -impl ContractClassV1 { - pub fn from_file(contract_path: &str) -> Self { +impl FromFileExt for ContractClassV1 { + fn from_file(contract_path: &str) -> Self { let raw_contract_class = get_raw_contract_class(contract_path); Self::try_from_json_string(&raw_contract_class).unwrap() } diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 1cc97e9ed1..89c044e119 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::calldata; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ContractAddress, EntryPointSelector}; use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::transaction::{Calldata, Fee, ResourceBounds, TransactionVersion}; @@ -10,7 +11,7 @@ use starknet_types_core::felt::Felt; use crate::abi::abi_utils::selector_from_name; use crate::context::{BlockContext, TransactionContext}; use crate::execution::call_info::{CallInfo, Retdata}; -use crate::execution::contract_class::ContractClass; +use crate::execution::contract_class::ClassInfoExt; use crate::execution::entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext}; use crate::fee::actual_cost::TransactionReceipt; use crate::fee::fee_checks::{FeeCheckReportFields, PostExecutionReport}; diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index 3f48297d15..241ef02b0d 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -5,6 +5,7 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ResourceTracker; use pretty_assertions::assert_eq; use rstest::rstest; +use starknet_api::contract_class::{ContractClass, ContractClassV1}; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, PatriciaKey}; use starknet_api::hash::StarkHash; use starknet_api::state::StorageKey; @@ -26,7 +27,7 @@ use crate::abi::abi_utils::{ selector_from_name, }; use crate::context::BlockContext; -use crate::execution::contract_class::{ContractClass, ContractClassV1}; +use crate::execution::contract_class::ContractClassV1PubExt; use crate::execution::entry_point::EntryPointExecutionContext; use crate::execution::syscalls::SyscallSelector; use crate::fee::fee_utils::{get_fee_by_gas_vector, get_sequencer_balance_keys}; diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index d6b1724e3a..0280e9d4c9 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -1,4 +1,5 @@ use rstest::fixture; +use starknet_api::contract_class::{ClassInfo, ContractClass}; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::transaction::{ Calldata, @@ -20,7 +21,7 @@ use strum::IntoEnumIterator; use crate::abi::abi_utils::get_fee_token_var_address; use crate::context::{BlockContext, ChainInfo}; -use crate::execution::contract_class::{ClassInfo, ContractClass}; +use crate::execution::contract_class::ClassInfoExt; use crate::state::cached_state::CachedState; use crate::state::state_api::State; use crate::test_utils::contracts::FeatureContract; diff --git a/crates/blockifier/src/transaction/transaction_execution.rs b/crates/blockifier/src/transaction/transaction_execution.rs index f2fb174a84..8e2a7d7ea4 100644 --- a/crates/blockifier/src/transaction/transaction_execution.rs +++ b/crates/blockifier/src/transaction/transaction_execution.rs @@ -1,12 +1,12 @@ use std::sync::Arc; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; +use starknet_api::contract_class::ClassInfo; use starknet_api::core::{calculate_contract_address, ContractAddress}; use starknet_api::transaction::{Fee, Transaction as StarknetApiTransaction, TransactionHash}; use crate::bouncer::verify_tx_weights_in_bounds; use crate::context::BlockContext; -use crate::execution::contract_class::ClassInfo; use crate::execution::entry_point::EntryPointExecutionContext; use crate::fee::actual_cost::TransactionReceipt; use crate::state::cached_state::TransactionalState; diff --git a/crates/blockifier/src/transaction/transaction_utils.rs b/crates/blockifier/src/transaction/transaction_utils.rs index 1f4edc40c4..74a60f6c1e 100644 --- a/crates/blockifier/src/transaction/transaction_utils.rs +++ b/crates/blockifier/src/transaction/transaction_utils.rs @@ -1,7 +1,7 @@ +use starknet_api::contract_class::ContractClass; use starknet_api::transaction::TransactionVersion; use crate::execution::call_info::CallInfo; -use crate::execution::contract_class::ContractClass; use crate::transaction::errors::TransactionExecutionError; pub fn update_remaining_gas(remaining_gas: &mut u64, call_info: &CallInfo) { diff --git a/crates/blockifier/src/transaction/transactions.rs b/crates/blockifier/src/transaction/transactions.rs index 834660c740..d039c608ad 100644 --- a/crates/blockifier/src/transaction/transactions.rs +++ b/crates/blockifier/src/transaction/transactions.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; +use starknet_api::contract_class::{ClassInfo, ContractClass}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::transaction::{ @@ -18,7 +19,7 @@ use starknet_api::transaction::{ use crate::abi::abi_utils::selector_from_name; use crate::context::{BlockContext, TransactionContext}; use crate::execution::call_info::CallInfo; -use crate::execution::contract_class::{ClassInfo, ContractClass}; +use crate::execution::contract_class::ClassInfoExt; use crate::execution::entry_point::{ CallEntryPoint, CallType, diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index a8198cfa9b..2c98cc8e9f 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -43,6 +43,7 @@ use crate::execution::call_info::{ OrderedL2ToL1Message, Retdata, }; +use crate::execution::contract_class::ClassInfoExt; use crate::execution::entry_point::{CallEntryPoint, CallType}; use crate::execution::errors::{ConstructorEntryPointExecutionError, EntryPointExecutionError}; use crate::execution::syscalls::hint_processor::{EmitEventError, L1_GAS, L2_GAS}; diff --git a/crates/gateway/src/compilation.rs b/crates/gateway/src/compilation.rs index fbd687e802..0b6810cab7 100644 --- a/crates/gateway/src/compilation.rs +++ b/crates/gateway/src/compilation.rs @@ -1,8 +1,9 @@ use std::sync::Arc; -use blockifier::execution::contract_class::{ClassInfo, ContractClass, ContractClassV1}; +use blockifier::execution::contract_class::ClassInfoExt; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use cairo_lang_starknet_classes::contract_class::ContractClass as CairoLangContractClass; +use starknet_api::contract_class::{ClassInfo, ContractClass, ContractClassV1}; use starknet_api::core::CompiledClassHash; use starknet_api::rpc_transaction::RpcDeclareTransaction; use starknet_sierra_compile::cairo_lang_compiler::CairoLangSierraToCasmCompiler; diff --git a/crates/gateway/src/compilation_test.rs b/crates/gateway/src/compilation_test.rs index fd5018ee52..7c52d994df 100644 --- a/crates/gateway/src/compilation_test.rs +++ b/crates/gateway/src/compilation_test.rs @@ -1,10 +1,11 @@ use assert_matches::assert_matches; -use blockifier::execution::contract_class::ContractClass; +use blockifier::execution::contract_class::ClassInfoExt; use cairo_lang_sierra_to_casm::compiler::CompilationError; use cairo_lang_starknet_classes::allowed_libfuncs::AllowedLibfuncsError; use cairo_lang_starknet_classes::casm_contract_class::StarknetSierraCompilationError; use mempool_test_utils::starknet_api_test_utils::declare_tx as rpc_declare_tx; use rstest::{fixture, rstest}; +use starknet_api::contract_class::ContractClass; use starknet_api::core::CompiledClassHash; use starknet_api::rpc_transaction::{ RpcDeclareTransaction, diff --git a/crates/gateway/src/rpc_state_reader.rs b/crates/gateway/src/rpc_state_reader.rs index 60fec240bd..3b9ee709ad 100644 --- a/crates/gateway/src/rpc_state_reader.rs +++ b/crates/gateway/src/rpc_state_reader.rs @@ -1,5 +1,4 @@ use blockifier::blockifier::block::BlockInfo; -use blockifier::execution::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader as BlockifierStateReader, StateResult}; use papyrus_rpc::CompiledContractClass; @@ -7,6 +6,7 @@ use reqwest::blocking::Client as BlockingClient; use serde::Serialize; use serde_json::{json, Value}; use starknet_api::block::BlockNumber; +use starknet_api::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; diff --git a/crates/gateway/src/rpc_state_reader_test.rs b/crates/gateway/src/rpc_state_reader_test.rs index af344104a0..f79440fa97 100644 --- a/crates/gateway/src/rpc_state_reader_test.rs +++ b/crates/gateway/src/rpc_state_reader_test.rs @@ -1,10 +1,10 @@ -use blockifier::execution::contract_class::ContractClass; use blockifier::state::state_api::StateReader; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use papyrus_rpc::CompiledContractClass; use serde::Serialize; use serde_json::json; use starknet_api::block::{BlockNumber, GasPrice}; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, ContractAddress, Nonce, PatriciaKey}; use starknet_api::{class_hash, contract_address, felt, patricia_key}; diff --git a/crates/gateway/src/state_reader.rs b/crates/gateway/src/state_reader.rs index 0aa555b050..2d16dcc6ba 100644 --- a/crates/gateway/src/state_reader.rs +++ b/crates/gateway/src/state_reader.rs @@ -1,10 +1,10 @@ use blockifier::blockifier::block::BlockInfo; -use blockifier::execution::contract_class::ContractClass; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader as BlockifierStateReader, StateResult}; #[cfg(test)] use mockall::automock; use starknet_api::block::BlockNumber; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; diff --git a/crates/gateway/src/state_reader_test_utils.rs b/crates/gateway/src/state_reader_test_utils.rs index a806bed9b6..65e43d0a14 100644 --- a/crates/gateway/src/state_reader_test_utils.rs +++ b/crates/gateway/src/state_reader_test_utils.rs @@ -1,6 +1,5 @@ use blockifier::blockifier::block::BlockInfo; use blockifier::context::BlockContext; -use blockifier::execution::contract_class::ContractClass; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader as BlockifierStateReader, StateResult}; use blockifier::test_utils::contracts::FeatureContract; @@ -8,6 +7,7 @@ use blockifier::test_utils::dict_state_reader::DictStateReader; use blockifier::test_utils::initial_test_state::test_state; use blockifier::test_utils::{CairoVersion, BALANCE}; use starknet_api::block::BlockNumber; +use starknet_api::contract_class::ContractClass; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; diff --git a/crates/gateway/src/stateful_transaction_validator.rs b/crates/gateway/src/stateful_transaction_validator.rs index e91dbf80d8..8dfad0cfd2 100644 --- a/crates/gateway/src/stateful_transaction_validator.rs +++ b/crates/gateway/src/stateful_transaction_validator.rs @@ -5,12 +5,12 @@ use blockifier::blockifier::stateful_validator::{ }; use blockifier::bouncer::BouncerConfig; use blockifier::context::BlockContext; -use blockifier::execution::contract_class::ClassInfo; use blockifier::state::cached_state::CachedState; use blockifier::transaction::account_transaction::AccountTransaction; use blockifier::versioned_constants::VersionedConstants; #[cfg(test)] use mockall::automock; +use starknet_api::contract_class::ClassInfo; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::rpc_transaction::{RpcInvokeTransaction, RpcTransaction}; use starknet_api::transaction::TransactionHash; diff --git a/crates/gateway/src/utils.rs b/crates/gateway/src/utils.rs index 026fbf46e0..c85c8320f8 100644 --- a/crates/gateway/src/utils.rs +++ b/crates/gateway/src/utils.rs @@ -1,10 +1,10 @@ -use blockifier::execution::contract_class::ClassInfo; use blockifier::transaction::account_transaction::AccountTransaction; use blockifier::transaction::transactions::{ DeclareTransaction as BlockifierDeclareTransaction, DeployAccountTransaction as BlockifierDeployAccountTransaction, InvokeTransaction as BlockifierInvokeTransaction, }; +use starknet_api::contract_class::ClassInfo; use starknet_api::core::{calculate_contract_address, ChainId, ClassHash, ContractAddress}; use starknet_api::rpc_transaction::{ RpcDeclareTransaction, diff --git a/crates/native_blockifier/src/py_block_executor_test.rs b/crates/native_blockifier/src/py_block_executor_test.rs index ffc5908ad8..79dfea7252 100644 --- a/crates/native_blockifier/src/py_block_executor_test.rs +++ b/crates/native_blockifier/src/py_block_executor_test.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; use blockifier::blockifier::transaction_executor::BLOCK_STATE_ACCESS_ERR; -use blockifier::execution::contract_class::{ContractClass, ContractClassV1}; use blockifier::state::state_api::StateReader; use cached::Cached; use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use pretty_assertions::assert_eq; +use starknet_api::contract_class::{ContractClass, ContractClassV1}; use starknet_api::core::ClassHash; use starknet_api::{class_hash, felt}; use starknet_types_core::felt::Felt; diff --git a/crates/native_blockifier/src/py_test_utils.rs b/crates/native_blockifier/src/py_test_utils.rs index 0e66423790..cdfaaf38b0 100644 --- a/crates/native_blockifier/src/py_test_utils.rs +++ b/crates/native_blockifier/src/py_test_utils.rs @@ -1,8 +1,9 @@ use std::collections::HashMap; -use blockifier::execution::contract_class::ContractClassV0; use blockifier::state::cached_state::CachedState; use blockifier::test_utils::dict_state_reader::DictStateReader; +use blockifier::test_utils::struct_impls::FromFileExt; +use starknet_api::contract_class::ContractClassV0; use starknet_api::core::ClassHash; use starknet_api::{class_hash, felt}; diff --git a/crates/native_blockifier/src/py_transaction.rs b/crates/native_blockifier/src/py_transaction.rs index 7b84d89d71..732b9098b4 100644 --- a/crates/native_blockifier/src/py_transaction.rs +++ b/crates/native_blockifier/src/py_transaction.rs @@ -1,16 +1,16 @@ use std::collections::BTreeMap; use blockifier::execution::contract_class::{ - ClassInfo, - ContractClass, - ContractClassV0, - ContractClassV1, + ClassInfoExt, + ContractClassV0PubExt, + ContractClassV1PubExt, }; use blockifier::transaction::account_transaction::AccountTransaction; use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transaction_types::TransactionType; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; +use starknet_api::contract_class::{ClassInfo, ContractClass, ContractClassV0, ContractClassV1}; use starknet_api::transaction::{Resource, ResourceBounds}; use starknet_api::StarknetApiError; diff --git a/crates/native_blockifier/src/state_readers/papyrus_state.rs b/crates/native_blockifier/src/state_readers/papyrus_state.rs index 463d242b0c..43dbe61771 100644 --- a/crates/native_blockifier/src/state_readers/papyrus_state.rs +++ b/crates/native_blockifier/src/state_readers/papyrus_state.rs @@ -1,4 +1,3 @@ -use blockifier::execution::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use blockifier::state::errors::StateError; use blockifier::state::global_cache::GlobalContractCache; use blockifier::state::state_api::{StateReader, StateResult}; @@ -7,6 +6,7 @@ use papyrus_storage::db::RO; use papyrus_storage::state::StateStorageReader; use papyrus_storage::StorageReader; use starknet_api::block::BlockNumber; +use starknet_api::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::{StateNumber, StorageKey}; use starknet_types_core::felt::Felt; diff --git a/crates/native_blockifier/src/state_readers/py_state_reader.rs b/crates/native_blockifier/src/state_readers/py_state_reader.rs index 35d78eea15..10f0c7dc94 100644 --- a/crates/native_blockifier/src/state_readers/py_state_reader.rs +++ b/crates/native_blockifier/src/state_readers/py_state_reader.rs @@ -1,7 +1,8 @@ -use blockifier::execution::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; +use blockifier::execution::contract_class::{ContractClassV0PubExt, ContractClassV1PubExt}; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader, StateResult}; use pyo3::{FromPyObject, PyAny, PyErr, PyObject, PyResult, Python}; +use starknet_api::contract_class::{ContractClass, ContractClassV0, ContractClassV1}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; diff --git a/crates/papyrus_execution/src/execution_utils.rs b/crates/papyrus_execution/src/execution_utils.rs index 928728acab..07cdde53c7 100644 --- a/crates/papyrus_execution/src/execution_utils.rs +++ b/crates/papyrus_execution/src/execution_utils.rs @@ -4,11 +4,6 @@ use std::path::PathBuf; // Expose the tool for creating entry point selectors from function names. pub use blockifier::abi::abi_utils::selector_from_name; -use blockifier::execution::contract_class::{ - ContractClass as BlockifierContractClass, - ContractClassV0, - ContractClassV1, -}; use blockifier::state::cached_state::{CachedState, CommitmentStateDiff, MutRefState}; use blockifier::state::state_api::StateReader; use blockifier::transaction::objects::TransactionExecutionInfo; @@ -19,6 +14,11 @@ use papyrus_storage::compiled_class::CasmStorageReader; use papyrus_storage::db::{TransactionKind, RO}; use papyrus_storage::state::StateStorageReader; use papyrus_storage::{StorageError, StorageResult, StorageTxn}; +use starknet_api::contract_class::{ + ContractClass as BlockifierContractClass, + ContractClassV0, + ContractClassV1, +}; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::state::{StateNumber, StorageKey, ThinStateDiff}; use starknet_types_core::felt::Felt; diff --git a/crates/papyrus_execution/src/lib.rs b/crates/papyrus_execution/src/lib.rs index 46536125d4..e1b07ac694 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -29,7 +29,7 @@ use blockifier::blockifier::block::{pre_process_block, BlockInfo, BlockNumberHas use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses, TransactionContext}; use blockifier::execution::call_info::CallExecution; -use blockifier::execution::contract_class::{ClassInfo, ContractClass as BlockifierContractClass}; +use blockifier::execution::contract_class::ClassInfoExt; use blockifier::execution::entry_point::{ CallEntryPoint, CallType as BlockifierCallType, @@ -59,6 +59,7 @@ use papyrus_storage::header::HeaderStorageReader; use papyrus_storage::{StorageError, StorageReader}; use serde::{Deserialize, Serialize}; use starknet_api::block::{BlockNumber, StarknetVersion}; +use starknet_api::contract_class::{ClassInfo, ContractClass as BlockifierContractClass}; use starknet_api::core::{ChainId, ClassHash, ContractAddress, EntryPointSelector, PatriciaKey}; use starknet_api::data_availability::L1DataAvailabilityMode; // TODO: merge multiple EntryPointType structs in SN_API into one. diff --git a/crates/papyrus_execution/src/state_reader.rs b/crates/papyrus_execution/src/state_reader.rs index a15df3c3c8..9ff78c3b36 100644 --- a/crates/papyrus_execution/src/state_reader.rs +++ b/crates/papyrus_execution/src/state_reader.rs @@ -4,17 +4,17 @@ mod state_reader_test; use std::cell::Cell; -use blockifier::execution::contract_class::{ - ContractClass as BlockifierContractClass, - ContractClassV0, - ContractClassV1, -}; use blockifier::state::errors::StateError; use blockifier::state::state_api::{StateReader as BlockifierStateReader, StateResult}; use papyrus_common::pending_classes::{ApiContractClass, PendingClassesTrait}; use papyrus_common::state::DeclaredClassHashEntry; use papyrus_storage::state::StateStorageReader; use papyrus_storage::{StorageError, StorageReader}; +use starknet_api::contract_class::{ + ContractClass as BlockifierContractClass, + ContractClassV0, + ContractClassV1, +}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::{StateNumber, StorageKey}; use starknet_types_core::felt::Felt; diff --git a/crates/papyrus_execution/src/state_reader_test.rs b/crates/papyrus_execution/src/state_reader_test.rs index 332eec48c9..71538316d9 100644 --- a/crates/papyrus_execution/src/state_reader_test.rs +++ b/crates/papyrus_execution/src/state_reader_test.rs @@ -1,11 +1,6 @@ use std::cell::Cell; use assert_matches::assert_matches; -use blockifier::execution::contract_class::{ - ContractClass as BlockifierContractClass, - ContractClassV0, - ContractClassV1, -}; use blockifier::state::errors::StateError; use blockifier::state::state_api::StateReader; use cairo_lang_utils::bigint::BigUintAsHex; @@ -24,6 +19,11 @@ use papyrus_storage::header::HeaderStorageWriter; use papyrus_storage::state::StateStorageWriter; use papyrus_storage::test_utils::get_test_storage; use starknet_api::block::{BlockBody, BlockHash, BlockHeader, BlockNumber}; +use starknet_api::contract_class::{ + ContractClass as BlockifierContractClass, + ContractClassV0, + ContractClassV1, +}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey}; use starknet_api::hash::StarkHash; use starknet_api::state::{ContractClass, StateNumber, StorageKey, ThinStateDiff}; diff --git a/crates/starknet_api/src/contract_class.rs b/crates/starknet_api/src/contract_class.rs index 8d9d1be4ec..a80a9f7970 100644 --- a/crates/starknet_api/src/contract_class.rs +++ b/crates/starknet_api/src/contract_class.rs @@ -1,20 +1,236 @@ -use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; +use std::collections::HashMap; +use std::ops::Deref; +use std::sync::Arc; -/// Compiled contract class. -#[derive(Clone, Debug, Eq, PartialEq)] +use cairo_lang_casm::hints::Hint; +use cairo_lang_starknet_classes::casm_contract_class::{CasmContractClass, CasmContractEntryPoint}; +use cairo_lang_starknet_classes::NestedIntList; +use cairo_vm::serde::deserialize_program::{ + ApTracking, + FlowTrackingData, + HintParams, + ReferenceManager, +}; +use cairo_vm::types::builtin_name::BuiltinName; +use cairo_vm::types::errors::program_errors::ProgramError; +use cairo_vm::types::program::Program as CairoVmProgram; +use cairo_vm::types::relocatable::MaybeRelocatable; +use serde::de::Error as DeserializationError; +use serde::{Deserialize, Deserializer}; +use starknet_types_core::felt::Felt; + +use crate::core::EntryPointSelector; +use crate::deprecated_contract_class::{ + sn_api_to_cairo_vm_program, + ContractClass as DeprecatedContractClass, + EntryPoint, + EntryPointOffset, + EntryPointType, + Program as DeprecatedProgram, +}; + +/// Executable contract class. +#[derive(Clone, Debug, Eq, PartialEq, derive_more::From)] pub enum ContractClass { + V0(ContractClassV0), V1(ContractClassV1), } -/// Compiled contract class variant for Cairo 1 contracts. +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] +pub struct ContractClassV0(pub Arc); +impl Deref for ContractClassV0 { + type Target = ContractClassV0Inner; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] +pub struct ContractClassV0Inner { + #[serde(deserialize_with = "deserialize_program")] + pub program: CairoVmProgram, + pub entry_points_by_type: HashMap>, +} + +impl TryFrom for ContractClassV0 { + type Error = ProgramError; + + fn try_from(class: DeprecatedContractClass) -> Result { + Ok(Self(Arc::new(ContractClassV0Inner { + program: sn_api_to_cairo_vm_program(class.program)?, + entry_points_by_type: class.entry_points_by_type, + }))) + } +} + +// V1. #[derive(Clone, Debug, Eq, PartialEq)] -pub enum ContractClassV1 { - Casm(CasmContractClass), +pub struct ContractClassV1(pub Arc); +impl Deref for ContractClassV1 { + type Target = ContractClassV1Inner; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ContractClassV1Inner { + pub program: CairoVmProgram, + pub entry_points_by_type: HashMap>, + pub hints: HashMap, + bytecode_segment_lengths: NestedIntList, +} + +impl ContractClassV1Inner { + #[cfg(any(feature = "testing", test))] + pub fn new_for_testing( + program: CairoVmProgram, + entry_points_by_type: HashMap>, + hints: HashMap, + bytecode_segment_lengths: NestedIntList, + ) -> Self { + Self { program, entry_points_by_type, hints, bytecode_segment_lengths } + } +} + +impl ContractClassV1 { + pub fn bytecode_segment_lengths(&self) -> &NestedIntList { + &self.bytecode_segment_lengths + } +} + +impl TryFrom for ContractClassV1 { + type Error = ProgramError; + + fn try_from(class: CasmContractClass) -> Result { + let data: Vec = class + .bytecode + .into_iter() + .map(|x| MaybeRelocatable::from(Felt::from(x.value))) + .collect(); + + let mut hints: HashMap> = HashMap::new(); + for (i, hint_list) in class.hints.iter() { + let hint_params: Result, ProgramError> = + hint_list.iter().map(hint_to_hint_params).collect(); + hints.insert(*i, hint_params?); + } + + // Collect a sting to hint map so that the hint processor can fetch the correct [Hint] + // for each instruction. + let mut string_to_hint: HashMap = HashMap::new(); + for (_, hint_list) in class.hints.iter() { + for hint in hint_list.iter() { + string_to_hint.insert(serde_json::to_string(hint)?, hint.clone()); + } + } + + let builtins = vec![]; // The builtins are initialize later. + let main = Some(0); + let reference_manager = ReferenceManager { references: Vec::new() }; + let identifiers = HashMap::new(); + let error_message_attributes = vec![]; + let instruction_locations = None; + + let program = CairoVmProgram::new( + builtins, + data, + main, + hints, + reference_manager, + identifiers, + error_message_attributes, + instruction_locations, + )?; + + let mut entry_points_by_type = HashMap::new(); + entry_points_by_type.insert( + EntryPointType::Constructor, + convert_entry_points_v1(class.entry_points_by_type.constructor), + ); + entry_points_by_type.insert( + EntryPointType::External, + convert_entry_points_v1(class.entry_points_by_type.external), + ); + entry_points_by_type.insert( + EntryPointType::L1Handler, + convert_entry_points_v1(class.entry_points_by_type.l1_handler), + ); + + let bytecode_segment_lengths = class + .bytecode_segment_lengths + .unwrap_or_else(|| NestedIntList::Leaf(program.data_len())); + + Ok(Self(Arc::new(ContractClassV1Inner { + program, + entry_points_by_type, + hints: string_to_hint, + bytecode_segment_lengths, + }))) + } +} + +#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] +pub struct EntryPointV1 { + pub selector: EntryPointSelector, + pub offset: EntryPointOffset, + pub builtins: Vec, +} + +impl EntryPointV1 { + pub fn pc(&self) -> usize { + self.offset.0 + } +} + +// V0 utilities. + +/// Converts the program type from SN API into a Cairo VM-compatible type. +pub fn deserialize_program<'de, D: Deserializer<'de>>( + deserializer: D, +) -> Result { + let deprecated_program = DeprecatedProgram::deserialize(deserializer)?; + sn_api_to_cairo_vm_program(deprecated_program) + .map_err(|err| DeserializationError::custom(err.to_string())) +} + +// V1 utilities. + +// TODO(spapini): Share with cairo-lang-runner. +/// Used in TryFrom +fn hint_to_hint_params(hint: &cairo_lang_casm::hints::Hint) -> Result { + Ok(HintParams { + code: serde_json::to_string(hint)?, + accessible_scopes: vec![], + flow_tracking_data: FlowTrackingData { + ap_tracking: ApTracking::new(), + reference_ids: HashMap::new(), + }, + }) +} + +/// Used in TryFrom +fn convert_entry_points_v1(external: Vec) -> Vec { + external + .into_iter() + .map(|ep| EntryPointV1 { + selector: EntryPointSelector(Felt::from(ep.selector)), + offset: EntryPointOffset(ep.offset), + builtins: ep + .builtins + .into_iter() + .map(|builtin| BuiltinName::from_str(&builtin).expect("Unrecognized builtin.")) + .collect(), + }) + .collect() } /// All relevant information about a declared contract class, including the compiled contract class /// and other parameters derived from the original declare transaction required for billing. #[derive(Clone, Debug, Eq, PartialEq)] +// TODO(Ayelet,10/02/2024): Change to bytes. pub struct ClassInfo { pub contract_class: ContractClass, pub sierra_program_length: usize,