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

External cost recorder #170

Merged
Merged
Show file tree
Hide file tree
Changes from 14 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
4 changes: 3 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ jobs:
- uses: actions/checkout@v2
- name: Build
run: cargo build --verbose
- name: Build for feature
- name: Build for feature (tracing)
run: cargo build --features tracing --verbose
- name: Build for feature (with-substrate)
run: cargo build --features with-substrate --verbose
- name: Run tests
run: cargo test --verbose
jsontests:
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ with-serde = [
"evm-core/with-serde",
"ethereum/with-serde",
]
with-substrate = []
tracing = [
"environmental",
"evm-gasometer/tracing",
Expand Down
10 changes: 5 additions & 5 deletions gasometer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
value: U256::from_big_endian(&stack.peek(2)?[..]),
gas: U256::from_big_endian(&stack.peek(0)?[..]),
target_is_cold: handler.is_cold(target, None)?,
target_exists: handler.exists(target),
target_exists: handler.exists(target)?,
}
}
Opcode::STATICCALL => {
Expand All @@ -519,7 +519,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
GasCost::StaticCall {
gas: U256::from_big_endian(&stack.peek(0)?[..]),
target_is_cold: handler.is_cold(target, None)?,
target_exists: handler.exists(target),
target_exists: handler.exists(target)?,
}
}
Opcode::SHA3 => GasCost::Sha3 {
Expand Down Expand Up @@ -553,7 +553,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
GasCost::DelegateCall {
gas: U256::from_big_endian(&stack.peek(0)?[..]),
target_is_cold: handler.is_cold(target, None)?,
target_exists: handler.exists(target),
target_exists: handler.exists(target)?,
}
}
Opcode::DELEGATECALL => GasCost::Invalid(opcode),
Expand Down Expand Up @@ -606,7 +606,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
GasCost::Suicide {
value: handler.balance(address),
target_is_cold: handler.is_cold(target, None)?,
target_exists: handler.exists(target),
target_exists: handler.exists(target)?,
already_removed: handler.deleted(address),
}
}
Expand All @@ -620,7 +620,7 @@ pub fn dynamic_opcode_cost<H: Handler>(
value: U256::from_big_endian(&stack.peek(2)?[..]),
gas: U256::from_big_endian(&stack.peek(0)?[..]),
target_is_cold: handler.is_cold(target, None)?,
target_exists: handler.exists(target),
target_exists: handler.exists(target)?,
}
}

Expand Down
34 changes: 23 additions & 11 deletions runtime/src/eval/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,34 +90,46 @@ pub fn base_fee<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
Control::Continue
}

pub fn extcodesize<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
pub fn extcodesize<H: Handler>(runtime: &mut Runtime, handler: &mut H) -> Control<H> {
pop!(runtime, address);
push_u256!(runtime, handler.code_size(address.into()));
let code_size = match handler.code_size(address.into()) {
Ok(v) => v,
Err(e) => return Control::Exit(e.into()),
};
push_u256!(runtime, code_size);

Control::Continue
}

pub fn extcodehash<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
pub fn extcodehash<H: Handler>(runtime: &mut Runtime, handler: &mut H) -> Control<H> {
pop!(runtime, address);
push!(runtime, handler.code_hash(address.into()));
let code_hash = match handler.code_hash(address.into()) {
Ok(v) => v,
Err(e) => return Control::Exit(e.into()),
};
push!(runtime, code_hash);

Control::Continue
}

pub fn extcodecopy<H: Handler>(runtime: &mut Runtime, handler: &H) -> Control<H> {
pub fn extcodecopy<H: Handler>(runtime: &mut Runtime, handler: &mut H) -> Control<H> {
pop!(runtime, address);
pop_u256!(runtime, memory_offset, code_offset, len);

try_or_fail!(runtime
.machine
.memory_mut()
.resize_offset(memory_offset, len));
match runtime.machine.memory_mut().copy_large(
memory_offset,
code_offset,
len,
&handler.code(address.into()),
) {

let code = match handler.code(address.into()) {
Ok(code) => code,
Err(e) => return Control::Exit(e.into()),
};
match runtime
.machine
.memory_mut()
.copy_large(memory_offset, code_offset, len, &code)
{
Ok(()) => (),
Err(e) => return Control::Exit(e.into()),
};
Expand Down
8 changes: 4 additions & 4 deletions runtime/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ pub trait Handler {
/// Get balance of address.
fn balance(&self, address: H160) -> U256;
/// Get code size of address.
fn code_size(&self, address: H160) -> U256;
fn code_size(&mut self, address: H160) -> Result<U256, ExitError>;
tgmichel marked this conversation as resolved.
Show resolved Hide resolved
/// Get code hash of address.
fn code_hash(&self, address: H160) -> H256;
fn code_hash(&mut self, address: H160) -> Result<H256, ExitError>;
/// Get code of address.
fn code(&self, address: H160) -> Vec<u8>;
fn code(&mut self, address: H160) -> Result<Vec<u8>, ExitError>;
/// Get storage value of address at index.
fn storage(&self, address: H160, index: H256) -> H256;
/// Get original storage value of address at index.
Expand Down Expand Up @@ -64,7 +64,7 @@ pub trait Handler {
fn chain_id(&self) -> U256;

/// Check whether an address exists.
fn exists(&self, address: H160) -> bool;
fn exists(&mut self, address: H160) -> Result<bool, ExitError>;
/// Check whether an address has already been deleted.
fn deleted(&self, address: H160) -> bool;
/// Checks if the address or (address, index) pair has been previously accessed
Expand Down
8 changes: 5 additions & 3 deletions src/backend/memory.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{Apply, ApplyBackend, Backend, Basic, Log};
use crate::ExitError;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use primitive_types::{H160, H256, U256};
Expand Down Expand Up @@ -143,11 +144,12 @@ impl<'vicinity> Backend for MemoryBackend<'vicinity> {
.unwrap_or_default()
}

fn code(&self, address: H160) -> Vec<u8> {
self.state
fn code(&mut self, address: H160) -> Result<Vec<u8>, ExitError> {
Ok(self
.state
.get(&address)
.map(|v| v.code.clone())
.unwrap_or_default()
.unwrap_or_default())
}

fn storage(&self, address: H160, index: H256) -> H256 {
Expand Down
6 changes: 3 additions & 3 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
mod memory;

pub use self::memory::{MemoryAccount, MemoryBackend, MemoryVicinity};

use crate::ExitError;
use alloc::vec::Vec;
use primitive_types::{H160, H256, U256};

Expand Down Expand Up @@ -50,7 +50,7 @@ pub enum Apply<I> {
}

/// EVM backend.
#[auto_impl::auto_impl(&, Arc, Box)]
//#[auto_impl::auto_impl(&, Arc, Box)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we still implement this for &mut and Box?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I'm fine keeping this as is for now.

A refactoring we can do is to move record_external_operation into a separate trait Record, and then add yet another type parameter to StackExecutor R: Record. Then we can uncomment this again.

But the changes are already huge so we can do that in a separate PR.

pub trait Backend {
/// Gas price. Unused for London.
fn gas_price(&self) -> U256;
Expand Down Expand Up @@ -80,7 +80,7 @@ pub trait Backend {
/// Get basic account information.
fn basic(&self, address: H160) -> Basic;
/// Get account code.
fn code(&self, address: H160) -> Vec<u8>;
fn code(&mut self, address: H160) -> Result<Vec<u8>, ExitError>;
/// Get storage value of address at index.
fn storage(&self, address: H160, index: H256) -> H256;
/// Get original storage value of address at index, if available.
Expand Down
Loading