code.vegaprotocol.io/vega@v0.79.0/cmd/data-node/commands/networkhistory/rollback.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package networkhistory
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  	"strconv"
    23  
    24  	"code.vegaprotocol.io/vega/cmd/vegawallet/commands/flags"
    25  	"code.vegaprotocol.io/vega/datanode/config"
    26  	"code.vegaprotocol.io/vega/datanode/networkhistory"
    27  	vgterm "code.vegaprotocol.io/vega/libs/term"
    28  	"code.vegaprotocol.io/vega/logging"
    29  	"code.vegaprotocol.io/vega/paths"
    30  )
    31  
    32  type rollbackCmd struct {
    33  	config.VegaHomeFlag
    34  	config.Config
    35  
    36  	Force bool `description:"do not prompt for confirmation" long:"force" short:"f"`
    37  }
    38  
    39  func (cmd *rollbackCmd) Execute(args []string) error {
    40  	ctx, cfunc := context.WithCancel(context.Background())
    41  	defer cfunc()
    42  	cfg := logging.NewDefaultConfig()
    43  	cfg.Custom.Zap.Level = logging.WarnLevel
    44  	cfg.Environment = "custom"
    45  	log := logging.NewLoggerFromConfig(
    46  		cfg,
    47  	)
    48  	defer log.AtExit()
    49  
    50  	if len(args) != 1 {
    51  		return errors.New("expected <rollback-to-height>")
    52  	}
    53  
    54  	rollbackToHeight, err := strconv.ParseInt(args[0], 10, 64)
    55  	if err != nil {
    56  		return fmt.Errorf("failed to parse rollback to height: %w", err)
    57  	}
    58  
    59  	vegaPaths := paths.New(cmd.VegaHome)
    60  	err = fixConfig(&cmd.Config, vegaPaths)
    61  	if err != nil {
    62  		return fmt.Errorf("failed to fix config:%w", err)
    63  	}
    64  
    65  	if datanodeLive(cmd.Config) {
    66  		return fmt.Errorf("datanode must be shutdown before it can be rolled back")
    67  	}
    68  
    69  	if !cmd.Force && vgterm.HasTTY() {
    70  		if !flags.YesOrNo("Running this command will kill all existing database connections, do you want to continue?") {
    71  			return nil
    72  		}
    73  	}
    74  
    75  	if err := networkhistory.KillAllConnectionsToDatabase(ctx, cmd.SQLStore.ConnectionConfig); err != nil {
    76  		return fmt.Errorf("failed to kill all connections to database: %w", err)
    77  	}
    78  
    79  	connPool, err := getCommandConnPool(ctx, cmd.Config.SQLStore.ConnectionConfig)
    80  	if err != nil {
    81  		return fmt.Errorf("failed to get command connection pool: %w", err)
    82  	}
    83  	defer connPool.Close()
    84  
    85  	networkHistoryService, err := createNetworkHistoryService(ctx, log, cmd.Config, connPool, vegaPaths)
    86  	if err != nil {
    87  		return fmt.Errorf("failed to created network history service: %w", err)
    88  	}
    89  	defer networkHistoryService.Stop()
    90  
    91  	loadLog := newLoadLog()
    92  	defer loadLog.AtExit()
    93  	err = networkHistoryService.RollbackToHeight(ctx, loadLog, rollbackToHeight)
    94  	if err != nil {
    95  		return fmt.Errorf("failed to rollback datanode: %w", err)
    96  	}
    97  
    98  	fmt.Printf("Rolled back datanode to height %d\n", rollbackToHeight)
    99  
   100  	return nil
   101  }