New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix computed db checkpoint for weak subjectivity checks #4575
Conversation
Performance Report✔️ no performance regression detected Full benchmark results
|
@@ -111,7 +111,7 @@ export function isWithinWeakSubjectivityPeriod( | |||
wsState: BeaconStateAllForks, | |||
wsCheckpoint: Checkpoint | |||
): boolean { | |||
const wsStateEpoch = computeEpochAtSlot(wsState.slot); | |||
const wsStateEpoch = Math.ceil(wsState.slot / SLOTS_PER_EPOCH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@g11tech do we really need this for the fix? it's quite confusing here so either not to include this change, or drop some comments to clarify
epoch: computeEpochAtSlot(state.latestBlockHeader.slot), | ||
// the correct checkpoint is based on state's slot, its latestBlockHeader's slot's epoch can be | ||
// behind the state | ||
epoch: Math.ceil(state.slot / SLOTS_PER_EPOCH), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using state.slot
makes sense, thru I think computeEpochAtSlot(state.slot)
is enough
if SLOTS_PER_EPOCH
= 32 and state.slot = 40 then this function return an epoch of 2 does not sounds right, otherwise please drop some comments to avoid the confusing
also note that there is another getCheckpointFromState
function defined somewhere else which expect the real checkpoint state (state.slot % 32 = 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my reasoning: if state slot is > some epoch boundary (ideally it should be on the boundary), and it its a checkpoint state, it should be for next epoch+1 only right? could be possible that the latestBlockHeader belongs from > epoch*32 slot, and hence the checkpoint root might belong to epoch+1
Also this: https://github.com/ChainSafe/lodestar/blob/unstable/packages/beacon-node/src/chain/initState.ts#L226
Motivation
The checkpoint computed from db state for weak subjetcivity checks is wrongly based on its latestBlockHeader's slot's epoch
which causes a mismatch while comparing epochs in
isWithinWeakSubjectivityPeriod
and can cause a restarted node to be stuck if the last state written's latestBlockHeader's slot doesn't alignThis PR fixes the calculation of a state's checkpoint epoch