1extern crate alloc;
18
19use super::Context;
20use alloc::vec::Vec;
21use ethereum_types::{H160, H256, U256};
22pub use evm::{ExitError, ExitReason, ExitSucceed, Opcode};
23use parity_scale_codec::{Decode, Encode};
24
25#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
26pub struct Stack {
27 pub data: Vec<H256>,
28 pub limit: u64,
29}
30
31impl From<&evm::Stack> for Stack {
32 fn from(i: &evm::Stack) -> Self {
33 Self {
34 data: i.data().clone(),
35 limit: i.limit() as u64,
36 }
37 }
38}
39
40#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
41pub struct Memory {
42 pub data: Vec<u8>,
43 pub effective_len: U256,
44 pub limit: u64,
45}
46
47impl From<&evm::Memory> for Memory {
48 fn from(i: &evm::Memory) -> Self {
49 Self {
50 data: i.data().clone(),
51 effective_len: i.effective_len(),
52 limit: i.limit() as u64,
53 }
54 }
55}
56
57#[derive(Clone, Copy, Debug, Eq, PartialEq, Encode, Decode)]
58pub enum Capture<E, T> {
59 Exit(E),
61 Trap(T),
64}
65
66pub type Trap = Vec<u8>; #[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
69pub enum RuntimeEvent {
70 Step {
71 context: Context,
72 opcode: Vec<u8>,
74 position: Result<u64, ExitReason>,
76 stack: Option<Stack>,
77 memory: Option<Memory>,
78 },
79 StepResult {
80 result: Result<(), Capture<ExitReason, Trap>>,
81 return_value: Vec<u8>,
82 },
83 SLoad {
84 address: H160,
85 index: H256,
86 value: H256,
87 },
88 SStore {
89 address: H160,
90 index: H256,
91 value: H256,
92 },
93}
94
95#[cfg(feature = "evm-tracing")]
96impl RuntimeEvent {
97 pub fn from_evm_event<'a>(
98 i: evm_runtime::tracing::Event<'a>,
99 filter: crate::StepEventFilter,
100 ) -> Self {
101 match i {
102 evm_runtime::tracing::Event::Step {
103 context,
104 opcode,
105 position,
106 stack,
107 memory,
108 } => Self::Step {
109 context: context.clone().into(),
110 opcode: opcodes_string(opcode),
111 position: match position {
112 Ok(position) => Ok(*position as u64),
113 Err(e) => Err(e.clone()),
114 },
115 stack: if filter.enable_stack {
116 Some(stack.into())
117 } else {
118 None
119 },
120 memory: if filter.enable_memory {
121 Some(memory.into())
122 } else {
123 None
124 },
125 },
126 evm_runtime::tracing::Event::StepResult {
127 result,
128 return_value,
129 } => Self::StepResult {
130 result: match result {
131 Ok(_) => Ok(()),
132 Err(capture) => match capture {
133 evm::Capture::Exit(e) => Err(Capture::Exit(e.clone())),
134 evm::Capture::Trap(t) => Err(Capture::Trap(opcodes_string(*t))),
135 },
136 },
137 return_value: return_value.to_vec(),
138 },
139 evm_runtime::tracing::Event::SLoad {
140 address,
141 index,
142 value,
143 } => Self::SLoad {
144 address,
145 index,
146 value,
147 },
148 evm_runtime::tracing::Event::SStore {
149 address,
150 index,
151 value,
152 } => Self::SStore {
153 address,
154 index,
155 value,
156 },
157 }
158 }
159}
160
161#[cfg(feature = "evm-tracing")]
162pub fn opcodes_string(opcode: Opcode) -> Vec<u8> {
164 let tmp;
165 let out = match opcode {
166 Opcode(0) => "Stop",
167 Opcode(1) => "Add",
168 Opcode(2) => "Mul",
169 Opcode(3) => "Sub",
170 Opcode(4) => "Div",
171 Opcode(5) => "SDiv",
172 Opcode(6) => "Mod",
173 Opcode(7) => "SMod",
174 Opcode(8) => "AddMod",
175 Opcode(9) => "MulMod",
176 Opcode(10) => "Exp",
177 Opcode(11) => "SignExtend",
178 Opcode(16) => "Lt",
179 Opcode(17) => "Gt",
180 Opcode(18) => "Slt",
181 Opcode(19) => "Sgt",
182 Opcode(20) => "Eq",
183 Opcode(21) => "IsZero",
184 Opcode(22) => "And",
185 Opcode(23) => "Or",
186 Opcode(24) => "Xor",
187 Opcode(25) => "Not",
188 Opcode(26) => "Byte",
189 Opcode(27) => "Shl",
190 Opcode(28) => "Shr",
191 Opcode(29) => "Sar",
192 Opcode(32) => "Keccak256",
193 Opcode(48) => "Address",
194 Opcode(49) => "Balance",
195 Opcode(50) => "Origin",
196 Opcode(51) => "Caller",
197 Opcode(52) => "CallValue",
198 Opcode(53) => "CallDataLoad",
199 Opcode(54) => "CallDataSize",
200 Opcode(55) => "CallDataCopy",
201 Opcode(56) => "CodeSize",
202 Opcode(57) => "CodeCopy",
203 Opcode(58) => "GasPrice",
204 Opcode(59) => "ExtCodeSize",
205 Opcode(60) => "ExtCodeCopy",
206 Opcode(61) => "ReturnDataSize",
207 Opcode(62) => "ReturnDataCopy",
208 Opcode(63) => "ExtCodeHash",
209 Opcode(64) => "BlockHash",
210 Opcode(65) => "Coinbase",
211 Opcode(66) => "Timestamp",
212 Opcode(67) => "Number",
213 Opcode(68) => "Difficulty",
214 Opcode(69) => "GasLimit",
215 Opcode(70) => "ChainId",
216 Opcode(80) => "Pop",
217 Opcode(81) => "MLoad",
218 Opcode(82) => "MStore",
219 Opcode(83) => "MStore8",
220 Opcode(84) => "SLoad",
221 Opcode(85) => "SStore",
222 Opcode(86) => "Jump",
223 Opcode(87) => "JumpI",
224 Opcode(88) => "GetPc",
225 Opcode(89) => "MSize",
226 Opcode(90) => "Gas",
227 Opcode(91) => "JumpDest",
228 Opcode(92) => "TLoad",
229 Opcode(93) => "TStore",
230 Opcode(94) => "MCopy",
231 Opcode(96) => "Push1",
232 Opcode(97) => "Push2",
233 Opcode(98) => "Push3",
234 Opcode(99) => "Push4",
235 Opcode(100) => "Push5",
236 Opcode(101) => "Push6",
237 Opcode(102) => "Push7",
238 Opcode(103) => "Push8",
239 Opcode(104) => "Push9",
240 Opcode(105) => "Push10",
241 Opcode(106) => "Push11",
242 Opcode(107) => "Push12",
243 Opcode(108) => "Push13",
244 Opcode(109) => "Push14",
245 Opcode(110) => "Push15",
246 Opcode(111) => "Push16",
247 Opcode(112) => "Push17",
248 Opcode(113) => "Push18",
249 Opcode(114) => "Push19",
250 Opcode(115) => "Push20",
251 Opcode(116) => "Push21",
252 Opcode(117) => "Push22",
253 Opcode(118) => "Push23",
254 Opcode(119) => "Push24",
255 Opcode(120) => "Push25",
256 Opcode(121) => "Push26",
257 Opcode(122) => "Push27",
258 Opcode(123) => "Push28",
259 Opcode(124) => "Push29",
260 Opcode(125) => "Push30",
261 Opcode(126) => "Push31",
262 Opcode(127) => "Push32",
263 Opcode(128) => "Dup1",
264 Opcode(129) => "Dup2",
265 Opcode(130) => "Dup3",
266 Opcode(131) => "Dup4",
267 Opcode(132) => "Dup5",
268 Opcode(133) => "Dup6",
269 Opcode(134) => "Dup7",
270 Opcode(135) => "Dup8",
271 Opcode(136) => "Dup9",
272 Opcode(137) => "Dup10",
273 Opcode(138) => "Dup11",
274 Opcode(139) => "Dup12",
275 Opcode(140) => "Dup13",
276 Opcode(141) => "Dup14",
277 Opcode(142) => "Dup15",
278 Opcode(143) => "Dup16",
279 Opcode(144) => "Swap1",
280 Opcode(145) => "Swap2",
281 Opcode(146) => "Swap3",
282 Opcode(147) => "Swap4",
283 Opcode(148) => "Swap5",
284 Opcode(149) => "Swap6",
285 Opcode(150) => "Swap7",
286 Opcode(151) => "Swap8",
287 Opcode(152) => "Swap9",
288 Opcode(153) => "Swap10",
289 Opcode(154) => "Swap11",
290 Opcode(155) => "Swap12",
291 Opcode(156) => "Swap13",
292 Opcode(157) => "Swap14",
293 Opcode(158) => "Swap15",
294 Opcode(159) => "Swap16",
295 Opcode(160) => "Log0",
296 Opcode(161) => "Log1",
297 Opcode(162) => "Log2",
298 Opcode(163) => "Log3",
299 Opcode(164) => "Log4",
300 Opcode(176) => "JumpTo",
301 Opcode(177) => "JumpIf",
302 Opcode(178) => "JumpSub",
303 Opcode(180) => "JumpSubv",
304 Opcode(181) => "BeginSub",
305 Opcode(182) => "BeginData",
306 Opcode(184) => "ReturnSub",
307 Opcode(185) => "PutLocal",
308 Opcode(186) => "GetLocal",
309 Opcode(225) => "SLoadBytes",
310 Opcode(226) => "SStoreBytes",
311 Opcode(227) => "SSize",
312 Opcode(240) => "Create",
313 Opcode(241) => "Call",
314 Opcode(242) => "CallCode",
315 Opcode(243) => "Return",
316 Opcode(244) => "DelegateCall",
317 Opcode(245) => "Create2",
318 Opcode(250) => "StaticCall",
319 Opcode(252) => "TxExecGas",
320 Opcode(253) => "Revert",
321 Opcode(254) => "Invalid",
322 Opcode(255) => "SelfDestruct",
323 Opcode(n) => {
324 tmp = alloc::format!("Unknown({})", n);
325 &tmp
326 }
327 };
328 out.as_bytes().to_vec()
329}