diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 106446c0a..c77623876 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -12,6 +12,7 @@ import ( "io" "os" "path" + "path/filepath" "runtime/pprof" "strings" @@ -27,6 +28,7 @@ import ( "go.opencensus.io/stats" "go.opencensus.io/stats/view" "go.opencensus.io/tag" + "go.uber.org/multierr" "golang.org/x/xerrors" "gopkg.in/cheggaaa/pb.v1" @@ -128,6 +130,10 @@ var DaemonCmd = &cli.Command{ Name: "import-snapshot", Usage: "import chain state from a given chain export file or url", }, + &cli.BoolFlag{ + Name: "remove-existing-chain", + Usage: "remove existing chain and splitstore data on a snapshot-import", + }, &cli.BoolFlag{ Name: "halt-after-import", Usage: "halt the process after importing chain from file", @@ -285,6 +291,69 @@ var DaemonCmd = &cli.Command{ } } + if cctx.Bool("remove-existing-chain") { + lr, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return xerrors.Errorf("error opening fs repo: %w", err) + } + + exists, err := lr.Exists() + if err != nil { + return err + } + if !exists { + return xerrors.Errorf("lotus repo doesn't exist") + } + + lockedRepo, err := lr.Lock(repo.FullNode) + if err != nil { + return xerrors.Errorf("error locking repo: %w", err) + } + + cfg, err := lockedRepo.Config() + if err != nil { + lockedRepo.Close() + return xerrors.Errorf("error getting config: %w", err) + } + + fullNodeConfig, ok := cfg.(*config.FullNode) + if !ok { + lockedRepo.Close() + return xerrors.Errorf("wrong config type: %T", cfg) + } + + if fullNodeConfig.Chainstore.EnableSplitstore { + log.Info("removing splitstore directory...") + err = deleteSplitstoreDir(lockedRepo) + if err != nil { + lockedRepo.Close() + return xerrors.Errorf("error removing splitstore directory: %w", err) + } + } + + // Get the base repo path + repoPath := lockedRepo.Path() + + // Construct the path to the chain directory + chainPath := filepath.Join(repoPath, "datastore", "chain") + + log.Info("removing chain directory:", chainPath) + + err = os.RemoveAll(chainPath) + if err != nil { + lockedRepo.Close() + return xerrors.Errorf("error removing chain directory: %w", err) + } + + log.Info("chain and splitstore data have been removed") + + // Explicitly close the lockedRepo now that we're done with it. + err = lockedRepo.Close() + if err != nil { + return xerrors.Errorf("error releasing lock: %w", err) + } + } + chainfile := cctx.String("import-chain") snapshot := cctx.String("import-snapshot") if chainfile != "" || snapshot != "" { @@ -722,3 +791,36 @@ func slashFilterMinedBlock(ctx context.Context, sf *slashfilter.SlashFilter, a l return nil, nil, nil } + +func deleteSplitstoreDir(lr repo.LockedRepo) error { + path, err := lr.SplitstorePath() + if err != nil { + return xerrors.Errorf("error getting splitstore path: %w", err) + } + + return os.RemoveAll(path) +} + +func clearSplitstoreDir(lr repo.LockedRepo) error { + path, err := lr.SplitstorePath() + if err != nil { + return xerrors.Errorf("error getting splitstore path: %w", err) + } + + entries, err := os.ReadDir(path) + if err != nil { + return xerrors.Errorf("error reading splitstore directory %s: %W", path, err) + } + + var result error + for _, e := range entries { + target := filepath.Join(path, e.Name()) + err = os.RemoveAll(target) + if err != nil { + log.Errorf("error removing %s: %s", target, err) + result = multierr.Append(result, err) + } + } + + return result +} diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index 751182a43..1674e2ffd 100644 --- a/documentation/en/cli-lotus.md +++ b/documentation/en/cli-lotus.md @@ -65,6 +65,7 @@ OPTIONS: --bootstrap (default: true) --import-chain value on first run, load chain from given file or url and validate --import-snapshot value import chain state from a given chain export file or url + --remove-existing-chain remove existing chain and splitstore data on a snapshot-import (default: false) --halt-after-import halt the process after importing chain from file (default: false) --lite start lotus in lite mode (default: false) --pprof value specify name of file for writing cpu profile to