From 03068ba781c51c521d53561a41470c92336b93e2 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Fri, 9 Feb 2024 21:52:30 -0600 Subject: [PATCH] db: clear blobs when using --clear-db or --force-clear-db (#13605) * Call Close() as part of ClearDB * Add method to clear blob storage * Clear blob storage when clearing DB --- beacon-chain/db/filesystem/blob.go | 14 ++++++++++++++ beacon-chain/db/filesystem/blob_test.go | 13 +++++++++++++ beacon-chain/db/kv/kv.go | 3 +++ beacon-chain/db/slasherkv/kv.go | 4 ++++ beacon-chain/node/node.go | 13 ++++++------- validator/db/kv/db.go | 5 ++++- validator/db/testing/setup_db.go | 3 --- 7 files changed, 44 insertions(+), 11 deletions(-) diff --git a/beacon-chain/db/filesystem/blob.go b/beacon-chain/db/filesystem/blob.go index adc07f329..b334000cb 100644 --- a/beacon-chain/db/filesystem/blob.go +++ b/beacon-chain/db/filesystem/blob.go @@ -228,6 +228,20 @@ func (bs *BlobStorage) Indices(root [32]byte) ([fieldparams.MaxBlobsPerBlock]boo return mask, nil } +// Clear deletes all files on the filesystem. +func (bs *BlobStorage) Clear() error { + dirs, err := listDir(bs.fs, ".") + if err != nil { + return err + } + for _, dir := range dirs { + if err := bs.fs.RemoveAll(dir); err != nil { + return err + } + } + return nil +} + type blobNamer struct { root [32]byte index uint64 diff --git a/beacon-chain/db/filesystem/blob_test.go b/beacon-chain/db/filesystem/blob_test.go index 74300de75..86e512daa 100644 --- a/beacon-chain/db/filesystem/blob_test.go +++ b/beacon-chain/db/filesystem/blob_test.go @@ -88,6 +88,19 @@ func TestBlobStorage_SaveBlobData(t *testing.T) { _, err = bs.Get(expected.BlockRoot(), expected.Index) require.ErrorContains(t, "file does not exist", err) }) + + t.Run("clear", func(t *testing.T) { + blob := testSidecars[0] + b := NewEphemeralBlobStorage(t) + require.NoError(t, b.Save(blob)) + res, err := b.Get(blob.BlockRoot(), blob.Index) + require.NoError(t, err) + require.NotNil(t, res) + require.NoError(t, b.Clear()) + // After clearing, the blob should not exist in the db. + _, err = b.Get(blob.BlockRoot(), blob.Index) + require.ErrorIs(t, err, os.ErrNotExist) + }) } // pollUntil polls a condition function until it returns true or a timeout is reached. diff --git a/beacon-chain/db/kv/kv.go b/beacon-chain/db/kv/kv.go index 4edd992fd..e37bea960 100644 --- a/beacon-chain/db/kv/kv.go +++ b/beacon-chain/db/kv/kv.go @@ -213,6 +213,9 @@ func NewKVStore(ctx context.Context, dirPath string, opts ...KVStoreOption) (*St // ClearDB removes the previously stored database in the data directory. func (s *Store) ClearDB() error { + if err := s.Close(); err != nil { + return fmt.Errorf("failed to close db: %w", err) + } if _, err := os.Stat(s.databasePath); os.IsNotExist(err) { return nil } diff --git a/beacon-chain/db/slasherkv/kv.go b/beacon-chain/db/slasherkv/kv.go index 0c0147fcb..c24acb379 100644 --- a/beacon-chain/db/slasherkv/kv.go +++ b/beacon-chain/db/slasherkv/kv.go @@ -4,6 +4,7 @@ package slasherkv import ( "context" + "fmt" "os" "path" "time" @@ -87,6 +88,9 @@ func NewKVStore(ctx context.Context, dirPath string) (*Store, error) { // ClearDB removes the previously stored database in the data directory. func (s *Store) ClearDB() error { + if err := s.Close(); err != nil { + return fmt.Errorf("failed to close db: %w", err) + } if _, err := os.Stat(s.databasePath); os.IsNotExist(err) { return nil } diff --git a/beacon-chain/node/node.go b/beacon-chain/node/node.go index 3fc7c942c..2e5be1e92 100644 --- a/beacon-chain/node/node.go +++ b/beacon-chain/node/node.go @@ -427,13 +427,12 @@ func (b *BeaconNode) startDB(cliCtx *cli.Context, depositAddress string) error { } if clearDBConfirmed || forceClearDB { log.Warning("Removing database") - if err := d.Close(); err != nil { - return errors.Wrap(err, "could not close db prior to clearing") - } if err := d.ClearDB(); err != nil { return errors.Wrap(err, "could not clear database") } - + if err := b.BlobStorage.Clear(); err != nil { + return errors.Wrap(err, "could not clear blob storage") + } d, err = kv.NewKVStore(b.ctx, dbPath) if err != nil { return errors.Wrap(err, "could not create new database") @@ -531,12 +530,12 @@ func (b *BeaconNode) startSlasherDB(cliCtx *cli.Context) error { } if clearDBConfirmed || forceClearDB { log.Warning("Removing database") - if err := d.Close(); err != nil { - return errors.Wrap(err, "could not close db prior to clearing") - } if err := d.ClearDB(); err != nil { return errors.Wrap(err, "could not clear database") } + if err := b.BlobStorage.Clear(); err != nil { + return errors.Wrap(err, "could not clear blob storage") + } d, err = slasherkv.NewKVStore(b.ctx, dbPath) if err != nil { return errors.Wrap(err, "could not create new database") diff --git a/validator/db/kv/db.go b/validator/db/kv/db.go index 4d153f515..a936be57f 100644 --- a/validator/db/kv/db.go +++ b/validator/db/kv/db.go @@ -3,6 +3,7 @@ package kv import ( "context" + "fmt" "os" "path/filepath" "time" @@ -84,10 +85,12 @@ func (s *Store) view(fn func(*bolt.Tx) error) error { // ClearDB removes any previously stored data at the configured data directory. func (s *Store) ClearDB() error { + if err := s.Close(); err != nil { + return fmt.Errorf("failed to close db: %w", err) + } if _, err := os.Stat(s.databasePath); os.IsNotExist(err) { return nil } - prometheus.Unregister(createBoltCollector(s.db)) return os.Remove(filepath.Join(s.databasePath, ProtectionDbFileName)) } diff --git a/validator/db/testing/setup_db.go b/validator/db/testing/setup_db.go index 2dcf5713a..8c40420ff 100644 --- a/validator/db/testing/setup_db.go +++ b/validator/db/testing/setup_db.go @@ -18,9 +18,6 @@ func SetupDB(t testing.TB, pubkeys [][fieldparams.BLSPubkeyLength]byte) iface.Va t.Fatalf("Failed to instantiate DB: %v", err) } t.Cleanup(func() { - if err := db.Close(); err != nil { - t.Fatalf("Failed to close database: %v", err) - } if err := db.ClearDB(); err != nil { t.Fatalf("Failed to clear database: %v", err) }