Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Refactore IsPrecompileResult type #62

Merged
merged 2 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
}
}
Loading