diff --git a/modules/evm/src/runner/tracing.rs b/modules/evm/src/runner/tracing.rs index 08f134a483..9a4f2d3b7c 100644 --- a/modules/evm/src/runner/tracing.rs +++ b/modules/evm/src/runner/tracing.rs @@ -88,6 +88,7 @@ pub enum Event<'a> { } pub struct Tracer { + vm: bool, events: Vec, stack: Vec, steps: Vec, @@ -96,8 +97,9 @@ pub struct Tracer { } impl Tracer { - pub fn new() -> Self { + pub fn new(vm: bool) -> Self { Self { + vm, events: Vec::new(), stack: Vec::new(), steps: Vec::new(), @@ -135,16 +137,24 @@ impl Tracer { memory, } => { self.opcode = Some(opcode); + if !self.vm { + return; + } self.steps.push(Step { - op: opcode.stringify().as_bytes().to_vec(), - pc: position.clone().unwrap_or_default() as u64, - depth: self.stack.last().map(|x| x.depth).unwrap_or_default(), - gas: if let Some(snapshot) = self.snapshot { - snapshot.gas() - } else { - 0 - }, - stack: stack.data().clone(), + op: opcode, + pc: position.as_ref().map_or(0, |pc| *pc as u32), + depth: self.stack.last().map_or(0, |x| x.depth), + gas: self.snapshot.map_or(0, |s| s.gas()), + stack: stack + .data() + .iter() + .map(|x| { + let slice = x.as_fixed_bytes(); + // trim left zeros + let start = slice.iter().position(|x| *x != 0).unwrap_or(31); + slice[start..].to_vec() + }) + .collect(), memory: if memory.is_empty() { None } else { @@ -373,157 +383,6 @@ trait Stringify { fn stringify(&self) -> &str; } -impl Stringify for Opcode { - fn stringify(&self) -> &str { - match self { - &Opcode::STOP => "STOP", - &Opcode::ADD => "ADD", - &Opcode::MUL => "MUL", - &Opcode::SUB => "SUB", - &Opcode::DIV => "DIV", - &Opcode::SDIV => "SDIV", - &Opcode::MOD => "MOD", - &Opcode::SMOD => "SMOD", - &Opcode::ADDMOD => "ADDMOD", - &Opcode::MULMOD => "MULMOD", - &Opcode::EXP => "EXP", - &Opcode::SIGNEXTEND => "SIGNEXTEND", - &Opcode::LT => "LT", - &Opcode::GT => "GT", - &Opcode::SLT => "SLT", - &Opcode::SGT => "SGT", - &Opcode::EQ => "EQ", - &Opcode::ISZERO => "ISZERO", - &Opcode::AND => "AND", - &Opcode::OR => "OR", - &Opcode::XOR => "XOR", - &Opcode::NOT => "NOT", - &Opcode::BYTE => "BYTE", - &Opcode::SHL => "SHL", - &Opcode::SHR => "SHR", - &Opcode::SAR => "SAR", - &Opcode::SHA3 => "SHA3", - &Opcode::ADDRESS => "ADDRESS", - &Opcode::BALANCE => "BALANCE", - &Opcode::ORIGIN => "ORIGIN", - &Opcode::CALLER => "CALLER", - &Opcode::CALLVALUE => "CALLVALUE", - &Opcode::CALLDATALOAD => "CALLDATALOAD", - &Opcode::CALLDATASIZE => "CALLDATASIZE", - &Opcode::CALLDATACOPY => "CALLDATACOPY", - &Opcode::CODESIZE => "CODESIZE", - &Opcode::CODECOPY => "CODECOPY", - &Opcode::GASPRICE => "GASPRICE", - &Opcode::EXTCODESIZE => "EXTCODESIZE", - &Opcode::EXTCODECOPY => "EXTCODECOPY", - &Opcode::RETURNDATASIZE => "RETURNDATASIZE", - &Opcode::RETURNDATACOPY => "RETURNDATACOPY", - &Opcode::EXTCODEHASH => "EXTCODEHASH", - &Opcode::BLOCKHASH => "BLOCKHASH", - &Opcode::COINBASE => "COINBASE", - &Opcode::TIMESTAMP => "TIMESTAMP", - &Opcode::NUMBER => "NUMBER", - &Opcode::DIFFICULTY => "DIFFICULTY", - &Opcode::GASLIMIT => "GASLIMIT", - &Opcode::CHAINID => "CHAINID", - &Opcode::SELFBALANCE => "SELFBALANCE", - &Opcode::POP => "POP", - &Opcode::MLOAD => "MLOAD", - &Opcode::MSTORE => "MSTORE", - &Opcode::MSTORE8 => "MSTORE8", - &Opcode::SLOAD => "SLOAD", - &Opcode::SSTORE => "SSTORE", - &Opcode::JUMP => "JUMP", - &Opcode::JUMPI => "JUMPI", - &Opcode::PC => "PC", - &Opcode::MSIZE => "MSIZE", - &Opcode::GAS => "GAS", - &Opcode::JUMPDEST => "JUMPDEST", - &Opcode::PUSH1 => "PUSH1", - &Opcode::PUSH2 => "PUSH2", - &Opcode::PUSH3 => "PUSH3", - &Opcode::PUSH4 => "PUSH4", - &Opcode::PUSH5 => "PUSH5", - &Opcode::PUSH6 => "PUSH6", - &Opcode::PUSH7 => "PUSH7", - &Opcode::PUSH8 => "PUSH8", - &Opcode::PUSH9 => "PUSH9", - &Opcode::PUSH10 => "PUSH10", - &Opcode::PUSH11 => "PUSH11", - &Opcode::PUSH12 => "PUSH12", - &Opcode::PUSH13 => "PUSH13", - &Opcode::PUSH14 => "PUSH14", - &Opcode::PUSH15 => "PUSH15", - &Opcode::PUSH16 => "PUSH16", - &Opcode::PUSH17 => "PUSH17", - &Opcode::PUSH18 => "PUSH18", - &Opcode::PUSH19 => "PUSH19", - &Opcode::PUSH20 => "PUSH20", - &Opcode::PUSH21 => "PUSH21", - &Opcode::PUSH22 => "PUSH22", - &Opcode::PUSH23 => "PUSH23", - &Opcode::PUSH24 => "PUSH24", - &Opcode::PUSH25 => "PUSH25", - &Opcode::PUSH26 => "PUSH26", - &Opcode::PUSH27 => "PUSH27", - &Opcode::PUSH28 => "PUSH28", - &Opcode::PUSH29 => "PUSH29", - &Opcode::PUSH30 => "PUSH30", - &Opcode::PUSH31 => "PUSH31", - &Opcode::PUSH32 => "PUSH32", - &Opcode::DUP1 => "DUP1", - &Opcode::DUP2 => "DUP2", - &Opcode::DUP3 => "DUP3", - &Opcode::DUP4 => "DUP4", - &Opcode::DUP5 => "DUP5", - &Opcode::DUP6 => "DUP6", - &Opcode::DUP7 => "DUP7", - &Opcode::DUP8 => "DUP8", - &Opcode::DUP9 => "DUP9", - &Opcode::DUP10 => "DUP10", - &Opcode::DUP11 => "DUP11", - &Opcode::DUP12 => "DUP12", - &Opcode::DUP13 => "DUP13", - &Opcode::DUP14 => "DUP14", - &Opcode::DUP15 => "DUP15", - &Opcode::DUP16 => "DUP16", - &Opcode::SWAP1 => "SWAP1", - &Opcode::SWAP2 => "SWAP2", - &Opcode::SWAP3 => "SWAP3", - &Opcode::SWAP4 => "SWAP4", - &Opcode::SWAP5 => "SWAP5", - &Opcode::SWAP6 => "SWAP6", - &Opcode::SWAP7 => "SWAP7", - &Opcode::SWAP8 => "SWAP8", - &Opcode::SWAP9 => "SWAP9", - &Opcode::SWAP10 => "SWAP10", - &Opcode::SWAP11 => "SWAP11", - &Opcode::SWAP12 => "SWAP12", - &Opcode::SWAP13 => "SWAP13", - &Opcode::SWAP14 => "SWAP14", - &Opcode::SWAP15 => "SWAP15", - &Opcode::SWAP16 => "SWAP16", - &Opcode::LOG0 => "LOG0", - &Opcode::LOG1 => "LOG1", - &Opcode::LOG2 => "LOG2", - &Opcode::LOG3 => "LOG3", - &Opcode::LOG4 => "LOG4", - &Opcode::CREATE => "CREATE", - &Opcode::CALL => "CALL", - &Opcode::CALLCODE => "CALLCODE", - &Opcode::RETURN => "RETURN", - &Opcode::DELEGATECALL => "DELEGATECALL", - &Opcode::STATICCALL => "STATICCALL", - &Opcode::REVERT => "REVERT", - &Opcode::INVALID => "INVALID", - &Opcode::CREATE2 => "CREATE2", - &Opcode::EOFMAGIC => "EOFMAGIC", - &Opcode::SUICIDE => "SUICIDE", - _ => "UNKNOWN", - } - } -} - impl Stringify for ExitError { fn stringify(&self) -> &str { match self { diff --git a/modules/evm/src/tests.rs b/modules/evm/src/tests.rs index 3d88d7b166..997fe247af 100644 --- a/modules/evm/src/tests.rs +++ b/modules/evm/src/tests.rs @@ -3026,7 +3026,7 @@ fn tracer_works() { let alice_account_id = ::AddressMapping::get_account_id(&alice()); - let mut tracer = crate::runner::tracing::Tracer::new(); + let mut tracer = crate::runner::tracing::Tracer::new(true); crate::runner::tracing::using(&mut tracer, || { assert_ok!(EVM::call( RuntimeOrigin::signed(alice_account_id.clone()), @@ -3082,7 +3082,7 @@ fn tracer_works() { assert_eq!(steps.len(), 553); let step = r#" { - "op": [80, 85, 83, 72, 49], + "op": 96, "pc": 0, "depth": 0, "gas": 978796, @@ -3092,20 +3092,18 @@ fn tracer_works() { "#; let step = serde_json::from_str::(step).unwrap(); assert_eq!(steps.first().unwrap(), &step); - assert_eq!(String::from_utf8_lossy(&step.op), "PUSH1"); let step = r#" { - "op": [83, 84, 79, 80], + "op": 0, "pc": 194, "depth": 0, "gas": 949994, - "stack": ["0x00000000000000000000000000000000000000000000000000000000da1385d5"], + "stack": [[218, 19, 133, 213]], "memory": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 131, 74, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] } "#; let step = serde_json::from_str::(step).unwrap(); assert_eq!(steps.last().unwrap(), &step); - assert_eq!(String::from_utf8_lossy(&step.op), "STOP"); }) } diff --git a/primitives/src/evm.rs b/primitives/src/evm.rs index 98a94730b5..74aa5e06ce 100644 --- a/primitives/src/evm.rs +++ b/primitives/src/evm.rs @@ -336,9 +336,10 @@ pub use convert::*; #[cfg(feature = "tracing")] pub mod tracing { + use module_evm_utility::evm::Opcode; use parity_scale_codec::{Decode, Encode}; use scale_info::TypeInfo; - use sp_core::{H160, H256, U256}; + use sp_core::{H160, U256}; use sp_runtime::RuntimeDebug; use sp_std::vec::Vec; @@ -422,14 +423,14 @@ pub mod tracing { #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))] pub struct Step { - pub op: Vec, + pub op: Opcode, #[codec(compact)] - pub pc: u64, + pub pc: u32, #[codec(compact)] pub depth: u32, #[codec(compact)] pub gas: u64, - pub stack: Vec, + pub stack: Vec>, pub memory: Option>, } @@ -439,7 +440,7 @@ pub mod tracing { pub struct VMTrace { #[codec(compact)] pub gas: u64, - pub return_value: H256, + pub return_value: Vec, pub struct_logs: Vec, } } diff --git a/runtime/acala/src/lib.rs b/runtime/acala/src/lib.rs index 30affa31a2..9fa34f1305 100644 --- a/runtime/acala/src/lib.rs +++ b/runtime/acala/src/lib.rs @@ -2240,7 +2240,7 @@ sp_api::impl_runtime_apis! { storage_limit: u32, access_list: Option>, ) -> Result, sp_runtime::DispatchError> { - let mut tracer = module_evm::runner::tracing::Tracer::new(); + let mut tracer = module_evm::runner::tracing::Tracer::new(false); module_evm::runner::tracing::using(&mut tracer, || { if to == H160::zero() { ::Runner::rpc_create( @@ -2277,9 +2277,8 @@ sp_api::impl_runtime_apis! { storage_limit: u32, access_list: Option>, ) -> Result { - use sp_core::H256; use sp_runtime::traits::UniqueSaturatedInto; - let mut tracer = module_evm::runner::tracing::Tracer::new(); + let mut tracer = module_evm::runner::tracing::Tracer::new(true); module_evm::runner::tracing::using(&mut tracer, || { if to == H160::zero() { ::Runner::rpc_create( @@ -2290,7 +2289,7 @@ sp_api::impl_runtime_apis! { storage_limit, access_list.unwrap_or_default().into_iter().map(|v| (v.address, v.storage_keys)).collect(), ::config(), - ).map(|res| (H256::from(res.value), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) + ).map(|res| (res.value.as_bytes().to_vec(), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) } else { ::Runner::rpc_call( from, @@ -2302,7 +2301,7 @@ sp_api::impl_runtime_apis! { storage_limit, access_list.unwrap_or_default().into_iter().map(|v| (v.address, v.storage_keys)).collect(), ::config(), - ).map(|res| (H256::from_slice(&res.value), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) + ).map(|res| (res.value, UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) } }).map(|(return_value, gas) | module_evm::runner::tracing::VMTrace { gas, diff --git a/runtime/karura/src/lib.rs b/runtime/karura/src/lib.rs index 99774cb9cc..900f73eab9 100644 --- a/runtime/karura/src/lib.rs +++ b/runtime/karura/src/lib.rs @@ -2242,7 +2242,7 @@ impl_runtime_apis! { storage_limit: u32, access_list: Option>, ) -> Result, sp_runtime::DispatchError> { - let mut tracer = module_evm::runner::tracing::Tracer::new(); + let mut tracer = module_evm::runner::tracing::Tracer::new(false); module_evm::runner::tracing::using(&mut tracer, || { if to == H160::zero() { ::Runner::rpc_create( @@ -2279,9 +2279,8 @@ impl_runtime_apis! { storage_limit: u32, access_list: Option>, ) -> Result { - use sp_core::H256; use sp_runtime::traits::UniqueSaturatedInto; - let mut tracer = module_evm::runner::tracing::Tracer::new(); + let mut tracer = module_evm::runner::tracing::Tracer::new(true); module_evm::runner::tracing::using(&mut tracer, || { if to == H160::zero() { ::Runner::rpc_create( @@ -2292,7 +2291,7 @@ impl_runtime_apis! { storage_limit, access_list.unwrap_or_default().into_iter().map(|v| (v.address, v.storage_keys)).collect(), ::config(), - ).map(|res| (H256::from(res.value), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) + ).map(|res| (res.value.as_bytes().to_vec(), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) } else { ::Runner::rpc_call( from, @@ -2304,7 +2303,7 @@ impl_runtime_apis! { storage_limit, access_list.unwrap_or_default().into_iter().map(|v| (v.address, v.storage_keys)).collect(), ::config(), - ).map(|res| (H256::from_slice(&res.value), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) + ).map(|res| (res.value, UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) } }).map(|(return_value, gas) | module_evm::runner::tracing::VMTrace { gas, diff --git a/runtime/mandala/src/lib.rs b/runtime/mandala/src/lib.rs index 018df93129..a77162ca7a 100644 --- a/runtime/mandala/src/lib.rs +++ b/runtime/mandala/src/lib.rs @@ -2441,7 +2441,7 @@ impl_runtime_apis! { storage_limit: u32, access_list: Option>, ) -> Result, sp_runtime::DispatchError> { - let mut tracer = module_evm::runner::tracing::Tracer::new(); + let mut tracer = module_evm::runner::tracing::Tracer::new(false); module_evm::runner::tracing::using(&mut tracer, || { if to == H160::zero() { ::Runner::rpc_create( @@ -2478,9 +2478,8 @@ impl_runtime_apis! { storage_limit: u32, access_list: Option>, ) -> Result { - use sp_core::H256; use sp_runtime::traits::UniqueSaturatedInto; - let mut tracer = module_evm::runner::tracing::Tracer::new(); + let mut tracer = module_evm::runner::tracing::Tracer::new(true); module_evm::runner::tracing::using(&mut tracer, || { if to == H160::zero() { ::Runner::rpc_create( @@ -2491,7 +2490,7 @@ impl_runtime_apis! { storage_limit, access_list.unwrap_or_default().into_iter().map(|v| (v.address, v.storage_keys)).collect(), ::config(), - ).map(|res| (H256::from(res.value), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) + ).map(|res| (res.value.as_bytes().to_vec(), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) } else { ::Runner::rpc_call( from, @@ -2503,7 +2502,7 @@ impl_runtime_apis! { storage_limit, access_list.unwrap_or_default().into_iter().map(|v| (v.address, v.storage_keys)).collect(), ::config(), - ).map(|res| (H256::from_slice(&res.value), UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) + ).map(|res| (res.value, UniqueSaturatedInto::::unique_saturated_into(res.used_gas))) } }).map(|(return_value, gas) | module_evm::runner::tracing::VMTrace { gas,