diff --git a/crates/blockifier/src/execution/contract_class.rs b/crates/blockifier/src/execution/contract_class.rs index e65cd08787..5af6716367 100644 --- a/crates/blockifier/src/execution/contract_class.rs +++ b/crates/blockifier/src/execution/contract_class.rs @@ -37,7 +37,6 @@ use crate::execution::errors::{ContractClassError, PreExecutionError}; use crate::execution::execution_utils::{poseidon_hash_many_cost, sn_api_to_cairo_vm_program}; #[cfg(feature = "cairo_native")] use crate::execution::native::contract_class::NativeContractClassV1; -use crate::fee::eth_gas_constants; use crate::transaction::errors::TransactionExecutionError; use crate::versioned_constants::CompilerVersion; @@ -521,76 +520,6 @@ 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. - * eth_gas_constants::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/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index 336abb1a7c..eef04f26b6 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -766,13 +766,12 @@ fn test_fail_declare(block_context: BlockContext, max_fee: Fee) { let class_info = calculate_class_info_for_testing(contract_class); let declare_tx = DeclareTransaction::V2(DeclareTransactionV2 { nonce: next_nonce, ..declare_tx_v2 }); - let declare_account_tx = AccountTransaction::new(ApiExecutableTransaction::Declare( - ApiExecutableDeclareTransaction { - tx: declare_tx, - tx_hash: TransactionHash::default(), - class_info, - }, - )); + let executable_tx = ApiExecutableTransaction::Declare(ApiExecutableDeclareTransaction { + tx: declare_tx, + tx_hash: TransactionHash::default(), + class_info, + }); + let declare_account_tx = AccountTransaction::new(executable_tx); // Fail execution, assert nonce and balance are unchanged. let tx_info = declare_account_tx.create_tx_info(); diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index 1c324020a0..c3018c37d7 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -11,11 +11,7 @@ use starknet_api::transaction::{ ContractAddressSalt, Fee, GasVectorComputationMode, - InvokeTransactionV0, - InvokeTransactionV1, - InvokeTransactionV3, ResourceBounds, - TransactionHash, TransactionSignature, TransactionVersion, ValidResourceBounds, @@ -50,7 +46,7 @@ use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::constants; use crate::transaction::objects::{FeeType, TransactionExecutionInfo, TransactionExecutionResult}; use crate::transaction::transaction_types::TransactionType; -use crate::transaction::transactions::{ExecutableTransaction, InvokeTransaction}; +use crate::transaction::transactions::ExecutableTransaction; // Corresponding constants to the ones in faulty_account. pub const VALID: u64 = 0; @@ -62,25 +58,6 @@ pub const GET_BLOCK_NUMBER: u64 = 5; pub const GET_BLOCK_TIMESTAMP: u64 = 6; pub const GET_SEQUENCER_ADDRESS: u64 = 7; -macro_rules! impl_from_versioned_tx { - ($(($specified_tx_type:ty, $enum_variant:ident)),*) => { - $(impl From<$specified_tx_type> for InvokeTransaction { - fn from(tx: $specified_tx_type) -> Self { - Self::new( - starknet_api::transaction::InvokeTransaction::$enum_variant(tx), - TransactionHash::default(), - ) - } - })* - }; -} - -impl_from_versioned_tx!( - (InvokeTransactionV0, V0), - (InvokeTransactionV1, V1), - (InvokeTransactionV3, V3) -); - /// Test fixtures. #[fixture] diff --git a/crates/blockifier/src/transaction/transactions.rs b/crates/blockifier/src/transaction/transactions.rs index 73444770c8..4a5ea1d1ec 100644 --- a/crates/blockifier/src/transaction/transactions.rs +++ b/crates/blockifier/src/transaction/transactions.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::contract_class::{ContractClass, EntryPointType}; -use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; +use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress}; use starknet_api::executable_transaction::{ DeclareTransaction as ExecutableDeclareTx, DeployAccountTransaction as ExecutableDeployAccountTx, @@ -12,11 +12,9 @@ use starknet_api::executable_transaction::{ use starknet_api::transaction::{ AccountDeploymentData, Calldata, - ContractAddressSalt, DeclareTransactionV2, DeclareTransactionV3, Fee, - TransactionHash, TransactionSignature, TransactionVersion, }; @@ -24,7 +22,6 @@ 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; use crate::execution::entry_point::{ CallEntryPoint, CallType, @@ -35,7 +32,6 @@ use crate::execution::execution_utils::execute_deployment; use crate::state::cached_state::TransactionalState; use crate::state::errors::StateError; use crate::state::state_api::{State, UpdatableState}; -use crate::transaction::account_transaction::is_cairo1; use crate::transaction::constants; use crate::transaction::errors::TransactionExecutionError; use crate::transaction::objects::{ @@ -53,14 +49,6 @@ use crate::transaction::objects::{ #[path = "transactions_test.rs"] mod test; -macro_rules! implement_inner_tx_getter_calls { - ($(($field:ident, $field_type:ty)),*) => { - $(pub fn $field(&self) -> $field_type { - self.tx.$field().clone() - })* - }; -} - #[derive(Clone, Copy, Debug)] pub struct ExecutionFlags { pub charge_fee: bool, @@ -132,439 +120,6 @@ pub trait ValidatableTransaction { ) -> TransactionExecutionResult>; } -#[derive(Clone, Debug)] -pub struct DeclareTransaction { - pub tx: starknet_api::transaction::DeclareTransaction, - pub tx_hash: TransactionHash, - // Indicates the presence of the only_query bit in the version. - only_query: bool, - pub class_info: ClassInfo, -} - -impl TryFrom for DeclareTransaction { - type Error = TransactionExecutionError; - - fn try_from( - declare_tx: starknet_api::executable_transaction::DeclareTransaction, - ) -> Result { - Self::new_from_executable_tx(declare_tx, false) - } -} - -impl DeclareTransaction { - fn create( - declare_tx: starknet_api::transaction::DeclareTransaction, - tx_hash: TransactionHash, - class_info: ClassInfo, - only_query: bool, - ) -> TransactionExecutionResult { - let declare_version = declare_tx.version(); - // Verify contract class version. - // TODO(Noa): Avoid the unnecessary conversion. - if !is_cairo1(&class_info.contract_class().try_into()?) { - if declare_version > TransactionVersion::ONE { - Err(TransactionExecutionError::ContractClassVersionMismatch { - declare_version, - cairo_version: 0, - })? - } - } else if declare_version <= TransactionVersion::ONE { - Err(TransactionExecutionError::ContractClassVersionMismatch { - declare_version, - cairo_version: 1, - })? - } - Ok(Self { tx: declare_tx, tx_hash, class_info, only_query }) - } - - pub fn new( - declare_tx: starknet_api::transaction::DeclareTransaction, - tx_hash: TransactionHash, - class_info: ClassInfo, - ) -> TransactionExecutionResult { - Self::create(declare_tx, tx_hash, class_info, false) - } - - pub fn new_for_query( - declare_tx: starknet_api::transaction::DeclareTransaction, - tx_hash: TransactionHash, - class_info: ClassInfo, - ) -> TransactionExecutionResult { - Self::create(declare_tx, tx_hash, class_info, true) - } - - fn new_from_executable_tx( - declare_tx: starknet_api::executable_transaction::DeclareTransaction, - only_query: bool, - ) -> Result { - let starknet_api::executable_transaction::DeclareTransaction { tx, tx_hash, class_info } = - declare_tx; - let class_info = class_info.try_into()?; - - Self::create(tx, tx_hash, class_info, only_query) - } - - implement_inner_tx_getter_calls!( - (class_hash, ClassHash), - (nonce, Nonce), - (sender_address, ContractAddress), - (signature, TransactionSignature), - (version, TransactionVersion) - ); - - pub fn tx(&self) -> &starknet_api::transaction::DeclareTransaction { - &self.tx - } - - pub fn tx_hash(&self) -> TransactionHash { - self.tx_hash - } - - pub fn contract_class(&self) -> ContractClass { - self.class_info.contract_class() - } - - pub fn only_query(&self) -> bool { - self.only_query - } - - fn try_declare( - &self, - state: &mut S, - class_hash: ClassHash, - compiled_class_hash: Option, - ) -> TransactionExecutionResult<()> { - match state.get_compiled_contract_class(class_hash) { - Err(StateError::UndeclaredClassHash(_)) => { - // Class is undeclared; declare it. - state.set_contract_class(class_hash, self.contract_class().try_into()?)?; - if let Some(compiled_class_hash) = compiled_class_hash { - state.set_compiled_class_hash(class_hash, compiled_class_hash)?; - } - Ok(()) - } - Err(error) => Err(error)?, - Ok(_) => { - // Class is already declared, cannot redeclare. - Err(TransactionExecutionError::DeclareTransactionError { class_hash }) - } - } - } -} - -impl Executable for DeclareTransaction { - fn run_execute( - &self, - state: &mut S, - _resources: &mut ExecutionResources, - context: &mut EntryPointExecutionContext, - _remaining_gas: &mut u64, - ) -> TransactionExecutionResult> { - let class_hash = self.class_hash(); - match &self.tx { - starknet_api::transaction::DeclareTransaction::V0(_) - | starknet_api::transaction::DeclareTransaction::V1(_) => { - if context.tx_context.block_context.versioned_constants.disable_cairo0_redeclaration - { - self.try_declare(state, class_hash, None)? - } else { - // We allow redeclaration of the class for backward compatibility. - // In the past, we allowed redeclaration of Cairo 0 contracts since there was - // no class commitment (so no need to check if the class is already declared). - state.set_contract_class(class_hash, self.contract_class().try_into()?)?; - } - } - starknet_api::transaction::DeclareTransaction::V2(DeclareTransactionV2 { - compiled_class_hash, - .. - }) - | starknet_api::transaction::DeclareTransaction::V3(DeclareTransactionV3 { - compiled_class_hash, - .. - }) => self.try_declare(state, class_hash, Some(*compiled_class_hash))?, - } - Ok(None) - } -} - -impl TransactionInfoCreator for DeclareTransaction { - fn create_tx_info(&self) -> TransactionInfo { - // TODO(Nir, 01/11/2023): Consider to move this (from all get_tx_info methods). - let common_fields = CommonAccountFields { - transaction_hash: self.tx_hash(), - version: self.version(), - signature: self.signature(), - nonce: self.nonce(), - sender_address: self.sender_address(), - only_query: self.only_query, - }; - - match &self.tx { - starknet_api::transaction::DeclareTransaction::V0(tx) - | starknet_api::transaction::DeclareTransaction::V1(tx) => { - TransactionInfo::Deprecated(DeprecatedTransactionInfo { - common_fields, - max_fee: tx.max_fee, - }) - } - starknet_api::transaction::DeclareTransaction::V2(tx) => { - TransactionInfo::Deprecated(DeprecatedTransactionInfo { - common_fields, - max_fee: tx.max_fee, - }) - } - starknet_api::transaction::DeclareTransaction::V3(tx) => { - TransactionInfo::Current(CurrentTransactionInfo { - common_fields, - resource_bounds: tx.resource_bounds, - tip: tx.tip, - nonce_data_availability_mode: tx.nonce_data_availability_mode, - fee_data_availability_mode: tx.fee_data_availability_mode, - paymaster_data: tx.paymaster_data.clone(), - account_deployment_data: tx.account_deployment_data.clone(), - }) - } - } - } -} -#[derive(Debug, Clone)] -pub struct DeployAccountTransaction { - pub tx: starknet_api::executable_transaction::DeployAccountTransaction, - // Indicates the presence of the only_query bit in the version. - pub only_query: bool, -} - -impl DeployAccountTransaction { - pub fn new( - deploy_account_tx: starknet_api::transaction::DeployAccountTransaction, - tx_hash: TransactionHash, - contract_address: ContractAddress, - ) -> Self { - Self { - tx: starknet_api::executable_transaction::DeployAccountTransaction { - tx: deploy_account_tx, - tx_hash, - contract_address, - }, - only_query: false, - } - } - - pub fn new_for_query( - deploy_account_tx: starknet_api::transaction::DeployAccountTransaction, - tx_hash: TransactionHash, - contract_address: ContractAddress, - ) -> Self { - Self { - tx: starknet_api::executable_transaction::DeployAccountTransaction { - tx: deploy_account_tx, - tx_hash, - contract_address, - }, - only_query: true, - } - } - - implement_inner_tx_getter_calls!( - (class_hash, ClassHash), - (constructor_calldata, Calldata), - (contract_address, ContractAddress), - (contract_address_salt, ContractAddressSalt), - (nonce, Nonce), - (signature, TransactionSignature), - (tx_hash, TransactionHash), - (version, TransactionVersion) - ); - - pub fn tx(&self) -> &starknet_api::transaction::DeployAccountTransaction { - self.tx.tx() - } -} - -impl Executable for DeployAccountTransaction { - fn run_execute( - &self, - state: &mut S, - resources: &mut ExecutionResources, - context: &mut EntryPointExecutionContext, - remaining_gas: &mut u64, - ) -> TransactionExecutionResult> { - let class_hash = self.class_hash(); - let ctor_context = ConstructorContext { - class_hash, - code_address: None, - storage_address: self.contract_address(), - caller_address: ContractAddress::default(), - }; - let call_info = execute_deployment( - state, - resources, - context, - ctor_context, - self.constructor_calldata(), - remaining_gas, - )?; - - Ok(Some(call_info)) - } -} - -impl TransactionInfoCreator for DeployAccountTransaction { - fn create_tx_info(&self) -> TransactionInfo { - let common_fields = CommonAccountFields { - transaction_hash: self.tx_hash(), - version: self.version(), - signature: self.signature(), - nonce: self.nonce(), - sender_address: self.contract_address(), - only_query: self.only_query, - }; - - match &self.tx() { - starknet_api::transaction::DeployAccountTransaction::V1(tx) => { - TransactionInfo::Deprecated(DeprecatedTransactionInfo { - common_fields, - max_fee: tx.max_fee, - }) - } - starknet_api::transaction::DeployAccountTransaction::V3(tx) => { - TransactionInfo::Current(CurrentTransactionInfo { - common_fields, - resource_bounds: tx.resource_bounds, - tip: tx.tip, - nonce_data_availability_mode: tx.nonce_data_availability_mode, - fee_data_availability_mode: tx.fee_data_availability_mode, - paymaster_data: tx.paymaster_data.clone(), - account_deployment_data: AccountDeploymentData::default(), - }) - } - } - } -} - -#[derive(Debug, Clone)] -pub struct InvokeTransaction { - pub tx: starknet_api::executable_transaction::InvokeTransaction, - // Indicates the presence of the only_query bit in the version. - pub only_query: bool, -} - -impl InvokeTransaction { - pub fn new( - invoke_tx: starknet_api::transaction::InvokeTransaction, - tx_hash: TransactionHash, - ) -> Self { - Self { - tx: starknet_api::executable_transaction::InvokeTransaction { tx: invoke_tx, tx_hash }, - only_query: false, - } - } - - pub fn new_for_query( - invoke_tx: starknet_api::transaction::InvokeTransaction, - tx_hash: TransactionHash, - ) -> Self { - Self { - tx: starknet_api::executable_transaction::InvokeTransaction { tx: invoke_tx, tx_hash }, - only_query: true, - } - } - - implement_inner_tx_getter_calls!( - (calldata, Calldata), - (nonce, Nonce), - (signature, TransactionSignature), - (sender_address, ContractAddress), - (tx_hash, TransactionHash), - (version, TransactionVersion) - ); - - pub fn tx(&self) -> &starknet_api::transaction::InvokeTransaction { - self.tx.tx() - } -} - -impl Executable for InvokeTransaction { - fn run_execute( - &self, - state: &mut S, - resources: &mut ExecutionResources, - context: &mut EntryPointExecutionContext, - remaining_gas: &mut u64, - ) -> TransactionExecutionResult> { - let entry_point_selector = match &self.tx.tx { - starknet_api::transaction::InvokeTransaction::V0(tx) => tx.entry_point_selector, - starknet_api::transaction::InvokeTransaction::V1(_) - | starknet_api::transaction::InvokeTransaction::V3(_) => { - selector_from_name(constants::EXECUTE_ENTRY_POINT_NAME) - } - }; - let storage_address = context.tx_context.tx_info.sender_address(); - let class_hash = state.get_class_hash_at(storage_address)?; - let execute_call = CallEntryPoint { - entry_point_type: EntryPointType::External, - entry_point_selector, - calldata: self.calldata(), - class_hash: None, - code_address: None, - storage_address, - caller_address: ContractAddress::default(), - call_type: CallType::Call, - initial_gas: *remaining_gas, - }; - - let call_info = execute_call - .non_reverting_execute(state, resources, context, remaining_gas) - .map_err(|error| TransactionExecutionError::ExecutionError { - error, - class_hash, - storage_address, - selector: entry_point_selector, - })?; - - Ok(Some(call_info)) - } -} - -impl TransactionInfoCreator for InvokeTransaction { - fn create_tx_info(&self) -> TransactionInfo { - let common_fields = CommonAccountFields { - transaction_hash: self.tx_hash(), - version: self.version(), - signature: self.signature(), - nonce: self.nonce(), - sender_address: self.sender_address(), - only_query: self.only_query, - }; - - match &self.tx() { - starknet_api::transaction::InvokeTransaction::V0(tx) => { - TransactionInfo::Deprecated(DeprecatedTransactionInfo { - common_fields, - max_fee: tx.max_fee, - }) - } - starknet_api::transaction::InvokeTransaction::V1(tx) => { - TransactionInfo::Deprecated(DeprecatedTransactionInfo { - common_fields, - max_fee: tx.max_fee, - }) - } - starknet_api::transaction::InvokeTransaction::V3(tx) => { - TransactionInfo::Current(CurrentTransactionInfo { - common_fields, - resource_bounds: tx.resource_bounds, - tip: tx.tip, - nonce_data_availability_mode: tx.nonce_data_availability_mode, - fee_data_availability_mode: tx.fee_data_availability_mode, - paymaster_data: tx.paymaster_data.clone(), - account_deployment_data: tx.account_deployment_data.clone(), - }) - } - } - } -} - impl HasRelatedFeeType for L1HandlerTransaction { fn version(&self) -> TransactionVersion { self.tx.version diff --git a/crates/starknet_api/src/contract_class.rs b/crates/starknet_api/src/contract_class.rs index 6a6025abcf..9c0f02aebf 100644 --- a/crates/starknet_api/src/contract_class.rs +++ b/crates/starknet_api/src/contract_class.rs @@ -45,6 +45,7 @@ impl ContractClass { /// 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, Deserialize, Eq, PartialEq, Serialize)] +// TODO(Ayelet,10/02/2024): Change to bytes. pub struct ClassInfo { // TODO(Noa): Consider using Arc. pub contract_class: ContractClass,