Skip to content

Commit 9231770

Browse files
holimanfjl
andauthored
rpc: change BlockNumber constant values to match ethclient (#27219)
ethclient accepts certain negative block number values as specifiers for the "pending", "safe" and "finalized" block. In case of "pending", the value accepted by ethclient (-1) did not match rpc.PendingBlockNumber (-2). This wasn't really a problem, but other values accepted by ethclient did match the definitions in package rpc, and it's weird to have this one special case where they don't. To fix it, we decided to change the values of the constants rather than changing ethclient. The constant values are not otherwise significant. This is a breaking API change, but we believe not a dangerous one. --------- Co-authored-by: Felix Lange <[email protected]>
1 parent 1a18283 commit 9231770

File tree

6 files changed

+54
-47
lines changed

6 files changed

+54
-47
lines changed

eth/filters/api_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
5656

5757
// from, to block number
5858
var test1 FilterCriteria
59-
vector := fmt.Sprintf(`{"fromBlock":"%#x","toBlock":"%#x"}`, fromBlock, toBlock)
59+
vector := fmt.Sprintf(`{"fromBlock":"%v","toBlock":"%v"}`, fromBlock, toBlock)
6060
if err := json.Unmarshal([]byte(vector), &test1); err != nil {
6161
t.Fatal(err)
6262
}

eth/filters/filter.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) ([]*typ
296296
// pendingLogs returns the logs matching the filter criteria within the pending block.
297297
func (f *Filter) pendingLogs() ([]*types.Log, error) {
298298
block, receipts := f.sys.backend.PendingBlockAndReceipts()
299+
if block == nil {
300+
return nil, errors.New("pending state not available")
301+
}
299302
if bloomFilter(block.Bloom(), f.addresses, f.topics) {
300303
var unfiltered []*types.Log
301304
for _, r := range receipts {

eth/filters/filter_test.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/ethereum/go-ethereum/core/types"
3030
"github.com/ethereum/go-ethereum/crypto"
3131
"github.com/ethereum/go-ethereum/params"
32+
"github.com/ethereum/go-ethereum/rpc"
3233
)
3334

3435
func makeReceipt(addr common.Address) *types.Receipt {
@@ -179,7 +180,7 @@ func TestFilters(t *testing.T) {
179180
// Set block 998 as Finalized (-3)
180181
rawdb.WriteFinalizedBlockHash(db, chain[998].Hash())
181182

182-
filter := sys.NewRangeFilter(0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
183+
filter := sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
183184
logs, _ := filter.Logs(context.Background())
184185
if len(logs) != 4 {
185186
t.Error("expected 4 log, got", len(logs))
@@ -193,34 +194,36 @@ func TestFilters(t *testing.T) {
193194
sys.NewRangeFilter(900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}),
194195
[]common.Hash{hash3},
195196
}, {
196-
sys.NewRangeFilter(990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}),
197+
sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{addr}, [][]common.Hash{{hash3}}),
197198
[]common.Hash{hash3},
198199
}, {
199200
sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}),
200201
[]common.Hash{hash1, hash2},
201202
}, {
202-
sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
203+
sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
203204
nil,
204205
}, {
205-
sys.NewRangeFilter(0, -1, []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
206+
sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
206207
nil,
207208
}, {
208-
sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
209+
sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
209210
nil,
210211
}, {
211-
sys.NewRangeFilter(-1, -1, nil, nil), []common.Hash{hash4},
212+
sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), []common.Hash{hash4},
212213
}, {
213-
sys.NewRangeFilter(-3, -1, nil, nil), []common.Hash{hash3, hash4},
214+
sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), []common.Hash{hash3, hash4},
214215
}, {
215-
sys.NewRangeFilter(-3, -3, nil, nil), []common.Hash{hash3},
216+
sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), []common.Hash{hash3},
216217
}, {
217-
sys.NewRangeFilter(-1, -3, nil, nil), nil,
218+
sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), nil,
218219
}, {
219-
sys.NewRangeFilter(-4, -1, nil, nil), nil,
220+
sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), nil,
220221
}, {
221-
sys.NewRangeFilter(-4, -4, nil, nil), nil,
222+
sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), nil,
222223
}, {
223-
sys.NewRangeFilter(-1, -4, nil, nil), nil,
224+
sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), nil,
225+
}, {
226+
sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), nil,
224227
},
225228
} {
226229
logs, _ := tc.f.Logs(context.Background())

ethclient/ethclient.go

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -592,19 +592,15 @@ func toBlockNumArg(number *big.Int) string {
592592
if number == nil {
593593
return "latest"
594594
}
595-
pending := big.NewInt(-1)
596-
if number.Cmp(pending) == 0 {
597-
return "pending"
595+
if number.Sign() >= 0 {
596+
return hexutil.EncodeBig(number)
598597
}
599-
finalized := big.NewInt(int64(rpc.FinalizedBlockNumber))
600-
if number.Cmp(finalized) == 0 {
601-
return "finalized"
598+
// It's negative.
599+
if number.IsInt64() {
600+
return rpc.BlockNumber(number.Int64()).String()
602601
}
603-
safe := big.NewInt(int64(rpc.SafeBlockNumber))
604-
if number.Cmp(safe) == 0 {
605-
return "safe"
606-
}
607-
return hexutil.EncodeBig(number)
602+
// It's negative and large, which is invalid.
603+
return fmt.Sprintf("<invalid %d>", number)
608604
}
609605

610606
func toCallArg(msg ethereum.CallMsg) interface{} {

ethclient/gethclient/gethclient.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package gethclient
2020
import (
2121
"context"
2222
"encoding/json"
23+
"fmt"
2324
"math/big"
2425
"runtime"
2526
"runtime/debug"
@@ -207,19 +208,15 @@ func toBlockNumArg(number *big.Int) string {
207208
if number == nil {
208209
return "latest"
209210
}
210-
pending := big.NewInt(-1)
211-
if number.Cmp(pending) == 0 {
212-
return "pending"
211+
if number.Sign() >= 0 {
212+
return hexutil.EncodeBig(number)
213213
}
214-
finalized := big.NewInt(int64(rpc.FinalizedBlockNumber))
215-
if number.Cmp(finalized) == 0 {
216-
return "finalized"
214+
// It's negative.
215+
if number.IsInt64() {
216+
return rpc.BlockNumber(number.Int64()).String()
217217
}
218-
safe := big.NewInt(int64(rpc.SafeBlockNumber))
219-
if number.Cmp(safe) == 0 {
220-
return "safe"
221-
}
222-
return hexutil.EncodeBig(number)
218+
// It's negative and large, which is invalid.
219+
return fmt.Sprintf("<invalid %d>", number)
223220
}
224221

225222
func toCallArg(msg ethereum.CallMsg) interface{} {

rpc/types.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ type BlockNumber int64
6565
const (
6666
SafeBlockNumber = BlockNumber(-4)
6767
FinalizedBlockNumber = BlockNumber(-3)
68-
PendingBlockNumber = BlockNumber(-2)
69-
LatestBlockNumber = BlockNumber(-1)
68+
LatestBlockNumber = BlockNumber(-2)
69+
PendingBlockNumber = BlockNumber(-1)
7070
EarliestBlockNumber = BlockNumber(0)
7171
)
7272

@@ -111,30 +111,38 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
111111
return nil
112112
}
113113

114+
// Int64 returns the block number as int64.
115+
func (bn BlockNumber) Int64() int64 {
116+
return (int64)(bn)
117+
}
118+
114119
// MarshalText implements encoding.TextMarshaler. It marshals:
115120
// - "safe", "finalized", "latest", "earliest" or "pending" as strings
116121
// - other numbers as hex
117122
func (bn BlockNumber) MarshalText() ([]byte, error) {
123+
return []byte(bn.String()), nil
124+
}
125+
126+
func (bn BlockNumber) String() string {
118127
switch bn {
119128
case EarliestBlockNumber:
120-
return []byte("earliest"), nil
129+
return "earliest"
121130
case LatestBlockNumber:
122-
return []byte("latest"), nil
131+
return "latest"
123132
case PendingBlockNumber:
124-
return []byte("pending"), nil
133+
return "pending"
125134
case FinalizedBlockNumber:
126-
return []byte("finalized"), nil
135+
return "finalized"
127136
case SafeBlockNumber:
128-
return []byte("safe"), nil
137+
return "safe"
129138
default:
130-
return hexutil.Uint64(bn).MarshalText()
139+
if bn < 0 {
140+
return fmt.Sprintf("<invalid %d>", bn)
141+
}
142+
return hexutil.Uint64(bn).String()
131143
}
132144
}
133145

134-
func (bn BlockNumber) Int64() int64 {
135-
return (int64)(bn)
136-
}
137-
138146
type BlockNumberOrHash struct {
139147
BlockNumber *BlockNumber `json:"blockNumber,omitempty"`
140148
BlockHash *common.Hash `json:"blockHash,omitempty"`

0 commit comments

Comments
 (0)