diff --git a/core/types/log.go b/core/types/log.go index 0b83c60fdf6..df5073a4d5d 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -79,7 +79,7 @@ type ErigonLogs []*ErigonLog type Logs []*Log -func (logs Logs) Filter(addrMap map[libcommon.Address]struct{}, topics [][]libcommon.Hash) Logs { +func (logs Logs) Filter(addrMap map[libcommon.Address]struct{}, topics [][]libcommon.Hash, maxLogs uint64) Logs { topicMap := make(map[int]map[libcommon.Hash]struct{}, 7) //populate topic map @@ -93,6 +93,8 @@ func (logs Logs) Filter(addrMap map[libcommon.Address]struct{}, topics [][]libco } o := make(Logs, 0, len(logs)) + var logCount uint64 + logCount = 0 for _, v := range logs { // check address if addrMap is not empty if len(addrMap) != 0 { @@ -124,12 +126,19 @@ func (logs Logs) Filter(addrMap map[libcommon.Address]struct{}, topics [][]libco if found { o = append(o, v) } + + logCount += 1 + if maxLogs != 0 && logCount >= maxLogs { + break + } } return o } -func (logs Logs) CointainTopics(addrMap map[libcommon.Address]struct{}, topicsMap map[libcommon.Hash]struct{}) Logs { +func (logs Logs) CointainTopics(addrMap map[libcommon.Address]struct{}, topicsMap map[libcommon.Hash]struct{}, maxLogs uint64) Logs { o := make(Logs, 0, len(logs)) + var logCount uint64 + logCount = 0 for _, v := range logs { found := false @@ -154,6 +163,10 @@ func (logs Logs) CointainTopics(addrMap map[libcommon.Address]struct{}, topicsMa o = append(o, v) } } + logCount += 1 + if maxLogs != 0 && logCount >= maxLogs { + break + } } return o } diff --git a/core/types/log_test.go b/core/types/log_test.go index 38c11939834..2df0e6e9f4d 100644 --- a/core/types/log_test.go +++ b/core/types/log_test.go @@ -234,7 +234,7 @@ func TestFilterLogsTopics(t *testing.T) { }, } for name, v := range filterLogTests { - ares := testFLExtractAddress(v.input.Filter(map[libcommon.Address]struct{}{}, v.filter)) + ares := testFLExtractAddress(v.input.Filter(map[libcommon.Address]struct{}{}, v.filter, 0)) if !reflect.DeepEqual(ares, v.want) { t.Errorf("Fail %s, got %v want %v", name, ares, v.want) } diff --git a/turbo/jsonrpc/erigon_receipts.go b/turbo/jsonrpc/erigon_receipts.go index d213191cdfa..150a4fba60e 100644 --- a/turbo/jsonrpc/erigon_receipts.go +++ b/turbo/jsonrpc/erigon_receipts.go @@ -154,7 +154,7 @@ func (api *ErigonImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) log.Index = logIndex logIndex++ } - filtered := logs.Filter(addrMap, crit.Topics) + filtered := logs.Filter(addrMap, crit.Topics, 0) if len(filtered) == 0 { continue } @@ -324,10 +324,16 @@ func (api *ErigonImpl) GetLatestLogs(ctx context.Context, crit filters.FilterCri logIndex++ } var filtered types.Logs + var maxLogCount uint64 + maxLogCount = 0 + if logOptions.LogCount != 0 { + maxLogCount = logOptions.LogCount - logCount + } + if logOptions.IgnoreTopicsOrder { - filtered = logs.CointainTopics(addrMap, topicsMap) + filtered = logs.CointainTopics(addrMap, topicsMap, maxLogCount) } else { - filtered = logs.Filter(addrMap, crit.Topics) + filtered = logs.Filter(addrMap, crit.Topics, maxLogCount) } if len(filtered) == 0 { continue diff --git a/turbo/jsonrpc/eth_receipts.go b/turbo/jsonrpc/eth_receipts.go index c7ff94ca19d..6097a6194dc 100644 --- a/turbo/jsonrpc/eth_receipts.go +++ b/turbo/jsonrpc/eth_receipts.go @@ -358,7 +358,7 @@ func (api *APIImpl) getLogsV3(ctx context.Context, tx kv.TemporalTx, begin, end // log.Index = logIndex // logIndex++ //} - filtered := rawLogs.Filter(addrMap, crit.Topics) + filtered := rawLogs.Filter(addrMap, crit.Topics, 0) for _, log := range filtered { log.BlockNumber = blockNum log.BlockHash = blockHash diff --git a/turbo/jsonrpc/overlay_api.go b/turbo/jsonrpc/overlay_api.go index ade9c585da4..102b6ecaf4c 100644 --- a/turbo/jsonrpc/overlay_api.go +++ b/turbo/jsonrpc/overlay_api.go @@ -401,7 +401,7 @@ func filterLogs(logs types.Logs, addresses []common.Address, topics [][]common.H for _, v := range addresses { addrMap[v] = struct{}{} } - return logs.Filter(addrMap, topics) + return logs.Filter(addrMap, topics, 0) } func (api *OverlayAPIImpl) replayBlock(ctx context.Context, blockNum uint64, statedb *state.IntraBlockState, chainConfig *chain.Config, tx kv.Tx) ([]*types.Log, error) {