From ee120ef865e9468fef0bbb0a0bcffba93e3e358e Mon Sep 17 00:00:00 2001
From: Marius van der Wijden <m.vanderwijden@live.de>
Date: Fri, 8 Oct 2021 20:12:52 +0200
Subject: [PATCH] miner: fix data race during shutdown (#23435)

This fixes a data race on worker.current by moving the call to StopPrefetcher
into the main loop.

The commit also contains fixes for two other races in unit tests of unrelated packages.
---
 eth/gasprice/gasprice_test.go | 2 +-
 eth/handler_eth_test.go       | 1 -
 miner/worker.go               | 8 +++++---
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go
index feecfddec..ced9010bc 100644
--- a/eth/gasprice/gasprice_test.go
+++ b/eth/gasprice/gasprice_test.go
@@ -151,7 +151,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke
 	// Construct testing chain
 	diskdb := rawdb.NewMemoryDatabase()
 	gspec.Commit(diskdb)
-	chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
+	chain, err := core.NewBlockChain(diskdb, &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec.Config, engine, vm.Config{}, nil, nil)
 	if err != nil {
 		t.Fatalf("Failed to create local chain, %v", err)
 	}
diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go
index 039091244..b8db5039c 100644
--- a/eth/handler_eth_test.go
+++ b/eth/handler_eth_test.go
@@ -486,7 +486,6 @@ func TestCheckpointChallenge(t *testing.T) {
 }
 
 func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpoint bool, timeout bool, empty bool, match bool, drop bool) {
-	t.Parallel()
 
 	// Reduce the checkpoint handshake challenge timeout
 	defer func(old time.Duration) { syncChallengeTimeout = old }(syncChallengeTimeout)
diff --git a/miner/worker.go b/miner/worker.go
index f4c901e18..8a34ac117 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -321,9 +321,6 @@ func (w *worker) isRunning() bool {
 // close terminates all background threads maintained by the worker.
 // Note the worker does not support being closed multiple times.
 func (w *worker) close() {
-	if w.current != nil && w.current.state != nil {
-		w.current.state.StopPrefetcher()
-	}
 	atomic.StoreInt32(&w.running, 0)
 	close(w.exitCh)
 	w.wg.Wait()
@@ -455,6 +452,11 @@ func (w *worker) mainLoop() {
 	defer w.txsSub.Unsubscribe()
 	defer w.chainHeadSub.Unsubscribe()
 	defer w.chainSideSub.Unsubscribe()
+	defer func() {
+		if w.current != nil && w.current.state != nil {
+			w.current.state.StopPrefetcher()
+		}
+	}()
 
 	for {
 		select {
-- 
GitLab