From 5ee67db4b5e2354d90ff12a1399e3ec8fa89cb99 Mon Sep 17 00:00:00 2001 From: Aner Ben Efraim Date: Tue, 10 Dec 2024 11:54:58 +0200 Subject: [PATCH] test(blockifier): global validate and execute sierra_gas; deploy --- .../transaction/account_transactions_test.rs | 32 ++-- .../src/transaction/post_execution_test.rs | 21 +-- .../blockifier/src/transaction/test_utils.rs | 45 +++--- .../src/transaction/transactions_test.rs | 138 +++++++++++++++--- 4 files changed, 162 insertions(+), 74 deletions(-) diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index f4d48ab14a..907790a48c 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -17,7 +17,7 @@ use starknet_api::executable_transaction::{ AccountTransaction as ApiExecutableTransaction, DeclareTransaction as ApiExecutableDeclareTransaction, }; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::hash::StarkHash; use starknet_api::state::StorageKey; use starknet_api::test_utils::declare::executable_declare_tx; @@ -79,7 +79,6 @@ use crate::test_utils::{ DEFAULT_L1_DATA_GAS_MAX_AMOUNT, DEFAULT_L1_GAS_AMOUNT, DEFAULT_L2_GAS_MAX_AMOUNT, - DEFAULT_STRK_L1_DATA_GAS_PRICE, DEFAULT_STRK_L1_GAS_PRICE, DEFAULT_STRK_L2_GAS_PRICE, MAX_FEE, @@ -95,6 +94,7 @@ use crate::transaction::test_utils::{ calculate_class_info_for_testing, create_account_tx_for_validate_test_nonce_0, create_all_resource_bounds, + create_gas_amount_bounds_with_default_price, create_test_init_data, default_all_resource_bounds, default_l1_resource_bounds, @@ -194,6 +194,8 @@ fn test_fee_enforcement( #[case] gas_bounds_mode: GasVectorComputationMode, #[values(true, false)] zero_bounds: bool, ) { + use crate::transaction::test_utils::create_gas_amount_bounds_with_default_price; + let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo0); let state = &mut test_state(&block_context.chain_info, BALANCE, &[(account, 1)]); let tx = executable_deploy_account_tx( @@ -205,13 +207,12 @@ fn test_fee_enforcement( (if zero_bounds { 0 } else { DEFAULT_L1_GAS_AMOUNT.0 }).into(), DEFAULT_STRK_L1_GAS_PRICE.into() ), - GasVectorComputationMode::All => create_all_resource_bounds( - (if zero_bounds { 0 } else { DEFAULT_L1_GAS_AMOUNT.0 }).into(), - DEFAULT_STRK_L1_GAS_PRICE.into(), - (if zero_bounds { 0 } else { DEFAULT_L2_GAS_MAX_AMOUNT.0 }).into(), - DEFAULT_STRK_L2_GAS_PRICE.into(), - (if zero_bounds { 0 } else { DEFAULT_L1_DATA_GAS_MAX_AMOUNT.0 }).into(), - DEFAULT_STRK_L1_DATA_GAS_PRICE.into(), + GasVectorComputationMode::All => create_gas_amount_bounds_with_default_price( + GasVector{ + l1_gas: (if zero_bounds { 0 } else { DEFAULT_L1_GAS_AMOUNT.0 }).into(), + l2_gas: (if zero_bounds { 0 } else { DEFAULT_L2_GAS_MAX_AMOUNT.0 }).into(), + l1_data_gas: (if zero_bounds { 0 } else { DEFAULT_L1_DATA_GAS_MAX_AMOUNT.0 }).into(), + }, ), }, version, @@ -237,13 +238,12 @@ fn test_all_bounds_combinations_enforce_fee( let expected_enforce_fee = l1_gas_bound + l1_data_gas_bound + l2_gas_bound > 0; let account_tx = invoke_tx_with_default_flags(invoke_tx_args! { version: TransactionVersion::THREE, - resource_bounds: create_all_resource_bounds( - l1_gas_bound.into(), - DEFAULT_STRK_L1_GAS_PRICE.into(), - l2_gas_bound.into(), - DEFAULT_STRK_L2_GAS_PRICE.into(), - l1_data_gas_bound.into(), - DEFAULT_STRK_L1_DATA_GAS_PRICE.into(), + resource_bounds: create_gas_amount_bounds_with_default_price( + GasVector { + l1_gas: l1_gas_bound.into(), + l2_gas: l2_gas_bound.into(), + l1_data_gas: l1_data_gas_bound.into(), + }, ), }); assert_eq!(account_tx.enforce_fee(), expected_enforce_fee); diff --git a/crates/blockifier/src/transaction/post_execution_test.rs b/crates/blockifier/src/transaction/post_execution_test.rs index 8718ee7bb9..7750ee7a2c 100644 --- a/crates/blockifier/src/transaction/post_execution_test.rs +++ b/crates/blockifier/src/transaction/post_execution_test.rs @@ -22,20 +22,12 @@ use crate::fee::fee_checks::FeeCheckError; use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; use crate::test_utils::initial_test_state::test_state; -use crate::test_utils::{ - create_calldata, - CairoVersion, - BALANCE, - DEFAULT_STRK_L1_DATA_GAS_PRICE, - DEFAULT_STRK_L1_GAS_PRICE, - DEFAULT_STRK_L2_GAS_PRICE, -}; +use crate::test_utils::{create_calldata, CairoVersion, BALANCE, DEFAULT_STRK_L1_GAS_PRICE}; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::errors::TransactionExecutionError; use crate::transaction::objects::{HasRelatedFeeType, TransactionInfoCreator}; use crate::transaction::test_utils::{ block_context, - create_all_resource_bounds, default_all_resource_bounds, default_l1_resource_bounds, invoke_tx_with_default_flags, @@ -268,6 +260,10 @@ fn test_revert_on_resource_overuse( #[case] resource_to_decrement: Option, #[values(CairoVersion::Cairo0)] cairo_version: CairoVersion, ) { + use starknet_api::execution_resources::GasVector; + + use crate::transaction::test_utils::create_gas_amount_bounds_with_default_price; + block_context.block_info.use_kzg_da = true; block_context.versioned_constants.allocation_cost = AllocationCost::ZERO; let gas_mode = resource_bounds.get_gas_vector_computation_mode(); @@ -374,14 +370,11 @@ fn test_revert_on_resource_overuse( Resource::L2Gas => l2_gas.0 -= 1, Resource::L1DataGas => l1_data_gas.0 -= 1, } - create_all_resource_bounds( + create_gas_amount_bounds_with_default_price(GasVector { l1_gas, - DEFAULT_STRK_L1_GAS_PRICE.into(), l2_gas, - DEFAULT_STRK_L2_GAS_PRICE.into(), l1_data_gas, - DEFAULT_STRK_L1_DATA_GAS_PRICE.into(), - ) + }) } } }; diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index 844e000936..bf3ed8ec25 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -3,7 +3,7 @@ use starknet_api::abi::abi_utils::get_fee_token_var_address; use starknet_api::block::{FeeType, GasPrice}; use starknet_api::contract_class::{ClassInfo, ContractClass, SierraVersion}; use starknet_api::core::{ClassHash, ContractAddress, Nonce}; -use starknet_api::execution_resources::GasAmount; +use starknet_api::execution_resources::{GasAmount, GasVector}; use starknet_api::test_utils::declare::executable_declare_tx; use starknet_api::test_utils::deploy_account::{executable_deploy_account_tx, DeployAccountTxArgs}; use starknet_api::test_utils::invoke::{executable_invoke_tx, InvokeTxArgs}; @@ -59,6 +59,16 @@ pub const STORAGE_WRITE: u64 = 8; /// Test fixtures. +#[fixture] +pub fn block_context() -> BlockContext { + BlockContext::create_for_account_testing() +} + +#[fixture] +pub fn versioned_constants(block_context: BlockContext) -> VersionedConstants { + block_context.versioned_constants().clone() +} + #[fixture] pub fn max_fee() -> Fee { MAX_FEE @@ -80,42 +90,27 @@ pub fn create_resource_bounds(computation_mode: &GasVectorComputationMode) -> Va GasVectorComputationMode::NoL2Gas => { l1_resource_bounds(DEFAULT_L1_GAS_AMOUNT, DEFAULT_STRK_L1_GAS_PRICE.into()) } - GasVectorComputationMode::All => create_all_resource_bounds( - DEFAULT_L1_GAS_AMOUNT, - DEFAULT_STRK_L1_GAS_PRICE.into(), - DEFAULT_L2_GAS_MAX_AMOUNT, - DEFAULT_STRK_L2_GAS_PRICE.into(), - DEFAULT_L1_DATA_GAS_MAX_AMOUNT, - DEFAULT_STRK_L1_DATA_GAS_PRICE.into(), - ), + GasVectorComputationMode::All => create_gas_amount_bounds_with_default_price(GasVector { + l1_gas: DEFAULT_L1_GAS_AMOUNT, + l1_data_gas: DEFAULT_L1_DATA_GAS_MAX_AMOUNT, + l2_gas: DEFAULT_L2_GAS_MAX_AMOUNT, + }), } } pub fn create_gas_amount_bounds_with_default_price( - l1_gas_amount: GasAmount, - l2_gas_amount: GasAmount, - l1_data_gas_amount: GasAmount, + GasVector { l1_gas, l1_data_gas, l2_gas }: GasVector, ) -> ValidResourceBounds { create_all_resource_bounds( - l1_gas_amount, + l1_gas, DEFAULT_STRK_L1_GAS_PRICE.into(), - l2_gas_amount, + l2_gas, DEFAULT_STRK_L2_GAS_PRICE.into(), - l1_data_gas_amount, + l1_data_gas, DEFAULT_STRK_L1_DATA_GAS_PRICE.into(), ) } -#[fixture] -pub fn block_context() -> BlockContext { - BlockContext::create_for_account_testing() -} - -#[fixture] -pub fn versioned_constants(block_context: BlockContext) -> VersionedConstants { - block_context.versioned_constants().clone() -} - /// Struct containing the data usually needed to initialize a test. pub struct TestInitData { pub state: CachedState, diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index abdada306f..e9a766f66f 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -134,7 +134,6 @@ use crate::transaction::test_utils::{ calculate_class_info_for_testing, create_account_tx_for_validate_test, create_account_tx_for_validate_test_nonce_0, - create_all_resource_bounds, create_gas_amount_bounds_with_default_price, default_all_resource_bounds, default_l1_resource_bounds, @@ -1087,14 +1086,11 @@ fn test_max_fee_exceeds_balance( let l1_data_gas_amount = partial_balance.checked_div(DEFAULT_STRK_L1_DATA_GAS_PRICE).unwrap(); let ValidResourceBounds::AllResources(mut base_resource_bounds) = - create_all_resource_bounds( - l1_gas_amount, - DEFAULT_STRK_L1_GAS_PRICE.into(), - l2_gas_amount, - DEFAULT_STRK_L2_GAS_PRICE.into(), - l1_data_gas_amount, - DEFAULT_STRK_L1_DATA_GAS_PRICE.into(), - ) + create_gas_amount_bounds_with_default_price(GasVector { + l1_gas: l1_gas_amount, + l2_gas: l2_gas_amount, + l1_data_gas: l1_data_gas_amount, + }) else { panic!("Invalid resource bounds."); }; @@ -2623,16 +2619,21 @@ fn test_balance_print() { #[rstest] #[case::small_user_bounds(create_gas_amount_bounds_with_default_price( - GasAmount(1652), - GasAmount(654321), - GasAmount(0) + GasVector{ l1_gas: GasAmount(1652), l2_gas: GasAmount(654321), l1_data_gas: GasAmount(0) } +))] +#[case::user_bounds_between_validate_and_execute(create_gas_amount_bounds_with_default_price( + GasVector{ + l1_gas: GasAmount(1652), + l2_gas: versioned_constants.validate_max_sierra_gas + GasAmount(1234567), + l1_data_gas: GasAmount(0), + } ))] -#[case::user_bounds_between_validate_and_execute(create_gas_amount_bounds_with_default_price(GasAmount(1652), versioned_constants.validate_max_sierra_gas + GasAmount(1234567), GasAmount(0)))] #[case::large_user_bounds(default_all_resource_bounds())] +#[case::l1_user_bounds(default_l1_resource_bounds())] fn test_invoke_max_sierra_gas_validate_execute( block_context: BlockContext, versioned_constants: VersionedConstants, - #[case] resource_bounds: ValidResourceBounds, + #[case] user_resource_bounds: ValidResourceBounds, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1(RunnableCairo1::Casm))] account_cairo_version: CairoVersion, #[values(CairoVersion::Cairo0, CairoVersion::Cairo1(RunnableCairo1::Casm))] @@ -2648,9 +2649,9 @@ fn test_invoke_max_sierra_gas_validate_execute( let invoke_tx = invoke_tx_with_default_flags(invoke_tx_args! { sender_address: account_contract_address, calldata: Calldata(Arc::clone(&calldata.0)), - resource_bounds, + resource_bounds: user_resource_bounds, }); - let tx_context = block_context.to_tx_context(&invoke_tx); + let user_initial_gas = user_initial_gas_from_bounds(user_resource_bounds, Some(&block_context)); let actual_execution_info = invoke_tx.execute(state, &block_context).unwrap(); @@ -2667,7 +2668,7 @@ fn test_invoke_max_sierra_gas_validate_execute( let expected_validate_initial_gas = match account_tracked_resource { TrackedResource::CairoSteps => VERSIONED_CONSTANTS.default_initial_gas_cost(), TrackedResource::SierraGas => { - versioned_constants.validate_max_sierra_gas.min(tx_context.initial_sierra_gas()).0 + versioned_constants.validate_max_sierra_gas.min(user_initial_gas).0 } }; @@ -2678,8 +2679,20 @@ fn test_invoke_max_sierra_gas_validate_execute( let expected_execute_initial_gas = match account_tracked_resource { TrackedResource::CairoSteps => VERSIONED_CONSTANTS.default_initial_gas_cost(), TrackedResource::SierraGas => { - versioned_constants.execute_max_sierra_gas.min(tx_context.initial_sierra_gas()).0 - - actual_execution_info.validate_call_info.as_ref().unwrap().execution.gas_consumed + versioned_constants + .execute_max_sierra_gas + .min( + user_initial_gas + - GasAmount( + actual_execution_info + .validate_call_info + .as_ref() + .unwrap() + .execution + .gas_consumed, + ), + ) + .0 } }; assert_eq!(actual_execute_initial_gas, expected_execute_initial_gas); @@ -2697,3 +2710,90 @@ fn test_invoke_max_sierra_gas_validate_execute( }; assert_eq!(actual_inner_call_initial_gas, expected_inner_call_initial_gas); } + +#[rstest] +#[case::small_user_bounds(create_gas_amount_bounds_with_default_price( + GasVector{ l1_gas: GasAmount(2203), l1_data_gas: GasAmount(0), l2_gas: GasAmount(654321) } +))] +#[case::user_bounds_between_validate_and_execute(create_gas_amount_bounds_with_default_price( + GasVector{ + l1_gas: GasAmount(2203), + l2_gas:versioned_constants.validate_max_sierra_gas + GasAmount(1234567), + l1_data_gas: GasAmount(0), + } +))] +#[case::large_user_bounds(default_all_resource_bounds())] +#[case::l1_user_bounds(default_l1_resource_bounds())] +fn test_deploy_max_sierra_gas_validate_execute( + block_context: BlockContext, + versioned_constants: VersionedConstants, + #[values(CairoVersion::Cairo0, CairoVersion::Cairo1(RunnableCairo1::Casm))] + cairo_version: CairoVersion, + #[case] user_resource_bounds: ValidResourceBounds, +) { + let chain_info = &block_context.chain_info; + let mut nonce_manager = NonceManager::default(); + let account = FeatureContract::AccountWithoutValidations(cairo_version); + let account_class_hash = account.get_class_hash(); + let state = &mut test_state(chain_info, BALANCE, &[(account, 1)]); + let deploy_account = AccountTransaction::new_with_default_flags(executable_deploy_account_tx( + deploy_account_tx_args! { + resource_bounds: user_resource_bounds, + class_hash: account_class_hash + }, + &mut nonce_manager, + )); + + // Extract deploy account transaction fields for testing, as it is consumed when creating an + // account transaction. + let deployed_account_address = deploy_account.sender_address(); + let user_initial_gas = user_initial_gas_from_bounds(user_resource_bounds, Some(&block_context)); + + // Update the balance of the about to be deployed account contract in the erc20 contract, so it + // can pay for the transaction execution. + let deployed_account_balance_key = get_fee_token_var_address(deployed_account_address); + for fee_type in FeeType::iter() { + state + .set_storage_at( + chain_info.fee_token_address(&fee_type), + deployed_account_balance_key, + felt!(BALANCE.0), + ) + .unwrap(); + } + + let account_tracked_resource = account + .get_runnable_class() + .tracked_resource(&versioned_constants.min_compiler_version_for_sierra_gas, None); + + let actual_execution_info = deploy_account.execute(state, &block_context).unwrap(); + + let actual_execute_initial_gas = + actual_execution_info.execute_call_info.as_ref().unwrap().call.initial_gas; + let expected_execute_initial_gas = + versioned_constants.validate_max_sierra_gas.min(user_initial_gas).0; + assert_eq!(actual_execute_initial_gas, expected_execute_initial_gas); + + let actual_validate_initial_gas = + actual_execution_info.validate_call_info.as_ref().unwrap().call.initial_gas; + let expected_validate_initial_gas = match account_tracked_resource { + TrackedResource::CairoSteps => VERSIONED_CONSTANTS.default_initial_gas_cost(), + TrackedResource::SierraGas => { + versioned_constants + .validate_max_sierra_gas + .min( + user_initial_gas + - GasAmount( + actual_execution_info + .execute_call_info + .as_ref() + .unwrap() + .execution + .gas_consumed, + ), + ) + .0 + } + }; + assert_eq!(actual_validate_initial_gas, expected_validate_initial_gas); +}