diff --git a/crates/blockifier/src/execution/contract_class.rs b/crates/blockifier/src/execution/contract_class.rs index 6641c81fce..e80512407b 100644 --- a/crates/blockifier/src/execution/contract_class.rs +++ b/crates/blockifier/src/execution/contract_class.rs @@ -22,7 +22,7 @@ use semver::Version; use serde::de::Error as DeserializationError; use serde::{Deserialize, Deserializer, Serialize}; use starknet_api::contract_class::{ContractClass, EntryPointType}; -use starknet_api::core::EntryPointSelector; +use starknet_api::core::{EntryPointSelector, WORD_WIDTH}; use starknet_api::deprecated_contract_class::{ ContractClass as DeprecatedContractClass, EntryPointOffset, @@ -514,6 +514,76 @@ fn convert_entry_points_v1(external: &[CasmContractEntryPoint]) -> Vec 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; + + Ok(Self { contract_class: contract_class.clone(), sierra_program_length, abi_length }) + } +} + +impl ClassInfo { + pub fn bytecode_length(&self) -> usize { + match &self.contract_class { + ContractClass::V0(contract_class) => contract_class.bytecode_length(), + ContractClass::V1(contract_class) => contract_class.bytecode.len(), + } + } + + pub fn contract_class(&self) -> ContractClass { + self.contract_class.clone() + } + + pub fn sierra_program_length(&self) -> usize { + self.sierra_program_length + } + + pub fn abi_length(&self) -> usize { + self.abi_length + } + + pub fn code_size(&self) -> usize { + (self.bytecode_length() + self.sierra_program_length()) + // We assume each felt is a word. + * WORD_WIDTH + + self.abi_length() + } + + pub fn new( + contract_class: &ContractClass, + sierra_program_length: usize, + abi_length: usize, + ) -> ContractClassResult { + let (contract_class_version, condition) = match contract_class { + ContractClass::V0(_) => (0, sierra_program_length == 0), + ContractClass::V1(_) => (1, sierra_program_length > 0), + }; + + if condition { + Ok(Self { contract_class: contract_class.clone(), sierra_program_length, abi_length }) + } else { + Err(ContractClassError::ContractClassVersionSierraProgramLengthMismatch { + contract_class_version, + sierra_program_length, + }) + } + } +} + // TODO(Yoni): organize this file. #[derive(Clone, Debug, Default, Eq, PartialEq)] /// Modelled after [cairo_lang_starknet_classes::contract_class::ContractEntryPoints]. diff --git a/crates/blockifier/src/fee/eth_gas_constants.rs b/crates/blockifier/src/fee/eth_gas_constants.rs index e01eb73132..0055c5d1f4 100644 --- a/crates/blockifier/src/fee/eth_gas_constants.rs +++ b/crates/blockifier/src/fee/eth_gas_constants.rs @@ -1,8 +1,8 @@ +use starknet_api::core::WORD_WIDTH; + // Calldata. pub const GAS_PER_MEMORY_ZERO_BYTE: usize = 4; pub const GAS_PER_MEMORY_BYTE: usize = 16; -// TODO(AvivG): use starknet_api::core::WORD_WIDTH instead. -pub const WORD_WIDTH: usize = 32; pub const GAS_PER_MEMORY_WORD: usize = GAS_PER_MEMORY_BYTE * WORD_WIDTH; // Blob Data. diff --git a/crates/blockifier/src/fee/receipt_test.rs b/crates/blockifier/src/fee/receipt_test.rs index 95c315918b..ac1a72e24d 100644 --- a/crates/blockifier/src/fee/receipt_test.rs +++ b/crates/blockifier/src/fee/receipt_test.rs @@ -1,4 +1,5 @@ use rstest::{fixture, rstest}; +use starknet_api::core::WORD_WIDTH; use starknet_api::execution_resources::GasVector; use starknet_api::transaction::fields::GasVectorComputationMode; use starknet_api::transaction::L2ToL1Payload; @@ -85,8 +86,7 @@ fn test_calculate_tx_gas_usage_basic<'a>( .gas_per_code_byte; let code_gas_cost = (gas_per_code_byte * u64_from_usize( - (class_info.bytecode_length() + class_info.sierra_program_length()) - * eth_gas_constants::WORD_WIDTH + (class_info.bytecode_length() + class_info.sierra_program_length()) * WORD_WIDTH + class_info.abi_length(), )) .to_integer()