From da50b4b1518a80dc8b54410cc136d322386fec60 Mon Sep 17 00:00:00 2001 From: aner-starkware <147302140+aner-starkware@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:14:16 +0200 Subject: [PATCH 01/10] feat(fee): modified calculate_tx_l1_gas_usage(s), added calculate_tx_gas_and_blob_gas_usage (#1370) --- crates/blockifier/src/fee/actual_cost.rs | 7 +- crates/blockifier/src/fee/fee_checks.rs | 15 +++- crates/blockifier/src/fee/fee_utils.rs | 22 ++++-- crates/blockifier/src/fee/gas_usage.rs | 21 +++++- crates/blockifier/src/fee/gas_usage_test.rs | 75 +++++++++++++------ .../src/transaction/account_transaction.rs | 6 +- .../transaction/account_transactions_test.rs | 30 +++++--- crates/blockifier/src/transaction/errors.rs | 2 + .../src/transaction/execution_flavors_test.rs | 20 +++-- .../src/transaction/post_execution_test.rs | 6 +- .../src/transaction/transaction_utils.rs | 4 +- .../src/transaction/transactions_test.rs | 29 ++++--- 12 files changed, 166 insertions(+), 71 deletions(-) diff --git a/crates/blockifier/src/fee/actual_cost.rs b/crates/blockifier/src/fee/actual_cost.rs index 6e84bc5185..3d8f825770 100644 --- a/crates/blockifier/src/fee/actual_cost.rs +++ b/crates/blockifier/src/fee/actual_cost.rs @@ -5,7 +5,7 @@ use crate::abi::constants as abi_constants; use crate::block_context::BlockContext; use crate::execution::call_info::CallInfo; use crate::execution::entry_point::ExecutionResources; -use crate::fee::gas_usage::calculate_tx_gas_usage; +use crate::fee::gas_usage::calculate_tx_gas_and_blob_gas_usage; use crate::state::cached_state::{CachedState, StateChanges, StateChangesCount}; use crate::state::state_api::{StateReader, StateResult}; use crate::transaction::objects::{ @@ -138,14 +138,15 @@ impl<'a> ActualCostBuilder<'a> { // Gas usage for SHARP costs and Starknet L1-L2 messages. Includes gas usage for data // availability. // TODO(Aner, 21/01/24) Include gas for data availability according to use_kzg_da flag. - let l1_gas_usage = calculate_tx_gas_usage( + let l1_gas_and_blob_gas_usage = calculate_tx_gas_and_blob_gas_usage( non_optional_call_infos, state_changes_count, self.l1_payload_size, )?; + let mut actual_resources = calculate_tx_resources( execution_resources, - l1_gas_usage, + l1_gas_and_blob_gas_usage, self.tx_type, self.calldata_length, )?; diff --git a/crates/blockifier/src/fee/fee_checks.rs b/crates/blockifier/src/fee/fee_checks.rs index 6a6c278c94..ab884066c4 100644 --- a/crates/blockifier/src/fee/fee_checks.rs +++ b/crates/blockifier/src/fee/fee_checks.rs @@ -5,11 +5,13 @@ use thiserror::Error; use crate::block_context::{BlockContext, BlockInfo, ChainInfo}; 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, + calculate_tx_l1_gas_usages, get_balance_and_if_covers_fee, get_fee_by_l1_gas_usage, }; use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionExecutionError; -use crate::transaction::objects::{AccountTransactionContext, FeeType, TransactionExecutionResult}; +use crate::transaction::objects::{ + AccountTransactionContext, FeeType, GasAndBlobGasUsages, TransactionExecutionResult, +}; #[derive(Clone, Copy, Debug, Error)] pub enum FeeCheckError { @@ -46,6 +48,7 @@ impl FeeCheckReportFields for FeeCheckReport { } } +// TODO(Aner, 23/1/24): Update this struct to check data gas bounds as well as other bounds. impl FeeCheckReport { pub fn success_report(actual_fee: Fee) -> Self { Self { recommended_fee: actual_fee, error: None } @@ -71,7 +74,10 @@ impl FeeCheckReport { match account_tx_context { AccountTransactionContext::Current(context) => get_fee_by_l1_gas_usage( block_info, - context.l1_resource_bounds()?.max_amount.into(), + GasAndBlobGasUsages { + gas_usage: context.l1_resource_bounds()?.max_amount.into(), + blob_gas_usage: 0, + }, &FeeType::Strk, ), AccountTransactionContext::Deprecated(context) => context.max_fee, @@ -92,12 +98,13 @@ impl FeeCheckReport { // First, compare the actual resources used against the upper bound(s) defined by the // sender. + // TODO(Aner, 21/01/24) modify for 4844 (include check for blob_gas). match account_tx_context { AccountTransactionContext::Current(context) => { // Check L1 gas limit. let max_l1_gas = context.l1_resource_bounds()?.max_amount.into(); let actual_used_l1_gas = - calculate_tx_l1_gas_usage(actual_resources, block_context)?; + calculate_tx_l1_gas_usages(actual_resources, block_context)?.gas_usage; if actual_used_l1_gas > max_l1_gas { return Err(FeeCheckError::MaxL1GasAmountExceeded { max_amount: max_l1_gas, diff --git a/crates/blockifier/src/fee/fee_utils.rs b/crates/blockifier/src/fee/fee_utils.rs index 52bc17035c..8e44c7bf3b 100644 --- a/crates/blockifier/src/fee/fee_utils.rs +++ b/crates/blockifier/src/fee/fee_utils.rs @@ -8,7 +8,8 @@ use crate::block_context::{BlockContext, BlockInfo, ChainInfo}; use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionFeeError; use crate::transaction::objects::{ - AccountTransactionContext, FeeType, HasRelatedFeeType, ResourcesMapping, TransactionFeeResult, + AccountTransactionContext, FeeType, GasAndBlobGasUsages, HasRelatedFeeType, ResourcesMapping, + TransactionFeeResult, }; #[cfg(test)] @@ -59,23 +60,28 @@ pub fn calculate_l1_gas_by_vm_usage( /// Computes and returns the total L1 gas consumption. /// We add the l1_gas_usage (which may include, for example, the direct cost of L2-to-L1 messages) /// to the gas consumed by Cairo VM resource. -pub fn calculate_tx_l1_gas_usage( +pub fn calculate_tx_l1_gas_usages( resources: &ResourcesMapping, block_context: &BlockContext, -) -> TransactionFeeResult { +) -> TransactionFeeResult { let (l1_gas_usage, vm_resources) = extract_l1_gas_and_vm_usage(resources); + let (l1_blob_gas_usage, vm_resources) = extract_l1_blob_gas_usage(&vm_resources); let l1_gas_by_vm_usage = calculate_l1_gas_by_vm_usage(block_context, &vm_resources)?; let total_l1_gas_usage = l1_gas_usage as f64 + l1_gas_by_vm_usage; - Ok(total_l1_gas_usage.ceil() as u128) + Ok(GasAndBlobGasUsages { + gas_usage: total_l1_gas_usage.ceil() as u128, + blob_gas_usage: l1_blob_gas_usage as u128, + }) } pub fn get_fee_by_l1_gas_usage( block_info: &BlockInfo, - l1_gas_usage: u128, + l1_gas_usages: GasAndBlobGasUsages, fee_type: &FeeType, ) -> Fee { - Fee(l1_gas_usage * block_info.gas_prices.get_gas_price_by_fee_type(fee_type)) + // TODO(Aner, 25/01/24) compute via linear combination and rename function accordingly. + Fee(l1_gas_usages.gas_usage * block_info.gas_prices.get_gas_price_by_fee_type(fee_type)) } /// Calculates the fee that should be charged, given execution resources. @@ -84,8 +90,8 @@ pub fn calculate_tx_fee( block_context: &BlockContext, 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.block_info, l1_gas_usage, fee_type)) + let l1_gas_and_blob_gas_usage = calculate_tx_l1_gas_usages(resources, block_context)?; + Ok(get_fee_by_l1_gas_usage(&block_context.block_info, l1_gas_and_blob_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 a250137566..12aa8080ee 100644 --- a/crates/blockifier/src/fee/gas_usage.rs +++ b/crates/blockifier/src/fee/gas_usage.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use starknet_api::transaction::Fee; -use super::fee_utils::{calculate_tx_l1_gas_usage, get_fee_by_l1_gas_usage}; +use super::fee_utils::{calculate_tx_l1_gas_usages, get_fee_by_l1_gas_usage}; use crate::abi::constants; use crate::block_context::BlockContext; use crate::execution::call_info::CallInfo; @@ -11,7 +11,8 @@ use crate::fee::os_resources::OS_RESOURCES; use crate::state::cached_state::StateChangesCount; use crate::transaction::account_transaction::AccountTransaction; use crate::transaction::objects::{ - HasRelatedFeeType, ResourcesMapping, TransactionExecutionResult, TransactionPreValidationResult, + GasAndBlobGasUsages, HasRelatedFeeType, ResourcesMapping, TransactionExecutionResult, + TransactionPreValidationResult, }; #[cfg(test)] @@ -35,6 +36,18 @@ fn calculate_l2_to_l1_payloads_length_and_message_segment_length<'a>( Ok((l2_to_l1_payloads_length, message_segment_length)) } +pub fn calculate_tx_gas_and_blob_gas_usage<'a>( + call_infos: impl Iterator, + state_changes_count: StateChangesCount, + l1_handler_payload_size: Option, +) -> TransactionExecutionResult { + Ok(GasAndBlobGasUsages { + gas_usage: calculate_tx_gas_usage(call_infos, state_changes_count, l1_handler_payload_size)? + as u128, + blob_gas_usage: 0, + }) +} + /// Returns the blob-gas (data-gas) needed to publish the transaction's state diff in a blob. pub fn calculate_tx_blob_gas_usage(state_changes_count: StateChangesCount) -> usize { let onchain_data_segment_length = get_onchain_data_segment_length(state_changes_count); @@ -199,7 +212,7 @@ fn get_event_emission_cost(n_topics: usize, data_length: usize) -> usize { pub fn estimate_minimal_l1_gas( block_context: &BlockContext, tx: &AccountTransaction, -) -> TransactionPreValidationResult { +) -> TransactionPreValidationResult { // TODO(Dori, 1/8/2023): Give names to the constant VM step estimates and regression-test them. let os_steps_for_type = OS_RESOURCES.resources_for_tx_type(&tx.tx_type()).n_steps; let gas_cost: usize = match tx { @@ -231,7 +244,7 @@ pub fn estimate_minimal_l1_gas( (constants::N_STEPS_RESOURCE.to_string(), os_steps_for_type), ])); - Ok(calculate_tx_l1_gas_usage(&resources, block_context)?) + Ok(calculate_tx_l1_gas_usages(&resources, block_context)?) } pub fn estimate_minimal_fee( diff --git a/crates/blockifier/src/fee/gas_usage_test.rs b/crates/blockifier/src/fee/gas_usage_test.rs index 0c5f74fcaa..4242f6b644 100644 --- a/crates/blockifier/src/fee/gas_usage_test.rs +++ b/crates/blockifier/src/fee/gas_usage_test.rs @@ -7,10 +7,12 @@ use starknet_api::transaction::L2ToL1Payload; use crate::execution::call_info::{CallExecution, CallInfo, MessageToL1, OrderedL2ToL1Message}; use crate::fee::eth_gas_constants; use crate::fee::gas_usage::{ - calculate_tx_blob_gas_usage, calculate_tx_gas_usage, get_consumed_message_to_l2_emissions_cost, - get_log_message_to_l1_emissions_cost, get_message_segment_length, get_onchain_data_cost, + calculate_tx_blob_gas_usage, calculate_tx_gas_and_blob_gas_usage, + get_consumed_message_to_l2_emissions_cost, get_log_message_to_l1_emissions_cost, + get_message_segment_length, get_onchain_data_cost, }; use crate::state::cached_state::StateChangesCount; +use crate::transaction::objects::GasAndBlobGasUsages; #[rstest] #[case::storage_write(StateChangesCount { @@ -65,9 +67,13 @@ fn test_calculate_tx_blob_gas_usage_basic(#[case] state_changes_count: StateChan #[test] fn test_calculate_tx_gas_usage_basic() { // An empty transaction (a theoretical case for sanity check). - let empty_tx_gas_usage = - calculate_tx_gas_usage(std::iter::empty(), StateChangesCount::default(), None).unwrap(); - assert_eq!(empty_tx_gas_usage, 0); + let empty_tx_gas_and_blob_gas_usage = + calculate_tx_gas_and_blob_gas_usage(std::iter::empty(), StateChangesCount::default(), None) + .unwrap(); + assert_eq!( + empty_tx_gas_and_blob_gas_usage, + GasAndBlobGasUsages { gas_usage: 0, blob_gas_usage: 0 } + ); // DeployAccount. @@ -82,20 +88,30 @@ fn test_calculate_tx_gas_usage_basic() { let manual_starknet_gas_usage = 0; let manual_sharp_gas_usage = get_onchain_data_cost(deploy_account_state_changes_count); - let deploy_account_gas_usage = - calculate_tx_gas_usage(std::iter::empty(), deploy_account_state_changes_count, None) - .unwrap(); - assert_eq!(manual_starknet_gas_usage + manual_sharp_gas_usage, deploy_account_gas_usage); + let deploy_account_gas_and_blob_gas_usage = calculate_tx_gas_and_blob_gas_usage( + std::iter::empty(), + deploy_account_state_changes_count, + None, + ) + .unwrap(); + let GasAndBlobGasUsages { gas_usage: deploy_account_gas_usage, .. } = + deploy_account_gas_and_blob_gas_usage; + assert_eq!( + (manual_starknet_gas_usage + manual_sharp_gas_usage) as u128, + deploy_account_gas_usage, + ); // L1 handler. let l1_handler_payload_size = 4; - let l1_handler_gas_usage = calculate_tx_gas_usage( + let l1_handler_gas_and_blob_gas_usage = calculate_tx_gas_and_blob_gas_usage( std::iter::empty(), StateChangesCount::default(), Some(l1_handler_payload_size), ) .unwrap(); + let GasAndBlobGasUsages { gas_usage: l1_handler_gas_usage, .. } = + l1_handler_gas_and_blob_gas_usage; // Manual calculation. let message_segment_length = get_message_segment_length(&[], Some(l1_handler_payload_size)); @@ -105,7 +121,7 @@ fn test_calculate_tx_gas_usage_basic() { let manual_sharp_gas_usage = message_segment_length * eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD; - assert_eq!(manual_starknet_gas_usage + manual_sharp_gas_usage, l1_handler_gas_usage); + assert_eq!((manual_starknet_gas_usage + manual_sharp_gas_usage) as u128, l1_handler_gas_usage); // Any transaction with L2-to-L1 messages. @@ -144,9 +160,14 @@ fn test_calculate_tx_gas_usage_basic() { n_compiled_class_hash_updates: 0, n_modified_contracts: 1, }; - let l2_to_l1_messages_gas_usage = - calculate_tx_gas_usage(call_infos_iter.clone(), l2_to_l1_state_changes_count, None) - .unwrap(); + let l2_to_l1_messages_gas_and_blob_gas_usage = calculate_tx_gas_and_blob_gas_usage( + call_infos_iter.clone(), + l2_to_l1_state_changes_count, + None, + ) + .unwrap(); + let GasAndBlobGasUsages { gas_usage: l2_to_l1_messages_gas_usage, .. } = + l2_to_l1_messages_gas_and_blob_gas_usage; // Manual calculation. let message_segment_length = get_message_segment_length(&l2_to_l1_payloads_length, None); @@ -158,7 +179,10 @@ fn test_calculate_tx_gas_usage_basic() { * eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD + get_onchain_data_cost(l2_to_l1_state_changes_count); - assert_eq!(manual_starknet_gas_usage + manual_sharp_gas_usage, l2_to_l1_messages_gas_usage); + assert_eq!( + (manual_starknet_gas_usage + manual_sharp_gas_usage) as u128, + l2_to_l1_messages_gas_usage + ); // Any calculation with storage writings. @@ -170,15 +194,23 @@ fn test_calculate_tx_gas_usage_basic() { n_compiled_class_hash_updates: 0, n_modified_contracts, }; - let storage_writings_gas_usage = - calculate_tx_gas_usage(std::iter::empty(), storage_writes_state_changes_count, None) - .unwrap(); + let storage_writings_gas_and_blob_gas_usage = calculate_tx_gas_and_blob_gas_usage( + std::iter::empty(), + storage_writes_state_changes_count, + None, + ) + .unwrap(); + let GasAndBlobGasUsages { gas_usage: storage_writings_gas_usage, .. } = + storage_writings_gas_and_blob_gas_usage; // Manual calculation. let manual_starknet_gas_usage = 0; let manual_sharp_gas_usage = get_onchain_data_cost(storage_writes_state_changes_count); - assert_eq!(manual_starknet_gas_usage + manual_sharp_gas_usage, storage_writings_gas_usage); + assert_eq!( + (manual_starknet_gas_usage + manual_sharp_gas_usage) as u128, + storage_writings_gas_usage + ); // Combined case of an L1 handler, L2-to-L1 messages and storage writes. let combined_state_changes_count = StateChangesCount { @@ -188,12 +220,13 @@ fn test_calculate_tx_gas_usage_basic() { n_modified_contracts: storage_writes_state_changes_count.n_modified_contracts + l2_to_l1_state_changes_count.n_modified_contracts, }; - let gas_usage = calculate_tx_gas_usage( + let gas_usage_and_blob_gas_usage = calculate_tx_gas_and_blob_gas_usage( call_infos_iter, combined_state_changes_count, Some(l1_handler_payload_size), ) .unwrap(); + let GasAndBlobGasUsages { gas_usage, .. } = gas_usage_and_blob_gas_usage; // Manual calculation. let fee_balance_discount = @@ -204,7 +237,7 @@ fn test_calculate_tx_gas_usage_basic() { + storage_writings_gas_usage // l2_to_l1_messages_gas_usage and storage_writings_gas_usage got a discount each, while // the combined calculation got it once. - + fee_balance_discount; + + fee_balance_discount as u128; assert_eq!(gas_usage, expected_gas_usage); } diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 9ff37162ca..c183a16134 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -177,7 +177,9 @@ impl AccountTransaction { account_tx_context: &AccountTransactionContext, block_context: &BlockContext, ) -> TransactionPreValidationResult<()> { - let minimal_l1_gas_amount = estimate_minimal_l1_gas(block_context, self)?; + // TODO(Aner, 21/01/24) modify for 4844 (blob_gas). + let minimal_l1_gas_and_blob_gas_amount = estimate_minimal_l1_gas(block_context, self)?; + let minimal_l1_gas_amount = minimal_l1_gas_and_blob_gas_amount.gas_usage; let block_info = &block_context.block_info; match account_tx_context { @@ -212,7 +214,7 @@ impl AccountTransaction { let max_fee = context.max_fee; let min_fee = get_fee_by_l1_gas_usage( block_info, - minimal_l1_gas_amount, + minimal_l1_gas_and_blob_gas_amount, &account_tx_context.fee_type(), ); if max_fee < min_fee { diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index 8aeeb4c19c..857e7e9e0f 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -25,7 +25,7 @@ use crate::execution::contract_class::{ContractClass, ContractClassV1}; use crate::execution::entry_point::EntryPointExecutionContext; use crate::execution::errors::{EntryPointExecutionError, VirtualMachineExecutionError}; use crate::execution::execution_utils::{felt_to_stark_felt, stark_felt_to_felt}; -use crate::fee::fee_utils::{calculate_tx_l1_gas_usage, get_fee_by_l1_gas_usage}; +use crate::fee::fee_utils::{calculate_tx_l1_gas_usages, get_fee_by_l1_gas_usage}; use crate::fee::gas_usage::estimate_minimal_l1_gas; use crate::state::cached_state::CachedState; use crate::state::state_api::{State, StateReader}; @@ -244,6 +244,7 @@ fn test_infinite_recursion( } /// Tests that validation fails on insufficient steps if max fee is too low. +// TODO(Aner, 21/01/24) modify test for 4844. #[rstest] #[case(TransactionVersion::ONE)] #[case(TransactionVersion::THREE)] @@ -330,9 +331,14 @@ fn test_max_fee_limit_validate( resource_bounds: max_resource_bounds, ..tx_args.clone() }); - 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_info, estimated_min_l1_gas, &account_tx.fee_type()); + let estimated_min_l1_gas_and_blob_gas = + estimate_minimal_l1_gas(&block_context, &account_tx).unwrap(); + let estimated_min_l1_gas = estimated_min_l1_gas_and_blob_gas.gas_usage; + let estimated_min_fee = get_fee_by_l1_gas_usage( + block_info, + estimated_min_l1_gas_and_blob_gas, + &account_tx.fee_type(), + ); let error = run_invoke_tx( &mut state, @@ -857,8 +863,8 @@ fn test_max_fee_to_max_steps_conversion( 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 n_steps1 = tx_execution_info1.actual_resources.n_steps(); - let gas_used1 = - calculate_tx_l1_gas_usage(&tx_execution_info1.actual_resources, &block_context).unwrap(); + let gas_and_blob_gas_used1 = + calculate_tx_l1_gas_usages(&tx_execution_info1.actual_resources, &block_context).unwrap(); // Second invocation of `with_arg` gets twice the pre-calculated actual fee as max_fee. let account_tx2 = account_invoke_tx(invoke_tx_args! { @@ -878,17 +884,21 @@ fn test_max_fee_to_max_steps_conversion( 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 n_steps2 = tx_execution_info2.actual_resources.n_steps(); - let gas_used2 = - calculate_tx_l1_gas_usage(&tx_execution_info2.actual_resources, &block_context).unwrap(); + let gas_and_blob_gas_used2 = + calculate_tx_l1_gas_usages(&tx_execution_info2.actual_resources, &block_context).unwrap(); // Test that steps limit doubles as max_fee doubles, but actual consumed steps and fee remains. assert_eq!(max_steps_limit2.unwrap(), 2 * max_steps_limit1.unwrap()); assert_eq!(tx_execution_info1.actual_fee.0, tx_execution_info2.actual_fee.0); // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the conversion works. - assert_eq!(actual_gas_used, u64::try_from(gas_used2).expect("Failed to convert u128 to u64.")); + // TODO(Aner, 21/01/24): verify test compliant with 4844 (or modify accordingly). + assert_eq!( + actual_gas_used, + u64::try_from(gas_and_blob_gas_used2.gas_usage).expect("Failed to convert u128 to u64.") + ); assert_eq!(actual_fee, tx_execution_info2.actual_fee.0); assert_eq!(n_steps1, n_steps2); - assert_eq!(gas_used1, gas_used2); + assert_eq!(gas_and_blob_gas_used1, gas_and_blob_gas_used2); } #[rstest] diff --git a/crates/blockifier/src/transaction/errors.rs b/crates/blockifier/src/transaction/errors.rs index fa3fcfd40e..5625077b56 100644 --- a/crates/blockifier/src/transaction/errors.rs +++ b/crates/blockifier/src/transaction/errors.rs @@ -86,6 +86,8 @@ pub enum TransactionExecutionError { TransactionPreValidationError(#[from] TransactionPreValidationError), #[error("Unexpected holes in the {object} order. No object with the order: {order}.")] UnexpectedHoles { object: String, order: usize }, + #[error(transparent)] + TryFromIntError(#[from] std::num::TryFromIntError), #[error("Transaction validation has failed: {0}")] ValidateTransactionError(#[source] EntryPointExecutionError), } diff --git a/crates/blockifier/src/transaction/execution_flavors_test.rs b/crates/blockifier/src/transaction/execution_flavors_test.rs index c0d23251c3..7f27457ac1 100644 --- a/crates/blockifier/src/transaction/execution_flavors_test.rs +++ b/crates/blockifier/src/transaction/execution_flavors_test.rs @@ -10,7 +10,9 @@ use starknet_api::transaction::{Calldata, Fee, TransactionSignature, Transaction use crate::block_context::{BlockContext, ChainInfo}; use crate::execution::errors::EntryPointExecutionError; use crate::execution::execution_utils::{felt_to_stark_felt, stark_felt_to_felt}; -use crate::fee::fee_utils::{calculate_tx_fee, calculate_tx_l1_gas_usage, get_fee_by_l1_gas_usage}; +use crate::fee::fee_utils::{ + calculate_tx_fee, calculate_tx_l1_gas_usages, get_fee_by_l1_gas_usage, +}; use crate::invoke_tx_args; use crate::state::cached_state::CachedState; use crate::state::state_api::StateReader; @@ -24,7 +26,7 @@ use crate::test_utils::{ use crate::transaction::errors::{ TransactionExecutionError, TransactionFeeError, TransactionPreValidationError, }; -use crate::transaction::objects::{FeeType, TransactionExecutionInfo}; +use crate::transaction::objects::{FeeType, GasAndBlobGasUsages, TransactionExecutionInfo}; use crate::transaction::test_utils::{account_invoke_tx, l1_resource_bounds, INVALID}; use crate::transaction::transactions::ExecutableTransaction; const VALIDATE_GAS_OVERHEAD: u64 = 21; @@ -88,13 +90,14 @@ fn gas_and_fee(base_gas: u64, validate_mode: bool, fee_type: &FeeType) -> (u64, gas, get_fee_by_l1_gas_usage( &BlockContext::create_for_account_testing().block_info, - gas.into(), + GasAndBlobGasUsages { gas_usage: gas.into(), blob_gas_usage: 0 }, fee_type, ), ) } /// Asserts gas used and reported fee are as expected. +// TODO(Aner, 21/01/24) modify for 4844 (taking blob_gas into account). fn check_gas_and_fee( block_context: &BlockContext, tx_execution_info: &TransactionExecutionInfo, @@ -104,7 +107,9 @@ fn check_gas_and_fee( expected_cost_of_resources: Fee, ) { assert_eq!( - calculate_tx_l1_gas_usage(&tx_execution_info.actual_resources, block_context).unwrap(), + calculate_tx_l1_gas_usages(&tx_execution_info.actual_resources, block_context) + .unwrap() + .gas_usage, expected_actual_gas.into() ); assert_eq!(tx_execution_info.actual_fee, expected_actual_fee); @@ -481,8 +486,11 @@ fn test_simulate_validate_charge_fee_mid_execution( 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_info, block_limit_gas.into(), &fee_type); + let block_limit_fee = get_fee_by_l1_gas_usage( + &block_context.block_info, + GasAndBlobGasUsages { gas_usage: block_limit_gas.into(), blob_gas_usage: 0 }, + &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), diff --git a/crates/blockifier/src/transaction/post_execution_test.rs b/crates/blockifier/src/transaction/post_execution_test.rs index 2f178518c2..2796e9bf92 100644 --- a/crates/blockifier/src/transaction/post_execution_test.rs +++ b/crates/blockifier/src/transaction/post_execution_test.rs @@ -9,7 +9,7 @@ use starknet_crypto::FieldElement; use crate::block_context::{BlockContext, ChainInfo}; use crate::fee::fee_checks::FeeCheckError; -use crate::fee::fee_utils::calculate_tx_l1_gas_usage; +use crate::fee::fee_utils::calculate_tx_l1_gas_usages; use crate::invoke_tx_args; use crate::state::state_api::StateReader; use crate::test_utils::contracts::FeatureContract; @@ -205,6 +205,7 @@ fn test_revert_on_overdraft( /// Tests that when a transaction requires more resources than what the sender bounds allow, the /// execution is reverted; in the non-revertible case, checks for the correct error. +// TODO(Aner, 21/01/24) modify for 4844 (taking blob_gas into account). #[rstest] #[case(TransactionVersion::ZERO, "", false)] #[case(TransactionVersion::ONE, "Insufficient max fee", true)] @@ -257,8 +258,9 @@ fn test_revert_on_resource_overuse( let actual_fee = execution_info_measure.actual_fee; // TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the conversion works. let actual_gas_usage: u64 = - calculate_tx_l1_gas_usage(&execution_info_measure.actual_resources, &block_context) + calculate_tx_l1_gas_usages(&execution_info_measure.actual_resources, &block_context) .unwrap() + .gas_usage .try_into() .expect("Failed to convert u128 to u64."); diff --git a/crates/blockifier/src/transaction/transaction_utils.rs b/crates/blockifier/src/transaction/transaction_utils.rs index f0c20fd996..f0b5f7f2e2 100644 --- a/crates/blockifier/src/transaction/transaction_utils.rs +++ b/crates/blockifier/src/transaction/transaction_utils.rs @@ -3,6 +3,7 @@ use std::collections::HashMap; use cairo_vm::vm::runners::builtin_runner::SEGMENT_ARENA_BUILTIN_NAME; use starknet_api::transaction::TransactionVersion; +use super::objects::GasAndBlobGasUsages; use crate::abi::constants; use crate::execution::call_info::CallInfo; use crate::execution::contract_class::ContractClass; @@ -17,10 +18,11 @@ use crate::transaction::transaction_types::TransactionType; /// I.e., Cairo VM execution resources. pub fn calculate_tx_resources( execution_resources: &ExecutionResources, - l1_gas_usage: usize, + l1_gas_usages: GasAndBlobGasUsages, tx_type: TransactionType, calldata_length: usize, ) -> TransactionExecutionResult { + let l1_gas_usage = l1_gas_usages.gas_usage.try_into()?; // Add additional Cairo resources needed for the OS to run the transaction. let total_vm_usage = &execution_resources.vm_resources + &get_additional_os_resources( diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index dd58a39857..fe93ee3509 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -35,7 +35,7 @@ use crate::execution::errors::{EntryPointExecutionError, VirtualMachineExecution use crate::execution::execution_utils::{felt_to_stark_felt, stark_felt_to_felt}; use crate::fee::fee_utils::calculate_tx_fee; use crate::fee::gas_usage::{ - calculate_tx_gas_usage, estimate_minimal_l1_gas, get_onchain_data_cost, + calculate_tx_gas_and_blob_gas_usage, estimate_minimal_l1_gas, get_onchain_data_cost, }; use crate::state::cached_state::{CachedState, StateChangesCount}; use crate::state::errors::StateError; @@ -60,7 +60,7 @@ use crate::transaction::errors::{ TransactionExecutionError, TransactionFeeError, TransactionPreValidationError, }; use crate::transaction::objects::{ - AccountTransactionContext, FeeType, HasRelatedFeeType, ResourcesMapping, + AccountTransactionContext, FeeType, GasAndBlobGasUsages, HasRelatedFeeType, ResourcesMapping, TransactionExecutionInfo, }; use crate::transaction::test_utils::{ @@ -786,6 +786,7 @@ fn test_max_fee_exceeds_balance(account_cairo_version: CairoVersion) { assert_failure_if_resource_bounds_exceed_balance(state, block_context, invalid_tx); } +// TODO(Aner, 21/01/24) modify for 4844 (taking blob_gas into account). #[test_case(CairoVersion::Cairo0; "With Cairo0 account")] #[test_case(CairoVersion::Cairo1; "With Cairo1 account")] fn test_insufficient_resource_bounds(account_cairo_version: CairoVersion) { @@ -805,11 +806,13 @@ fn test_insufficient_resource_bounds(account_cairo_version: CairoVersion) { // The minimal gas estimate does not depend on tx version. let minimal_l1_gas = estimate_minimal_l1_gas(block_context, &account_invoke_tx(valid_invoke_tx_args.clone())) - .unwrap(); + .unwrap() + .gas_usage; // Test V1 transaction. let gas_prices = &block_context.block_info.gas_prices; + // TODO(Aner, 21/01/24) change to linear combination. 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); @@ -873,6 +876,7 @@ fn test_insufficient_resource_bounds(account_cairo_version: CairoVersion) { ); } +// TODO(Aner, 21/01/24) modify test for 4844. #[test_case(CairoVersion::Cairo0; "With Cairo0 account")] #[test_case(CairoVersion::Cairo1; "With Cairo1 account")] fn test_actual_fee_gt_resource_bounds(account_cairo_version: CairoVersion) { @@ -890,7 +894,9 @@ 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(); + estimate_minimal_l1_gas(block_context, &account_invoke_tx(invoke_tx_args.clone())) + .unwrap() + .gas_usage; 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 }); @@ -1447,6 +1453,7 @@ fn test_validate_accounts_tx( // Test that we exclude the fee token contract modification and adds the account’s balance change // in the state changes. +// TODO(Aner, 21/01/24) modify for 4844 (taking blob_gas into account). #[test] fn test_calculate_tx_gas_usage() { let account_cairo_version = CairoVersion::Cairo0; @@ -1474,9 +1481,10 @@ fn test_calculate_tx_gas_usage() { n_compiled_class_hash_updates: 0, }; - let l1_gas_usage = - calculate_tx_gas_usage(std::iter::empty(), state_changes_count, None).unwrap(); - assert_eq!(tx_execution_info.actual_resources.gas_usage(), l1_gas_usage); + let l1_gas_and_blob_gas_usage = + calculate_tx_gas_and_blob_gas_usage(std::iter::empty(), state_changes_count, None).unwrap(); + let GasAndBlobGasUsages { gas_usage: l1_gas_usage, .. } = l1_gas_and_blob_gas_usage; + assert_eq!(tx_execution_info.actual_resources.gas_usage() as u128, l1_gas_usage); // A tx that changes the account and some other balance in execute. let some_other_account_address = account_contract.get_instance_address(17); @@ -1510,9 +1518,10 @@ fn test_calculate_tx_gas_usage() { n_compiled_class_hash_updates: 0, }; - let l1_gas_usage = - calculate_tx_gas_usage(std::iter::empty(), state_changes_count, None).unwrap(); - assert_eq!(tx_execution_info.actual_resources.gas_usage(), l1_gas_usage); + let l1_gas_and_blob_gas_usage = + calculate_tx_gas_and_blob_gas_usage(std::iter::empty(), state_changes_count, None).unwrap(); + let GasAndBlobGasUsages { gas_usage: l1_gas_usage, .. } = l1_gas_and_blob_gas_usage; + assert_eq!(tx_execution_info.actual_resources.gas_usage() as u128, l1_gas_usage); } #[rstest] From 2f7113f608a8cec26183eed1f30f7c117e0db3a8 Mon Sep 17 00:00:00 2001 From: OriStarkware <76900983+OriStarkware@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:35:52 +0200 Subject: [PATCH 02/10] refactor(state): replace GlobalContractCache default with GlobalContractCache new (#1368) --- crates/blockifier/src/state/cached_state.rs | 21 +++++++++++-------- .../blockifier/src/state/cached_state_test.rs | 2 +- .../src/py_block_executor.rs | 11 +++++----- crates/native_blockifier/src/py_validator.rs | 9 ++++---- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/crates/blockifier/src/state/cached_state.rs b/crates/blockifier/src/state/cached_state.rs index ff6d39f8ff..cf71253635 100644 --- a/crates/blockifier/src/state/cached_state.rs +++ b/crates/blockifier/src/state/cached_state.rs @@ -184,9 +184,13 @@ impl CachedState { } } +#[cfg(any(feature = "testing", test))] impl From for CachedState { fn from(state_reader: S) -> Self { - CachedState::new(state_reader, Default::default()) + CachedState::new( + state_reader, + GlobalContractCache::new(GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST), + ) } } @@ -365,7 +369,9 @@ impl Default for CachedState = MutexGuard<'a, ContractClassLRUCache>; // `blockifier` compiles as a shared library. pub struct GlobalContractCache(pub Arc>); -impl GlobalContractCache { - // TODO(Arni, 7/1/2024): make this configurable via a CachedState constructor argument. - const CACHE_SIZE: usize = 100; +pub const GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST: usize = 100; +impl GlobalContractCache { /// Locks the cache for atomic access. Although conceptually shared, writing to this cache is /// only possible for one writer at a time. pub fn lock(&mut self) -> LockedContractClassCache<'_> { @@ -739,10 +744,8 @@ impl GlobalContractCache { pub fn clear(&mut self) { self.lock().cache_clear(); } -} -impl Default for GlobalContractCache { - fn default() -> Self { - Self(Arc::new(Mutex::new(ContractClassLRUCache::with_size(Self::CACHE_SIZE)))) + pub fn new(cache_size: usize) -> Self { + Self(Arc::new(Mutex::new(ContractClassLRUCache::with_size(cache_size)))) } } diff --git a/crates/blockifier/src/state/cached_state_test.rs b/crates/blockifier/src/state/cached_state_test.rs index d05cbd75a4..97b34cb64a 100644 --- a/crates/blockifier/src/state/cached_state_test.rs +++ b/crates/blockifier/src/state/cached_state_test.rs @@ -375,7 +375,7 @@ fn test_state_changes_merge() { fn global_contract_cache_is_used() { // Initialize the global cache with a single class, and initialize an empty state with this // cache. - let mut global_cache = GlobalContractCache::default(); + let mut global_cache = GlobalContractCache::new(GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST); let class_hash = class_hash!(TEST_CLASS_HASH); let contract_class = get_test_contract_class(); global_cache.lock().cache_set(class_hash, contract_class.clone()); diff --git a/crates/native_blockifier/src/py_block_executor.rs b/crates/native_blockifier/src/py_block_executor.rs index 831f3c1b3a..196a3d2886 100644 --- a/crates/native_blockifier/src/py_block_executor.rs +++ b/crates/native_blockifier/src/py_block_executor.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::sync::Arc; use blockifier::block_context::{BlockContext, BlockInfo, ChainInfo, FeeTokenAddresses, GasPrices}; -use blockifier::state::cached_state::GlobalContractCache; +use blockifier::state::cached_state::{GlobalContractCache, GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST}; use pyo3::prelude::*; use starknet_api::block::{BlockNumber, BlockTimestamp}; use starknet_api::core::{ChainId, ContractAddress}; @@ -33,10 +33,11 @@ pub struct PyBlockExecutor { #[pymethods] impl PyBlockExecutor { #[new] - #[pyo3(signature = (general_config, max_recursion_depth, target_storage_config))] + #[pyo3(signature = (general_config, max_recursion_depth, global_contract_cache_size, target_storage_config))] pub fn create( general_config: PyGeneralConfig, max_recursion_depth: usize, + global_contract_cache_size: usize, target_storage_config: StorageConfig, ) -> Self { log::debug!("Initializing Block Executor..."); @@ -50,7 +51,7 @@ impl PyBlockExecutor { max_recursion_depth, tx_executor, storage: Box::new(storage), - global_contract_cache: GlobalContractCache::default(), + global_contract_cache: GlobalContractCache::new(global_contract_cache_size), } } @@ -203,7 +204,7 @@ impl PyBlockExecutor { general_config, max_recursion_depth: 50, tx_executor: None, - global_contract_cache: GlobalContractCache::default(), + global_contract_cache: GlobalContractCache::new(GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST), } } } @@ -226,7 +227,7 @@ impl PyBlockExecutor { general_config: PyGeneralConfig::default(), max_recursion_depth: 50, tx_executor: None, - global_contract_cache: GlobalContractCache::default(), + global_contract_cache: GlobalContractCache::new(GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST), } } } diff --git a/crates/native_blockifier/src/py_validator.rs b/crates/native_blockifier/src/py_validator.rs index 9a3c088292..09d05e0ca5 100644 --- a/crates/native_blockifier/src/py_validator.rs +++ b/crates/native_blockifier/src/py_validator.rs @@ -1,7 +1,7 @@ use blockifier::execution::call_info::CallInfo; use blockifier::fee::actual_cost::ActualCost; use blockifier::fee::fee_checks::PostValidationReport; -use blockifier::state::cached_state::GlobalContractCache; +use blockifier::state::cached_state::{GlobalContractCache, GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST}; use blockifier::state::state_api::StateReader; use blockifier::transaction::account_transaction::AccountTransaction; use blockifier::transaction::objects::{AccountTransactionContext, TransactionExecutionResult}; @@ -31,12 +31,13 @@ pub struct PyValidator { #[pymethods] impl PyValidator { #[new] - #[pyo3(signature = (general_config, state_reader_proxy, next_block_info, max_recursion_depth, max_nonce_for_validation_skip))] + #[pyo3(signature = (general_config, state_reader_proxy, next_block_info, max_recursion_depth, global_contract_cache_size, max_nonce_for_validation_skip))] pub fn create( general_config: PyGeneralConfig, state_reader_proxy: &PyAny, next_block_info: PyBlockInfo, max_recursion_depth: usize, + global_contract_cache_size: usize, max_nonce_for_validation_skip: PyFelt, ) -> NativeBlockifierResult { let tx_executor = TransactionExecutor::new( @@ -44,7 +45,7 @@ impl PyValidator { &general_config, next_block_info, max_recursion_depth, - GlobalContractCache::default(), + GlobalContractCache::new(global_contract_cache_size), )?; let validator = Self { general_config, @@ -115,7 +116,7 @@ impl PyValidator { &general_config, next_block_info, max_recursion_depth, - GlobalContractCache::default(), + GlobalContractCache::new(GLOBAL_CONTRACT_CACHE_SIZE_FOR_TEST), )?; Ok(Self { general_config, From 9d1c3a11879e542ceb2a0b68d46d1ebf325576a6 Mon Sep 17 00:00:00 2001 From: dorimedini-starkware Date: Thu, 25 Jan 2024 14:45:01 +0200 Subject: [PATCH 03/10] feat(fee): check gas amount including discounted data gas (#1374) Signed-off-by: Dori Medini --- crates/blockifier/src/fee/fee_checks.rs | 31 +++++++++--- crates/blockifier/src/fee/fee_test.rs | 66 +++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/crates/blockifier/src/fee/fee_checks.rs b/crates/blockifier/src/fee/fee_checks.rs index ab884066c4..8b8e2711dc 100644 --- a/crates/blockifier/src/fee/fee_checks.rs +++ b/crates/blockifier/src/fee/fee_checks.rs @@ -10,7 +10,8 @@ use crate::fee::fee_utils::{ use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionExecutionError; use crate::transaction::objects::{ - AccountTransactionContext, FeeType, GasAndBlobGasUsages, TransactionExecutionResult, + AccountTransactionContext, FeeType, GasAndBlobGasUsages, HasRelatedFeeType, + TransactionExecutionResult, }; #[derive(Clone, Copy, Debug, Error)] @@ -98,17 +99,35 @@ impl FeeCheckReport { // First, compare the actual resources used against the upper bound(s) defined by the // sender. - // TODO(Aner, 21/01/24) modify for 4844 (include check for blob_gas). match account_tx_context { AccountTransactionContext::Current(context) => { // Check L1 gas limit. let max_l1_gas = context.l1_resource_bounds()?.max_amount.into(); - let actual_used_l1_gas = - calculate_tx_l1_gas_usages(actual_resources, block_context)?.gas_usage; - if actual_used_l1_gas > max_l1_gas { + + let GasAndBlobGasUsages { gas_usage, blob_gas_usage } = + calculate_tx_l1_gas_usages(actual_resources, block_context)?; + + // TODO(Dori, 1/7/2024): When data gas limit is added (and enforced) in resource + // bounds, check it here as well (separately, with a different error variant if + // limit exceeded). + // One byte of data costs either 1 data gas (in blob mode) or 16 gas (in calldata + // mode). For gas price GP and data gas price DGP, the discount for using blobs + // would be DGP / (16 * GP). + // X non-data-related gas consumption and Y bytes of data, in non-blob mode, would + // cost (X + 16*Y) units of gas. Applying the discount ratio to the data-related + // summand, we get total_gas = (X + Y * DGP / GP). + let fee_type = account_tx_context.fee_type(); + let gas_price = + block_context.block_info.gas_prices.get_gas_price_by_fee_type(&fee_type); + let data_gas_price = + block_context.block_info.gas_prices.get_data_gas_price_by_fee_type(&fee_type); + let total_discounted_gas_used = + gas_usage + (blob_gas_usage * data_gas_price) / gas_price; + + if total_discounted_gas_used > max_l1_gas { return Err(FeeCheckError::MaxL1GasAmountExceeded { max_amount: max_l1_gas, - actual_amount: actual_used_l1_gas, + actual_amount: total_discounted_gas_used, })?; } } diff --git a/crates/blockifier/src/fee/fee_test.rs b/crates/blockifier/src/fee/fee_test.rs index 6da9489d27..68927f4739 100644 --- a/crates/blockifier/src/fee/fee_test.rs +++ b/crates/blockifier/src/fee/fee_test.rs @@ -5,12 +5,21 @@ use cairo_vm::vm::runners::builtin_runner::{ BITWISE_BUILTIN_NAME, HASH_BUILTIN_NAME, POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, }; +use rstest::rstest; +use starknet_api::transaction::{Fee, TransactionVersion}; use crate::abi::constants; use crate::block_context::BlockContext; +use crate::fee::actual_cost::ActualCost; +use crate::fee::fee_checks::{FeeCheckError, FeeCheckReportFields, PostExecutionReport}; use crate::fee::fee_utils::calculate_l1_gas_by_vm_usage; +use crate::invoke_tx_args; +use crate::test_utils::contracts::FeatureContract; +use crate::test_utils::initial_test_state::test_state; +use crate::test_utils::{CairoVersion, BALANCE}; use crate::transaction::errors::TransactionFeeError; use crate::transaction::objects::ResourcesMapping; +use crate::transaction::test_utils::{account_invoke_tx, l1_resource_bounds}; fn get_vm_resource_usage() -> ResourcesMapping { ResourcesMapping(HashMap::from([ @@ -44,3 +53,60 @@ fn test_calculate_l1_gas_by_vm_usage() { calculate_l1_gas_by_vm_usage(&block_context, &invalid_vm_resource_usage).unwrap_err(); assert_matches!(error, TransactionFeeError::CairoResourcesNotContainedInFeeCosts); } + +/// Test the L1 gas limit bound, as applied to the case where both gas and data gas are consumed. +#[rstest] +#[case::no_dg_within_bounds(1000, 10, 10000, 0, 10000, false)] +#[case::no_dg_overdraft(1000, 10, 10001, 0, 10000, true)] +#[case::both_gases_within_bounds(1000, 10, 10000, 5000, 100000, false)] +#[case::both_gases_overdraft(1000, 10, 10000, 5000, 10000, true)] +#[case::expensive_dg_no_dg_within_bounds(10, 1000, 10, 0, 10, false)] +#[case::expensive_dg_with_dg_overdraft(10, 1000, 10, 1, 109, true)] +#[case::expensive_dg_with_dg_within_bounds(10, 1000, 10, 1, 110, false)] +fn test_discounted_gas_overdraft( + #[case] gas_price: u128, + #[case] data_gas_price: u128, + #[case] l1_gas_used: usize, + #[case] l1_data_gas_used: usize, + #[case] gas_bound: u64, + #[case] expect_failure: bool, +) { + let mut block_context = BlockContext::create_for_account_testing(); + block_context.block_info.gas_prices.strk_l1_gas_price = gas_price; + block_context.block_info.gas_prices.strk_l1_data_gas_price = data_gas_price; + + let account = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo0); + let mut state = test_state(&block_context.chain_info, BALANCE, &[(account, 1)]); + let tx = account_invoke_tx(invoke_tx_args! { + sender_address: account.get_instance_address(0), + resource_bounds: l1_resource_bounds(gas_bound, gas_price * 10), + version: TransactionVersion::THREE + }); + let actual_cost = ActualCost { + actual_fee: Fee(7), + actual_resources: ResourcesMapping(HashMap::from([ + (constants::GAS_USAGE.to_string(), l1_gas_used), + (constants::BLOB_GAS_USAGE.to_string(), l1_data_gas_used), + ])), + }; + let report = PostExecutionReport::new( + &mut state, + &block_context, + &tx.get_account_tx_context(), + &actual_cost, + true, + ) + .unwrap(); + + if expect_failure { + let error = report.error().unwrap(); + let expected_actual_amount = + l1_gas_used as u128 + (l1_data_gas_used as u128 * data_gas_price) / gas_price; + assert_matches!( + error, FeeCheckError::MaxL1GasAmountExceeded { max_amount, actual_amount } + if max_amount == gas_bound as u128 && actual_amount == expected_actual_amount + ) + } else { + assert_matches!(report.error(), None); + } +} From 174a0c9588069032ca03e57b0adc8b430ddf0e0b Mon Sep 17 00:00:00 2001 From: zuphitf <51879558+zuphitf@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:52:50 +0200 Subject: [PATCH 04/10] test: add cairo0 variants to the new stack trace regression tests (#1371) --- .../compiled/test_contract_compiled.json | 515 +++++++++++++----- .../cairo0/test_contract.cairo | 57 +- .../src/execution/entry_point_test.rs | 112 +++- 3 files changed, 535 insertions(+), 149 deletions(-) diff --git a/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json b/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json index 95c6a08e0a..230eb2a39f 100644 --- a/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json +++ b/crates/blockifier/feature_contracts/cairo0/compiled/test_contract_compiled.json @@ -351,6 +351,26 @@ "outputs": [], "type": "function" }, + { + "inputs": [ + { + "name": "calldata_len", + "type": "felt" + }, + { + "name": "calldata", + "type": "felt*" + } + ], + "name": "invoke_call_chain", + "outputs": [ + { + "name": "res", + "type": "felt" + } + ], + "type": "function" + }, { "inputs": [], "name": "fail", @@ -598,19 +618,23 @@ ], "EXTERNAL": [ { - "offset": 1115, + "offset": 1228, "selector": "0x1143aa89c8e3ebf8ed14df2a3606c1cd2dd513fac8040b0f8ab441f5c52fe4" }, { - "offset": 1157, + "offset": 1270, "selector": "0x600c98a299d72ef1e09a2e1503206fbc76081233172c65f7e2438ef0069d8d" }, { - "offset": 1671, + "offset": 1144, + "selector": "0x62c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5" + }, + { + "offset": 1784, "selector": "0x679c22735055a10db4f275395763a3752a1e3a3043c192299ab6b574fba8d6" }, { - "offset": 1595, + "offset": 1708, "selector": "0x7772be8b80a8a33dc6c1f9a6ab820c02e537c73e859de67f288c70f92571bb" }, { @@ -618,7 +642,7 @@ "selector": "0xad451bd0dba3d8d97104e1bfc474f88605ccc7acbe1c846839a120fdf30d95" }, { - "offset": 1421, + "offset": 1534, "selector": "0xd47144c49bce05b6de6bce9d5ff0cc8da9420f8945453e20ef779cbea13ad4" }, { @@ -634,11 +658,11 @@ "selector": "0x120c24672855cfe872cb35256ea85172417f2aada7a22c15908906dc5f3c69d" }, { - "offset": 1388, + "offset": 1501, "selector": "0x127a04cfe41aceb22fc022bce0c5c70f2d860a7c7c054681bd821cdc18e6dbc" }, { - "offset": 1748, + "offset": 1861, "selector": "0x12ead94ae9d3f9d2bdb6b847cf255f1f398193a1f88884a0ae8e18f24a037b6" }, { @@ -646,7 +670,7 @@ "selector": "0x137a07fa9c479e27114b8ae1fbf252f2065cf91a0d8615272e060a7ccf37309" }, { - "offset": 1279, + "offset": 1392, "selector": "0x167ac610845cc0ab1501b38169a7e50f1bf60602d3c2a961b30987454f97812" }, { @@ -654,7 +678,7 @@ "selector": "0x169f135eddda5ab51886052d777a57f2ea9c162d713691b5e04a6d4ed71d47f" }, { - "offset": 1712, + "offset": 1825, "selector": "0x1ae1a515cf2d214b29bdf63a79ee2d490efd4dd1acc99d383a8e549c3cecb5d" }, { @@ -666,7 +690,7 @@ "selector": "0x1b47f727a0668d8593c5bb115d5b53a470f29833fd4d598e748f68e65f4f003" }, { - "offset": 1358, + "offset": 1471, "selector": "0x1de4779362d5ca708d55fe1d4d499501b7f692730d2e01656e9180708985e07" }, { @@ -674,19 +698,19 @@ "selector": "0x27c3334165536f239cfd400ed956eabff55fc60de4fb56728b6a4f6b87db01c" }, { - "offset": 1224, + "offset": 1337, "selector": "0x309687d54611a7db521175c78ba48b082df1372350d2529981a8c0dd09a6529" }, { - "offset": 1627, + "offset": 1740, "selector": "0x30f842021fbf02caf80d09a113997c1e00a32870eee0c6136bed27acb348bea" }, { - "offset": 1547, + "offset": 1660, "selector": "0x317eb442b72a9fae758d4fb26830ed0d9f31c8e7da4dbff4e8c59ea6a158e7f" }, { - "offset": 1064, + "offset": 1177, "selector": "0x32564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25" }, { @@ -694,7 +718,7 @@ "selector": "0x3307b3297ab2ab7a46a9b7d139a52dddf9c343e9a0a3ac69c5b4048d80e3aaf" }, { - "offset": 1303, + "offset": 1416, "selector": "0x33ce93a3eececa5c9fc70da05f4aff3b00e1820b79587924d514bc76788991a" }, { @@ -726,11 +750,11 @@ "selector": "0x3b097c62d3e4b85742aadd0dfb823f96134b886ec13bda57b68faf86f294d97" }, { - "offset": 1255, + "offset": 1368, "selector": "0x3dc5da2d6d1275aeed57f43461d31967b0fed58bfe739b4ffad4091e89c4b03" }, { - "offset": 1090, + "offset": 1203, "selector": "0x3eb640b15f75fcc06d43182cdb94ed38c8e71755d5fb57c16dd673b466db1d4" } ], @@ -1805,6 +1829,119 @@ "0x0", "0x48127ff97fff8000", "0x208b7fff7fff7ffe", + "0x482680017ffc8000", + "0x800000000000011000000000000000000000000000000000000000000000000", + "0x48527fff7ffc8000", + "0x482680017ffc8000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffff", + "0x48507fff7ffe8000", + "0x20680017fff7fff", + "0x8", + "0x48297ffc80007ffc", + "0x480680017fff8000", + "0x1", + "0x480a7ffb7fff8000", + "0x48507ffd80007ffe", + "0x208b7fff7fff7ffe", + "0x480280027ffd8000", + "0x20680017fff7fff", + "0xf", + "0x480a7ffb7fff8000", + "0x480280007ffd8000", + "0x480280017ffd8000", + "0x482680017ffc8000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffe", + "0x482680017ffd8000", + "0x3", + "0x1104800180018000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffbe4", + "0x48127ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x480280027ffd8000", + "0x482480017fff8000", + "0x800000000000011000000000000000000000000000000000000000000000000", + "0x20680017fff7fff", + "0xf", + "0x480a7ffb7fff8000", + "0x480280007ffd8000", + "0x480280017ffd8000", + "0x482680017ffc8000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffe", + "0x482680017ffd8000", + "0x3", + "0x1104800180018000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffbde", + "0x48127ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x480280017ffd8000", + "0x482480017fff8000", + "0x79d37ca8d2d7358cb5c21c3e16b6885be6eb965b573d92e2843aacfa19bf12c", + "0x20680017fff7fff", + "0xa", + "0x480a7ffb7fff8000", + "0x482680017ffc8000", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffe", + "0x482680017ffd8000", + "0x3", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffc7", + "0x208b7fff7fff7ffe", + "0x480280017ffd8000", + "0x482480017fff8000", + "0x4da9b281f01f6f3b64b3df0b9cde6e1b1296794066c7b6786540106b9a210dc", + "0x20680017fff7fff", + "0x8", + "0x1104800180018000", + "0x2f", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x4003800080007ffc", + "0x4826800180008000", + "0x1", + "0x480a7ffd7fff8000", + "0x4828800080007ffe", + "0x480a80007fff8000", + "0x208b7fff7fff7ffe", + "0x480280027ffb8000", + "0x480280007ffd8000", + "0x400080007ffe7fff", + "0x482680017ffd8000", + "0x1", + "0x480280007ffd8000", + "0x48307fff7ffe8000", + "0x402a7ffd7ffc7fff", + "0x480280007ffb8000", + "0x480280007ffd8000", + "0x482680017ffd8000", + "0x1", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffa0", + "0x480280027ffb8000", + "0x48127ffe7fff8000", + "0x482480017ffe8000", + "0x1", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffe6", + "0x48127ff47fff8000", + "0x480280017ffb8000", + "0x48127ffb7fff8000", + "0x480280037ffb8000", + "0x480280047ffb8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", "0x480680017fff8000", "0x1", "0x400680017fff7fff", @@ -1889,7 +2026,7 @@ "0x482680017ffd8000", "0x800000000000011000000000000000000000000000000000000000000000000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffba4", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb33", "0x482480017fff8000", "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffe", "0x40137fff7fff8000", @@ -1900,7 +2037,7 @@ "0x3", "0x480a80007fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb9e", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb2d", "0x48127ffd7fff8000", "0x208b7fff7fff7ffe", "0x482680017ffd8000", @@ -1929,15 +2066,15 @@ "0x480a7ff97fff8000", "0x480a7ffa7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffbd1", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb60", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffba3", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb32", "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", "0x480680017fff8000", "0x0", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb74", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb03", "0x482480017fff8000", "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffffd", "0x40137fff7fff8000", @@ -1949,7 +2086,7 @@ "0x4", "0x480a80007fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb6d", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffafc", "0x208b7fff7fff7ffe", "0x40780017fff7fff", "0x3", @@ -1965,7 +2102,7 @@ "0x480a7ffc7fff8000", "0x480a7ffb7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb48", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffad7", "0x480a80017fff8000", "0x4829800080008002", "0x480a80007fff8000", @@ -1997,7 +2134,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb6f", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffafe", "0x400a7ffd7fff7fff", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2021,7 +2158,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb5e", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaed", "0x400a7ffd7fff7fff", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2045,7 +2182,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb38", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffac7", "0x400a7ffd7fff7fff", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2069,7 +2206,7 @@ "0x208b7fff7fff7ffe", "0x480a7ff67fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb4d", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffadc", "0x480080007fff8000", "0x480080017ffe8000", "0x480080027ffd8000", @@ -2091,17 +2228,17 @@ "0x12c", "0x48127ffb7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb2f", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffabe", "0x480680017fff8000", "0x137", "0x48127ff67fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb2a", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffab9", "0x480680017fff8000", "0x142", "0x48127ff17fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb25", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffab4", "0x480a7ff77fff8000", "0x208b7fff7fff7ffe", "0x482680017ffd8000", @@ -2130,7 +2267,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffb10", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa9f", "0x400180007fff7ffd", "0x48127ffe7fff8000", "0x208b7fff7fff7ffe", @@ -2158,13 +2295,13 @@ "0x480680017fff8000", "0x0", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaec", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa7b", "0x480680017fff8000", "0xf", "0x480680017fff8000", "0x1", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffae6", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa75", "0x480a7ffd7fff8000", "0x208b7fff7fff7ffe", "0x402b7ffd7ffc7ffd", @@ -2186,7 +2323,7 @@ "0x40780017fff7fff", "0x1", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa62", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9f1", "0x40137fff7fff8000", "0x4003800080007ffb", "0x4003800180007ffc", @@ -2200,7 +2337,7 @@ "0x4828800080007ffc", "0x480a80007fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa72", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa01", "0x48127ffd7fff8000", "0x480a7ff97fff8000", "0x208b7fff7fff7ffe", @@ -2209,11 +2346,11 @@ "0x2691cb735b18f3f656c3b82bd97a32b65d15019b64117513f8604d1e06fe58b", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa4e", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9dd", "0x480a7ffc7fff8000", "0x48127ffe7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffad8", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa67", "0x48127fe17fff8000", "0x48127ffd7fff8000", "0x48127ffd7fff8000", @@ -2226,12 +2363,12 @@ "0x480a7ffa7fff8000", "0x48127ffe7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffaa0", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa2f", "0x48127ffe7fff8000", "0x482480017ff78000", "0x1", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa9b", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa2a", "0x48127ffe7fff8000", "0x48127fee7fff8000", "0x48127fee7fff8000", @@ -2247,12 +2384,12 @@ "0x48127ffe7fff8000", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa93", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa22", "0x482480017ff88000", "0x1", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa8e", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa1d", "0x48127ff07fff8000", "0x48127ff07fff8000", "0x208b7fff7fff7ffe", @@ -2269,12 +2406,12 @@ "0x48127ffe7fff8000", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa7d", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa0c", "0x482480017ff88000", "0x1", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa78", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa07", "0x48127ff07fff8000", "0x48127ff07fff8000", "0x208b7fff7fff7ffe", @@ -2325,12 +2462,12 @@ "0x48127ffd7fff8000", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa90", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa1f", "0x48127ffe7fff8000", "0x48127ff77fff8000", "0x480a7ffd7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa8b", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa1a", "0x48127fed7fff8000", "0x48127fed7fff8000", "0x48127fed7fff8000", @@ -2407,7 +2544,7 @@ "0x480680017fff8000", "0x4b5810004d9272776dec83ecc20c19353453b956e594188890b48467cb53c19", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa80", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa0f", "0x480a7ffa7fff8000", "0x480a7ffb7fff8000", "0x480a7ffc7fff8000", @@ -2437,7 +2574,7 @@ "0x208b7fff7fff7ffe", "0x480a7ffc7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9c5", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff954", "0x400680017fff7ffe", "0x2", "0x48127ffd7fff8000", @@ -2485,14 +2622,14 @@ "0x400780017fff8001", "0x22", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff94f", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff8de", "0x480a7ffc7fff8000", "0x480a7ffd7fff8000", "0x480680017fff8000", "0x2", "0x48127ffb7fff8000", "0x1104800180018000", - "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffffa4a", + "0x800000000000010fffffffffffffffffffffffffffffffffffffffffffff9d9", "0x208b7fff7fff7ffe", "0x482680017ffd8000", "0x1", @@ -3204,7 +3341,25 @@ } } ], - "1067": [ + "1135": [ + { + "accessible_scopes": [ + "__main__", + "__main__", + "__wrappers__", + "__wrappers__.invoke_call_chain_encode_return" + ], + "code": "memory[ap] = segments.add()", + "flow_tracking_data": { + "ap_tracking": { + "group": 91, + "offset": 0 + }, + "reference_ids": {} + } + } + ], + "1180": [ { "accessible_scopes": [ "__main__", @@ -3215,14 +3370,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 89, + "group": 95, "offset": 3 }, "reference_ids": {} } } ], - "1096": [ + "1209": [ { "accessible_scopes": [ "__main__", @@ -3233,14 +3388,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 93, + "group": 99, "offset": 0 }, "reference_ids": {} } } ], - "1121": [ + "1234": [ { "accessible_scopes": [ "__main__", @@ -3251,14 +3406,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 97, + "group": 103, "offset": 0 }, "reference_ids": {} } } ], - "1166": [ + "1279": [ { "accessible_scopes": [ "__main__", @@ -3269,14 +3424,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 100, + "group": 106, "offset": 0 }, "reference_ids": {} } } ], - "1205": [ + "1318": [ { "accessible_scopes": [ "__main__", @@ -3287,14 +3442,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 102, + "group": 108, "offset": 0 }, "reference_ids": {} } } ], - "1262": [ + "1375": [ { "accessible_scopes": [ "__main__", @@ -3305,14 +3460,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 107, + "group": 113, "offset": 12 }, "reference_ids": {} } } ], - "1286": [ + "1399": [ { "accessible_scopes": [ "__main__", @@ -3323,14 +3478,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 109, + "group": 115, "offset": 12 }, "reference_ids": {} } } ], - "1310": [ + "1423": [ { "accessible_scopes": [ "__main__", @@ -3341,14 +3496,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 111, + "group": 117, "offset": 12 }, "reference_ids": {} } } ], - "1371": [ + "1484": [ { "accessible_scopes": [ "__main__", @@ -3359,14 +3514,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 113, + "group": 119, "offset": 45 }, "reference_ids": {} } } ], - "1395": [ + "1508": [ { "accessible_scopes": [ "__main__", @@ -3377,14 +3532,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 115, + "group": 121, "offset": 12 }, "reference_ids": {} } } ], - "1426": [ + "1539": [ { "accessible_scopes": [ "__main__", @@ -3395,14 +3550,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 117, + "group": 123, "offset": 18 }, "reference_ids": {} } } ], - "1558": [ + "1671": [ { "accessible_scopes": [ "__main__", @@ -3413,14 +3568,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 125, + "group": 131, "offset": 145 }, "reference_ids": {} } } ], - "1607": [ + "1720": [ { "accessible_scopes": [ "__main__", @@ -3431,14 +3586,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 127, + "group": 133, "offset": 161 }, "reference_ids": {} } } ], - "1638": [ + "1751": [ { "accessible_scopes": [ "__main__", @@ -3449,14 +3604,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 129, + "group": 135, "offset": 35 }, "reference_ids": {} } } ], - "1678": [ + "1791": [ { "accessible_scopes": [ "__main__", @@ -3467,14 +3622,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 133, + "group": 139, "offset": 0 }, "reference_ids": {} } } ], - "1721": [ + "1834": [ { "accessible_scopes": [ "__main__", @@ -3485,14 +3640,14 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 135, + "group": 141, "offset": 153 }, "reference_ids": {} } } ], - "1755": [ + "1868": [ { "accessible_scopes": [ "__main__", @@ -3503,7 +3658,7 @@ "code": "memory[ap] = segments.add()", "flow_tracking_data": { "ap_tracking": { - "group": 137, + "group": 143, "offset": 17 }, "reference_ids": {} @@ -3592,7 +3747,7 @@ }, "__main__.MyContract.xor_counters": { "decorators": [], - "pc": 1437, + "pc": 1550, "type": "function" }, "__main__.MyContract.xor_counters.Args": { @@ -3645,7 +3800,7 @@ "decorators": [ "external" ], - "pc": 1689, + "pc": 1802, "type": "function" }, "__main__.add_signature_to_counters.Args": { @@ -3690,7 +3845,7 @@ "decorators": [ "external" ], - "pc": 1532, + "pc": 1645, "type": "function" }, "__main__.advance_counter.Args": { @@ -3792,7 +3947,7 @@ "decorators": [ "external" ], - "pc": 1618, + "pc": 1731, "type": "function" }, "__main__.call_xor_counters.Args": { @@ -3911,7 +4066,7 @@ }, "__main__.ec_point.addr": { "decorators": [], - "pc": 1510, + "pc": 1623, "type": "function" }, "__main__.ec_point.addr.Args": { @@ -3961,7 +4116,7 @@ }, "__main__.ec_point.write": { "decorators": [], - "pc": 1515, + "pc": 1628, "type": "function" }, "__main__.ec_point.write.Args": { @@ -4006,7 +4161,7 @@ "decorators": [ "external" ], - "pc": 1059, + "pc": 1172, "type": "function" }, "__main__.fail.Args": { @@ -4088,6 +4243,47 @@ "destination": "starkware.starknet.common.syscalls.get_tx_signature", "type": "alias" }, + "__main__.invoke_call_chain": { + "decorators": [ + "external" + ], + "pc": 1059, + "type": "function" + }, + "__main__.invoke_call_chain.Args": { + "full_name": "__main__.invoke_call_chain.Args", + "members": { + "calldata": { + "cairo_type": "felt*", + "offset": 1 + }, + "calldata_len": { + "cairo_type": "felt", + "offset": 0 + } + }, + "size": 2, + "type": "struct" + }, + "__main__.invoke_call_chain.ImplicitArgs": { + "full_name": "__main__.invoke_call_chain.ImplicitArgs", + "members": { + "syscall_ptr": { + "cairo_type": "felt*", + "offset": 0 + } + }, + "size": 1, + "type": "struct" + }, + "__main__.invoke_call_chain.Return": { + "cairo_type": "(res: felt)", + "type": "type_definition" + }, + "__main__.invoke_call_chain.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, "__main__.library_call": { "destination": "starkware.starknet.common.syscalls.library_call", "type": "alias" @@ -4268,7 +4464,7 @@ "decorators": [ "external" ], - "pc": 1107, + "pc": 1220, "type": "function" }, "__main__.recurse.Args": { @@ -4300,7 +4496,7 @@ "decorators": [ "external" ], - "pc": 1078, + "pc": 1191, "type": "function" }, "__main__.recursive_fail.Args": { @@ -4332,7 +4528,7 @@ "decorators": [ "external" ], - "pc": 1132, + "pc": 1245, "type": "function" }, "__main__.recursive_syscall.Args": { @@ -4413,7 +4609,7 @@ "decorators": [ "external" ], - "pc": 1732, + "pc": 1845, "type": "function" }, "__main__.send_message.Args": { @@ -4636,7 +4832,7 @@ "decorators": [ "external" ], - "pc": 1406, + "pc": 1519, "type": "function" }, "__main__.test_count_actual_storage_changes.Args": { @@ -4729,7 +4925,7 @@ "decorators": [ "external" ], - "pc": 1649, + "pc": 1762, "type": "function" }, "__main__.test_ec_op.Args": { @@ -4773,7 +4969,7 @@ "decorators": [ "external" ], - "pc": 1249, + "pc": 1362, "type": "function" }, "__main__.test_get_block_number.Args": { @@ -4810,7 +5006,7 @@ "decorators": [ "external" ], - "pc": 1273, + "pc": 1386, "type": "function" }, "__main__.test_get_block_timestamp.Args": { @@ -4847,7 +5043,7 @@ "decorators": [ "external" ], - "pc": 1297, + "pc": 1410, "type": "function" }, "__main__.test_get_sequencer_address.Args": { @@ -4884,7 +5080,7 @@ "decorators": [ "external" ], - "pc": 1321, + "pc": 1434, "type": "function" }, "__main__.test_get_tx_info.Args": { @@ -5193,7 +5389,7 @@ "decorators": [ "external" ], - "pc": 1382, + "pc": 1495, "type": "function" }, "__main__.test_tx_version.Args": { @@ -5230,7 +5426,7 @@ "decorators": [ "external" ], - "pc": 1177, + "pc": 1290, "type": "function" }, "__main__.test_write_and_transfer.Args": { @@ -5308,7 +5504,7 @@ }, "__main__.two_counters.addr": { "decorators": [], - "pc": 1458, + "pc": 1571, "type": "function" }, "__main__.two_counters.addr.Args": { @@ -5355,7 +5551,7 @@ }, "__main__.two_counters.read": { "decorators": [], - "pc": 1472, + "pc": 1585, "type": "function" }, "__main__.two_counters.read.Args": { @@ -5406,7 +5602,7 @@ }, "__main__.two_counters.write": { "decorators": [], - "pc": 1492, + "pc": 1605, "type": "function" }, "__main__.two_counters.write.Args": { @@ -5596,7 +5792,7 @@ "decorators": [ "external" ], - "pc": 1569, + "pc": 1682, "type": "function" }, "__main__.xor_counters.Args": { @@ -5645,7 +5841,7 @@ "decorators": [ "external" ], - "pc": 1712, + "pc": 1825, "type": "function" }, "__wrappers__.add_signature_to_counters.Args": { @@ -5680,7 +5876,7 @@ "decorators": [ "external" ], - "pc": 1547, + "pc": 1660, "type": "function" }, "__wrappers__.advance_counter.Args": { @@ -5750,7 +5946,7 @@ "decorators": [ "external" ], - "pc": 1627, + "pc": 1740, "type": "function" }, "__wrappers__.call_xor_counters.Args": { @@ -5820,7 +6016,7 @@ "decorators": [ "external" ], - "pc": 1064, + "pc": 1177, "type": "function" }, "__wrappers__.fail.Args": { @@ -5886,11 +6082,80 @@ "destination": "starkware.cairo.common.memcpy.memcpy", "type": "alias" }, + "__wrappers__.invoke_call_chain": { + "decorators": [ + "external" + ], + "pc": 1144, + "type": "function" + }, + "__wrappers__.invoke_call_chain.Args": { + "full_name": "__wrappers__.invoke_call_chain.Args", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.invoke_call_chain.ImplicitArgs": { + "full_name": "__wrappers__.invoke_call_chain.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.invoke_call_chain.Return": { + "cairo_type": "(syscall_ptr: felt*, pedersen_ptr: felt, range_check_ptr: felt, bitwise_ptr: felt, ec_op_ptr: felt, size: felt, retdata: felt*)", + "type": "type_definition" + }, + "__wrappers__.invoke_call_chain.SIZEOF_LOCALS": { + "type": "const", + "value": 0 + }, + "__wrappers__.invoke_call_chain.__wrapped_func": { + "destination": "__main__.invoke_call_chain", + "type": "alias" + }, + "__wrappers__.invoke_call_chain_encode_return": { + "decorators": [], + "pc": 1135, + "type": "function" + }, + "__wrappers__.invoke_call_chain_encode_return.Args": { + "full_name": "__wrappers__.invoke_call_chain_encode_return.Args", + "members": { + "range_check_ptr": { + "cairo_type": "felt", + "offset": 1 + }, + "ret_value": { + "cairo_type": "(res: felt)", + "offset": 0 + } + }, + "size": 2, + "type": "struct" + }, + "__wrappers__.invoke_call_chain_encode_return.ImplicitArgs": { + "full_name": "__wrappers__.invoke_call_chain_encode_return.ImplicitArgs", + "members": {}, + "size": 0, + "type": "struct" + }, + "__wrappers__.invoke_call_chain_encode_return.Return": { + "cairo_type": "(range_check_ptr: felt, data_len: felt, data: felt*)", + "type": "type_definition" + }, + "__wrappers__.invoke_call_chain_encode_return.SIZEOF_LOCALS": { + "type": "const", + "value": 1 + }, + "__wrappers__.invoke_call_chain_encode_return.memcpy": { + "destination": "starkware.cairo.common.memcpy.memcpy", + "type": "alias" + }, "__wrappers__.recurse": { "decorators": [ "external" ], - "pc": 1115, + "pc": 1228, "type": "function" }, "__wrappers__.recurse.Args": { @@ -5925,7 +6190,7 @@ "decorators": [ "external" ], - "pc": 1090, + "pc": 1203, "type": "function" }, "__wrappers__.recursive_fail.Args": { @@ -5960,7 +6225,7 @@ "decorators": [ "external" ], - "pc": 1157, + "pc": 1270, "type": "function" }, "__wrappers__.recursive_syscall.Args": { @@ -6064,7 +6329,7 @@ "decorators": [ "external" ], - "pc": 1748, + "pc": 1861, "type": "function" }, "__wrappers__.send_message.Args": { @@ -6239,7 +6504,7 @@ "decorators": [ "external" ], - "pc": 1421, + "pc": 1534, "type": "function" }, "__wrappers__.test_count_actual_storage_changes.Args": { @@ -6343,7 +6608,7 @@ "decorators": [ "external" ], - "pc": 1671, + "pc": 1784, "type": "function" }, "__wrappers__.test_ec_op.Args": { @@ -6378,7 +6643,7 @@ "decorators": [ "external" ], - "pc": 1255, + "pc": 1368, "type": "function" }, "__wrappers__.test_get_block_number.Args": { @@ -6413,7 +6678,7 @@ "decorators": [ "external" ], - "pc": 1279, + "pc": 1392, "type": "function" }, "__wrappers__.test_get_block_timestamp.Args": { @@ -6448,7 +6713,7 @@ "decorators": [ "external" ], - "pc": 1303, + "pc": 1416, "type": "function" }, "__wrappers__.test_get_sequencer_address.Args": { @@ -6483,7 +6748,7 @@ "decorators": [ "external" ], - "pc": 1358, + "pc": 1471, "type": "function" }, "__wrappers__.test_get_tx_info.Args": { @@ -6831,7 +7096,7 @@ "decorators": [ "external" ], - "pc": 1388, + "pc": 1501, "type": "function" }, "__wrappers__.test_tx_version.Args": { @@ -6866,7 +7131,7 @@ "decorators": [ "external" ], - "pc": 1224, + "pc": 1337, "type": "function" }, "__wrappers__.test_write_and_transfer.Args": { @@ -6895,7 +7160,7 @@ }, "__wrappers__.test_write_and_transfer_encode_return": { "decorators": [], - "pc": 1205, + "pc": 1318, "type": "function" }, "__wrappers__.test_write_and_transfer_encode_return.Args": { @@ -7075,7 +7340,7 @@ "decorators": [ "external" ], - "pc": 1595, + "pc": 1708, "type": "function" }, "__wrappers__.xor_counters.Args": { diff --git a/crates/blockifier/feature_contracts/cairo0/test_contract.cairo b/crates/blockifier/feature_contracts/cairo0/test_contract.cairo index 9d4d743a9f..adb6df80e9 100644 --- a/crates/blockifier/feature_contracts/cairo0/test_contract.cairo +++ b/crates/blockifier/feature_contracts/cairo0/test_contract.cairo @@ -130,7 +130,7 @@ func test_nested_library_call{syscall_ptr: felt*}( ) -> (result: felt) { alloc_locals; assert calldata_len = 2; - local nested_library_calldata: felt* = new ( + local nested_library_calldata: felt* = new( class_hash, nested_selector, 2, calldata[0] + 1, calldata[1] + 1 ); let (retdata_size: felt, retdata: felt*) = library_call( @@ -220,6 +220,57 @@ func foo() { return (); } +@external +func invoke_call_chain{syscall_ptr: felt*}(calldata_len: felt, calldata: felt*) -> (res: felt) { + // If the chain is too short, fail with division by zero. + if ((calldata_len * (calldata_len - 1) * (calldata_len - 2)) == 0) { + tempvar zero = calldata_len - calldata_len; + return (res=1 / zero); + } + + // Pop the parameters for the next call in the chain. + let contract_id = calldata[0]; + let function_selector = calldata[1]; + let call_type = calldata[2]; + + let calldata = &calldata[3]; + let calldata_len = calldata_len - 3; + + // Choose call type according to the following options: + // 0 - call contract syscall. 1 - library call syscall. other - regular inner call. + // The remaining items of the call_chain array are passed on as calldata. + if (call_type == 0) { + call_contract( + contract_address=contract_id, + function_selector=function_selector, + calldata_size=calldata_len, + calldata=calldata, + ); + return (res=0); + } + if (call_type == 1) { + library_call( + class_hash=contract_id, + function_selector=function_selector, + calldata_size=calldata_len, + calldata=calldata, + ); + return (res=0); + } + + let invoke_call_chain_selector = 0x0062c83572d28cb834a3de3c1e94977a4191469a4a8c26d1d7bc55305e640ed5; + let fail_selector = 0x032564d7e0fe091d49b4c20f4632191e4ed6986bf993849879abfef9465def25; + if (function_selector == invoke_call_chain_selector) { + return invoke_call_chain(calldata_len=calldata_len, calldata=calldata); + } + if (function_selector == fail_selector) { + fail(); + return (res=0); + } + + return (res=0); +} + @external func fail() { assert 0 = 1; @@ -246,7 +297,9 @@ func recurse(depth: felt) { } @external -func recursive_syscall{syscall_ptr: felt*}(contract_address: felt, function_selector: felt, depth: felt) { +func recursive_syscall{syscall_ptr: felt*}( + contract_address: felt, function_selector: felt, depth: felt +) { alloc_locals; if (depth == 0) { return (); diff --git a/crates/blockifier/src/execution/entry_point_test.rs b/crates/blockifier/src/execution/entry_point_test.rs index 0f11f9b6c9..38b1e774b2 100644 --- a/crates/blockifier/src/execution/entry_point_test.rs +++ b/crates/blockifier/src/execution/entry_point_test.rs @@ -632,10 +632,10 @@ Unknown location (pc=0:{call_location}) Unknown location (pc=0:{entry_point_location}) Error in the called contract ({}): -Error at pc=0:1061: +Error at pc=0:1174: An ASSERT_EQ instruction failed: 1 != 0. Cairo traceback (most recent call last): -Unknown location (pc=0:1065) +Unknown location (pc=0:1178) ", *test_contract_address.0.key(), *test_contract_address_2.0.key(), @@ -679,14 +679,18 @@ Execution failed. Failure reason: 0x6661696c ('fail'). } #[rstest] -#[case("invoke_call_chain", "0x75382069732030 ('u8 is 0')")] -#[case("fail", "0x6661696c ('fail')")] +#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:37", (1071_u16, 1117_u16))] +#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", (1174_u16, 1125_u16))] +#[case(CairoVersion::Cairo1, "invoke_call_chain", "0x75382069732030 ('u8 is 0')", (0_u16, 0_u16))] +#[case(CairoVersion::Cairo1, "fail", "0x6661696c ('fail')", (0_u16, 0_u16))] fn test_trace_callchain_ends_with_regular_call( + #[case] cairo_version: CairoVersion, #[case] last_func_name: &str, #[case] expected_error: &str, + #[case] expected_pc_locations: (u16, u16), ) { let chain_info = ChainInfo::create_for_testing(); - let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1); + let test_contract = FeatureContract::TestContract(cairo_version); let mut state = test_state(&chain_info, BALANCE, &[(test_contract, 1)]); let test_contract_address = test_contract.get_instance_address(0); let contract_address_felt = *test_contract_address.0.key(); @@ -713,37 +717,69 @@ fn test_trace_callchain_ends_with_regular_call( let entry_point_offset = get_entry_point_offset(&test_contract.get_class(), entry_point_call.entry_point_selector); - let pc_location = entry_point_offset.0 + INNER_CALL_CONTRACT_IN_CALL_CHAIN_OFFSET; - let expected_trace = format!( - "Error in the called contract ({contract_address_felt}): + let expected_trace = match cairo_version { + CairoVersion::Cairo0 => { + let call_location = entry_point_offset.0 + 12; + let entry_point_location = entry_point_offset.0 - 61; + format!( + "Error in the called contract ({contract_address_felt}): +Error at pc=0:37: +Got an exception while executing a hint. +Cairo traceback (most recent call last): +Unknown location (pc=0:{call_location}) +Unknown location (pc=0:{entry_point_location}) + +Error in the called contract ({contract_address_felt}): +Error at pc=0:{}: +{expected_error} +Cairo traceback (most recent call last): +Unknown location (pc=0:{call_location}) +Unknown location (pc=0:{}) +", + expected_pc_locations.0, expected_pc_locations.1 + ) + } + CairoVersion::Cairo1 => { + let pc_location = entry_point_offset.0 + INNER_CALL_CONTRACT_IN_CALL_CHAIN_OFFSET; + format!( + "Error in the called contract ({contract_address_felt}): Error at pc=0:7981: Got an exception while executing a hint: Hint Error: Execution failed. Failure reason: \ - {expected_error}. + {expected_error}. Cairo traceback (most recent call last): Unknown location (pc=0:{pc_location}) Error in the called contract ({contract_address_felt}): Execution failed. Failure reason: {expected_error}. " - ); + ) + } + }; let actual_trace = entry_point_call.execute_directly(&mut state).unwrap_err().to_string(); assert_eq!(actual_trace, expected_trace); } #[rstest] -#[case("invoke_call_chain", "0x75382069732030 ('u8 is 0')", 1_u8)] -#[case("fail", "0x6661696c ('fail')", 0_u8)] +#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:23", 1_u8, 0_u8, (37_u16, 1083_u16, 1071_u16, 1156_u16))] +#[case(CairoVersion::Cairo0, "invoke_call_chain", "Couldn't compute operand op0. Unknown value for memory cell 1:23", 1_u8, 1_u8, (49_u16, 1101_u16, 1071_u16, 1156_u16))] +#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", 0_u8, 0_u8, (37_u16, 1083_u16, 1174_u16, 1178_u16))] +#[case(CairoVersion::Cairo0, "fail", "An ASSERT_EQ instruction failed: 1 != 0.", 0_u8, 1_u8, (49_u16, 1101_u16, 1174_u16, 1178_u16))] +#[case(CairoVersion::Cairo1, "invoke_call_chain", "0x75382069732030 ('u8 is 0')", 1_u8, 0_u8, (7981_u16, 0_u16, 0_u16, 0_u16))] +#[case(CairoVersion::Cairo1, "invoke_call_chain", "0x75382069732030 ('u8 is 0')", 1_u8, 1_u8, (8070_u16, 0_u16, 0_u16, 0_u16))] +#[case(CairoVersion::Cairo1, "fail", "0x6661696c ('fail')", 0_u8, 0_u8, (7981_u16, 0_u16, 0_u16, 0_u16))] +#[case(CairoVersion::Cairo1, "fail", "0x6661696c ('fail')", 0_u8, 1_u8, (8070_u16, 0_u16, 0_u16, 0_u16))] fn test_trace_call_chain_with_syscalls( - #[values((0_u8, 7981_u16), (1_u8, 8070_u16))] call_type_expected_pc: (u8, u16), + #[case] cairo_version: CairoVersion, #[case] last_func_name: &str, #[case] expected_error: &str, #[case] calldata_extra_length: u8, + #[case] call_type: u8, + #[case] expected_pcs: (u16, u16, u16, u16), ) { - let (call_type, expected_pc) = call_type_expected_pc; let chain_info = ChainInfo::create_for_testing(); - let test_contract = FeatureContract::TestContract(CairoVersion::Cairo1); + let test_contract = FeatureContract::TestContract(cairo_version); let mut state = test_state(&chain_info, BALANCE, &[(test_contract, 1)]); let test_contract_address = test_contract.get_instance_address(0); let test_contract_hash = test_contract.get_class_hash().0; @@ -778,26 +814,58 @@ fn test_trace_call_chain_with_syscalls( let entry_point_offset = get_entry_point_offset(&test_contract.get_class(), entry_point_call.entry_point_selector); - let pc_location = entry_point_offset.0 + INNER_CALL_CONTRACT_IN_CALL_CHAIN_OFFSET; - let expected_trace = format!( - "Error in the called contract ({address_felt}): + let expected_trace = match cairo_version { + CairoVersion::Cairo0 => { + let call_location = entry_point_offset.0 + 12; + let entry_point_location = entry_point_offset.0 - 61; + format!( + "Error in the called contract ({address_felt}): +Error at pc=0:37: +Got an exception while executing a hint. +Cairo traceback (most recent call last): +Unknown location (pc=0:{call_location}) +Unknown location (pc=0:{entry_point_location}) + +Error in the called contract ({address_felt}): +Error at pc=0:{}: +Got an exception while executing a hint. +Cairo traceback (most recent call last): +Unknown location (pc=0:{call_location}) +Unknown location (pc=0:{}) + +Error in the called contract ({address_felt}): +Error at pc=0:{}: +{expected_error} +Cairo traceback (most recent call last): +Unknown location (pc=0:{}) +", + expected_pcs.0, expected_pcs.1, expected_pcs.2, expected_pcs.3 + ) + } + CairoVersion::Cairo1 => { + let pc_location = entry_point_offset.0 + INNER_CALL_CONTRACT_IN_CALL_CHAIN_OFFSET; + format!( + "Error in the called contract ({address_felt}): Error at pc=0:7981: Got an exception while executing a hint. Cairo traceback (most recent call last): Unknown location (pc=0:{pc_location}) Error in the called contract ({address_felt}): -Error at pc=0:{expected_pc}: +Error at pc=0:{}: Got an exception while executing a hint: Hint Error: Execution failed. Failure reason: \ - {expected_error}. + {expected_error}. Cairo traceback (most recent call last): Unknown location (pc=0:{pc_location}) Error in the called contract ({address_felt}): Execution failed. Failure reason: {expected_error}. -" - ); +", + expected_pcs.0 + ) + } + }; let actual_trace = entry_point_call.execute_directly(&mut state).unwrap_err().to_string(); assert_eq!(actual_trace, expected_trace); From e8c07a16ccf0935abb284a3b30b6e8d49edde4e8 Mon Sep 17 00:00:00 2001 From: Ayelet Zilber <138376632+ayeletstarkware@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:44:16 +0200 Subject: [PATCH 05/10] feat(fee): calculates messages size field (#1290) --- crates/blockifier/src/execution/call_info.rs | 32 ++++++++++++-- crates/blockifier/src/fee/gas_usage.rs | 42 +++++-------------- crates/blockifier/src/fee/gas_usage_test.rs | 12 +++--- .../src/transaction/transaction_execution.rs | 3 +- .../src/transaction/transactions.rs | 5 +++ .../src/transaction_executor.rs | 21 ++++++++-- 6 files changed, 69 insertions(+), 46 deletions(-) diff --git a/crates/blockifier/src/execution/call_info.rs b/crates/blockifier/src/execution/call_info.rs index 104b6bc4d6..e723cb1735 100644 --- a/crates/blockifier/src/execution/call_info.rs +++ b/crates/blockifier/src/execution/call_info.rs @@ -7,6 +7,7 @@ use starknet_api::state::StorageKey; use starknet_api::transaction::{EventContent, L2ToL1Payload}; use crate::execution::entry_point::CallEntryPoint; +use crate::fee::gas_usage::get_message_segment_length; use crate::state::cached_state::StorageEntry; use crate::transaction::errors::TransactionExecutionError; use crate::transaction::objects::TransactionExecutionResult; @@ -28,6 +29,29 @@ pub struct OrderedEvent { pub event: EventContent, } +#[derive(Debug, Default, Eq, PartialEq)] +pub struct MessageL1CostInfo { + pub l2_to_l1_payload_lengths: Vec, + pub message_segment_length: usize, +} + +impl MessageL1CostInfo { + pub fn calculate<'a>( + call_infos: impl Iterator, + l1_handler_payload_size: Option, + ) -> TransactionExecutionResult { + let mut l2_to_l1_payload_lengths = Vec::new(); + for call_info in call_infos { + l2_to_l1_payload_lengths.extend(call_info.get_sorted_l2_to_l1_payload_lengths()?); + } + + let message_segment_length = + get_message_segment_length(&l2_to_l1_payload_lengths, l1_handler_payload_size); + + Ok(Self { l2_to_l1_payload_lengths, message_segment_length }) + } +} + #[cfg_attr(test, derive(Clone))] #[derive(Debug, Default, Eq, PartialEq)] pub struct MessageToL1 { @@ -99,9 +123,9 @@ impl CallInfo { /// Returns a list of Starknet L2ToL1Payload length collected during the execution, sorted /// by the order in which they were sent. - pub fn get_sorted_l2_to_l1_payloads_length(&self) -> TransactionExecutionResult> { + pub fn get_sorted_l2_to_l1_payload_lengths(&self) -> TransactionExecutionResult> { let n_messages = self.into_iter().map(|call| call.execution.l2_to_l1_messages.len()).sum(); - let mut starknet_l2_to_l1_payloads_length: Vec> = vec![None; n_messages]; + let mut starknet_l2_to_l1_payload_lengths: Vec> = vec![None; n_messages]; for call_info in self.into_iter() { for ordered_message_content in &call_info.execution.l2_to_l1_messages { @@ -113,12 +137,12 @@ impl CallInfo { max_order: n_messages, }); } - starknet_l2_to_l1_payloads_length[message_order] = + starknet_l2_to_l1_payload_lengths[message_order] = Some(ordered_message_content.message.payload.0.len()); } } - starknet_l2_to_l1_payloads_length.into_iter().enumerate().try_fold( + starknet_l2_to_l1_payload_lengths.into_iter().enumerate().try_fold( Vec::new(), |mut acc, (i, option)| match option { Some(value) => { diff --git a/crates/blockifier/src/fee/gas_usage.rs b/crates/blockifier/src/fee/gas_usage.rs index 12aa8080ee..fb0c7a11f1 100644 --- a/crates/blockifier/src/fee/gas_usage.rs +++ b/crates/blockifier/src/fee/gas_usage.rs @@ -5,7 +5,7 @@ use starknet_api::transaction::Fee; use super::fee_utils::{calculate_tx_l1_gas_usages, get_fee_by_l1_gas_usage}; use crate::abi::constants; use crate::block_context::BlockContext; -use crate::execution::call_info::CallInfo; +use crate::execution::call_info::{CallInfo, MessageL1CostInfo}; use crate::fee::eth_gas_constants; use crate::fee::os_resources::OS_RESOURCES; use crate::state::cached_state::StateChangesCount; @@ -19,23 +19,6 @@ use crate::transaction::objects::{ #[path = "gas_usage_test.rs"] pub mod test; -// TODO(Ayelet, 10/1/2024): Use to calculate message segment length in transaction_executer's -// execute -fn calculate_l2_to_l1_payloads_length_and_message_segment_length<'a>( - call_infos: impl Iterator, - l1_handler_payload_size: Option, -) -> TransactionExecutionResult<(Vec, usize)> { - let mut l2_to_l1_payloads_length = Vec::new(); - for call_info in call_infos { - l2_to_l1_payloads_length.extend(call_info.get_sorted_l2_to_l1_payloads_length()?); - } - - let message_segment_length = - get_message_segment_length(&l2_to_l1_payloads_length, l1_handler_payload_size); - - Ok((l2_to_l1_payloads_length, message_segment_length)) -} - pub fn calculate_tx_gas_and_blob_gas_usage<'a>( call_infos: impl Iterator, state_changes_count: StateChangesCount, @@ -75,18 +58,15 @@ pub fn calculate_tx_gas_usage_messages<'a>( call_infos: impl Iterator, l1_handler_payload_size: Option, ) -> TransactionExecutionResult { - let (l2_to_l1_payloads_length, residual_message_segment_length) = - calculate_l2_to_l1_payloads_length_and_message_segment_length( - call_infos, - l1_handler_payload_size, - )?; + let MessageL1CostInfo { l2_to_l1_payload_lengths, message_segment_length } = + MessageL1CostInfo::calculate(call_infos, l1_handler_payload_size)?; - let n_l2_to_l1_messages = l2_to_l1_payloads_length.len(); + let n_l2_to_l1_messages = l2_to_l1_payload_lengths.len(); let n_l1_to_l2_messages = usize::from(l1_handler_payload_size.is_some()); let starknet_gas_usage = // Starknet's updateState gets the message segment as an argument. - residual_message_segment_length * eth_gas_constants::GAS_PER_MEMORY_WORD + message_segment_length * eth_gas_constants::GAS_PER_MEMORY_WORD // Starknet's updateState increases a (storage) counter for each L2-to-L1 message. + n_l2_to_l1_messages * eth_gas_constants::GAS_PER_ZERO_TO_NONZERO_STORAGE_SET // Starknet's updateState decreases a (storage) counter for each L1-to-L2 consumed message. @@ -94,10 +74,10 @@ pub fn calculate_tx_gas_usage_messages<'a>( // ignore it since refunded gas cannot be used for the current transaction execution). + n_l1_to_l2_messages * eth_gas_constants::GAS_PER_COUNTER_DECREASE + get_consumed_message_to_l2_emissions_cost(l1_handler_payload_size) - + get_log_message_to_l1_emissions_cost(&l2_to_l1_payloads_length); + + get_log_message_to_l1_emissions_cost(&l2_to_l1_payload_lengths); let sharp_gas_usage_without_data = - residual_message_segment_length * eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD; + message_segment_length * eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD; Ok(starknet_gas_usage + sharp_gas_usage_without_data) } @@ -152,12 +132,12 @@ pub fn get_onchain_data_cost(state_changes_count: StateChangesCount) -> usize { /// a transaction with the given parameters to a batch. Note that constant cells - such as the one /// that holds the segment size - are not counted. pub fn get_message_segment_length( - l2_to_l1_payloads_length: &[usize], + l2_to_l1_payload_lengths: &[usize], l1_handler_payload_size: Option, ) -> usize { // Add L2-to-L1 message segment length; for each message, the OS outputs the following: // to_address, from_address, payload_size, payload. - let mut message_segment_length = l2_to_l1_payloads_length + let mut message_segment_length = l2_to_l1_payload_lengths .iter() .map(|payload_length| constants::L2_TO_L1_MSG_HEADER_SIZE + payload_length) .sum(); @@ -189,8 +169,8 @@ pub fn get_consumed_message_to_l2_emissions_cost(l1_handler_payload_size: Option } /// Returns the cost of LogMessageToL1 event emissions caused by the given messages payload length. -pub fn get_log_message_to_l1_emissions_cost(l2_to_l1_payloads_length: &[usize]) -> usize { - l2_to_l1_payloads_length +pub fn get_log_message_to_l1_emissions_cost(l2_to_l1_payload_lengths: &[usize]) -> usize { + l2_to_l1_payload_lengths .iter() .map(|length| { get_event_emission_cost( diff --git a/crates/blockifier/src/fee/gas_usage_test.rs b/crates/blockifier/src/fee/gas_usage_test.rs index 4242f6b644..b21e51bc25 100644 --- a/crates/blockifier/src/fee/gas_usage_test.rs +++ b/crates/blockifier/src/fee/gas_usage_test.rs @@ -147,11 +147,11 @@ fn test_calculate_tx_gas_usage_basic() { call_infos.push(call_info); } - // l2_to_l1_payloads_length is [0, 1, 2, 3] + // l2_to_l1_payload_lengths is [0, 1, 2, 3] let call_infos_iter = call_infos.iter(); - let l2_to_l1_payloads_length: Vec = call_infos_iter + let l2_to_l1_payload_lengths: Vec = call_infos_iter .clone() - .flat_map(|call_info| call_info.get_sorted_l2_to_l1_payloads_length().unwrap()) + .flat_map(|call_info| call_info.get_sorted_l2_to_l1_payload_lengths().unwrap()) .collect(); let l2_to_l1_state_changes_count = StateChangesCount { @@ -170,11 +170,11 @@ fn test_calculate_tx_gas_usage_basic() { l2_to_l1_messages_gas_and_blob_gas_usage; // Manual calculation. - let message_segment_length = get_message_segment_length(&l2_to_l1_payloads_length, None); - let n_l2_to_l1_messages = l2_to_l1_payloads_length.len(); + let message_segment_length = get_message_segment_length(&l2_to_l1_payload_lengths, None); + let n_l2_to_l1_messages = l2_to_l1_payload_lengths.len(); let manual_starknet_gas_usage = message_segment_length * eth_gas_constants::GAS_PER_MEMORY_WORD + n_l2_to_l1_messages * eth_gas_constants::GAS_PER_ZERO_TO_NONZERO_STORAGE_SET - + get_log_message_to_l1_emissions_cost(&l2_to_l1_payloads_length); + + get_log_message_to_l1_emissions_cost(&l2_to_l1_payload_lengths); let manual_sharp_gas_usage = message_segment_length * eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD + get_onchain_data_cost(l2_to_l1_state_changes_count); diff --git a/crates/blockifier/src/transaction/transaction_execution.rs b/crates/blockifier/src/transaction/transaction_execution.rs index 28e8caf23c..5f87725803 100644 --- a/crates/blockifier/src/transaction/transaction_execution.rs +++ b/crates/blockifier/src/transaction/transaction_execution.rs @@ -103,8 +103,7 @@ impl ExecutableTransaction for L1HandlerTransaction { let mut remaining_gas = Transaction::initial_gas(); let execute_call_info = self.run_execute(state, &mut execution_resources, &mut context, &mut remaining_gas)?; - // The calldata includes the "from" field, which is not a part of the payload. - let l1_handler_payload_size = self.tx.calldata.0.len() - 1; + let l1_handler_payload_size = self.payload_size(); let ActualCost { actual_fee, actual_resources } = ActualCost::builder_for_l1_handler(block_context, tx_context, l1_handler_payload_size) diff --git a/crates/blockifier/src/transaction/transactions.rs b/crates/blockifier/src/transaction/transactions.rs index 485cbf48b2..0bd266b7a8 100644 --- a/crates/blockifier/src/transaction/transactions.rs +++ b/crates/blockifier/src/transaction/transactions.rs @@ -466,6 +466,11 @@ impl L1HandlerTransaction { max_fee: Fee::default(), }) } + + pub fn payload_size(&self) -> usize { + // The calldata includes the "from" field, which is not a part of the payload. + self.tx.calldata.0.len() - 1 + } } impl HasRelatedFeeType for L1HandlerTransaction { diff --git a/crates/native_blockifier/src/transaction_executor.rs b/crates/native_blockifier/src/transaction_executor.rs index 83b59b1049..c9e626b9c0 100644 --- a/crates/native_blockifier/src/transaction_executor.rs +++ b/crates/native_blockifier/src/transaction_executor.rs @@ -1,8 +1,9 @@ use std::collections::{HashMap, HashSet}; +use std::vec::IntoIter; use blockifier::block_context::BlockContext; use blockifier::block_execution::pre_process_block; -use blockifier::execution::call_info::CallInfo; +use blockifier::execution::call_info::{CallInfo, MessageL1CostInfo}; use blockifier::execution::entry_point::ExecutionResources; use blockifier::fee::actual_cost::ActualCost; use blockifier::state::cached_state::{ @@ -74,7 +75,12 @@ impl TransactionExecutor { charge_fee: bool, ) -> NativeBlockifierResult<(PyTransactionExecutionInfo, PyBouncerInfo)> { let tx: Transaction = py_tx(tx, raw_contract_class)?; - + let l1_handler_payload_size: usize = + if let Transaction::L1HandlerTransaction(l1_handler_tx) = &tx { + l1_handler_tx.payload_size() + } else { + 0 + }; let mut tx_executed_class_hashes = HashSet::::new(); let mut tx_visited_storage_entries = HashSet::::new(); let mut transactional_state = CachedState::create_transactional(&mut self.state); @@ -88,9 +94,18 @@ impl TransactionExecutor { // TODO(Elin, 01/06/2024): consider traversing the calls to collect data once. tx_executed_class_hashes.extend(tx_execution_info.get_executed_class_hashes()); tx_visited_storage_entries.extend(tx_execution_info.get_visited_storage_entries()); + let call_infos: IntoIter<&CallInfo> = + [&tx_execution_info.validate_call_info, &tx_execution_info.execute_call_info] + .iter() + .filter_map(|&call_info| call_info.as_ref()) + .collect::>() + .into_iter(); + let MessageL1CostInfo { l2_to_l1_payload_lengths: _, message_segment_length } = + MessageL1CostInfo::calculate(call_infos, Some(l1_handler_payload_size))?; // TODO(Elin, 01/06/2024): consider moving Bouncer logic to a function. let py_tx_execution_info = PyTransactionExecutionInfo::from(tx_execution_info); + let mut additional_os_resources = get_casm_hash_calculation_resources( &mut transactional_state, &self.executed_class_hashes, @@ -101,7 +116,7 @@ impl TransactionExecutor { &tx_visited_storage_entries, )?; let py_bouncer_info = PyBouncerInfo { - message_segment_length: 0, + message_segment_length, state_diff_size: 0, additional_os_resources: PyVmExecutionResources::from(additional_os_resources), }; From 0590210a8a4b5eb830ad5b612767b8e61236760b Mon Sep 17 00:00:00 2001 From: OriStarkware <76900983+OriStarkware@users.noreply.github.com> Date: Thu, 25 Jan 2024 16:18:37 +0200 Subject: [PATCH 06/10] fix(native_blockifier): change failure_flag type to bool (#1334) --- crates/native_blockifier/src/py_transaction_execution_info.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/native_blockifier/src/py_transaction_execution_info.rs b/crates/native_blockifier/src/py_transaction_execution_info.rs index c2e52e068b..a7089f2188 100644 --- a/crates/native_blockifier/src/py_transaction_execution_info.rs +++ b/crates/native_blockifier/src/py_transaction_execution_info.rs @@ -61,7 +61,7 @@ pub struct PyCallInfo { #[pyo3(get)] pub gas_consumed: u64, // Currently not in use. #[pyo3(get)] - pub failure_flag: PyFelt, // Currently not in use. + pub failure_flag: bool, // Currently not in use. #[pyo3(get)] pub retdata: Vec, #[pyo3(get)] @@ -99,7 +99,7 @@ impl From for PyCallInfo { entry_point_type: call.entry_point_type as u8, calldata: to_py_vec(call.calldata.0.to_vec(), PyFelt), gas_consumed: execution.gas_consumed, - failure_flag: PyFelt::from(execution.failed as u8), + failure_flag: execution.failed, retdata: to_py_vec(execution.retdata.0, PyFelt), execution_resources: PyVmExecutionResources::from(call_info.vm_resources), events: to_py_vec(execution.events, PyOrderedEvent::from), From ccec5d4e3dabda86b10257a0a16a40731cba8b17 Mon Sep 17 00:00:00 2001 From: dorimedini-starkware Date: Thu, 25 Jan 2024 17:04:23 +0200 Subject: [PATCH 07/10] fix(execution): convert all local errors to stack trace (#1378) Signed-off-by: Dori Medini --- crates/blockifier/src/execution/entry_point.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index eabbfd496a..babc67e0a4 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -113,13 +113,10 @@ impl CallEntryPoint { source: error, } } - EntryPointExecutionError::ExecutionFailed { .. } => { - // TODO(Zuphit): Handle errors such that `Execution failed. Failure reason: ...` - // is not printed twice. - context.error_stack.push((storage_address, format!("{}\n", &error))); - error + other_error => { + context.error_stack.push((storage_address, format!("{}\n", &other_error))); + other_error } - other_error => other_error, } }) } From 9575e81e3c01222e58b4e35b1352799607c74d23 Mon Sep 17 00:00:00 2001 From: OriStarkware <76900983+OriStarkware@users.noreply.github.com> Date: Thu, 25 Jan 2024 17:21:28 +0200 Subject: [PATCH 08/10] fix(execution): change additional as to from (#1373) --- crates/blockifier/src/execution/syscalls/hint_processor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/blockifier/src/execution/syscalls/hint_processor.rs b/crates/blockifier/src/execution/syscalls/hint_processor.rs index 55c3540704..2e75ea3940 100644 --- a/crates/blockifier/src/execution/syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/syscalls/hint_processor.rs @@ -563,7 +563,7 @@ fn get_ptr_from_res_operand_unchecked(vm: &mut VirtualMachine, res: &ResOperand) Register::AP => vm.get_ap(), Register::FP => vm.get_fp(), }; - let cell_reloc = (base + (cell.offset as i32)).unwrap(); + let cell_reloc = (base + (i32::from(cell.offset))).unwrap(); (vm.get_relocatable(cell_reloc).unwrap() + &base_offset).unwrap() } From eee45dcf2f0b35b91f02b939da91abde8732f51e Mon Sep 17 00:00:00 2001 From: Elin Tulchinsky Date: Sat, 27 Jan 2024 17:54:25 +0200 Subject: [PATCH 09/10] Merge `main-v0.13.1` into `main` (resolve conflicts). --- crates/blockifier/src/fee/fee_checks.rs | 18 ------------------ crates/blockifier/src/fee/gas_usage.rs | 12 ------------ 2 files changed, 30 deletions(-) diff --git a/crates/blockifier/src/fee/fee_checks.rs b/crates/blockifier/src/fee/fee_checks.rs index d89c5e1daa..bf11bfd0db 100644 --- a/crates/blockifier/src/fee/fee_checks.rs +++ b/crates/blockifier/src/fee/fee_checks.rs @@ -9,18 +9,10 @@ use crate::fee::fee_utils::{ }; use crate::state::state_api::StateReader; use crate::transaction::errors::TransactionExecutionError; -<<<<<<< HEAD -use crate::transaction::objects::{ - AccountTransactionContext, FeeType, GasAndBlobGasUsages, TransactionExecutionResult, -}; -||||||| a743d49c -use crate::transaction::objects::{AccountTransactionContext, FeeType, TransactionExecutionResult}; -======= use crate::transaction::objects::{ AccountTransactionContext, FeeType, GasAndBlobGasUsages, HasRelatedFeeType, TransactionExecutionResult, }; ->>>>>>> origin/main-v0.13.1 #[derive(Clone, Copy, Debug, Error)] pub enum FeeCheckError { @@ -112,15 +104,6 @@ impl FeeCheckReport { AccountTransactionContext::Current(context) => { // Check L1 gas limit. let max_l1_gas = context.l1_resource_bounds()?.max_amount.into(); -<<<<<<< HEAD - let actual_used_l1_gas = - calculate_tx_l1_gas_usages(actual_resources, block_context)?.gas_usage; - if actual_used_l1_gas > max_l1_gas { -||||||| a743d49c - let actual_used_l1_gas = - calculate_tx_l1_gas_usage(actual_resources, block_context)?; - if actual_used_l1_gas > max_l1_gas { -======= let GasAndBlobGasUsages { gas_usage, blob_gas_usage } = calculate_tx_l1_gas_usages(actual_resources, block_context)?; @@ -143,7 +126,6 @@ impl FeeCheckReport { gas_usage + (blob_gas_usage * data_gas_price) / gas_price; if total_discounted_gas_used > max_l1_gas { ->>>>>>> origin/main-v0.13.1 return Err(FeeCheckError::MaxL1GasAmountExceeded { max_amount: max_l1_gas, actual_amount: total_discounted_gas_used, diff --git a/crates/blockifier/src/fee/gas_usage.rs b/crates/blockifier/src/fee/gas_usage.rs index 3871b5a8a8..fb0c7a11f1 100644 --- a/crates/blockifier/src/fee/gas_usage.rs +++ b/crates/blockifier/src/fee/gas_usage.rs @@ -31,18 +31,6 @@ pub fn calculate_tx_gas_and_blob_gas_usage<'a>( }) } -pub fn calculate_tx_gas_and_blob_gas_usage<'a>( - call_infos: impl Iterator, - state_changes_count: StateChangesCount, - l1_handler_payload_size: Option, -) -> TransactionExecutionResult { - Ok(GasAndBlobGasUsages { - gas_usage: calculate_tx_gas_usage(call_infos, state_changes_count, l1_handler_payload_size)? - as u128, - blob_gas_usage: 0, - }) -} - /// Returns the blob-gas (data-gas) needed to publish the transaction's state diff in a blob. pub fn calculate_tx_blob_gas_usage(state_changes_count: StateChangesCount) -> usize { let onchain_data_segment_length = get_onchain_data_segment_length(state_changes_count); From 97c7e3956b5f10434f478c329ded7f9a26297e2a Mon Sep 17 00:00:00 2001 From: Dori Medini Date: Sun, 28 Jan 2024 10:47:12 +0200 Subject: [PATCH 10/10] ci: prevent PR title check on merges Signed-off-by: Dori Medini --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a37c234ecc..56685f69c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: run: commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose - name: Validate PR title with commitlint - if: github.event_name != 'merge_group' && github.event_name != 'push' + if: github.event_name != 'merge_group' && github.event_name != 'push' && !(contains(github.event.pull_request.title, '/merge-main') || contains(github.event.pull_request.title, '/merge main')) run: echo "${{ github.event.pull_request.title }}" | commitlint --verbose format: