Skip to content

Commit

Permalink
trace logs and storage (#2740)
Browse files Browse the repository at this point in the history
  • Loading branch information
ermalkaleci authored Apr 17, 2024
1 parent 8f4485b commit 3fd4ab0
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 74 deletions.
50 changes: 50 additions & 0 deletions modules/evm-bridge/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,15 @@ fn tracing_should_work() {
"error": null,
"revertReason": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002645524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63650000000000000000000000000000000000000000000000000000",
"depth": 0,
"logs": [
{
"sLoad": {
"address": "0x5dddfce53ee040d9eb21afbc0ae1bb4dbb0ba643",
"index": "0xfb750de6f7d0583f749efc558ce6626b24fed04efd7219dc3f4294c408699e8c",
"value": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
}
],
"calls": []
}
]"#;
Expand Down Expand Up @@ -424,6 +433,47 @@ fn tracing_should_work() {
"error": null,
"revertReason": null,
"depth": 0,
"logs": [
{
"sLoad": {
"address": "0x5dddfce53ee040d9eb21afbc0ae1bb4dbb0ba643",
"index": "0xe6f18b3f6d2cdeb50fb82c61f7a7a249abf7b534575880ddcfde84bba07ce81d",
"value": "0x00000000000000000000000000000000000000000000152d02c7e14af6800000"
}
},
{
"sStore": {
"address": "0x5dddfce53ee040d9eb21afbc0ae1bb4dbb0ba643",
"index": "0xe6f18b3f6d2cdeb50fb82c61f7a7a249abf7b534575880ddcfde84bba07ce81d",
"value": "0x00000000000000000000000000000000000000000000152d02c7e14af67fff9c"
}
},
{
"sLoad": {
"address": "0x5dddfce53ee040d9eb21afbc0ae1bb4dbb0ba643",
"index": "0xfb750de6f7d0583f749efc558ce6626b24fed04efd7219dc3f4294c408699e8c",
"value": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
{
"sStore": {
"address": "0x5dddfce53ee040d9eb21afbc0ae1bb4dbb0ba643",
"index": "0xfb750de6f7d0583f749efc558ce6626b24fed04efd7219dc3f4294c408699e8c",
"value": "0x0000000000000000000000000000000000000000000000000000000000000064"
}
},
{
"log": {
"address": "0x5dddfce53ee040d9eb21afbc0ae1bb4dbb0ba643",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000001000000000000000000000000000000000000001",
"0x0000000000000000000000001000000000000000000000000000000000000002"
],
"data": "0x0000000000000000000000000000000000000000000000000000000000000064"
}
}
],
"calls": []
}
]"#;
Expand Down
5 changes: 5 additions & 0 deletions modules/evm/src/runner/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,11 @@ impl<'config, 'precompiles, S: StackState<'config>, P: PrecompileSet> Handler
}

fn log(&mut self, address: H160, topics: Vec<H256>, data: Vec<u8>) -> Result<(), ExitError> {
event!(Log {
address,
topics: &topics,
data: &data,
});
self.state.log(address, topics, data);
Ok(())
}
Expand Down
136 changes: 65 additions & 71 deletions modules/evm/src/runner/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use module_evm_utility::{
use sp_core::{H160, H256, U256};
use sp_std::prelude::*;

pub use primitives::evm::tracing::{CallTrace, CallType, OpcodeConfig, Step, TraceOutcome, TracerConfig};
pub use primitives::evm::tracing::{CallTrace, CallType, LogTrace, OpcodeConfig, Step, TraceOutcome, TracerConfig};

#[derive(Debug, Copy, Clone)]
pub enum Event<'a> {
Expand Down Expand Up @@ -84,6 +84,11 @@ pub enum Event<'a> {
Enter {
depth: u32,
},
Log {
address: H160,
topics: &'a Vec<H256>,
data: &'a Vec<u8>,
},
}

pub struct Tracer {
Expand Down Expand Up @@ -220,7 +225,20 @@ impl Tracer {
step.gas = self.gas;
}
}
_ => {}
evm_runtime::tracing::Event::SLoad { address, index, value } => {
if !self.trace_call() {
return;
}
let trace = self.stack.last_mut().expect("missing call trace");
trace.logs.push(LogTrace::SLoad { address, index, value });
}
evm_runtime::tracing::Event::SStore { address, index, value } => {
if !self.trace_call() {
return;
}
let trace = self.stack.last_mut().expect("missing call trace");
trace.logs.push(LogTrace::SStore { address, index, value });
}
};
}

Expand Down Expand Up @@ -263,12 +281,7 @@ impl Tracer {
input: input.to_vec(),
value: transfer.as_ref().map_or(U256::zero(), |x| x.value),
gas: target_gas.unwrap_or(self.gas),
gas_used: 0,
output: None,
error: None,
revert_reason: None,
calls: Vec::new(),
depth: 0,
..Default::default()
});
}
Event::TransactCall {
Expand All @@ -285,12 +298,7 @@ impl Tracer {
input: data.to_vec(),
value,
gas: gas_limit,
gas_used: 0,
output: None,
error: None,
revert_reason: None,
calls: Vec::new(),
depth: 0,
..Default::default()
});
}
Event::Create {
Expand All @@ -307,12 +315,7 @@ impl Tracer {
input: init_code.to_vec(),
value,
gas: target_gas.unwrap_or(self.gas),
gas_used: 0,
output: None,
error: None,
revert_reason: None,
calls: Vec::new(),
depth: 0,
..Default::default()
});
}
Event::TransactCreate {
Expand All @@ -337,75 +340,66 @@ impl Tracer {
input: init_code.to_vec(),
value,
gas: gas_limit,
gas_used: 0,
output: None,
error: None,
revert_reason: None,
calls: Vec::new(),
depth: 0,
..Default::default()
});
}
Event::Suicide {
address,
target,
balance,
} => {
if let Some(trace) = self.stack.last_mut() {
trace.calls.push(CallTrace {
call_type: CallType::SUICIDE,
from: address,
to: target,
input: vec![],
value: balance,
gas: 0,
gas_used: 0,
output: None,
error: None,
revert_reason: None,
calls: Vec::new(),
depth: 0,
});
}
let trace = self.stack.last_mut().expect("missing call trace");
trace.calls.push(CallTrace {
call_type: CallType::SUICIDE,
from: address,
to: target,
value: balance,
..Default::default()
});
}
Event::Exit { reason, return_value } => {
if let Some(mut trace) = self.stack.pop() {
match reason {
ExitReason::Succeed(ExitSucceed::Returned) => {
if !return_value.is_empty() {
trace.output = Some(return_value.to_vec());
}
let mut trace = self.stack.pop().expect("missing call trace");
match reason {
ExitReason::Succeed(ExitSucceed::Returned) => {
if !return_value.is_empty() {
trace.output = Some(return_value.to_vec());
}
ExitReason::Succeed(_) => {}
ExitReason::Error(e) => trace.error = Some(e.stringify().as_bytes().to_vec()),
ExitReason::Revert(_) => {
if !return_value.is_empty() {
trace.revert_reason = Some(return_value.to_vec());
}
}
ExitReason::Succeed(_) => {}
ExitReason::Error(e) => trace.error = Some(e.stringify().as_bytes().to_vec()),
ExitReason::Revert(_) => {
if !return_value.is_empty() {
trace.revert_reason = Some(return_value.to_vec());
}
ExitReason::Fatal(e) => trace.error = Some(e.stringify().as_bytes().to_vec()),
}
ExitReason::Fatal(e) => trace.error = Some(e.stringify().as_bytes().to_vec()),
}

trace.gas_used = trace.gas.saturating_sub(self.gas);
trace.gas_used = trace.gas.saturating_sub(self.gas);

if let Some(index) = self.calls.iter().position(|x| x.depth > trace.depth) {
let mut subcalls = self.calls.drain(index..).collect::<Vec<_>>();
if matches!(reason, ExitReason::Succeed(ExitSucceed::Suicided)) {
let mut suicide_call = trace.calls.pop().expect("suicide call should be injected");
suicide_call.depth = trace.depth + 1;
subcalls.push(suicide_call);
}
trace.calls = subcalls;
if let Some(index) = self.calls.iter().position(|x| x.depth > trace.depth) {
let mut subcalls = self.calls.drain(index..).collect::<Vec<_>>();
if matches!(reason, ExitReason::Succeed(ExitSucceed::Suicided)) {
let mut suicide_call = trace.calls.pop().expect("suicide call should be injected");
suicide_call.depth = trace.depth + 1;
subcalls.push(suicide_call);
}

self.calls.push(trace);
} else {
panic!("exit event without call event")
trace.calls = subcalls;
}

self.calls.push(trace);
}
Event::Enter { depth } => {
if let Some(event) = self.stack.last_mut() {
event.depth = depth;
}
let trace = self.stack.last_mut().expect("missing call trace");
trace.depth = depth;
}
Event::Log { address, topics, data } => {
let trace = self.stack.last_mut().expect("missing call trace");
trace.logs.push(LogTrace::Log {
address,
topics: topics.clone(),
data: data.clone(),
});
}
}
}
Expand Down
35 changes: 35 additions & 0 deletions modules/evm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3039,6 +3039,22 @@ fn tracer_works() {
"error": null,
"revertReason": null,
"depth": 0,
"logs": [
{
"sLoad": {
"address": "0x5f8bd49cd9f0cb2bd5bb9d4320dfe9b61023249d",
"index": "0x0000000000000000000000000000000000000000000000000000000000000000",
"value": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
},
{
"sStore": {
"address": "0x5f8bd49cd9f0cb2bd5bb9d4320dfe9b61023249d",
"index": "0x0000000000000000000000000000000000000000000000000000000000000000",
"value": "0x0000000000000000000000007b8f8ca099f6e33cf1817cf67d0556429cfc54e4"
}
}
],
"calls": [
{
"type": "CREATE",
Expand All @@ -3052,6 +3068,7 @@ fn tracer_works() {
"error": null,
"revertReason": null,
"depth": 1,
"logs": [],
"calls": []
}
]
Expand Down Expand Up @@ -3096,6 +3113,15 @@ fn tracer_works() {
"error": null,
"revertReason": null,
"depth": 0,
"logs": [
{
"sLoad": {
"address": "0x5f8bd49cd9f0cb2bd5bb9d4320dfe9b61023249d",
"index": "0x0000000000000000000000000000000000000000000000000000000000000000",
"value": "0x0000000000000000000000007b8f8ca099f6e33cf1817cf67d0556429cfc54e4"
}
}
],
"calls": [
{
"type": "CALL",
Expand All @@ -3109,6 +3135,15 @@ fn tracer_works() {
"error": null,
"revertReason": null,
"depth": 1,
"logs": [
{
"sStore": {
"address": "0x7b8f8ca099f6e33cf1817cf67d0556429cfc54e4",
"index": "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5",
"value": "0x0000000000000000000000000000000000000000000000000000000000000001"
}
}
],
"calls": []
}
]
Expand Down
Loading

0 comments on commit 3fd4ab0

Please sign in to comment.