diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index b2bebb15ce..36a3417d8f 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -18,7 +18,6 @@ package native import ( "encoding/json" - "errors" "math/big" "strconv" "strings" @@ -60,21 +59,21 @@ type callTracer struct { func newCallTracer(ctx *tracers.Context) tracers.Tracer { // First callframe contains tx context info // and is populated on start and end. - t := &callTracer{callstack: make([]callFrame, 1)} + t := &callTracer{callstack: make([]callFrame, 0, 1)} return t } // CaptureStart implements the EVMLogger interface to initialize the tracing operation. func (t *callTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int, authorizationResults []types.AuthorizationResult) { t.env = env - t.callstack[0] = callFrame{ + t.callstack = append(t.callstack, callFrame{ Type: "CALL", From: addrToHex(from), To: addrToHex(to), Input: bytesToHex(input), Gas: uintToHex(gas), Value: bigToHex(value), - } + }) if create { t.callstack[0].Type = "CREATE" } @@ -152,7 +151,10 @@ func (t *callTracer) CaptureExit(output []byte, gasUsed uint64, err error) { // error arising from the encoding or forceful termination (via `Stop`). func (t *callTracer) GetResult() (json.RawMessage, error) { if len(t.callstack) != 1 { - return nil, errors.New("incorrect number of top-level calls") + // If the callstack is empty, return an empty JSON object instead of erroring + // Callstack can be empty due to an edge case where an L1 message is reverted even + // before entering the first call. + return json.RawMessage("{}"), nil } res, err := json.Marshal(t.callstack[0]) if err != nil { diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index b82398c78a..721882b0c9 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -18,7 +18,6 @@ package native import ( "encoding/json" - "errors" "fmt" "math/big" "strings" @@ -115,7 +114,7 @@ type flatCallTracer struct { // newFlatCallTracer returns a new flatCallTracer. func newFlatCallTracer(ctx *tracers.Context) tracers.Tracer { - t := &callTracer{callstack: make([]callFrame, 1)} + t := &callTracer{callstack: make([]callFrame, 0, 1)} return &flatCallTracer{callTracer: t, ctx: ctx} @@ -133,7 +132,10 @@ func (t *flatCallTracer) CaptureEnter(typ vm.OpCode, from common.Address, to com // error arising from the encoding or forceful termination (via `Stop`). func (t *flatCallTracer) GetResult() (json.RawMessage, error) { if len(t.callTracer.callstack) < 1 { - return nil, errors.New("invalid number of calls") + // If the callstack is empty, return an empty JSON list instead of erroring + // Callstack can be empty due to an edge case where an L1 message is reverted even + // before entering the first call. + return json.RawMessage("[]"), nil } flat, err := flatFromNested(&t.callTracer.callstack[0], []int{}, true, t.ctx) diff --git a/params/version.go b/params/version.go index 265cf80503..d3a7166505 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 8 // Minor version component of the current release - VersionPatch = 39 // Patch version component of the current release + VersionPatch = 40 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string )