rpc: implement JSON marshaling of BlockNumber #23324 (#958)

This commit is contained in:
Daniel Liu 2025-04-24 18:20:03 +08:00 committed by GitHub
parent 6225b6dd9f
commit c789f86542
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 1 deletions

View file

@ -68,7 +68,7 @@ const (
)
// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports:
// - "latest", "earliest", "pending" and "committed" as string arguments
// - "committed", "finalized", "latest", "earliest" or "pending" as string arguments
// - the block number
// Returned errors:
// - an invalid block number error when the given argument isn't a known strings
@ -109,6 +109,24 @@ func (bn BlockNumber) Int64() int64 {
return (int64)(bn)
}
// MarshalText implements encoding.TextMarshaler. It marshals:
// - "finalized", "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
case CommittedBlockNumber:
return []byte("finalized"), nil
default:
return hexutil.Uint64(bn).MarshalText()
}
}
func (e *EpochNumber) UnmarshalJSON(data []byte) error {
input := trimData(data)
if input == "latest" {

View file

@ -19,6 +19,7 @@ package rpc
import (
"encoding/json"
"math"
"reflect"
"testing"
"github.com/XinFinOrg/XDPoSChain/common"
@ -122,3 +123,35 @@ 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)},
{"finalized", int64(CommittedBlockNumber)},
{"committed", int64(CommittedBlockNumber)},
}
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)
}
})
}
}