From 471644eebfc6c4fa16718da9b8945b30707a8f32 Mon Sep 17 00:00:00 2001 From: rian Date: Tue, 25 Feb 2025 15:51:29 +0200 Subject: [PATCH] fix rpc: handle EntryPointNotFound error correctly --- vm/rust/src/execution.rs | 90 ++++++++++++++++++++-------------------- vm/rust/src/lib.rs | 1 - vm/vm.go | 2 +- 3 files changed, 45 insertions(+), 48 deletions(-) diff --git a/vm/rust/src/execution.rs b/vm/rust/src/execution.rs index d333b815a1..c91eccc75c 100644 --- a/vm/rust/src/execution.rs +++ b/vm/rust/src/execution.rs @@ -50,7 +50,6 @@ pub fn is_l2_gas_accounting_enabled( return Ok(false); } - let min_sierra_version = &block_context .versioned_constants() .min_sierra_version_for_sierra_gas; @@ -112,13 +111,13 @@ where // Simulate transaction execution with maximum possible gas to get actual gas usage. set_l2_gas_limit(transaction, GasAmount::MAX); -// TODO: Consider getting the upper bound from the balance and not changing the execution flags + // TODO: Consider getting the upper bound from the balance and not changing the execution flags match transaction { Transaction::Account(account_transaction) => { account_transaction.execution_flags.charge_fee = false; account_transaction.execution_flags.validate = false; } - _ =>{}, + _ => {} }; let (simulation_result, _) = match simulate_execution(transaction, state, block_context) { Ok(info) => info, @@ -142,54 +141,53 @@ where let l2_gas_adjusted = GasAmount(gas_used.saturating_add(gas_used / 10)); set_l2_gas_limit(transaction, l2_gas_adjusted); - let (l2_gas_limit, _, tx_state) = - match simulate_execution(transaction, state, block_context) { - Ok((tx_info, tx_state)) => { - // If 110% of the actual transaction gas fee is enough, we use that - // as the estimate and skip the binary search. - (l2_gas_adjusted, tx_info, tx_state) - } - Err(SimulationError::OutOfGas(_)) => { - let mut lower_bound = GasAmount(gas_used); - let mut upper_bound = GasAmount::MAX; - let mut current_l2_gas_limit = calculate_midpoint(lower_bound, upper_bound); - - // Run a binary search to find the minimal gas limit that still allows the - // transaction to execute without running out of L2 gas. - let (tx_info, tx_state) = loop { - set_l2_gas_limit(transaction, current_l2_gas_limit); + let (l2_gas_limit, _, tx_state) = match simulate_execution(transaction, state, block_context) { + Ok((tx_info, tx_state)) => { + // If 110% of the actual transaction gas fee is enough, we use that + // as the estimate and skip the binary search. + (l2_gas_adjusted, tx_info, tx_state) + } + Err(SimulationError::OutOfGas(_)) => { + let mut lower_bound = GasAmount(gas_used); + let mut upper_bound = GasAmount::MAX; + let mut current_l2_gas_limit = calculate_midpoint(lower_bound, upper_bound); - // Special case where the search would get stuck if `current_l2_gas_limit == - // lower_bound` but the required amount is equal to the upper bound. - let bounds_diff = upper_bound - .checked_sub(lower_bound) - .expect("Upper bound >= lower bound"); - if bounds_diff == GasAmount(1) && current_l2_gas_limit == lower_bound { - lower_bound = upper_bound; - current_l2_gas_limit = upper_bound; - } + // Run a binary search to find the minimal gas limit that still allows the + // transaction to execute without running out of L2 gas. + let (tx_info, tx_state) = loop { + set_l2_gas_limit(transaction, current_l2_gas_limit); - match simulate_execution(transaction, state, block_context) { - Ok((tx_info, tx_state)) => { - if is_search_complete(lower_bound, upper_bound, L2_GAS_SEARCH_MARGIN) { - break (tx_info, tx_state); - } + // Special case where the search would get stuck if `current_l2_gas_limit == + // lower_bound` but the required amount is equal to the upper bound. + let bounds_diff = upper_bound + .checked_sub(lower_bound) + .expect("Upper bound >= lower bound"); + if bounds_diff == GasAmount(1) && current_l2_gas_limit == lower_bound { + lower_bound = upper_bound; + current_l2_gas_limit = upper_bound; + } - upper_bound = current_l2_gas_limit; - current_l2_gas_limit = calculate_midpoint(lower_bound, upper_bound); - } - Err(SimulationError::OutOfGas(_)) => { - lower_bound = current_l2_gas_limit; - current_l2_gas_limit = calculate_midpoint(lower_bound, upper_bound); + match simulate_execution(transaction, state, block_context) { + Ok((tx_info, tx_state)) => { + if is_search_complete(lower_bound, upper_bound, L2_GAS_SEARCH_MARGIN) { + break (tx_info, tx_state); } - Err(SimulationError::ExecutionError(error)) => return Err(error), + + upper_bound = current_l2_gas_limit; + current_l2_gas_limit = calculate_midpoint(lower_bound, upper_bound); + } + Err(SimulationError::OutOfGas(_)) => { + lower_bound = current_l2_gas_limit; + current_l2_gas_limit = calculate_midpoint(lower_bound, upper_bound); } - }; + Err(SimulationError::ExecutionError(error)) => return Err(error), + } + }; - (current_l2_gas_limit, tx_info, tx_state) - } - Err(SimulationError::ExecutionError(error)) => return Err(error), - }; + (current_l2_gas_limit, tx_info, tx_state) + } + Err(SimulationError::ExecutionError(error)) => return Err(error), + }; tx_state.abort(); // If the computed gas limit exceeds the initial limit, revert the transaction. @@ -202,7 +200,7 @@ where set_l2_gas_limit(&mut original_transaction, initial_gas_limit); let mut simulated_state = CachedState::<_>::create_transactional(state); - let mut exec_info = original_transaction.execute(&mut simulated_state, block_context)?; + let mut exec_info = original_transaction.execute(&mut simulated_state, block_context)?; // Execute the transaction with the determined gas limit and update the estimate. simulated_state.commit(); diff --git a/vm/rust/src/lib.rs b/vm/rust/src/lib.rs index ff65800def..1a7a83a682 100644 --- a/vm/rust/src/lib.rs +++ b/vm/rust/src/lib.rs @@ -193,7 +193,6 @@ pub extern "C" fn cairoVMCall( Ok(call_info) => { if call_info.execution.failed { report_error(reader_handle, "execution failed", -1, 1); - return; } for data in call_info.execution.retdata.0 { unsafe { diff --git a/vm/vm.go b/vm/vm.go index 658a3a0ec2..c2148e3bba 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -247,7 +247,7 @@ func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateRead C.free(unsafe.Pointer(cBlockInfo.version)) C.free(unsafe.Pointer(cSierraVersion)) - if context.err != "" { + if context.err != "" && !context.executionFailed { return CallResult{}, errors.New(context.err) } return CallResult{Result: context.response, ExecutionFailed: context.executionFailed}, nil