From 54d7bd9a2131ea5139f0be93fae888e40dcd326d Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 22 Oct 2024 10:15:51 +0700 Subject: [PATCH] `RecentLogs` prevent grow over `limit` (#12386) --- turbo/shards/events.go | 21 ++++++++++++-- turbo/shards/events_test.go | 55 +++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 turbo/shards/events_test.go diff --git a/turbo/shards/events.go b/turbo/shards/events.go index dff2c7e8c12..53a1b19b18c 100644 --- a/turbo/shards/events.go +++ b/turbo/shards/events.go @@ -243,11 +243,28 @@ func (r *RecentLogs) Add(receipts types.Receipts) { } r.mu.Lock() defer r.mu.Unlock() + var blockNum uint64 + var ok bool // find non-nil receipt for _, receipt := range receipts { if receipt != nil { - r.receipts[receipts[0].BlockNumber.Uint64()] = receipts - return + ok = true + blockNum = receipt.BlockNumber.Uint64() + break + } + } + if !ok { + return + } + r.receipts[blockNum] = receipts + + //enforce `limit`: drop all items older than `limit` blocks + if len(r.receipts) <= int(r.limit) { + return + } + for bn := range r.receipts { + if bn+r.limit < blockNum { + delete(r.receipts, bn) } } } diff --git a/turbo/shards/events_test.go b/turbo/shards/events_test.go new file mode 100644 index 00000000000..356d37b5b4f --- /dev/null +++ b/turbo/shards/events_test.go @@ -0,0 +1,55 @@ +// Copyright 2024 The Erigon Authors +// This file is part of Erigon. +// +// Erigon is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Erigon is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with Erigon. If not, see . + +package shards + +import ( + "math/big" + "testing" + + "github.com/erigontech/erigon/core/types" + "github.com/stretchr/testify/require" +) + +func TestRecentLogs(t *testing.T) { + t.Parallel() + t.Run("Evict", func(t *testing.T) { + e := NewRecentLogs(3) + e.Add(types.Receipts{{BlockNumber: big.NewInt(1)}}) + e.Add(types.Receipts{{BlockNumber: big.NewInt(11)}}) + e.Add(types.Receipts{{BlockNumber: big.NewInt(21)}}) + require.Equal(t, 3, len(e.receipts)) + + e.Add(types.Receipts{{BlockNumber: big.NewInt(31)}}) + require.Equal(t, 1, len(e.receipts)) + }) + t.Run("Nil", func(t *testing.T) { + e := NewRecentLogs(3) + e.Add(types.Receipts{nil, {BlockNumber: big.NewInt(1)}}) + e.Add(types.Receipts{{BlockNumber: big.NewInt(21)}, nil}) + e.Add(types.Receipts{nil, nil, {BlockNumber: big.NewInt(31)}}) + require.Equal(t, 3, len(e.receipts)) + }) + t.Run("Order", func(t *testing.T) { + e := NewRecentLogs(3) + e.Add(types.Receipts{{BlockNumber: big.NewInt(1)}}) + e.Add(types.Receipts{{BlockNumber: big.NewInt(11)}}) + e.Add(types.Receipts{{BlockNumber: big.NewInt(1)}}) + require.Equal(t, 2, len(e.receipts)) + e.Add(types.Receipts{{BlockNumber: big.NewInt(11)}}) + require.Equal(t, 2, len(e.receipts)) + }) +}