Skip to content
Prev Previous commit
Next Next commit
refactor: inline and docs
  • Loading branch information
DaniPopes committed Jul 29, 2023
commit c657758366911e7c223ebc4fb1ec7bb37785db13
11 changes: 11 additions & 0 deletions crates/interpreter/src/gas/calc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub fn sstore_refund(original: U256, current: U256, new: U256, spec: SpecId) ->
}
}

#[inline]
pub fn create2_cost(len: usize) -> Option<u64> {
let base = CREATE;
// ceil(len / 32.0)
Expand All @@ -64,6 +65,7 @@ pub fn create2_cost(len: usize) -> Option<u64> {
Some(gas)
}

#[inline]
fn log2floor(value: U256) -> u64 {
assert!(value != U256::ZERO);
let mut l: u64 = 256;
Expand All @@ -83,6 +85,7 @@ fn log2floor(value: U256) -> u64 {
l
}

#[inline]
pub fn exp_cost(power: U256, spec: SpecId) -> Option<u64> {
if power == U256::ZERO {
Some(EXP)
Expand All @@ -100,12 +103,14 @@ pub fn exp_cost(power: U256, spec: SpecId) -> Option<u64> {
}
}

#[inline]
pub fn verylowcopy_cost(len: u64) -> Option<u64> {
let wordd = len / 32;
let wordr = len % 32;
VERYLOW.checked_add(COPY.checked_mul(if wordr == 0 { wordd } else { wordd + 1 })?)
}

#[inline]
pub fn extcodecopy_cost(len: u64, is_cold: bool, spec: SpecId) -> Option<u64> {
let wordd = len / 32;
let wordr = len % 32;
Expand Down Expand Up @@ -154,12 +159,14 @@ pub fn keccak256_cost(len: u64) -> Option<u64> {
/// Apply extra gas cost of 2 for every 32-byte chunk of initcode.
///
/// This cannot overflow as the initcode length is assumed to be checked.
#[inline]
pub fn initcode_cost(len: u64) -> u64 {
let wordd = len / 32;
let wordr = len % 32;
INITCODE_WORD_COST * if wordr == 0 { wordd } else { wordd + 1 }
}

#[inline]
pub fn sload_cost(is_cold: bool, spec: SpecId) -> u64 {
if SpecId::enabled(spec, BERLIN) {
if is_cold {
Expand Down Expand Up @@ -288,6 +295,7 @@ pub fn call_cost(
+ new_cost(is_call_or_staticcall, is_new, transfers_value, spec)
}

#[inline]
pub fn hot_cold_cost(is_cold: bool, regular_value: u64, spec: SpecId) -> u64 {
if SpecId::enabled(spec, BERLIN) {
if is_cold {
Expand All @@ -300,6 +308,7 @@ pub fn hot_cold_cost(is_cold: bool, regular_value: u64, spec: SpecId) -> u64 {
}
}

#[inline]
fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 {
if is_call_or_callcode && transfers_value {
CALLVALUE
Expand All @@ -308,6 +317,7 @@ fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 {
}
}

#[inline]
fn new_cost(is_call_or_staticcall: bool, is_new: bool, transfers_value: bool, spec: SpecId) -> u64 {
if is_call_or_staticcall {
// EIP-161: State trie clearing (invariant-preserving alternative)
Expand All @@ -327,6 +337,7 @@ fn new_cost(is_call_or_staticcall: bool, is_new: bool, transfers_value: bool, sp
}
}

#[inline]
pub fn memory_gas(a: usize) -> u64 {
let a = a as u64;
MEMORY
Expand Down
57 changes: 41 additions & 16 deletions crates/interpreter/src/gas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ mod constants;
pub use calc::*;
pub use constants::*;

#[derive(Clone, Copy, Debug)]
/// Represents the state of gas during execution.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Gas {
/// Gas Limit
/// The initial gas limit.
limit: u64,
/// used+memory gas.
/// The total used gas.
all_used_gas: u64,
/// Used gas without memory
/// Used gas without memory expansion.
used: u64,
/// Used gas for memory expansion
/// Used gas for memory expansion.
memory: u64,
/// Refunded gas. This gas is used only at the end of execution.
/// Refunded gas. This is used only at the end of execution.
refunded: i64,
}

impl Gas {
pub fn new(limit: u64) -> Self {
/// Creates a new `Gas` struct with the given gas limit.
#[inline]
pub const fn new(limit: u64) -> Self {
Self {
limit,
used: 0,
Expand All @@ -28,36 +32,55 @@ impl Gas {
}
}

pub fn limit(&self) -> u64 {
/// Returns the gas limit.
#[inline]
pub const fn limit(&self) -> u64 {
self.limit
}

pub fn memory(&self) -> u64 {
/// Returns the amount of gas that was used.
#[inline]
pub const fn memory(&self) -> u64 {
self.memory
}

pub fn refunded(&self) -> i64 {
/// Returns the amount of gas that was refunded.
#[inline]
pub const fn refunded(&self) -> i64 {
self.refunded
}

pub fn spend(&self) -> u64 {
/// Returns all the gas used in the execution.
#[inline]
pub const fn spend(&self) -> u64 {
self.all_used_gas
}

pub fn remaining(&self) -> u64 {
/// Returns the amount of gas remaining.
#[inline]
pub const fn remaining(&self) -> u64 {
self.limit - self.all_used_gas
}

/// Erases a gas cost from the totals.
#[inline]
pub fn erase_cost(&mut self, returned: u64) {
self.used -= returned;
self.all_used_gas -= returned;
}

/// Records a refund value.
///
/// `refund` can be negative but `self.refunded` should always be positive.
#[inline]
pub fn record_refund(&mut self, refund: i64) {
self.refunded += refund;
}

/// Record an explicit cost.
/// Records an explicit cost.
///
/// This function is called on every instruction in the interpreter if the feature
/// `no_gas_measuring` is not enabled.
#[inline(always)]
pub fn record_cost(&mut self, cost: u64) -> bool {
let (all_used_gas, overflow) = self.all_used_gas.overflowing_add(cost);
Expand All @@ -71,6 +94,7 @@ impl Gas {
}

/// used in memory_resize! macro to record gas used for memory expansion.
#[inline]
pub fn record_memory(&mut self, gas_memory: u64) -> bool {
if gas_memory > self.memory {
let (all_used_gas, overflow) = self.used.overflowing_add(gas_memory);
Expand All @@ -83,9 +107,10 @@ impl Gas {
true
}

/// used in gas_refund! macro to record refund value.
/// Refund can be negative but self.refunded is always positive.
#[inline]
#[deprecated = "Use `record_refund` instead"]
#[doc(hidden)]
pub fn gas_refund(&mut self, refund: i64) {
self.refunded += refund;
self.record_refund(refund);
}
}
19 changes: 19 additions & 0 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,31 @@ pub struct DummyHost {
}

impl DummyHost {
/// Create a new dummy host with the given [`Env`].
#[inline]
pub fn new(env: Env) -> Self {
Self {
env,
storage: HashMap::new(),
log: Vec::new(),
}
}

/// Clears the storage and logs of the dummy host.
#[inline]
pub fn clear(&mut self) {
self.storage.clear();
self.log.clear();
}
}

impl Host for DummyHost {
#[inline]
fn step(&mut self, _interp: &mut Interpreter) -> InstructionResult {
InstructionResult::Continue
}

#[inline]
fn step_end(
&mut self,
_interp: &mut Interpreter,
Expand All @@ -38,30 +45,37 @@ impl Host for DummyHost {
InstructionResult::Continue
}

#[inline]
fn env(&mut self) -> &mut Env {
&mut self.env
}

#[inline]
fn load_account(&mut self, _address: B160) -> Option<(bool, bool)> {
Some((true, true))
}

#[inline]
fn block_hash(&mut self, _number: U256) -> Option<B256> {
Some(B256::zero())
}

#[inline]
fn balance(&mut self, _address: B160) -> Option<(U256, bool)> {
Some((U256::ZERO, false))
}

#[inline]
fn code(&mut self, _address: B160) -> Option<(Bytecode, bool)> {
Some((Bytecode::default(), false))
}

#[inline]
fn code_hash(&mut self, __address: B160) -> Option<(B256, bool)> {
Some((KECCAK_EMPTY, false))
}

#[inline]
fn sload(&mut self, __address: B160, index: U256) -> Option<(U256, bool)> {
match self.storage.entry(index) {
Entry::Occupied(entry) => Some((*entry.get(), false)),
Expand All @@ -72,6 +86,7 @@ impl Host for DummyHost {
}
}

#[inline]
fn sstore(
&mut self,
_address: B160,
Expand All @@ -89,6 +104,7 @@ impl Host for DummyHost {
Some((U256::ZERO, present, value, is_cold))
}

#[inline]
fn log(&mut self, address: B160, topics: Vec<B256>, data: Bytes) {
self.log.push(Log {
address,
Expand All @@ -97,17 +113,20 @@ impl Host for DummyHost {
})
}

#[inline]
fn selfdestruct(&mut self, _address: B160, _target: B160) -> Option<SelfDestructResult> {
panic!("Selfdestruct is not supported for this host")
}

#[inline]
fn create(
&mut self,
_inputs: &mut CreateInputs,
) -> (InstructionResult, Option<B160>, Gas, Bytes) {
panic!("Create is not supported for this host")
}

#[inline]
fn call(&mut self, _input: &mut CallInputs) -> (InstructionResult, Gas, Bytes) {
panic!("Call is not supported for this host")
}
Expand Down
27 changes: 23 additions & 4 deletions crates/interpreter/src/instruction_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,21 @@ pub enum InstructionResult {
}

impl InstructionResult {
pub fn is_error(&self) -> bool {
/// Returns whether the result is a success.
#[inline]
pub fn is_ok(self) -> bool {
matches!(self, crate::return_ok!())
}

/// Returns whether the result is a revert.
#[inline]
pub fn is_revert(self) -> bool {
matches!(self, crate::return_revert!())
}

/// Returns whether the result is an error.
#[inline]
pub fn is_error(self) -> bool {
matches!(
self,
Self::OutOfGas
Expand Down Expand Up @@ -87,11 +101,13 @@ pub enum SuccessOrHalt {

impl SuccessOrHalt {
/// Returns true if the transaction returned successfully without halts.
pub fn is_success(&self) -> bool {
#[inline]
pub fn is_success(self) -> bool {
matches!(self, SuccessOrHalt::Success(_))
}

/// Returns the [Eval] value if this a successful result
#[inline]
pub fn to_success(self) -> Option<Eval> {
match self {
SuccessOrHalt::Success(eval) => Some(eval),
Expand All @@ -100,16 +116,19 @@ impl SuccessOrHalt {
}

/// Returns true if the transaction reverted.
pub fn is_revert(&self) -> bool {
#[inline]
pub fn is_revert(self) -> bool {
matches!(self, SuccessOrHalt::Revert)
}

/// Returns true if the EVM has experienced an exceptional halt
pub fn is_halt(&self) -> bool {
#[inline]
pub fn is_halt(self) -> bool {
matches!(self, SuccessOrHalt::Halt(_))
}

/// Returns the [Halt] value the EVM has experienced an exceptional halt
#[inline]
pub fn to_halt(self) -> Option<Halt> {
match self {
SuccessOrHalt::Halt(halt) => Some(halt),
Expand Down
Loading