diff --git a/miner/payload_building.go b/miner/payload_building.go index 6b010186bf99..14d903f66385 100644 --- a/miner/payload_building.go +++ b/miner/payload_building.go @@ -254,6 +254,13 @@ func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload for { select { case <-timer.C: + // Select is random, so we need to check if the payload has been stopped + select { + case <-payload.stop: + log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery") + return + default: + } start := time.Now() r := miner.generateWork(fullParams, witness) if r.err == nil { @@ -261,7 +268,12 @@ func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload } else { log.Info("Error while generating work", "id", payload.id, "err", r.err) } - timer.Reset(miner.config.Recommit) + if r.interrupted { + // Retry immediately bc there are more txs to include. + timer.Reset(0) + } else { + timer.Reset(miner.config.Recommit) + } case <-payload.stop: log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery") return diff --git a/miner/worker.go b/miner/worker.go index 45d7073ed76f..1d13a22cfac2 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -92,14 +92,15 @@ const maxBlockSizeBufferZone = 1_000_000 // newPayloadResult is the result of payload generation. type newPayloadResult struct { - err error - block *types.Block - fees *big.Int // total block fees - sidecars []*types.BlobTxSidecar // collected blobs of blob transactions - stateDB *state.StateDB // StateDB after executing the transactions - receipts []*types.Receipt // Receipts collected during construction - requests [][]byte // Consensus layer requests collected during block construction - witness *stateless.Witness // Witness is an optional stateless proof + err error + block *types.Block + fees *big.Int // total block fees + sidecars []*types.BlobTxSidecar // collected blobs of blob transactions + stateDB *state.StateDB // StateDB after executing the transactions + receipts []*types.Receipt // Receipts collected during construction + requests [][]byte // Consensus layer requests collected during block construction + witness *stateless.Witness // Witness is an optional stateless proof + interrupted bool // true if fillTransactions was interrupted before finishing } // generateParams wraps various settings for generating sealing task. @@ -131,6 +132,7 @@ func (miner *Miner) generateWork(genParam *generateParams, witness bool) *newPay // Also add size of withdrawals to work block size. work.size += uint64(genParam.withdrawals.Size()) + var interrupted bool if !genParam.noTxs { interrupt := new(atomic.Int32) timer := time.AfterFunc(miner.config.Recommit, func() { @@ -141,6 +143,7 @@ func (miner *Miner) generateWork(genParam *generateParams, witness bool) *newPay err := miner.fillTransactions(interrupt, work) if errors.Is(err, errBlockInterruptedByTimeout) { log.Warn("Block building is interrupted", "allowance", common.PrettyDuration(miner.config.Recommit)) + interrupted = true } } body := types.Body{Transactions: work.txs, Withdrawals: genParam.withdrawals} @@ -177,13 +180,14 @@ func (miner *Miner) generateWork(genParam *generateParams, witness bool) *newPay return &newPayloadResult{err: err} } return &newPayloadResult{ - block: block, - fees: totalFees(block, work.receipts), - sidecars: work.sidecars, - stateDB: work.state, - receipts: work.receipts, - requests: requests, - witness: work.witness, + block: block, + fees: totalFees(block, work.receipts), + sidecars: work.sidecars, + stateDB: work.state, + receipts: work.receipts, + requests: requests, + witness: work.witness, + interrupted: interrupted, } }