upgrade log filter

This commit is contained in:
maskpp 2024-09-20 18:38:18 +08:00
parent deb5c087c4
commit 3626e27973

View file

@ -19,13 +19,11 @@ package filters
import ( import (
"context" "context"
"errors" "errors"
"math/big"
"slices"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"math/big"
) )
// Filter can be used to retrieve and filter logs. // Filter can be used to retrieve and filter logs.
@ -306,15 +304,32 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) ([]*typ
} }
for i, log := range logs { for i, log := range logs {
// Copy log not to modify cache elements // Copy log not to modify cache elements
logcopy := *log logCopy := *log
logcopy.TxHash = body.Transactions[logcopy.TxIndex].Hash() logCopy.TxHash = body.Transactions[logCopy.TxIndex].Hash()
logs[i] = &logcopy logs[i] = &logCopy
} }
return logs, nil return logs, nil
} }
// filterLogs creates a slice of logs matching the given criteria. // filterLogs creates a slice of logs matching the given criteria.
func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log { func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log {
var (
addressMap = make(map[common.Address]struct{}, len(addresses))
topicMaps = make([]map[common.Hash]struct{}, len(topics))
)
for _, addr := range addresses {
addressMap[addr] = struct{}{}
}
for i, sub := range topics {
var topicMap map[common.Hash]struct{}
if len(sub) > 0 {
topicMap = make(map[common.Hash]struct{}, len(sub))
for _, topic := range sub {
topicMap[topic] = struct{}{}
}
}
topicMaps[i] = topicMap
}
var check = func(log *types.Log) bool { var check = func(log *types.Log) bool {
if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber { if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber {
return false return false
@ -322,24 +337,24 @@ func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []comm
if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber { if toBlock != nil && toBlock.Int64() >= 0 && toBlock.Uint64() < log.BlockNumber {
return false return false
} }
if len(addresses) > 0 && !slices.Contains(addresses, log.Address) { if _, ok := addressMap[log.Address]; !ok {
return false return false
} }
// If the to filtered topics is greater than the amount of topics in logs, skip. // If the to filtered topics is greater than the amount of topics in logs, skip.
if len(topics) > len(log.Topics) { if len(topicMaps) > len(log.Topics) {
return false return false
} }
for i, sub := range topics { for i, topicMap := range topicMaps {
if len(sub) == 0 { if topicMap == nil {
continue // empty rule set == wildcard continue // empty rule set == wildcard
} }
if !slices.Contains(sub, log.Topics[i]) { if _, ok := topicMap[log.Topics[i]]; !ok {
return false return false
} }
} }
return true return true
} }
var ret []*types.Log var ret = make([]*types.Log, 0, len(logs))
for _, log := range logs { for _, log := range logs {
if check(log) { if check(log) {
ret = append(ret, log) ret = append(ret, log)