Inability to restore confirmed checkpoints to sealed state
Description
The SetCheckpointForgotten function in the btccheckpoint module is intended to transition an epoch in the submitted or confirmed states to the sealed state. However, due to the hardcoded from parameter in the setCheckpointStatus function, only epochs in the submitted state can successfully transition.
Specifically, in SetCheckpointForgotten, the function call to setCheckpointStatus passes types.Submitted as the expected from state:
ckpt, err := k.setCheckpointStatus(ctx, epoch, types.Submitted, types.Sealed)Since the setCheckpointStatus function contains a strict equality check,
if ckptWithMeta.Status != from {
return nil, types.ErrInvalidCkptStatus.Wrapf("the status of the checkpoint should be %s", from.String())
}epochs in the confirmed state cannot satisfy this condition and are unable to transition to sealed as intended.
This issue can be observed in the error triggered here↗.
Although confirmed checkpoints being reverted is considered a rare edge case, the caller of SetCheckpointForgotten implicitly assumes that such a transition should be possible.
Impact
The checkpointing module does not properly handle reorg scenarios where confirmed epochs should be transitioned to the sealed state.
Recommendations
Modify SetCheckpointForgotten to allow both submitted and confirmed epochs to transition to the sealed state.
Remediation
This issue has been acknowledged by Babylon Labs, and a fix was implemented in commit 8d23c5de↗.
This was remediated by adding logic that changes the setCheckpointStatus function to accept multiple from states, adding the missed confirmed from state to the list of possible transitions.