From a5e68b9c525e8b5cc06315811fe090ac14b42a69 Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Fri, 31 Oct 2025 14:54:32 +0800 Subject: [PATCH] miner: not sleep if locks multiple mutex, close XFN-40 (#1639) --- miner/worker.go | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/miner/worker.go b/miner/worker.go index 13fa1c5b0c..316ab31d01 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -596,7 +596,7 @@ func abs(x int64) int64 { return x } -func (w *worker) commitNewWork() { +func (w *worker) checkPreCommitWithLock() (*types.Block, bool) { w.mu.Lock() defer w.mu.Unlock() w.uncleMu.Lock() @@ -604,8 +604,10 @@ func (w *worker) commitNewWork() { w.currentMu.Lock() defer w.currentMu.Unlock() - tstart := time.Now() + return w.checkPreCommit() +} +func (w *worker) checkPreCommit() (*types.Block, bool) { c := w.engine.(*XDPoS.XDPoS) var parent *types.Block if c != nil { @@ -614,12 +616,11 @@ func (w *worker) commitNewWork() { parent = w.chain.CurrentBlock() } - var signers map[common.Address]struct{} if parent.Hash().Hex() == w.lastParentBlockCommit { - return + return parent, true } if !w.announceTxs && atomic.LoadInt32(&w.mining) == 0 { - return + return parent, true } // Only try to commit new work if we are mining @@ -629,14 +630,24 @@ func (w *worker) commitNewWork() { ok, err := c.YourTurn(w.chain, parent.Header(), w.coinbase) if err != nil { log.Warn("Failed when trying to commit new work", "err", err) - return + return parent, true } if !ok { log.Info("Not my turn to commit block. Waiting...") - return + return parent, true } } } + + return parent, false +} + +func (w *worker) commitNewWork() { + parent, shouldReturn := w.checkPreCommitWithLock() + if shouldReturn { + return + } + tstart := time.Now() tstamp := tstart.Unix() if parent.Time() >= uint64(tstamp) { tstamp = int64(parent.Time() + 1) @@ -648,6 +659,18 @@ func (w *worker) commitNewWork() { time.Sleep(wait) } + w.mu.Lock() + defer w.mu.Unlock() + w.uncleMu.Lock() + defer w.uncleMu.Unlock() + w.currentMu.Lock() + defer w.currentMu.Unlock() + + parent, shouldReturn = w.checkPreCommit() + if shouldReturn { + return + } + num := parent.Number() header := &types.Header{ ParentHash: parent.Hash(), @@ -720,6 +743,7 @@ func (w *worker) commitNewWork() { log.Error("[commitNewWork] fail to check if block is epoch switch block when fetching pending transactions", "BlockNum", header.Number, "Hash", header.Hash()) } if !isEpochSwitchBlock { + var signers map[common.Address]struct{} pending := w.eth.TxPool().Pending(true) txs, specialTxs = types.NewTransactionsByPriceAndNonce(w.current.signer, pending, signers, feeCapacity) }