Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -1677,12 +1677,20 @@ func (p *Parlia) Authorize(val common.Address, signFn SignerFn, signTxFn SignerT

// Argument leftOver is the time reserved for block finalize(calculate root, distribute income...)
func (p *Parlia) Delay(chain consensus.ChainReader, header *types.Header, leftOver *time.Duration) *time.Duration {
number := header.Number.Uint64()
snap, err := p.snapshot(chain, number-1, header.ParentHash, nil)
snap, err := p.snapshot(chain, header.Number.Uint64()-1, header.ParentHash, nil)
if err != nil {
return nil
}

delay := p.delayForRamanujanFork(snap, header)
// The blocking time should be no more than half of period when snap.TurnLength == 1
timeForMining := time.Duration(snap.BlockInterval) * time.Millisecond / 2
if !snap.lastBlockInOneTurn(header.Number.Uint64()) {
timeForMining = time.Duration(snap.BlockInterval) * time.Millisecond
}
if delay > timeForMining {
delay = timeForMining
}

if *leftOver >= time.Duration(snap.BlockInterval)*time.Millisecond {
// ignore invalid leftOver
Expand All @@ -1694,14 +1702,6 @@ func (p *Parlia) Delay(chain consensus.ChainReader, header *types.Header, leftOv
delay = delay - *leftOver
}

// The blocking time should be no more than half of period when snap.TurnLength == 1
timeForMining := time.Duration(snap.BlockInterval) * time.Millisecond / 2
if !snap.lastBlockInOneTurn(header.Number.Uint64()) {
timeForMining = time.Duration(snap.BlockInterval) * time.Millisecond
}
if delay > timeForMining {
delay = timeForMining
}
return &delay
}

Expand Down
19 changes: 19 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,25 @@ LOOP:
log.Debug("Not enough time for commitWork")
break
} else {
if !w.inTurn() && len(workList) == 1 {
if parliaEngine, ok := w.engine.(*parlia.Parlia); ok {
// When mining out of turn, continuous access to the txpool and trie database
// may cause lock contention, slowing down transaction insertion and block importing.
// Applying a backoff delay mitigates this issue and significantly reduces CPU usage.
if blockInterval, err := parliaEngine.BlockInterval(w.chain, w.chain.CurrentBlock()); err == nil {
beforeSealing := time.Until(time.UnixMilli(int64(work.header.MilliTimestamp())))
if wait := beforeSealing - time.Duration(blockInterval)*time.Millisecond; wait > 0 {
log.Debug("Applying backoff before mining", "block", work.header.Number, "waiting(ms)", wait.Milliseconds())
select {
case <-time.After(wait):
case <-interruptCh:
log.Debug("CommitWork interrupted: new block imported or resubmission triggered", "block", work.header.Number)
return
}
}
}
}
}
log.Debug("commitWork stopTimer", "block", work.header.Number,
"header time", time.UnixMilli(int64(work.header.MilliTimestamp())),
"commit delay", *delay, "DelayLeftOver", w.config.DelayLeftOver)
Expand Down