diff --git a/core/blockchain.go b/core/blockchain.go index 54f5291c889..134d494f437 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -22,6 +22,7 @@ import ( "fmt" "io" "math/big" + "slices" "strings" "sync" "sync/atomic" @@ -2309,6 +2310,9 @@ func (bc *BlockChain) UpdateBlocksHashCache(block *types.Block) []common.Hash { cached, ok := bc.blocksHashCache.Get(blockNumber) if ok { + if slices.Contains(cached, block.Hash()) { + return cached + } hashArr := cached hashArr = append(hashArr, block.Hash()) bc.blocksHashCache.Remove(blockNumber) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index dc747e5e219..d09b7e12e15 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -2495,6 +2495,22 @@ func TestBlocksHashCacheUpdate(t *testing.T) { t.Error("BlocksHashCache doesn't work when inserting block solely") } }) + + t.Run("Expect repeated cache update to keep one entry per hash", func(t *testing.T) { + head := chain.CurrentBlock() + chain.UpdateBlocksHashCache(types.NewBlockWithHeader(head)) + chain.UpdateBlocksHashCache(types.NewBlockWithHeader(head)) + cached, _ := chain.blocksHashCache.Get(head.Number.Uint64()) + count := 0 + for _, hash := range cached { + if hash == head.Hash() { + count++ + } + } + if count != 1 { + t.Errorf("BlocksHashCache has %d entries for head hash, want 1: %v", count, cached) + } + }) } // TestAreTwoBlocksSamePath tests are two blocks same path.