Skip to content

Commit 37e5816

Browse files
committed
common: use package hexutil for fixed size type encoding
1 parent 1609df3 commit 37e5816

File tree

2 files changed

+30
-60
lines changed

2 files changed

+30
-60
lines changed

common/types.go

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,19 @@
1717
package common
1818

1919
import (
20-
"encoding/hex"
21-
"encoding/json"
22-
"errors"
2320
"fmt"
2421
"math/big"
2522
"math/rand"
2623
"reflect"
27-
"strings"
24+
25+
"github.com/ethereum/go-ethereum/common/hexutil"
2826
)
2927

3028
const (
3129
HashLength = 32
3230
AddressLength = 20
3331
)
3432

35-
var hashJsonLengthErr = errors.New("common: unmarshalJSON failed: hash must be exactly 32 bytes")
36-
3733
type (
3834
// Hash represents the 32 byte Keccak256 hash of arbitrary data.
3935
Hash [HashLength]byte
@@ -57,30 +53,16 @@ func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
5753
func (h Hash) Str() string { return string(h[:]) }
5854
func (h Hash) Bytes() []byte { return h[:] }
5955
func (h Hash) Big() *big.Int { return Bytes2Big(h[:]) }
60-
func (h Hash) Hex() string { return "0x" + Bytes2Hex(h[:]) }
56+
func (h Hash) Hex() string { return hexutil.Encode(h[:]) }
6157

6258
// UnmarshalJSON parses a hash in its hex from to a hash.
6359
func (h *Hash) UnmarshalJSON(input []byte) error {
64-
length := len(input)
65-
if length >= 2 && input[0] == '"' && input[length-1] == '"' {
66-
input = input[1 : length-1]
67-
}
68-
// strip "0x" for length check
69-
if len(input) > 1 && strings.ToLower(string(input[:2])) == "0x" {
70-
input = input[2:]
71-
}
72-
73-
// validate the length of the input hash
74-
if len(input) != HashLength*2 {
75-
return hashJsonLengthErr
76-
}
77-
h.SetBytes(FromHex(string(input)))
78-
return nil
60+
return hexutil.UnmarshalJSON("Hash", input, h[:])
7961
}
8062

8163
// Serialize given hash to JSON
8264
func (h Hash) MarshalJSON() ([]byte, error) {
83-
return json.Marshal(h.Hex())
65+
return hexutil.Bytes(h[:]).MarshalJSON()
8466
}
8567

8668
// Sets the hash to the value of b. If b is larger than len(h) it will panic
@@ -142,7 +124,7 @@ func (a Address) Str() string { return string(a[:]) }
142124
func (a Address) Bytes() []byte { return a[:] }
143125
func (a Address) Big() *big.Int { return Bytes2Big(a[:]) }
144126
func (a Address) Hash() Hash { return BytesToHash(a[:]) }
145-
func (a Address) Hex() string { return "0x" + Bytes2Hex(a[:]) }
127+
func (a Address) Hex() string { return hexutil.Encode(a[:]) }
146128

147129
// Sets the address to the value of b. If b is larger than len(a) it will panic
148130
func (a *Address) SetBytes(b []byte) {
@@ -164,34 +146,12 @@ func (a *Address) Set(other Address) {
164146

165147
// Serialize given address to JSON
166148
func (a Address) MarshalJSON() ([]byte, error) {
167-
return json.Marshal(a.Hex())
149+
return hexutil.Bytes(a[:]).MarshalJSON()
168150
}
169151

170152
// Parse address from raw json data
171-
func (a *Address) UnmarshalJSON(data []byte) error {
172-
if len(data) > 2 && data[0] == '"' && data[len(data)-1] == '"' {
173-
data = data[1 : len(data)-1]
174-
}
175-
176-
if len(data) > 2 && data[0] == '0' && data[1] == 'x' {
177-
data = data[2:]
178-
}
179-
180-
if len(data) != 2*AddressLength {
181-
return fmt.Errorf("Invalid address length, expected %d got %d bytes", 2*AddressLength, len(data))
182-
}
183-
184-
n, err := hex.Decode(a[:], data)
185-
if err != nil {
186-
return err
187-
}
188-
189-
if n != AddressLength {
190-
return fmt.Errorf("Invalid address")
191-
}
192-
193-
a.Set(HexToAddress(string(data)))
194-
return nil
153+
func (a *Address) UnmarshalJSON(input []byte) error {
154+
return hexutil.UnmarshalJSON("Address", input, a[:])
195155
}
196156

197157
// PP Pretty Prints a byte slice in the following format:

common/types_test.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ package common
1818

1919
import (
2020
"math/big"
21+
"strings"
2122
"testing"
23+
24+
"github.com/ethereum/go-ethereum/common/hexutil"
2225
)
2326

2427
func TestBytesConversion(t *testing.T) {
@@ -38,19 +41,26 @@ func TestHashJsonValidation(t *testing.T) {
3841
var tests = []struct {
3942
Prefix string
4043
Size int
41-
Error error
44+
Error string
4245
}{
43-
{"", 2, hashJsonLengthErr},
44-
{"", 62, hashJsonLengthErr},
45-
{"", 66, hashJsonLengthErr},
46-
{"", 65, hashJsonLengthErr},
47-
{"0X", 64, nil},
48-
{"0x", 64, nil},
49-
{"0x", 62, hashJsonLengthErr},
46+
{"", 62, hexutil.ErrMissingPrefix.Error()},
47+
{"0x", 66, "hex string has length 66, want 64 for Hash"},
48+
{"0x", 63, hexutil.ErrOddLength.Error()},
49+
{"0x", 0, "hex string has length 0, want 64 for Hash"},
50+
{"0x", 64, ""},
51+
{"0X", 64, ""},
5052
}
51-
for i, test := range tests {
52-
if err := h.UnmarshalJSON(append([]byte(test.Prefix), make([]byte, test.Size)...)); err != test.Error {
53-
t.Errorf("test #%d: error mismatch: have %v, want %v", i, err, test.Error)
53+
for _, test := range tests {
54+
input := `"` + test.Prefix + strings.Repeat("0", test.Size) + `"`
55+
err := h.UnmarshalJSON([]byte(input))
56+
if err == nil {
57+
if test.Error != "" {
58+
t.Errorf("%s: error mismatch: have nil, want %q", input, test.Error)
59+
}
60+
} else {
61+
if err.Error() != test.Error {
62+
t.Errorf("%s: error mismatch: have %q, want %q", input, err, test.Error)
63+
}
5464
}
5565
}
5666
}

0 commit comments

Comments
 (0)