Skip to content

Commit

Permalink
HexOrDecimal - to accept unquoted numbers - in json (e3) (#11262)
Browse files Browse the repository at this point in the history
accept in `genesis.json`:` "nonce": 0,`
now see: 
```
Fatal: invalid genesis file: json: cannot unmarshal number into Go struct field Genesis.alloc of type *math.HexOrDecimal64
```

See also `ethereum/go-ethereum#26758
  • Loading branch information
AskAlexSharov committed Jul 22, 2024
1 parent 0390616 commit 11c47f1
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 3 deletions.
11 changes: 11 additions & 0 deletions common/math/big.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ func NewHexOrDecimal256(x int64) *HexOrDecimal256 {
return &h
}

// UnmarshalJSON implements json.Unmarshaler.
//
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
// quoted decimal strings.
func (i *HexOrDecimal256) UnmarshalJSON(input []byte) error {
if len(input) > 0 && input[0] == '"' {
input = input[1 : len(input)-1]
}
return i.UnmarshalText(input)
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (i *HexOrDecimal256) UnmarshalText(input []byte) error {
bigint, ok := ParseBig256(string(input))
Expand Down
16 changes: 13 additions & 3 deletions common/math/integer.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,27 @@ const (
// HexOrDecimal64 marshals uint64 as hex or decimal.
type HexOrDecimal64 uint64

// UnmarshalJSON implements json.Unmarshaler.
//
// It is similar to UnmarshalText, but allows parsing real decimals too, not just
// quoted decimal strings.
func (i *HexOrDecimal64) UnmarshalJSON(input []byte) error {
if len(input) > 1 && input[0] == '"' {
input = input[1 : len(input)-1]
}
return i.UnmarshalText(input)
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (i *HexOrDecimal64) UnmarshalText(input []byte) error {
in, ok := ParseUint64(string(input))
n, ok := ParseUint64(string(input))
if !ok {
return fmt.Errorf("invalid hex or decimal integer %q", input)
}
*i = HexOrDecimal64(in)
*i = HexOrDecimal64(n)
return nil
}

// MarshalText implements encoding.TextMarshaler.
func (i HexOrDecimal64) MarshalText() ([]byte, error) {
return []byte(fmt.Sprintf("%#x", uint64(i))), nil
}
Expand Down
13 changes: 13 additions & 0 deletions core/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ package core_test

import (
"context"
"encoding/json"
"math/big"
"os"
"testing"

"github.com/holiman/uint256"
Expand Down Expand Up @@ -167,3 +169,14 @@ func TestAllocConstructor(t *testing.T) {
state.GetState(address, &key1, storage1)
assert.Equal(uint256.NewInt(0x01c9), storage1)
}

// See https://github.com/erigontech/erigon/pull/11264
func TestDecodeBalance0(t *testing.T) {
genesisData, err := os.ReadFile("./genesis_test.json")
require.NoError(t, err)

genesis := &types.Genesis{}
err = json.Unmarshal(genesisData, genesis)
require.NoError(t, err)
_ = genesisData
}
Loading

0 comments on commit 11c47f1

Please sign in to comment.