From aface5f9b832711fe4499ee58abc6196e22587bd Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 8 Mar 2022 09:20:11 -0800 Subject: [PATCH] cmd: make reset more safe (backport #8081) (#8090) Backport notes: - Revert command declaration to the old explicit format. - Update threading of the keyType argument. - Fix function naming collision. --- .../commands/reset_priv_validator.go | 88 ++++++++++++++++--- cmd/tendermint/main.go | 1 + 2 files changed, 79 insertions(+), 10 deletions(-) diff --git a/cmd/tendermint/commands/reset_priv_validator.go b/cmd/tendermint/commands/reset_priv_validator.go index 8745e55d8..e9e2e1fd4 100644 --- a/cmd/tendermint/commands/reset_priv_validator.go +++ b/cmd/tendermint/commands/reset_priv_validator.go @@ -2,6 +2,7 @@ package commands import ( "os" + "path/filepath" "github.com/spf13/cobra" @@ -16,11 +17,20 @@ import ( var ResetAllCmd = &cobra.Command{ Use: "unsafe-reset-all", Short: "(unsafe) Remove all the data and WAL, reset this node's validator to genesis state", - RunE: resetAll, + RunE: resetAllCmd, } var keepAddrBook bool +// ResetStateCmd removes the database of the specified Tendermint core instance. +var ResetStateCmd = &cobra.Command{ + Use: "reset-state", + Short: "Remove all the data and WAL", + RunE: func(cmd *cobra.Command, args []string) error { + return resetState(config.DBDir(), logger, keyType) + }, +} + func init() { ResetAllCmd.Flags().BoolVar(&keepAddrBook, "keep-addr-book", false, "keep the address book intact") ResetPrivValidatorCmd.Flags().StringVar(&keyType, "key", types.ABCIPubKeyTypeEd25519, @@ -36,20 +46,19 @@ var ResetPrivValidatorCmd = &cobra.Command{ // XXX: this is totally unsafe. // it's only suitable for testnets. -func resetAll(cmd *cobra.Command, args []string) error { - return ResetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidator.KeyFile(), +func resetAllCmd(cmd *cobra.Command, args []string) error { + return resetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidator.KeyFile(), config.PrivValidator.StateFile(), logger) } // XXX: this is totally unsafe. // it's only suitable for testnets. func resetPrivValidator(cmd *cobra.Command, args []string) error { - return resetFilePV(config.PrivValidator.KeyFile(), config.PrivValidator.StateFile(), logger) + return resetFilePV(config.PrivValidator.KeyFile(), config.PrivValidator.StateFile(), logger, keyType) } -// ResetAll removes address book files plus all data, and resets the privValdiator data. -// Exported so other CLI tools can use it. -func ResetAll(dbDir, addrBookFile, privValKeyFile, privValStateFile string, logger log.Logger) error { +// resetAllCmd removes address book files plus all data, and resets the privValidator data. +func resetAll(dbDir, addrBookFile, privValKeyFile, privValStateFile string, logger log.Logger) error { if keepAddrBook { logger.Info("The address book remains intact") } else { @@ -60,14 +69,73 @@ func ResetAll(dbDir, addrBookFile, privValKeyFile, privValStateFile string, logg } else { logger.Error("Error removing all blockchain history", "dir", dbDir, "err", err) } - // recreate the dbDir since the privVal state needs to live there + + return resetFilePV(privValKeyFile, privValStateFile, logger, keyType) +} + +// resetState removes address book files plus all databases. +func resetState(dbDir string, logger log.Logger, keyType string) error { + blockdb := filepath.Join(dbDir, "blockstore.db") + state := filepath.Join(dbDir, "state.db") + wal := filepath.Join(dbDir, "cs.wal") + evidence := filepath.Join(dbDir, "evidence.db") + txIndex := filepath.Join(dbDir, "tx_index.db") + peerstore := filepath.Join(dbDir, "peerstore.db") + + if tmos.FileExists(blockdb) { + if err := os.RemoveAll(blockdb); err == nil { + logger.Info("Removed all blockstore.db", "dir", blockdb) + } else { + logger.Error("error removing all blockstore.db", "dir", blockdb, "err", err) + } + } + + if tmos.FileExists(state) { + if err := os.RemoveAll(state); err == nil { + logger.Info("Removed all state.db", "dir", state) + } else { + logger.Error("error removing all state.db", "dir", state, "err", err) + } + } + + if tmos.FileExists(wal) { + if err := os.RemoveAll(wal); err == nil { + logger.Info("Removed all cs.wal", "dir", wal) + } else { + logger.Error("error removing all cs.wal", "dir", wal, "err", err) + } + } + + if tmos.FileExists(evidence) { + if err := os.RemoveAll(evidence); err == nil { + logger.Info("Removed all evidence.db", "dir", evidence) + } else { + logger.Error("error removing all evidence.db", "dir", evidence, "err", err) + } + } + + if tmos.FileExists(txIndex) { + if err := os.RemoveAll(txIndex); err == nil { + logger.Info("Removed tx_index.db", "dir", txIndex) + } else { + logger.Error("error removing tx_index.db", "dir", txIndex, "err", err) + } + } + + if tmos.FileExists(peerstore) { + if err := os.RemoveAll(peerstore); err == nil { + logger.Info("Removed peerstore.db", "dir", peerstore) + } else { + logger.Error("error removing peerstore.db", "dir", peerstore, "err", err) + } + } if err := tmos.EnsureDir(dbDir, 0700); err != nil { logger.Error("unable to recreate dbDir", "err", err) } - return resetFilePV(privValKeyFile, privValStateFile, logger) + return nil } -func resetFilePV(privValKeyFile, privValStateFile string, logger log.Logger) error { +func resetFilePV(privValKeyFile, privValStateFile string, logger log.Logger, keyType string) error { if _, err := os.Stat(privValKeyFile); err == nil { pv, err := privval.LoadFilePVEmptyState(privValKeyFile, privValStateFile) if err != nil { diff --git a/cmd/tendermint/main.go b/cmd/tendermint/main.go index 52a00e4c0..b0ca549e5 100644 --- a/cmd/tendermint/main.go +++ b/cmd/tendermint/main.go @@ -23,6 +23,7 @@ func main() { cmd.ReplayConsoleCmd, cmd.ResetAllCmd, cmd.ResetPrivValidatorCmd, + cmd.ResetStateCmd, cmd.ShowValidatorCmd, cmd.TestnetFilesCmd, cmd.ShowNodeIDCmd,