+// Rollback rollback chain from one height to targetHeight
+func Rollback(config *cfg.Config, targetHeight uint64) error {
+ if err := initNodeConfig(config); err != nil {
+ return err
+ }
+
+ // Get store
+ if config.DBBackend != "leveldb" {
+ return errors.New("Param db_backend is invalid, use leveldb")
+ }
+
+ coreDB := dbm.NewDB("core", config.DBBackend, config.DBDir())
+ store := database.NewStore(coreDB)
+
+ dispatcher := event.NewDispatcher()
+ movCore := mov.NewCore(config.DBBackend, config.DBDir(), consensus.ActiveNetParams.MovStartHeight)
+ txPool := protocol.NewTxPool(store, []protocol.DustFilterer{movCore}, dispatcher)
+ chain, err := protocol.NewChain(store, txPool, []protocol.SubProtocol{movCore}, dispatcher)
+ if err != nil {
+ return err
+ }
+
+ hsm, err := pseudohsm.New(config.KeysDir())
+ if err != nil {
+ return err
+ }
+
+ walletDB := dbm.NewDB("wallet", config.DBBackend, config.DBDir())
+ walletStore := database.NewWalletStore(walletDB)
+ accountStore := database.NewAccountStore(walletDB)
+ accounts := account.NewManager(accountStore, chain)
+ assets := asset.NewRegistry(walletDB, chain)
+ wallet, err := w.NewWallet(walletStore, accounts, assets, hsm, chain, dispatcher, config.Wallet.TxIndex)
+ if err != nil {
+ return err
+ }
+
+ if err := wallet.Rollback(targetHeight); err != nil {
+ return err
+ }
+
+ return chain.Rollback(targetHeight)
+}
+
+func initNodeConfig(config *cfg.Config) error {
+ if err := lockDataDirectory(config); err != nil {
+ log.WithField("err", err).Info("Error: " + err.Error())
+ return err
+ }
+
+ if err := cfg.LoadFederationFile(config.FederationFile(), config); err != nil {
+ log.WithField("err", err).Info("Failed to load federated information")
+ return err
+ }
+
+ if err := consensus.InitActiveNetParams(config.ChainID); err != nil {
+ log.Fatalf("Failed to init ActiveNetParams:[%s]", err.Error())
+ }
+
+ cfg.CommonConfig = config
+ return nil
+}
+