Skip to content

Commit 4c3e1e2

Browse files
authored
chore: wait in the precommit step without re-scheduling (#2619)
Closes celestiaorg/celestia-app#6124
1 parent ca3d1c3 commit 4c3e1e2

File tree

1 file changed

+25
-10
lines changed

1 file changed

+25
-10
lines changed

consensus/state.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"runtime/debug"
1111
"sort"
1212
"sync"
13+
"sync/atomic"
1314
"time"
1415

1516
"github.com/cometbft/cometbft/privval"
@@ -145,9 +146,10 @@ type State struct {
145146
nSteps int
146147

147148
// some functions can be overwritten for testing
148-
decideProposal func(height int64, round int32)
149-
doPrevote func(height int64, round int32)
150-
setProposal func(proposal *types.Proposal) error
149+
decideProposal func(height int64, round int32)
150+
doPrevote func(height int64, round int32)
151+
setProposal func(proposal *types.Proposal) error
152+
StartedPrecommitSleep atomic.Bool
151153

152154
// closed when we finish shutting down
153155
done chan struct{}
@@ -1627,9 +1629,22 @@ func (cs *State) enterPrecommit(height int64, round int32) {
16271629
return
16281630
}
16291631

1630-
if ready, waitTime := cs.isReadyToPrecommit(); !ready {
1631-
logger.Trace("rescheduling precommit", "delay(ms)", waitTime.Milliseconds())
1632-
cs.scheduleTimeout(waitTime, height, round, cstypes.RoundStepPrevoteWait)
1632+
if cs.StartedPrecommitSleep.CompareAndSwap(false, true) {
1633+
waitTime := cs.precommitDelay()
1634+
logger.Debug("delaying precommit", "delay", waitTime)
1635+
cs.unlockAll()
1636+
t := time.NewTimer(waitTime)
1637+
select {
1638+
case <-cs.Quit():
1639+
cs.lockAll()
1640+
return
1641+
case <-t.C:
1642+
}
1643+
cs.lockAll()
1644+
cs.StartedPrecommitSleep.Store(false)
1645+
} else {
1646+
logger.Debug("already entered precommit delay")
1647+
// if any other routine tries to enter precommit, we just return
16331648
return
16341649
}
16351650

@@ -2110,20 +2125,20 @@ func (cs *State) recordMetrics(height int64, block *types.Block) {
21102125
// KMSSigningDelay is a constant representing a delay used primarily to adjust for KMS signing latencies.
21112126
const KMSSigningDelay = 200 * time.Millisecond
21122127

2113-
// isReadyToPrecommit calculates if the process has waited at least a certain number of seconds
2128+
// precommitDelay calculates if the process has waited at least a certain number of seconds
21142129
// from their start time before they can vote
21152130
// If the application's DelayedPrecommitTimeout is set to 0, no precommit wait is done.
2116-
func (cs *State) isReadyToPrecommit() (bool, time.Duration) {
2131+
func (cs *State) precommitDelay() time.Duration {
21172132
if cs.state.Timeouts.DelayedPrecommitTimeout == 0 {
21182133
// setting 0 as a special case not to reschedule the pre-commit
2119-
return true, 0
2134+
return 0
21202135
}
21212136
precommitVoteTime := cs.rs.StartTime.Add(cs.state.Timeouts.DelayedPrecommitTimeout)
21222137
waitTime := time.Until(precommitVoteTime)
21232138
if _, ok := cs.privValidator.(*privval.SignerClient); ok {
21242139
waitTime = waitTime - KMSSigningDelay
21252140
}
2126-
return waitTime <= 0, waitTime
2141+
return waitTime
21272142
}
21282143

21292144
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)