Skip to content

Commit

Permalink
fix rpc: handle EntryPointNotFound error correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
rianhughes committed Feb 25, 2025
1 parent 7239e37 commit 471644e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 48 deletions.
90 changes: 44 additions & 46 deletions vm/rust/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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.
Expand All @@ -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();
Expand Down
1 change: 0 additions & 1 deletion vm/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 471644e

Please sign in to comment.