fix finalized epoch ref loading on checkpoint start (#3517)

regression from #3513 that did not take tail into consideration when
loading epoch ancestor
This commit is contained in:
Jacek Sieka 2022-03-18 13:13:57 +01:00 committed by GitHub
parent d11d61c745
commit d0223d1f28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 3 deletions

View File

@ -307,8 +307,11 @@ func epochAncestor*(dag: ChainDAGRef, bid: BlockId, epoch: Epoch): EpochKey =
## This function returns an epoch key pointing to that epoch boundary, i.e. the ## This function returns an epoch key pointing to that epoch boundary, i.e. the
## boundary where the last block has been applied to the state and epoch ## boundary where the last block has been applied to the state and epoch
## processing has been done. ## processing has been done.
if epoch == dag.genesis.slot.epoch: if epoch < dag.tail.slot.epoch or bid.slot < dag.tail.slot:
return EpochKey(bid: dag.genesis, epoch: epoch) return EpochKey() # We can't load these states
if epoch == dag.tail.slot.epoch:
return EpochKey(bid: dag.tail, epoch: epoch)
let bsi = dag.atSlot(bid, epoch.start_slot - 1).valueOr: let bsi = dag.atSlot(bid, epoch.start_slot - 1).valueOr:
# If we lack history for the given slot, we can use the given bid as epoch # If we lack history for the given slot, we can use the given bid as epoch
@ -881,10 +884,12 @@ proc getEpochRef*(
## Requests for epochs < dag.finalizedHead.slot.epoch may fail, either because ## Requests for epochs < dag.finalizedHead.slot.epoch may fail, either because
## the search was limited by the `preFinalized` flag or because state history ## the search was limited by the `preFinalized` flag or because state history
## has been pruned - none will be returned in this case. ## has been pruned - none will be returned in this case.
if not preFinalized and epoch < dag.finalizedHead.slot.epoch: if not preFinalized and epoch < dag.finalizedHead.slot.epoch:
return err() return err()
if bid.slot < dag.tail.slot or epoch < dag.tail.slot.epoch:
return err()
let epochRef = dag.findEpochRef(bid, epoch) let epochRef = dag.findEpochRef(bid, epoch)
if epochRef.isOk(): if epochRef.isOk():
beacon_state_data_cache_hits.inc beacon_state_data_cache_hits.inc
@ -892,6 +897,11 @@ proc getEpochRef*(
beacon_state_data_cache_misses.inc beacon_state_data_cache_misses.inc
# TODO instead of using the epoch ancestor, we should really be looking
# for _any_ state in the desired epoch in the history of bid since the
# epoch values remain unchanged: currently `epochAncestor` itself
# contains a work-around for the tail state, but it would be better to
# turn that work-around into a more efficient loading solution here
let let
ancestor = dag.epochAncestor(bid, epoch) ancestor = dag.epochAncestor(bid, epoch)

View File

@ -729,6 +729,8 @@ suite "Backfill":
# No epochref for pre-tail epochs # No epochref for pre-tail epochs
dag.getEpochRef(dag.tail, dag.tail.slot.epoch - 1, true).isErr() dag.getEpochRef(dag.tail, dag.tail.slot.epoch - 1, true).isErr()
dag.getFinalizedEpochRef() != nil
dag.backfill == tailBlock.phase0Data.message.toBeaconBlockSummary() dag.backfill == tailBlock.phase0Data.message.toBeaconBlockSummary()
var var
@ -800,6 +802,8 @@ suite "Backfill":
dag2 = init(ChainDAGRef, defaultRuntimeConfig, db, validatorMonitor2, {}) dag2 = init(ChainDAGRef, defaultRuntimeConfig, db, validatorMonitor2, {})
check: check:
dag2.getFinalizedEpochRef() != nil
dag2.getBlockRef(tailBlock.root).get().root == dag.tail.root dag2.getBlockRef(tailBlock.root).get().root == dag.tail.root
dag2.getBlockRef(blocks[^2].root).isNone() dag2.getBlockRef(blocks[^2].root).isNone()