Skip to content

Commit eb791cf

Browse files
authored
avoid rewinds during syncing (#4093)
1 parent cd46af1 commit eb791cf

File tree

1 file changed

+28
-5
lines changed

1 file changed

+28
-5
lines changed

beacon_chain/consensus_object_pools/consensus_manager.nim

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
277293
proc 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

Comments
 (0)