@@ -77,6 +77,11 @@ const (
7777 staleThreshold = 7
7878)
7979
80+ var (
81+ ErrBlockInterruptedByNewHead = errors .New ("new head arrived while building block" )
82+ ErrBlockInterruptedByRecommit = errors .New ("recommit interrupt while building block" )
83+ )
84+
8085// environment is the worker's current environment and holds all
8186// information of the sealing block generation.
8287type environment struct {
@@ -592,7 +597,11 @@ func (w *worker) mainLoop() {
592597 }
593598 txset := types .NewTransactionsByPriceAndNonce (w .current .signer , txs , w .current .header .BaseFee )
594599 tcount := w .current .tcount
595- w .commitTransactions (w .current , txset , nil )
600+ err := w .commitTransactions (w .current , txset , nil )
601+ if err != nil {
602+ // Log but update the snapshot anyway to ensure it's consistent with w.current
603+ log .Error ("unexpected error while committing transactions" , "err" , err )
604+ }
596605
597606 // Only update the snapshot if any new transactions were added
598607 // to the pending block
@@ -841,7 +850,7 @@ func (w *worker) commitTransaction(env *environment, tx *types.Transaction) ([]*
841850 return receipt .Logs , nil
842851}
843852
844- func (w * worker ) commitTransactions (env * environment , txs * types.TransactionsByPriceAndNonce , interrupt * int32 ) bool {
853+ func (w * worker ) commitTransactions (env * environment , txs * types.TransactionsByPriceAndNonce , interrupt * int32 ) error {
845854 gasLimit := env .header .GasLimit
846855 if env .gasPool == nil {
847856 env .gasPool = new (core.GasPool ).AddGas (gasLimit )
@@ -866,8 +875,9 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
866875 ratio : ratio ,
867876 inc : true ,
868877 }
878+ return ErrBlockInterruptedByRecommit
869879 }
870- return atomic . LoadInt32 ( interrupt ) == commitInterruptNewHead
880+ return ErrBlockInterruptedByNewHead
871881 }
872882 // If we don't have enough gas for any further transactions then we're done
873883 if env .gasPool .Gas () < params .TxGas {
@@ -951,7 +961,7 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
951961 if interrupt != nil {
952962 w .resubmitAdjustCh <- & intervalAdjust {inc : false }
953963 }
954- return false
964+ return nil
955965}
956966
957967// generateParams wraps various of settings for generating sealing task.
@@ -1050,8 +1060,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
10501060// fillTransactions retrieves the pending transactions from the txpool and fills them
10511061// into the given sealing block. The transaction selection and ordering strategy can
10521062// be customized with the plugin in the future.
1053- // Returns whether block should be discarded.
1054- func (w * worker ) fillTransactions (interrupt * int32 , env * environment ) bool {
1063+ func (w * worker ) fillTransactions (interrupt * int32 , env * environment ) error {
10551064 // Split the pending transactions into locals and remotes
10561065 // Fill the block with all available pending transactions.
10571066 pending := w .eth .TxPool ().Pending (true )
@@ -1064,18 +1073,20 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment) bool {
10641073 }
10651074 if len (localTxs ) > 0 {
10661075 txs := types .NewTransactionsByPriceAndNonce (env .signer , localTxs , env .header .BaseFee )
1067- if w .commitTransactions (env , txs , interrupt ) {
1068- return true
1076+ err := w .commitTransactions (env , txs , interrupt )
1077+ if err != nil {
1078+ return err
10691079 }
10701080 }
10711081 if len (remoteTxs ) > 0 {
10721082 txs := types .NewTransactionsByPriceAndNonce (env .signer , remoteTxs , env .header .BaseFee )
1073- if w .commitTransactions (env , txs , interrupt ) {
1074- return true
1083+ err := w .commitTransactions (env , txs , interrupt )
1084+ if err != nil {
1085+ return err
10751086 }
10761087 }
10771088
1078- return false
1089+ return nil
10791090}
10801091
10811092// generateWork generates a sealing block based on the given parameters.
@@ -1086,8 +1097,9 @@ func (w *worker) generateWork(params *generateParams) (*types.Block, error) {
10861097 }
10871098 defer work .discard ()
10881099
1089- if w .fillTransactions (nil , work ) {
1090- return nil , errors .New ("could not populate block" )
1100+ err = w .fillTransactions (nil , work )
1101+ if err != nil {
1102+ return nil , err
10911103 }
10921104
10931105 return w .engine .FinalizeAndAssemble (w .chain , work .header , work .state , work .txs , work .unclelist (), work .receipts )
@@ -1121,7 +1133,8 @@ func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) {
11211133 }
11221134
11231135 // Fill pending transactions from the txpool
1124- if w .fillTransactions (interrupt , work ) {
1136+ err = w .fillTransactions (interrupt , work )
1137+ if err != nil && err != ErrBlockInterruptedByRecommit {
11251138 work .discard ()
11261139 return
11271140 }
0 commit comments