From a90bc9f09d51c90b45e131d37644a00282360fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6ller?= Date: Mon, 7 Oct 2024 14:38:01 +0200 Subject: [PATCH 1/3] Add Type back to CallFrame --- packages/evm/jsonrpc/tracer_call.go | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/evm/jsonrpc/tracer_call.go b/packages/evm/jsonrpc/tracer_call.go index 03acf914f1..fc8b55ba37 100644 --- a/packages/evm/jsonrpc/tracer_call.go +++ b/packages/evm/jsonrpc/tracer_call.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "strings" "sync/atomic" "github.com/ethereum/go-ethereum/accounts/abi" @@ -33,7 +34,7 @@ type callLog struct { } type CallFrame struct { - Type vm.OpCode `json:"-"` + Type vm.OpCode `json:"type"` From common.Address `json:"from"` Gas hexutil.Uint64 `json:"gas"` GasUsed hexutil.Uint64 `json:"gasUsed"` @@ -50,6 +51,36 @@ type CallFrame struct { revertedSnapshot bool } +/* +MarshalJSON / UnMarshalJSON functions are only there to return/take `Type` as a string (like `call`). Otherwise, it would simply return a number. +*/ +func (f CallFrame) MarshalJSON() ([]byte, error) { + type Alias CallFrame + return json.Marshal(&struct { + Type string `json:"type"` + Alias + }{ + Type: strings.ToLower(f.Type.String()), + Alias: Alias(f), + }) +} + +func (f *CallFrame) UnmarshalJSON(data []byte) error { + type Alias CallFrame + aux := &struct { + Type string `json:"type"` + *Alias + }{ + Alias: (*Alias)(f), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + // Convert string back to OpCode + f.Type = vm.StringToOp(strings.ToUpper(aux.Type)) + return nil +} + func (f CallFrame) TypeString() string { return f.Type.String() } From d61d8d0b3d1c21540c2a90be8911193e22ab43b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6ller?= Date: Mon, 7 Oct 2024 14:40:26 +0200 Subject: [PATCH 2/3] Update comment --- packages/evm/jsonrpc/tracer_call.go | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/evm/jsonrpc/tracer_call.go b/packages/evm/jsonrpc/tracer_call.go index fc8b55ba37..ea4cc260fe 100644 --- a/packages/evm/jsonrpc/tracer_call.go +++ b/packages/evm/jsonrpc/tracer_call.go @@ -53,6 +53,7 @@ type CallFrame struct { /* MarshalJSON / UnMarshalJSON functions are only there to return/take `Type` as a string (like `call`). Otherwise, it would simply return a number. +It returns the type in lowercase as it was before. But EVM internal functions require uppercase, so it's converted to that in UnMarshal. */ func (f CallFrame) MarshalJSON() ([]byte, error) { type Alias CallFrame From dc6dc1657f9f2f90019a9ff4b6d58d95c7acc41c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20M=C3=B6ller?= Date: Mon, 7 Oct 2024 15:01:36 +0200 Subject: [PATCH 3/3] Revert to OpCode wrapper type --- packages/evm/jsonrpc/tracer_call.go | 58 ++++++++++++----------------- 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/packages/evm/jsonrpc/tracer_call.go b/packages/evm/jsonrpc/tracer_call.go index ea4cc260fe..3330435434 100644 --- a/packages/evm/jsonrpc/tracer_call.go +++ b/packages/evm/jsonrpc/tracer_call.go @@ -33,8 +33,29 @@ type callLog struct { Position hexutil.Uint `json:"position"` } +type OpCodeJSON struct { + vm.OpCode +} + +func NewOpCodeJSON(code vm.OpCode) OpCodeJSON { + return OpCodeJSON{OpCode: code} +} + +func (o OpCodeJSON) MarshalJSON() ([]byte, error) { + return json.Marshal(strings.ToLower(o.String())) +} + +func (o *OpCodeJSON) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + o.OpCode = vm.StringToOp(strings.ToUpper(s)) + return nil +} + type CallFrame struct { - Type vm.OpCode `json:"type"` + Type OpCodeJSON `json:"type"` From common.Address `json:"from"` Gas hexutil.Uint64 `json:"gas"` GasUsed hexutil.Uint64 `json:"gasUsed"` @@ -51,37 +72,6 @@ type CallFrame struct { revertedSnapshot bool } -/* -MarshalJSON / UnMarshalJSON functions are only there to return/take `Type` as a string (like `call`). Otherwise, it would simply return a number. -It returns the type in lowercase as it was before. But EVM internal functions require uppercase, so it's converted to that in UnMarshal. -*/ -func (f CallFrame) MarshalJSON() ([]byte, error) { - type Alias CallFrame - return json.Marshal(&struct { - Type string `json:"type"` - Alias - }{ - Type: strings.ToLower(f.Type.String()), - Alias: Alias(f), - }) -} - -func (f *CallFrame) UnmarshalJSON(data []byte) error { - type Alias CallFrame - aux := &struct { - Type string `json:"type"` - *Alias - }{ - Alias: (*Alias)(f), - } - if err := json.Unmarshal(data, &aux); err != nil { - return err - } - // Convert string back to OpCode - f.Type = vm.StringToOp(strings.ToUpper(aux.Type)) - return nil -} - func (f CallFrame) TypeString() string { return f.Type.String() } @@ -103,7 +93,7 @@ func (f *CallFrame) processOutput(output []byte, err error, reverted bool) { } f.Error = err.Error() f.revertedSnapshot = reverted - if f.Type == vm.CREATE || f.Type == vm.CREATE2 { + if f.Type.OpCode == vm.CREATE || f.Type.OpCode == vm.CREATE2 { f.To = nil } if !errors.Is(err, vm.ErrExecutionReverted) || len(output) == 0 { @@ -193,7 +183,7 @@ func (t *callTracer) OnEnter(depth int, typ byte, from common.Address, to common toCopy := to call := CallFrame{ - Type: vm.OpCode(typ), + Type: NewOpCodeJSON(vm.OpCode(typ)), From: from, To: &toCopy, Input: common.CopyBytes(input),