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.