eth/tracers/logger: make structlog/json-log stack hex again (#28628)
* common/hexutil: define hex wrappers for uint256.Int * eth/tracers/logger: make structlog/json-log stack hex again * common/hexutil: goimports
This commit is contained in:
parent
2e13b01046
commit
3dc071e036
@ -23,6 +23,8 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -30,6 +32,7 @@ var (
|
|||||||
bigT = reflect.TypeOf((*Big)(nil))
|
bigT = reflect.TypeOf((*Big)(nil))
|
||||||
uintT = reflect.TypeOf(Uint(0))
|
uintT = reflect.TypeOf(Uint(0))
|
||||||
uint64T = reflect.TypeOf(Uint64(0))
|
uint64T = reflect.TypeOf(Uint64(0))
|
||||||
|
u256T = reflect.TypeOf((*uint256.Int)(nil))
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bytes marshals/unmarshals as a JSON string with 0x prefix.
|
// Bytes marshals/unmarshals as a JSON string with 0x prefix.
|
||||||
@ -225,6 +228,48 @@ func (b *Big) UnmarshalGraphQL(input interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// U256 marshals/unmarshals as a JSON string with 0x prefix.
|
||||||
|
// The zero value marshals as "0x0".
|
||||||
|
type U256 uint256.Int
|
||||||
|
|
||||||
|
// MarshalText implements encoding.TextMarshaler
|
||||||
|
func (b U256) MarshalText() ([]byte, error) {
|
||||||
|
u256 := (*uint256.Int)(&b)
|
||||||
|
return []byte(u256.Hex()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON implements json.Unmarshaler.
|
||||||
|
func (b *U256) UnmarshalJSON(input []byte) error {
|
||||||
|
// The uint256.Int.UnmarshalJSON method accepts "dec", "0xhex"; we must be
|
||||||
|
// more strict, hence we check string and invoke SetFromHex directly.
|
||||||
|
if !isString(input) {
|
||||||
|
return errNonString(u256T)
|
||||||
|
}
|
||||||
|
// The hex decoder needs to accept empty string ("") as '0', which uint256.Int
|
||||||
|
// would reject.
|
||||||
|
if len(input) == 2 {
|
||||||
|
(*uint256.Int)(b).Clear()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := (*uint256.Int)(b).SetFromHex(string(input[1 : len(input)-1]))
|
||||||
|
if err != nil {
|
||||||
|
return &json.UnmarshalTypeError{Value: err.Error(), Type: u256T}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText implements encoding.TextUnmarshaler
|
||||||
|
func (b *U256) UnmarshalText(input []byte) error {
|
||||||
|
// The uint256.Int.UnmarshalText method accepts "dec", "0xhex"; we must be
|
||||||
|
// more strict, hence we check string and invoke SetFromHex directly.
|
||||||
|
return (*uint256.Int)(b).SetFromHex(string(input))
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the hex encoding of b.
|
||||||
|
func (b *U256) String() string {
|
||||||
|
return (*uint256.Int)(b).Hex()
|
||||||
|
}
|
||||||
|
|
||||||
// Uint64 marshals/unmarshals as a JSON string with 0x prefix.
|
// Uint64 marshals/unmarshals as a JSON string with 0x prefix.
|
||||||
// The zero value marshals as "0x0".
|
// The zero value marshals as "0x0".
|
||||||
type Uint64 uint64
|
type Uint64 uint64
|
||||||
|
@ -23,6 +23,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkError(t *testing.T, input string, got, want error) bool {
|
func checkError(t *testing.T, input string, got, want error) bool {
|
||||||
@ -176,6 +178,64 @@ func TestUnmarshalBig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var unmarshalU256Tests = []unmarshalTest{
|
||||||
|
// invalid encoding
|
||||||
|
{input: "", wantErr: errJSONEOF},
|
||||||
|
{input: "null", wantErr: errNonString(u256T)},
|
||||||
|
{input: "10", wantErr: errNonString(u256T)},
|
||||||
|
{input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, u256T)},
|
||||||
|
{input: `"0x"`, wantErr: wrapTypeError(ErrEmptyNumber, u256T)},
|
||||||
|
{input: `"0x01"`, wantErr: wrapTypeError(ErrLeadingZero, u256T)},
|
||||||
|
{input: `"0xx"`, wantErr: wrapTypeError(ErrSyntax, u256T)},
|
||||||
|
{input: `"0x1zz01"`, wantErr: wrapTypeError(ErrSyntax, u256T)},
|
||||||
|
{
|
||||||
|
input: `"0x10000000000000000000000000000000000000000000000000000000000000000"`,
|
||||||
|
wantErr: wrapTypeError(ErrBig256Range, u256T),
|
||||||
|
},
|
||||||
|
|
||||||
|
// valid encoding
|
||||||
|
{input: `""`, want: big.NewInt(0)},
|
||||||
|
{input: `"0x0"`, want: big.NewInt(0)},
|
||||||
|
{input: `"0x2"`, want: big.NewInt(0x2)},
|
||||||
|
{input: `"0x2F2"`, want: big.NewInt(0x2f2)},
|
||||||
|
{input: `"0X2F2"`, want: big.NewInt(0x2f2)},
|
||||||
|
{input: `"0x1122aaff"`, want: big.NewInt(0x1122aaff)},
|
||||||
|
{input: `"0xbBb"`, want: big.NewInt(0xbbb)},
|
||||||
|
{input: `"0xfffffffff"`, want: big.NewInt(0xfffffffff)},
|
||||||
|
{
|
||||||
|
input: `"0x112233445566778899aabbccddeeff"`,
|
||||||
|
want: referenceBig("112233445566778899aabbccddeeff"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: `"0xffffffffffffffffffffffffffffffffffff"`,
|
||||||
|
want: referenceBig("ffffffffffffffffffffffffffffffffffff"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: `"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`,
|
||||||
|
want: referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalU256(t *testing.T) {
|
||||||
|
for _, test := range unmarshalU256Tests {
|
||||||
|
var v U256
|
||||||
|
err := json.Unmarshal([]byte(test.input), &v)
|
||||||
|
if !checkError(t, test.input, err, test.wantErr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if test.want == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
want := new(uint256.Int)
|
||||||
|
want.SetFromBig(test.want.(*big.Int))
|
||||||
|
have := (*uint256.Int)(&v)
|
||||||
|
if want.Cmp(have) != 0 {
|
||||||
|
t.Errorf("input %s: value mismatch: have %x, want %x", test.input, have, want)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkUnmarshalBig(b *testing.B) {
|
func BenchmarkUnmarshalBig(b *testing.B) {
|
||||||
input := []byte(`"0x123456789abcdef123456789abcdef"`)
|
input := []byte(`"0x123456789abcdef123456789abcdef"`)
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
|
@ -23,7 +23,7 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
|
|||||||
GasCost math.HexOrDecimal64 `json:"gasCost"`
|
GasCost math.HexOrDecimal64 `json:"gasCost"`
|
||||||
Memory hexutil.Bytes `json:"memory,omitempty"`
|
Memory hexutil.Bytes `json:"memory,omitempty"`
|
||||||
MemorySize int `json:"memSize"`
|
MemorySize int `json:"memSize"`
|
||||||
Stack []uint256.Int `json:"stack"`
|
Stack []hexutil.U256 `json:"stack"`
|
||||||
ReturnData hexutil.Bytes `json:"returnData,omitempty"`
|
ReturnData hexutil.Bytes `json:"returnData,omitempty"`
|
||||||
Storage map[common.Hash]common.Hash `json:"-"`
|
Storage map[common.Hash]common.Hash `json:"-"`
|
||||||
Depth int `json:"depth"`
|
Depth int `json:"depth"`
|
||||||
@ -39,7 +39,12 @@ func (s StructLog) MarshalJSON() ([]byte, error) {
|
|||||||
enc.GasCost = math.HexOrDecimal64(s.GasCost)
|
enc.GasCost = math.HexOrDecimal64(s.GasCost)
|
||||||
enc.Memory = s.Memory
|
enc.Memory = s.Memory
|
||||||
enc.MemorySize = s.MemorySize
|
enc.MemorySize = s.MemorySize
|
||||||
enc.Stack = s.Stack
|
if s.Stack != nil {
|
||||||
|
enc.Stack = make([]hexutil.U256, len(s.Stack))
|
||||||
|
for k, v := range s.Stack {
|
||||||
|
enc.Stack[k] = hexutil.U256(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
enc.ReturnData = s.ReturnData
|
enc.ReturnData = s.ReturnData
|
||||||
enc.Storage = s.Storage
|
enc.Storage = s.Storage
|
||||||
enc.Depth = s.Depth
|
enc.Depth = s.Depth
|
||||||
@ -59,7 +64,7 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
|
|||||||
GasCost *math.HexOrDecimal64 `json:"gasCost"`
|
GasCost *math.HexOrDecimal64 `json:"gasCost"`
|
||||||
Memory *hexutil.Bytes `json:"memory,omitempty"`
|
Memory *hexutil.Bytes `json:"memory,omitempty"`
|
||||||
MemorySize *int `json:"memSize"`
|
MemorySize *int `json:"memSize"`
|
||||||
Stack []uint256.Int `json:"stack"`
|
Stack []hexutil.U256 `json:"stack"`
|
||||||
ReturnData *hexutil.Bytes `json:"returnData,omitempty"`
|
ReturnData *hexutil.Bytes `json:"returnData,omitempty"`
|
||||||
Storage map[common.Hash]common.Hash `json:"-"`
|
Storage map[common.Hash]common.Hash `json:"-"`
|
||||||
Depth *int `json:"depth"`
|
Depth *int `json:"depth"`
|
||||||
@ -89,7 +94,10 @@ func (s *StructLog) UnmarshalJSON(input []byte) error {
|
|||||||
s.MemorySize = *dec.MemorySize
|
s.MemorySize = *dec.MemorySize
|
||||||
}
|
}
|
||||||
if dec.Stack != nil {
|
if dec.Stack != nil {
|
||||||
s.Stack = dec.Stack
|
s.Stack = make([]uint256.Int, len(dec.Stack))
|
||||||
|
for k, v := range dec.Stack {
|
||||||
|
s.Stack[k] = uint256.Int(v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if dec.ReturnData != nil {
|
if dec.ReturnData != nil {
|
||||||
s.ReturnData = *dec.ReturnData
|
s.ReturnData = *dec.ReturnData
|
||||||
|
@ -83,6 +83,7 @@ type structLogMarshaling struct {
|
|||||||
GasCost math.HexOrDecimal64
|
GasCost math.HexOrDecimal64
|
||||||
Memory hexutil.Bytes
|
Memory hexutil.Bytes
|
||||||
ReturnData hexutil.Bytes
|
ReturnData hexutil.Bytes
|
||||||
|
Stack []hexutil.U256
|
||||||
OpName string `json:"opName"` // adds call to OpName() in MarshalJSON
|
OpName string `json:"opName"` // adds call to OpName() in MarshalJSON
|
||||||
ErrorString string `json:"error,omitempty"` // adds call to ErrorString() in MarshalJSON
|
ErrorString string `json:"error,omitempty"` // adds call to ErrorString() in MarshalJSON
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user