diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 106446c0af3..14a8669b397 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -12,6 +12,7 @@ import ( "io" "os" "path" + "path/filepath" "runtime/pprof" "strings" @@ -128,6 +129,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 +290,26 @@ 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") + } + + err = removeExistingChain(cctx, lr) + if err != nil { + return err + } + } + chainfile := cctx.String("import-chain") snapshot := cctx.String("import-snapshot") if chainfile != "" || snapshot != "" { @@ -722,3 +747,59 @@ func slashFilterMinedBlock(ctx context.Context, sf *slashfilter.SlashFilter, a l return nil, nil, nil } + +func removeExistingChain(cctx *cli.Context, lr repo.Repo) error { + lockedRepo, err := lr.Lock(repo.FullNode) + if err != nil { + return xerrors.Errorf("error locking repo: %w", err) + } + // Ensure that lockedRepo is closed when this function exits + defer func() { + if closeErr := lockedRepo.Close(); closeErr != nil { + log.Errorf("Error closing the lockedRepo: %v", closeErr) + } + }() + + cfg, err := lockedRepo.Config() + if err != nil { + return xerrors.Errorf("error getting config: %w", err) + } + + fullNodeConfig, ok := cfg.(*config.FullNode) + if !ok { + return xerrors.Errorf("wrong config type: %T", cfg) + } + + if fullNodeConfig.Chainstore.EnableSplitstore { + log.Info("removing splitstore directory...") + err = deleteSplitstoreDir(lockedRepo) + if err != nil { + 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 { + return xerrors.Errorf("error removing chain directory: %w", err) + } + + log.Info("chain and splitstore data have been removed") + return 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) +} diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md index 751182a4341..1674e2ffdda 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