From 28a410407df0d9d124f4b05fc2884c2074bd5026 Mon Sep 17 00:00:00 2001 From: Dori Medini Date: Sun, 29 Dec 2024 22:28:35 +0200 Subject: [PATCH] feat(blockifier): support reverted sierra gas tracking and charging Signed-off-by: Dori Medini --- .../src/blockifier/stateful_validator.rs | 2 + .../blockifier/src/execution/entry_point.rs | 81 ++++++++++++++++++- .../src/execution/syscalls/hint_processor.rs | 22 +++++ crates/blockifier/src/fee/receipt.rs | 7 +- crates/blockifier/src/test_utils/prices.rs | 9 ++- .../blockifier/src/test_utils/struct_impls.rs | 3 + .../src/transaction/account_transaction.rs | 49 ++++++++--- .../transaction/account_transactions_test.rs | 20 ++++- .../src/transaction/transaction_execution.rs | 14 +++- crates/papyrus_execution/src/lib.rs | 3 + 10 files changed, 188 insertions(+), 22 deletions(-) diff --git a/crates/blockifier/src/blockifier/stateful_validator.rs b/crates/blockifier/src/blockifier/stateful_validator.rs index 8683088833..d044bad0c0 100644 --- a/crates/blockifier/src/blockifier/stateful_validator.rs +++ b/crates/blockifier/src/blockifier/stateful_validator.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::executable_transaction::AccountTransaction as ApiTransaction; +use starknet_api::execution_resources::GasAmount; use thiserror::Error; use crate::blockifier::config::TransactionExecutorConfig; @@ -132,6 +133,7 @@ impl StatefulValidator { &tx_context.block_context.versioned_constants, ), 0, + GasAmount(0), ); Ok((validate_call_info, tx_receipt)) diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index e7fd2e84a7..a8855d2539 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -172,6 +172,11 @@ impl CallEntryPoint { if let Ok(call_info) = &execution_result { // If the execution of the outer call failed, revert the transction. if call_info.execution.failed { + // For Cairo1 revert, need to explicitly set the amount of gas to revert from the + // call info. + context + .sierra_gas_revert_tracker + .set_gas_consumed_directly(GasAmount(call_info.execution.gas_consumed)); return Err(EntryPointExecutionError::ExecutionFailed { error_trace: extract_trailing_cairo1_revert_trace( call_info, @@ -183,6 +188,7 @@ impl CallEntryPoint { execution_result } + pub fn verify_constructor(&self) -> Result<(), PreExecutionError> { if self.entry_point_type == EntryPointType::Constructor && self.entry_point_selector != selector_from_name(CONSTRUCTOR_ENTRY_POINT_NAME) @@ -202,6 +208,55 @@ pub struct ConstructorContext { pub caller_address: ContractAddress, } +#[derive(Debug)] +pub struct SierraGasRevertTracker { + sierra_gas_consumed_so_far: GasAmount, + last_seen_remaining_gas: GasAmount, +} + +impl SierraGasRevertTracker { + pub fn new_execute(initial_remaining_gas: GasAmount) -> Self { + Self { + sierra_gas_consumed_so_far: GasAmount(0), + last_seen_remaining_gas: initial_remaining_gas, + } + } + + /// In validate, we cannot charge for reverted gas, so the values are meaningless. + pub fn new_validate() -> Self { + Self::new_execute(GasAmount::MAX) + } + + /// Given the next remaining gas (before entering the next syscall), updates the consumed gas + /// (difference between previous and next remaining gas) and then updates the last seen + /// remaining gas. + pub fn update_before_syscall(&mut self, next_remaining_gas: GasAmount) { + let next_gas_consumed = + self.last_seen_remaining_gas.checked_sub(next_remaining_gas).expect(&format!( + "Next remaining gas higher than last. Last seen remaining gas: {}, next remaining \ + gas: {next_remaining_gas}.", + self.last_seen_remaining_gas + )); + self.sierra_gas_consumed_so_far = + self.sierra_gas_consumed_so_far.checked_add(next_gas_consumed).expect(&format!( + "Sierra gas consumed overflowed. Last consumed gas: {}, extra consumed gas: \ + {next_gas_consumed}.", + self.sierra_gas_consumed_so_far + )); + self.last_seen_remaining_gas = next_remaining_gas; + } + + /// In Cairo1 reverts, the total gas consumed for fee charge is available on the call info, and + /// can be used directly. + pub fn set_gas_consumed_directly(&mut self, gas_consumed: GasAmount) { + self.sierra_gas_consumed_so_far = gas_consumed; + } + + pub fn get_gas_consumed(&self) -> GasAmount { + self.sierra_gas_consumed_so_far + } +} + #[derive(Debug)] pub struct EntryPointExecutionContext { // We use `Arc` to avoid the clone of this potentially large object, as inner calls @@ -223,6 +278,9 @@ pub struct EntryPointExecutionContext { // Information for reverting the state (inludes the revert info of the callers). pub revert_infos: ExecutionRevertInfo, + + // Used to support charging for gas consumed in blockifier revert flow. + pub sierra_gas_revert_tracker: SierraGasRevertTracker, } impl EntryPointExecutionContext { @@ -230,6 +288,7 @@ impl EntryPointExecutionContext { tx_context: Arc, mode: ExecutionMode, limit_steps_by_resources: bool, + sierra_gas_revert_tracker: SierraGasRevertTracker, ) -> Self { let max_steps = Self::max_steps(&tx_context, &mode, limit_steps_by_resources); Self { @@ -241,6 +300,7 @@ impl EntryPointExecutionContext { execution_mode: mode, tracked_resource_stack: vec![], revert_infos: ExecutionRevertInfo(vec![]), + sierra_gas_revert_tracker, } } @@ -248,11 +308,25 @@ impl EntryPointExecutionContext { tx_context: Arc, limit_steps_by_resources: bool, ) -> Self { - Self::new(tx_context, ExecutionMode::Validate, limit_steps_by_resources) + Self::new( + tx_context, + ExecutionMode::Validate, + limit_steps_by_resources, + SierraGasRevertTracker::new_validate(), + ) } - pub fn new_invoke(tx_context: Arc, limit_steps_by_resources: bool) -> Self { - Self::new(tx_context, ExecutionMode::Execute, limit_steps_by_resources) + pub fn new_invoke( + tx_context: Arc, + limit_steps_by_resources: bool, + sierra_gas_revert_tracker: SierraGasRevertTracker, + ) -> Self { + Self::new( + tx_context, + ExecutionMode::Execute, + limit_steps_by_resources, + sierra_gas_revert_tracker, + ) } /// Returns the maximum number of cairo steps allowed, given the max fee, gas price and the @@ -428,6 +502,7 @@ pub fn execute_constructor_entry_point( initial_gas: *remaining_gas, }; + // TODO: On error, compute sierra gas consumed and charge for blockifier revert flow. constructor_call.non_reverting_execute(state, context, remaining_gas).map_err(|error| { ConstructorEntryPointExecutionError::new(error, &ctor_context, Some(constructor_selector)) }) diff --git a/crates/blockifier/src/execution/syscalls/hint_processor.rs b/crates/blockifier/src/execution/syscalls/hint_processor.rs index bf7d9f50b7..af7d7b0416 100644 --- a/crates/blockifier/src/execution/syscalls/hint_processor.rs +++ b/crates/blockifier/src/execution/syscalls/hint_processor.rs @@ -14,6 +14,7 @@ use cairo_vm::vm::errors::vm_errors::VirtualMachineError; use cairo_vm::vm::runners::cairo_runner::{ResourceTracker, RunResources}; use cairo_vm::vm::vm_core::VirtualMachine; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector}; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::fields::{ AllResourceBounds, Calldata, @@ -26,6 +27,7 @@ use thiserror::Error; use crate::abi::sierra_types::SierraTypeError; use crate::execution::common_hints::{ExecutionMode, HintExecutionResult}; +use crate::execution::contract_class::TrackedResource; use crate::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext}; use crate::execution::errors::{ConstructorEntryPointExecutionError, EntryPointExecutionError}; use crate::execution::execution_utils::{ @@ -475,6 +477,26 @@ impl<'a> SyscallHintProcessor<'a> { // Execute. let mut remaining_gas = gas_counter - required_gas; + + // To support sierra gas charge for blockifier revert flow, we track the remaining gas left + // before executing a syscall if the current tracked resource is gas. + // 1. If the syscall does not run Cairo code (i.e. not library call, not call contract, and + // not a deploy), any failure will not run in the OS, so no need to charge - the value + // before entering the callback is good enough to charge. + // 2. If the syscall runs Cairo code, but the tracked resource is steps (and not gas), the + // additional charge of reverted cairo steps will cover the inner cost, and the outer + // cost we track here will be the additional reverted gas. + // 3. If the syscall runs Cairo code and the tracked resource is gas, either the inner + // failure will be a Cairo1 revert (and the gas consumed on the call info will override + // the current tracked value), or we will pass through another syscall before failing - + // and by induction (we will reach this point again), the gas will be charged correctly. + if self.base.context.tracked_resource_stack.last() == Some(&TrackedResource::CairoSteps) { + self.base + .context + .sierra_gas_revert_tracker + .update_before_syscall(GasAmount(remaining_gas)); + } + let original_response = execute_callback(request, vm, self, &mut remaining_gas); let response = match original_response { Ok(response) => { diff --git a/crates/blockifier/src/fee/receipt.rs b/crates/blockifier/src/fee/receipt.rs index 0c7a13d4d9..6d0e55066a 100644 --- a/crates/blockifier/src/fee/receipt.rs +++ b/crates/blockifier/src/fee/receipt.rs @@ -31,6 +31,7 @@ struct TransactionReceiptParameters<'a> { execution_summary_without_fee_transfer: ExecutionSummary, tx_type: TransactionType, reverted_steps: usize, + reverted_sierra_gas: GasAmount, } // TODO(Gilad): Use everywhere instead of passing the `actual_{fee,resources}` tuple, which often @@ -58,6 +59,7 @@ impl TransactionReceipt { execution_summary_without_fee_transfer, tx_type, reverted_steps, + reverted_sierra_gas, } = tx_receipt_params; let charged_resources = execution_summary_without_fee_transfer.charged_resources.clone(); let starknet_resources = StarknetResources::new( @@ -85,7 +87,7 @@ impl TransactionReceipt { vm_resources: total_vm_resources, n_reverted_steps: reverted_steps, sierra_gas: charged_resources.gas_for_fee, - reverted_sierra_gas: GasAmount(0), // TODO(tzahi): compute value. + reverted_sierra_gas, }, }; @@ -127,6 +129,7 @@ impl TransactionReceipt { execution_summary_without_fee_transfer, tx_type: TransactionType::L1Handler, reverted_steps: 0, + reverted_sierra_gas: GasAmount(0), }) } @@ -137,6 +140,7 @@ impl TransactionReceipt { state_changes: &'a StateChanges, execution_summary_without_fee_transfer: ExecutionSummary, reverted_steps: usize, + reverted_sierra_gas: GasAmount, ) -> Self { Self::from_params(TransactionReceiptParameters { tx_context, @@ -149,6 +153,7 @@ impl TransactionReceipt { execution_summary_without_fee_transfer, tx_type: account_tx.tx_type(), reverted_steps, + reverted_sierra_gas, }) } } diff --git a/crates/blockifier/src/test_utils/prices.rs b/crates/blockifier/src/test_utils/prices.rs index 0184474f69..063f41a5ce 100644 --- a/crates/blockifier/src/test_utils/prices.rs +++ b/crates/blockifier/src/test_utils/prices.rs @@ -5,13 +5,18 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use starknet_api::abi::abi_utils::{get_fee_token_var_address, selector_from_name}; use starknet_api::block::FeeType; use starknet_api::core::ContractAddress; +use starknet_api::execution_resources::GasAmount; use starknet_api::test_utils::invoke::InvokeTxArgs; use starknet_api::transaction::constants; use starknet_api::{calldata, felt}; use crate::context::BlockContext; use crate::execution::common_hints::ExecutionMode; -use crate::execution::entry_point::{CallEntryPoint, EntryPointExecutionContext}; +use crate::execution::entry_point::{ + CallEntryPoint, + EntryPointExecutionContext, + SierraGasRevertTracker, +}; use crate::state::state_api::State; use crate::test_utils::initial_test_state::test_state; use crate::test_utils::BALANCE; @@ -77,6 +82,8 @@ fn fee_transfer_resources( ), ExecutionMode::Execute, false, + // No need to limit gas in fee transfer. + SierraGasRevertTracker::new_execute(GasAmount::MAX), ), &mut remaining_gas, ) diff --git a/crates/blockifier/src/test_utils/struct_impls.rs b/crates/blockifier/src/test_utils/struct_impls.rs index 33cc861232..a1b87c0290 100644 --- a/crates/blockifier/src/test_utils/struct_impls.rs +++ b/crates/blockifier/src/test_utils/struct_impls.rs @@ -16,6 +16,7 @@ use starknet_api::contract_address; use starknet_api::contract_class::SierraVersion; use starknet_api::core::{ChainId, ClassHash}; use starknet_api::deprecated_contract_class::ContractClass as DeprecatedContractClass; +use starknet_api::execution_resources::GasAmount; use starknet_api::test_utils::{TEST_ERC20_CONTRACT_ADDRESS, TEST_ERC20_CONTRACT_ADDRESS2}; use crate::bouncer::{BouncerConfig, BouncerWeights, BuiltinCount}; @@ -28,6 +29,7 @@ use crate::execution::entry_point::{ CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, + SierraGasRevertTracker, }; #[cfg(feature = "cairo_native")] use crate::execution::native::contract_class::NativeCompiledClassV1; @@ -72,6 +74,7 @@ impl CallEntryPoint { Arc::new(tx_context), execution_mode, limit_steps_by_resources, + SierraGasRevertTracker::new_execute(GasAmount(self.initial_gas)), ); let mut remaining_gas = self.initial_gas; self.execute(state, &mut context, &mut remaining_gas) diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 5d1f25dee6..534dd048d3 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -7,6 +7,7 @@ use starknet_api::contract_class::EntryPointType; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::executable_transaction::AccountTransaction as Transaction; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::fields::Resource::{L1DataGas, L1Gas, L2Gas}; use starknet_api::transaction::fields::{ AccountDeploymentData, @@ -23,8 +24,14 @@ use starknet_types_core::felt::Felt; use crate::context::{BlockContext, GasCounter, TransactionContext}; use crate::execution::call_info::CallInfo; +use crate::execution::common_hints::ExecutionMode; use crate::execution::contract_class::RunnableCompiledClass; -use crate::execution::entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext}; +use crate::execution::entry_point::{ + CallEntryPoint, + CallType, + EntryPointExecutionContext, + SierraGasRevertTracker, +}; use crate::execution::stack_trace::{ extract_trailing_cairo1_revert_trace, gen_tx_execution_error_trace, @@ -466,7 +473,11 @@ impl AccountTransaction { initial_gas: remaining_gas_for_fee_transfer, }; - let mut context = EntryPointExecutionContext::new_invoke(tx_context, true); + let mut context = EntryPointExecutionContext::new_invoke( + tx_context, + true, + SierraGasRevertTracker::new_execute(GasAmount(remaining_gas_for_fee_transfer)), + ); Ok(fee_transfer_call .execute(state, &mut context, &mut remaining_gas_for_fee_transfer) @@ -545,12 +556,21 @@ impl AccountTransaction { validate_call_info = self.handle_validate_tx(state, tx_context.clone(), remaining_gas)?; } else { + validate_call_info = + self.handle_validate_tx(state, tx_context.clone(), remaining_gas)?; let mut execution_context = EntryPointExecutionContext::new_invoke( tx_context.clone(), self.execution_flags.charge_fee, + // TODO: Reduce code dup (the gas usage limit is computed in run_execute). + SierraGasRevertTracker::new_execute(GasAmount( + remaining_gas.limit_usage( + tx_context + .block_context + .versioned_constants + .sierra_gas_limit(&ExecutionMode::Execute), + ), + )), ); - validate_call_info = - self.handle_validate_tx(state, tx_context.clone(), remaining_gas)?; execute_call_info = self.run_execute(state, &mut execution_context, remaining_gas)?; } @@ -563,6 +583,7 @@ impl AccountTransaction { &tx_context.block_context.versioned_constants, ), 0, + GasAmount(0), ); let post_execution_report = PostExecutionReport::new( @@ -587,14 +608,23 @@ impl AccountTransaction { tx_context: Arc, remaining_gas: &mut GasCounter, ) -> TransactionExecutionResult { - let mut execution_context = EntryPointExecutionContext::new_invoke( - tx_context.clone(), - self.execution_flags.charge_fee, - ); // Run the validation, and if execution later fails, only keep the validation diff. let validate_call_info = self.handle_validate_tx(state, tx_context.clone(), remaining_gas)?; + let mut execution_context = EntryPointExecutionContext::new_invoke( + tx_context.clone(), + self.execution_flags.charge_fee, + // TODO: Reduce code dup (the gas usage limit is computed in run_execute). + SierraGasRevertTracker::new_execute(GasAmount( + remaining_gas.limit_usage( + tx_context + .block_context + .versioned_constants + .sierra_gas_limit(&ExecutionMode::Execute), + ), + )), + ); let n_allotted_execution_steps = execution_context.subtract_validation_and_overhead_steps( &validate_call_info, &self.tx_type(), @@ -613,7 +643,6 @@ impl AccountTransaction { self.run_execute(&mut execution_state, &mut execution_context, remaining_gas); // Pre-compute cost in case of revert. - // TODO(tzahi): add reverted_l2_gas to the receipt. let execution_steps_consumed = n_allotted_execution_steps - execution_context.n_remaining_steps(); // Get the receipt only in case of revert. @@ -627,6 +656,7 @@ impl AccountTransaction { &tx_context.block_context.versioned_constants, ), execution_steps_consumed, + execution_context.sierra_gas_revert_tracker.get_gas_consumed(), ) }; @@ -649,6 +679,7 @@ impl AccountTransaction { &tx_context.block_context.versioned_constants, ), 0, + GasAmount(0), ); // Post-execution checks. let post_execution_report = PostExecutionReport::new( diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index e09f3948a7..81bb37369e 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -66,7 +66,7 @@ use crate::check_tx_execution_error_for_invalid_scenario; use crate::context::{BlockContext, TransactionContext}; use crate::execution::call_info::CallInfo; use crate::execution::contract_class::TrackedResource; -use crate::execution::entry_point::EntryPointExecutionContext; +use crate::execution::entry_point::{EntryPointExecutionContext, SierraGasRevertTracker}; use crate::execution::syscalls::SyscallSelector; use crate::fee::fee_utils::{get_fee_by_gas_vector, get_sequencer_balance_keys}; use crate::fee::gas_usage::estimate_minimal_gas_vector; @@ -1072,7 +1072,11 @@ fn test_max_fee_computation_from_tx_bounds(block_context: BlockContext) { macro_rules! assert_max_steps_as_expected { ($account_tx:expr, $expected_max_steps:expr $(,)?) => { let tx_context = Arc::new(block_context.to_tx_context(&$account_tx)); - let execution_context = EntryPointExecutionContext::new_invoke(tx_context, true); + let execution_context = EntryPointExecutionContext::new_invoke( + tx_context, + true, + SierraGasRevertTracker::new_execute(GasAmount::MAX), + ); let max_steps = execution_context.vm_run_resources.get_n_steps().unwrap(); assert_eq!(u64::try_from(max_steps).unwrap(), $expected_max_steps); }; @@ -1160,7 +1164,11 @@ fn test_max_fee_to_max_steps_conversion( nonce: nonce_manager.next(account_address), }); let tx_context1 = Arc::new(block_context.to_tx_context(&account_tx1)); - let execution_context1 = EntryPointExecutionContext::new_invoke(tx_context1, true); + let execution_context1 = EntryPointExecutionContext::new_invoke( + tx_context1, + true, + SierraGasRevertTracker::new_execute(GasAmount::MAX), + ); let max_steps_limit1 = execution_context1.vm_run_resources.get_n_steps(); let tx_execution_info1 = account_tx1.execute(&mut state, &block_context).unwrap(); let n_steps1 = tx_execution_info1.receipt.resources.computation.vm_resources.n_steps; @@ -1181,7 +1189,11 @@ fn test_max_fee_to_max_steps_conversion( nonce: nonce_manager.next(account_address), }); let tx_context2 = Arc::new(block_context.to_tx_context(&account_tx2)); - let execution_context2 = EntryPointExecutionContext::new_invoke(tx_context2, true); + let execution_context2 = EntryPointExecutionContext::new_invoke( + tx_context2, + true, + SierraGasRevertTracker::new_execute(GasAmount::MAX), + ); let max_steps_limit2 = execution_context2.vm_run_resources.get_n_steps(); let tx_execution_info2 = account_tx2.execute(&mut state, &block_context).unwrap(); let n_steps2 = tx_execution_info2.receipt.resources.computation.vm_resources.n_steps; diff --git a/crates/blockifier/src/transaction/transaction_execution.rs b/crates/blockifier/src/transaction/transaction_execution.rs index ec2a7aeac6..b99a165323 100644 --- a/crates/blockifier/src/transaction/transaction_execution.rs +++ b/crates/blockifier/src/transaction/transaction_execution.rs @@ -9,13 +9,15 @@ use starknet_api::executable_transaction::{ InvokeTransaction, L1HandlerTransaction, }; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::fields::Fee; use starknet_api::transaction::{Transaction as StarknetApiTransaction, TransactionHash}; use crate::bouncer::verify_tx_weights_within_max_capacity; use crate::context::BlockContext; use crate::execution::call_info::CallInfo; -use crate::execution::entry_point::EntryPointExecutionContext; +use crate::execution::common_hints::ExecutionMode; +use crate::execution::entry_point::{EntryPointExecutionContext, SierraGasRevertTracker}; use crate::fee::receipt::TransactionReceipt; use crate::state::cached_state::TransactionalState; use crate::state::state_api::UpdatableState; @@ -142,10 +144,14 @@ impl ExecutableTransaction for L1HandlerTransaction { ) -> TransactionExecutionResult { let tx_context = Arc::new(block_context.to_tx_context(self)); let limit_steps_by_resources = false; - let mut context = - EntryPointExecutionContext::new_invoke(tx_context.clone(), limit_steps_by_resources); // The Sierra gas limit for L1 handler transaction is set to max_execute_sierra_gas. - let mut remaining_gas = context.mode_sierra_gas_limit().0; + let mut remaining_gas = + block_context.versioned_constants.sierra_gas_limit(&ExecutionMode::Execute).0; + let mut context = EntryPointExecutionContext::new_invoke( + tx_context.clone(), + limit_steps_by_resources, + SierraGasRevertTracker::new_execute(GasAmount(remaining_gas)), + ); let execute_call_info = self.run_execute(state, &mut context, &mut remaining_gas)?; let l1_handler_payload_size = self.payload_size(); let TransactionReceipt { diff --git a/crates/papyrus_execution/src/lib.rs b/crates/papyrus_execution/src/lib.rs index 5f9db37b84..d69b152f04 100644 --- a/crates/papyrus_execution/src/lib.rs +++ b/crates/papyrus_execution/src/lib.rs @@ -30,6 +30,7 @@ use blockifier::execution::entry_point::{ CallEntryPoint, CallType as BlockifierCallType, EntryPointExecutionContext, + SierraGasRevertTracker, }; use blockifier::state::cached_state::CachedState; use blockifier::transaction::account_transaction::ExecutionFlags; @@ -62,6 +63,7 @@ use starknet_api::contract_class::{ClassInfo, EntryPointType, SierraVersion}; use starknet_api::core::{ChainId, ClassHash, ContractAddress, EntryPointSelector}; use starknet_api::data_availability::L1DataAvailabilityMode; use starknet_api::deprecated_contract_class::ContractClass as DeprecatedContractClass; +use starknet_api::execution_resources::GasAmount; use starknet_api::state::{StateNumber, ThinStateDiff}; use starknet_api::transaction::fields::{Calldata, Fee}; use starknet_api::transaction::{ @@ -274,6 +276,7 @@ pub fn execute_call( let mut context = EntryPointExecutionContext::new_invoke( Arc::new(TransactionContext { block_context, tx_info }), limit_steps_by_resources, + SierraGasRevertTracker::new_execute(GasAmount(remaining_gas)), ); let res = call_entry_point