diff --git a/crates/blockifier/src/block_context.rs b/crates/blockifier/src/block_context.rs index eb0d9bbf98..cffb7a2d48 100644 --- a/crates/blockifier/src/block_context.rs +++ b/crates/blockifier/src/block_context.rs @@ -8,6 +8,17 @@ use crate::transaction::objects::FeeType; #[derive(Clone, Debug)] pub struct BlockContext { + pub block_info: BlockInfo, +} + +impl BlockContext { + pub fn fee_token_address(&self, fee_type: &FeeType) -> ContractAddress { + self.block_info.fee_token_addresses.get_by_fee_type(fee_type) + } +} + +#[derive(Clone, Debug)] +pub struct BlockInfo { pub chain_id: ChainId, pub block_number: BlockNumber, pub block_timestamp: BlockTimestamp, @@ -25,12 +36,6 @@ pub struct BlockContext { pub max_recursion_depth: usize, } -impl BlockContext { - pub fn fee_token_address(&self, fee_type: &FeeType) -> ContractAddress { - self.fee_token_addresses.get_by_fee_type(fee_type) - } -} - #[derive(Clone, Debug)] pub struct FeeTokenAddresses { pub strk_fee_token_address: ContractAddress, diff --git a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs index f8451683f4..f606924b14 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/hint_processor.rs @@ -317,7 +317,8 @@ impl<'a> DeprecatedSyscallHintProcessor<'a> { tx_signature_length.into(), tx_signature_start_ptr.into(), stark_felt_to_felt(account_tx_context.transaction_hash().0).into(), - Felt252::from_bytes_be(self.context.block_context.chain_id.0.as_bytes()).into(), + Felt252::from_bytes_be(self.context.block_context.block_info.chain_id.0.as_bytes()) + .into(), stark_felt_to_felt(account_tx_context.nonce().0).into(), ]; diff --git a/crates/blockifier/src/execution/deprecated_syscalls/mod.rs b/crates/blockifier/src/execution/deprecated_syscalls/mod.rs index 476351cf9e..6e6bf6e252 100644 --- a/crates/blockifier/src/execution/deprecated_syscalls/mod.rs +++ b/crates/blockifier/src/execution/deprecated_syscalls/mod.rs @@ -397,7 +397,9 @@ pub fn get_block_number( syscall_handler: &mut DeprecatedSyscallHintProcessor<'_>, ) -> DeprecatedSyscallResult { // TODO(Yoni, 1/5/2024): disable for validate. - Ok(GetBlockNumberResponse { block_number: syscall_handler.context.block_context.block_number }) + Ok(GetBlockNumberResponse { + block_number: syscall_handler.context.block_context.block_info.block_number, + }) } // GetBlockTimestamp syscall. @@ -423,7 +425,7 @@ pub fn get_block_timestamp( ) -> DeprecatedSyscallResult { // TODO(Yoni, 1/5/2024): disable for validate. Ok(GetBlockTimestampResponse { - block_timestamp: syscall_handler.context.block_context.block_timestamp, + block_timestamp: syscall_handler.context.block_context.block_info.block_timestamp, }) } @@ -476,7 +478,7 @@ pub fn get_sequencer_address( ) -> DeprecatedSyscallResult { syscall_handler.verify_not_in_validate_mode("get_sequencer_address")?; Ok(GetSequencerAddressResponse { - address: syscall_handler.context.block_context.sequencer_address, + address: syscall_handler.context.block_context.block_info.sequencer_address, }) } diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index 6c65a96c7b..260db95afe 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -171,7 +171,7 @@ impl EntryPointExecutionContext { error_stack: vec![], account_tx_context: account_tx_context.clone(), current_recursion_depth: Default::default(), - max_recursion_depth: block_context.max_recursion_depth, + max_recursion_depth: block_context.block_info.max_recursion_depth, block_context: block_context.clone(), execution_mode: mode, }) @@ -212,18 +212,19 @@ impl EntryPointExecutionContext { mode: &ExecutionMode, limit_steps_by_resources: bool, ) -> TransactionExecutionResult { + let block_info = &block_context.block_info; let block_upper_bound = match mode { // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the conversion // works. ExecutionMode::Validate => min( - block_context + block_info .validate_max_n_steps .try_into() .expect("Failed to convert u32 to usize."), constants::MAX_VALIDATE_STEPS_PER_TX, ), ExecutionMode::Execute => min( - block_context + block_info .invoke_tx_max_n_steps .try_into() .expect("Failed to convert u32 to usize."), @@ -236,16 +237,16 @@ impl EntryPointExecutionContext { } let gas_per_step = - block_context.vm_resource_fee_cost.get(constants::N_STEPS_RESOURCE).unwrap_or_else( - || panic!("{} must appear in `vm_resource_fee_cost`.", constants::N_STEPS_RESOURCE), - ); + block_info.vm_resource_fee_cost.get(constants::N_STEPS_RESOURCE).unwrap_or_else(|| { + panic!("{} must appear in `vm_resource_fee_cost`.", constants::N_STEPS_RESOURCE) + }); // New transactions derive the step limit by the L1 gas resource bounds; deprecated // transactions derive this value from the `max_fee`. let tx_gas_upper_bound = match account_tx_context { AccountTransactionContext::Deprecated(context) => { let max_cairo_steps = context.max_fee.0 - / block_context + / block_info .gas_prices .get_gas_price_by_fee_type(&account_tx_context.fee_type()); // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the diff --git a/crates/blockifier/src/execution/syscalls/hint_processor.rs b/crates/blockifier/src/execution/syscalls/hint_processor.rs index d5c90d2834..576f828650 100644 --- a/crates/blockifier/src/execution/syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/syscalls/hint_processor.rs @@ -434,23 +434,21 @@ impl<'a> SyscallHintProcessor<'a> { &mut self, vm: &mut VirtualMachine, ) -> SyscallResult { - let block_context = &self.context.block_context; - let block_info: Vec = if self.is_validate_mode() { + let block_info = &self.context.block_context.block_info; + let block_timestamp = StarkFelt::from(block_info.block_timestamp.0); + let block_number = StarkFelt::from(block_info.block_number.0); + let block_data: Vec = if self.is_validate_mode() { vec![ // TODO(Yoni, 1/5/2024): set the number to be zero for `validate`. - StarkFelt::from(block_context.block_number.0), + block_number, // TODO(Yoni, 1/5/2024): set the timestamp to be zero for `validate`. - StarkFelt::from(block_context.block_timestamp.0), + block_timestamp, StarkFelt::ZERO, ] } else { - vec![ - StarkFelt::from(block_context.block_number.0), - StarkFelt::from(block_context.block_timestamp.0), - *block_context.sequencer_address.0.key(), - ] + vec![block_number, block_timestamp, *block_info.sequencer_address.0.key()] }; - let (block_info_segment_start_ptr, _) = self.allocate_data_segment(vm, block_info)?; + let (block_info_segment_start_ptr, _) = self.allocate_data_segment(vm, block_data)?; Ok(block_info_segment_start_ptr) } @@ -478,7 +476,8 @@ impl<'a> SyscallHintProcessor<'a> { tx_signature_start_ptr.into(), tx_signature_end_ptr.into(), stark_felt_to_felt((self.context.account_tx_context).transaction_hash().0).into(), - Felt252::from_bytes_be(self.context.block_context.chain_id.0.as_bytes()).into(), + Felt252::from_bytes_be(self.context.block_context.block_info.chain_id.0.as_bytes()) + .into(), stark_felt_to_felt((self.context.account_tx_context).nonce().0).into(), ]; diff --git a/crates/blockifier/src/execution/syscalls/mod.rs b/crates/blockifier/src/execution/syscalls/mod.rs index 2839b18a86..41817a0bc9 100644 --- a/crates/blockifier/src/execution/syscalls/mod.rs +++ b/crates/blockifier/src/execution/syscalls/mod.rs @@ -352,7 +352,7 @@ pub fn get_block_hash( } let requested_block_number = request.block_number.0; - let current_block_number = syscall_handler.context.block_context.block_number.0; + let current_block_number = syscall_handler.context.block_context.block_info.block_number.0; if current_block_number < constants::STORED_BLOCK_HASH_BUFFER || requested_block_number > current_block_number - constants::STORED_BLOCK_HASH_BUFFER diff --git a/crates/blockifier/src/fee/fee_checks.rs b/crates/blockifier/src/fee/fee_checks.rs index 620583a739..099e24b972 100644 --- a/crates/blockifier/src/fee/fee_checks.rs +++ b/crates/blockifier/src/fee/fee_checks.rs @@ -2,7 +2,7 @@ use starknet_api::hash::StarkFelt; use starknet_api::transaction::Fee; use thiserror::Error; -use crate::block_context::BlockContext; +use crate::block_context::{BlockContext, BlockInfo}; use crate::fee::actual_cost::ActualCost; use crate::fee::fee_utils::{ calculate_tx_l1_gas_usage, get_balance_and_if_covers_fee, get_fee_by_l1_gas_usage, @@ -55,7 +55,7 @@ impl FeeCheckReport { pub fn from_fee_check_error( actual_fee: Fee, error: FeeCheckError, - block_context: &BlockContext, + block_info: &BlockInfo, account_tx_context: &AccountTransactionContext, ) -> TransactionExecutionResult { let recommended_fee = match error { @@ -70,7 +70,7 @@ impl FeeCheckReport { FeeCheckError::MaxFeeExceeded { .. } | FeeCheckError::MaxL1GasAmountExceeded { .. } => { match account_tx_context { AccountTransactionContext::Current(context) => get_fee_by_l1_gas_usage( - block_context, + block_info, context.l1_resource_bounds()?.max_amount.into(), &FeeType::Strk, ), @@ -227,7 +227,7 @@ impl PostExecutionReport { return Ok(Self(FeeCheckReport::from_fee_check_error( *actual_fee, fee_check_error, - block_context, + &block_context.block_info, account_tx_context, )?)); } diff --git a/crates/blockifier/src/fee/fee_utils.rs b/crates/blockifier/src/fee/fee_utils.rs index fa1690b2a1..eb015cef48 100644 --- a/crates/blockifier/src/fee/fee_utils.rs +++ b/crates/blockifier/src/fee/fee_utils.rs @@ -4,7 +4,7 @@ use starknet_api::hash::StarkFelt; use starknet_api::transaction::Fee; use crate::abi::constants; -use crate::block_context::BlockContext; +use crate::block_context::{BlockContext, BlockInfo}; use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionFeeError; use crate::transaction::objects::{ @@ -31,7 +31,7 @@ pub fn calculate_l1_gas_by_vm_usage( block_context: &BlockContext, vm_resource_usage: &ResourcesMapping, ) -> TransactionFeeResult { - let vm_resource_fee_costs = &block_context.vm_resource_fee_cost; + let vm_resource_fee_costs = &block_context.block_info.vm_resource_fee_cost; let vm_resource_names = HashSet::<&String>::from_iter(vm_resource_usage.0.keys()); if !vm_resource_names.is_subset(&HashSet::from_iter(vm_resource_fee_costs.keys())) { return Err(TransactionFeeError::CairoResourcesNotContainedInFeeCosts); @@ -63,11 +63,11 @@ pub fn calculate_tx_l1_gas_usage( } pub fn get_fee_by_l1_gas_usage( - block_context: &BlockContext, + block_info: &BlockInfo, l1_gas_usage: u128, fee_type: &FeeType, ) -> Fee { - Fee(l1_gas_usage * block_context.gas_prices.get_gas_price_by_fee_type(fee_type)) + Fee(l1_gas_usage * block_info.gas_prices.get_gas_price_by_fee_type(fee_type)) } /// Calculates the fee that should be charged, given execution resources. @@ -77,7 +77,7 @@ pub fn calculate_tx_fee( fee_type: &FeeType, ) -> TransactionFeeResult { let l1_gas_usage = calculate_tx_l1_gas_usage(resources, block_context)?; - Ok(get_fee_by_l1_gas_usage(block_context, l1_gas_usage, fee_type)) + Ok(get_fee_by_l1_gas_usage(&block_context.block_info, l1_gas_usage, fee_type)) } /// Returns the current fee balance and a boolean indicating whether the balance covers the fee. diff --git a/crates/blockifier/src/fee/gas_usage.rs b/crates/blockifier/src/fee/gas_usage.rs index cf984fbd31..92ce71083e 100644 --- a/crates/blockifier/src/fee/gas_usage.rs +++ b/crates/blockifier/src/fee/gas_usage.rs @@ -225,5 +225,5 @@ pub fn estimate_minimal_fee( tx: &AccountTransaction, ) -> TransactionExecutionResult { let estimated_minimal_l1_gas = estimate_minimal_l1_gas(block_context, tx)?; - Ok(get_fee_by_l1_gas_usage(block_context, estimated_minimal_l1_gas, &tx.fee_type())) + Ok(get_fee_by_l1_gas_usage(&block_context.block_info, estimated_minimal_l1_gas, &tx.fee_type())) } diff --git a/crates/blockifier/src/state/cached_state_test.rs b/crates/blockifier/src/state/cached_state_test.rs index 4c6baeb8c0..9dc1514b58 100644 --- a/crates/blockifier/src/state/cached_state_test.rs +++ b/crates/blockifier/src/state/cached_state_test.rs @@ -305,7 +305,7 @@ fn test_state_changes_merge() { let mut state: CachedState = CachedState::default(); let mut transactional_state = CachedState::create_transactional(&mut state); let block_context = BlockContext::create_for_testing(); - let fee_token_address = block_context.fee_token_addresses.eth_fee_token_address; + let fee_token_address = block_context.block_info.fee_token_addresses.eth_fee_token_address; let state_changes1 = create_state_changes_for_test(&mut transactional_state, fee_token_address); transactional_state.commit(); diff --git a/crates/blockifier/src/test_utils/prices.rs b/crates/blockifier/src/test_utils/prices.rs index 461c9b48d5..316d445a9b 100644 --- a/crates/blockifier/src/test_utils/prices.rs +++ b/crates/blockifier/src/test_utils/prices.rs @@ -59,9 +59,9 @@ fn fee_transfer_resources( let fee_transfer_call = CallEntryPoint { entry_point_selector: selector_from_name(constants::TRANSFER_ENTRY_POINT_NAME), calldata: calldata![ - *block_context.sequencer_address.0.key(), // Recipient. - stark_felt!(7_u8), // LSB of Amount. - stark_felt!(0_u8) // MSB of Amount. + *block_context.block_info.sequencer_address.0.key(), // Recipient. + stark_felt!(7_u8), // LSB of Amount. + stark_felt!(0_u8) // MSB of Amount. ], storage_address: token_address, caller_address: account_contract_address, diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs index b2a11771ed..38b8a598aa 100644 --- a/crates/blockifier/src/test_utils/struct_impls.rs +++ b/crates/blockifier/src/test_utils/struct_impls.rs @@ -17,7 +17,7 @@ use super::{ }; use crate::abi::constants; use crate::abi::constants::{MAX_STEPS_PER_TX, MAX_VALIDATE_STEPS_PER_TX}; -use crate::block_context::{BlockContext, FeeTokenAddresses, GasPrices}; +use crate::block_context::{BlockContext, BlockInfo, FeeTokenAddresses, GasPrices}; use crate::execution::call_info::{CallExecution, CallInfo, Retdata}; use crate::execution::contract_class::{ContractClassV0, ContractClassV1}; use crate::execution::entry_point::{ @@ -84,9 +84,9 @@ impl CallEntryPoint { } } -impl BlockContext { - pub fn create_for_testing() -> BlockContext { - BlockContext { +impl BlockInfo { + pub fn create_for_testing() -> Self { + Self { chain_id: ChainId(CHAIN_ID_NAME.to_string()), block_number: BlockNumber(CURRENT_BLOCK_NUMBER), block_timestamp: BlockTimestamp(CURRENT_BLOCK_TIMESTAMP), @@ -115,7 +115,7 @@ impl BlockContext { } } - pub fn create_for_account_testing() -> BlockContext { + pub fn create_for_account_testing() -> Self { let vm_resource_fee_cost = Arc::new(HashMap::from([ (constants::N_STEPS_RESOURCE.to_string(), 1_f64), (HASH_BUILTIN_NAME.to_string(), 1_f64), @@ -126,7 +126,18 @@ impl BlockContext { (OUTPUT_BUILTIN_NAME.to_string(), 1_f64), (EC_OP_BUILTIN_NAME.to_string(), 1_f64), ])); - BlockContext { vm_resource_fee_cost, ..BlockContext::create_for_testing() } + + Self { vm_resource_fee_cost, ..Self::create_for_testing() } + } +} + +impl BlockContext { + pub fn create_for_testing() -> Self { + Self { block_info: BlockInfo::create_for_testing() } + } + + pub fn create_for_account_testing() -> Self { + Self { block_info: BlockInfo::create_for_account_testing() } } } diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index b446d68ae5..413445df63 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -170,6 +170,7 @@ impl AccountTransaction { block_context: &BlockContext, ) -> TransactionPreValidationResult<()> { let minimal_l1_gas_amount = estimate_minimal_l1_gas(block_context, self)?; + let block_info = &block_context.block_info; match account_tx_context { AccountTransactionContext::Current(context) => { @@ -190,9 +191,8 @@ impl AccountTransaction { })?; } - let actual_l1_gas_price = block_context - .gas_prices - .get_gas_price_by_fee_type(&account_tx_context.fee_type()); + let actual_l1_gas_price = + block_info.gas_prices.get_gas_price_by_fee_type(&account_tx_context.fee_type()); if max_l1_gas_price < actual_l1_gas_price { return Err(TransactionFeeError::MaxL1GasPriceTooLow { max_l1_gas_price, @@ -203,7 +203,7 @@ impl AccountTransaction { AccountTransactionContext::Deprecated(context) => { let max_fee = context.max_fee; let min_fee = get_fee_by_l1_gas_usage( - block_context, + block_info, minimal_l1_gas_amount, &account_tx_context.fee_type(), ); @@ -306,7 +306,7 @@ impl AccountTransaction { entry_point_type: EntryPointType::External, entry_point_selector: selector_from_name(constants::TRANSFER_ENTRY_POINT_NAME), calldata: calldata![ - *block_context.sequencer_address.0.key(), // Recipient. + *block_context.block_info.sequencer_address.0.key(), // Recipient. lsb_amount, msb_amount ], diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index 633b28f4fd..93a9dd1164 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -198,7 +198,7 @@ fn test_infinite_recursion( mut block_context: BlockContext, ) { // Limit the number of execution steps (so we quickly hit the limit). - block_context.invoke_tx_max_n_steps = 4000; + block_context.block_info.invoke_tx_max_n_steps = 4000; let TestInitData { mut state, account_address, contract_address, mut nonce_manager } = create_test_init_data(&block_context, CairoVersion::Cairo0); @@ -257,6 +257,7 @@ fn test_max_fee_limit_validate( create_test_init_data(&block_context, CairoVersion::Cairo0); let grindy_validate_account = FeatureContract::AccountWithLongValidate(CairoVersion::Cairo0); let grindy_class_hash = grindy_validate_account.get_class_hash(); + let block_info = &block_context.block_info; // Declare the grindy-validation account. let account_tx = declare_tx( @@ -330,7 +331,7 @@ fn test_max_fee_limit_validate( }); let estimated_min_l1_gas = estimate_minimal_l1_gas(&block_context, &account_tx).unwrap(); let estimated_min_fee = - get_fee_by_l1_gas_usage(&block_context, estimated_min_l1_gas, &account_tx.fee_type()); + get_fee_by_l1_gas_usage(block_info, estimated_min_l1_gas, &account_tx.fee_type()); let error = run_invoke_tx( &mut state, @@ -341,7 +342,7 @@ fn test_max_fee_limit_validate( // works. resource_bounds: l1_resource_bounds( estimated_min_l1_gas.try_into().expect("Failed to convert u128 to u64."), - block_context.gas_prices.get_gas_price_by_fee_type(&account_tx.fee_type()) + block_info.gas_prices.get_gas_price_by_fee_type(&account_tx.fee_type()) ), ..tx_args }, @@ -379,8 +380,9 @@ fn test_recursion_depth_exceeded( // 2. The base case for recursion occurs at depth 0, not at depth 1. // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the conversion works. - let max_inner_recursion_depth: u8 = - (block_context.max_recursion_depth - 2).try_into().expect("Failed to convert usize to u8."); + let max_inner_recursion_depth: u8 = (block_context.block_info.max_recursion_depth - 2) + .try_into() + .expect("Failed to convert usize to u8."); let recursive_syscall_entry_point_name = "recursive_syscall"; let calldata = create_calldata( @@ -613,7 +615,7 @@ fn test_reverted_reach_steps_limit( create_test_init_data(&block_context, cairo_version); // Limit the number of execution steps (so we quickly hit the limit). - block_context.invoke_tx_max_n_steps = 5000; + block_context.block_info.invoke_tx_max_n_steps = 5000; let recursion_base_args = invoke_tx_args! { max_fee, resource_bounds: max_resource_bounds, @@ -662,7 +664,7 @@ fn test_reverted_reach_steps_limit( let steps_diff = n_steps_1 - n_steps_0; // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the conversion works. let steps_diff_as_u32: u32 = steps_diff.try_into().expect("Failed to convert usize to u32."); - let fail_depth = block_context.invoke_tx_max_n_steps / steps_diff_as_u32; + let fail_depth = block_context.block_info.invoke_tx_max_n_steps / steps_diff_as_u32; // Invoke the `recurse` function with `fail_depth` iterations. This call should fail. let result = run_invoke_tx( @@ -825,7 +827,8 @@ fn test_max_fee_to_max_steps_conversion( let actual_gas_used = 6108; let actual_gas_used_as_u128: u128 = actual_gas_used.into(); let actual_fee = actual_gas_used_as_u128 * 100000000000; - let actual_strk_gas_price = block_context.gas_prices.get_gas_price_by_fee_type(&FeeType::Strk); + let actual_strk_gas_price = + block_context.block_info.gas_prices.get_gas_price_by_fee_type(&FeeType::Strk); let execute_calldata = create_calldata( contract_address, "with_arg", @@ -1013,8 +1016,9 @@ fn test_count_actual_storage_changes( let contract_address = test_contract.get_instance_address(0); let mut nonce_manager = NonceManager::default(); + let sequencer_address = block_context.block_info.sequencer_address; let initial_sequencer_balance = stark_felt_to_felt( - state.get_fee_token_balance(block_context.sequencer_address, fee_token_address).unwrap().0, + state.get_fee_token_balance(sequencer_address, fee_token_address).unwrap().0, ); // Calldata types. @@ -1054,7 +1058,7 @@ fn test_count_actual_storage_changes( ((fee_token_address, get_fee_token_var_address(account_address)), stark_felt!(0_u8)); let mut expected_sequencer_total_fee = initial_sequencer_balance + Felt252::from(fee_1.0); let mut expected_sequencer_fee_update = ( - (fee_token_address, get_fee_token_var_address(block_context.sequencer_address)), + (fee_token_address, get_fee_token_var_address(sequencer_address)), felt_to_stark_felt(&expected_sequencer_total_fee), ); diff --git a/crates/blockifier/src/transaction/execution_flavors_test.rs b/crates/blockifier/src/transaction/execution_flavors_test.rs index e99b67fb5c..bfa74a573a 100644 --- a/crates/blockifier/src/transaction/execution_flavors_test.rs +++ b/crates/blockifier/src/transaction/execution_flavors_test.rs @@ -86,7 +86,11 @@ fn gas_and_fee(base_gas: u64, validate_mode: bool, fee_type: &FeeType) -> (u64, let gas = base_gas + if validate_mode { VALIDATE_GAS_OVERHEAD } else { 0 }; ( gas, - get_fee_by_l1_gas_usage(&BlockContext::create_for_account_testing(), gas.into(), fee_type), + get_fee_by_l1_gas_usage( + &BlockContext::create_for_account_testing().block_info, + gas.into(), + fee_type, + ), ) } @@ -136,7 +140,7 @@ fn test_simulate_validate_charge_fee_pre_validate( ) { let block_context = BlockContext::create_for_account_testing(); let max_fee = Fee(MAX_FEE); - let gas_price = block_context.gas_prices.get_gas_price_by_fee_type(&fee_type); + let gas_price = block_context.block_info.gas_prices.get_gas_price_by_fee_type(&fee_type); let FlavorTestInitialState { mut state, account_address, @@ -369,7 +373,7 @@ fn test_simulate_validate_charge_fee_mid_execution( #[case] fee_type: FeeType, ) { let block_context = BlockContext::create_for_account_testing(); - let gas_price = block_context.gas_prices.get_gas_price_by_fee_type(&fee_type); + let gas_price = block_context.block_info.gas_prices.get_gas_price_by_fee_type(&fee_type); let FlavorTestInitialState { mut state, account_address, @@ -468,15 +472,16 @@ fn test_simulate_validate_charge_fee_mid_execution( // Third scenario: only limit is block bounds. Expect resources consumed to be identical, // whether or not `charge_fee` is true. let mut low_step_block_context = block_context.clone(); - low_step_block_context.invoke_tx_max_n_steps = 10000; + low_step_block_context.block_info.invoke_tx_max_n_steps = 10000; let (huge_gas_limit, huge_fee) = gas_and_fee(100000, validate, &fee_type); // Gas usage does not depend on `validate` flag in this scenario, because we reach the block // step limit during execution anyway. The actual limit when execution phase starts is slightly // lower when `validate` is true, but this is not reflected in the actual gas usage. - let invoke_tx_max_n_steps_as_u64: u64 = low_step_block_context.invoke_tx_max_n_steps.into(); + let invoke_tx_max_n_steps_as_u64: u64 = + low_step_block_context.block_info.invoke_tx_max_n_steps.into(); let block_limit_gas = invoke_tx_max_n_steps_as_u64 + 1720; let block_limit_fee = - get_fee_by_l1_gas_usage(&block_context, block_limit_gas.into(), &fee_type); + get_fee_by_l1_gas_usage(&block_context.block_info, block_limit_gas.into(), &fee_type); let tx_execution_info = account_invoke_tx(invoke_tx_args! { max_fee: huge_fee, resource_bounds: l1_resource_bounds(huge_gas_limit, gas_price), @@ -522,7 +527,7 @@ fn test_simulate_validate_charge_fee_post_execution( #[case] is_deprecated: bool, ) { let block_context = BlockContext::create_for_account_testing(); - let gas_price = block_context.gas_prices.get_gas_price_by_fee_type(&fee_type); + let gas_price = block_context.block_info.gas_prices.get_gas_price_by_fee_type(&fee_type); let fee_token_address = block_context.fee_token_address(&fee_type); let FlavorTestInitialState { diff --git a/crates/blockifier/src/transaction/post_execution_test.rs b/crates/blockifier/src/transaction/post_execution_test.rs index 04de79f2f1..ed773a3711 100644 --- a/crates/blockifier/src/transaction/post_execution_test.rs +++ b/crates/blockifier/src/transaction/post_execution_test.rs @@ -70,7 +70,7 @@ fn test_revert_on_overdraft( #[case] fee_type: FeeType, #[values(CairoVersion::Cairo0)] cairo_version: CairoVersion, ) { - let fee_token_address = block_context.fee_token_addresses.get_by_fee_type(&fee_type); + let fee_token_address = block_context.block_info.fee_token_addresses.get_by_fee_type(&fee_type); // An address to be written into to observe state changes. let storage_address = stark_felt!(10_u8); let storage_key = StorageKey::try_from(storage_address).unwrap(); diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index 1b9ffb9fb4..afb992fe52 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -13,7 +13,7 @@ use starknet_api::{calldata, class_hash, contract_address, patricia_key, stark_f use strum::IntoEnumIterator; use crate::abi::abi_utils::{get_fee_token_var_address, get_storage_var_address}; -use crate::block_context::BlockContext; +use crate::block_context::{BlockContext, FeeTokenAddresses}; use crate::execution::contract_class::{ContractClass, ContractClassV0}; use crate::state::cached_state::CachedState; use crate::state::state_api::State; @@ -153,8 +153,10 @@ pub fn create_account_tx_test_state( // A random address that is unlikely to equal the result of the calculation of a contract // address. let test_account_address = contract_address!(account_address); - let test_strk_token_address = block_context.fee_token_addresses.strk_fee_token_address; - let test_eth_token_address = block_context.fee_token_addresses.eth_fee_token_address; + let FeeTokenAddresses { + eth_fee_token_address: test_eth_token_address, + strk_fee_token_address: test_strk_token_address, + } = block_context.block_info.fee_token_addresses; let address_to_class_hash = HashMap::from([ (test_contract_address, test_contract_class_hash), (test_account_address, test_account_class_hash), diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index f48d25dd27..d3b0bcc79d 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -26,7 +26,7 @@ use crate::abi::abi_utils::{ }; use crate::abi::constants as abi_constants; use crate::abi::sierra_types::next_storage_key; -use crate::block_context::BlockContext; +use crate::block_context::{BlockContext, FeeTokenAddresses}; use crate::execution::call_info::{ CallExecution, CallInfo, MessageToL1, OrderedEvent, OrderedL2ToL1Message, Retdata, }; @@ -159,7 +159,8 @@ fn expected_fee_transfer_call_info( fee_type: &FeeType, expected_fee_token_class_hash: ClassHash, ) -> Option { - let expected_sequencer_address = *block_context.sequencer_address.0.key(); + let expected_sequencer_address = block_context.block_info.sequencer_address; + let expected_sequencer_address_felt = *expected_sequencer_address.0.key(); // The least significant 128 bits of the expected amount transferred. let lsb_expected_amount = stark_felt!(actual_fee.0); // The most significant 128 bits of the expected amount transferred. @@ -171,7 +172,7 @@ fn expected_fee_transfer_call_info( entry_point_type: EntryPointType::External, entry_point_selector: selector_from_name(constants::TRANSFER_ENTRY_POINT_NAME), calldata: calldata![ - expected_sequencer_address, // Recipient. + expected_sequencer_address_felt, // Recipient. lsb_expected_amount, msb_expected_amount ], @@ -187,7 +188,7 @@ fn expected_fee_transfer_call_info( keys: vec![EventKey(selector_from_name(constants::TRANSFER_EVENT_NAME).0)], data: EventData(vec![ expected_fee_sender_address, - expected_sequencer_address, // Recipient. + expected_sequencer_address_felt, // Recipient. lsb_expected_amount, msb_expected_amount, ]), @@ -197,7 +198,7 @@ fn expected_fee_transfer_call_info( let sender_balance_key_low = get_fee_token_var_address(account_address); let sender_balance_key_high = next_storage_key(&sender_balance_key_low).expect("Cannot get sender balance high key."); - let sequencer_balance_key_low = get_fee_token_var_address(block_context.sequencer_address); + let sequencer_balance_key_low = get_fee_token_var_address(expected_sequencer_address); let sequencer_balance_key_high = next_storage_key(&sequencer_balance_key_low) .expect("Cannot get sequencer balance high key."); Some(CallInfo { @@ -256,8 +257,8 @@ fn validate_final_balances( } // Verify balances of both accounts, of both fee types, are as expected. - let eth_fee_token_address = block_context.fee_token_addresses.eth_fee_token_address; - let strk_fee_token_address = block_context.fee_token_addresses.strk_fee_token_address; + let FeeTokenAddresses { eth_fee_token_address, strk_fee_token_address } = + block_context.block_info.fee_token_addresses; for (fee_address, expected_account_balance, expected_sequencer_balance) in [ (eth_fee_token_address, expected_account_balance_eth, expected_sequencer_balance_eth), (strk_fee_token_address, expected_account_balance_strk, expected_sequencer_balance_strk), @@ -800,7 +801,8 @@ fn test_insufficient_resource_bounds(account_cairo_version: CairoVersion) { // Test V1 transaction. - let minimal_fee = Fee(minimal_l1_gas * block_context.gas_prices.eth_l1_gas_price); + let gas_prices = &block_context.block_info.gas_prices; + let minimal_fee = Fee(minimal_l1_gas * gas_prices.eth_l1_gas_price); // Max fee too low (lower than minimal estimated fee). let invalid_max_fee = Fee(minimal_fee.0 - 1); let invalid_v1_tx = account_invoke_tx( @@ -818,7 +820,7 @@ fn test_insufficient_resource_bounds(account_cairo_version: CairoVersion) { ); // Test V3 transaction. - let actual_strk_l1_gas_price = block_context.gas_prices.strk_l1_gas_price; + let actual_strk_l1_gas_price = gas_prices.strk_l1_gas_price; // Max L1 gas amount too low. // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the conversion works. @@ -878,7 +880,7 @@ fn test_actual_fee_gt_resource_bounds(account_cairo_version: CairoVersion) { let minimal_l1_gas = estimate_minimal_l1_gas(block_context, &account_invoke_tx(invoke_tx_args.clone())).unwrap(); - let minimal_fee = Fee(minimal_l1_gas * block_context.gas_prices.eth_l1_gas_price); + let minimal_fee = Fee(minimal_l1_gas * block_context.block_info.gas_prices.eth_l1_gas_price); // The estimated minimal fee is lower than the actual fee. let invalid_tx = account_invoke_tx(invoke_tx_args! { max_fee: minimal_fee, ..invoke_tx_args }); diff --git a/crates/native_blockifier/bench/blockifier_bench.rs b/crates/native_blockifier/bench/blockifier_bench.rs index fb72efe778..6994516887 100644 --- a/crates/native_blockifier/bench/blockifier_bench.rs +++ b/crates/native_blockifier/bench/blockifier_bench.rs @@ -43,7 +43,7 @@ fn create_state() -> CachedState { (test_erc20_class_hash, ContractClassV0::from_file(ERC20_CONTRACT_PATH).into()), ]); // Deploy the ERC20 contract. - let test_erc20_address = block_context.fee_token_addresses.eth_fee_token_address; + let test_erc20_address = block_context.block_info.fee_token_addresses.eth_fee_token_address; let address_to_class_hash = HashMap::from([(test_erc20_address, test_erc20_class_hash)]); CachedState::from(DictStateReader { @@ -86,7 +86,8 @@ fn do_transfer( let entry_point_selector = selector_from_name(blockifier::transaction::constants::TRANSFER_ENTRY_POINT_NAME); // TODO(gilad, 06/09/2023): NEW_TOKEN_SUPPORT this should depend the version of invoke tx. - let contract_address = *block_context.fee_token_addresses.eth_fee_token_address.0.key(); + let contract_address = + *block_context.block_info.fee_token_addresses.eth_fee_token_address.0.key(); let execute_calldata = calldata![ contract_address, // Contract address. @@ -143,7 +144,7 @@ fn prepare_accounts( let deployed_account_balance_key = get_fee_token_var_address(deployed_account_address); state .set_storage_at( - block_context.fee_token_addresses.eth_fee_token_address, + block_context.block_info.fee_token_addresses.eth_fee_token_address, deployed_account_balance_key, stark_felt!(BALANCE * 1000), ) diff --git a/crates/native_blockifier/src/py_block_executor.rs b/crates/native_blockifier/src/py_block_executor.rs index 448bd28e53..03380773b7 100644 --- a/crates/native_blockifier/src/py_block_executor.rs +++ b/crates/native_blockifier/src/py_block_executor.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::sync::Arc; -use blockifier::block_context::{BlockContext, FeeTokenAddresses, GasPrices}; +use blockifier::block_context::{BlockContext, BlockInfo, FeeTokenAddresses}; use blockifier::state::cached_state::GlobalContractCache; use pyo3::prelude::*; use starknet_api::block::{BlockNumber, BlockTimestamp}; @@ -282,29 +282,26 @@ pub fn into_block_context( ) -> NativeBlockifierResult { let starknet_os_config = general_config.starknet_os_config.clone(); let block_context = BlockContext { - chain_id: starknet_os_config.chain_id, - block_number: BlockNumber(block_info.block_number), - block_timestamp: BlockTimestamp(block_info.block_timestamp), - sequencer_address: ContractAddress::try_from(block_info.sequencer_address.0)?, - fee_token_addresses: FeeTokenAddresses { - eth_fee_token_address: ContractAddress::try_from( - starknet_os_config.deprecated_fee_token_address.0, - )?, - strk_fee_token_address: ContractAddress::try_from( - starknet_os_config.fee_token_address.0, - )?, - }, - vm_resource_fee_cost: general_config.cairo_resource_fee_weights.clone(), - gas_prices: GasPrices { - eth_l1_gas_price: block_info.gas_prices.eth_l1_gas_price, - strk_l1_gas_price: block_info.gas_prices.strk_l1_gas_price, - eth_l1_data_gas_price: block_info.gas_prices.eth_l1_data_gas_price, - strk_l1_data_gas_price: block_info.gas_prices.strk_l1_data_gas_price, + block_info: BlockInfo { + chain_id: starknet_os_config.chain_id, + block_number: BlockNumber(block_info.block_number), + block_timestamp: BlockTimestamp(block_info.block_timestamp), + sequencer_address: ContractAddress::try_from(block_info.sequencer_address.0)?, + fee_token_addresses: FeeTokenAddresses { + eth_fee_token_address: ContractAddress::try_from( + starknet_os_config.deprecated_fee_token_address.0, + )?, + strk_fee_token_address: ContractAddress::try_from( + starknet_os_config.fee_token_address.0, + )?, + }, + vm_resource_fee_cost: general_config.cairo_resource_fee_weights.clone(), + gas_prices: block_info.gas_prices.into(), + use_kzg_da: block_info.use_kzg_da, + invoke_tx_max_n_steps: general_config.invoke_tx_max_n_steps, + validate_max_n_steps: general_config.validate_max_n_steps, + max_recursion_depth, }, - use_kzg_da: block_info.use_kzg_da, - invoke_tx_max_n_steps: general_config.invoke_tx_max_n_steps, - validate_max_n_steps: general_config.validate_max_n_steps, - max_recursion_depth, }; Ok(block_context) diff --git a/crates/native_blockifier/src/py_state_diff.rs b/crates/native_blockifier/src/py_state_diff.rs index 46e6e6b90a..9cc7c3030f 100644 --- a/crates/native_blockifier/src/py_state_diff.rs +++ b/crates/native_blockifier/src/py_state_diff.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::convert::TryFrom; +use blockifier::block_context::GasPrices; use blockifier::state::cached_state::CommitmentStateDiff; use indexmap::IndexMap; use pyo3::prelude::*; @@ -8,7 +9,7 @@ use starknet_api::core::{ClassHash, ContractAddress, Nonce}; use starknet_api::state::{StateDiff, StorageKey}; use crate::errors::{NativeBlockifierError, NativeBlockifierResult}; -use crate::py_utils::{py_attr, PyFelt}; +use crate::py_utils::PyFelt; #[pyclass] #[derive(FromPyObject)] @@ -122,7 +123,18 @@ pub struct PyGasPrices { pub strk_l1_data_gas_price: u128, } -#[derive(Default)] +impl From for GasPrices { + fn from(py_gas_prices: PyGasPrices) -> Self { + Self { + eth_l1_gas_price: py_gas_prices.eth_l1_gas_price, + strk_l1_gas_price: py_gas_prices.strk_l1_gas_price, + eth_l1_data_gas_price: py_gas_prices.eth_l1_data_gas_price, + strk_l1_data_gas_price: py_gas_prices.strk_l1_data_gas_price, + } + } +} + +#[derive(Default, FromPyObject)] pub struct PyBlockInfo { pub block_number: u64, pub block_timestamp: u64, @@ -130,20 +142,3 @@ pub struct PyBlockInfo { pub sequencer_address: PyFelt, pub use_kzg_da: bool, } - -impl FromPyObject<'_> for PyBlockInfo { - fn extract(block_info: &PyAny) -> PyResult { - let block_number: u64 = py_attr(block_info, "block_number")?; - let block_timestamp: u64 = py_attr(block_info, "block_timestamp")?; - let sequencer_address: PyFelt = py_attr(block_info, "sequencer_address")?; - let use_kzg_da: bool = py_attr(block_info, "use_kzg_da")?; - let gas_prices = PyGasPrices { - eth_l1_gas_price: py_attr(block_info, "eth_l1_gas_price")?, - strk_l1_gas_price: py_attr(block_info, "strk_l1_gas_price")?, - eth_l1_data_gas_price: py_attr(block_info, "eth_l1_data_gas_price")?, - strk_l1_data_gas_price: py_attr(block_info, "strk_l1_data_gas_price")?, - }; - - Ok(Self { block_number, block_timestamp, gas_prices, sequencer_address, use_kzg_da }) - } -}