avoid small gaps in optimistic block stream (#3749)
Ensures that all intermediate blocks are reported if a small gap is encountered when downloading optimistic blocks. Gaps may occur when a block is missed and still downloading, or when EL processing is slow. If the gap exceeds 1 epoch, optimistic block stream jumps to latest.
This commit is contained in:
parent
e8efc0f184
commit
21b69d5901
|
@ -35,7 +35,8 @@ type
|
||||||
lcBlocks: LCBlocks
|
lcBlocks: LCBlocks
|
||||||
blockVerifier: request_manager.BlockVerifier
|
blockVerifier: request_manager.BlockVerifier
|
||||||
requestManager: RequestManager
|
requestManager: RequestManager
|
||||||
finalizedBid, optimisticBid, optimisticCandidateBid: BlockId
|
finalizedBid, optimisticBid: BlockId
|
||||||
|
lastReportedSlot: Slot
|
||||||
finalizedIsExecutionBlock: Option[bool]
|
finalizedIsExecutionBlock: Option[bool]
|
||||||
syncStrategy: SyncStrategy
|
syncStrategy: SyncStrategy
|
||||||
syncFut, processFut: Future[void]
|
syncFut, processFut: Future[void]
|
||||||
|
@ -60,20 +61,34 @@ proc reportOptimisticCandidateBlock(optSync: LCOptimisticSync) {.gcsafe.} =
|
||||||
|
|
||||||
let
|
let
|
||||||
currentSlot = optSync.lcBlocks.getHeadSlot()
|
currentSlot = optSync.lcBlocks.getHeadSlot()
|
||||||
signedBlock =
|
maxSlot =
|
||||||
if optSync.finalizedIsExecutionBlock.get(false):
|
if optSync.finalizedIsExecutionBlock.get(false):
|
||||||
# If finalized is execution block, can import any later block
|
# If finalized is execution block, can import any later block
|
||||||
optSync.lcBlocks.getLatestBlockThroughSlot(currentSlot)
|
currentSlot
|
||||||
else:
|
else:
|
||||||
# Else, block must be deep (min `SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY`)
|
# Else, block must be deep (min `SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY`)
|
||||||
let
|
let minAge = optSync.safeSlotsToImportOptimistically
|
||||||
minAge = optSync.safeSlotsToImportOptimistically
|
max(currentSlot, minAge.Slot) - minAge.uint64
|
||||||
maxSlot = max(currentSlot, minAge.Slot) - minAge.uint64
|
|
||||||
optSync.lcBlocks.getLatestBlockThroughSlot(maxSlot)
|
if maxSlot > optSync.lastReportedSlot:
|
||||||
if signedBlock.isOk:
|
const minGapSize = SLOTS_PER_EPOCH
|
||||||
let bid = signedBlock.get.toBlockId()
|
var signedBlock: Opt[ForkedMsgTrustedSignedBeaconBlock]
|
||||||
if bid.slot > optSync.optimisticCandidateBid.slot:
|
if maxSlot - optSync.lastReportedSlot >= minGapSize:
|
||||||
optSync.optimisticCandidateBid = bid
|
# Large gap, skip to latest
|
||||||
|
signedBlock = optSync.lcBlocks.getLatestBlockThroughSlot(maxSlot)
|
||||||
|
elif optSync.lcBlocks.getFrontfillSlot() <= optSync.lastReportedSlot + 1 and
|
||||||
|
optSync.lcBlocks.getBackfillSlot() > optSync.lastReportedSlot + 1:
|
||||||
|
# Small gap, but still downloading
|
||||||
|
discard
|
||||||
|
else:
|
||||||
|
# Report next sequential block (even if it is slightly outdated)
|
||||||
|
for slot in optSync.lastReportedSlot + 1 .. maxSlot:
|
||||||
|
signedBlock = optSync.lcBlocks.getBlockAtSlot(slot)
|
||||||
|
if signedBlock.isOk:
|
||||||
|
break
|
||||||
|
|
||||||
|
if signedBlock.isOk and signedBlock.get.slot > optSync.lastReportedSlot:
|
||||||
|
optSync.lastReportedSlot = signedBlock.get.slot
|
||||||
optSync.processFut = optSync.optimisticProcessor(signedBlock.get)
|
optSync.processFut = optSync.optimisticProcessor(signedBlock.get)
|
||||||
|
|
||||||
proc handleFinishedProcess(future: pointer) =
|
proc handleFinishedProcess(future: pointer) =
|
||||||
|
|
Loading…
Reference in New Issue