mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-18 05:56:37 +00:00
eth/filters: fix error when blockHash is used with fromBlock/toBlock (#31877)
This introduces an error when the filter has both `blockHash` and `fromBlock`/`toBlock`, since these are mutually exclusive. Seems the tests were actually returning `not found` error, which went undetected since there was no check on the actual returned error in the test.
This commit is contained in:
parent
9c58810e71
commit
038ff766ff
3 changed files with 63 additions and 14 deletions
|
|
@ -38,6 +38,8 @@ var (
|
||||||
errInvalidTopic = errors.New("invalid topic(s)")
|
errInvalidTopic = errors.New("invalid topic(s)")
|
||||||
errFilterNotFound = errors.New("filter not found")
|
errFilterNotFound = errors.New("filter not found")
|
||||||
errInvalidBlockRange = errors.New("invalid block range params")
|
errInvalidBlockRange = errors.New("invalid block range params")
|
||||||
|
errUnknownBlock = errors.New("unknown block")
|
||||||
|
errBlockHashWithRange = errors.New("can't specify fromBlock/toBlock with blockHash")
|
||||||
errPendingLogsUnsupported = errors.New("pending logs are not supported")
|
errPendingLogsUnsupported = errors.New("pending logs are not supported")
|
||||||
errExceedMaxTopics = errors.New("exceed max topics")
|
errExceedMaxTopics = errors.New("exceed max topics")
|
||||||
errExceedMaxAddresses = errors.New("exceed max addresses")
|
errExceedMaxAddresses = errors.New("exceed max addresses")
|
||||||
|
|
@ -348,8 +350,13 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
|
||||||
if len(crit.Addresses) > maxAddresses {
|
if len(crit.Addresses) > maxAddresses {
|
||||||
return nil, errExceedMaxAddresses
|
return nil, errExceedMaxAddresses
|
||||||
}
|
}
|
||||||
|
|
||||||
var filter *Filter
|
var filter *Filter
|
||||||
if crit.BlockHash != nil {
|
if crit.BlockHash != nil {
|
||||||
|
if crit.FromBlock != nil || crit.ToBlock != nil {
|
||||||
|
return nil, errBlockHashWithRange
|
||||||
|
}
|
||||||
|
|
||||||
// Block filter requested, construct a single-shot filter
|
// Block filter requested, construct a single-shot filter
|
||||||
filter = api.sys.NewBlockFilter(*crit.BlockHash, crit.Addresses, crit.Topics)
|
filter = api.sys.NewBlockFilter(*crit.BlockHash, crit.Addresses, crit.Topics)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -372,6 +379,7 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
|
||||||
// Construct the range filter
|
// Construct the range filter
|
||||||
filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics)
|
filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the filter and return all the logs
|
// Run the filter and return all the logs
|
||||||
logs, err := filter.Logs(ctx)
|
logs, err := filter.Logs(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if header == nil {
|
if header == nil {
|
||||||
return nil, errors.New("unknown block")
|
return nil, errUnknownBlock
|
||||||
}
|
}
|
||||||
if header.Number.Uint64() < f.sys.backend.HistoryPruningCutoff() {
|
if header.Number.Uint64() < f.sys.backend.HistoryPruningCutoff() {
|
||||||
return nil, &history.PrunedHistoryError{}
|
return nil, &history.PrunedHistoryError{}
|
||||||
|
|
|
||||||
|
|
@ -450,24 +450,65 @@ func TestInvalidGetLogsRequest(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
db = rawdb.NewMemoryDatabase()
|
genesis = &core.Genesis{
|
||||||
_, sys = newTestFilterSystem(db, Config{})
|
Config: params.TestChainConfig,
|
||||||
api = NewFilterAPI(sys)
|
BaseFee: big.NewInt(params.InitialBaseFee),
|
||||||
blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
|
}
|
||||||
|
db, blocks, _ = core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 10, func(i int, gen *core.BlockGen) {})
|
||||||
|
_, sys = newTestFilterSystem(db, Config{})
|
||||||
|
api = NewFilterAPI(sys)
|
||||||
|
blockHash = blocks[0].Hash()
|
||||||
|
unknownBlockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Reason: Cannot specify both BlockHash and FromBlock/ToBlock)
|
// Insert the blocks into the chain so filter can look them up
|
||||||
testCases := []FilterCriteria{
|
blockchain, err := core.NewBlockChain(db, genesis, ethash.NewFaker(), nil)
|
||||||
0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)},
|
if err != nil {
|
||||||
1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)},
|
t.Fatalf("failed to create tester chain: %v", err)
|
||||||
2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
|
}
|
||||||
3: {BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
|
if n, err := blockchain.InsertChain(blocks); err != nil {
|
||||||
4: {BlockHash: &blockHash, Addresses: make([]common.Address, maxAddresses+1)},
|
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type testcase struct {
|
||||||
|
f FilterCriteria
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
testCases := []testcase{
|
||||||
|
{
|
||||||
|
f: FilterCriteria{BlockHash: &blockHash, FromBlock: big.NewInt(100)},
|
||||||
|
err: errBlockHashWithRange,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f: FilterCriteria{BlockHash: &blockHash, ToBlock: big.NewInt(500)},
|
||||||
|
err: errBlockHashWithRange,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f: FilterCriteria{BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
|
||||||
|
err: errBlockHashWithRange,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f: FilterCriteria{BlockHash: &unknownBlockHash},
|
||||||
|
err: errUnknownBlock,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f: FilterCriteria{BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
|
||||||
|
err: errExceedMaxTopics,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f: FilterCriteria{BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
|
||||||
|
err: errExceedMaxTopics,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
f: FilterCriteria{BlockHash: &blockHash, Addresses: make([]common.Address, maxAddresses+1)},
|
||||||
|
err: errExceedMaxAddresses,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range testCases {
|
for i, test := range testCases {
|
||||||
if _, err := api.GetLogs(context.Background(), test); err == nil {
|
_, err := api.GetLogs(context.Background(), test.f)
|
||||||
t.Errorf("Expected Logs for case #%d to fail", i)
|
if !errors.Is(err, test.err) {
|
||||||
|
t.Errorf("case %d: wrong error: %q\nwant: %q", i, err, test.err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue