diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go index 4e7fc31a9c..c19a8f3ae6 100644 --- a/eth/tracers/native/call_flat.go +++ b/eth/tracers/native/call_flat.go @@ -368,12 +368,18 @@ func convertErrorToParity(call *flatCallFrame) { if parityError, ok := parityErrorMapping[call.Error]; ok { call.Error = parityError - } else { - for gethError, parityError := range parityErrorMappingStartingWith { - if strings.HasPrefix(call.Error, gethError) { - call.Error = parityError - break - } + return + } + if i := strings.IndexByte(call.Error, ':'); i > 0 { + if parityError, ok := parityErrorMapping[call.Error[:i]]; ok { + call.Error = parityError + return + } + } + for gethError, parityError := range parityErrorMappingStartingWith { + if strings.HasPrefix(call.Error, gethError) { + call.Error = parityError + return } } } diff --git a/eth/tracers/native/call_flat_error_mapping_test.go b/eth/tracers/native/call_flat_error_mapping_test.go new file mode 100644 index 0000000000..4b749ad78f --- /dev/null +++ b/eth/tracers/native/call_flat_error_mapping_test.go @@ -0,0 +1,58 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package native + +import "testing" + +func TestConvertErrorToParity(t *testing.T) { + tests := []struct { + name string + in string + want string + }{ + { + name: "exact map key", + in: "max code size exceeded", + want: "Out of gas", + }, + { + name: "wrapped map key", + in: "max code size exceeded: code size 32769 limit 32768", + want: "Out of gas", + }, + { + name: "existing prefix rule", + in: "out of gas: not enough gas for reentrancy sentry", + want: "Out of gas", + }, + { + name: "unknown error unchanged", + in: "some unknown error", + want: "some unknown error", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + frame := &flatCallFrame{Error: tc.in} + convertErrorToParity(frame) + if frame.Error != tc.want { + t.Fatalf("unexpected mapped error, got=%q want=%q", frame.Error, tc.want) + } + }) + } +}