fix: remove `OpCode` enum and update `VMOperation`'s `op` field type (#1904)

* remove OpCode enum and update VMOperation's op field

* restore opcodes + update 0x20 to keccak256

* enum to deserialize opcodes into known or unknown

* Update ethers-core/src/types/trace/mod.rs

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>

* fix typo: ExecutedInstruction

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
This commit is contained in:
MouseLess.eth 2022-12-02 12:51:16 -08:00 committed by GitHub
parent 4e98c4a5f0
commit 913f15dc84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 6 deletions

View File

@ -134,9 +134,9 @@ pub struct VMOperation {
/// Subordinate trace of the CALL/CREATE if applicable.
// #[serde(bound="VMTrace: Deserialize")]
pub sub: Option<VMTrace>,
/// The executed opcode name
/// The opcode of the executed instruction
#[serde(rename = "op")]
pub op: OpCode,
pub op: ExecutedInstruction,
}
#[derive(Debug, Clone, PartialEq, Eq, Default, Deserialize, Serialize)]
@ -176,6 +176,23 @@ pub struct StorageDiff {
pub val: U256,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
#[allow(clippy::upper_case_acronyms)]
/// Helper to classify the executed instruction
pub enum ExecutedInstruction {
/// The instruction is recognized
Known(Opcode),
/// The instruction is not recognized
Unknown(String),
}
impl Default for ExecutedInstruction {
fn default() -> Self {
Self::Known(Opcode::INVALID)
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -208,4 +225,19 @@ mod tests {
fn test_deserialize_blocktraces() {
let _traces: Vec<BlockTrace> = serde_json::from_str(EXAMPLE_TRACES).unwrap();
}
#[test]
fn test_deserialize_unknown_opcode() {
let example_opcodes = r#"["GAS", "CREATE2", "CUSTOMOP"]"#;
let parsed_opcodes: Vec<ExecutedInstruction> =
serde_json::from_str(example_opcodes).unwrap();
assert_eq!(
vec![
ExecutedInstruction::Known(Opcode::GAS),
ExecutedInstruction::Known(Opcode::CREATE2),
ExecutedInstruction::Unknown("CUSTOMOP".to_string())
],
parsed_opcodes
)
}
}

View File

@ -2,9 +2,9 @@ use serde::{Deserialize, Serialize};
// opcode descriptions taken from evm.codes https://github.com/comitylabs/evm.codes/blob/bc7f102808055d88365559d40c190c5bd6d164c3/opcodes.json
// https://github.com/ethereum/go-ethereum/blob/2b1299b1c006077c56ecbad32e79fc16febe3dd6/core/vm/opcodes.go
#[derive(Debug, Clone, PartialEq, Eq, Default, Deserialize, Serialize)]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
/// Name of executed EVM opcode
pub enum OpCode {
pub enum Opcode {
// 0x0 range - arithmetic ops.
/// Opcode 0x0 - Halts execution
STOP,
@ -67,7 +67,7 @@ pub enum OpCode {
// 0x20 range - crypto.
/// Opcode 0x20 - Compute Keccak-256 hash
SHA3,
KECCAK256,
// 0x21 - 0x2F are invalid
@ -335,7 +335,6 @@ pub enum OpCode {
// 0xfd range - closures
/// Opcode 0xFD - Halt execution reverting state changes but returning data and remaining gas
REVERT,
#[default]
/// Opcode 0xFE - Designated invalid instruction
INVALID,
/// Opcode 0xFF - Halt execution and register account for later deletion