-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
migration to fix index corruption from pr 13486
- Loading branch information
Showing
3 changed files
with
90 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package kv | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/prysmaticlabs/prysm/v5/config/params" | ||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" | ||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" | ||
bolt "go.etcd.io/bbolt" | ||
) | ||
|
||
var migrationFinalizedParent = []byte("parent_bug_32fb183") | ||
|
||
func migrateFinalizedParent(ctx context.Context, db *bolt.DB) error { | ||
if updateErr := db.Update(func(tx *bolt.Tx) error { | ||
mb := tx.Bucket(migrationsBucket) | ||
if b := mb.Get(migrationFinalizedParent); bytes.Equal(b, migrationCompleted) { | ||
return nil // Migration already completed. | ||
} | ||
|
||
bkt := tx.Bucket(finalizedBlockRootsIndexBucket) | ||
if bkt == nil { | ||
return fmt.Errorf("unable to read %s bucket for migration", finalizedBlockRootsIndexBucket) | ||
} | ||
bb := tx.Bucket(blocksBucket) | ||
if bb == nil { | ||
return fmt.Errorf("unable to read %s bucket for migration", blocksBucket) | ||
} | ||
|
||
c := bkt.Cursor() | ||
var skipped primitives.Slot | ||
foundBuggedIdx := false | ||
maxBugSearch := params.BeaconConfig().SlotsPerEpoch * 100 | ||
for k, v := c.Last(); k != nil; k, v = c.Prev() { | ||
// check if context is cancelled in between | ||
if ctx.Err() != nil { | ||
return ctx.Err() | ||
} | ||
|
||
idxEntry := ðpb.FinalizedBlockRootContainer{} | ||
if err := decode(ctx, v, idxEntry); err != nil { | ||
return errors.Wrapf(err, "unable to decode finalized block root container for root=%#x", k) | ||
} | ||
// Not one of the corrupt values | ||
if !bytes.Equal(idxEntry.ParentRoot, k) { | ||
skipped += 1 | ||
if !foundBuggedIdx && skipped > maxBugSearch { | ||
break | ||
} | ||
continue | ||
} | ||
foundBuggedIdx = true | ||
log.WithField("root", fmt.Sprintf("%#x", k)).Debug("found index entry with incorrect parent root") | ||
|
||
// Look up full block to get the correct parent root. | ||
encBlk := bb.Get(k) | ||
if encBlk == nil { | ||
return errors.Wrapf(ErrNotFound, "could not find block for corrupt finalized index entry %#x", k) | ||
} | ||
blk, err := unmarshalBlock(ctx, encBlk) | ||
if err != nil { | ||
return errors.Wrapf(err, "unable to decode block for root=%#x", k) | ||
} | ||
// Replace parent root in the index with the correct value and write it back. | ||
pr := blk.Block().ParentRoot() | ||
idxEntry.ParentRoot = pr[:] | ||
idxEnc, err := encode(ctx, idxEntry) | ||
if err != nil { | ||
return errors.Wrapf(err, "failed to encode finalized index entry for root=%#x", k) | ||
} | ||
if err := bkt.Put(k, idxEnc); err != nil { | ||
return errors.Wrapf(err, "failed to update finalized index entry for root=%#x", k) | ||
} | ||
log.WithField("root", fmt.Sprintf("%#x", k)). | ||
WithField("parentRoot", fmt.Sprintf("%#x", idxEntry.ParentRoot)). | ||
Debug("updated corrupt index entry with correct parent") | ||
} | ||
// Mark migration complete. | ||
return mb.Put(migrationFinalizedParent, migrationCompleted) | ||
}); updateErr != nil { | ||
log.WithError(updateErr).Errorf("could not run finalized parent root index repair migration") | ||
return updateErr | ||
} | ||
return nil | ||
} |