@@ -161,6 +161,21 @@ type worker struct {
161161 atWork int32
162162 announceTxs bool
163163 lastParentBlockCommit string
164+
165+ // last block number logged for XDPoS config/engine mismatch
166+ lastXDPoSMismatchBlock * big.Int
167+ }
168+
169+ func (w * worker ) lockAll () {
170+ w .mu .Lock ()
171+ w .uncleMu .Lock ()
172+ w .currentMu .Lock ()
173+ }
174+
175+ func (w * worker ) unlockAll () {
176+ w .currentMu .Unlock ()
177+ w .uncleMu .Unlock ()
178+ w .mu .Unlock ()
164179}
165180
166181func newWorker (config * params.ChainConfig , engine consensus.Engine , coinbase common.Address , eth Backend , mux * event.TypeMux , announceTxs bool ) * worker {
@@ -286,8 +301,12 @@ func (w *worker) update() {
286301
287302 // timeout waiting for v1 initial value
288303 minePeriod := 2
289- MinePeriodCh := w .engine .(* XDPoS.XDPoS ).MinePeriodCh
290- NewRoundCh := w .engine .(* XDPoS.XDPoS ).NewRoundCh
304+ var MinePeriodCh <- chan int
305+ var NewRoundCh <- chan types.Round
306+ if xdposEngine , ok := w .engine .(* XDPoS.XDPoS ); ok {
307+ MinePeriodCh = xdposEngine .MinePeriodCh
308+ NewRoundCh = xdposEngine .NewRoundCh
309+ }
291310
292311 timeout := time .NewTimer (time .Duration (minePeriod ) * time .Second )
293312 defer timeout .Stop ()
@@ -646,37 +665,41 @@ func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error {
646665 return nil
647666}
648667
649- // checkPreCommitWithLock checks whether a new work commit is needed with locks,
650- // returns the parent block and shouldReturn.
651- func (w * worker ) checkPreCommitWithLock () (* types.Block , bool ) {
652- w .mu .Lock ()
653- defer w .mu .Unlock ()
654- w .uncleMu .Lock ()
655- defer w .uncleMu .Unlock ()
656- w .currentMu .Lock ()
657- defer w .currentMu .Unlock ()
658-
659- return w .checkPreCommit ()
660- }
668+ // preCommitCheck checks whether a new work commit is needed.
669+ // If locked is false, the worker locks are acquired internally.
670+ // If locked is true, callers must already hold w.mu, w.uncleMu, and w.currentMu.
671+ func (w * worker ) preCommitCheck (locked bool ) (* types.Block , bool ) {
672+ if ! locked {
673+ w .lockAll ()
674+ defer w .unlockAll ()
675+ }
661676
662- // checkPreCommit checks whether a new work commit is needed,
663- // returns the parent block and shouldReturn.
664- func ( w * worker ) checkPreCommit () ( * types. Block , bool ) {
665- c := w . engine .( * XDPoS. XDPoS )
677+ var xdposEngine * XDPoS. XDPoS
678+ if engine , ok := w . engine .( * XDPoS. XDPoS ); ok {
679+ xdposEngine = engine
680+ }
666681 var parent * types.Block
667682 currentHeader := w .chain .CurrentBlock ()
668683 // Guard against nil header (early startup or uninitialised chain).
669684 if currentHeader == nil {
670685 return nil , true
671686 }
672- if c != nil {
673- parent = c .FindParentBlockToAssign (w .chain , currentHeader )
687+ if xdposEngine != nil {
688+ parent = xdposEngine .FindParentBlockToAssign (w .chain , currentHeader )
674689 } else {
675690 parent = w .chain .GetBlock (currentHeader .Hash (), currentHeader .Number .Uint64 ())
676691 }
677692 if parent == nil {
678693 return nil , true
679694 }
695+ if w .config .XDPoS != nil && xdposEngine == nil {
696+ blockNum := new (big.Int ).Set (parent .Number ())
697+ if w .lastXDPoSMismatchBlock == nil || blockNum .Cmp (w .lastXDPoSMismatchBlock ) > 0 {
698+ w .lastXDPoSMismatchBlock = blockNum
699+ log .Warn ("XDPoS config enabled but consensus engine is not XDPoS; skipping work commit" , "block" , blockNum )
700+ }
701+ return parent , true
702+ }
680703 if parent .Hash ().Hex () == w .lastParentBlockCommit {
681704 return parent , true
682705 }
@@ -687,8 +710,8 @@ func (w *worker) checkPreCommit() (*types.Block, bool) {
687710 // Only try to commit new work if we are mining
688711 if atomic .LoadInt32 (& w .mining ) == 1 {
689712 // check if we are right after parent's coinbase in the list
690- if w .config .XDPoS != nil {
691- ok , err := c .YourTurn (w .chain , parent .Header (), w .coinbase )
713+ if w .config .XDPoS != nil && xdposEngine != nil {
714+ ok , err := xdposEngine .YourTurn (w .chain , parent .Header (), w .coinbase )
692715 if err != nil {
693716 log .Warn ("Failed when trying to commit new work" , "err" , err )
694717 return parent , true
@@ -704,7 +727,7 @@ func (w *worker) checkPreCommit() (*types.Block, bool) {
704727}
705728
706729func (w * worker ) commitNewWork () {
707- parent , shouldReturn := w .checkPreCommitWithLock ( )
730+ parent , shouldReturn := w .preCommitCheck ( false )
708731 if parent == nil || shouldReturn {
709732 return
710733 }
@@ -720,14 +743,10 @@ func (w *worker) commitNewWork() {
720743 time .Sleep (wait )
721744 }
722745
723- w .mu .Lock ()
724- defer w .mu .Unlock ()
725- w .uncleMu .Lock ()
726- defer w .uncleMu .Unlock ()
727- w .currentMu .Lock ()
728- defer w .currentMu .Unlock ()
746+ w .lockAll ()
747+ defer w .unlockAll ()
729748
730- parent , shouldReturn = w .checkPreCommit ( )
749+ parent , shouldReturn = w .preCommitCheck ( true )
731750 if parent == nil || shouldReturn {
732751 return
733752 }
0 commit comments