mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-03-04 18:35:03 +00:00
miner: avoid unnecessary work after payload resolution (#33943)
In `buildPayload()`, the background goroutine uses a `select` to wait on the recommit timer, the stop channel, and the end timer. When both `timer.C` and `payload.stop` are ready simultaneously, Go's `select` picks a case non-deterministically. This means the loop can enter the `timer.C` case and perform an unnecessary `generateWork` call even after the payload has been resolved. Add a non-blocking check of `payload.stop` at the top of the `timer.C` case to exit immediately when the payload has already been delivered.
This commit is contained in:
parent
773f71bb9e
commit
4f75049ea0
1 changed files with 11 additions and 0 deletions
|
|
@ -260,6 +260,17 @@ func (miner *Miner) buildPayload(args *BuildPayloadArgs, witness bool) (*Payload
|
|||
for {
|
||||
select {
|
||||
case <-timer.C:
|
||||
// When block building takes close to the full recommit interval,
|
||||
// the timer fires near-instantly on the next iteration. If the
|
||||
// payload was resolved during that build, both timer.C and
|
||||
// payload.stop are ready and Go's select picks one at random.
|
||||
// Check payload.stop first to avoid an unnecessary generateWork.
|
||||
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 {
|
||||
|
|
|
|||
Loading…
Reference in a new issue