From 1c223939446f5de0bfe2dbb3c3979925eb5c7e69 Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Thu, 3 Sep 2026 17:59:55 +0800 Subject: [PATCH] fix(core): keep blocksHashCache entries unique per height MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UpdateBlocksHashCache appended unconditionally, so refreshing the cache for a block that was already cached — which the known-block path now does when it promotes a stored block — grew the per-height slice with duplicate hashes. Skip the append when the hash is already tracked; distinct fork hashes at the same height are still kept. --- core/blockchain.go | 4 ++++ core/blockchain_test.go | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/core/blockchain.go b/core/blockchain.go index 54f5291c8895..134d494f437b 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 dc747e5e2190..d09b7e12e156 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.