From c241fc3574dafd7ff80ebed5f3cef093239b4247 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Tue, 14 Jan 2025 10:56:14 +0800 Subject: [PATCH] eth/filters: fix for eth_getLogs failing with tag (#25922) --- accounts/abi/bind/backends/simulated.go | 27 +++++++++++++++++--- eth/filters/filter.go | 33 +++++++++++++++++++------ eth/filters/filter_system_test.go | 13 +++++++--- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 9a71791da7..0e77a27b24 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -895,11 +895,32 @@ type filterBackend struct { func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } -func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { - if block == rpc.LatestBlockNumber { +func (fb *filterBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { + switch number { + case rpc.PendingBlockNumber: + if block := fb.backend.pendingBlock; block != nil { + return block.Header(), nil + } + return nil, nil + case rpc.LatestBlockNumber: return fb.bc.CurrentHeader(), nil + case rpc.CommittedBlockNumber: + if fb.bc.Config().XDPoS == nil { + return nil, errors.New("only XDPoS v2 supports committed block lookup") + } + current := fb.bc.CurrentBlock().Header() + if fb.bc.Config().XDPoS.BlockConsensusVersion( + current.Number, + current.Extra, + XDPoS.ExtraFieldCheck, + ) == params.ConsensusEngineVersion2 { + confirmedHash := fb.bc.Engine().(*XDPoS.XDPoS).EngineV2.GetLatestCommittedBlockInfo().Hash + return fb.bc.GetHeaderByHash(confirmedHash), nil + } + return nil, errors.New("only XDPoS v2 can lookup committed block") + default: + return fb.bc.GetHeaderByNumber(uint64(number.Int64())), nil } - return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil } func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 3defe854f8..3479860b2b 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -119,20 +119,39 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return nil, nil } var ( - head = header.Number.Uint64() - end = uint64(f.end) + err error + head = header.Number.Int64() pending = f.end == rpc.PendingBlockNumber.Int64() ) - if f.begin == rpc.LatestBlockNumber.Int64() { - f.begin = int64(head) + resolveSpecial := func(number int64) (int64, error) { + var hdr *types.Header + switch number { + case rpc.LatestBlockNumber.Int64(): + return head, nil + case rpc.PendingBlockNumber.Int64(): + // we should return head here since we've already captured + // that we need to get the pending logs in the pending boolean above + return head, nil + case rpc.CommittedBlockNumber.Int64(): + hdr, _ = f.sys.backend.HeaderByNumber(ctx, rpc.CommittedBlockNumber) + if hdr == nil { + return 0, errors.New("committed header not found") + } + default: + return number, nil + } + return hdr.Number.Int64(), nil } - if f.end == rpc.LatestBlockNumber.Int64() || f.end == rpc.PendingBlockNumber.Int64() { - end = head + if f.begin, err = resolveSpecial(f.begin); err != nil { + return nil, err + } + if f.end, err = resolveSpecial(f.end); err != nil { + return nil, err } // Gather all indexed logs, and finish with non indexed ones var ( logs []*types.Log - err error + end = uint64(f.end) size, sections = f.sys.backend.BloomStatus() ) if indexed := sections * size; indexed > uint64(f.begin) { diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index b3b07243e0..0aa3e12949 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -57,16 +57,21 @@ func (b *testBackend) ChainDb() ethdb.Database { } func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { - var hash common.Hash - var num uint64 - if blockNr == rpc.LatestBlockNumber { + var ( + hash common.Hash + num uint64 + ) + switch blockNr { + case rpc.LatestBlockNumber: hash = rawdb.ReadHeadBlockHash(b.db) number := rawdb.ReadHeaderNumber(b.db, hash) if number == nil { return nil, nil } num = *number - } else { + case rpc.CommittedBlockNumber: + return nil, nil + default: num = uint64(blockNr) hash = rawdb.ReadCanonicalHash(b.db, num) }