Skip to content

Commit

Permalink
Init tracer and generalize gaosmeter over standard invoker (#215)
Browse files Browse the repository at this point in the history
  • Loading branch information
sorpaas authored Nov 16, 2023
1 parent 47e371a commit 1f05d4c
Show file tree
Hide file tree
Showing 11 changed files with 247 additions and 134 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ with-serde = [
members = [
"interpreter",
"jsontests",
"tracer",
]
14 changes: 14 additions & 0 deletions interpreter/src/call_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ impl CallCreateTrapData {
_ => Err(ExitException::InvalidOpcode(opcode).into()),
}
}

pub fn code<H: RuntimeBackend>(&self, handler: &H) -> Vec<u8> {
match self {
Self::Call(trap) => handler.code(trap.target),
Self::Create(trap) => trap.code.clone(),
}
}
}

pub struct CallTrapData {
Expand Down Expand Up @@ -311,6 +318,13 @@ impl CallTrapData {
Err(e) => Err(e),
}
}

pub fn has_value(&self) -> bool {
self.transfer
.as_ref()
.map(|t| t.value != U256::zero())
.unwrap_or(false)
}
}

#[derive(Clone, Debug)]
Expand Down
4 changes: 2 additions & 2 deletions jsontests/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::types::*;
use evm::backend::in_memory::{
InMemoryAccount, InMemoryBackend, InMemoryEnvironment, InMemoryLayer,
};
use evm::standard::{Config, Etable, Invoker};
use evm::standard::{Config, Etable, Gasometer, Invoker};
use evm::utils::u256_to_h256;
use primitive_types::U256;
use std::collections::{BTreeMap, BTreeSet};
Expand Down Expand Up @@ -62,7 +62,7 @@ pub fn run_test(_filename: &str, _test_name: &str, test: Test) -> Result<(), Err

let etable = Etable::runtime();
let invoker = Invoker::new(&config);
let _result = invoker.transact_call(
let _result = invoker.transact_call::<Gasometer, _>(
test.transaction.sender,
test.transaction.to,
test.transaction.value,
Expand Down
6 changes: 3 additions & 3 deletions src/gasometer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ impl Gas for U256 {}
pub enum GasometerMergeStrategy {
Commit,
Revert,
Discard,
}

pub trait Gasometer<S, H>: Sized {
type Gas: Gas;

fn record_stepn(
&mut self,
machine: &Machine<S>,
is_static: bool,
backend: &H,
) -> Result<usize, ExitError>;
fn record_codedeposit(&mut self, len: usize) -> Result<(), ExitError>;
fn gas(&self) -> Self::Gas;
fn gas(&self) -> U256;
fn submeter(&mut self, gas_limit: U256, code: &[u8]) -> Result<Self, ExitError>;
fn merge(&mut self, other: Self, strategy: GasometerMergeStrategy);
}

Expand Down
78 changes: 73 additions & 5 deletions src/standard/gasometer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ use crate::{
use core::cmp::max;
use primitive_types::{H160, H256, U256};

pub trait TransactGasometer<'config, S: AsRef<RuntimeState>>: Sized {
fn new_transact_call(
gas_limit: U256,
code: &[u8],
data: &[u8],
access_list: &Vec<(H160, Vec<H256>)>,
config: &'config Config,
) -> Result<Self, ExitError>;

fn new_transact_create(
gas_limit: U256,
code: &[u8],
access_list: &Vec<(H160, Vec<H256>)>,
config: &'config Config,
) -> Result<Self, ExitError>;
}

pub struct Gasometer<'config> {
gas_limit: u64,
memory_gas: u64,
Expand Down Expand Up @@ -58,7 +75,7 @@ impl<'config> Gasometer<'config> {
}
}

pub fn new<S>(gas_limit: u64, _machine: &Machine<S>, config: &'config Config) -> Self {
pub fn new(gas_limit: u64, _code: &[u8], config: &'config Config) -> Self {
Self {
gas_limit,
memory_gas: 0,
Expand All @@ -69,9 +86,48 @@ impl<'config> Gasometer<'config> {
}
}

impl<'config, S: AsRef<RuntimeState>, H: RuntimeBackend> GasometerT<S, H> for Gasometer<'config> {
type Gas = u64;
impl<'config, S: AsRef<RuntimeState>> TransactGasometer<'config, S> for Gasometer<'config> {
fn new_transact_call(
gas_limit: U256,
code: &[u8],
data: &[u8],
access_list: &Vec<(H160, Vec<H256>)>,
config: &'config Config,
) -> Result<Self, ExitError> {
let gas_limit = if gas_limit > U256::from(u64::MAX) {
return Err(ExitException::OutOfGas.into());
} else {
gas_limit.as_u64()
};

let mut s = Self::new(gas_limit, code, config);
let transaction_cost = TransactionCost::call(data, access_list).cost(config);

s.record_cost(transaction_cost)?;
Ok(s)
}

fn new_transact_create(
gas_limit: U256,
code: &[u8],
access_list: &Vec<(H160, Vec<H256>)>,
config: &'config Config,
) -> Result<Self, ExitError> {
let gas_limit = if gas_limit > U256::from(u64::MAX) {
return Err(ExitException::OutOfGas.into());
} else {
gas_limit.as_u64()
};

let mut s = Self::new(gas_limit, code, config);
let transaction_cost = TransactionCost::create(code, access_list).cost(config);

s.record_cost(transaction_cost)?;
Ok(s)
}
}

impl<'config, S: AsRef<RuntimeState>, H: RuntimeBackend> GasometerT<S, H> for Gasometer<'config> {
fn record_stepn(
&mut self,
machine: &Machine<S>,
Expand Down Expand Up @@ -125,8 +181,19 @@ impl<'config, S: AsRef<RuntimeState>, H: RuntimeBackend> GasometerT<S, H> for Ga
})
}

fn gas(&self) -> u64 {
self.gas()
fn gas(&self) -> U256 {
self.gas().into()
}

fn submeter(&mut self, gas_limit: U256, code: &[u8]) -> Result<Self, ExitError> {
let gas_limit = if gas_limit > U256::from(u64::MAX) {
return Err(ExitException::OutOfGas.into());
} else {
gas_limit.as_u64()
};

self.record_cost(gas_limit)?;
Ok(Self::new(gas_limit, code, self.config))
}

fn merge(&mut self, other: Self, strategy: GasometerMergeStrategy) {
Expand All @@ -138,6 +205,7 @@ impl<'config, S: AsRef<RuntimeState>, H: RuntimeBackend> GasometerT<S, H> for Ga
GasometerMergeStrategy::Revert => {
self.used_gas -= other.gas();
}
GasometerMergeStrategy::Discard => {}
}
}
}
Expand Down
Loading

0 comments on commit 1f05d4c

Please sign in to comment.