Skip to content

Commit 9a00f9a

Browse files
Giulio2002claude
andauthored
[SharovBot] Fix data race on bheapCache in db/rawdb (#19606)
**[SharovBot]** ## Summary - Fix DATA RACE between `TestBlockStorage` and `TestBadBlocks` in `db/rawdb` - Add `sync.RWMutex` to protect concurrent access to the package-level `bheapCache` variable - The variable was being read in `TruncateCanonicalHash` and written in `ResetBadBlockCache` without synchronization ## Test plan - [x] `go test -race ./db/rawdb/... -run "TestBlockStorage|TestBadBlocks" -count=3` passes with no DATA RACE - [x] `go build ./...` passes - [x] No test files modified 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b8a1590 commit 9a00f9a

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

db/rawdb/accessors_chain.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"encoding/binary"
2727
"fmt"
2828
"math/big"
29+
"sync"
2930
"time"
3031

3132
"github.com/erigontech/erigon/common"
@@ -77,9 +78,11 @@ func TruncateCanonicalHash(tx kv.RwTx, blockFrom uint64, markChainAsBad bool) er
7778
return err
7879
}
7980

81+
bheapMu.Lock()
8082
if bheapCache != nil {
8183
heap.Push(bheapCache, &utils.BlockId{Number: binary.BigEndian.Uint64(blockNumBytes), Hash: common.BytesToHash(blockHash)})
8284
}
85+
bheapMu.Unlock()
8386
}
8487
return tx.Delete(kv.HeaderCanonical, blockNumBytes)
8588
}); err != nil {
@@ -89,14 +92,24 @@ func TruncateCanonicalHash(tx kv.RwTx, blockFrom uint64, markChainAsBad bool) er
8992
}
9093

9194
/* latest bad blocks start */
92-
var bheapCache utils.ExtendedHeap
95+
var (
96+
bheapCache utils.ExtendedHeap
97+
bheapMu sync.RWMutex
98+
)
9399

94100
func GetLatestBadBlocks(tx kv.Tx) ([]*types.Block, error) {
95-
if bheapCache == nil {
101+
bheapMu.RLock()
102+
needsInit := bheapCache == nil
103+
bheapMu.RUnlock()
104+
105+
if needsInit {
96106
ResetBadBlockCache(tx, 100)
97107
}
98108

109+
bheapMu.RLock()
99110
blockIds := bheapCache.SortedValues()
111+
bheapMu.RUnlock()
112+
100113
blocks := make([]*types.Block, len(blockIds))
101114
for i, blockId := range blockIds {
102115
blocks[i] = ReadBlock(tx, blockId.Hash, blockId.Number)
@@ -107,10 +120,14 @@ func GetLatestBadBlocks(tx kv.Tx) ([]*types.Block, error) {
107120

108121
// mainly for testing purposes
109122
func ResetBadBlockCache(tx kv.Tx, limit int) error {
123+
bheapMu.Lock()
110124
bheapCache = utils.NewBlockMaxHeap(limit)
125+
bheapMu.Unlock()
111126
// load the heap
112127
return tx.ForEach(kv.BadHeaderNumber, nil, func(blockHash, blockNumBytes []byte) error {
128+
bheapMu.Lock()
113129
heap.Push(bheapCache, &utils.BlockId{Number: binary.BigEndian.Uint64(blockNumBytes), Hash: common.BytesToHash(blockHash)})
130+
bheapMu.Unlock()
114131
return nil
115132
})
116133
}

0 commit comments

Comments
 (0)