diff --git a/Cargo.lock b/Cargo.lock index 2e1a7412ad..3fddec8b3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1494,7 +1494,6 @@ dependencies = [ "cairo-lang-sierra", "cairo-lang-starknet-classes", "cairo-native", - "cairo-vm", "criterion", "derive_more 0.99.18", "glob", @@ -10059,6 +10058,7 @@ dependencies = [ "bitvec", "cairo-lang-runner", "cairo-lang-starknet-classes", + "cairo-vm", "derive_more 0.99.18", "hex", "indexmap 2.6.0", diff --git a/crates/batcher/src/block_builder.rs b/crates/batcher/src/block_builder.rs index 9c471f5740..cdd4e93535 100644 --- a/crates/batcher/src/block_builder.rs +++ b/crates/batcher/src/block_builder.rs @@ -160,7 +160,7 @@ impl BlockBuilderTrait for BlockBuilder { let mut executor_input_chunk = vec![]; for tx in &next_tx_chunk { executor_input_chunk - .push(BlockifierTransaction::Account(AccountTransaction::try_from(tx)?)); + .push(BlockifierTransaction::Account(AccountTransaction::new(tx.clone()))); } let results = self.executor.lock().await.add_txs_to_block(&executor_input_chunk); trace!("Transaction execution results: {:?}", results); diff --git a/crates/blockifier/src/blockifier/stateful_validator.rs b/crates/blockifier/src/blockifier/stateful_validator.rs index 14964e1a56..73efb725ee 100644 --- a/crates/blockifier/src/blockifier/stateful_validator.rs +++ b/crates/blockifier/src/blockifier/stateful_validator.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::core::{ContractAddress, Nonce}; +use starknet_api::executable_transaction::Transaction as ApiExecutableTransaction; use thiserror::Error; use crate::blockifier::config::TransactionExecutorConfig; @@ -61,7 +62,7 @@ impl StatefulValidator { // Deploy account transactions should be fully executed, since the constructor must run // before `__validate_deploy__`. The execution already includes all necessary validations, // so they are skipped here. - if let AccountTransaction::DeployAccount(_) = tx { + if let ApiExecutableTransaction::DeployAccount(_) = tx.tx { self.execute(tx)?; return Ok(()); } diff --git a/crates/blockifier/src/blockifier/stateful_validator_test.rs b/crates/blockifier/src/blockifier/stateful_validator_test.rs index 42b2b57b04..69c5e56cbe 100644 --- a/crates/blockifier/src/blockifier/stateful_validator_test.rs +++ b/crates/blockifier/src/blockifier/stateful_validator_test.rs @@ -1,5 +1,6 @@ use assert_matches::assert_matches; use rstest::rstest; +use starknet_api::executable_transaction::Transaction; use starknet_api::transaction::{TransactionVersion, ValidResourceBounds}; use crate::blockifier::stateful_validator::StatefulValidator; @@ -7,7 +8,6 @@ use crate::context::BlockContext; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::{fund_account, test_state}; use crate::test_utils::{CairoVersion, BALANCE}; -use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::test_utils::{ block_context, create_account_tx_for_validate_test_nonce_0, @@ -61,18 +61,18 @@ fn test_tx_validator( }; // Positive flow. - let tx = create_account_tx_for_validate_test_nonce_0(FaultyAccountTxCreatorArgs { + let account_tx = create_account_tx_for_validate_test_nonce_0(FaultyAccountTxCreatorArgs { scenario: VALID, ..tx_args }); - if let AccountTransaction::DeployAccount(deploy_tx) = &tx { + if let Transaction::DeployAccount(deploy_tx) = &account_tx.tx { fund_account(chain_info, deploy_tx.contract_address(), BALANCE, &mut state.state); } // Test the stateful validator. let mut stateful_validator = StatefulValidator::create(state, block_context); let skip_validate = false; - let result = stateful_validator.perform_validations(tx, skip_validate); + let result = stateful_validator.perform_validations(account_tx, skip_validate); assert!(result.is_ok(), "Validation failed: {:?}", result.unwrap_err()); } diff --git a/crates/blockifier/src/blockifier/transaction_executor_test.rs b/crates/blockifier/src/blockifier/transaction_executor_test.rs index 4259c207d6..216f183563 100644 --- a/crates/blockifier/src/blockifier/transaction_executor_test.rs +++ b/crates/blockifier/src/blockifier/transaction_executor_test.rs @@ -142,15 +142,15 @@ fn test_deploy_account( let account_contract = FeatureContract::AccountWithoutValidations(cairo_version); let state = test_state(&block_context.chain_info, BALANCE, &[(account_contract, 0)]); - let tx = deploy_account_tx( + let deploy_account_tx = deploy_account_tx( deploy_account_tx_args! { class_hash: account_contract.get_class_hash(), resource_bounds: l1_resource_bounds(0_u8.into(), DEFAULT_STRK_L1_GAS_PRICE.into()), version, }, &mut NonceManager::default(), - ) - .into(); + ); + let tx = Transaction::Account(deploy_account_tx); let expected_bouncer_weights = BouncerWeights { state_diff_size: 3, message_segment_length: 0, diff --git a/crates/blockifier/src/execution/stack_trace_test.rs b/crates/blockifier/src/execution/stack_trace_test.rs index f7e3ac97af..73909ff46d 100644 --- a/crates/blockifier/src/execution/stack_trace_test.rs +++ b/crates/blockifier/src/execution/stack_trace_test.rs @@ -9,6 +9,7 @@ use starknet_api::core::{ EntryPointSelector, Nonce, }; +use starknet_api::executable_transaction::Transaction; use starknet_api::transaction::{ ContractAddressSalt, Fee, @@ -35,7 +36,6 @@ use crate::execution::syscalls::hint_processor::ENTRYPOINT_FAILED_ERROR; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::{fund_account, test_state}; use crate::test_utils::{create_calldata, CairoVersion, BALANCE}; -use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::constants::{ DEPLOY_CONTRACT_FUNCTION_ENTRY_POINT_NAME, EXECUTE_ENTRY_POINT_NAME, @@ -589,9 +589,9 @@ fn test_validate_trace( if let TransactionType::DeployAccount = tx_type { // Deploy account uses the actual address as the sender address. - match &account_tx { - AccountTransaction::DeployAccount(tx) => { - sender_address = tx.contract_address(); + match &account_tx.tx { + Transaction::DeployAccount(_) => { + sender_address = account_tx.sender_address(); } _ => panic!("Expected DeployAccountTransaction type"), } @@ -658,8 +658,8 @@ fn test_account_ctor_frame_stack_trace( }); // Fund the account so it can afford the deployment. - let deploy_address = match &deploy_account_tx { - AccountTransaction::DeployAccount(deploy_tx) => deploy_tx.contract_address(), + let deploy_address = match &deploy_account_tx.tx { + Transaction::DeployAccount(_) => deploy_account_tx.sender_address(), _ => unreachable!("deploy_account_tx is a DeployAccount"), }; fund_account(chain_info, deploy_address, Fee(BALANCE.0 * 2), &mut state.state); diff --git a/crates/blockifier/src/fee/gas_usage.rs b/crates/blockifier/src/fee/gas_usage.rs index bf5cfa5e8a..c32d71c955 100644 --- a/crates/blockifier/src/fee/gas_usage.rs +++ b/crates/blockifier/src/fee/gas_usage.rs @@ -1,4 +1,5 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; +use starknet_api::executable_transaction::Transaction; use starknet_api::execution_resources::GasVector; use starknet_api::transaction::GasVectorComputationMode; @@ -160,24 +161,24 @@ pub fn estimate_minimal_gas_vector( ) -> GasVector { // TODO(Dori, 1/8/2023): Give names to the constant VM step estimates and regression-test them. let BlockContext { block_info, versioned_constants, .. } = block_context; - let state_changes_by_account_tx = match tx { + let state_changes_by_account_tx = match &tx.tx { // We consider the following state changes: sender balance update (storage update) + nonce // increment (contract modification) (we exclude the sequencer balance update and the ERC20 // contract modification since it occurs for every tx). - AccountTransaction::Declare(_) => StateChangesCount { + Transaction::Declare(_) => StateChangesCount { n_storage_updates: 1, n_class_hash_updates: 0, n_compiled_class_hash_updates: 0, n_modified_contracts: 1, }, - AccountTransaction::Invoke(_) => StateChangesCount { + Transaction::Invoke(_) => StateChangesCount { n_storage_updates: 1, n_class_hash_updates: 0, n_compiled_class_hash_updates: 0, n_modified_contracts: 1, }, // DeployAccount also updates the address -> class hash mapping. - AccountTransaction::DeployAccount(_) => StateChangesCount { + Transaction::DeployAccount(_) => StateChangesCount { n_storage_updates: 1, n_class_hash_updates: 1, n_compiled_class_hash_updates: 0, diff --git a/crates/blockifier/src/test_utils/declare.rs b/crates/blockifier/src/test_utils/declare.rs index d78f3ff06c..fd191a524b 100644 --- a/crates/blockifier/src/test_utils/declare.rs +++ b/crates/blockifier/src/test_utils/declare.rs @@ -1,12 +1,16 @@ +use starknet_api::contract_class::ClassInfo; +use starknet_api::executable_transaction::{DeclareTransaction, Transaction}; use starknet_api::test_utils::declare::DeclareTxArgs; -use crate::execution::contract_class::ClassInfo; use crate::transaction::account_transaction::AccountTransaction; -use crate::transaction::transactions::DeclareTransaction; pub fn declare_tx(declare_tx_args: DeclareTxArgs, class_info: ClassInfo) -> AccountTransaction { let tx_hash = declare_tx_args.tx_hash; let declare_tx = starknet_api::test_utils::declare::declare_tx(declare_tx_args); - AccountTransaction::Declare(DeclareTransaction::new(declare_tx, tx_hash, class_info).unwrap()) + AccountTransaction::new(Transaction::Declare(DeclareTransaction { + tx: declare_tx, + tx_hash, + class_info, + })) } diff --git a/crates/blockifier/src/test_utils/deploy_account.rs b/crates/blockifier/src/test_utils/deploy_account.rs index 5bce5e5504..c2e9a74852 100644 --- a/crates/blockifier/src/test_utils/deploy_account.rs +++ b/crates/blockifier/src/test_utils/deploy_account.rs @@ -1,9 +1,9 @@ use starknet_api::core::calculate_contract_address; +use starknet_api::executable_transaction::{DeployAccountTransaction, Transaction}; use starknet_api::test_utils::deploy_account::DeployAccountTxArgs; use starknet_api::test_utils::NonceManager; use crate::transaction::account_transaction::AccountTransaction; -use crate::transaction::transactions::DeployAccountTransaction; pub fn deploy_account_tx( deploy_tx_args: DeployAccountTxArgs, @@ -22,9 +22,10 @@ pub fn deploy_account_tx( deploy_tx_args, nonce_manager.next(contract_address), ); - AccountTransaction::DeployAccount(DeployAccountTransaction::new( - deploy_account_tx, + + AccountTransaction::new(Transaction::DeployAccount(DeployAccountTransaction { + tx: deploy_account_tx, tx_hash, contract_address, - )) + })) } diff --git a/crates/blockifier/src/test_utils/invoke.rs b/crates/blockifier/src/test_utils/invoke.rs index 73ffe5ffa5..07002ec20c 100644 --- a/crates/blockifier/src/test_utils/invoke.rs +++ b/crates/blockifier/src/test_utils/invoke.rs @@ -1,17 +1,20 @@ +use starknet_api::executable_transaction::{ + InvokeTransaction as ExecutableInvokeTransaction, + Transaction as ExecutableTransaction, +}; use starknet_api::test_utils::invoke::InvokeTxArgs; -use starknet_api::transaction::{InvokeTransactionV0, TransactionVersion}; +use starknet_api::transaction::{InvokeTransaction, InvokeTransactionV0, TransactionVersion}; use crate::abi::abi_utils::selector_from_name; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::constants::EXECUTE_ENTRY_POINT_NAME; -use crate::transaction::transactions::InvokeTransaction; pub fn invoke_tx(invoke_args: InvokeTxArgs) -> AccountTransaction { let tx_hash = invoke_args.tx_hash; let only_query = invoke_args.only_query; // TODO: Make TransactionVersion an enum and use match here. let invoke_tx = if invoke_args.version == TransactionVersion::ZERO { - starknet_api::transaction::InvokeTransaction::V0(InvokeTransactionV0 { + InvokeTransaction::V0(InvokeTransactionV0 { max_fee: invoke_args.max_fee, calldata: invoke_args.calldata, contract_address: invoke_args.sender_address, @@ -24,7 +27,14 @@ pub fn invoke_tx(invoke_args: InvokeTxArgs) -> AccountTransaction { }; match only_query { - true => AccountTransaction::Invoke(InvokeTransaction::new_for_query(invoke_tx, tx_hash)), - false => AccountTransaction::Invoke(InvokeTransaction::new(invoke_tx, tx_hash)), + true => AccountTransaction::new_for_query(ExecutableTransaction::Invoke( + ExecutableInvokeTransaction { tx: invoke_tx, tx_hash }, + )), + false => { + AccountTransaction::new(ExecutableTransaction::Invoke(ExecutableInvokeTransaction { + tx: invoke_tx, + tx_hash, + })) + } } } diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 03b21a2009..8775fbd5f5 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -6,6 +6,7 @@ use starknet_api::calldata; use starknet_api::contract_class::EntryPointType; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; +use starknet_api::executable_transaction::Transaction; use starknet_api::transaction::Resource::{L1DataGas, L1Gas, L2Gas}; use starknet_api::transaction::{ AccountDeploymentData, @@ -51,16 +52,14 @@ use crate::transaction::objects::{ TransactionExecutionResult, TransactionInfo, TransactionInfoCreator, + TransactionInfoCreatorInner, TransactionPreValidationResult, }; use crate::transaction::transaction_types::TransactionType; use crate::transaction::transactions::{ - DeclareTransaction, - DeployAccountTransaction, Executable, ExecutableTransaction, ExecutionFlags, - InvokeTransaction, ValidatableTransaction, }; @@ -78,76 +77,36 @@ mod post_execution_test; /// Represents a paid Starknet transaction. #[derive(Clone, Debug, derive_more::From)] -pub enum AccountTransaction { - Declare(DeclareTransaction), - DeployAccount(DeployAccountTransaction), - Invoke(InvokeTransaction), + +pub struct AccountTransaction { + pub tx: Transaction, + only_query: bool, } macro_rules! implement_account_tx_inner_getters { ($(($field:ident, $field_type:ty)),*) => { $(pub fn $field(&self) -> $field_type { - match self { - Self::Declare(tx) => tx.tx.$field().clone(), - Self::DeployAccount(tx) => tx.tx.$field().clone(), - Self::Invoke(tx) => tx.tx.$field().clone(), + match &self.tx { + Transaction::Declare(tx) => tx.tx.$field().clone(), + Transaction::DeployAccount(tx) => tx.tx.$field().clone(), + Transaction::Invoke(tx) => tx.tx.$field().clone(), } })* }; } -impl TryFrom<&starknet_api::executable_transaction::Transaction> for AccountTransaction { - type Error = TransactionExecutionError; - - fn try_from( - value: &starknet_api::executable_transaction::Transaction, - ) -> Result { - match value { - starknet_api::executable_transaction::Transaction::Declare(declare_tx) => { - Ok(Self::Declare(declare_tx.clone().try_into()?)) - } - starknet_api::executable_transaction::Transaction::DeployAccount(deploy_account_tx) => { - Ok(Self::DeployAccount(DeployAccountTransaction { - tx: deploy_account_tx.clone(), - only_query: false, - })) - } - starknet_api::executable_transaction::Transaction::Invoke(invoke_tx) => { - Ok(Self::Invoke(InvokeTransaction { tx: invoke_tx.clone(), only_query: false })) - } - } - } -} - -impl TryFrom for AccountTransaction { - type Error = TransactionExecutionError; - - fn try_from( - executable_transaction: starknet_api::executable_transaction::Transaction, - ) -> Result { - match executable_transaction { - starknet_api::executable_transaction::Transaction::Declare(declare_tx) => { - Ok(Self::Declare(declare_tx.try_into()?)) - } - starknet_api::executable_transaction::Transaction::DeployAccount(deploy_account_tx) => { - Ok(Self::DeployAccount(DeployAccountTransaction { - tx: deploy_account_tx, - only_query: false, - })) - } - starknet_api::executable_transaction::Transaction::Invoke(invoke_tx) => { - Ok(Self::Invoke(InvokeTransaction { tx: invoke_tx, only_query: false })) - } - } +impl From for AccountTransaction { + fn from(executable_transaction: starknet_api::executable_transaction::Transaction) -> Self { + AccountTransaction::new(executable_transaction) } } impl HasRelatedFeeType for AccountTransaction { fn version(&self) -> TransactionVersion { - match self { - Self::Declare(tx) => tx.tx.version(), - Self::DeployAccount(tx) => tx.tx.version(), - Self::Invoke(tx) => tx.tx.version(), + match &self.tx { + Transaction::Declare(executable_tx) => executable_tx.tx.version(), + Transaction::DeployAccount(executable_tx) => executable_tx.tx.version(), + Transaction::Invoke(executable_tx) => executable_tx.tx.version(), } } @@ -168,43 +127,47 @@ impl AccountTransaction { ); pub fn sender_address(&self) -> ContractAddress { - match self { - Self::Declare(tx) => tx.tx.sender_address(), - Self::DeployAccount(tx) => tx.tx.contract_address(), - Self::Invoke(tx) => tx.tx.sender_address(), - } + self.tx.sender_address() } pub fn class_hash(&self) -> Option { - match self { - Self::Declare(tx) => Some(tx.tx.class_hash()), - Self::DeployAccount(tx) => Some(tx.tx.class_hash()), - Self::Invoke(_) => None, + match &self.tx { + Transaction::Declare(tx) => Some(tx.tx.class_hash()), + Transaction::DeployAccount(tx) => Some(tx.tx.class_hash()), + Transaction::Invoke(_) => None, } } pub fn account_deployment_data(&self) -> Option { - match self { - Self::Declare(tx) => Some(tx.tx.account_deployment_data().clone()), - Self::DeployAccount(_) => None, - Self::Invoke(tx) => Some(tx.tx.account_deployment_data().clone()), + match &self.tx { + Transaction::Declare(tx) => Some(tx.tx.account_deployment_data().clone()), + Transaction::DeployAccount(_) => None, + Transaction::Invoke(tx) => Some(tx.tx.account_deployment_data().clone()), } } + pub fn new(tx: starknet_api::executable_transaction::Transaction) -> Self { + AccountTransaction { tx, only_query: false } + } + + pub fn new_for_query(tx: starknet_api::executable_transaction::Transaction) -> Self { + AccountTransaction { tx, only_query: true } + } + // TODO(nir, 01/11/2023): Consider instantiating CommonAccountFields in AccountTransaction. pub fn tx_type(&self) -> TransactionType { - match self { - AccountTransaction::Declare(_) => TransactionType::Declare, - AccountTransaction::DeployAccount(_) => TransactionType::DeployAccount, - AccountTransaction::Invoke(_) => TransactionType::InvokeFunction, + match &self.tx { + Transaction::Declare(_) => TransactionType::Declare, + Transaction::DeployAccount(_) => TransactionType::DeployAccount, + Transaction::Invoke(_) => TransactionType::InvokeFunction, } } fn validate_entry_point_selector(&self) -> EntryPointSelector { - let validate_entry_point_name = match self { - Self::Declare(_) => constants::VALIDATE_DECLARE_ENTRY_POINT_NAME, - Self::DeployAccount(_) => constants::VALIDATE_DEPLOY_ENTRY_POINT_NAME, - Self::Invoke(_) => constants::VALIDATE_ENTRY_POINT_NAME, + let validate_entry_point_name = match &self.tx { + Transaction::Declare(_) => constants::VALIDATE_DECLARE_ENTRY_POINT_NAME, + Transaction::DeployAccount(_) => constants::VALIDATE_DEPLOY_ENTRY_POINT_NAME, + Transaction::Invoke(_) => constants::VALIDATE_ENTRY_POINT_NAME, }; selector_from_name(validate_entry_point_name) } @@ -212,9 +175,9 @@ impl AccountTransaction { // Calldata for validation contains transaction fields that cannot be obtained by calling // `et_tx_info()`. pub fn validate_entrypoint_calldata(&self) -> Calldata { - match self { - Self::Declare(tx) => calldata![tx.class_hash().0], - Self::DeployAccount(tx) => Calldata( + match &self.tx { + Transaction::Declare(tx) => calldata![tx.class_hash().0], + Transaction::DeployAccount(tx) => Calldata( [ vec![tx.class_hash().0, tx.contract_address_salt().0], (*tx.constructor_calldata().0).clone(), @@ -223,7 +186,7 @@ impl AccountTransaction { .into(), ), // Calldata for validation is the same calldata as for the execution itself. - Self::Invoke(tx) => tx.calldata(), + Transaction::Invoke(tx) => tx.calldata(), } } @@ -232,29 +195,25 @@ impl AccountTransaction { } pub fn calldata(&self) -> Calldata { - match self { - Self::Declare(_tx) => calldata![], - Self::DeployAccount(tx) => tx.constructor_calldata(), - Self::Invoke(tx) => tx.calldata(), + match &self.tx { + Transaction::Declare(_tx) => calldata![], + Transaction::DeployAccount(tx) => tx.constructor_calldata(), + Transaction::Invoke(tx) => tx.calldata(), } } pub fn signature_length(&self) -> usize { - let signature = match self { - Self::Declare(tx) => tx.signature(), - Self::DeployAccount(tx) => tx.signature(), - Self::Invoke(tx) => tx.signature(), + let signature = match &self.tx { + Transaction::Declare(tx) => tx.signature(), + Transaction::DeployAccount(tx) => tx.signature(), + Transaction::Invoke(tx) => tx.signature(), }; signature.0.len() } pub fn tx_hash(&self) -> TransactionHash { - match self { - Self::Declare(tx) => tx.tx_hash(), - Self::DeployAccount(tx) => tx.tx_hash(), - Self::Invoke(tx) => tx.tx_hash(), - } + self.tx.tx_hash() } pub fn enforce_fee(&self) -> bool { @@ -262,9 +221,9 @@ impl AccountTransaction { } fn verify_tx_version(&self, version: TransactionVersion) -> TransactionExecutionResult<()> { - let allowed_versions: Vec = match self { + let allowed_versions: Vec = match &self.tx { // Support `Declare` of version 0 in order to allow bootstrapping of a new system. - Self::Declare(_) => { + Transaction::Declare(_) => { vec![ TransactionVersion::ZERO, TransactionVersion::ONE, @@ -272,10 +231,10 @@ impl AccountTransaction { TransactionVersion::THREE, ] } - Self::DeployAccount(_) => { + Transaction::DeployAccount(_) => { vec![TransactionVersion::ONE, TransactionVersion::THREE] } - Self::Invoke(_) => { + Transaction::Invoke(_) => { vec![TransactionVersion::ZERO, TransactionVersion::ONE, TransactionVersion::THREE] } }; @@ -314,7 +273,7 @@ impl AccountTransaction { // TODO(Aner): seprate to cases based on context.resource_bounds type let minimal_gas_amount_vector = estimate_minimal_gas_vector( &tx_context.block_context, - self, + &self, // aviv: TODO: & ? &tx_context.get_gas_vector_computation_mode(), ); let TransactionContext { block_context, tx_info } = tx_context; @@ -548,7 +507,7 @@ impl AccountTransaction { } let fee_transfer_call_info = - AccountTransaction::execute_fee_transfer(&mut transfer_state, tx_context, actual_fee); + Self::execute_fee_transfer(&mut transfer_state, tx_context, actual_fee); // Commit without updating the sequencer balance. let storage_writes = &mut transfer_state.cache.get_mut().writes.storage; storage_writes.remove(&(fee_address, sequencer_balance_key_low)); @@ -564,10 +523,12 @@ impl AccountTransaction { context: &mut EntryPointExecutionContext, remaining_gas: &mut u64, ) -> TransactionExecutionResult> { - match &self { - Self::Declare(tx) => tx.run_execute(state, resources, context, remaining_gas), - Self::DeployAccount(tx) => tx.run_execute(state, resources, context, remaining_gas), - Self::Invoke(tx) => tx.run_execute(state, resources, context, remaining_gas), + match &self.tx { + Transaction::Declare(tx) => tx.run_execute(state, resources, context, remaining_gas), + Transaction::DeployAccount(tx) => { + tx.run_execute(state, resources, context, remaining_gas) + } + Transaction::Invoke(tx) => tx.run_execute(state, resources, context, remaining_gas), } } @@ -582,7 +543,8 @@ impl AccountTransaction { let mut resources = ExecutionResources::default(); let validate_call_info: Option; let execute_call_info: Option; - if matches!(self, Self::DeployAccount(_)) { + if matches!(&self.tx, Transaction::DeployAccount(_)) { + // aviv: TODO: & ? // Handle `DeployAccount` transactions separately, due to different order of things. // Also, the execution context required form the `DeployAccount` execute phase is // validation context. @@ -760,15 +722,15 @@ impl AccountTransaction { /// Returns 0 on non-declare transactions; for declare transactions, returns the class code /// size. pub(crate) fn declare_code_size(&self) -> usize { - if let Self::Declare(tx) = self { tx.class_info.code_size() } else { 0 } + if let Transaction::Declare(tx) = &self.tx { tx.class_info.code_size() } else { 0 } } fn is_non_revertible(&self, tx_info: &TransactionInfo) -> bool { // Reverting a Declare or Deploy transaction is not currently supported in the OS. - match self { - Self::Declare(_) => true, - Self::DeployAccount(_) => true, - Self::Invoke(_) => { + match &self.tx { + Transaction::Declare(_) => true, + Transaction::DeployAccount(_) => true, + Transaction::Invoke(_) => { // V0 transactions do not have validation; we cannot deduct fee for execution. Thus, // invoke transactions of are non-revertible iff they are of version 0. tx_info.is_v0() @@ -858,10 +820,10 @@ impl ExecutableTransaction for AccountTransaction { impl TransactionInfoCreator for AccountTransaction { fn create_tx_info(&self) -> TransactionInfo { - match self { - Self::Declare(tx) => tx.create_tx_info(), - Self::DeployAccount(tx) => tx.create_tx_info(), - Self::Invoke(tx) => tx.create_tx_info(), + match &self.tx { + Transaction::Declare(tx) => tx.create_tx_info(self.only_query), + Transaction::DeployAccount(tx) => tx.create_tx_info(self.only_query), + Transaction::Invoke(tx) => tx.create_tx_info(self.only_query), } } } diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index e5f1082ace..336abb1a7c 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -8,6 +8,10 @@ use pretty_assertions::{assert_eq, assert_ne}; use rstest::rstest; use starknet_api::block::GasPrice; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress}; +use starknet_api::executable_transaction::{ + DeclareTransaction as ApiExecutableDeclareTransaction, + Transaction as ApiExecutableTransaction, +}; use starknet_api::execution_resources::GasAmount; use starknet_api::hash::StarkHash; use starknet_api::state::StorageKey; @@ -17,6 +21,7 @@ use starknet_api::transaction::{ AllResourceBounds, Calldata, ContractAddressSalt, + DeclareTransaction, DeclareTransactionV2, Fee, GasVectorComputationMode, @@ -96,7 +101,7 @@ use crate::transaction::test_utils::{ INVALID, }; use crate::transaction::transaction_types::TransactionType; -use crate::transaction::transactions::{DeclareTransaction, ExecutableTransaction, ExecutionFlags}; +use crate::transaction::transactions::{ExecutableTransaction, ExecutionFlags}; use crate::utils::u64_from_usize; #[rstest] @@ -718,8 +723,8 @@ fn test_fail_deploy_account( }); let fee_token_address = chain_info.fee_token_address(&deploy_account_tx.fee_type()); - let deploy_address = match &deploy_account_tx { - AccountTransaction::DeployAccount(deploy_tx) => deploy_tx.contract_address(), + let deploy_address = match &deploy_account_tx.tx { + ApiExecutableTransaction::DeployAccount(deploy_tx) => deploy_tx.contract_address(), _ => unreachable!("deploy_account_tx is a DeployAccount"), }; fund_account(chain_info, deploy_address, Fee(BALANCE.0 * 2), &mut state.state); @@ -750,26 +755,24 @@ fn test_fail_declare(block_context: BlockContext, max_fee: Fee) { let next_nonce = nonce_manager.next(account_address); // Cannot fail executing a declare tx unless it's V2 or above, and already declared. - let declare_tx = DeclareTransactionV2 { + let declare_tx_v2 = DeclareTransactionV2 { max_fee, class_hash, sender_address: account_address, ..Default::default() }; state.set_contract_class(class_hash, contract_class.clone().try_into().unwrap()).unwrap(); - state.set_compiled_class_hash(class_hash, declare_tx.compiled_class_hash).unwrap(); + state.set_compiled_class_hash(class_hash, declare_tx_v2.compiled_class_hash).unwrap(); let class_info = calculate_class_info_for_testing(contract_class); - let declare_account_tx = AccountTransaction::Declare( - DeclareTransaction::new( - starknet_api::transaction::DeclareTransaction::V2(DeclareTransactionV2 { - nonce: next_nonce, - ..declare_tx - }), - TransactionHash::default(), + 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, - ) - .unwrap(), - ); + }, + )); // Fail execution, assert nonce and balance are unchanged. let tx_info = declare_account_tx.create_tx_info(); diff --git a/crates/blockifier/src/transaction/objects.rs b/crates/blockifier/src/transaction/objects.rs index f3a7ed7cf4..a3ad411891 100644 --- a/crates/blockifier/src/transaction/objects.rs +++ b/crates/blockifier/src/transaction/objects.rs @@ -233,3 +233,7 @@ pub enum FeeType { pub trait TransactionInfoCreator { fn create_tx_info(&self) -> TransactionInfo; } + +pub trait TransactionInfoCreatorInner { + fn create_tx_info(&self, only_query: bool) -> TransactionInfo; +} diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index 17a158253b..b2ecf1a4cb 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -1,6 +1,6 @@ use rstest::fixture; use starknet_api::block::GasPrice; -use starknet_api::contract_class::ContractClass; +use starknet_api::contract_class::{ClassInfo, ContractClass}; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::execution_resources::GasAmount; use starknet_api::test_utils::deploy_account::DeployAccountTxArgs; @@ -26,7 +26,6 @@ use strum::IntoEnumIterator; use crate::abi::abi_utils::get_fee_token_var_address; use crate::context::{BlockContext, ChainInfo}; -use crate::execution::contract_class::ClassInfo; 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 64ca5b5901..dd80a218c9 100644 --- a/crates/blockifier/src/transaction/transaction_execution.rs +++ b/crates/blockifier/src/transaction/transaction_execution.rs @@ -1,14 +1,20 @@ 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, Nonce}; -use starknet_api::executable_transaction::L1HandlerTransaction; +use starknet_api::executable_transaction::{ + DeclareTransaction as ApiExecutableDeclareTransaction, + DeployAccountTransaction as ApiExecutableDeployAccountTransaction, + InvokeTransaction as ApiExecutableInvokeTransaction, + L1HandlerTransaction, + Transaction as ApiExecutableTransaction, +}; use starknet_api::transaction::{Fee, Transaction as StarknetApiTransaction, TransactionHash}; use crate::bouncer::verify_tx_weights_within_max_capacity; use crate::context::BlockContext; use crate::execution::call_info::CallInfo; -use crate::execution::contract_class::ClassInfo; use crate::execution::entry_point::EntryPointExecutionContext; use crate::fee::receipt::TransactionReceipt; use crate::state::cached_state::TransactionalState; @@ -21,14 +27,7 @@ use crate::transaction::objects::{ TransactionInfo, TransactionInfoCreator, }; -use crate::transaction::transactions::{ - DeclareTransaction, - DeployAccountTransaction, - Executable, - ExecutableTransaction, - ExecutionFlags, - InvokeTransaction, -}; +use crate::transaction::transactions::{Executable, ExecutableTransaction, ExecutionFlags}; // TODO: Move into transaction.rs, makes more sense to be defined there. #[derive(Clone, Debug, derive_more::From)] @@ -79,13 +78,17 @@ impl Transaction { StarknetApiTransaction::Declare(declare) => { let non_optional_class_info = class_info.expect("Declare should be created with a ClassInfo."); + let executable_declare_tx = + ApiExecutableTransaction::Declare(ApiExecutableDeclareTransaction { + tx: declare, + tx_hash, + class_info: non_optional_class_info, + }); let declare_tx = match only_query { - true => { - DeclareTransaction::new_for_query(declare, tx_hash, non_optional_class_info) - } - false => DeclareTransaction::new(declare, tx_hash, non_optional_class_info), + true => AccountTransaction::new_for_query(executable_declare_tx), + false => AccountTransaction::new(executable_declare_tx), }; - Ok(declare_tx?.into()) + Ok(Self::Account(declare_tx)) } StarknetApiTransaction::DeployAccount(deploy_account) => { let contract_address = match deployed_contract_address { @@ -97,24 +100,30 @@ impl Transaction { ContractAddress::default(), )?, }; - let deploy_account_tx = match only_query { - true => DeployAccountTransaction::new_for_query( - deploy_account, + let executable_deploy_account_tx = ApiExecutableTransaction::DeployAccount( + ApiExecutableDeployAccountTransaction { + tx: deploy_account, tx_hash, contract_address, - ), - false => { - DeployAccountTransaction::new(deploy_account, tx_hash, contract_address) - } + }, + ); + let deploy_account_tx = match only_query { + true => AccountTransaction::new_for_query(executable_deploy_account_tx), + false => AccountTransaction::new(executable_deploy_account_tx), }; - Ok(deploy_account_tx.into()) + Ok(Self::Account(deploy_account_tx)) } StarknetApiTransaction::Invoke(invoke) => { + let executable_invoke_tx = + ApiExecutableTransaction::Invoke(ApiExecutableInvokeTransaction { + tx: invoke, + tx_hash, + }); let invoke_tx = match only_query { - true => InvokeTransaction::new_for_query(invoke, tx_hash), - false => InvokeTransaction::new(invoke, tx_hash), + true => AccountTransaction::new_for_query(executable_invoke_tx), + false => AccountTransaction::new(executable_invoke_tx), }; - Ok(invoke_tx.into()) + Ok(Self::Account(invoke_tx)) } _ => unimplemented!(), } @@ -220,21 +229,3 @@ impl ExecutableTransaction for Transaction { Ok(tx_execution_info) } } - -impl From for Transaction { - fn from(value: DeclareTransaction) -> Self { - Self::Account(AccountTransaction::Declare(value)) - } -} - -impl From for Transaction { - fn from(value: DeployAccountTransaction) -> Self { - Self::Account(AccountTransaction::DeployAccount(value)) - } -} - -impl From for Transaction { - fn from(value: InvokeTransaction) -> Self { - Self::Account(AccountTransaction::Invoke(value)) - } -} diff --git a/crates/blockifier/src/transaction/transactions.rs b/crates/blockifier/src/transaction/transactions.rs index 86cddf207d..73444770c8 100644 --- a/crates/blockifier/src/transaction/transactions.rs +++ b/crates/blockifier/src/transaction/transactions.rs @@ -47,6 +47,7 @@ use crate::transaction::objects::{ TransactionExecutionResult, TransactionInfo, TransactionInfoCreator, + TransactionInfoCreatorInner, }; #[cfg(test)] #[path = "transactions_test.rs"] @@ -661,8 +662,8 @@ impl Executable for ExecutableDeclareTx { } } -impl TransactionInfoCreator for ExecutableDeclareTx { - fn create_tx_info(&self) -> TransactionInfo { +impl TransactionInfoCreatorInner for ExecutableDeclareTx { + fn create_tx_info(&self, only_query: bool) -> 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, @@ -670,8 +671,7 @@ impl TransactionInfoCreator for ExecutableDeclareTx { signature: self.signature(), nonce: self.nonce(), sender_address: self.sender_address(), - only_query: false, /* Reminder(AvivG remove before PR): override by the AccountTx - * when calling. */ + only_query, }; match &self.tx { @@ -731,16 +731,15 @@ impl Executable for ExecutableDeployAccountTx { } } -impl TransactionInfoCreator for ExecutableDeployAccountTx { - fn create_tx_info(&self) -> TransactionInfo { +impl TransactionInfoCreatorInner for ExecutableDeployAccountTx { + fn create_tx_info(&self, only_query: bool) -> 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: false, /* Reminder(AvivG remove before PR): override by the AccountTx - * when calling. */ + only_query, }; match &self.tx { @@ -806,16 +805,15 @@ impl Executable for ExecutableInvokeTx { } } -impl TransactionInfoCreator for ExecutableInvokeTx { - fn create_tx_info(&self) -> TransactionInfo { +impl TransactionInfoCreatorInner for ExecutableInvokeTx { + fn create_tx_info(&self, only_query: bool) -> 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: false, /* Reminder(AvivG remove before PR): override by the AccountTx - * when calling. */ + only_query, }; match &self.tx() { diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index 76ce6f9b36..fcddeac745 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -446,7 +446,7 @@ fn test_invoke_tx( // Extract invoke transaction fields for testing, as it is consumed when creating an account // transaction. - let calldata = Calldata(Arc::clone(&account_tx.calldata().0)); //Aviv how to access? + let calldata = Calldata(Arc::clone(&account_tx.calldata().0)); let calldata_length = account_tx.calldata_length(); let signature_length = account_tx.signature_length(); let state_changes_for_fee = StateChangesCount { diff --git a/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs b/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs index e0b1b67734..bf5a2db626 100644 --- a/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs +++ b/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs @@ -1,7 +1,7 @@ -use blockifier::execution::contract_class::ClassInfo; use blockifier::state::state_api::StateResult; use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; use papyrus_execution::DEPRECATED_CONTRACT_SIERRA_SIZE; +use starknet_api::contract_class::ClassInfo; use starknet_api::core::ClassHash; use starknet_api::transaction::{Transaction, TransactionHash}; use starknet_core::types::ContractClass as StarknetContractClass; diff --git a/crates/gateway/src/stateful_transaction_validator.rs b/crates/gateway/src/stateful_transaction_validator.rs index 51694eb868..3f51a027c1 100644 --- a/crates/gateway/src/stateful_transaction_validator.rs +++ b/crates/gateway/src/stateful_transaction_validator.rs @@ -75,7 +75,7 @@ impl StatefulTransactionValidator { mut validator: V, ) -> StatefulTransactionValidatorResult<()> { let skip_validate = skip_stateful_validations(executable_tx, account_nonce); - let account_tx = AccountTransaction::try_from(executable_tx).map_err(|error| { + let account_tx = AccountTransaction::try_from(executable_tx.clone()).map_err(|error| { error!("Failed to convert executable transaction into account transaction: {}", error); GatewaySpecError::UnexpectedError { data: "Internal server error".to_owned() } })?; diff --git a/crates/native_blockifier/src/py_declare.rs b/crates/native_blockifier/src/py_declare.rs index b8d74535f0..75acb321ac 100644 --- a/crates/native_blockifier/src/py_declare.rs +++ b/crates/native_blockifier/src/py_declare.rs @@ -1,10 +1,10 @@ use std::convert::TryFrom; use blockifier::transaction::transaction_types::TransactionType; -use blockifier::transaction::transactions::DeclareTransaction; use pyo3::prelude::*; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; +use starknet_api::executable_transaction::DeclareTransaction; use starknet_api::transaction::{ AccountDeploymentData, DeclareTransactionV0V1, @@ -136,5 +136,5 @@ pub fn py_declare( }?; let tx_hash = TransactionHash(py_attr::(py_tx, "hash_value")?.0); let class_info = PyClassInfo::try_from(py_class_info, &tx)?; - Ok(DeclareTransaction::new(tx, tx_hash, class_info)?) + Ok(DeclareTransaction { tx, tx_hash, class_info }) } diff --git a/crates/native_blockifier/src/py_deploy_account.rs b/crates/native_blockifier/src/py_deploy_account.rs index b25b464103..53ef9442b2 100644 --- a/crates/native_blockifier/src/py_deploy_account.rs +++ b/crates/native_blockifier/src/py_deploy_account.rs @@ -1,10 +1,10 @@ use std::sync::Arc; use blockifier::transaction::transaction_types::TransactionType; -use blockifier::transaction::transactions::DeployAccountTransaction; use pyo3::prelude::*; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; +use starknet_api::executable_transaction::DeployAccountTransaction; use starknet_api::transaction::{ Calldata, ContractAddressSalt, @@ -100,5 +100,5 @@ pub fn py_deploy_account(py_tx: &PyAny) -> NativeBlockifierResult(py_tx, "hash_value")?.0); let contract_address = ContractAddress::try_from(py_attr::(py_tx, "sender_address")?.0)?; - Ok(DeployAccountTransaction::new(tx, tx_hash, contract_address)) + Ok(DeployAccountTransaction { tx, tx_hash, contract_address }) } diff --git a/crates/native_blockifier/src/py_invoke_function.rs b/crates/native_blockifier/src/py_invoke_function.rs index 974d0b9b1d..dbc96f4c70 100644 --- a/crates/native_blockifier/src/py_invoke_function.rs +++ b/crates/native_blockifier/src/py_invoke_function.rs @@ -2,10 +2,10 @@ use std::convert::TryFrom; use std::sync::Arc; use blockifier::transaction::transaction_types::TransactionType; -use blockifier::transaction::transactions::InvokeTransaction; use pyo3::prelude::*; use starknet_api::core::{ContractAddress, EntryPointSelector, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; +use starknet_api::executable_transaction::InvokeTransaction; use starknet_api::transaction::{ AccountDeploymentData, Calldata, @@ -127,5 +127,5 @@ pub fn py_invoke_function(py_tx: &PyAny) -> NativeBlockifierResult(py_tx, "hash_value")?.0); - Ok(InvokeTransaction::new(tx, tx_hash)) + Ok(InvokeTransaction { tx, tx_hash }) } diff --git a/crates/native_blockifier/src/py_transaction.rs b/crates/native_blockifier/src/py_transaction.rs index 5ac4b56df8..658cc61102 100644 --- a/crates/native_blockifier/src/py_transaction.rs +++ b/crates/native_blockifier/src/py_transaction.rs @@ -1,13 +1,13 @@ use std::collections::BTreeMap; -use blockifier::execution::contract_class::ClassInfo; 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::block::GasPrice; -use starknet_api::contract_class::ContractClass; +use starknet_api::contract_class::{ClassInfo, ContractClass}; +use starknet_api::executable_transaction::Transaction as ExecutableTransaction; use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::{ DeprecatedResourceBoundsMapping, @@ -138,13 +138,18 @@ pub fn py_tx( TransactionType::Declare => { let non_optional_py_class_info: PyClassInfo = optional_py_class_info .expect("A class info must be passed in a Declare transaction."); - AccountTransaction::Declare(py_declare(tx, non_optional_py_class_info)?).into() + AccountTransaction::new(ExecutableTransaction::Declare(py_declare( + tx, + non_optional_py_class_info, + )?)) + .into() } TransactionType::DeployAccount => { - AccountTransaction::DeployAccount(py_deploy_account(tx)?).into() + AccountTransaction::new(ExecutableTransaction::DeployAccount(py_deploy_account(tx)?)) + .into() } TransactionType::InvokeFunction => { - AccountTransaction::Invoke(py_invoke_function(tx)?).into() + AccountTransaction::new(ExecutableTransaction::Invoke(py_invoke_function(tx)?)).into() } TransactionType::L1Handler => py_l1_handler(tx)?.into(), }) diff --git a/crates/papyrus_execution/src/lib.rs b/crates/papyrus_execution/src/lib.rs index cf393a232e..8a69cd3103 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -27,7 +27,6 @@ use blockifier::blockifier::block::{pre_process_block, BlockInfo, GasPrices}; use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo, FeeTokenAddresses, TransactionContext}; use blockifier::execution::call_info::CallExecution; -use blockifier::execution::contract_class::ClassInfo; use blockifier::execution::entry_point::{ CallEntryPoint, CallType as BlockifierCallType, @@ -54,7 +53,7 @@ use papyrus_storage::header::HeaderStorageReader; use papyrus_storage::{StorageError, StorageReader}; use serde::{Deserialize, Serialize}; use starknet_api::block::{BlockHashAndNumber, BlockNumber, NonzeroGasPrice, StarknetVersion}; -use starknet_api::contract_class::EntryPointType; +use starknet_api::contract_class::{ClassInfo, EntryPointType}; use starknet_api::core::{ChainId, ClassHash, ContractAddress, EntryPointSelector}; use starknet_api::data_availability::L1DataAvailabilityMode; use starknet_api::deprecated_contract_class::ContractClass as DeprecatedContractClass; @@ -165,7 +164,7 @@ pub enum ExecutionError { BadDeclareTransaction { tx: DeclareTransaction, #[source] - err: blockifier::execution::errors::ContractClassError, + err: starknet_api::StarknetApiError, }, #[error("Execution config file does not contain a configuration for all blocks")] ConfigContentError, diff --git a/crates/starknet_api/src/executable_transaction.rs b/crates/starknet_api/src/executable_transaction.rs index 7c9ee86e4b..a9f3251659 100644 --- a/crates/starknet_api/src/executable_transaction.rs +++ b/crates/starknet_api/src/executable_transaction.rs @@ -230,6 +230,8 @@ impl DeclareTransaction { (signature, TransactionSignature), (version, TransactionVersion) ); + + implement_getter_calls!((tx_hash, TransactionHash)); } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]