Skip to content

Commit a43767d

Browse files
authored
fix: close head tracker/broadcaster before balance monitor to prevent race (#425)
Reorder chain.Close() to stop event sources (headTracker, headBroadcaster) before event consumers (balanceMonitor). Previously, the balance monitor was closed while the head pipeline was still running, allowing headBroadcaster to deliver a last-second OnNewLongestChain that wakes the balance monitor's SleeperTask. When SleeperTask.Stop() then closes chStop, both chStop and chQueue are ready in the select — Go picks randomly, and 50% of the time runs one more Work() that calls BalanceAt on a torn-down mock client, triggering a data race detected by go_core_race_tests.
1 parent dbcbab4 commit a43767d

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

pkg/chains/legacyevm/chain.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -377,20 +377,26 @@ func (c *chain) Close() error {
377377
return c.StopOnce("Chain", func() (merr error) {
378378
c.logger.Debug("Chain: stopping")
379379

380+
// Stop event sources before consumers to prevent late delivery
381+
// (e.g. headBroadcaster calling balanceMonitor.OnNewLongestChain
382+
// after the balance monitor has stopped, causing a data race).
383+
380384
if c.logPoller != logpoller.LogPollerDisabled {
381385
merr = multierr.Append(merr, c.logPoller.Close())
382386
}
383387

384-
if c.balanceMonitor != nil {
385-
c.logger.Debug("Chain: stopping balance monitor")
386-
merr = c.balanceMonitor.Close()
387-
}
388388
c.logger.Debug("Chain: stopping logBroadcaster")
389389
merr = multierr.Combine(merr, c.logBroadcaster.Close())
390390
c.logger.Debug("Chain: stopping headTracker")
391391
merr = multierr.Combine(merr, c.headTracker.Close())
392392
c.logger.Debug("Chain: stopping headBroadcaster")
393393
merr = multierr.Combine(merr, c.headBroadcaster.Close())
394+
395+
if c.balanceMonitor != nil {
396+
c.logger.Debug("Chain: stopping balance monitor")
397+
merr = multierr.Combine(merr, c.balanceMonitor.Close())
398+
}
399+
394400
c.logger.Debug("Chain: stopping evmTxm")
395401
merr = multierr.Combine(merr, c.txm.Close())
396402

0 commit comments

Comments
 (0)