import finalized head LC bootstrap on launch (#5775)
If the initial state replays cover the finalized head, import matching `LightClientBootstrap` into database. This also addresses this error when light client requests bootstrap from the genesis slot on networks that launch with Altair enabled. ``` {"lvl":"DBG","ts":"2023-10-04 11:17:49.665+00:00","msg":"LC bootstrap unavailable: Sync committee branch not cached","topics":"chaindag_lc","slot":0} ```
This commit is contained in:
parent
479c133375
commit
be73ce2e9a
|
@ -579,7 +579,7 @@ proc assignLightClientData(
|
|||
forkyObject.signature_slot = signature_slot
|
||||
ok()
|
||||
|
||||
proc createLightClientUpdates(
|
||||
proc createLightClientUpdate(
|
||||
dag: ChainDAGRef,
|
||||
state: ForkyHashedBeaconState,
|
||||
blck: ForkyTrustedSignedBeaconBlock,
|
||||
|
@ -665,6 +665,38 @@ proc createLightClientUpdates(
|
|||
current_period_best_update = best,
|
||||
latest_signature_slot = latest_signature_slot)
|
||||
|
||||
proc createLightClientBootstrap(
|
||||
dag: ChainDAGRef, bid: BlockId): Opt[void] =
|
||||
let
|
||||
bdata = ? dag.getExistingForkedBlock(bid)
|
||||
period = bid.slot.sync_committee_period
|
||||
if not dag.lcDataStore.db.hasSyncCommittee(period):
|
||||
let didPutSyncCommittee = withState(dag.headState):
|
||||
when consensusFork >= ConsensusFork.Altair:
|
||||
if period == forkyState.data.slot.sync_committee_period:
|
||||
dag.lcDataStore.db.putSyncCommittee(
|
||||
period, forkyState.data.current_sync_committee)
|
||||
true
|
||||
else:
|
||||
false
|
||||
else:
|
||||
false
|
||||
if not didPutSyncCommittee:
|
||||
let
|
||||
tmpState = assignClone(dag.headState)
|
||||
syncCommittee = ? dag.existingCurrentSyncCommitteeForPeriod(
|
||||
tmpState[], period)
|
||||
dag.lcDataStore.db.putSyncCommittee(period, syncCommittee)
|
||||
withBlck(bdata):
|
||||
when consensusFork >= ConsensusFork.Altair:
|
||||
const lcDataFork = lcDataForkAtConsensusFork(consensusFork)
|
||||
dag.lcDataStore.db.putHeader(
|
||||
forkyBlck.toLightClientHeader(lcDataFork))
|
||||
else: raiseAssert "Unreachable"
|
||||
dag.lcDataStore.db.putCurrentSyncCommitteeBranch(
|
||||
bid.slot, dag.getLightClientData(bid).current_sync_committee_branch)
|
||||
ok()
|
||||
|
||||
proc initLightClientDataCache*(dag: ChainDAGRef) =
|
||||
## Initialize cached light client data
|
||||
if not dag.shouldImportLcData:
|
||||
|
@ -712,7 +744,7 @@ proc initLightClientDataCache*(dag: ChainDAGRef) =
|
|||
else:
|
||||
false
|
||||
|
||||
# Build list of block to process.
|
||||
# Build list of blocks to process.
|
||||
# As it is slow to load states in descending order,
|
||||
# build a reverse todo list to then process them in ascending order
|
||||
let tailSlot = dag.lcDataStore.cache.tailSlot
|
||||
|
@ -767,10 +799,16 @@ proc initLightClientDataCache*(dag: ChainDAGRef) =
|
|||
current_period_best_update = best,
|
||||
latest_signature_slot = GENESIS_SLOT)
|
||||
else:
|
||||
dag.createLightClientUpdates(
|
||||
dag.createLightClientUpdate(
|
||||
forkyState, forkyBlck, parentBid = blocks[i + 1])
|
||||
else: raiseAssert "Unreachable"
|
||||
|
||||
# Import initial `LightClientBootstrap`
|
||||
if dag.finalizedHead.slot >= dag.lcDataStore.cache.tailSlot:
|
||||
if dag.createLightClientBootstrap(dag.finalizedHead.blck.bid).isErr:
|
||||
dag.handleUnexpectedLightClientError(dag.finalizedHead.blck.bid.slot)
|
||||
res.err()
|
||||
|
||||
let lightClientEndTick = Moment.now()
|
||||
debug "Initialized cached LC data",
|
||||
initDur = lightClientEndTick - lightClientStartTick, res
|
||||
|
@ -807,7 +845,7 @@ proc processNewBlockForLightClient*(
|
|||
const consensusFork = typeof(signedBlock).kind
|
||||
when consensusFork >= ConsensusFork.Altair:
|
||||
template forkyState: untyped = state.forky(consensusFork)
|
||||
dag.createLightClientUpdates(forkyState, signedBlock, parentBid)
|
||||
dag.createLightClientUpdate(forkyState, signedBlock, parentBid)
|
||||
else:
|
||||
raiseAssert "Unreachable" # `tailSlot` cannot be before Altair
|
||||
|
||||
|
@ -902,38 +940,9 @@ proc processFinalizationForLightClient*(
|
|||
break
|
||||
bid = bsi.bid
|
||||
if bid.slot >= lowSlot:
|
||||
let
|
||||
bdata = dag.getExistingForkedBlock(bid).valueOr:
|
||||
if dag.createLightClientBootstrap(bid).isErr:
|
||||
dag.handleUnexpectedLightClientError(bid.slot)
|
||||
break
|
||||
period = bid.slot.sync_committee_period
|
||||
if not dag.lcDataStore.db.hasSyncCommittee(period):
|
||||
let didPutSyncCommittee = withState(dag.headState):
|
||||
when consensusFork >= ConsensusFork.Altair:
|
||||
if period == forkyState.data.slot.sync_committee_period:
|
||||
dag.lcDataStore.db.putSyncCommittee(
|
||||
period, forkyState.data.current_sync_committee)
|
||||
true
|
||||
else:
|
||||
false
|
||||
else:
|
||||
false
|
||||
if not didPutSyncCommittee:
|
||||
let
|
||||
tmpState = assignClone(dag.headState)
|
||||
syncCommittee = dag.existingCurrentSyncCommitteeForPeriod(
|
||||
tmpState[], period).valueOr:
|
||||
dag.handleUnexpectedLightClientError(bid.slot)
|
||||
break
|
||||
dag.lcDataStore.db.putSyncCommittee(period, syncCommittee)
|
||||
withBlck(bdata):
|
||||
when consensusFork >= ConsensusFork.Altair:
|
||||
const lcDataFork = lcDataForkAtConsensusFork(consensusFork)
|
||||
dag.lcDataStore.db.putHeader(
|
||||
forkyBlck.toLightClientHeader(lcDataFork))
|
||||
else: raiseAssert "Unreachable"
|
||||
dag.lcDataStore.db.putCurrentSyncCommitteeBranch(
|
||||
bid.slot, dag.getLightClientData(bid).current_sync_committee_branch)
|
||||
boundarySlot = bid.slot.nextEpochBoundarySlot
|
||||
if boundarySlot < SLOTS_PER_EPOCH:
|
||||
break
|
||||
|
|
|
@ -459,6 +459,17 @@ proc addObject*(
|
|||
(afterGenesis, _) = wallTime.toSlot()
|
||||
|
||||
if not afterGenesis:
|
||||
let mayProcessBeforeGenesis =
|
||||
when obj is ForkedLightClientBootstrap:
|
||||
withForkyBootstrap(obj):
|
||||
when lcDataFork > LightClientDataFork.None:
|
||||
forkyBootstrap.header.beacon.slot == GENESIS_SLOT and
|
||||
self.cfg.ALTAIR_FORK_EPOCH == GENESIS_EPOCH
|
||||
else:
|
||||
false
|
||||
else:
|
||||
false
|
||||
if not mayProcessBeforeGenesis:
|
||||
error "Processing LC object before genesis, clock turned back?"
|
||||
quit 1
|
||||
|
||||
|
|
Loading…
Reference in New Issue