Skip to content

Commit

Permalink
fix(EOF): MIN_CALLEE_GAS light failure, static-mode check (bluealloy#…
Browse files Browse the repository at this point in the history
…1599)

* fix(EOF): MIN_CALLEE_GAS light failure, static-mode check

* clear buffer

* readd min caller gas
  • Loading branch information
rakita authored and j75689 committed Aug 1, 2024
1 parent aae840e commit 48409bc
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 8 deletions.
1 change: 1 addition & 0 deletions crates/interpreter/src/gas/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ pub const PER_CONTRACT_CODE_BASE_COST: u64 = 2400;
pub const INITCODE_WORD_COST: u64 = 2;

pub const CALL_STIPEND: u64 = 2300;
pub const MIN_CALLEE_GAS: u64 = CALL_STIPEND;
2 changes: 2 additions & 0 deletions crates/interpreter/src/instruction_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ pub enum InstructionResult {
PrecompileOOG,
InvalidOperandOOG,
OpcodeNotFound,
/// Transferring value with CALL/CALLCODE is not possible in static mode.
CallNotAllowedInsideStatic,
/// State change attempted in static mode.
StateChangeDuringStaticCall,
InvalidFEOpcode,
InvalidJump,
Expand Down
24 changes: 16 additions & 8 deletions crates/interpreter/src/instructions/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mod call_helpers;
pub use call_helpers::{calc_call_gas, get_memory_input_and_out_ranges, resize_memory};

use crate::{
gas::{self, cost_per_word, EOF_CREATE_GAS, KECCAK256WORD},
gas::{self, cost_per_word, EOF_CREATE_GAS, KECCAK256WORD, MIN_CALLEE_GAS},
interpreter::Interpreter,
primitives::{
eof::EofHeader, keccak256, Address, BerlinSpec, Bytes, Eof, Spec, SpecId::*, B256, U256,
Expand Down Expand Up @@ -170,7 +170,6 @@ pub fn extcall_gas_calc<H: Host + ?Sized>(
return None;
};

// TODO(EOF) is_empty should only be checked on delegatecall
let call_cost = gas::call_cost(
BerlinSpec::SPEC_ID,
transfers_value,
Expand All @@ -184,10 +183,17 @@ pub fn extcall_gas_calc<H: Host + ?Sized>(
let gas_reduce = max(interpreter.gas.remaining() / 64, 5000);
let gas_limit = interpreter.gas().remaining().saturating_sub(gas_reduce);

if gas_limit < 2300 {
interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic;
// TODO(EOF) error;
// interpreter.instruction_result = InstructionResult::CallGasTooLow;
// The MIN_CALLEE_GAS rule is a replacement for stipend:
// it simplifies the reasoning about the gas costs and is
// applied uniformly for all introduced EXT*CALL instructions.
//
// If Gas available to callee is less than MIN_CALLEE_GAS trigger light failure (Same as Revert).
if gas_limit < MIN_CALLEE_GAS {
// Push 1 to stack to indicate that call light failed.
// It is safe to ignore stack overflow error as we already popped multiple values from stack.
let _ = interpreter.stack_mut().push(U256::from(1));
interpreter.return_data_buffer.clear();
// Return none to continue execution.
return None;
}

Expand Down Expand Up @@ -226,11 +232,14 @@ pub fn extcall<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host

pop!(interpreter, value);
let has_transfer = value != U256::ZERO;
if interpreter.is_static && has_transfer {
interpreter.instruction_result = InstructionResult::CallNotAllowedInsideStatic;
return;
}

let Some(gas_limit) = extcall_gas_calc(interpreter, host, target_address, has_transfer) else {
return;
};
// TODO Check if static and value 0

// Call host to interact with target contract
interpreter.next_action = InterpreterAction::Call {
Expand Down Expand Up @@ -266,7 +275,6 @@ pub fn extdelegatecall<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpret
let Some(gas_limit) = extcall_gas_calc(interpreter, host, target_address, false) else {
return;
};
// TODO Check if static and value 0

// Call host to interact with target contract
interpreter.next_action = InterpreterAction::Call {
Expand Down
6 changes: 6 additions & 0 deletions crates/interpreter/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ impl Interpreter {
&self.stack
}

/// Returns a mutable reference to the interpreter's stack.
#[inline]
pub fn stack_mut(&mut self) -> &mut Stack {
&mut self.stack
}

/// Returns the current program counter.
#[inline]
pub fn program_counter(&self) -> usize {
Expand Down

0 comments on commit 48409bc

Please sign in to comment.