@@ -274,18 +274,41 @@ proc updateHead*(self: var ConsensusManager, wallSlot: Slot) =
274274
275275 self.updateHead (newHead.blck)
276276
277+ func isSynced (dag: ChainDAGRef , wallSlot: Slot ): bool =
278+ # This is a tweaked version of the validator_duties isSynced. TODO, refactor
279+ # that one so this becomes the default version, with the same information to
280+ # work with. For the head slot, use the DAG head regardless of what head the
281+ # proposer forkchoiceUpdated is using, because by the validator_duties might
282+ # be ready to actually propose, it's going to do so from the DAG head. Given
283+ # the defaultSyncHorizon, it will start triggering in time so that potential
284+ # discrepancies between the head here, and the head the DAG has (which might
285+ # not yet be updated) won't be visible.
286+ const defaultSyncHorizon = 50
287+
288+ if dag.head.slot + defaultSyncHorizon < wallSlot:
289+ false
290+ else :
291+ not dag.is_optimistic (dag.head.root)
292+
277293proc checkNextProposer (
278294 dag: ChainDAGRef , actionTracker: ActionTracker ,
279295 dynamicFeeRecipientsStore: ref DynamicFeeRecipientsStore ,
280- slot : Slot ):
296+ wallSlot : Slot ):
281297 Opt [(ValidatorIndex , ValidatorPubKey )] =
282- let nextSlot = slot + 1
283- let proposer = dag.getProposer (dag.head, nextSlot)
298+ let nextWallSlot = wallSlot + 1
299+
300+ # Avoid long rewinds during syncing, when it's not going to propose. Though
301+ # this is preparing for a proposal on `nextWallSlot`, it can't possibly yet
302+ # be on said slot, so still check just `wallSlot`.
303+ if not dag.isSynced (wallSlot):
304+ return Opt .none ((ValidatorIndex , ValidatorPubKey ))
305+
306+ let proposer = dag.getProposer (dag.head, nextWallSlot)
284307 if proposer.isNone ():
285308 return Opt .none ((ValidatorIndex , ValidatorPubKey ))
286- if actionTracker.getNextProposalSlot (slot ) != nextSlot and
309+ if actionTracker.getNextProposalSlot (wallSlot ) != nextWallSlot and
287310 dynamicFeeRecipientsStore[].getDynamicFeeRecipient (
288- proposer.get, nextSlot .epoch).isNone:
311+ proposer.get, nextWallSlot .epoch).isNone:
289312 return Opt .none ((ValidatorIndex , ValidatorPubKey ))
290313 let proposerKey = dag.validatorKey (proposer.get).get ().toPubKey
291314 Opt .some ((proposer.get, proposerKey))
0 commit comments