rpc: add BlockNumber.MarshalText (#23324)
Currently rpc.BlockNumber is marshalled to JSON as a numeric value, which is wrong because BlockNumber.UnmarshalJSON() wants it to either be hex-encoded or string "earliest"/"latest"/"pending". As a result, the call chain rpc.BlockNumberOrHashWithNumber(123) -> json.Marshal() -> json.Unmarshal() fails with error "cannot unmarshal object into Go value of type string".
This commit is contained in:
parent
154b525ce8
commit
7c4cad064c
16
rpc/types.go
16
rpc/types.go
|
@ -98,6 +98,22 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler. It marshals:
|
||||
// - "latest", "earliest" or "pending" as strings
|
||||
// - other numbers as hex
|
||||
func (bn BlockNumber) MarshalText() ([]byte, error) {
|
||||
switch bn {
|
||||
case EarliestBlockNumber:
|
||||
return []byte("earliest"), nil
|
||||
case LatestBlockNumber:
|
||||
return []byte("latest"), nil
|
||||
case PendingBlockNumber:
|
||||
return []byte("pending"), nil
|
||||
default:
|
||||
return hexutil.Uint64(bn).MarshalText()
|
||||
}
|
||||
}
|
||||
|
||||
func (bn BlockNumber) Int64() int64 {
|
||||
return (int64)(bn)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package rpc
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
@ -122,3 +123,33 @@ func TestBlockNumberOrHash_UnmarshalJSON(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlockNumberOrHash_WithNumber_MarshalAndUnmarshal(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
number int64
|
||||
}{
|
||||
{"max", math.MaxInt64},
|
||||
{"pending", int64(PendingBlockNumber)},
|
||||
{"latest", int64(LatestBlockNumber)},
|
||||
{"earliest", int64(EarliestBlockNumber)},
|
||||
}
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
bnh := BlockNumberOrHashWithNumber(BlockNumber(test.number))
|
||||
marshalled, err := json.Marshal(bnh)
|
||||
if err != nil {
|
||||
t.Fatal("cannot marshal:", err)
|
||||
}
|
||||
var unmarshalled BlockNumberOrHash
|
||||
err = json.Unmarshal(marshalled, &unmarshalled)
|
||||
if err != nil {
|
||||
t.Fatal("cannot unmarshal:", err)
|
||||
}
|
||||
if !reflect.DeepEqual(bnh, unmarshalled) {
|
||||
t.Fatalf("wrong result: expected %v, got %v", bnh, unmarshalled)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue