diff --git a/crates/blockifier/src/blockifier/transaction_executor.rs b/crates/blockifier/src/blockifier/transaction_executor.rs index 4ad8bfb285..f693daf8ff 100644 --- a/crates/blockifier/src/blockifier/transaction_executor.rs +++ b/crates/blockifier/src/blockifier/transaction_executor.rs @@ -17,7 +17,7 @@ use crate::state::cached_state::{CachedState, CommitmentStateDiff, Transactional use crate::state::errors::StateError; use crate::state::state_api::{StateReader, StateResult}; use crate::transaction::errors::TransactionExecutionError; -use crate::transaction::objects::{TransactionExecutionInfo, TransactionInfoCreator}; +use crate::transaction::objects::TransactionExecutionInfo; use crate::transaction::transaction_execution::Transaction; use crate::transaction::transactions::{ExecutableTransaction, ExecutionFlags}; @@ -100,11 +100,9 @@ impl TransactionExecutor { let mut transactional_state = TransactionalState::create_transactional( self.block_state.as_mut().expect(BLOCK_STATE_ACCESS_ERR), ); - let tx_charge_fee = tx.create_tx_info().enforce_fee(); // Executing a single transaction cannot be done in a concurrent mode. - let execution_flags = - ExecutionFlags { charge_fee: tx_charge_fee, validate: true, concurrency_mode: false }; + let execution_flags = ExecutionFlags { concurrency_mode: false }; let tx_execution_result = tx.execute_raw(&mut transactional_state, &self.block_context, execution_flags); match tx_execution_result { diff --git a/crates/blockifier/src/blockifier/transaction_executor_test.rs b/crates/blockifier/src/blockifier/transaction_executor_test.rs index 0816316998..1e9cf7299a 100644 --- a/crates/blockifier/src/blockifier/transaction_executor_test.rs +++ b/crates/blockifier/src/blockifier/transaction_executor_test.rs @@ -30,7 +30,7 @@ use crate::test_utils::{ BALANCE, DEFAULT_STRK_L1_GAS_PRICE, }; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use crate::transaction::errors::TransactionExecutionError; use crate::transaction::test_utils::{ block_context, @@ -41,6 +41,7 @@ use crate::transaction::test_utils::{ TestInitData, }; use crate::transaction::transaction_execution::Transaction; +use crate::transaction::transactions::enforce_fee; fn tx_executor_test_body( state: CachedState, block_context: BlockContext, @@ -131,7 +132,10 @@ fn test_declare( }, calculate_class_info_for_testing(declared_contract.get_class()), ); - let tx = AccountTransaction { tx: declare_tx, only_query: false }.into(); + let only_query = false; + let charge_fee = enforce_fee(&declare_tx, only_query); + let execution_flags = ExecutionFlags { only_query, charge_fee, ..ExecutionFlags::default() }; + let tx = AccountTransaction { tx: declare_tx, execution_flags }.into(); tx_executor_test_body(state, block_context, tx, expected_bouncer_weights); } @@ -152,13 +156,17 @@ fn test_deploy_account( }, &mut NonceManager::default(), ); - let tx = AccountTransaction { tx: deploy_account_tx, only_query: false }.into(); + let only_query = false; + let charge_fee = enforce_fee(&deploy_account_tx, only_query); + let execution_flags = ExecutionFlags { only_query, charge_fee, ..ExecutionFlags::default() }; + let tx = AccountTransaction { tx: deploy_account_tx, execution_flags }.into(); let expected_bouncer_weights = BouncerWeights { state_diff_size: 3, message_segment_length: 0, n_events: 0, ..BouncerWeights::empty() - }; + } + .into(); tx_executor_test_body(state, block_context, tx, expected_bouncer_weights); } @@ -223,7 +231,10 @@ fn test_invoke( calldata, version, }); - let tx = AccountTransaction { tx: invoke_tx, only_query: false }.into(); + let only_query = false; + let charge_fee = enforce_fee(&invoke_tx, only_query); + let execution_flags = ExecutionFlags { only_query, charge_fee, ..ExecutionFlags::default() }; + let tx = AccountTransaction { tx: invoke_tx, execution_flags }.into(); tx_executor_test_body(state, block_context, tx, expected_bouncer_weights); } diff --git a/crates/blockifier/src/concurrency/test_utils.rs b/crates/blockifier/src/concurrency/test_utils.rs index 96e8d20261..a14e96de6f 100644 --- a/crates/blockifier/src/concurrency/test_utils.rs +++ b/crates/blockifier/src/concurrency/test_utils.rs @@ -76,7 +76,7 @@ pub fn create_fee_transfer_call_info( ) -> CallInfo { let block_context = BlockContext::create_for_account_testing(); let mut transactional_state = TransactionalState::create_transactional(state); - let execution_flags = ExecutionFlags { charge_fee: true, validate: true, concurrency_mode }; + let execution_flags = ExecutionFlags { concurrency_mode }; let execution_info = account_tx.execute_raw(&mut transactional_state, &block_context, execution_flags).unwrap(); diff --git a/crates/blockifier/src/concurrency/versioned_state_test.rs b/crates/blockifier/src/concurrency/versioned_state_test.rs index 48a0a95065..87727a1c36 100644 --- a/crates/blockifier/src/concurrency/versioned_state_test.rs +++ b/crates/blockifier/src/concurrency/versioned_state_test.rs @@ -44,10 +44,10 @@ use crate::test_utils::deploy_account::deploy_account_tx; use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{CairoVersion, BALANCE, DEFAULT_STRK_L1_GAS_PRICE}; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use crate::transaction::objects::HasRelatedFeeType; use crate::transaction::test_utils::{default_all_resource_bounds, l1_resource_bounds}; -use crate::transaction::transactions::ExecutableTransaction; +use crate::transaction::transactions::{enforce_fee, ExecutableTransaction}; #[fixture] pub fn safe_versioned_state( @@ -236,8 +236,9 @@ fn test_run_parallel_txs(default_all_resource_bounds: ValidResourceBounds) { }, &mut NonceManager::default(), ); - let deploy_account_tx_1 = AccountTransaction { tx, only_query: false }; - let enforce_fee = deploy_account_tx_1.enforce_fee(); + let enforce_fee = enforce_fee(&tx, false); + let execution_flags = ExecutionFlags { charge_fee: enforce_fee, ..ExecutionFlags::default() }; + let deploy_account_tx_1 = AccountTransaction { tx, execution_flags: execution_flags.clone() }; let class_hash = grindy_account.get_class_hash(); let ctor_storage_arg = felt!(1_u8); @@ -251,8 +252,9 @@ fn test_run_parallel_txs(default_all_resource_bounds: ValidResourceBounds) { let nonce_manager = &mut NonceManager::default(); let delpoy_account_tx_2 = AccountTransaction { tx: deploy_account_tx(deploy_tx_args, nonce_manager), - only_query: false, + execution_flags, }; + let account_address = delpoy_account_tx_2.sender_address(); let tx_context = block_context.to_tx_context(&delpoy_account_tx_2); let fee_type = tx_context.tx_info.fee_type(); @@ -269,12 +271,11 @@ fn test_run_parallel_txs(default_all_resource_bounds: ValidResourceBounds) { // Execute transactions thread::scope(|s| { s.spawn(move || { - let result = - deploy_account_tx_1.execute(&mut state_1, &block_context_1, enforce_fee, true); + let result = deploy_account_tx_1.execute(&mut state_1, &block_context_1); assert_eq!(result.is_err(), enforce_fee); // Transaction fails iff we enforced the fee charge (as the acount is not funded). }); s.spawn(move || { - delpoy_account_tx_2.execute(&mut state_2, &block_context_2, true, true).unwrap(); + delpoy_account_tx_2.execute(&mut state_2, &block_context_2).unwrap(); // Check that the constructor wrote ctor_arg to the storage. let storage_key = get_storage_var_address("ctor_arg", &[]); let deployed_contract_address = calculate_contract_address( diff --git a/crates/blockifier/src/concurrency/worker_logic.rs b/crates/blockifier/src/concurrency/worker_logic.rs index af2ec35c36..dee56aa6aa 100644 --- a/crates/blockifier/src/concurrency/worker_logic.rs +++ b/crates/blockifier/src/concurrency/worker_logic.rs @@ -17,11 +17,7 @@ use crate::concurrency::TxIndex; use crate::context::BlockContext; use crate::state::cached_state::{ContractClassMapping, StateMaps, TransactionalState}; use crate::state::state_api::{StateReader, UpdatableState}; -use crate::transaction::objects::{ - TransactionExecutionInfo, - TransactionExecutionResult, - TransactionInfoCreator, -}; +use crate::transaction::objects::{TransactionExecutionInfo, TransactionExecutionResult}; use crate::transaction::transaction_execution::Transaction; use crate::transaction::transactions::{ExecutableTransaction, ExecutionFlags}; @@ -127,11 +123,9 @@ impl<'a, S: StateReader> WorkerExecutor<'a, S> { fn execute_tx(&self, tx_index: TxIndex) { let mut tx_versioned_state = self.state.pin_version(tx_index); let tx = &self.chunk[tx_index]; - let tx_charge_fee = tx.create_tx_info().enforce_fee(); let mut transactional_state = TransactionalState::create_transactional(&mut tx_versioned_state); - let execution_flags = - ExecutionFlags { charge_fee: tx_charge_fee, validate: true, concurrency_mode: true }; + let execution_flags = ExecutionFlags { concurrency_mode: true }; let execution_result = tx.execute_raw(&mut transactional_state, self.block_context, execution_flags); diff --git a/crates/blockifier/src/concurrency/worker_logic_test.rs b/crates/blockifier/src/concurrency/worker_logic_test.rs index 4370e43d17..ee64bb8210 100644 --- a/crates/blockifier/src/concurrency/worker_logic_test.rs +++ b/crates/blockifier/src/concurrency/worker_logic_test.rs @@ -32,7 +32,7 @@ use crate::test_utils::{ BALANCE, TEST_ERC20_CONTRACT_ADDRESS2, }; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use crate::transaction::objects::HasRelatedFeeType; use crate::transaction::test_utils::{ account_invoke_tx, @@ -561,7 +561,8 @@ fn test_deploy_before_declare( }, test_class_info.clone(), ); - let declare_tx = AccountTransaction { tx, only_query: false }; + let execution_flags = ExecutionFlags::default(); + let declare_tx = AccountTransaction { tx, execution_flags }; // Deploy test contract. let invoke_tx = account_invoke_tx(invoke_tx_args! { diff --git a/crates/blockifier/src/execution/stack_trace_test.rs b/crates/blockifier/src/execution/stack_trace_test.rs index 80e77478a6..5b171d9cff 100644 --- a/crates/blockifier/src/execution/stack_trace_test.rs +++ b/crates/blockifier/src/execution/stack_trace_test.rs @@ -45,6 +45,7 @@ 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, ExecutionFlags}; use crate::transaction::test_utils::{ account_invoke_tx, block_context, @@ -608,6 +609,11 @@ fn test_validate_trace( } } + // TODO(AvivG): Change this fixup to not create account_tx twice w wrong charge_fee. + let execution_flags = + ExecutionFlags { charge_fee: account_tx.enforce_fee(), ..ExecutionFlags::default() }; + let account_tx = AccountTransaction { tx: account_tx.tx, execution_flags }; + let contract_address = *sender_address.0.key(); let expected_error = match cairo_version { @@ -639,8 +645,7 @@ Error in contract (contract address: {contract_address:#064x}, class hash: {:#06 // Clean pc locations from the trace. let re = Regex::new(r"pc=0:[0-9]+").unwrap(); let cleaned_expected_error = &re.replace_all(&expected_error, "pc=0:*"); - let charge_fee = account_tx.enforce_fee(); - let actual_error = account_tx.execute(state, block_context, charge_fee, true).unwrap_err(); + let actual_error = account_tx.execute(state, block_context).unwrap_err(); let actual_error_str = actual_error.to_string(); let cleaned_actual_error = &re.replace_all(&actual_error_str, "pc=0:*"); // Compare actual trace to the expected trace (sans pc locations). @@ -713,7 +718,7 @@ Error in contract (contract address: {expected_address:#064x}, class hash: {:#06 }; // Compare expected and actual error. - let error = deploy_account_tx.execute(state, &block_context, true, true).unwrap_err(); + let error = deploy_account_tx.execute(state, &block_context).unwrap_err(); assert_eq!(error.to_string(), expected_error); } @@ -854,8 +859,7 @@ Error in contract (contract address: {expected_address:#064x}, class hash: {:#06 }; // Compare expected and actual error. - let error = - invoke_deploy_tx.execute(state, &block_context, true, true).unwrap().revert_error.unwrap(); + let error = invoke_deploy_tx.execute(state, &block_context).unwrap().revert_error.unwrap(); assert_eq!(error.to_string(), expected_error); } diff --git a/crates/blockifier/src/fee/receipt_test.rs b/crates/blockifier/src/fee/receipt_test.rs index 34b41bca13..c6ae428f49 100644 --- a/crates/blockifier/src/fee/receipt_test.rs +++ b/crates/blockifier/src/fee/receipt_test.rs @@ -383,7 +383,7 @@ fn test_calculate_tx_gas_usage( let calldata_length = account_tx.calldata_length(); let signature_length = account_tx.signature_length(); let fee_token_address = chain_info.fee_token_address(&account_tx.fee_type()); - let tx_execution_info = account_tx.execute(state, block_context, true, true).unwrap(); + let tx_execution_info = account_tx.execute(state, block_context).unwrap(); let n_storage_updates = 1; // For the account balance update. let n_modified_contracts = 1; @@ -437,7 +437,7 @@ fn test_calculate_tx_gas_usage( let calldata_length = account_tx.calldata_length(); let signature_length = account_tx.signature_length(); - let tx_execution_info = account_tx.execute(state, block_context, true, true).unwrap(); + let tx_execution_info = account_tx.execute(state, block_context).unwrap(); // For the balance update of the sender and the recipient. let n_storage_updates = 2; // Only the account contract modification (nonce update) excluding the fee token contract. diff --git a/crates/blockifier/src/test_utils/transfers_generator.rs b/crates/blockifier/src/test_utils/transfers_generator.rs index 213215ca10..6833e78a20 100644 --- a/crates/blockifier/src/test_utils/transfers_generator.rs +++ b/crates/blockifier/src/test_utils/transfers_generator.rs @@ -18,9 +18,9 @@ use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::invoke::invoke_tx; use crate::test_utils::{CairoVersion, BALANCE, MAX_FEE}; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use crate::transaction::transaction_execution::Transaction; - +use crate::transaction::transactions::enforce_fee; const N_ACCOUNTS: u16 = 10000; const N_TXS: usize = 1000; const RANDOMIZATION_SEED: u64 = 0; @@ -145,7 +145,13 @@ impl TransfersGenerator { self.sender_index = (self.sender_index + 1) % self.account_addresses.len(); let tx = self.generate_transfer(sender_address, recipient_address); - let account_tx = AccountTransaction { tx, only_query: false }; + let only_query = false; + let execution_flags = ExecutionFlags { + charge_fee: enforce_fee(&tx, only_query), + only_query, + ..ExecutionFlags::default() + }; + let account_tx = AccountTransaction { tx, execution_flags }; txs.push(Transaction::Account(account_tx)); } let results = self.executor.execute_txs(&txs); diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 3d87f93c85..19c622a5af 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -61,7 +61,7 @@ use crate::transaction::transaction_types::TransactionType; use crate::transaction::transactions::{ Executable, ExecutableTransaction, - ExecutionFlags, + ExecutionFlags as TransactionExecutionFlags, ValidatableTransaction, }; @@ -77,11 +77,24 @@ mod flavors_test; #[path = "post_execution_test.rs"] mod post_execution_test; +#[derive(Clone, Debug, derive_more::From)] +pub struct ExecutionFlags { + pub only_query: bool, + pub charge_fee: bool, + pub validate: bool, +} + +impl Default for ExecutionFlags { + fn default() -> Self { + Self { only_query: false, charge_fee: true, validate: true } + } +} + /// Represents a paid Starknet transaction. #[derive(Clone, Debug, derive_more::From)] pub struct AccountTransaction { pub tx: Transaction, - pub only_query: bool, + pub execution_flags: ExecutionFlags, } // TODO(AvivG): create additional macro that returns a reference. macro_rules! implement_tx_getter_calls { @@ -708,7 +721,7 @@ impl ExecutableTransaction for AccountTransaction { &self, state: &mut TransactionalState<'_, U>, block_context: &BlockContext, - execution_flags: ExecutionFlags, + execution_flags_: TransactionExecutionFlags, ) -> TransactionExecutionResult { let tx_context = Arc::new(block_context.to_tx_context(self)); self.verify_tx_version(tx_context.tx_info.version())?; @@ -718,7 +731,8 @@ impl ExecutableTransaction for AccountTransaction { self.perform_pre_validation_stage( state, &tx_context, - execution_flags.charge_fee, + // TODO (AvivG): access execution_flags within func instead of passing them as args. + self.execution_flags.charge_fee, strict_nonce_check, )?; @@ -739,15 +753,17 @@ impl ExecutableTransaction for AccountTransaction { state, &mut remaining_gas, tx_context.clone(), - execution_flags.validate, - execution_flags.charge_fee, + // TODO (AvivG): access execution_flags within func instead of passing them as args. + self.execution_flags.validate, + self.execution_flags.charge_fee, )?; let fee_transfer_call_info = Self::handle_fee( state, tx_context, final_fee, - execution_flags.charge_fee, - execution_flags.concurrency_mode, + // TODO (AvivG): access execution_flags within func instead of passing them as args. + self.execution_flags.charge_fee, + execution_flags_.concurrency_mode, )?; let tx_execution_info = TransactionExecutionInfo { @@ -768,7 +784,7 @@ impl ExecutableTransaction for AccountTransaction { impl TransactionInfoCreator for AccountTransaction { fn create_tx_info(&self) -> TransactionInfo { - self.tx.create_tx_info(self.only_query) + self.tx.create_tx_info(self.execution_flags.only_query) } } diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index a016105508..73db0ab828 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -84,7 +84,10 @@ use crate::test_utils::{ DEFAULT_STRK_L2_GAS_PRICE, MAX_FEE, }; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{ + AccountTransaction, + ExecutionFlags as AccountExecutionFlags, +}; use crate::transaction::objects::{HasRelatedFeeType, TransactionInfoCreator}; use crate::transaction::test_utils::{ account_invoke_tx, @@ -105,7 +108,7 @@ use crate::transaction::test_utils::{ INVALID, }; use crate::transaction::transaction_types::TransactionType; -use crate::transaction::transactions::{ExecutableTransaction, ExecutionFlags}; +use crate::transaction::transactions::{enforce_fee, ExecutableTransaction, ExecutionFlags}; use crate::utils::u64_from_usize; #[rstest] @@ -213,11 +216,15 @@ fn test_fee_enforcement( }, &mut NonceManager::default(), ); - let deploy_account_tx = AccountTransaction { tx, only_query: false }; + let only_query = false; + let charge_fee = enforce_fee(&tx, only_query); + let execution_flags = + AccountExecutionFlags { only_query, charge_fee, ..AccountExecutionFlags::default() }; + let deploy_account_tx = AccountTransaction { tx, execution_flags }; let enforce_fee = deploy_account_tx.enforce_fee(); assert_ne!(zero_bounds, enforce_fee); - let result = deploy_account_tx.execute(state, &block_context, enforce_fee, true); + let result = deploy_account_tx.execute(state, &block_context); // Execution should fail if the fee is enforced because the account doesn't have sufficient // balance. assert_eq!(result.is_err(), enforce_fee); @@ -462,8 +469,9 @@ fn test_max_fee_limit_validate( }, class_info, ); - let account_tx = AccountTransaction { tx, only_query: false }; - account_tx.execute(&mut state, &block_context, true, true).unwrap(); + let execution_flags = AccountExecutionFlags::default(); + let account_tx = AccountTransaction { tx, execution_flags }; + account_tx.execute(&mut state, &block_context).unwrap(); // Deploy grindy account with a lot of grind in the constructor. // Expect this to fail without bumping nonce, so pass a temporary nonce manager. @@ -483,7 +491,7 @@ fn test_max_fee_limit_validate( }, ); let error_trace = - deploy_account_tx.execute(&mut state, &block_context, true, true).unwrap_err().to_string(); + deploy_account_tx.execute(&mut state, &block_context).unwrap_err().to_string(); assert!(error_trace.contains("no remaining steps")); block_context.versioned_constants.validate_max_n_steps = old_validate_max_n_steps; @@ -499,7 +507,7 @@ fn test_max_fee_limit_validate( constructor_calldata: calldata![ctor_grind_arg, ctor_storage_arg], }, ); - deploy_account_tx.execute(&mut state, &block_context, true, true).unwrap(); + deploy_account_tx.execute(&mut state, &block_context).unwrap(); // Invoke a function that grinds validate (any function will do); set bounds low enough to fail // on this grind. @@ -745,7 +753,7 @@ fn test_fail_deploy_account( let initial_balance = state.get_fee_token_balance(deploy_address, fee_token_address).unwrap(); - let error = deploy_account_tx.execute(state, &block_context, true, true).unwrap_err(); + let error = deploy_account_tx.execute(state, &block_context).unwrap_err(); // Check the error is as expected. Assure the error message is not nonce or fee related. check_tx_execution_error_for_invalid_scenario!(cairo_version, error, false); @@ -785,7 +793,7 @@ fn test_fail_declare(block_context: BlockContext, max_fee: Fee) { }; let declare_account_tx = AccountTransaction { tx: ApiExecutableTransaction::Declare(executable_declare), - only_query: false, + execution_flags: AccountExecutionFlags::default(), }; // Fail execution, assert nonce and balance are unchanged. @@ -793,7 +801,7 @@ fn test_fail_declare(block_context: BlockContext, max_fee: Fee) { let initial_balance = state .get_fee_token_balance(account_address, chain_info.fee_token_address(&tx_info.fee_type())) .unwrap(); - declare_account_tx.execute(&mut state, &block_context, true, true).unwrap_err(); + declare_account_tx.execute(&mut state, &block_context).unwrap_err(); assert_eq!(state.get_nonce_at(account_address).unwrap(), next_nonce); assert_eq!( @@ -1131,7 +1139,7 @@ fn test_max_fee_to_max_steps_conversion( let tx_context1 = Arc::new(block_context.to_tx_context(&account_tx1)); let execution_context1 = EntryPointExecutionContext::new_invoke(tx_context1, true); let max_steps_limit1 = execution_context1.vm_run_resources.get_n_steps(); - let tx_execution_info1 = account_tx1.execute(&mut state, &block_context, true, true).unwrap(); + let tx_execution_info1 = account_tx1.execute(&mut state, &block_context).unwrap(); let n_steps1 = tx_execution_info1.receipt.resources.computation.vm_resources.n_steps; let gas_used_vector1 = tx_execution_info1.receipt.resources.to_gas_vector( &block_context.versioned_constants, @@ -1152,7 +1160,7 @@ fn test_max_fee_to_max_steps_conversion( let tx_context2 = Arc::new(block_context.to_tx_context(&account_tx2)); let execution_context2 = EntryPointExecutionContext::new_invoke(tx_context2, true); let max_steps_limit2 = execution_context2.vm_run_resources.get_n_steps(); - let tx_execution_info2 = account_tx2.execute(&mut state, &block_context, true, true).unwrap(); + let tx_execution_info2 = account_tx2.execute(&mut state, &block_context).unwrap(); let n_steps2 = tx_execution_info2.receipt.resources.computation.vm_resources.n_steps; let gas_used_vector2 = tx_execution_info2.receipt.resources.to_gas_vector( &block_context.versioned_constants, @@ -1292,7 +1300,7 @@ fn test_deploy_account_constructor_storage_write( constructor_calldata: constructor_calldata.clone(), }, ); - deploy_account_tx.execute(state, &block_context, true, true).unwrap(); + deploy_account_tx.execute(state, &block_context).unwrap(); // Check that the constructor wrote ctor_arg to the storage. let storage_key = get_storage_var_address("ctor_arg", &[]); @@ -1364,8 +1372,7 @@ fn test_count_actual_storage_changes( nonce: nonce_manager.next(account_address), }; let account_tx = account_invoke_tx(invoke_args.clone()); - let execution_flags = - ExecutionFlags { charge_fee: true, validate: true, concurrency_mode: false }; + let execution_flags = ExecutionFlags { concurrency_mode: false }; let execution_info = account_tx.execute_raw(&mut state, &block_context, execution_flags).unwrap(); @@ -1535,8 +1542,7 @@ fn test_concurrency_execute_fee_transfer( // Case 1: The transaction did not read form/ write to the sequenser balance before executing // fee transfer. let mut transactional_state = TransactionalState::create_transactional(state); - let execution_flags = - ExecutionFlags { charge_fee: true, validate: true, concurrency_mode: true }; + let execution_flags = ExecutionFlags { concurrency_mode: true }; let result = account_tx.execute_raw(&mut transactional_state, &block_context, execution_flags).unwrap(); assert!(!result.is_reverted()); @@ -1631,8 +1637,7 @@ fn test_concurrent_fee_transfer_when_sender_is_sequencer( let fee_token_address = block_context.chain_info.fee_token_address(fee_type); let mut transactional_state = TransactionalState::create_transactional(state); - let execution_flags = - ExecutionFlags { charge_fee: true, validate: true, concurrency_mode: true }; + let execution_flags = ExecutionFlags { concurrency_mode: true }; let result = account_tx.execute_raw(&mut transactional_state, &block_context, execution_flags).unwrap(); assert!(!result.is_reverted()); @@ -1680,7 +1685,7 @@ fn test_initial_gas( version: TransactionVersion::THREE }); - let transaction_ex_info = account_tx.execute(state, &block_context, true, true).unwrap(); + let transaction_ex_info = account_tx.execute(state, &block_context).unwrap(); let validate_call_info = &transaction_ex_info.validate_call_info.unwrap(); let validate_initial_gas = validate_call_info.call.initial_gas; @@ -1763,8 +1768,9 @@ fn test_revert_in_execute( resource_bounds: default_all_resource_bounds, ..tx_args }); - let account_tx = AccountTransaction { tx, only_query: false }; - let tx_execution_info = account_tx.execute(state, &block_context, true, validate).unwrap(); + let execution_flags = AccountExecutionFlags { validate, ..AccountExecutionFlags::default() }; + let account_tx = AccountTransaction { tx, execution_flags }; + let tx_execution_info = account_tx.execute(state, &block_context).unwrap(); assert!(tx_execution_info.is_reverted()); assert!( diff --git a/crates/blockifier/src/transaction/execution_flavors_test.rs b/crates/blockifier/src/transaction/execution_flavors_test.rs index 202197cc12..d369fc0d09 100644 --- a/crates/blockifier/src/transaction/execution_flavors_test.rs +++ b/crates/blockifier/src/transaction/execution_flavors_test.rs @@ -38,7 +38,7 @@ use crate::test_utils::{ DEFAULT_STRK_L1_GAS_PRICE, MAX_FEE, }; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use crate::transaction::errors::{ TransactionExecutionError, TransactionFeeError, @@ -226,8 +226,9 @@ fn test_invalid_nonce_pre_validate( let invalid_nonce = nonce!(7_u8); let account_nonce = state.get_nonce_at(account_address).unwrap(); let tx = invoke_tx(invoke_tx_args! {nonce: invalid_nonce, ..pre_validation_base_args}); - let account_tx = AccountTransaction { tx, only_query }; - let result = account_tx.execute(&mut state, &block_context, charge_fee, validate); + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; + let account_tx = AccountTransaction { tx, execution_flags }; + let result = account_tx.execute(&mut state, &block_context); assert_matches!( result.unwrap_err(), TransactionExecutionError::TransactionPreValidationError( @@ -268,9 +269,10 @@ fn test_simulate_validate_pre_validate_with_charge_fee( max_fee: Fee(10), resource_bounds: l1_resource_bounds(10_u8.into(), 10_u8.into()), nonce: nonce_manager.next(account_address), + ..pre_validation_base_args.clone() }) - .execute(&mut state, &block_context, charge_fee, validate) + .execute(&mut state, &block_context) .unwrap_err(); nonce_manager.rollback(account_address); @@ -307,8 +309,11 @@ fn test_simulate_validate_pre_validate_with_charge_fee( ..pre_validation_base_args.clone() }); - let account_tx = AccountTransaction { tx, only_query }; - let result = account_tx.execute(&mut state, &block_context, charge_fee, validate); + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let result = account_tx.execute(&mut state, &block_context); nonce_manager.rollback(account_address); if is_deprecated { @@ -340,8 +345,11 @@ fn test_simulate_validate_pre_validate_with_charge_fee( ..pre_validation_base_args }); - let account_tx = AccountTransaction { tx, only_query }; - let err = account_tx.execute(&mut state, &block_context, charge_fee, validate).unwrap_err(); + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let err = account_tx.execute(&mut state, &block_context).unwrap_err(); nonce_manager.rollback(account_address); assert_matches!( @@ -378,10 +386,11 @@ fn test_simulate_validate_pre_validate_not_charge_fee( nonce: nonce_manager.next(account_address), ..pre_validation_base_args.clone() }); - let account_tx = AccountTransaction { tx, only_query }; - let tx_execution_info = - account_tx.execute(&mut state, &block_context, charge_fee, false).unwrap(); - + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate: false }, + }; + let tx_execution_info = account_tx.execute(&mut state, &block_context).unwrap(); let base_gas = calculate_actual_gas(&tx_execution_info, &block_context, false); assert!( base_gas @@ -402,10 +411,11 @@ fn test_simulate_validate_pre_validate_not_charge_fee( ..pre_validation_base_args.clone() }); - let account_tx = AccountTransaction { tx, only_query }; - let tx_execution_info = - account_tx.execute(&mut state, &block_context, charge_fee, validate).unwrap(); - + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let tx_execution_info = account_tx.execute(&mut state, &block_context).unwrap(); check_gas_and_fee( &block_context, &tx_execution_info, @@ -470,8 +480,11 @@ fn execute_fail_validation( version, nonce: nonce_manager.next(faulty_account_address), }); - let account_tx = AccountTransaction { tx, only_query }; - account_tx.execute(&mut falliable_state, &block_context, charge_fee, validate) + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + account_tx.execute(&mut falliable_state, &block_context) } /// Test simulate / charge_fee flag combinations in (fallible) validation stage. @@ -593,9 +606,11 @@ fn test_simulate_validate_charge_fee_mid_execution( only_query, ..execution_base_args.clone() }); - let account_tx = AccountTransaction { tx, only_query }; - let tx_execution_info = - account_tx.execute(&mut state, &block_context, charge_fee, validate).unwrap(); + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let tx_execution_info = account_tx.execute(&mut state, &block_context).unwrap(); let base_gas = calculate_actual_gas(&tx_execution_info, &block_context, validate); let (revert_gas_used, revert_fee) = gas_and_fee(base_gas, validate, &fee_type); assert!( @@ -644,10 +659,11 @@ fn test_simulate_validate_charge_fee_mid_execution( ..execution_base_args.clone() }); - let account_tx = AccountTransaction { tx, only_query }; - let tx_execution_info = - account_tx.execute(&mut state, &block_context, charge_fee, validate).unwrap(); - + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let tx_execution_info = account_tx.execute(&mut state, &block_context).unwrap(); assert_eq!(tx_execution_info.is_reverted(), charge_fee); if charge_fee { assert!( @@ -692,6 +708,7 @@ fn test_simulate_validate_charge_fee_mid_execution( GasVector::from_l1_gas(block_limit_gas), &fee_type, ); + let tx = invoke_tx(invoke_tx_args! { max_fee: huge_fee, resource_bounds: l1_resource_bounds(huge_gas_limit, gas_price.into()), @@ -699,10 +716,11 @@ fn test_simulate_validate_charge_fee_mid_execution( nonce: nonce_manager.next(account_address), ..execution_base_args }); - let account_tx = AccountTransaction { tx, only_query }; - let tx_execution_info = - account_tx.execute(&mut state, &low_step_block_context, charge_fee, validate).unwrap(); - + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let tx_execution_info = account_tx.execute(&mut state, &low_step_block_context).unwrap(); assert!( tx_execution_info.revert_error.clone().unwrap().to_string().contains("no remaining steps") ); @@ -788,10 +806,11 @@ fn test_simulate_validate_charge_fee_post_execution( version, only_query, }); - let account_tx = AccountTransaction { tx, only_query }; - let tx_execution_info = - account_tx.execute(&mut state, &block_context, charge_fee, validate).unwrap(); - + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let tx_execution_info = account_tx.execute(&mut state, &block_context).unwrap(); assert_eq!(tx_execution_info.is_reverted(), charge_fee); if charge_fee { let expected_error_prefix = @@ -851,10 +870,11 @@ fn test_simulate_validate_charge_fee_post_execution( only_query, }); - let account_tx = AccountTransaction { tx, only_query }; - let tx_execution_info = - account_tx.execute(&mut state, &block_context, charge_fee, validate).unwrap(); - + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { only_query, charge_fee, validate }, + }; + let tx_execution_info = account_tx.execute(&mut state, &block_context).unwrap(); assert_eq!(tx_execution_info.is_reverted(), charge_fee); if charge_fee { diff --git a/crates/blockifier/src/transaction/post_execution_test.rs b/crates/blockifier/src/transaction/post_execution_test.rs index 3975763403..ed8e3df15b 100644 --- a/crates/blockifier/src/transaction/post_execution_test.rs +++ b/crates/blockifier/src/transaction/post_execution_test.rs @@ -134,8 +134,7 @@ fn test_revert_on_overdraft( nonce: nonce_manager.next(account_address), }); let tx_info = approve_tx.create_tx_info(); - let approval_execution_info = - approve_tx.execute(&mut state, &block_context, true, true).unwrap(); + let approval_execution_info = approve_tx.execute(&mut state, &block_context).unwrap(); assert!(!approval_execution_info.is_reverted()); // Transfer a valid amount of funds to compute the cost of a successful diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index 07ff2ba797..ad304c0cf5 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -42,10 +42,10 @@ use crate::test_utils::{ DEFAULT_STRK_L2_GAS_PRICE, MAX_FEE, }; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use crate::transaction::objects::{TransactionExecutionInfo, TransactionExecutionResult}; use crate::transaction::transaction_types::TransactionType; -use crate::transaction::transactions::ExecutableTransaction; +use crate::transaction::transactions::{enforce_fee, ExecutableTransaction}; // Corresponding constants to the ones in faulty_account. pub const VALID: u64 = 0; @@ -115,7 +115,7 @@ pub fn deploy_and_fund_account( // Deploy an account contract. let deploy_account_tx = AccountTransaction { tx: deploy_account_tx(deploy_tx_args, nonce_manager), - only_query: false, + execution_flags: ExecutionFlags::default(), }; let account_address = deploy_account_tx.sender_address(); @@ -165,6 +165,9 @@ pub struct FaultyAccountTxCreatorArgs { pub validate_constructor: bool, // Should be used with tx_type Declare. pub declared_contract: Option, + pub validate: bool, + pub only_query: bool, + pub charge_fee: bool, } impl Default for FaultyAccountTxCreatorArgs { @@ -181,6 +184,9 @@ impl Default for FaultyAccountTxCreatorArgs { max_fee: Fee::default(), resource_bounds: ValidResourceBounds::create_for_testing_no_fee_enforcement(), declared_contract: None, + validate: true, + only_query: false, + charge_fee: true, } } } @@ -217,6 +223,9 @@ pub fn create_account_tx_for_validate_test( max_fee, resource_bounds, declared_contract, + validate, + only_query, + charge_fee, } = faulty_account_tx_creator_args; // The first felt of the signature is used to set the scenario. If the scenario is @@ -226,7 +235,7 @@ pub fn create_account_tx_for_validate_test( signature_vector.extend(additional_data); } let signature = TransactionSignature(signature_vector); - + let execution_flags = ExecutionFlags { validate, charge_fee, only_query }; match tx_type { TransactionType::Declare => { let declared_contract = match declared_contract { @@ -251,7 +260,7 @@ pub fn create_account_tx_for_validate_test( }, class_info, ); - AccountTransaction { tx, only_query: false } + AccountTransaction { tx, execution_flags } } TransactionType::DeployAccount => { // We do not use the sender address here because the transaction generates the actual @@ -272,7 +281,7 @@ pub fn create_account_tx_for_validate_test( }, nonce_manager, ); - AccountTransaction { tx, only_query: false } + AccountTransaction { tx, execution_flags } } TransactionType::InvokeFunction => { let execute_calldata = create_calldata(sender_address, "foo", &[]); @@ -284,8 +293,9 @@ pub fn create_account_tx_for_validate_test( calldata: execute_calldata, version: tx_version, nonce: nonce_manager.next(sender_address), + }); - AccountTransaction { tx, only_query: false } + AccountTransaction { tx, execution_flags } } _ => panic!("{tx_type:?} is not an account transaction."), } @@ -294,7 +304,8 @@ pub fn create_account_tx_for_validate_test( // TODO(AvivG): Consider removing this function. pub fn account_invoke_tx(invoke_args: InvokeTxArgs) -> AccountTransaction { let only_query = invoke_args.only_query; - AccountTransaction { tx: invoke_tx(invoke_args), only_query } + let execution_flags = ExecutionFlags { only_query, ..ExecutionFlags::default() }; + AccountTransaction { tx: invoke_tx(invoke_args), execution_flags } } pub fn run_invoke_tx( @@ -304,10 +315,11 @@ pub fn run_invoke_tx( ) -> TransactionExecutionResult { let only_query = invoke_args.only_query; let tx = invoke_tx(invoke_args); - let account_tx = AccountTransaction { tx, only_query }; - let charge_fee = account_tx.enforce_fee(); + let charge_fee = enforce_fee(&tx, only_query); + let execution_flags = ExecutionFlags { charge_fee, only_query, ..ExecutionFlags::default() }; + let account_tx = AccountTransaction { tx, execution_flags }; - account_tx.execute(state, block_context, charge_fee, true) + account_tx.execute(state, block_context) } /// Creates a `ResourceBoundsMapping` with the given `max_amount` and `max_price` for L1 gas limits. @@ -382,6 +394,9 @@ pub fn emit_n_events_tx( calldata, nonce }); + let only_query = false; + let charge_fee = enforce_fee(&tx, only_query); + let execution_flags = ExecutionFlags { only_query, charge_fee, ..ExecutionFlags::default() }; - AccountTransaction { tx, only_query: false } + AccountTransaction { tx, execution_flags } } diff --git a/crates/blockifier/src/transaction/transaction_execution.rs b/crates/blockifier/src/transaction/transaction_execution.rs index d305e0bdb8..93c3ef5f0a 100644 --- a/crates/blockifier/src/transaction/transaction_execution.rs +++ b/crates/blockifier/src/transaction/transaction_execution.rs @@ -19,7 +19,10 @@ use crate::execution::entry_point::EntryPointExecutionContext; use crate::fee::receipt::TransactionReceipt; use crate::state::cached_state::TransactionalState; use crate::state::state_api::UpdatableState; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{ + AccountTransaction, + ExecutionFlags as AccountExecutionFlags, +}; use crate::transaction::errors::TransactionFeeError; use crate::transaction::objects::{ TransactionExecutionInfo, @@ -40,7 +43,10 @@ impl From for Transaction { fn from(value: starknet_api::executable_transaction::Transaction) -> Self { match value { starknet_api::executable_transaction::Transaction::Account(tx) => { - Transaction::Account(AccountTransaction { tx, only_query: false }) + Transaction::Account(AccountTransaction { + tx, + execution_flags: AccountExecutionFlags::default(), + }) } starknet_api::executable_transaction::Transaction::L1Handler(tx) => { Transaction::L1Handler(tx) @@ -77,7 +83,7 @@ impl Transaction { class_info: Option, paid_fee_on_l1: Option, deployed_contract_address: Option, - only_query: bool, + execution_flags: AccountExecutionFlags, ) -> TransactionExecutionResult { let executable_tx = match tx { StarknetApiTransaction::L1Handler(l1_handler) => { @@ -119,7 +125,7 @@ impl Transaction { } _ => unimplemented!(), }; - Ok(AccountTransaction { tx: executable_tx, only_query }.into()) + Ok(AccountTransaction { tx: executable_tx, execution_flags }.into()) } } diff --git a/crates/blockifier/src/transaction/transactions.rs b/crates/blockifier/src/transaction/transactions.rs index 106423c1c3..8f30f658ff 100644 --- a/crates/blockifier/src/transaction/transactions.rs +++ b/crates/blockifier/src/transaction/transactions.rs @@ -53,8 +53,6 @@ mod test; #[derive(Clone, Copy, Debug)] pub struct ExecutionFlags { - pub charge_fee: bool, - pub validate: bool, pub concurrency_mode: bool, } @@ -65,12 +63,10 @@ pub trait ExecutableTransaction: Sized { &self, state: &mut U, block_context: &BlockContext, - charge_fee: bool, - validate: bool, ) -> TransactionExecutionResult { log::debug!("Executing Transaction..."); let mut transactional_state = TransactionalState::create_transactional(state); - let execution_flags = ExecutionFlags { charge_fee, validate, concurrency_mode: false }; + let execution_flags = ExecutionFlags { concurrency_mode: false }; let execution_result = self.execute_raw(&mut transactional_state, block_context, execution_flags); diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index a5d8511b2a..b292fac224 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -116,7 +116,7 @@ use crate::test_utils::{ MAX_FEE, TEST_SEQUENCER_ADDRESS, }; -use crate::transaction::account_transaction::AccountTransaction; +use crate::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use crate::transaction::errors::{ TransactionExecutionError, TransactionFeeError, @@ -454,7 +454,8 @@ fn test_invoke_tx( calldata: Calldata(Arc::clone(&calldata.0)), resource_bounds, }); - let invoke_tx = AccountTransaction { tx, only_query: false }; + let execution_flags = ExecutionFlags::default(); + let invoke_tx = AccountTransaction { tx, execution_flags }; // Extract invoke transaction fields for testing, as it is consumed when creating an account // transaction. @@ -477,7 +478,7 @@ fn test_invoke_tx( let tx_context = block_context.to_tx_context(&invoke_tx); - let actual_execution_info = invoke_tx.execute(state, block_context, true, true).unwrap(); + let actual_execution_info = invoke_tx.execute(state, block_context).unwrap(); let tracked_resource = account_contract.get_runnable_class().tracked_resource( &versioned_constants.min_compiler_version_for_sierra_gas, @@ -677,7 +678,7 @@ fn test_invoke_tx_advanced_operations( create_calldata(contract_address, "advance_counter", &calldata_args), ..base_tx_args.clone() }); - account_tx.execute(state, block_context, true, true).unwrap(); + account_tx.execute(state, block_context).unwrap(); let next_nonce = nonce_manager.next(account_address); let initial_ec_point = [Felt::ZERO, Felt::ZERO]; @@ -702,7 +703,7 @@ fn test_invoke_tx_advanced_operations( create_calldata(contract_address, "call_xor_counters", &calldata_args), ..base_tx_args.clone() }); - account_tx.execute(state, block_context, true, true).unwrap(); + account_tx.execute(state, block_context).unwrap(); let expected_counters = [felt!(counter_diffs[0] ^ xor_values[0]), felt!(counter_diffs[1] ^ xor_values[1])]; @@ -724,7 +725,7 @@ fn test_invoke_tx_advanced_operations( create_calldata(contract_address, "test_ec_op", &[]), ..base_tx_args.clone() }); - account_tx.execute(state, block_context, true, true).unwrap(); + account_tx.execute(state, block_context).unwrap(); let expected_ec_point = [ Felt::from_bytes_be(&[ @@ -762,7 +763,7 @@ fn test_invoke_tx_advanced_operations( create_calldata(contract_address, "add_signature_to_counters", &[index]), ..base_tx_args.clone() }); - account_tx.execute(state, block_context, true, true).unwrap(); + account_tx.execute(state, block_context).unwrap(); let expected_counters = [ (expected_counters[0] + signature_values[0]), @@ -787,7 +788,7 @@ fn test_invoke_tx_advanced_operations( create_calldata(contract_address, "send_message", &[to_address]), ..base_tx_args }); - let execution_info = account_tx.execute(state, block_context, true, true).unwrap(); + let execution_info = account_tx.execute(state, block_context).unwrap(); let next_nonce = nonce_manager.next(account_address); verify_storage_after_invoke_advanced_operations( state, @@ -851,7 +852,7 @@ fn test_state_get_fee_token_balance( version: tx_version, nonce: Nonce::default(), }); - account_tx.execute(state, block_context, true, true).unwrap(); + account_tx.execute(state, block_context).unwrap(); // Get balance from state, and validate. let (low, high) = @@ -866,7 +867,7 @@ fn assert_resource_bounds_exceed_balance_failure( block_context: &BlockContext, invalid_tx: AccountTransaction, ) { - let tx_error = invalid_tx.execute(state, block_context, true, true).unwrap_err(); + let tx_error = invalid_tx.execute(state, block_context).unwrap_err(); match invalid_tx.create_tx_info() { TransactionInfo::Deprecated(context) => { assert_matches!( @@ -976,7 +977,7 @@ fn test_max_fee_exceeds_balance( }, &mut NonceManager::default(), ), - only_query: false, + execution_flags: ExecutionFlags::default(), }; assert_resource_bounds_exceed_balance_failure(state, block_context, invalid_tx); @@ -1011,7 +1012,7 @@ fn test_max_fee_exceeds_balance( }, class_info, ), - only_query: false, + execution_flags: ExecutionFlags::default(), }; assert_resource_bounds_exceed_balance_failure(state, block_context, invalid_tx); }; @@ -1114,7 +1115,7 @@ fn test_insufficient_new_resource_bounds_pre_validation( resource_bounds: ValidResourceBounds::AllResources(default_resource_bounds), ..valid_invoke_tx_args.clone() }) - .execute(state, block_context, true, true); + .execute(state, block_context); let next_nonce = match valid_resources_tx { Ok(_) => 1, @@ -1156,7 +1157,7 @@ fn test_insufficient_new_resource_bounds_pre_validation( nonce: nonce!(next_nonce), ..valid_invoke_tx_args.clone() }); - let execution_error = invalid_v3_tx.execute(state, block_context, true, true).unwrap_err(); + let execution_error = invalid_v3_tx.execute(state, block_context).unwrap_err(); assert_matches!( execution_error, TransactionExecutionError::TransactionPreValidationError( @@ -1182,7 +1183,7 @@ fn test_insufficient_new_resource_bounds_pre_validation( nonce: nonce!(next_nonce), ..valid_invoke_tx_args.clone() }); - let execution_error = invalid_v3_tx.execute(state, block_context, true, true).unwrap_err(); + let execution_error = invalid_v3_tx.execute(state, block_context).unwrap_err(); assert_matches!( execution_error, TransactionExecutionError::TransactionPreValidationError( @@ -1230,7 +1231,7 @@ fn test_insufficient_deprecated_resource_bounds_pre_validation( let invalid_v1_tx = account_invoke_tx( invoke_tx_args! { max_fee: invalid_max_fee, version: TransactionVersion::ONE, ..valid_invoke_tx_args.clone() }, ); - let execution_error = invalid_v1_tx.execute(state, block_context, true, true).unwrap_err(); + let execution_error = invalid_v1_tx.execute(state, block_context).unwrap_err(); // Test error. assert_matches!( @@ -1251,7 +1252,7 @@ fn test_insufficient_deprecated_resource_bounds_pre_validation( resource_bounds: l1_resource_bounds(insufficient_max_l1_gas_amount, actual_strk_l1_gas_price.into()), ..valid_invoke_tx_args.clone() }); - let execution_error = invalid_v3_tx.execute(state, block_context, true, true).unwrap_err(); + let execution_error = invalid_v3_tx.execute(state, block_context).unwrap_err(); assert_matches!( execution_error, TransactionExecutionError::TransactionPreValidationError( @@ -1270,7 +1271,7 @@ fn test_insufficient_deprecated_resource_bounds_pre_validation( resource_bounds: l1_resource_bounds(minimal_l1_gas, insufficient_max_l1_gas_price), ..valid_invoke_tx_args.clone() }); - let execution_error = invalid_v3_tx.execute(state, block_context, true, true).unwrap_err(); + let execution_error = invalid_v3_tx.execute(state, block_context).unwrap_err(); assert_matches!( execution_error, TransactionExecutionError::TransactionPreValidationError( @@ -1318,7 +1319,7 @@ fn test_actual_fee_gt_resource_bounds( // Execute the tx to compute the final gas costs. let tx = &account_invoke_tx(tx_args.clone()); - let execution_result = tx.execute(state, block_context, true, true).unwrap(); + let execution_result = tx.execute(state, block_context).unwrap(); let mut actual_gas = execution_result.receipt.gas; // Create new gas bounds that are lower than the actual gas. @@ -1351,7 +1352,7 @@ fn test_actual_fee_gt_resource_bounds( ), nonce: nonce_manager.next(sender_address1), }); - let execution_result = invalid_tx.execute(state, block_context, true, true).unwrap(); + let execution_result = invalid_tx.execute(state, block_context).unwrap(); let execution_error = execution_result.revert_error.unwrap(); // Test error and that fee was charged. Should be at most the fee charged in a successful @@ -1527,7 +1528,7 @@ fn test_declare_tx( }, class_info.clone(), ); - let account_tx = AccountTransaction { tx, only_query: false }; + let account_tx = AccountTransaction { tx, execution_flags: ExecutionFlags::default() }; // Check state before transaction application. assert_matches!( @@ -1537,7 +1538,7 @@ fn test_declare_tx( ); let fee_type = &account_tx.fee_type(); let tx_context = &block_context.to_tx_context(&account_tx); - let actual_execution_info = account_tx.execute(state, block_context, true, true).unwrap(); + let actual_execution_info = account_tx.execute(state, block_context).unwrap(); assert_eq!(actual_execution_info.revert_error, None); // Build expected validate call info. @@ -1649,8 +1650,8 @@ fn test_declare_tx( }, class_info.clone(), ); - let account_tx2 = AccountTransaction { tx: tx2, only_query: false }; - let result = account_tx2.execute(state, block_context, true, true); + let account_tx2 = AccountTransaction { tx: tx2, execution_flags: ExecutionFlags::default() }; + let result = account_tx2.execute(state, block_context); assert_matches!( result.unwrap_err(), TransactionExecutionError::DeclareTransactionError{ class_hash:already_declared_class_hash } if @@ -1684,9 +1685,12 @@ fn test_declare_tx_v0(default_l1_resource_bounds: ValidResourceBounds) { }, class_info.clone(), ); - let account_tx = AccountTransaction { tx, only_query: false }; + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { charge_fee: false, ..ExecutionFlags::default() }, + }; - let actual_execution_info = account_tx.execute(state, block_context, false, true).unwrap(); // fee not charged for declare v0. + let actual_execution_info = account_tx.execute(state, block_context).unwrap(); // fee not charged for declare v0. assert_eq!(actual_execution_info.fee_transfer_call_info, None, "not none"); assert_eq!(actual_execution_info.receipt.fee, Fee(0)); @@ -1713,7 +1717,7 @@ fn test_deploy_account_tx( }, &mut nonce_manager, ), - only_query: false, + execution_flags: ExecutionFlags::default(), }; // Extract deploy account transaction fields for testing, as it is consumed when creating an @@ -1737,7 +1741,7 @@ fn test_deploy_account_tx( let fee_type = &deploy_account.fee_type(); let tx_context = &block_context.to_tx_context(&deploy_account); - let actual_execution_info = deploy_account.execute(state, block_context, true, true).unwrap(); + let actual_execution_info = deploy_account.execute(state, block_context).unwrap(); // Build expected validate call info. let validate_calldata = if let ApiExecutableTransaction::DeployAccount(tx) = &deploy_account.tx @@ -1873,9 +1877,9 @@ fn test_deploy_account_tx( }, &mut nonce_manager, ), - only_query: false, + execution_flags: ExecutionFlags::default(), }; - let error = deploy_account.execute(state, block_context, true, true).unwrap_err(); + let error = deploy_account.execute(state, block_context).unwrap_err(); assert_matches!( error, TransactionExecutionError::ContractConstructorExecutionFailed( @@ -1906,7 +1910,7 @@ fn test_fail_deploy_account_undeclared_class_hash( }, &mut nonce_manager, ), - only_query: false, + execution_flags: ExecutionFlags::default(), }; let tx_context = block_context.to_tx_context(&deploy_account); let fee_type = tx_context.tx_info.fee_type(); @@ -1920,7 +1924,7 @@ fn test_fail_deploy_account_undeclared_class_hash( ) .unwrap(); - let error = deploy_account.execute(state, block_context, true, true).unwrap_err(); + let error = deploy_account.execute(state, block_context).unwrap_err(); assert_matches!( error, TransactionExecutionError::ContractConstructorExecutionFailed( @@ -1968,6 +1972,8 @@ fn test_validate_accounts_tx( sender_address, class_hash, validate_constructor, + validate: true, + charge_fee: false, // We test `__validate__`, and don't care about the charge fee flow. ..Default::default() }; @@ -1980,10 +1986,8 @@ fn test_validate_accounts_tx( additional_data: None, ..default_args }); - // We test `__validate__`, and don't care about the cahrge fee flow. - let charge_fee = false; - let error = account_tx.execute(state, block_context, charge_fee, true).unwrap_err(); + let error = account_tx.execute(state, block_context).unwrap_err(); check_tx_execution_error_for_invalid_scenario!(cairo_version, error, validate_constructor,); // Try to call another contract (forbidden). @@ -1996,7 +2000,7 @@ fn test_validate_accounts_tx( resource_bounds: ValidResourceBounds::create_for_testing_no_fee_enforcement(), ..default_args }); - let error = account_tx.execute(state, block_context, charge_fee, true).unwrap_err(); + let error = account_tx.execute(state, block_context).unwrap_err(); check_tx_execution_error_for_custom_hint!( &error, "Unauthorized syscall call_contract in execution mode Validate.", @@ -2012,7 +2016,7 @@ fn test_validate_accounts_tx( resource_bounds: ValidResourceBounds::create_for_testing_no_fee_enforcement(), ..default_args }); - let error = account_tx.execute(state, block_context, charge_fee, true).unwrap_err(); + let error = account_tx.execute(state, block_context).unwrap_err(); check_tx_execution_error_for_custom_hint!( &error, "Unauthorized syscall get_block_hash in execution mode Validate.", @@ -2027,7 +2031,7 @@ fn test_validate_accounts_tx( resource_bounds: ValidResourceBounds::create_for_testing_no_fee_enforcement(), ..default_args }); - let error = account_tx.execute(state, block_context, charge_fee, true).unwrap_err(); + let error = account_tx.execute(state, block_context).unwrap_err(); check_tx_execution_error_for_custom_hint!( &error, "Unauthorized syscall get_sequencer_address in execution mode Validate.", @@ -2051,7 +2055,7 @@ fn test_validate_accounts_tx( ..default_args }, ); - let result = account_tx.execute(state, block_context, charge_fee, true); + let result = account_tx.execute(state, block_context); assert!(result.is_ok(), "Execution failed: {:?}", result.unwrap_err()); if tx_type != TransactionType::DeployAccount { @@ -2068,7 +2072,7 @@ fn test_validate_accounts_tx( ..default_args }, ); - let result = account_tx.execute(state, block_context, charge_fee, true); + let result = account_tx.execute(state, block_context); assert!(result.is_ok(), "Execution failed: {:?}", result.unwrap_err()); } @@ -2088,7 +2092,7 @@ fn test_validate_accounts_tx( ..default_args }, ); - let result = account_tx.execute(state, block_context, charge_fee, true); + let result = account_tx.execute(state, block_context); assert!(result.is_ok(), "Execution failed: {:?}", result.unwrap_err()); // Call the syscall get_block_timestamp and assert the returned timestamp was modified @@ -2104,7 +2108,7 @@ fn test_validate_accounts_tx( ..default_args }, ); - let result = account_tx.execute(state, block_context, charge_fee, true); + let result = account_tx.execute(state, block_context); assert!(result.is_ok(), "Execution failed: {:?}", result.unwrap_err()); } @@ -2126,7 +2130,7 @@ fn test_validate_accounts_tx( ..default_args }, ); - let result = account_tx.execute(state, block_context, charge_fee, true); + let result = account_tx.execute(state, block_context); assert!(result.is_ok(), "Execution failed: {:?}", result.unwrap_err()); } } @@ -2152,9 +2156,12 @@ fn test_valid_flag( calldata: create_trivial_calldata(test_contract.get_instance_address(0)), resource_bounds: default_all_resource_bounds, }); - let account_tx = AccountTransaction { tx, only_query: false }; + let account_tx = AccountTransaction { + tx, + execution_flags: ExecutionFlags { validate: false, ..ExecutionFlags::default() }, + }; - let actual_execution_info = account_tx.execute(state, block_context, true, false).unwrap(); + let actual_execution_info = account_tx.execute(state, block_context).unwrap(); assert!(actual_execution_info.validate_call_info.is_none()); } @@ -2253,9 +2260,10 @@ fn test_only_query_flag( sender_address, only_query, }); - let invoke_tx = AccountTransaction { tx, only_query }; + let execution_flags = ExecutionFlags { only_query, ..Default::default() }; + let invoke_tx = AccountTransaction { tx, execution_flags }; - let tx_execution_info = invoke_tx.execute(state, block_context, true, true).unwrap(); + let tx_execution_info = invoke_tx.execute(state, block_context).unwrap(); assert_eq!(tx_execution_info.revert_error, None); } @@ -2273,7 +2281,7 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) { let key = calldata.0[1]; let value = calldata.0[2]; let payload_size = tx.payload_size(); - let actual_execution_info = tx.execute(state, block_context, false, true).unwrap(); // Do not charge fee as L1Handler's resource bounds (/max fee) is 0. + let actual_execution_info = tx.execute(state, block_context).unwrap(); // Build the expected call info. let accessed_storage_key = StorageKey::try_from(key).unwrap(); @@ -2405,7 +2413,7 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) { // always uptade the storage instad. state.set_storage_at(contract_address, StorageKey::try_from(key).unwrap(), Felt::ZERO).unwrap(); let tx_no_fee = l1handler_tx(Fee(0), contract_address); - let error = tx_no_fee.execute(state, block_context, false, true).unwrap_err(); // Do not charge fee as L1Handler's resource bounds (/max fee) is 0. + let error = tx_no_fee.execute(state, block_context).unwrap_err(); // Do not charge fee as L1Handler's resource bounds (/max fee) is 0. // Today, we check that the paid_fee is positive, no matter what was the actual fee. let expected_actual_fee = get_fee_by_gas_vector(&block_context.block_info, total_gas, &FeeType::Eth); @@ -2442,7 +2450,7 @@ fn test_execute_tx_with_invalid_tx_version( calldata, }); - let execution_info = account_tx.execute(state, block_context, true, true).unwrap(); + let execution_info = account_tx.execute(state, block_context).unwrap(); assert!( execution_info .revert_error @@ -2538,7 +2546,7 @@ fn test_emit_event_exceeds_limit( resource_bounds: default_all_resource_bounds, nonce: nonce!(0_u8), }); - let execution_info = account_tx.execute(state, block_context, true, true).unwrap(); + let execution_info = account_tx.execute(state, block_context).unwrap(); match &expected_error { Some(expected_error) => { let error_string = execution_info.revert_error.unwrap().to_string(); 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 a1aec7138b..2d906e1e6a 100644 --- a/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs +++ b/crates/blockifier_reexecution/src/state_reader/reexecution_state_reader.rs @@ -3,6 +3,7 @@ use blockifier::blockifier::transaction_executor::TransactionExecutor; use blockifier::state::cached_state::CommitmentStateDiff; use blockifier::state::state_api::{StateReader, StateResult}; use blockifier::test_utils::MAX_FEE; +use blockifier::transaction::account_transaction::ExecutionFlags; use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; use papyrus_execution::DEPRECATED_CONTRACT_SIERRA_SIZE; use starknet_api::block::{BlockHash, BlockNumber}; @@ -50,11 +51,19 @@ pub trait ReexecutionStateReader { &self, txs_and_hashes: Vec<(Transaction, TransactionHash)>, ) -> ReexecutionResult> { + let execution_flags = ExecutionFlags::default(); txs_and_hashes .into_iter() .map(|(tx, tx_hash)| match tx { Transaction::Invoke(_) | Transaction::DeployAccount(_) => { - Ok(BlockifierTransaction::from_api(tx, tx_hash, None, None, None, false)?) + Ok(BlockifierTransaction::from_api( + tx, + tx_hash, + None, + None, + None, + execution_flags.clone(), + )?) } Transaction::Declare(ref declare_tx) => { let class_info = self @@ -66,7 +75,7 @@ pub trait ReexecutionStateReader { Some(class_info), None, None, - false, + execution_flags.clone(), )?) } Transaction::L1Handler(_) => Ok(BlockifierTransaction::from_api( @@ -75,7 +84,7 @@ pub trait ReexecutionStateReader { None, Some(MAX_FEE), None, - false, + execution_flags.clone(), )?), Transaction::Deploy(_) => { diff --git a/crates/native_blockifier/src/py_transaction.rs b/crates/native_blockifier/src/py_transaction.rs index 65b89e81a1..8bc3fdf4b6 100644 --- a/crates/native_blockifier/src/py_transaction.rs +++ b/crates/native_blockifier/src/py_transaction.rs @@ -1,8 +1,9 @@ use std::collections::BTreeMap; -use blockifier::transaction::account_transaction::AccountTransaction; +use blockifier::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transaction_types::TransactionType; +use blockifier::transaction::transactions::enforce_fee; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; use starknet_api::block::GasPrice; @@ -136,21 +137,37 @@ pub fn py_tx( let tx_type = get_py_tx_type(tx)?; let tx_type: TransactionType = tx_type.parse().map_err(NativeBlockifierInputError::ParseError)?; + let only_query = false; Ok(match tx_type { TransactionType::Declare => { let non_optional_py_class_info: PyClassInfo = optional_py_class_info .expect("A class info must be passed in a Declare transaction."); let tx = ExecutableTransaction::Declare(py_declare(tx, non_optional_py_class_info)?); - AccountTransaction { tx, only_query: false }.into() + let execution_flags = ExecutionFlags { + only_query, + charge_fee: enforce_fee(&tx, only_query), + ..ExecutionFlags::default() + }; + AccountTransaction { tx, execution_flags }.into() } TransactionType::DeployAccount => { let tx = ExecutableTransaction::DeployAccount(py_deploy_account(tx)?); - AccountTransaction { tx, only_query: false }.into() + let execution_flags = ExecutionFlags { + only_query, + charge_fee: enforce_fee(&tx, only_query), + ..ExecutionFlags::default() + }; + AccountTransaction { tx, execution_flags }.into() } TransactionType::InvokeFunction => { let tx = ExecutableTransaction::Invoke(py_invoke_function(tx)?); - AccountTransaction { tx, only_query: false }.into() + let execution_flags = ExecutionFlags { + only_query, + charge_fee: enforce_fee(&tx, only_query), + ..ExecutionFlags::default() + }; + AccountTransaction { tx, execution_flags }.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 e982c8a8df..6eca2854a5 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -32,6 +32,7 @@ use blockifier::execution::entry_point::{ EntryPointExecutionContext, }; use blockifier::state::cached_state::CachedState; +use blockifier::transaction::account_transaction::ExecutionFlags; use blockifier::transaction::errors::TransactionExecutionError as BlockifierTransactionExecutionError; use blockifier::transaction::objects::{ DeprecatedTransactionInfo, @@ -735,10 +736,10 @@ fn execute_transactions( ) => Some(*class_hash), _ => None, }; - let blockifier_tx = to_blockifier_tx(tx, tx_hash, transaction_index)?; + let blockifier_tx = to_blockifier_tx(tx, tx_hash, transaction_index, charge_fee, validate)?; // TODO(Yoni): use the TransactionExecutor instead. let tx_execution_info_result = - blockifier_tx.execute(&mut transactional_state, &block_context, charge_fee, validate); + blockifier_tx.execute(&mut transactional_state, &block_context); let state_diff = induced_state_diff(&mut transactional_state, deprecated_declared_class_hash)?; transactional_state.commit(); @@ -797,30 +798,34 @@ fn to_blockifier_tx( tx: ExecutableTransactionInput, tx_hash: TransactionHash, transaction_index: usize, + charge_fee: bool, + validate: bool, ) -> ExecutionResult { // TODO(yair): support only_query version bit (enable in the RPC v0.6 and use the correct // value). match tx { ExecutableTransactionInput::Invoke(invoke_tx, only_query) => { + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; BlockifierTransaction::from_api( Transaction::Invoke(invoke_tx), tx_hash, None, None, None, - only_query, + execution_flags, ) .map_err(|err| ExecutionError::from((transaction_index, err))) } ExecutableTransactionInput::DeployAccount(deploy_acc_tx, only_query) => { + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; BlockifierTransaction::from_api( Transaction::DeployAccount(deploy_acc_tx), tx_hash, None, None, None, - only_query, + execution_flags, ) .map_err(|err| ExecutionError::from((transaction_index, err))) } @@ -842,13 +847,14 @@ fn to_blockifier_tx( err, })?; + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; BlockifierTransaction::from_api( Transaction::Declare(DeclareTransaction::V0(declare_tx)), tx_hash, Some(class_info), None, None, - only_query, + execution_flags, ) .map_err(|err| ExecutionError::from((transaction_index, err))) } @@ -868,13 +874,14 @@ fn to_blockifier_tx( tx: DeclareTransaction::V1(declare_tx.clone()), err, })?; + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; BlockifierTransaction::from_api( Transaction::Declare(DeclareTransaction::V1(declare_tx)), tx_hash, Some(class_info), None, None, - only_query, + execution_flags, ) .map_err(|err| ExecutionError::from((transaction_index, err))) } @@ -896,13 +903,14 @@ fn to_blockifier_tx( tx: DeclareTransaction::V2(declare_tx.clone()), err, })?; + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; BlockifierTransaction::from_api( Transaction::Declare(DeclareTransaction::V2(declare_tx)), tx_hash, Some(class_info), None, None, - only_query, + execution_flags, ) .map_err(|err| ExecutionError::from((transaction_index, err))) } @@ -924,24 +932,26 @@ fn to_blockifier_tx( tx: DeclareTransaction::V3(declare_tx.clone()), err, })?; + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; BlockifierTransaction::from_api( Transaction::Declare(DeclareTransaction::V3(declare_tx)), tx_hash, Some(class_info), None, None, - only_query, + execution_flags, ) .map_err(|err| ExecutionError::from((transaction_index, err))) } ExecutableTransactionInput::L1Handler(l1_handler_tx, paid_fee, only_query) => { + let execution_flags = ExecutionFlags { only_query, charge_fee, validate }; BlockifierTransaction::from_api( Transaction::L1Handler(l1_handler_tx), tx_hash, None, Some(paid_fee), None, - only_query, + execution_flags, ) .map_err(|err| ExecutionError::from((transaction_index, err))) } diff --git a/crates/starknet_batcher/src/block_builder.rs b/crates/starknet_batcher/src/block_builder.rs index b900f35d9c..0a53ca2ee9 100644 --- a/crates/starknet_batcher/src/block_builder.rs +++ b/crates/starknet_batcher/src/block_builder.rs @@ -15,9 +15,10 @@ use blockifier::execution::contract_class::RunnableCompiledClass; use blockifier::state::cached_state::CommitmentStateDiff; use blockifier::state::errors::StateError; use blockifier::state::global_cache::GlobalContractCache; -use blockifier::transaction::account_transaction::AccountTransaction; +use blockifier::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; use blockifier::transaction::objects::TransactionExecutionInfo; use blockifier::transaction::transaction_execution::Transaction as BlockifierTransaction; +use blockifier::transaction::transactions::enforce_fee; use blockifier::versioned_constants::{VersionedConstants, VersionedConstantsOverrides}; use indexmap::IndexMap; #[cfg(test)] @@ -164,10 +165,16 @@ impl BlockBuilderTrait for BlockBuilder { // 'match'. let executable_tx = match tx { Transaction::Account(account_tx) => { + let only_query = false; + let charge_fee = enforce_fee(account_tx, only_query); BlockifierTransaction::Account(AccountTransaction { // TODO(yair): Avoid this clone. tx: account_tx.clone(), - only_query: false, + execution_flags: ExecutionFlags { + only_query, + charge_fee, + validate: true, + }, }) } Transaction::L1Handler(l1_handler_tx) => { diff --git a/crates/starknet_gateway/src/stateful_transaction_validator.rs b/crates/starknet_gateway/src/stateful_transaction_validator.rs index 0674b8cd4b..fd04f6d66f 100644 --- a/crates/starknet_gateway/src/stateful_transaction_validator.rs +++ b/crates/starknet_gateway/src/stateful_transaction_validator.rs @@ -5,7 +5,8 @@ use blockifier::blockifier::stateful_validator::{ use blockifier::bouncer::BouncerConfig; use blockifier::context::{BlockContext, ChainInfo}; use blockifier::state::cached_state::CachedState; -use blockifier::transaction::account_transaction::AccountTransaction; +use blockifier::transaction::account_transaction::{AccountTransaction, ExecutionFlags}; +use blockifier::transaction::transactions::enforce_fee; use blockifier::versioned_constants::VersionedConstants; #[cfg(test)] use mockall::automock; @@ -75,7 +76,11 @@ impl StatefulTransactionValidator { mut validator: V, ) -> StatefulTransactionValidatorResult<()> { let skip_validate = skip_stateful_validations(executable_tx, account_nonce); - let account_tx = AccountTransaction { tx: executable_tx.clone(), only_query: false }; + let only_query = false; + let charge_fee = enforce_fee(executable_tx, only_query); + let execution_flags = ExecutionFlags { only_query, charge_fee, validate: !skip_validate }; + + let account_tx = AccountTransaction { tx: executable_tx.clone(), execution_flags }; validator .validate(account_tx, skip_validate) .map_err(|err| GatewaySpecError::ValidationFailure { data: err.to_string() })?;