From bd42edee0b259fe616d0207b0e260df24c4492b1 Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Tue, 27 Jan 2026 11:16:24 +0800 Subject: [PATCH] eth/filters: fix error when blockHash is used with fromBlock/toBlock #31877 (#1962) --- eth/filters/api.go | 7 ++++ eth/filters/filter.go | 2 +- eth/filters/filter_system_test.go | 67 +++++++++++++++++++++++++------ 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/eth/filters/api.go b/eth/filters/api.go index 2ec5ff62a2..8a6effabdb 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -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 { diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 5de7039e2e..8a667b1dab 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -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) } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 6cb8896b46..d0bd4af73f 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -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) } } }