From 488f52565ce62028ed3be1aa8044f03021734ea8 Mon Sep 17 00:00:00 2001 From: Adrian Sutton Date: Tue, 17 Oct 2023 12:08:47 +1000 Subject: [PATCH] ethclient: Fix eth_getBlockReceipts call when using block numbers or labels The String() version of BlockNumberOrHash uses decimal for all block numbers, including negative ones used to indicate labels. Switch to using BlockNumber.String() which encodes it correctly for use in the JSON-RPC API. --- rpc/types.go | 3 +-- rpc/types_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/rpc/types.go b/rpc/types.go index 34a1451dea..f88c37c59d 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -21,7 +21,6 @@ import ( "encoding/json" "fmt" "math" - "strconv" "strings" "github.com/ethereum/go-ethereum/common" @@ -221,7 +220,7 @@ func (bnh *BlockNumberOrHash) Number() (BlockNumber, bool) { func (bnh *BlockNumberOrHash) String() string { if bnh.BlockNumber != nil { - return strconv.Itoa(int(*bnh.BlockNumber)) + return bnh.BlockNumber.String() } if bnh.BlockHash != nil { return bnh.BlockHash.String() diff --git a/rpc/types_test.go b/rpc/types_test.go index f110dee7c6..b8cdcd6f04 100644 --- a/rpc/types_test.go +++ b/rpc/types_test.go @@ -153,3 +153,33 @@ func TestBlockNumberOrHash_WithNumber_MarshalAndUnmarshal(t *testing.T) { }) } } + +func TestBlockNumberOrHash_WithNumber_StringAndUnmarshal(t *testing.T) { + tests := []struct { + name string + value BlockNumberOrHash + }{ + {"max", BlockNumberOrHashWithNumber(math.MaxInt64)}, + {"pending", BlockNumberOrHashWithNumber(PendingBlockNumber)}, + {"latest", BlockNumberOrHashWithNumber(LatestBlockNumber)}, + {"earliest", BlockNumberOrHashWithNumber(EarliestBlockNumber)}, + {"0x20", BlockNumberOrHashWithNumber(32)}, + {"hash", BlockNumberOrHashWithHash(common.Hash{0xaa}, false)}, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + bnh := test.value + // Wrap the string value in quotes to make it a JSON string. + marshalled := []byte("\"" + bnh.String() + "\"") + var unmarshalled BlockNumberOrHash + err := json.Unmarshal(marshalled, &unmarshalled) + if err != nil { + t.Fatalf("cannot unmarshal (%v): %v", string(marshalled), err) + } + if !reflect.DeepEqual(bnh, unmarshalled) { + t.Fatalf("wrong result: expected %v, got %v", bnh, unmarshalled) + } + }) + } +}