@@ -925,6 +925,7 @@ func (w *worker) commitTransaction(env *environment, tx *types.Transaction) ([]*
925925 return receipt .Logs , nil
926926}
927927
928+ // Returns whether the block should be discarded
928929func (w * worker ) commitBundle (env * environment , txs types.Transactions , interrupt * int32 ) bool {
929930 gasLimit := env .header .GasLimit
930931 if env .gasPool == nil {
@@ -938,8 +939,7 @@ func (w *worker) commitBundle(env *environment, txs types.Transactions, interrup
938939 // (1) new head block event arrival, the interrupt signal is 1
939940 // (2) worker start or restart, the interrupt signal is 1
940941 // (3) worker recreate the sealing block with any newly arrived transactions, the interrupt signal is 2.
941- // For the first two cases, the semi-finished work will be discarded.
942- // For the third case, the semi-finished work will be submitted to the consensus engine.
942+ // Discard the interrupted work, since it is incomplete and contains partial bundles
943943 if interrupt != nil && atomic .LoadInt32 (interrupt ) != commitInterruptNone {
944944 // Notify resubmit loop to increase resubmitting interval due to too frequent commits.
945945 if atomic .LoadInt32 (interrupt ) == commitInterruptResubmit {
@@ -953,12 +953,13 @@ func (w *worker) commitBundle(env *environment, txs types.Transactions, interrup
953953 }
954954 }
955955
956- return atomic . LoadInt32 ( interrupt ) == commitInterruptNewHead
956+ return true
957957 }
958- // If we don't have enough gas for any further transactions then we're done
958+ // If we don't have enough gas for any further transactions discard the block
959+ // since not all bundles of the were applied
959960 if env .gasPool .Gas () < params .TxGas {
960961 log .Trace ("Not enough gas for further transactions" , "have" , env .gasPool , "want" , params .TxGas )
961- break
962+ return true
962963 }
963964
964965 // Error may be ignored here. The error has already been checked
@@ -1245,7 +1246,8 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
12451246// fillTransactions retrieves the pending transactions from the txpool and fills them
12461247// into the given sealing block. The transaction selection and ordering strategy can
12471248// be customized with the plugin in the future.
1248- func (w * worker ) fillTransactions (interrupt * int32 , env * environment ) {
1249+ // Returns whether the block should be discarded.
1250+ func (w * worker ) fillTransactions (interrupt * int32 , env * environment ) bool {
12491251 // Split the pending transactions into locals and remotes
12501252 // Fill the block with all available pending transactions.
12511253 pending := w .eth .TxPool ().Pending (true )
@@ -1260,36 +1262,36 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment) {
12601262 bundles , err := w .eth .TxPool ().MevBundles (env .header .Number , env .header .Time )
12611263 if err != nil {
12621264 log .Error ("Failed to fetch pending transactions" , "err" , err )
1263- return
1265+ return true
12641266 }
12651267
12661268 bundleTxs , bundle , numBundles , err := w .generateFlashbotsBundle (env , bundles , pending )
12671269 if err != nil {
12681270 log .Error ("Failed to generate flashbots bundle" , "err" , err )
1269- return
1271+ return true
12701272 }
12711273 log .Info ("Flashbots bundle" , "ethToCoinbase" , ethIntToFloat (bundle .totalEth ), "gasUsed" , bundle .totalGasUsed , "bundleScore" , bundle .mevGasPrice , "bundleLength" , len (bundleTxs ), "numBundles" , numBundles , "worker" , w .flashbots .maxMergedBundles )
12721274 if len (bundleTxs ) == 0 {
1273- return
1275+ return true
12741276 }
12751277 if w .commitBundle (env , bundleTxs , interrupt ) {
1276- return
1278+ return true
12771279 }
12781280 env .profit .Add (env .profit , bundle .ethSentToCoinbase )
12791281 }
12801282 if w .flashbots .isMegabundleWorker {
12811283 megabundle , err := w .eth .TxPool ().GetMegabundle (w .flashbots .relayAddr , env .header .Number , env .header .Time )
12821284 log .Info ("Starting to process a Megabundle" , "relay" , w .flashbots .relayAddr , "megabundle" , megabundle , "error" , err )
12831285 if err != nil {
1284- return // no valid megabundle for this relay, nothing to do
1286+ return true // no valid megabundle for this relay, nothing to do
12851287 }
12861288
12871289 // Flashbots bundle merging duplicates work by simulating TXes and then committing them once more.
12881290 // Megabundles API focuses on speed and runs everything in one cycle.
12891291 coinbaseBalanceBefore := env .state .GetBalance (env .coinbase )
12901292 if w .commitBundle (env , megabundle .Txs , interrupt ) {
12911293 log .Info ("Could not commit a Megabundle" , "relay" , w .flashbots .relayAddr , "megabundle" , megabundle )
1292- return
1294+ return true
12931295 }
12941296 var txStatuses = map [common.Hash ]bool {}
12951297 for _ , receipt := range env .receipts {
@@ -1299,11 +1301,11 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment) {
12991301 status , ok := txStatuses [tx .Hash ()]
13001302 if ! ok {
13011303 log .Error ("No TX receipt after megabundle simulation" , "TxHash" , tx .Hash ())
1302- return
1304+ return true
13031305 }
13041306 if ! status && ! containsHash (megabundle .RevertingTxHashes , tx .Hash ()) {
13051307 log .Info ("Ignoring megabundle because of failing TX" , "relay" , w .flashbots .relayAddr , "TxHash" , tx .Hash ())
1306- return
1308+ return true
13071309 }
13081310 }
13091311 coinbaseBalanceAfter := env .state .GetBalance (env .coinbase )
@@ -1315,15 +1317,17 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment) {
13151317 if len (localTxs ) > 0 {
13161318 txs := types .NewTransactionsByPriceAndNonce (env .signer , localTxs , env .header .BaseFee )
13171319 if w .commitTransactions (env , txs , interrupt ) {
1318- return
1320+ return true
13191321 }
13201322 }
13211323 if len (remoteTxs ) > 0 {
13221324 txs := types .NewTransactionsByPriceAndNonce (env .signer , remoteTxs , env .header .BaseFee )
13231325 if w .commitTransactions (env , txs , interrupt ) {
1324- return
1326+ return true
13251327 }
13261328 }
1329+
1330+ return false
13271331}
13281332
13291333// generateWork generates a sealing block based on the given parameters.
@@ -1334,7 +1338,11 @@ func (w *worker) generateWork(params *generateParams) (*types.Block, error) {
13341338 }
13351339 defer work .discard ()
13361340
1337- w .fillTransactions (nil , work )
1341+ shouldDiscard := w .fillTransactions (nil , work )
1342+ if shouldDiscard {
1343+ return nil , errors .New ("could not generate valid block" )
1344+ }
1345+
13381346 return w .engine .FinalizeAndAssemble (w .chain , work .header , work .state , work .txs , work .unclelist (), work .receipts )
13391347}
13401348
@@ -1365,7 +1373,12 @@ func (w *worker) commitWork(interrupt *int32, noempty bool, timestamp int64) {
13651373 w .commit (work .copy (), nil , false , start )
13661374 }
13671375 // Fill pending transactions from the txpool
1368- w .fillTransactions (interrupt , work )
1376+ shouldDiscard := w .fillTransactions (interrupt , work )
1377+ if shouldDiscard {
1378+ work .discard ()
1379+ return
1380+ }
1381+
13691382 w .commit (work .copy (), w .fullTaskHook , true , start )
13701383
13711384 // Swap out the old work with the new one, terminating any leftover
@@ -1525,11 +1538,11 @@ func (w *worker) simulateBundles(env *environment, bundles []types.MevBundle, pe
15251538 simulatedBundles := []simulatedBundle {}
15261539
15271540 for _ , bundle := range bundles {
1528- state := env .state .Copy ()
1529- gasPool := new (core.GasPool ).AddGas (env .header .GasLimit )
15301541 if len (bundle .Txs ) == 0 {
15311542 continue
15321543 }
1544+ state := env .state .Copy ()
1545+ gasPool := new (core.GasPool ).AddGas (env .header .GasLimit )
15331546 simmed , err := w .computeBundleGas (env , bundle , state , gasPool , pendingTxs , 0 )
15341547
15351548 if err != nil {
0 commit comments