Skip to content

Commit

Permalink
Feat: Refactore IsPrecompileResult type (#62)
Browse files Browse the repository at this point in the history
* Redactore IsPrecompile

* Remove type: IsPrecompileResult
  • Loading branch information
mrLSD authored Oct 7, 2024
1 parent 6ead120 commit 530697e
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 63 deletions.
22 changes: 11 additions & 11 deletions gasometer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,14 +634,14 @@ pub fn dynamic_opcode_cost<H: Handler>(
let target = stack.peek_h256(0)?.into();
storage_target = StorageTarget::Address(target);
GasCost::ExtCodeSize {
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
}
}
Opcode::BALANCE => {
let target = stack.peek_h256(0)?.into();
storage_target = StorageTarget::Address(target);
GasCost::Balance {
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
}
}
Opcode::BLOCKHASH => GasCost::BlockHash,
Expand All @@ -650,7 +650,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
let target = stack.peek_h256(0)?.into();
storage_target = StorageTarget::Address(target);
GasCost::ExtCodeHash {
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
}
}
Opcode::EXTCODEHASH => GasCost::Invalid(opcode),
Expand All @@ -661,7 +661,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
GasCost::CallCode {
value: stack.peek(2)?,
gas: stack.peek(0)?,
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
target_exists: {
handler.record_external_operation(evm_core::ExternalOperation::IsEmpty)?;
handler.exists(target)
Expand All @@ -673,7 +673,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
storage_target = StorageTarget::Address(target);
GasCost::StaticCall {
gas: stack.peek(0)?,
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
target_exists: {
handler.record_external_operation(evm_core::ExternalOperation::IsEmpty)?;
handler.exists(target)
Expand All @@ -687,7 +687,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
let target = stack.peek_h256(0)?.into();
storage_target = StorageTarget::Address(target);
GasCost::ExtCodeCopy {
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
len: stack.peek(3)?,
}
}
Expand All @@ -701,7 +701,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
let index = stack.peek_h256(0)?;
storage_target = StorageTarget::Slot(address, index);
GasCost::SLoad {
target_is_cold: handler.is_cold(address, Some(index))?,
target_is_cold: handler.is_cold(address, Some(index)),
}
}

Expand All @@ -710,7 +710,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
storage_target = StorageTarget::Address(target);
GasCost::DelegateCall {
gas: stack.peek(0)?,
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
target_exists: {
handler.record_external_operation(evm_core::ExternalOperation::IsEmpty)?;
handler.exists(target)
Expand All @@ -734,7 +734,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
original: handler.original_storage(address, index),
current: handler.storage(address, index),
new: value,
target_is_cold: handler.is_cold(address, Some(index))?,
target_is_cold: handler.is_cold(address, Some(index)),
}
}
Opcode::LOG0 if !is_static => GasCost::Log {
Expand Down Expand Up @@ -766,7 +766,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
storage_target = StorageTarget::Address(target);
GasCost::Suicide {
value: handler.balance(address),
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
target_exists: {
handler.record_external_operation(evm_core::ExternalOperation::IsEmpty)?;
handler.exists(target)
Expand All @@ -780,7 +780,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
GasCost::Call {
value: stack.peek(2)?,
gas: stack.peek(0)?,
target_is_cold: handler.is_cold(target, None)?,
target_is_cold: handler.is_cold(target, None),
target_exists: {
handler.record_external_operation(evm_core::ExternalOperation::IsEmpty)?;
handler.exists(target)
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ pub trait Handler {
///
/// # Errors
/// Return `ExitError`
fn is_cold(&mut self, address: H160, index: Option<H256>) -> Result<bool, ExitError>;
fn is_cold(&mut self, address: H160, index: Option<H256>) -> bool;

/// Set storage value of address at index.
///
Expand Down
36 changes: 6 additions & 30 deletions src/executor/stack/executor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::backend::Backend;
use crate::executor::stack::precompile::{
IsPrecompileResult, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileSet,
PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileSet,
};
use crate::executor::stack::tagged_runtime::{RuntimeKind, TaggedRuntime};
use crate::gasometer::{self, Gasometer, StorageTarget};
Expand Down Expand Up @@ -1336,30 +1336,11 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler
}
}

fn is_cold(&mut self, address: H160, maybe_index: Option<H256>) -> Result<bool, ExitError> {
Ok(match maybe_index {
None => {
let is_precompile = match self
.precompile_set
.is_precompile(address, self.state.metadata().gasometer.gas())
{
IsPrecompileResult::Answer {
is_precompile,
extra_cost,
} => {
self.state
.metadata_mut()
.gasometer
.record_cost(extra_cost)?;
is_precompile
}
IsPrecompileResult::OutOfGas => return Err(ExitError::OutOfGas),
};

!is_precompile && self.state.is_cold(address)
}
fn is_cold(&mut self, address: H160, maybe_index: Option<H256>) -> bool {
match maybe_index {
None => !self.precompile_set.is_precompile(address) && self.state.is_cold(address),
Some(index) => self.state.is_storage_cold(address, index),
})
}
}

fn gas_left(&self) -> U256 {
Expand Down Expand Up @@ -1610,15 +1591,10 @@ impl<'inner, 'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Pr
// Since we don't go through opcodes we need manually record the call
// cost. Not doing so will make the code panic as recording the call stipend
// will do an underflow.
let target_is_cold = match self.executor.is_cold(code_address, None) {
Ok(x) => x,
Err(err) => return (ExitReason::Error(err), Vec::new()),
};

let gas_cost = gasometer::GasCost::Call {
value: transfer.clone().map_or_else(U256::zero, |x| x.value),
gas: U256::from(gas_limit.unwrap_or(u64::MAX)),
target_is_cold,
target_is_cold: self.executor.is_cold(code_address, None),
target_exists: self.executor.exists(code_address),
};

Expand Down
3 changes: 1 addition & 2 deletions src/executor/stack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub use self::executor::{
};
pub use self::memory::{MemoryStackAccount, MemoryStackState, MemoryStackSubstate};
pub use self::precompile::{
IsPrecompileResult, PrecompileFailure, PrecompileFn, PrecompileHandle, PrecompileOutput,
PrecompileSet,
PrecompileFailure, PrecompileFn, PrecompileHandle, PrecompileOutput, PrecompileSet,
};
pub use ethereum::Log;
24 changes: 5 additions & 19 deletions src/executor/stack/precompile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,27 +104,16 @@ pub trait PrecompileSet {
/// Check if the given address is a precompile. Should only be called to
/// perform the check while not executing the precompile afterward, since
/// `execute` already performs a check internally.
fn is_precompile(&self, address: H160, remaining_gas: u64) -> IsPrecompileResult;
}

pub enum IsPrecompileResult {
Answer {
is_precompile: bool,
extra_cost: u64,
},
OutOfGas,
fn is_precompile(&self, address: H160) -> bool;
}

impl PrecompileSet for () {
fn execute(&self, _: &mut impl PrecompileHandle) -> Option<PrecompileResult> {
None
}

fn is_precompile(&self, _: H160, _: u64) -> IsPrecompileResult {
IsPrecompileResult::Answer {
is_precompile: false,
extra_cost: 0,
}
fn is_precompile(&self, _: H160) -> bool {
false
}
}

Expand Down Expand Up @@ -161,10 +150,7 @@ impl PrecompileSet for BTreeMap<H160, PrecompileFn> {
/// Check if the given address is a precompile. Should only be called to
/// perform the check while not executing the precompile afterward, since
/// `execute` already performs a check internally.
fn is_precompile(&self, address: H160, _: u64) -> IsPrecompileResult {
IsPrecompileResult::Answer {
is_precompile: self.contains_key(&address),
extra_cost: 0,
}
fn is_precompile(&self, address: H160) -> bool {
self.contains_key(&address)
}
}

0 comments on commit 530697e

Please sign in to comment.