diff --git a/crates/blockifier/src/abi/constants.rs b/crates/blockifier/src/abi/constants.rs index ac870c06d4..232d849684 100644 --- a/crates/blockifier/src/abi/constants.rs +++ b/crates/blockifier/src/abi/constants.rs @@ -37,59 +37,6 @@ pub const N_STEPS_RESOURCE: &str = "n_steps"; pub const CAIRO0_ENTRY_POINT_STRUCT_SIZE: usize = 2; pub const N_STEPS_PER_PEDERSEN: usize = 8; -// Gas Cost. -// See documentation in core/os/constants.cairo. -pub const STEP_GAS_COST: u64 = 100; -pub const RANGE_CHECK_GAS_COST: u64 = 70; -pub const MEMORY_HOLE_GAS_COST: u64 = 10; - -// An estimation of the initial gas for a transaction to run with. This solution is temporary and -// this value will become a field of the transaction. -pub const INITIAL_GAS_COST: u64 = 10_u64.pow(8) * STEP_GAS_COST; -// Compiler gas costs. -pub const ENTRY_POINT_INITIAL_BUDGET: u64 = 100 * STEP_GAS_COST; -// The initial gas budget for a system call (this value is hard-coded by the compiler). -// This needs to be high enough to cover OS costs in the case of failure due to out of gas. -pub const SYSCALL_BASE_GAS_COST: u64 = 100 * STEP_GAS_COST; -// OS gas costs. -pub const ENTRY_POINT_GAS_COST: u64 = ENTRY_POINT_INITIAL_BUDGET + 500 * STEP_GAS_COST; -pub const FEE_TRANSFER_GAS_COST: u64 = ENTRY_POINT_GAS_COST + 100 * STEP_GAS_COST; -pub const TRANSACTION_GAS_COST: u64 = - (2 * ENTRY_POINT_GAS_COST) + FEE_TRANSFER_GAS_COST + (100 * STEP_GAS_COST); -// The required gas for each syscall. -pub const CALL_CONTRACT_GAS_COST: u64 = - SYSCALL_BASE_GAS_COST + 10 * STEP_GAS_COST + ENTRY_POINT_GAS_COST; -pub const DEPLOY_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 200 * STEP_GAS_COST + ENTRY_POINT_GAS_COST; -pub const EMIT_EVENT_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 10 * STEP_GAS_COST; -pub const GET_BLOCK_HASH_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 50 * STEP_GAS_COST; -pub const GET_EXECUTION_INFO_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 10 * STEP_GAS_COST; -pub const KECCAK_GAS_COST: u64 = SYSCALL_BASE_GAS_COST; -pub const KECCAK_ROUND_COST_GAS_COST: u64 = 180000; -pub const LIBRARY_CALL_GAS_COST: u64 = CALL_CONTRACT_GAS_COST; -pub const REPLACE_CLASS_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 50 * STEP_GAS_COST; -pub const SECP256K1_ADD_GAS_COST: u64 = 406 * STEP_GAS_COST + 29 * RANGE_CHECK_GAS_COST; -pub const SECP256K1_GET_POINT_FROM_X_GAS_COST: u64 = - 391 * STEP_GAS_COST + 30 * RANGE_CHECK_GAS_COST + 20 * MEMORY_HOLE_GAS_COST; -pub const SECP256K1_GET_XY_GAS_COST: u64 = - 239 * STEP_GAS_COST + 11 * RANGE_CHECK_GAS_COST + 40 * MEMORY_HOLE_GAS_COST; -pub const SECP256K1_MUL_GAS_COST: u64 = - 76501 * STEP_GAS_COST + 7045 * RANGE_CHECK_GAS_COST + 2 * MEMORY_HOLE_GAS_COST; -pub const SECP256K1_NEW_GAS_COST: u64 = - 475 * STEP_GAS_COST + 35 * RANGE_CHECK_GAS_COST + 40 * MEMORY_HOLE_GAS_COST; -pub const SECP256R1_ADD_GAS_COST: u64 = 589 * STEP_GAS_COST + 57 * RANGE_CHECK_GAS_COST; -pub const SECP256R1_GET_POINT_FROM_X_GAS_COST: u64 = - 510 * STEP_GAS_COST + 44 * RANGE_CHECK_GAS_COST + 20 * MEMORY_HOLE_GAS_COST; -pub const SECP256R1_GET_XY_GAS_COST: u64 = - 241 * STEP_GAS_COST + 11 * RANGE_CHECK_GAS_COST + 40 * MEMORY_HOLE_GAS_COST; -pub const SECP256R1_MUL_GAS_COST: u64 = - 125340 * STEP_GAS_COST + 13961 * RANGE_CHECK_GAS_COST + 2 * MEMORY_HOLE_GAS_COST; -pub const SECP256R1_NEW_GAS_COST: u64 = - 594 * STEP_GAS_COST + 49 * RANGE_CHECK_GAS_COST + 40 * MEMORY_HOLE_GAS_COST; - -pub const SEND_MESSAGE_TO_L1_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 50 * STEP_GAS_COST; -pub const STORAGE_READ_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 50 * STEP_GAS_COST; -pub const STORAGE_WRITE_GAS_COST: u64 = SYSCALL_BASE_GAS_COST + 50 * STEP_GAS_COST; - // OS reserved contract addresses. // This contract stores the block number -> block hash mapping. diff --git a/crates/blockifier/src/execution/contract_address_test.rs b/crates/blockifier/src/execution/contract_address_test.rs index 14f69e9f95..ee98a26c0d 100644 --- a/crates/blockifier/src/execution/contract_address_test.rs +++ b/crates/blockifier/src/execution/contract_address_test.rs @@ -5,7 +5,6 @@ use starknet_api::transaction::{Calldata, ContractAddressSalt}; use starknet_api::{calldata, stark_felt}; use crate::abi::abi_utils::selector_from_name; -use crate::abi::constants; use crate::context::ChainInfo; use crate::execution::call_info::{CallExecution, Retdata}; use crate::execution::entry_point::CallEntryPoint; @@ -15,6 +14,7 @@ use crate::test_utils::contracts::FeatureContract; use crate::test_utils::dict_state_reader::DictStateReader; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::{CairoVersion, BALANCE}; +use crate::versioned_constants::VersionedConstants; #[rstest] fn test_calculate_contract_address() { @@ -30,11 +30,12 @@ fn test_calculate_contract_address() { deployer_address: ContractAddress, state: &mut CachedState, ) { + let versioned_constants = VersionedConstants::create_for_testing(); let entry_point_call = CallEntryPoint { calldata, entry_point_selector: selector_from_name("test_contract_address"), storage_address: deployer_address, - initial_gas: constants::INITIAL_GAS_COST, + initial_gas: versioned_constants.gas_cost("initial_gas_cost"), ..Default::default() }; let contract_address = diff --git a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs index 5b8f711c11..6f8b6c1c4c 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs @@ -24,7 +24,6 @@ use starknet_api::transaction::Calldata; use starknet_api::StarknetApiError; use thiserror::Error; -use crate::abi::constants; use crate::block::BlockInfo; use crate::context::TransactionContext; use crate::execution::call_info::{CallInfo, OrderedEvent, OrderedL2ToL1Message}; @@ -458,7 +457,7 @@ pub fn execute_library_call( storage_address: syscall_handler.storage_address, caller_address: syscall_handler.caller_address, call_type: CallType::Delegate, - initial_gas: constants::INITIAL_GAS_COST, + initial_gas: syscall_handler.context.get_gas_cost("initial_gas_cost"), }; execute_inner_call(entry_point, vm, syscall_handler) diff --git a/crates/blockifier/src/execution/deprecated_syscalls/mod.rs b/crates/blockifier/src/execution/deprecated_syscalls/mod.rs index cf166edf50..23b932a7c2 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/mod.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/mod.rs @@ -18,7 +18,6 @@ use self::hint_processor::{ execute_inner_call, execute_library_call, felt_to_bool, read_call_params, read_calldata, read_felt_array, DeprecatedSyscallExecutionError, DeprecatedSyscallHintProcessor, }; -use crate::abi::constants; use crate::execution::call_info::{MessageToL1, OrderedEvent, OrderedL2ToL1Message}; use crate::execution::entry_point::{CallEntryPoint, CallType, ConstructorContext}; use crate::execution::execution_utils::{ @@ -201,7 +200,7 @@ pub fn call_contract( storage_address, caller_address: syscall_handler.storage_address, call_type: CallType::Call, - initial_gas: constants::INITIAL_GAS_COST, + initial_gas: syscall_handler.context.get_gas_cost("initial_gas_cost"), }; let retdata_segment = execute_inner_call(entry_point, vm, syscall_handler)?; @@ -329,7 +328,7 @@ pub fn deploy( syscall_handler.context, ctor_context, request.constructor_calldata, - constants::INITIAL_GAS_COST, + syscall_handler.context.get_gas_cost("initial_gas_cost"), )?; syscall_handler.inner_calls.push(call_info); diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index 226924fc63..c2dd9e9cb1 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -307,6 +307,10 @@ impl EntryPointExecutionContext { .collect::>() .join("\n") } + + pub fn get_gas_cost(&self, name: &str) -> u64 { + self.tx_context.block_context.versioned_constants.gas_cost(name) + } } pub fn execute_constructor_entry_point( diff --git a/crates/blockifier/src/execution/entry_point_test.rs b/crates/blockifier/src/execution/entry_point_test.rs index 4f9290ed9f..25d6995192 100644 --- a/crates/blockifier/src/execution/entry_point_test.rs +++ b/crates/blockifier/src/execution/entry_point_test.rs @@ -12,7 +12,6 @@ use starknet_api::transaction::Calldata; use starknet_api::{calldata, patricia_key, stark_felt}; use crate::abi::abi_utils::{get_storage_var_address, selector_from_name}; -use crate::abi::constants; use crate::context::ChainInfo; use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; use crate::execution::contract_class::ContractClass; @@ -28,6 +27,7 @@ use crate::test_utils::{ create_calldata, trivial_external_entry_point, trivial_external_entry_point_with_address, CairoVersion, BALANCE, }; +use crate::versioned_constants::VersionedConstants; const INNER_CALL_CONTRACT_IN_CALL_CHAIN_OFFSET: usize = 65; @@ -197,11 +197,12 @@ fn run_security_test( entry_point_name: &str, calldata: Calldata, ) { + let versioned_constants = VersionedConstants::create_for_testing(); let entry_point_call = CallEntryPoint { entry_point_selector: selector_from_name(entry_point_name), calldata, storage_address: security_contract.get_instance_address(0), - initial_gas: constants::INITIAL_GAS_COST, + initial_gas: versioned_constants.gas_cost("initial_gas_cost"), ..Default::default() }; let error = match entry_point_call.execute_directly(state) { diff --git a/crates/blockifier/src/execution/syscalls/hint_processor.rs b/crates/blockifier/src/execution/syscalls/hint_processor.rs index 81fbb40b1e..2cd8243681 100644 --- a/crates/blockifier/src/execution/syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/syscalls/hint_processor.rs @@ -24,7 +24,6 @@ use starknet_api::transaction::{Calldata, Resource}; use starknet_api::StarknetApiError; use thiserror::Error; -use crate::abi::constants; use crate::abi::sierra_types::SierraTypeError; use crate::execution::call_info::{CallInfo, OrderedEvent, OrderedL2ToL1Message}; use crate::execution::common_hints::{ExecutionMode, HintExecutionResult}; @@ -229,72 +228,87 @@ impl<'a> SyscallHintProcessor<'a> { self.increment_syscall_count(&selector); } + let get_gas_cost = |name: &str| -> u64 { self.context.get_gas_cost(name) }; match selector { SyscallSelector::CallContract => { - self.execute_syscall(vm, call_contract, constants::CALL_CONTRACT_GAS_COST) + self.execute_syscall(vm, call_contract, get_gas_cost("call_contract_gas_cost")) + } + SyscallSelector::Deploy => { + self.execute_syscall(vm, deploy, get_gas_cost("deploy_gas_cost")) } - SyscallSelector::Deploy => self.execute_syscall(vm, deploy, constants::DEPLOY_GAS_COST), SyscallSelector::EmitEvent => { - self.execute_syscall(vm, emit_event, constants::EMIT_EVENT_GAS_COST) + self.execute_syscall(vm, emit_event, get_gas_cost("emit_event_gas_cost")) } SyscallSelector::GetBlockHash => { - self.execute_syscall(vm, get_block_hash, constants::GET_BLOCK_HASH_GAS_COST) + self.execute_syscall(vm, get_block_hash, get_gas_cost("get_block_hash_gas_cost")) } - SyscallSelector::GetExecutionInfo => { - self.execute_syscall(vm, get_execution_info, constants::GET_EXECUTION_INFO_GAS_COST) + SyscallSelector::GetExecutionInfo => self.execute_syscall( + vm, + get_execution_info, + get_gas_cost("get_execution_info_gas_cost"), + ), + SyscallSelector::Keccak => { + self.execute_syscall(vm, keccak, get_gas_cost("keccak_gas_cost")) } - SyscallSelector::Keccak => self.execute_syscall(vm, keccak, constants::KECCAK_GAS_COST), SyscallSelector::LibraryCall => { - self.execute_syscall(vm, library_call, constants::LIBRARY_CALL_GAS_COST) - } - SyscallSelector::LibraryCallL1Handler => { - self.execute_syscall(vm, library_call_l1_handler, constants::LIBRARY_CALL_GAS_COST) + self.execute_syscall(vm, library_call, get_gas_cost("library_call_gas_cost")) } + SyscallSelector::LibraryCallL1Handler => self.execute_syscall( + vm, + library_call_l1_handler, + get_gas_cost("library_call_gas_cost"), + ), SyscallSelector::ReplaceClass => { - self.execute_syscall(vm, replace_class, constants::REPLACE_CLASS_GAS_COST) + self.execute_syscall(vm, replace_class, get_gas_cost("replace_class_gas_cost")) } SyscallSelector::Secp256k1Add => { - self.execute_syscall(vm, secp256k1_add, constants::SECP256K1_ADD_GAS_COST) + self.execute_syscall(vm, secp256k1_add, get_gas_cost("secp256k1_add_gas_cost")) } SyscallSelector::Secp256k1GetPointFromX => self.execute_syscall( vm, secp256k1_get_point_from_x, - constants::SECP256K1_GET_POINT_FROM_X_GAS_COST, + get_gas_cost("secp256k1_get_point_from_x_gas_cost"), + ), + SyscallSelector::Secp256k1GetXy => self.execute_syscall( + vm, + secp256k1_get_xy, + get_gas_cost("secp256k1_get_xy_gas_cost"), ), - SyscallSelector::Secp256k1GetXy => { - self.execute_syscall(vm, secp256k1_get_xy, constants::SECP256K1_GET_XY_GAS_COST) - } SyscallSelector::Secp256k1Mul => { - self.execute_syscall(vm, secp256k1_mul, constants::SECP256K1_MUL_GAS_COST) + self.execute_syscall(vm, secp256k1_mul, get_gas_cost("secp256k1_mul_gas_cost")) } SyscallSelector::Secp256k1New => { - self.execute_syscall(vm, secp256k1_new, constants::SECP256K1_NEW_GAS_COST) + self.execute_syscall(vm, secp256k1_new, get_gas_cost("secp256k1_new_gas_cost")) } SyscallSelector::Secp256r1Add => { - self.execute_syscall(vm, secp256r1_add, constants::SECP256R1_ADD_GAS_COST) + self.execute_syscall(vm, secp256r1_add, get_gas_cost("secp256r1_add_gas_cost")) } SyscallSelector::Secp256r1GetPointFromX => self.execute_syscall( vm, secp256r1_get_point_from_x, - constants::SECP256R1_GET_POINT_FROM_X_GAS_COST, + get_gas_cost("secp256r1_get_point_from_x_gas_cost"), + ), + SyscallSelector::Secp256r1GetXy => self.execute_syscall( + vm, + secp256r1_get_xy, + get_gas_cost("secp256r1_get_xy_gas_cost"), ), - SyscallSelector::Secp256r1GetXy => { - self.execute_syscall(vm, secp256r1_get_xy, constants::SECP256R1_GET_XY_GAS_COST) - } SyscallSelector::Secp256r1Mul => { - self.execute_syscall(vm, secp256r1_mul, constants::SECP256R1_MUL_GAS_COST) + self.execute_syscall(vm, secp256r1_mul, get_gas_cost("secp256r1_mul_gas_cost")) } SyscallSelector::Secp256r1New => { - self.execute_syscall(vm, secp256r1_new, constants::SECP256R1_NEW_GAS_COST) - } - SyscallSelector::SendMessageToL1 => { - self.execute_syscall(vm, send_message_to_l1, constants::SEND_MESSAGE_TO_L1_GAS_COST) + self.execute_syscall(vm, secp256r1_new, get_gas_cost("secp256r1_new_gas_cost")) } + SyscallSelector::SendMessageToL1 => self.execute_syscall( + vm, + send_message_to_l1, + get_gas_cost("send_message_to_l1_gas_cost"), + ), SyscallSelector::StorageRead => { - self.execute_syscall(vm, storage_read, constants::STORAGE_READ_GAS_COST) + self.execute_syscall(vm, storage_read, get_gas_cost("storage_read_gas_cost")) } SyscallSelector::StorageWrite => { - self.execute_syscall(vm, storage_write, constants::STORAGE_WRITE_GAS_COST) + self.execute_syscall(vm, storage_write, get_gas_cost("storage_write_gas_cost")) } _ => Err(HintError::UnknownHint( format!("Unsupported syscall selector {selector:?}.").into(), @@ -361,7 +375,7 @@ impl<'a> SyscallHintProcessor<'a> { ) -> SyscallResult, { // Refund `SYSCALL_BASE_GAS_COST` as it was pre-charged. - let required_gas = syscall_gas_cost - constants::SYSCALL_BASE_GAS_COST; + let required_gas = syscall_gas_cost - self.context.get_gas_cost("syscall_base_gas_cost"); let SyscallRequestWrapper { gas_counter, request } = SyscallRequestWrapper::::read(vm, &mut self.syscall_ptr)?; diff --git a/crates/blockifier/src/execution/syscalls/mod.rs b/crates/blockifier/src/execution/syscalls/mod.rs index ff5a98546d..384f456e5d 100644 --- a/crates/blockifier/src/execution/syscalls/mod.rs +++ b/crates/blockifier/src/execution/syscalls/mod.rs @@ -662,7 +662,8 @@ pub fn keccak( // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the conversion works. let n_rounds_as_u64 = u64::try_from(n_rounds).expect("Failed to convert usize to u64."); - let gas_cost = n_rounds_as_u64 * constants::KECCAK_ROUND_COST_GAS_COST; + let gas_cost = + n_rounds_as_u64 * syscall_handler.context.get_gas_cost("keccak_round_cost_gas_cost"); if gas_cost > *remaining_gas { let out_of_gas_error = StarkFelt::try_from(OUT_OF_GAS_ERROR).map_err(SyscallExecutionError::from)?; diff --git a/crates/blockifier/src/test_utils.rs b/crates/blockifier/src/test_utils.rs index b329618644..09e6484cd8 100644 --- a/crates/blockifier/src/test_utils.rs +++ b/crates/blockifier/src/test_utils.rs @@ -26,11 +26,11 @@ use starknet_api::transaction::{ use starknet_api::{calldata, contract_address, patricia_key, stark_felt}; use crate::abi::abi_utils::{get_fee_token_var_address, selector_from_name}; -use crate::abi::constants::{self}; use crate::execution::contract_class::{ContractClass, ContractClassV0}; use crate::execution::entry_point::{CallEntryPoint, CallType}; use crate::execution::execution_utils::felt_to_stark_felt; use crate::utils::const_max; +use crate::versioned_constants::VersionedConstants; // TODO(Dori, 1/2/2024): Remove these constants once all tests use the `contracts` and // `initial_test_state` modules for testing. @@ -212,7 +212,7 @@ pub fn trivial_external_entry_point_with_address( storage_address: contract_address, caller_address: ContractAddress::default(), call_type: CallType::Call, - initial_gas: constants::INITIAL_GAS_COST, + initial_gas: VersionedConstants::create_for_account_testing().gas_cost("initial_gas_cost"), } } diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 489702e48c..9730f050f0 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -8,7 +8,6 @@ use starknet_api::hash::StarkFelt; use starknet_api::transaction::{Calldata, Fee, ResourceBounds, TransactionVersion}; use crate::abi::abi_utils::selector_from_name; -use crate::abi::constants as abi_constants; use crate::context::{BlockContext, TransactionContext}; use crate::execution::call_info::{CallInfo, Retdata}; use crate::execution::contract_class::ContractClass; @@ -30,7 +29,6 @@ use crate::transaction::objects::{ HasRelatedFeeType, TransactionExecutionInfo, TransactionExecutionResult, TransactionInfo, TransactionInfoCreator, TransactionPreValidationResult, }; -use crate::transaction::transaction_execution::Transaction; use crate::transaction::transaction_types::TransactionType; use crate::transaction::transaction_utils::update_remaining_gas; use crate::transaction::transactions::{ @@ -309,7 +307,7 @@ impl AccountTransaction { caller_address: tx_info.sender_address(), call_type: CallType::Call, // The fee-token contract is a Cairo 0 contract, hence the initial gas is irrelevant. - initial_gas: abi_constants::INITIAL_GAS_COST, + initial_gas: block_context.versioned_constants.gas_cost("initial_gas_cost"), }; let mut context = EntryPointExecutionContext::new_invoke(tx_context, true)?; @@ -564,7 +562,7 @@ impl ExecutableTransaction for AccountTransaction { self.perform_pre_validation_stage(state, &tx_context, charge_fee, strict_nonce_check)?; // Run validation and execution. - let mut remaining_gas = Transaction::initial_gas(); + let mut remaining_gas = block_context.versioned_constants.tx_initial_gas(); let ValidateExecuteCallInfo { validate_call_info, execute_call_info, diff --git a/crates/blockifier/src/transaction/transaction_execution.rs b/crates/blockifier/src/transaction/transaction_execution.rs index 6be04265f7..3d38fdf62f 100644 --- a/crates/blockifier/src/transaction/transaction_execution.rs +++ b/crates/blockifier/src/transaction/transaction_execution.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use starknet_api::core::{calculate_contract_address, ContractAddress}; use starknet_api::transaction::{Fee, Transaction as StarknetApiTransaction, TransactionHash}; -use crate::abi::constants as abi_constants; use crate::context::BlockContext; use crate::execution::contract_class::ContractClass; use crate::execution::entry_point::{EntryPointExecutionContext, ExecutionResources}; @@ -28,11 +27,6 @@ pub enum Transaction { } impl Transaction { - /// Returns the initial gas of the transaction to run with. - pub fn initial_gas() -> u64 { - abi_constants::INITIAL_GAS_COST - abi_constants::TRANSACTION_GAS_COST - } - pub fn from_api( tx: StarknetApiTransaction, tx_hash: TransactionHash, @@ -114,7 +108,7 @@ impl ExecutableTransaction for L1HandlerTransaction { let mut execution_resources = ExecutionResources::default(); let mut context = EntryPointExecutionContext::new_invoke(tx_context.clone(), true)?; - let mut remaining_gas = Transaction::initial_gas(); + let mut remaining_gas = block_context.versioned_constants.tx_initial_gas(); let execute_call_info = self.run_execute(state, &mut execution_resources, &mut context, &mut remaining_gas)?; let l1_handler_payload_size = self.payload_size(); diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index 565a0054ab..b99351b2e2 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -8,7 +8,7 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources as VmExecutionResour use itertools::concat; use num_traits::Pow; use pretty_assertions::assert_eq; -use rstest::rstest; +use rstest::{fixture, rstest}; use starknet_api::core::{ChainId, ClassHash, ContractAddress, EthAddress, Nonce, PatriciaKey}; use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::hash::{StarkFelt, StarkHash}; @@ -67,15 +67,20 @@ use crate::transaction::test_utils::{ account_invoke_tx, create_account_tx_for_validate_test, l1_resource_bounds, FaultyAccountTxCreatorArgs, CALL_CONTRACT, GET_BLOCK_HASH, INVALID, VALID, }; -use crate::transaction::transaction_execution::Transaction; use crate::transaction::transaction_types::TransactionType; use crate::transaction::transactions::{ExecutableTransaction, L1HandlerTransaction}; +use crate::versioned_constants::VersionedConstants; use crate::{ check_transaction_execution_error_for_custom_hint, check_transaction_execution_error_for_invalid_scenario, declare_tx_args, deploy_account_tx_args, invoke_tx_args, retdata, }; +#[fixture] +fn initial_gas() -> u64 { + VersionedConstants::latest_constants().tx_initial_gas() +} + struct ExpectedResultTestInvokeTx { range_check: usize, n_steps: usize, @@ -143,7 +148,7 @@ fn expected_validate_call_info( storage_address, caller_address: ContractAddress::default(), call_type: CallType::Call, - initial_gas: Transaction::initial_gas(), + initial_gas: initial_gas(), }, // The account contract we use for testing has trivial `validate` functions. vm_resources, @@ -179,7 +184,7 @@ fn expected_fee_transfer_call_info( storage_address, caller_address: account_address, call_type: CallType::Call, - initial_gas: abi_constants::INITIAL_GAS_COST, + initial_gas: block_context.versioned_constants.gas_cost("initial_gas_cost"), }; let expected_fee_sender_address = *account_address.0.key(); let expected_fee_transfer_event = OrderedEvent { @@ -302,7 +307,7 @@ fn default_invoke_tx_args( }, validate_gas_consumed: 0, execute_gas_consumed: 0, - inner_call_initial_gas: abi_constants::INITIAL_GAS_COST, + inner_call_initial_gas: VersionedConstants::create_for_account_testing().gas_cost("initial_gas_cost"), }, CairoVersion::Cairo0; "With Cairo0 account")] @@ -371,7 +376,7 @@ fn test_invoke_tx( }; let expected_execute_call = CallEntryPoint { entry_point_selector: selector_from_name(constants::EXECUTE_ENTRY_POINT_NAME), - initial_gas: Transaction::initial_gas() - expected_arguments.validate_gas_consumed, + initial_gas: initial_gas() - expected_arguments.validate_gas_consumed, ..expected_validate_call_info.as_ref().unwrap().call.clone() }; let expected_return_result_retdata = Retdata(expected_return_result_calldata); @@ -1163,6 +1168,7 @@ fn test_deploy_account_tx( #[case] expected_range_check_builtin: usize, #[case] expected_n_steps_resource: usize, #[case] cairo_version: CairoVersion, + initial_gas: u64, ) { let block_context = &BlockContext::create_for_account_testing(); let chain_info = &block_context.chain_info; @@ -1220,7 +1226,7 @@ fn test_deploy_account_tx( entry_point_type: EntryPointType::Constructor, entry_point_selector: selector_from_name(abi_constants::CONSTRUCTOR_ENTRY_POINT_NAME), storage_address: deployed_account_address, - initial_gas: Transaction::initial_gas(), + initial_gas, ..Default::default() }, ..Default::default() @@ -1626,8 +1632,8 @@ fn l1_handler_tx(calldata: &Calldata, l1_fee: Fee) -> L1HandlerTransaction { } } -#[test] -fn test_l1_handler() { +#[rstest] +fn test_l1_handler(initial_gas: u64) { let state = &mut create_test_state(); let block_context = &BlockContext::create_for_account_testing(); let from_address = StarkFelt::from_u128(0x123); @@ -1650,7 +1656,7 @@ fn test_l1_handler() { storage_address: contract_address!(TEST_CONTRACT_ADDRESS), caller_address: ContractAddress::default(), call_type: CallType::Call, - initial_gas: Transaction::initial_gas(), + initial_gas, }, execution: CallExecution { retdata: Retdata(vec![value]), diff --git a/crates/blockifier/src/versioned_constants.rs b/crates/blockifier/src/versioned_constants.rs index 1ee8f959ac..95be78cfe2 100644 --- a/crates/blockifier/src/versioned_constants.rs +++ b/crates/blockifier/src/versioned_constants.rs @@ -47,6 +47,13 @@ impl VersionedConstants { &DEFAULT_CONSTANTS } + /// Returns the initial gas of any transaction to run with. + pub fn tx_initial_gas(&self) -> u64 { + let os_consts = &self.starknet_os_constants; + + os_consts.gas_costs["initial_gas_cost"] - os_consts.gas_costs["transaction_gas_cost"] + } + pub fn vm_resource_fee_cost(&self) -> &HashMap { &self.vm_resource_fee_cost } @@ -120,12 +127,19 @@ impl StarknetOSConstants { "step_gas_cost", "range_check_gas_cost", "memory_hole_gas_cost", + // An estimation of the initial gas for a transaction to run with. This solution is + // temporary and this value will become a field of the transaction. "initial_gas_cost", + // ** Compiler gas costs ** "entry_point_initial_budget", + // The initial gas budget for a system call (this value is hard-coded by the compiler). + // This needs to be high enough to cover OS costs in the case of failure due to out of gas. "syscall_base_gas_cost", + // ** OS gas costs ** "entry_point_gas_cost", "fee_transfer_gas_cost", "transaction_gas_cost", + // ** Required gas for each syscall ** "call_contract_gas_cost", "deploy_gas_cost", "get_block_hash_gas_cost", diff --git a/crates/native_blockifier/src/py_validator.rs b/crates/native_blockifier/src/py_validator.rs index 358259d474..5708433971 100644 --- a/crates/native_blockifier/src/py_validator.rs +++ b/crates/native_blockifier/src/py_validator.rs @@ -6,7 +6,6 @@ use blockifier::state::cached_state::{GlobalContractCache, GLOBAL_CONTRACT_CACHE use blockifier::state::state_api::StateReader; use blockifier::transaction::account_transaction::AccountTransaction; use blockifier::transaction::objects::{TransactionExecutionResult, TransactionInfo}; -use blockifier::transaction::transaction_execution::Transaction; use blockifier::versioned_constants::VersionedConstants; use pyo3::prelude::*; use starknet_api::core::Nonce; @@ -94,8 +93,9 @@ impl PyValidator { } // `__validate__` call. + let versioned_constants = &tx_context.block_context.versioned_constants; let (_optional_call_info, actual_cost) = - self.validate(account_tx, Transaction::initial_gas())?; + self.validate(account_tx, versioned_constants.tx_initial_gas())?; // Post validations. // TODO(Ayelet, 09/11/2023): Check call succeeded.