From ad79c3059ddba0633c1159b3db5f3aefe217ad79 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Tue, 11 May 2021 13:00:52 +0000 Subject: [PATCH 01/15] gasometer tracing --- gasometer/Cargo.toml | 5 +++++ gasometer/src/lib.rs | 17 ++++++++++++-- gasometer/src/tracing.rs | 48 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 gasometer/src/tracing.rs diff --git a/gasometer/Cargo.toml b/gasometer/Cargo.toml index 1cb0e0b11..c3b7c1604 100644 --- a/gasometer/Cargo.toml +++ b/gasometer/Cargo.toml @@ -12,6 +12,7 @@ edition = "2018" primitive-types = { version = "0.9", default-features = false } evm-core = { version = "0.26", path = "../core", default-features = false } evm-runtime = { version = "0.26", path = "../runtime", default-features = false } +environmental = { version = "1.1.2", default-features = false, optional = true} [features] default = ["std"] @@ -19,4 +20,8 @@ std = [ "evm-core/std", "evm-runtime/std", "primitive-types/std", + "environmental/std" ] +tracing = [ + "environmental" +] \ No newline at end of file diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 0d09828ae..8a63b2bd8 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -1,7 +1,7 @@ //! EVM gasometer. #![deny(warnings)] -#![forbid(unsafe_code, unused_variables, unused_imports)] +#![forbid(unsafe_code, unused_variables)] #![cfg_attr(not(feature = "std"), no_std)] @@ -9,6 +9,7 @@ mod consts; mod costs; mod memory; mod utils; +pub mod tracing; use core::cmp::max; use primitive_types::{H160, H256, U256}; @@ -115,6 +116,8 @@ impl<'config> Gasometer<'config> { &mut self, cost: u64, ) -> Result<(), ExitError> { + tracing::emit(|| tracing::Event::RecordCost(cost)); + let all_gas_cost = self.total_used_gas() + cost; if self.gas_limit < all_gas_cost { self.inner = Err(ExitError::OutOfGas); @@ -131,6 +134,8 @@ impl<'config> Gasometer<'config> { &mut self, refund: i64, ) -> Result<(), ExitError> { + tracing::emit(|| tracing::Event::RecordRefund(refund)); + self.inner_mut()?.refunded_gas += refund; Ok(()) } @@ -161,6 +166,10 @@ impl<'config> Gasometer<'config> { let gas_refund = self.inner_mut()?.gas_refund(cost); let used_gas = self.inner_mut()?.used_gas; + tracing::emit(|| tracing::Event::RecordDynamicCost { + gas_cost, memory_gas, gas_refund + }); + let all_gas_cost = memory_gas + used_gas + gas_cost; if self.gas_limit < all_gas_cost { self.inner = Err(ExitError::OutOfGas); @@ -183,6 +192,8 @@ impl<'config> Gasometer<'config> { &mut self, stipend: u64, ) -> Result<(), ExitError> { + tracing::emit(|| tracing::Event::RecordStipend(stipend)); + self.inner_mut()?.used_gas -= stipend; Ok(()) } @@ -205,10 +216,12 @@ impl<'config> Gasometer<'config> { }, }; + tracing::emit(|| tracing::Event::RecordTransaction(gas_cost)); + if self.gas() < gas_cost { self.inner = Err(ExitError::OutOfGas); return Err(ExitError::OutOfGas); - } + } self.inner_mut()?.used_gas += gas_cost; Ok(()) diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs new file mode 100644 index 000000000..a11aece4c --- /dev/null +++ b/gasometer/src/tracing.rs @@ -0,0 +1,48 @@ +//! Allow to listen to gasometer events. +//! Enable `tracing` feature for events to be emitted. + +#[cfg(feature = "tracing")] +environmental::environmental!(hook: dyn EventListener + 'static); + +pub trait EventListener { + fn accept(&mut self, event: Event); +} + +pub enum Event { + RecordCost(u64), + RecordRefund(i64), + RecordStipend(u64), + RecordDynamicCost { + gas_cost: u64, + memory_gas: u64, + gas_refund: i64, + }, + RecordTransaction(u64), +} + +#[cfg(feature = "tracing")] +pub(crate) fn emit(f: F) +where + F: FnOnce() -> Event +{ + hook::with(|hook| { + hook.accept(f()); + }); +} + +#[cfg(not(feature = "tracing"))] +pub(crate) fn emit(_f: F) +where + F: FnOnce() -> Event +{ + // No-op. +} + +/// Run closure with provided listener. +#[cfg(feature = "tracing")] +pub fn using R>( + listener: &mut (dyn EventListener + 'static), + f: F +) -> R { + hook::using(listener, f) +} \ No newline at end of file From 94eb563b901eb3b17866b5ae3cdeef4381239000 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Tue, 11 May 2021 13:53:10 +0000 Subject: [PATCH 02/15] use trait methods and macro --- gasometer/src/lib.rs | 14 +++++------ gasometer/src/tracing.rs | 52 ++++++++++++++++------------------------ 2 files changed, 28 insertions(+), 38 deletions(-) diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 8a63b2bd8..30e826bbd 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -9,6 +9,8 @@ mod consts; mod costs; mod memory; mod utils; + +#[macro_use] pub mod tracing; use core::cmp::max; @@ -116,7 +118,7 @@ impl<'config> Gasometer<'config> { &mut self, cost: u64, ) -> Result<(), ExitError> { - tracing::emit(|| tracing::Event::RecordCost(cost)); + event!(record_cost(cost)); let all_gas_cost = self.total_used_gas() + cost; if self.gas_limit < all_gas_cost { @@ -134,7 +136,7 @@ impl<'config> Gasometer<'config> { &mut self, refund: i64, ) -> Result<(), ExitError> { - tracing::emit(|| tracing::Event::RecordRefund(refund)); + event!(record_refund(refund)); self.inner_mut()?.refunded_gas += refund; Ok(()) @@ -166,9 +168,7 @@ impl<'config> Gasometer<'config> { let gas_refund = self.inner_mut()?.gas_refund(cost); let used_gas = self.inner_mut()?.used_gas; - tracing::emit(|| tracing::Event::RecordDynamicCost { - gas_cost, memory_gas, gas_refund - }); + event!(record_dynamic_cost(gas_cost, memory_gas, gas_refund)); let all_gas_cost = memory_gas + used_gas + gas_cost; if self.gas_limit < all_gas_cost { @@ -192,7 +192,7 @@ impl<'config> Gasometer<'config> { &mut self, stipend: u64, ) -> Result<(), ExitError> { - tracing::emit(|| tracing::Event::RecordStipend(stipend)); + event!(record_stipend(stipend)); self.inner_mut()?.used_gas -= stipend; Ok(()) @@ -216,7 +216,7 @@ impl<'config> Gasometer<'config> { }, }; - tracing::emit(|| tracing::Event::RecordTransaction(gas_cost)); + event!(record_transaction(gas_cost)); if self.gas() < gas_cost { self.inner = Err(ExitError::OutOfGas); diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs index a11aece4c..684e696a0 100644 --- a/gasometer/src/tracing.rs +++ b/gasometer/src/tracing.rs @@ -1,41 +1,19 @@ -//! Allow to listen to gasometer events. -//! Enable `tracing` feature for events to be emitted. +//! Allows to listen to gasometer events. #[cfg(feature = "tracing")] environmental::environmental!(hook: dyn EventListener + 'static); +#[cfg(feature = "tracing")] pub trait EventListener { - fn accept(&mut self, event: Event); -} - -pub enum Event { - RecordCost(u64), - RecordRefund(i64), - RecordStipend(u64), - RecordDynamicCost { + fn record_cost(cost: u64) { } + fn record_refund(refund: i64) { } + fn record_stipend(stipend: u64) { } + fn record_dynamic_cost( gas_cost: u64, memory_gas: u64, - gas_refund: i64, - }, - RecordTransaction(u64), -} - -#[cfg(feature = "tracing")] -pub(crate) fn emit(f: F) -where - F: FnOnce() -> Event -{ - hook::with(|hook| { - hook.accept(f()); - }); -} - -#[cfg(not(feature = "tracing"))] -pub(crate) fn emit(_f: F) -where - F: FnOnce() -> Event -{ - // No-op. + gas_refund: i64 + ) { } + fn record_transaction(transaction_cost: u64) { } } /// Run closure with provided listener. @@ -45,4 +23,16 @@ pub fn using R>( f: F ) -> R { hook::using(listener, f) +} + +#[cfg(not(feature = "tracing"))] +macro_rules! event { + ($func_name: ident ( $($arg:expr),* )) => { } +} + +#[cfg(feature = "tracing")] +macro_rules! event { + ($method: ident ( $($arg:expr),* )) => { + hook::with(|hook| hook.$method( $($arg)* )); + } } \ No newline at end of file From cc5448498a27c9c7046a9ea118a6490736a890d2 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Tue, 11 May 2021 14:20:50 +0000 Subject: [PATCH 03/15] fix macro --- gasometer/src/tracing.rs | 66 ++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs index 684e696a0..0a911c87f 100644 --- a/gasometer/src/tracing.rs +++ b/gasometer/src/tracing.rs @@ -1,29 +1,55 @@ //! Allows to listen to gasometer events. #[cfg(feature = "tracing")] -environmental::environmental!(hook: dyn EventListener + 'static); +pub(crate) mod inner { + environmental::environmental!(hook: dyn EventListener + 'static); -#[cfg(feature = "tracing")] -pub trait EventListener { - fn record_cost(cost: u64) { } - fn record_refund(refund: i64) { } - fn record_stipend(stipend: u64) { } - fn record_dynamic_cost( - gas_cost: u64, - memory_gas: u64, - gas_refund: i64 - ) { } - fn record_transaction(transaction_cost: u64) { } + pub trait EventListener { + fn record_cost( + &mut self, + _cost: u64 + ) { } + + fn record_refund( + &mut self, + _refund: i64 + ) { } + + fn record_stipend( + &mut self, + _stipend: u64 + ) { } + + fn record_dynamic_cost( + &mut self, + _gas_cost: u64, + _memory_gas: u64, + _gas_refund: i64 + ) { } + + fn record_transaction( + &mut self, + _transaction_cost: u64 + ) { } + } + + /// Run closure with provided listener. + pub fn using R>( + listener: &mut (dyn EventListener + 'static), + f: F + ) -> R { + hook::using(listener, f) + } + + pub(crate) fn with( + f: F + ) { + hook::with(f); + } } -/// Run closure with provided listener. #[cfg(feature = "tracing")] -pub fn using R>( - listener: &mut (dyn EventListener + 'static), - f: F -) -> R { - hook::using(listener, f) -} +pub use inner::using; #[cfg(not(feature = "tracing"))] macro_rules! event { @@ -33,6 +59,6 @@ macro_rules! event { #[cfg(feature = "tracing")] macro_rules! event { ($method: ident ( $($arg:expr),* )) => { - hook::with(|hook| hook.$method( $($arg)* )); + $crate::tracing::inner::with(|hook| hook.$method( $($arg),* )); } } \ No newline at end of file From baebf7011e103767d6304bfaacf1488a043df13b Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Wed, 12 May 2021 11:04:20 +0000 Subject: [PATCH 04/15] change back to enums --- gasometer/src/lib.rs | 12 +++--- gasometer/src/tracing.rs | 84 +++++++++++++++----------------------- runtime/Cargo.toml | 6 ++- runtime/src/eval/system.rs | 18 +++++++- runtime/src/lib.rs | 11 ++++- runtime/src/tracing.rs | 58 ++++++++++++++++++++++++++ 6 files changed, 127 insertions(+), 62 deletions(-) create mode 100644 runtime/src/tracing.rs diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 30e826bbd..634e5114b 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -9,8 +9,6 @@ mod consts; mod costs; mod memory; mod utils; - -#[macro_use] pub mod tracing; use core::cmp::max; @@ -118,7 +116,7 @@ impl<'config> Gasometer<'config> { &mut self, cost: u64, ) -> Result<(), ExitError> { - event!(record_cost(cost)); + tracing::Event::RecordCost(cost).emit(); let all_gas_cost = self.total_used_gas() + cost; if self.gas_limit < all_gas_cost { @@ -136,7 +134,7 @@ impl<'config> Gasometer<'config> { &mut self, refund: i64, ) -> Result<(), ExitError> { - event!(record_refund(refund)); + tracing::Event::RecordRefund(refund).emit(); self.inner_mut()?.refunded_gas += refund; Ok(()) @@ -168,7 +166,7 @@ impl<'config> Gasometer<'config> { let gas_refund = self.inner_mut()?.gas_refund(cost); let used_gas = self.inner_mut()?.used_gas; - event!(record_dynamic_cost(gas_cost, memory_gas, gas_refund)); + tracing::Event::RecordDynamicCost {gas_cost, memory_gas, gas_refund}.emit(); let all_gas_cost = memory_gas + used_gas + gas_cost; if self.gas_limit < all_gas_cost { @@ -192,7 +190,7 @@ impl<'config> Gasometer<'config> { &mut self, stipend: u64, ) -> Result<(), ExitError> { - event!(record_stipend(stipend)); + tracing::Event::RecordStipend(stipend).emit(); self.inner_mut()?.used_gas -= stipend; Ok(()) @@ -216,7 +214,7 @@ impl<'config> Gasometer<'config> { }, }; - event!(record_transaction(gas_cost)); + tracing::Event::RecordTransaction(gas_cost).emit(); if self.gas() < gas_cost { self.inner = Err(ExitError::OutOfGas); diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs index 0a911c87f..2eba324b1 100644 --- a/gasometer/src/tracing.rs +++ b/gasometer/src/tracing.rs @@ -1,64 +1,46 @@ //! Allows to listen to gasometer events. #[cfg(feature = "tracing")] -pub(crate) mod inner { - environmental::environmental!(hook: dyn EventListener + 'static); +environmental::environmental!(hook: dyn EventListener + 'static); - pub trait EventListener { - fn record_cost( - &mut self, - _cost: u64 - ) { } - - fn record_refund( - &mut self, - _refund: i64 - ) { } - - fn record_stipend( - &mut self, - _stipend: u64 - ) { } - - fn record_dynamic_cost( - &mut self, - _gas_cost: u64, - _memory_gas: u64, - _gas_refund: i64 - ) { } +#[cfg(feature = "tracing")] +pub trait EventListener { + fn event( + &mut self, + event: Event + ); +} - fn record_transaction( - &mut self, - _transaction_cost: u64 - ) { } - } +#[derive(Debug, Copy, Clone)] +pub enum Event { + RecordCost(u64), + RecordRefund(i64), + RecordStipend(u64), + RecordDynamicCost { + gas_cost: u64, + memory_gas: u64, + gas_refund: i64, + }, + RecordTransaction(u64), +} - /// Run closure with provided listener. - pub fn using R>( - listener: &mut (dyn EventListener + 'static), - f: F - ) -> R { - hook::using(listener, f) +impl Event { + #[cfg(feature = "tracing")] + pub(crate) fn emit(self) { + hook::with(|hook| hook.event(self)); } - pub(crate) fn with( - f: F - ) { - hook::with(f); + #[cfg(not(feature = "tracing"))] + pub(crate) fn emit(self) { + // no op. } } +/// Run closure with provided listener. #[cfg(feature = "tracing")] -pub use inner::using; - -#[cfg(not(feature = "tracing"))] -macro_rules! event { - ($func_name: ident ( $($arg:expr),* )) => { } -} - -#[cfg(feature = "tracing")] -macro_rules! event { - ($method: ident ( $($arg:expr),* )) => { - $crate::tracing::inner::with(|hook| hook.$method( $($arg),* )); - } +pub fn using R>( + listener: &mut (dyn EventListener + 'static), + f: F +) -> R { + hook::using(listener, f) } \ No newline at end of file diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 8f0668130..dbe7f5097 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -12,7 +12,11 @@ edition = "2018" evm-core = { version = "0.26", path = "../core", default-features = false } primitive-types = { version = "0.9", default-features = false } sha3 = { version = "0.8", default-features = false } +environmental = { version = "1.1.2", default-features = false, optional = true} [features] default = ["std"] -std = ["evm-core/std", "primitive-types/std", "sha3/std"] +std = ["evm-core/std", "primitive-types/std", "sha3/std", "environmental/std"] +tracing = [ + "environmental" +] \ No newline at end of file diff --git a/runtime/src/eval/system.rs b/runtime/src/eval/system.rs index 7d3321063..e02b8e0c4 100644 --- a/runtime/src/eval/system.rs +++ b/runtime/src/eval/system.rs @@ -2,7 +2,7 @@ use core::cmp::min; use alloc::vec::Vec; use primitive_types::{H256, U256}; use sha3::{Keccak256, Digest}; -use crate::{Runtime, ExitError, Handler, Capture, Transfer, ExitReason, +use crate::{tracing, Runtime, ExitError, Handler, Capture, Transfer, ExitReason, CreateScheme, CallScheme, Context, ExitSucceed, ExitFatal}; use super::Control; @@ -171,13 +171,27 @@ pub fn gaslimit(runtime: &mut Runtime, handler: &H) -> Control { pub fn sload(runtime: &mut Runtime, handler: &H) -> Control { pop!(runtime, index); - push!(runtime, handler.storage(runtime.context.address, index)); + let value = handler.storage(runtime.context.address, index); + push!(runtime, value); + + tracing::Event::SLoad { + address: runtime.context.address, + index, + value + }.emit(); Control::Continue } pub fn sstore(runtime: &mut Runtime, handler: &mut H) -> Control { pop!(runtime, index, value); + + tracing::Event::SStore { + address: runtime.context.address, + index, + value + }.emit(); + match handler.set_storage(runtime.context.address, index, value) { Ok(()) => Control::Continue, Err(e) => Control::Exit(e.into()), diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 35b391769..439d778e2 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1,16 +1,18 @@ //! Runtime layer for EVM. #![deny(warnings)] -#![forbid(unsafe_code, unused_variables, unused_imports)] +#![forbid(unsafe_code, unused_variables)] #![cfg_attr(not(feature = "std"), no_std)] extern crate alloc; + mod eval; mod context; mod interrupt; mod handler; +pub mod tracing; pub use evm_core::*; @@ -24,6 +26,13 @@ use alloc::rc::Rc; macro_rules! step { ( $self:expr, $handler:expr, $return:tt $($err:path)?; $($ok:path)? ) => ({ if let Some((opcode, stack)) = $self.machine.inspect() { + tracing::Event::Step { + context: &$self.context, + opcode, + stack, + memory: $self.machine.memory() + }.emit(); + match $handler.pre_validate(&$self.context, opcode, stack) { Ok(()) => (), Err(e) => { diff --git a/runtime/src/tracing.rs b/runtime/src/tracing.rs new file mode 100644 index 000000000..65c589f58 --- /dev/null +++ b/runtime/src/tracing.rs @@ -0,0 +1,58 @@ +//! Allows to listen to runtime events. + +use crate::{Context, Opcode, Stack, Memory}; +use primitive_types::{H160, H256}; + + + +#[cfg(feature = "tracing")] +environmental::environmental!(hook: dyn EventListener + 'static); + +#[cfg(feature = "tracing")] +pub trait EventListener { + fn event( + &mut self, + event: Event + ); +} + +#[derive(Debug, Copy, Clone)] +pub enum Event<'a> { + Step { + context: &'a Context, + opcode: Opcode, + stack: &'a Stack, + memory: &'a Memory + }, + SLoad { + address: H160, + index: H256, + value: H256 + }, + SStore { + address: H160, + index: H256, + value: H256 + }, +} + +impl<'a> Event<'a> { + #[cfg(feature = "tracing")] + pub(crate) fn emit(self) { + hook::with(|hook| hook.event(self)); + } + + #[cfg(not(feature = "tracing"))] + pub(crate) fn emit(self) { + // no op. + } +} + +/// Run closure with provided listener. +#[cfg(feature = "tracing")] +pub fn using R>( + listener: &mut (dyn EventListener + 'static), + f: F +) -> R { + hook::using(listener, f) +} \ No newline at end of file From dccd2193f73245c22bd830784815629366454ed4 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Wed, 12 May 2021 11:54:04 +0000 Subject: [PATCH 05/15] add StepResult event --- runtime/src/lib.rs | 6 +++++- runtime/src/tracing.rs | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 439d778e2..6e10f70fd 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -50,7 +50,11 @@ macro_rules! step { }, } - match $self.machine.step() { + let result = $self.machine.step(); + + tracing::Event::StepResult(&result).emit(); + + match result { Ok(()) => $($ok)?(()), Err(Capture::Exit(e)) => { $self.status = Err(e.clone()); diff --git a/runtime/src/tracing.rs b/runtime/src/tracing.rs index 65c589f58..612119234 100644 --- a/runtime/src/tracing.rs +++ b/runtime/src/tracing.rs @@ -1,6 +1,6 @@ //! Allows to listen to runtime events. -use crate::{Context, Opcode, Stack, Memory}; +use crate::{Context, Opcode, Stack, Memory, Capture, ExitReason, Trap}; use primitive_types::{H160, H256}; @@ -24,6 +24,7 @@ pub enum Event<'a> { stack: &'a Stack, memory: &'a Memory }, + StepResult (&'a Result<(), Capture>), SLoad { address: H160, index: H256, From 1f47c18ebfbf6c50eb0de87539fde8b79f50aea7 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Thu, 13 May 2021 14:09:47 +0000 Subject: [PATCH 06/15] more data in events --- gasometer/src/tracing.rs | 8 ++++---- runtime/src/lib.rs | 7 ++++++- runtime/src/tracing.rs | 16 +++++++++------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs index 2eba324b1..f962c3af7 100644 --- a/gasometer/src/tracing.rs +++ b/gasometer/src/tracing.rs @@ -1,7 +1,7 @@ //! Allows to listen to gasometer events. #[cfg(feature = "tracing")] -environmental::environmental!(hook: dyn EventListener + 'static); +environmental::environmental!(listener: dyn EventListener + 'static); #[cfg(feature = "tracing")] pub trait EventListener { @@ -27,7 +27,7 @@ pub enum Event { impl Event { #[cfg(feature = "tracing")] pub(crate) fn emit(self) { - hook::with(|hook| hook.event(self)); + listener::with(|listener| listener.event(self)); } #[cfg(not(feature = "tracing"))] @@ -39,8 +39,8 @@ impl Event { /// Run closure with provided listener. #[cfg(feature = "tracing")] pub fn using R>( - listener: &mut (dyn EventListener + 'static), + new: &mut (dyn EventListener + 'static), f: F ) -> R { - hook::using(listener, f) + listener::using(new, f) } \ No newline at end of file diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 6e10f70fd..611923235 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -29,6 +29,7 @@ macro_rules! step { tracing::Event::Step { context: &$self.context, opcode, + position: $self.machine.position(), stack, memory: $self.machine.memory() }.emit(); @@ -51,8 +52,12 @@ macro_rules! step { } let result = $self.machine.step(); + let return_value = $self.machine.return_value(); - tracing::Event::StepResult(&result).emit(); + tracing::Event::StepResult { + result: &result, + return_value: &return_value, + }.emit(); match result { Ok(()) => $($ok)?(()), diff --git a/runtime/src/tracing.rs b/runtime/src/tracing.rs index 612119234..623374c39 100644 --- a/runtime/src/tracing.rs +++ b/runtime/src/tracing.rs @@ -3,10 +3,8 @@ use crate::{Context, Opcode, Stack, Memory, Capture, ExitReason, Trap}; use primitive_types::{H160, H256}; - - #[cfg(feature = "tracing")] -environmental::environmental!(hook: dyn EventListener + 'static); +environmental::environmental!(listener: dyn EventListener + 'static); #[cfg(feature = "tracing")] pub trait EventListener { @@ -21,10 +19,14 @@ pub enum Event<'a> { Step { context: &'a Context, opcode: Opcode, + position: &'a Result, stack: &'a Stack, memory: &'a Memory }, - StepResult (&'a Result<(), Capture>), + StepResult { + result: &'a Result<(), Capture>, + return_value: &'a [u8], + }, SLoad { address: H160, index: H256, @@ -40,7 +42,7 @@ pub enum Event<'a> { impl<'a> Event<'a> { #[cfg(feature = "tracing")] pub(crate) fn emit(self) { - hook::with(|hook| hook.event(self)); + listener::with(|listener| listener.event(self)); } #[cfg(not(feature = "tracing"))] @@ -52,8 +54,8 @@ impl<'a> Event<'a> { /// Run closure with provided listener. #[cfg(feature = "tracing")] pub fn using R>( - listener: &mut (dyn EventListener + 'static), + new: &mut (dyn EventListener + 'static), f: F ) -> R { - hook::using(listener, f) + listener::using(new, f) } \ No newline at end of file From c58502dd09da0ff2df50935e9dca291c4d8c87f6 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Mon, 17 May 2021 09:22:35 +0000 Subject: [PATCH 07/15] EVM events --- Cargo.toml | 6 ++++- runtime/src/lib.rs | 1 - src/executor/stack/mod.rs | 19 ++++++++++++- src/lib.rs | 3 ++- src/tracing.rs | 56 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 src/tracing.rs diff --git a/Cargo.toml b/Cargo.toml index e888652d9..788c7009e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ primitive-types = { version = "0.9", default-features = false, features = ["rlp" serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "2.0", default-features = false, features = ["derive"], optional = true } ethereum = { version = "0.7", default-features = false } +environmental = { version = "1.1.2", default-features = false, optional = true} [dev-dependencies] criterion = "0.3" @@ -32,7 +33,10 @@ harness = false default = ["std"] with-codec = ["codec", "evm-core/with-codec", "primitive-types/codec", "ethereum/with-codec"] with-serde = ["serde", "evm-core/with-serde", "primitive-types/serde", "ethereum/with-serde"] -std = ["evm-core/std", "evm-gasometer/std", "evm-runtime/std", "sha3/std", "primitive-types/std", "serde/std", "codec/std", "log/std", "ethereum/std"] +std = ["evm-core/std", "evm-gasometer/std", "evm-runtime/std", "sha3/std", "primitive-types/std", "serde/std", "codec/std", "log/std", "ethereum/std", "environmental/std"] +tracing = [ + "environmental" +] [workspace] members = [ diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 611923235..edc7ce25d 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -7,7 +7,6 @@ extern crate alloc; - mod eval; mod context; mod interrupt; diff --git a/src/executor/stack/mod.rs b/src/executor/stack/mod.rs index 8ff7ac508..8c5b51c17 100644 --- a/src/executor/stack/mod.rs +++ b/src/executor/stack/mod.rs @@ -7,7 +7,7 @@ use alloc::{rc::Rc, vec::Vec}; use primitive_types::{U256, H256, H160}; use sha3::{Keccak256, Digest}; use crate::{ExitError, Stack, Opcode, Capture, Handler, Transfer, - Context, CreateScheme, Runtime, ExitReason, ExitSucceed, Config}; + Context, CreateScheme, Runtime, ExitReason, ExitSucceed, Config, tracing}; use crate::gasometer::{self, Gasometer}; pub enum StackExitKind { @@ -328,6 +328,14 @@ impl<'config, S: StackState<'config>> StackExecutor<'config, S> { gas - gas / 64 } + tracing::Event::Create { + caller, + scheme, + value, + init_code: &init_code, + target_gas + }.emit(); + if let Some(depth) = self.state.metadata().depth { if depth > self.config.call_stack_limit { return Capture::Exit((ExitError::CallTooDeep.into(), None, Vec::new())) @@ -475,6 +483,15 @@ impl<'config, S: StackState<'config>> StackExecutor<'config, S> { gas - gas / 64 } + tracing::Event::Call { + code_address, + transfer: &transfer, + input: &input, + target_gas, + is_static, + context: &context, + }.emit(); + let after_gas = if take_l64 && self.config.call_l64_after_gas { if self.config.estimate { let initial_after_gas = self.state.metadata().gasometer.gas(); diff --git a/src/lib.rs b/src/lib.rs index 612d4b845..9ff0c83ad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ //! Ethereum Virtual Machine implementation in Rust #![deny(warnings)] -#![forbid(unsafe_code, unused_variables, unused_imports)] +#![forbid(unsafe_code, unused_variables)] #![cfg_attr(not(feature = "std"), no_std)] @@ -13,3 +13,4 @@ pub use evm_gasometer as gasometer; pub mod executor; pub mod backend; +pub mod tracing; diff --git a/src/tracing.rs b/src/tracing.rs new file mode 100644 index 000000000..9954f0f53 --- /dev/null +++ b/src/tracing.rs @@ -0,0 +1,56 @@ +//! Allows to listen to runtime events. + +use crate::{Context}; +use evm_runtime::{CreateScheme, Transfer}; +use primitive_types::{H160, U256}; + +#[cfg(feature = "tracing")] +environmental::environmental!(listener: dyn EventListener + 'static); + +#[cfg(feature = "tracing")] +pub trait EventListener { + fn event( + &mut self, + event: Event + ); +} + +#[derive(Debug, Copy, Clone)] +pub enum Event<'a> { + Call { + code_address: H160, + transfer: &'a Option, + input: &'a [u8], + target_gas: Option, + is_static: bool, + context: &'a Context, + }, + Create { + caller: H160, + scheme: CreateScheme, + value: U256, + init_code: &'a [u8], + target_gas: Option, + } +} + +impl<'a> Event<'a> { + #[cfg(feature = "tracing")] + pub(crate) fn emit(self) { + listener::with(|listener| listener.event(self)); + } + + #[cfg(not(feature = "tracing"))] + pub(crate) fn emit(self) { + // no op. + } +} + +/// Run closure with provided listener. +#[cfg(feature = "tracing")] +pub fn using R>( + new: &mut (dyn EventListener + 'static), + f: F +) -> R { + listener::using(new, f) +} \ No newline at end of file From 6c2569afe7deac9e4e2cb47ddab346e31c994fe6 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Tue, 18 May 2021 11:23:07 +0000 Subject: [PATCH 08/15] add snapshot of gasometer state in events --- gasometer/src/lib.rs | 37 ++++++++++++++++++++++++++++++++----- gasometer/src/tracing.rs | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 634e5114b..4ba271f1e 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -116,7 +116,10 @@ impl<'config> Gasometer<'config> { &mut self, cost: u64, ) -> Result<(), ExitError> { - tracing::Event::RecordCost(cost).emit(); + tracing::Event::RecordCost { + cost, + snapshot: self.snapshot()?, + }.emit(); let all_gas_cost = self.total_used_gas() + cost; if self.gas_limit < all_gas_cost { @@ -134,7 +137,10 @@ impl<'config> Gasometer<'config> { &mut self, refund: i64, ) -> Result<(), ExitError> { - tracing::Event::RecordRefund(refund).emit(); + tracing::Event::RecordRefund { + refund, + snapshot: self.snapshot()?, + }.emit(); self.inner_mut()?.refunded_gas += refund; Ok(()) @@ -166,7 +172,12 @@ impl<'config> Gasometer<'config> { let gas_refund = self.inner_mut()?.gas_refund(cost); let used_gas = self.inner_mut()?.used_gas; - tracing::Event::RecordDynamicCost {gas_cost, memory_gas, gas_refund}.emit(); + tracing::Event::RecordDynamicCost { + gas_cost, + memory_gas, + gas_refund, + snapshot: self.snapshot()?, + }.emit(); let all_gas_cost = memory_gas + used_gas + gas_cost; if self.gas_limit < all_gas_cost { @@ -190,7 +201,10 @@ impl<'config> Gasometer<'config> { &mut self, stipend: u64, ) -> Result<(), ExitError> { - tracing::Event::RecordStipend(stipend).emit(); + tracing::Event::RecordStipend { + stipend, + snapshot: self.snapshot()?, + }.emit(); self.inner_mut()?.used_gas -= stipend; Ok(()) @@ -214,7 +228,10 @@ impl<'config> Gasometer<'config> { }, }; - tracing::Event::RecordTransaction(gas_cost).emit(); + tracing::Event::RecordTransaction { + cost: gas_cost, + snapshot: self.snapshot()?, + }.emit(); if self.gas() < gas_cost { self.inner = Err(ExitError::OutOfGas); @@ -224,6 +241,16 @@ impl<'config> Gasometer<'config> { self.inner_mut()?.used_gas += gas_cost; Ok(()) } + + fn snapshot(&self) -> Result { + let inner = self.inner.as_ref().map_err(|e| e.clone())?; + Ok(tracing::Snapshot { + gas_limit: self.gas_limit, + memory_gas: inner.memory_gas, + used_gas: inner.used_gas, + refunded_gas: inner.refunded_gas, + }) + } } /// Calculate the call transaction cost. diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs index f962c3af7..f60d5a587 100644 --- a/gasometer/src/tracing.rs +++ b/gasometer/src/tracing.rs @@ -11,17 +11,44 @@ pub trait EventListener { ); } +#[derive(Debug, Copy, Clone)] +pub struct Snapshot { + pub gas_limit: u64, + pub memory_gas: u64, + pub used_gas: u64, + pub refunded_gas: i64, +} + +impl Snapshot { + pub fn gas(&self) -> u64 { + self.gas_limit - self.used_gas - self.memory_gas + } +} + #[derive(Debug, Copy, Clone)] pub enum Event { - RecordCost(u64), - RecordRefund(i64), - RecordStipend(u64), + RecordCost { + cost: u64, + snapshot: Snapshot, + }, + RecordRefund { + refund: i64, + snapshot: Snapshot, + }, + RecordStipend { + stipend: u64, + snapshot: Snapshot, + }, RecordDynamicCost { gas_cost: u64, memory_gas: u64, gas_refund: i64, + snapshot: Snapshot, + }, + RecordTransaction { + cost: u64, + snapshot: Snapshot, }, - RecordTransaction(u64), } impl Event { From e1ac47c516f2f63df5629ee461cf24d59f73a9d3 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Tue, 18 May 2021 11:23:37 +0000 Subject: [PATCH 09/15] add create address + suicide event --- src/executor/stack/mod.rs | 12 ++++++++++-- src/tracing.rs | 8 +++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/executor/stack/mod.rs b/src/executor/stack/mod.rs index 8c5b51c17..658843c7f 100644 --- a/src/executor/stack/mod.rs +++ b/src/executor/stack/mod.rs @@ -328,8 +328,11 @@ impl<'config, S: StackState<'config>> StackExecutor<'config, S> { gas - gas / 64 } + let address = self.create_address(scheme); + tracing::Event::Create { caller, + address, scheme, value, init_code: &init_code, @@ -366,7 +369,6 @@ impl<'config, S: StackState<'config>> StackExecutor<'config, S> { self.state.metadata_mut().gasometer.record_cost(gas_limit) ); - let address = self.create_address(scheme); self.state.inc_nonce(caller); self.enter_substate(gas_limit, false); @@ -659,9 +661,15 @@ impl<'config, S: StackState<'config>> Handler for StackExecutor<'config, S> { fn mark_delete(&mut self, address: H160, target: H160) -> Result<(), ExitError> { let balance = self.balance(address); + tracing::Event::Suicide { + target, + address, + balance, + }.emit(); + self.state.transfer(Transfer { source: address, - target: target, + target, value: balance, })?; self.state.reset_balance(address); diff --git a/src/tracing.rs b/src/tracing.rs index 9954f0f53..431d121b5 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -27,11 +27,17 @@ pub enum Event<'a> { }, Create { caller: H160, + address: H160, scheme: CreateScheme, value: U256, init_code: &'a [u8], target_gas: Option, - } + }, + Suicide { + address: H160, + target: H160, + balance: U256, + }, } impl<'a> Event<'a> { From 5dfb3bdaad8bff2e1242bb7a4a47a17fef30b095 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Wed, 19 May 2021 09:47:26 +0000 Subject: [PATCH 10/15] runtime: use macro --- runtime/src/eval/system.rs | 10 +++++----- runtime/src/lib.rs | 28 +++++++++++++++++++++------- runtime/src/tracing.rs | 9 --------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/runtime/src/eval/system.rs b/runtime/src/eval/system.rs index e02b8e0c4..ef5b5f7d4 100644 --- a/runtime/src/eval/system.rs +++ b/runtime/src/eval/system.rs @@ -2,7 +2,7 @@ use core::cmp::min; use alloc::vec::Vec; use primitive_types::{H256, U256}; use sha3::{Keccak256, Digest}; -use crate::{tracing, Runtime, ExitError, Handler, Capture, Transfer, ExitReason, +use crate::{Runtime, ExitError, Handler, Capture, Transfer, ExitReason, CreateScheme, CallScheme, Context, ExitSucceed, ExitFatal}; use super::Control; @@ -174,11 +174,11 @@ pub fn sload(runtime: &mut Runtime, handler: &H) -> Control { let value = handler.storage(runtime.context.address, index); push!(runtime, value); - tracing::Event::SLoad { + event!(SLoad { address: runtime.context.address, index, value - }.emit(); + }); Control::Continue } @@ -186,11 +186,11 @@ pub fn sload(runtime: &mut Runtime, handler: &H) -> Control { pub fn sstore(runtime: &mut Runtime, handler: &mut H) -> Control { pop!(runtime, index, value); - tracing::Event::SStore { + event!(SStore { address: runtime.context.address, index, value - }.emit(); + }); match handler.set_storage(runtime.context.address, index, value) { Ok(()) => Control::Continue, diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index edc7ce25d..6e5a2172e 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -7,11 +7,26 @@ extern crate alloc; +#[cfg(feature = "tracing")] +pub mod tracing; + +#[cfg(feature = "tracing")] +macro_rules! event { + ($x:expr) => { + use tracing::Event::*; + $x.emit(); + } +} + +#[cfg(not(feature = "tracing"))] +macro_rules! event { + ($x:expr) => { } +} + mod eval; mod context; mod interrupt; mod handler; -pub mod tracing; pub use evm_core::*; @@ -25,13 +40,13 @@ use alloc::rc::Rc; macro_rules! step { ( $self:expr, $handler:expr, $return:tt $($err:path)?; $($ok:path)? ) => ({ if let Some((opcode, stack)) = $self.machine.inspect() { - tracing::Event::Step { + event!(Step { context: &$self.context, opcode, position: $self.machine.position(), stack, memory: $self.machine.memory() - }.emit(); + }); match $handler.pre_validate(&$self.context, opcode, stack) { Ok(()) => (), @@ -51,12 +66,11 @@ macro_rules! step { } let result = $self.machine.step(); - let return_value = $self.machine.return_value(); - tracing::Event::StepResult { + event!(StepResult { result: &result, - return_value: &return_value, - }.emit(); + return_value: &$self.machine.return_value(), + }); match result { Ok(()) => $($ok)?(()), diff --git a/runtime/src/tracing.rs b/runtime/src/tracing.rs index 623374c39..d83523ecd 100644 --- a/runtime/src/tracing.rs +++ b/runtime/src/tracing.rs @@ -3,10 +3,8 @@ use crate::{Context, Opcode, Stack, Memory, Capture, ExitReason, Trap}; use primitive_types::{H160, H256}; -#[cfg(feature = "tracing")] environmental::environmental!(listener: dyn EventListener + 'static); -#[cfg(feature = "tracing")] pub trait EventListener { fn event( &mut self, @@ -40,19 +38,12 @@ pub enum Event<'a> { } impl<'a> Event<'a> { - #[cfg(feature = "tracing")] pub(crate) fn emit(self) { listener::with(|listener| listener.event(self)); } - - #[cfg(not(feature = "tracing"))] - pub(crate) fn emit(self) { - // no op. - } } /// Run closure with provided listener. -#[cfg(feature = "tracing")] pub fn using R>( new: &mut (dyn EventListener + 'static), f: F From e3695a1c8ff6443ede36c4f3bfe80b9c7fb0ed22 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Wed, 19 May 2021 11:21:53 +0000 Subject: [PATCH 11/15] update all events to macros --- gasometer/src/lib.rs | 49 ++++++++++++++++++++++++++++----------- gasometer/src/tracing.rs | 19 ++------------- runtime/src/lib.rs | 2 +- src/executor/stack/mod.rs | 14 +++++------ src/lib.rs | 17 +++++++++++++- src/tracing.rs | 9 ------- 6 files changed, 62 insertions(+), 48 deletions(-) diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 4ba271f1e..328711939 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -5,11 +5,26 @@ #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(feature = "tracing")] +pub mod tracing; + +#[cfg(feature = "tracing")] +macro_rules! event { + ($x:expr) => { + use crate::tracing::Event::*; + $x.emit(); + } +} + +#[cfg(not(feature = "tracing"))] +macro_rules! event { + ($x:expr) => { } +} + mod consts; mod costs; mod memory; mod utils; -pub mod tracing; use core::cmp::max; use primitive_types::{H160, H256, U256}; @@ -28,6 +43,14 @@ macro_rules! try_or_fail { ) } +#[derive(Debug, Copy, Clone)] +pub struct Snapshot { + pub gas_limit: u64, + pub memory_gas: u64, + pub used_gas: u64, + pub refunded_gas: i64, +} + /// EVM gasometer. #[derive(Clone)] pub struct Gasometer<'config> { @@ -116,10 +139,10 @@ impl<'config> Gasometer<'config> { &mut self, cost: u64, ) -> Result<(), ExitError> { - tracing::Event::RecordCost { + event!(RecordCost { cost, snapshot: self.snapshot()?, - }.emit(); + }); let all_gas_cost = self.total_used_gas() + cost; if self.gas_limit < all_gas_cost { @@ -137,10 +160,10 @@ impl<'config> Gasometer<'config> { &mut self, refund: i64, ) -> Result<(), ExitError> { - tracing::Event::RecordRefund { + event!(RecordRefund { refund, snapshot: self.snapshot()?, - }.emit(); + }); self.inner_mut()?.refunded_gas += refund; Ok(()) @@ -172,12 +195,12 @@ impl<'config> Gasometer<'config> { let gas_refund = self.inner_mut()?.gas_refund(cost); let used_gas = self.inner_mut()?.used_gas; - tracing::Event::RecordDynamicCost { + event!(RecordDynamicCost { gas_cost, memory_gas, gas_refund, snapshot: self.snapshot()?, - }.emit(); + }); let all_gas_cost = memory_gas + used_gas + gas_cost; if self.gas_limit < all_gas_cost { @@ -201,10 +224,10 @@ impl<'config> Gasometer<'config> { &mut self, stipend: u64, ) -> Result<(), ExitError> { - tracing::Event::RecordStipend { + event!(RecordStipend { stipend, snapshot: self.snapshot()?, - }.emit(); + }); self.inner_mut()?.used_gas -= stipend; Ok(()) @@ -228,10 +251,10 @@ impl<'config> Gasometer<'config> { }, }; - tracing::Event::RecordTransaction { + event!(RecordTransaction { cost: gas_cost, snapshot: self.snapshot()?, - }.emit(); + }); if self.gas() < gas_cost { self.inner = Err(ExitError::OutOfGas); @@ -242,9 +265,9 @@ impl<'config> Gasometer<'config> { Ok(()) } - fn snapshot(&self) -> Result { + pub fn snapshot(&self) -> Result { let inner = self.inner.as_ref().map_err(|e| e.clone())?; - Ok(tracing::Snapshot { + Ok(Snapshot { gas_limit: self.gas_limit, memory_gas: inner.memory_gas, used_gas: inner.used_gas, diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs index f60d5a587..480f03998 100644 --- a/gasometer/src/tracing.rs +++ b/gasometer/src/tracing.rs @@ -1,9 +1,9 @@ //! Allows to listen to gasometer events. -#[cfg(feature = "tracing")] +use super::Snapshot; + environmental::environmental!(listener: dyn EventListener + 'static); -#[cfg(feature = "tracing")] pub trait EventListener { fn event( &mut self, @@ -11,14 +11,6 @@ pub trait EventListener { ); } -#[derive(Debug, Copy, Clone)] -pub struct Snapshot { - pub gas_limit: u64, - pub memory_gas: u64, - pub used_gas: u64, - pub refunded_gas: i64, -} - impl Snapshot { pub fn gas(&self) -> u64 { self.gas_limit - self.used_gas - self.memory_gas @@ -52,19 +44,12 @@ pub enum Event { } impl Event { - #[cfg(feature = "tracing")] pub(crate) fn emit(self) { listener::with(|listener| listener.event(self)); } - - #[cfg(not(feature = "tracing"))] - pub(crate) fn emit(self) { - // no op. - } } /// Run closure with provided listener. -#[cfg(feature = "tracing")] pub fn using R>( new: &mut (dyn EventListener + 'static), f: F diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 6e5a2172e..b23d2c2d7 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -13,7 +13,7 @@ pub mod tracing; #[cfg(feature = "tracing")] macro_rules! event { ($x:expr) => { - use tracing::Event::*; + use crate::tracing::Event::*; $x.emit(); } } diff --git a/src/executor/stack/mod.rs b/src/executor/stack/mod.rs index 6bb99269d..280237429 100644 --- a/src/executor/stack/mod.rs +++ b/src/executor/stack/mod.rs @@ -7,7 +7,7 @@ use alloc::{rc::Rc, vec::Vec}; use primitive_types::{U256, H256, H160}; use sha3::{Keccak256, Digest}; use crate::{ExitError, Stack, Opcode, Capture, Handler, Transfer, - Context, CreateScheme, Runtime, ExitReason, ExitSucceed, Config, tracing}; + Context, CreateScheme, Runtime, ExitReason, ExitSucceed, Config}; use ethereum::Log; use crate::gasometer::{self, Gasometer}; @@ -338,14 +338,14 @@ impl<'config, S: StackState<'config>> StackExecutor<'config, S> { let address = self.create_address(scheme); - tracing::Event::Create { + event!(Create { caller, address, scheme, value, init_code: &init_code, target_gas - }.emit(); + }); if let Some(depth) = self.state.metadata().depth { if depth > self.config.call_stack_limit { @@ -493,14 +493,14 @@ impl<'config, S: StackState<'config>> StackExecutor<'config, S> { gas - gas / 64 } - tracing::Event::Call { + event!(Call { code_address, transfer: &transfer, input: &input, target_gas, is_static, context: &context, - }.emit(); + }); let after_gas = if take_l64 && self.config.call_l64_after_gas { if self.config.estimate { @@ -678,11 +678,11 @@ impl<'config, S: StackState<'config>> Handler for StackExecutor<'config, S> { fn mark_delete(&mut self, address: H160, target: H160) -> Result<(), ExitError> { let balance = self.balance(address); - tracing::Event::Suicide { + event!(Suicide { target, address, balance, - }.emit(); + }); self.state.transfer(Transfer { source: address, diff --git a/src/lib.rs b/src/lib.rs index 9ff0c83ad..395040a08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,21 @@ pub use evm_core::*; pub use evm_runtime::*; pub use evm_gasometer as gasometer; +#[cfg(feature = "tracing")] +pub mod tracing; + +#[cfg(feature = "tracing")] +macro_rules! event { + ($x:expr) => { + use crate::tracing::Event::*; + $x.emit(); + } +} + +#[cfg(not(feature = "tracing"))] +macro_rules! event { + ($x:expr) => { } +} + pub mod executor; pub mod backend; -pub mod tracing; diff --git a/src/tracing.rs b/src/tracing.rs index 431d121b5..dcb083a6f 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -4,10 +4,8 @@ use crate::{Context}; use evm_runtime::{CreateScheme, Transfer}; use primitive_types::{H160, U256}; -#[cfg(feature = "tracing")] environmental::environmental!(listener: dyn EventListener + 'static); -#[cfg(feature = "tracing")] pub trait EventListener { fn event( &mut self, @@ -41,19 +39,12 @@ pub enum Event<'a> { } impl<'a> Event<'a> { - #[cfg(feature = "tracing")] pub(crate) fn emit(self) { listener::with(|listener| listener.event(self)); } - - #[cfg(not(feature = "tracing"))] - pub(crate) fn emit(self) { - // no op. - } } /// Run closure with provided listener. -#[cfg(feature = "tracing")] pub fn using R>( new: &mut (dyn EventListener + 'static), f: F From 29b1d27f3ac6cba30b021f9a2e4c7cfefede604b Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Fri, 21 May 2021 10:39:47 +0000 Subject: [PATCH 12/15] editorconfig --- gasometer/src/lib.rs | 6 +++--- gasometer/src/tracing.rs | 2 +- runtime/src/lib.rs | 2 +- runtime/src/tracing.rs | 2 +- src/tracing.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 328711939..3cf608470 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -161,7 +161,7 @@ impl<'config> Gasometer<'config> { refund: i64, ) -> Result<(), ExitError> { event!(RecordRefund { - refund, + refund, snapshot: self.snapshot()?, }); @@ -198,7 +198,7 @@ impl<'config> Gasometer<'config> { event!(RecordDynamicCost { gas_cost, memory_gas, - gas_refund, + gas_refund, snapshot: self.snapshot()?, }); @@ -259,7 +259,7 @@ impl<'config> Gasometer<'config> { if self.gas() < gas_cost { self.inner = Err(ExitError::OutOfGas); return Err(ExitError::OutOfGas); - } + } self.inner_mut()?.used_gas += gas_cost; Ok(()) diff --git a/gasometer/src/tracing.rs b/gasometer/src/tracing.rs index 480f03998..c8901ccd8 100644 --- a/gasometer/src/tracing.rs +++ b/gasometer/src/tracing.rs @@ -55,4 +55,4 @@ pub fn using R>( f: F ) -> R { listener::using(new, f) -} \ No newline at end of file +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index b23d2c2d7..09e355f29 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -47,7 +47,7 @@ macro_rules! step { stack, memory: $self.machine.memory() }); - + match $handler.pre_validate(&$self.context, opcode, stack) { Ok(()) => (), Err(e) => { diff --git a/runtime/src/tracing.rs b/runtime/src/tracing.rs index d83523ecd..14252ece3 100644 --- a/runtime/src/tracing.rs +++ b/runtime/src/tracing.rs @@ -49,4 +49,4 @@ pub fn using R>( f: F ) -> R { listener::using(new, f) -} \ No newline at end of file +} diff --git a/src/tracing.rs b/src/tracing.rs index dcb083a6f..a33982ddf 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -50,4 +50,4 @@ pub fn using R>( f: F ) -> R { listener::using(new, f) -} \ No newline at end of file +} From d248b177d55ff051f2061816e8feb56963b71c16 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Fri, 21 May 2021 10:41:46 +0000 Subject: [PATCH 13/15] fmt --- src/tracing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tracing.rs b/src/tracing.rs index a33982ddf..039fce91c 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -1,6 +1,6 @@ //! Allows to listen to runtime events. -use crate::{Context}; +use crate::Context; use evm_runtime::{CreateScheme, Transfer}; use primitive_types::{H160, U256}; From fbc7e8614a5bf226704d9e4a972e3c48ecb6be93 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Mon, 24 May 2021 11:31:10 +0000 Subject: [PATCH 14/15] fmt --- gasometer/Cargo.toml | 4 ++-- gasometer/src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gasometer/Cargo.toml b/gasometer/Cargo.toml index c3b7c1604..0a5c015f3 100644 --- a/gasometer/Cargo.toml +++ b/gasometer/Cargo.toml @@ -12,7 +12,7 @@ edition = "2018" primitive-types = { version = "0.9", default-features = false } evm-core = { version = "0.26", path = "../core", default-features = false } evm-runtime = { version = "0.26", path = "../runtime", default-features = false } -environmental = { version = "1.1.2", default-features = false, optional = true} +environmental = { version = "1.1.2", default-features = false, optional = true } [features] default = ["std"] @@ -24,4 +24,4 @@ std = [ ] tracing = [ "environmental" -] \ No newline at end of file +] diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 3cf608470..790852055 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -45,8 +45,8 @@ macro_rules! try_or_fail { #[derive(Debug, Copy, Clone)] pub struct Snapshot { - pub gas_limit: u64, - pub memory_gas: u64, + pub gas_limit: u64, + pub memory_gas: u64, pub used_gas: u64, pub refunded_gas: i64, } From 3e374474f4860a32d3ec61e58caf954d14d6e4f1 Mon Sep 17 00:00:00 2001 From: nanocryk <6422796+nanocryk@users.noreply.github.com> Date: Wed, 26 May 2021 16:09:00 +0000 Subject: [PATCH 15/15] Update Cargo.toml Co-authored-by: Wei Tang --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 788c7009e..eff67b880 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ primitive-types = { version = "0.9", default-features = false, features = ["rlp" serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } codec = { package = "parity-scale-codec", version = "2.0", default-features = false, features = ["derive"], optional = true } ethereum = { version = "0.7", default-features = false } -environmental = { version = "1.1.2", default-features = false, optional = true} +environmental = { version = "1.1.2", default-features = false, optional = true } [dev-dependencies] criterion = "0.3"