hdiff restart-support: add error types and startup handling

This commit is contained in:
Preston Van Loon
2026-02-05 15:23:50 -06:00
parent cee0b57601
commit fc51fb28d6
4 changed files with 20 additions and 4 deletions

View File

@@ -26,6 +26,15 @@ var ErrNotFoundMetadataSeqNum = errors.Wrap(ErrNotFound, "metadata sequence numb
// but the database was created without state-diff support.
var ErrStateDiffIncompatible = errors.New("state-diff feature enabled but database was created without state-diff support")
// ErrStateDiffCorrupted is returned when state-diff metadata or data is missing or invalid.
var ErrStateDiffCorrupted = errors.New("state-diff database corrupted")
// ErrStateDiffExponentMismatch is returned when configured exponents differ from stored metadata.
var ErrStateDiffExponentMismatch = errors.New("state-diff exponents mismatch")
// ErrStateDiffMissingSnapshot is returned when the offset snapshot is missing.
var ErrStateDiffMissingSnapshot = errors.New("state-diff offset snapshot missing")
var errEmptyBlockSlice = errors.New("[]blocks.ROBlock is empty")
var errIncorrectBlockParent = errors.New("unexpected missing or forked blocks in a []ROBlock")
var errFinalizedChildNotFound = errors.New("unable to find finalized root descending from backfill batch")

View File

@@ -228,11 +228,12 @@ func (kv *Store) startStateDiff(ctx context.Context) error {
if hasOffset {
storedExponents, err := kv.loadStateDiffExponents()
if err != nil {
return errors.Wrap(err, "state-diff metadata missing or invalid; re-sync required")
return fmt.Errorf("%w: state-diff metadata missing or invalid; re-sync required: %v", ErrStateDiffCorrupted, err)
}
currentExponents := flags.Get().StateDiffExponents
if !slices.Equal(storedExponents, currentExponents) {
return fmt.Errorf(
return errors.Wrapf(
ErrStateDiffExponentMismatch,
"state-diff exponents changed; database incompatible. "+
"Database was initialized with: %v. "+
"Current configuration: %v. "+

View File

@@ -3,11 +3,11 @@ package kv
import (
"encoding/binary"
"errors"
"fmt"
"sync"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
"github.com/OffchainLabs/prysm/v7/cmd/beacon-chain/flags"
pkgerrors "github.com/pkg/errors"
"go.etcd.io/bbolt"
)
@@ -45,7 +45,7 @@ func populateStateDiffCacheFromDB(s *Store, offset uint64) (*stateDiffCache, err
anchor0, err := s.getFullSnapshot(offset)
if err != nil {
return nil, fmt.Errorf("state diff cache: missing offset snapshot at %d: %w", offset, err)
return nil, pkgerrors.Wrapf(ErrStateDiffMissingSnapshot, "state diff cache: missing offset snapshot at %d", offset)
}
cache.anchors[0] = anchor0
cache.levelsWithData[0] = true

View File

@@ -550,6 +550,12 @@ func openDB(ctx context.Context, dbPath string, clearer *dbClearer) (*kv.Store,
cfg := features.Get()
cfg.EnableStateDiff = false
features.Init(cfg)
} else if errors.Is(err, kv.ErrStateDiffExponentMismatch) {
log.WithError(err).Error("State-diff configuration mismatch; restart aborted. Use the stored exponents or re-sync the database.")
return nil, err
} else if errors.Is(err, kv.ErrStateDiffMissingSnapshot) || errors.Is(err, kv.ErrStateDiffCorrupted) {
log.WithError(err).Error("State-diff database corrupted; restart aborted. Delete database and re-sync from genesis/checkpoint.")
return nil, err
} else if err != nil {
return nil, errors.Wrapf(err, "could not create database at %s", dbPath)
}