diff --git a/crates/blockifier/src/concurrency/fee_utils.rs b/crates/blockifier/src/concurrency/fee_utils.rs index 85d01871ca..1d202684f5 100644 --- a/crates/blockifier/src/concurrency/fee_utils.rs +++ b/crates/blockifier/src/concurrency/fee_utils.rs @@ -8,7 +8,7 @@ mod test; // We read account balance (sender), and sequencer balance (recipient). The balance is of type // `Uint256`, consist of two felts (lsb, msb). Hence, storage read values = // [account_balance, 0, sequencer_balance, 0] -const STORAGE_READ_SEQUENCER_BALANCE_INDICES: (usize, usize) = (2, 3); +pub const STORAGE_READ_SEQUENCER_BALANCE_INDICES: (usize, usize) = (2, 3); // Completes the fee transfer execution by fixing the call info to have the correct sequencer // balance. In concurrency mode, the fee transfer is executed with a false (constant) sequencer diff --git a/crates/blockifier/src/concurrency/worker_logic_test.rs b/crates/blockifier/src/concurrency/worker_logic_test.rs index f16b93e986..8cdeeec3e1 100644 --- a/crates/blockifier/src/concurrency/worker_logic_test.rs +++ b/crates/blockifier/src/concurrency/worker_logic_test.rs @@ -9,8 +9,10 @@ use starknet_api::{contract_address, patricia_key, stark_felt}; use super::WorkerExecutor; use crate::abi::abi_utils::get_fee_token_var_address; use crate::abi::sierra_types::next_storage_key; +use crate::concurrency::fee_utils::STORAGE_READ_SEQUENCER_BALANCE_INDICES; use crate::concurrency::scheduler::{Task, TransactionStatus}; use crate::concurrency::test_utils::safe_versioned_state_for_testing; +use crate::concurrency::utils::lock_mutex_in_array; use crate::concurrency::versioned_state::ThreadSafeVersionedState; use crate::concurrency::worker_logic::add_fee_to_sequencer_balance; use crate::context::BlockContext; @@ -31,7 +33,7 @@ use crate::transaction::test_utils::{account_invoke_tx, l1_resource_bounds}; use crate::transaction::transaction_execution::Transaction; use crate::{invoke_tx_args, nonce, storage_key}; -fn _trivial_calldata_invoke_tx( +fn trivial_calldata_invoke_tx( account_address: ContractAddress, nonce_manager: &mut NonceManager, ) -> AccountTransaction { @@ -81,7 +83,7 @@ fn _invoke_tx_without_calldata( // This function checks that the storage values of the account and sequencer balances in the // versioned state of tx_index are equal to the expected_storage_values. -fn _validate_fee_transfer( +fn validate_fee_transfer( executor: &WorkerExecutor<'_, S>, account_address: ContractAddress, tx_index: usize, @@ -132,11 +134,87 @@ fn _write_account_balance_at_versioned_state( versioned_state.apply_writes(&writes, &ContractClassMapping::default(), &HashMap::default()); } +fn check_sequencer_sender_fee_transfer( + executor: &WorkerExecutor<'_, S>, + tx_index: usize, + account_address: ContractAddress, +) { + let execution_task_outputs = lock_mutex_in_array(&executor.execution_outputs, tx_index); + let execution_result = &execution_task_outputs.as_ref().unwrap().result; + let actual_fee = execution_result.as_ref().unwrap().actual_fee.0; + assert!(execution_result.is_ok()); + let sequencer_balance_low = BALANCE; + let account_balance_high = 0_u128; + let sequencer_balance_high = 0_u128; + for (index, expected_balance) in [ + // TODO(Meshi, 03/06/2024): check with Yoni to see if this makes sence (intuitively it + // should be sequencer_balance_low). + (STORAGE_READ_SEQUENCER_BALANCE_INDICES.0, sequencer_balance_low - actual_fee), + (STORAGE_READ_SEQUENCER_BALANCE_INDICES.1, sequencer_balance_high), + ] { + assert_eq!( + execution_result + .as_ref() + .unwrap() + .fee_transfer_call_info + .as_ref() + .unwrap() + .storage_read_values[index], + stark_felt!(expected_balance) + ); + } + drop(execution_task_outputs); + + // Check fee transfer after commit. + validate_fee_transfer( + executor, + account_address, + tx_index, + ( + stark_felt!(BALANCE), + stark_felt!(account_balance_high), + stark_felt!(sequencer_balance_low), + stark_felt!(sequencer_balance_high), + ), + ); +} + +#[test] +fn test_commit_tx_when_the_sqeuncer_is_the_sender() { + let mut block_context = BlockContext::create_for_account_testing_with_concurrency_mode(true); + let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); + let mut nonce_manager = NonceManager::default(); + let account_address = account.get_instance_address(0_u16); + let mut block_info = block_context.block_info.clone(); + block_info.sequencer_address = account_address; + block_context.block_info = block_info; + + // Create transactions. + let transactions_array = [Transaction::AccountTransaction(trivial_calldata_invoke_tx( + account.get_instance_address(0_u16), + &mut nonce_manager, + ))]; + + let state_reader = test_state_reader( + &block_context.chain_info, + BALANCE, + &[(account, transactions_array.len().try_into().unwrap())], + ); + let versioned_state = safe_versioned_state_for_testing(state_reader); + let executor = WorkerExecutor::new(versioned_state, &transactions_array, block_context); + let tx_index = 0; + executor.execute_tx(tx_index); + check_sequencer_sender_fee_transfer(&executor, tx_index, account_address); + executor.commit_tx(tx_index).unwrap(); + check_sequencer_sender_fee_transfer(&executor, tx_index, account_address); +} + #[test] fn test_worker_execute() { // Settings. let concurrency_mode = true; - let block_context = BlockContext::create_for_testing_with_concurrency_mode(concurrency_mode); + let block_context = + BlockContext::create_for_account_testing_with_concurrency_mode(concurrency_mode); let account_contract = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); let test_contract = FeatureContract::TestContract(CairoVersion::Cairo0); let chain_info = &block_context.chain_info; @@ -307,7 +385,8 @@ fn test_worker_execute() { fn test_worker_validate() { // Settings. let concurrency_mode = true; - let block_context = BlockContext::create_for_testing_with_concurrency_mode(concurrency_mode); + let block_context = + BlockContext::create_for_account_testing_with_concurrency_mode(concurrency_mode); let account_contract = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1); let test_contract = FeatureContract::TestContract(CairoVersion::Cairo0); @@ -416,7 +495,7 @@ pub fn test_add_fee_to_sequencer_balance( #[case] sequencer_balance_high: StarkFelt, ) { let tx_index = 0; - let block_context = BlockContext::create_for_testing_with_concurrency_mode(true); + let block_context = BlockContext::create_for_account_testing_with_concurrency_mode(true); let account = FeatureContract::Empty(CairoVersion::Cairo1); let safe_versioned_state = safe_versioned_state_for_testing(test_state_reader( &block_context.chain_info,