From 202e35e79aebbf1e28a80289eaba16dd790b164a Mon Sep 17 00:00:00 2001 From: rayoo Date: Mon, 20 Apr 2026 11:49:44 +0800 Subject: [PATCH] core/txpool/locals: fix data race on journal writer The journal.setupWriter and journal.close calls in TxTracker.loop are not protected by tracker.mu, while recheck and TrackAll access journal.writer under the same mutex. This causes a data race between the loop goroutine and callers of recheck/TrackAll. Hold tracker.mu around setupWriter and close in loop to synchronize access to journal.writer. Fixes a race detected by go test -race: Write at journal.setupWriter (journal.go:134) by goroutine running TxTracker.loop Previous read at journal.rotate (journal.go:154) by goroutine running TxTracker.recheck --- core/txpool/locals/tx_tracker.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core/txpool/locals/tx_tracker.go b/core/txpool/locals/tx_tracker.go index bb178f175e..6809a7165c 100644 --- a/core/txpool/locals/tx_tracker.go +++ b/core/txpool/locals/tx_tracker.go @@ -195,12 +195,21 @@ func (tracker *TxTracker) loop() { return nil }) - // Setup the writer for the upcoming transactions - if err := tracker.journal.setupWriter(); err != nil { + // Setup the writer for the upcoming transactions. + // Hold the mutex to avoid racing with recheck/TrackAll + // which also access journal.writer. + tracker.mu.Lock() + err := tracker.journal.setupWriter() + tracker.mu.Unlock() + if err != nil { log.Error("Failed to setup the journal writer", "err", err) return } - defer tracker.journal.close() + defer func() { + tracker.mu.Lock() + tracker.journal.close() + tracker.mu.Unlock() + }() } var ( lastJournal = time.Now()