eth/filters: fix error when blockHash is used with fromBlock/toBlock #31877 (#1962)

This commit is contained in:
Daniel Liu 2026-01-27 11:16:24 +08:00 committed by GitHub
parent 5811eb69ce
commit bd42edee0b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 62 additions and 14 deletions

View file

@ -36,6 +36,8 @@ var (
errInvalidTopic = errors.New("invalid topic(s)")
errFilterNotFound = errors.New("filter not found")
errInvalidBlockRange = errors.New("invalid block range params")
errUnknownBlock = errors.New("unknown block")
errBlockHashWithRange = errors.New("can't specify fromBlock/toBlock with blockHash")
errExceedMaxTopics = errors.New("exceed max topics")
errExceedMaxAddresses = errors.New("exceed max addresses")
)
@ -345,6 +347,10 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
var filter *Filter
if crit.BlockHash != nil {
if crit.FromBlock != nil || crit.ToBlock != nil {
return nil, errBlockHashWithRange
}
// Block filter requested, construct a single-shot filter
filter = api.sys.NewBlockFilter(*crit.BlockHash, crit.Addresses, crit.Topics)
} else {
@ -363,6 +369,7 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type
// Construct the range filter
filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics)
}
// Run the filter and return all the logs
logs, err := filter.Logs(ctx)
if err != nil {

View file

@ -102,7 +102,7 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) {
return nil, err
}
if header == nil {
return nil, errors.New("unknown block")
return nil, errUnknownBlock
}
return f.blockLogs(ctx, header)
}

View file

@ -34,6 +34,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/bloombits"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/event"
@ -368,24 +369,64 @@ func TestInvalidGetLogsRequest(t *testing.T) {
t.Parallel()
var (
db = rawdb.NewMemoryDatabase()
_, sys = newTestFilterSystem(t, db, Config{})
api = NewFilterAPI(sys, false)
blockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
genesis = &core.Genesis{
Config: params.TestChainConfig,
BaseFee: big.NewInt(params.InitialBaseFee),
}
db, blocks, _ = core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 10, func(i int, gen *core.BlockGen) {})
_, sys = newTestFilterSystem(t, db, Config{})
api = NewFilterAPI(sys, false)
blockHash = blocks[0].Hash()
unknownBlockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
)
// Reason: Cannot specify both BlockHash and FromBlock/ToBlock)
testCases := []FilterCriteria{
0: {BlockHash: &blockHash, FromBlock: big.NewInt(100)},
1: {BlockHash: &blockHash, ToBlock: big.NewInt(500)},
2: {BlockHash: &blockHash, FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64())},
3: {BlockHash: &blockHash, Topics: [][]common.Hash{{}, {}, {}, {}, {}}},
4: {BlockHash: &blockHash, Addresses: make([]common.Address, maxAddresses+1)},
// Insert the blocks into the chain so filter can look them up
blockchain, err := core.NewBlockChain(db, nil, genesis.Config, ethash.NewFaker(), vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
if n, err := blockchain.InsertChain(blocks); err != nil {
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 {
if _, err := api.GetLogs(context.Background(), test); err == nil {
t.Errorf("Expected Logs for case #%d to fail", i)
_, err := api.GetLogs(context.Background(), test.f)
if !errors.Is(err, test.err) {
t.Errorf("case %d: wrong error: %q\nwant: %q", i, err, test.err)
}
}
}