@@ -77,7 +77,12 @@ const (
7777 intervalAdjustBias = 200 * 1000.0 * 1000.0
7878
7979 // staleThreshold is the maximum depth of the acceptable stale block.
80- staleThreshold = 7
80+ // In PoW chains (like pre-merge Ethereum), this is set to 7 because orphaned blocks
81+ // can still be included as "uncle blocks" up to 6-7 blocks deep, earning partial rewards.
82+ // In Bor's PoS consensus, validators take turns producing blocks deterministically,
83+ // so there are no competing miners and no uncle block concept. Any non-canonical block
84+ // is immediately stale and can be discarded, hence staleThreshold is set to 0.
85+ staleThreshold = 0
8186)
8287
8388var (
@@ -522,27 +527,17 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
522527 veblopTimer .Reset (veblopTimeout )
523528 w .newTxs .Store (0 )
524529 }
525- // clearPending cleans the stale pending tasks.
526- clearPending := func (number uint64 ) {
527- w .pendingMu .Lock ()
528- for h , t := range w .pendingTasks {
529- if t .block .NumberU64 ()+ staleThreshold <= number {
530- delete (w .pendingTasks , h )
531- }
532- }
533- w .pendingMu .Unlock ()
534- }
535530
536531 for {
537532 select {
538533 case <- w .startCh :
539- clearPending (w .chain .CurrentBlock ().Number .Uint64 ())
534+ w . clearPending (w .chain .CurrentBlock ().Number .Uint64 ())
540535
541536 timestamp = time .Now ().Unix ()
542537 commit (false , commitInterruptNewHead )
543538
544539 case head := <- w .chainHeadCh :
545- clearPending (head .Header .Number .Uint64 ())
540+ w . clearPending (head .Header .Number .Uint64 ())
546541
547542 timestamp = time .Now ().Unix ()
548543 commit (false , commitInterruptNewHead )
@@ -869,6 +864,10 @@ func (w *worker) resultLoop() {
869864
870865 if err != nil {
871866 log .Error ("Failed writing block to chain" , "err" , err )
867+ // Error writing block to chain, delete the pending task.
868+ w .pendingMu .Lock ()
869+ delete (w .pendingTasks , sealhash )
870+ w .pendingMu .Unlock ()
872871 continue
873872 }
874873
@@ -884,6 +883,10 @@ func (w *worker) resultLoop() {
884883 sealedEmptyBlocksCounter .Inc (1 )
885884 }
886885
886+ // Clear all pending tasks for blocks at or below the sealed block number.
887+ // These tasks are now obsolete since the chain has progressed past them.
888+ w .clearPending (block .NumberU64 ())
889+
887890 case <- w .exitCh :
888891 return
889892 }
@@ -1732,6 +1735,17 @@ func (w *worker) adjustResubmitInterval(message *intervalAdjust) {
17321735 }
17331736}
17341737
1738+ // clearPending cleans the stale pending tasks.
1739+ func (w * worker ) clearPending (number uint64 ) {
1740+ w .pendingMu .Lock ()
1741+ for h , t := range w .pendingTasks {
1742+ if t .block .NumberU64 ()+ staleThreshold <= number {
1743+ delete (w .pendingTasks , h )
1744+ }
1745+ }
1746+ w .pendingMu .Unlock ()
1747+ }
1748+
17351749// copyReceipts makes a deep copy of the given receipts.
17361750func copyReceipts (receipts []* types.Receipt ) []* types.Receipt {
17371751 result := make ([]* types.Receipt , len (receipts ))
0 commit comments