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 <fjl@twurst.com>
This commit is contained in:
parent
1a18283e85
commit
9231770811
@ -56,7 +56,7 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
|
||||
|
||||
// from, to block number
|
||||
var test1 FilterCriteria
|
||||
vector := fmt.Sprintf(`{"fromBlock":"%#x","toBlock":"%#x"}`, fromBlock, toBlock)
|
||||
vector := fmt.Sprintf(`{"fromBlock":"%v","toBlock":"%v"}`, fromBlock, toBlock)
|
||||
if err := json.Unmarshal([]byte(vector), &test1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -296,6 +296,9 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) ([]*typ
|
||||
// pendingLogs returns the logs matching the filter criteria within the pending block.
|
||||
func (f *Filter) pendingLogs() ([]*types.Log, error) {
|
||||
block, receipts := f.sys.backend.PendingBlockAndReceipts()
|
||||
if block == nil {
|
||||
return nil, errors.New("pending state not available")
|
||||
}
|
||||
if bloomFilter(block.Bloom(), f.addresses, f.topics) {
|
||||
var unfiltered []*types.Log
|
||||
for _, r := range receipts {
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
func makeReceipt(addr common.Address) *types.Receipt {
|
||||
@ -179,7 +180,7 @@ func TestFilters(t *testing.T) {
|
||||
// Set block 998 as Finalized (-3)
|
||||
rawdb.WriteFinalizedBlockHash(db, chain[998].Hash())
|
||||
|
||||
filter := sys.NewRangeFilter(0, -1, []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
|
||||
filter := sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{addr}, [][]common.Hash{{hash1, hash2, hash3, hash4}})
|
||||
logs, _ := filter.Logs(context.Background())
|
||||
if len(logs) != 4 {
|
||||
t.Error("expected 4 log, got", len(logs))
|
||||
@ -193,34 +194,36 @@ func TestFilters(t *testing.T) {
|
||||
sys.NewRangeFilter(900, 999, []common.Address{addr}, [][]common.Hash{{hash3}}),
|
||||
[]common.Hash{hash3},
|
||||
}, {
|
||||
sys.NewRangeFilter(990, -1, []common.Address{addr}, [][]common.Hash{{hash3}}),
|
||||
sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{addr}, [][]common.Hash{{hash3}}),
|
||||
[]common.Hash{hash3},
|
||||
}, {
|
||||
sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}),
|
||||
[]common.Hash{hash1, hash2},
|
||||
}, {
|
||||
sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
|
||||
sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
|
||||
nil,
|
||||
}, {
|
||||
sys.NewRangeFilter(0, -1, []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
|
||||
sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
|
||||
nil,
|
||||
}, {
|
||||
sys.NewRangeFilter(0, -1, nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
|
||||
sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
|
||||
nil,
|
||||
}, {
|
||||
sys.NewRangeFilter(-1, -1, nil, nil), []common.Hash{hash4},
|
||||
sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), []common.Hash{hash4},
|
||||
}, {
|
||||
sys.NewRangeFilter(-3, -1, nil, nil), []common.Hash{hash3, hash4},
|
||||
sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), []common.Hash{hash3, hash4},
|
||||
}, {
|
||||
sys.NewRangeFilter(-3, -3, nil, nil), []common.Hash{hash3},
|
||||
sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), []common.Hash{hash3},
|
||||
}, {
|
||||
sys.NewRangeFilter(-1, -3, nil, nil), nil,
|
||||
sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), nil,
|
||||
}, {
|
||||
sys.NewRangeFilter(-4, -1, nil, nil), nil,
|
||||
sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), nil,
|
||||
}, {
|
||||
sys.NewRangeFilter(-4, -4, nil, nil), nil,
|
||||
sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), nil,
|
||||
}, {
|
||||
sys.NewRangeFilter(-1, -4, nil, nil), nil,
|
||||
sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), nil,
|
||||
}, {
|
||||
sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), nil,
|
||||
},
|
||||
} {
|
||||
logs, _ := tc.f.Logs(context.Background())
|
||||
|
@ -592,20 +592,16 @@ func toBlockNumArg(number *big.Int) string {
|
||||
if number == nil {
|
||||
return "latest"
|
||||
}
|
||||
pending := big.NewInt(-1)
|
||||
if number.Cmp(pending) == 0 {
|
||||
return "pending"
|
||||
}
|
||||
finalized := big.NewInt(int64(rpc.FinalizedBlockNumber))
|
||||
if number.Cmp(finalized) == 0 {
|
||||
return "finalized"
|
||||
}
|
||||
safe := big.NewInt(int64(rpc.SafeBlockNumber))
|
||||
if number.Cmp(safe) == 0 {
|
||||
return "safe"
|
||||
}
|
||||
if number.Sign() >= 0 {
|
||||
return hexutil.EncodeBig(number)
|
||||
}
|
||||
// It's negative.
|
||||
if number.IsInt64() {
|
||||
return rpc.BlockNumber(number.Int64()).String()
|
||||
}
|
||||
// It's negative and large, which is invalid.
|
||||
return fmt.Sprintf("<invalid %d>", number)
|
||||
}
|
||||
|
||||
func toCallArg(msg ethereum.CallMsg) interface{} {
|
||||
arg := map[string]interface{}{
|
||||
|
@ -20,6 +20,7 @@ package gethclient
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
@ -207,20 +208,16 @@ func toBlockNumArg(number *big.Int) string {
|
||||
if number == nil {
|
||||
return "latest"
|
||||
}
|
||||
pending := big.NewInt(-1)
|
||||
if number.Cmp(pending) == 0 {
|
||||
return "pending"
|
||||
}
|
||||
finalized := big.NewInt(int64(rpc.FinalizedBlockNumber))
|
||||
if number.Cmp(finalized) == 0 {
|
||||
return "finalized"
|
||||
}
|
||||
safe := big.NewInt(int64(rpc.SafeBlockNumber))
|
||||
if number.Cmp(safe) == 0 {
|
||||
return "safe"
|
||||
}
|
||||
if number.Sign() >= 0 {
|
||||
return hexutil.EncodeBig(number)
|
||||
}
|
||||
// It's negative.
|
||||
if number.IsInt64() {
|
||||
return rpc.BlockNumber(number.Int64()).String()
|
||||
}
|
||||
// It's negative and large, which is invalid.
|
||||
return fmt.Sprintf("<invalid %d>", number)
|
||||
}
|
||||
|
||||
func toCallArg(msg ethereum.CallMsg) interface{} {
|
||||
arg := map[string]interface{}{
|
||||
|
44
rpc/types.go
44
rpc/types.go
@ -65,8 +65,8 @@ type BlockNumber int64
|
||||
const (
|
||||
SafeBlockNumber = BlockNumber(-4)
|
||||
FinalizedBlockNumber = BlockNumber(-3)
|
||||
PendingBlockNumber = BlockNumber(-2)
|
||||
LatestBlockNumber = BlockNumber(-1)
|
||||
LatestBlockNumber = BlockNumber(-2)
|
||||
PendingBlockNumber = BlockNumber(-1)
|
||||
EarliestBlockNumber = BlockNumber(0)
|
||||
)
|
||||
|
||||
@ -111,28 +111,36 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int64 returns the block number as int64.
|
||||
func (bn BlockNumber) Int64() int64 {
|
||||
return (int64)(bn)
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler. It marshals:
|
||||
// - "safe", "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 FinalizedBlockNumber:
|
||||
return []byte("finalized"), nil
|
||||
case SafeBlockNumber:
|
||||
return []byte("safe"), nil
|
||||
default:
|
||||
return hexutil.Uint64(bn).MarshalText()
|
||||
}
|
||||
return []byte(bn.String()), nil
|
||||
}
|
||||
|
||||
func (bn BlockNumber) Int64() int64 {
|
||||
return (int64)(bn)
|
||||
func (bn BlockNumber) String() string {
|
||||
switch bn {
|
||||
case EarliestBlockNumber:
|
||||
return "earliest"
|
||||
case LatestBlockNumber:
|
||||
return "latest"
|
||||
case PendingBlockNumber:
|
||||
return "pending"
|
||||
case FinalizedBlockNumber:
|
||||
return "finalized"
|
||||
case SafeBlockNumber:
|
||||
return "safe"
|
||||
default:
|
||||
if bn < 0 {
|
||||
return fmt.Sprintf("<invalid %d>", bn)
|
||||
}
|
||||
return hexutil.Uint64(bn).String()
|
||||
}
|
||||
}
|
||||
|
||||
type BlockNumberOrHash struct {
|
||||
|
Loading…
Reference in New Issue
Block a user