code.vegaprotocol.io/vega@v0.79.0/cmd/data-node/commands/networkhistory/latest_history_segment.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  	"fmt"
    21  	"os"
    22  	"path/filepath"
    23  
    24  	coreConfig "code.vegaprotocol.io/vega/core/config"
    25  	"code.vegaprotocol.io/vega/datanode/config"
    26  	"code.vegaprotocol.io/vega/datanode/networkhistory/store"
    27  	vgjson "code.vegaprotocol.io/vega/libs/json"
    28  	"code.vegaprotocol.io/vega/logging"
    29  	"code.vegaprotocol.io/vega/paths"
    30  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    31  )
    32  
    33  var errNoHistorySegmentFound = fmt.Errorf("no history segments found")
    34  
    35  type latestHistorySegment struct {
    36  	config.VegaHomeFlag
    37  	coreConfig.OutputFlag
    38  	config.Config
    39  }
    40  
    41  type latestHistoryOutput struct {
    42  	LatestSegment *v2.HistorySegment
    43  }
    44  
    45  func (o *latestHistoryOutput) printHuman() {
    46  	fmt.Printf("Latest segment to use data {%s}\n\n", o.LatestSegment)
    47  }
    48  
    49  func (cmd *latestHistorySegment) Execute(_ []string) error {
    50  	ctx, cfunc := context.WithCancel(context.Background())
    51  	defer cfunc()
    52  	cfg := logging.NewDefaultConfig()
    53  	cfg.Custom.Zap.Level = logging.ErrorLevel
    54  	cfg.Environment = "custom"
    55  	log := logging.NewLoggerFromConfig(
    56  		cfg,
    57  	)
    58  	defer log.AtExit()
    59  
    60  	vegaPaths := paths.New(cmd.VegaHome)
    61  	err := fixConfig(&cmd.Config, vegaPaths)
    62  	if err != nil {
    63  		handleErr(log, cmd.Output.IsJSON(), "failed to fix config", err)
    64  		os.Exit(1)
    65  	}
    66  
    67  	ctx, cancelFn := context.WithCancel(ctx)
    68  	defer cancelFn()
    69  
    70  	var latestSegment *v2.HistorySegment
    71  	if datanodeLive(cmd.Config) {
    72  		client, conn, err := getDatanodeClient(cmd.Config)
    73  		if err != nil {
    74  			handleErr(log, cmd.Output.IsJSON(), "failed to get datanode client", err)
    75  			os.Exit(1)
    76  		}
    77  		defer func() { _ = conn.Close() }()
    78  
    79  		response, err := client.ListAllNetworkHistorySegments(ctx, &v2.ListAllNetworkHistorySegmentsRequest{})
    80  		if err != nil {
    81  			handleErr(log, cmd.Output.IsJSON(), "failed to list all network history segments", errorFromGrpcError("", err))
    82  			os.Exit(1)
    83  		}
    84  
    85  		if len(response.Segments) < 1 {
    86  			handleErr(log, cmd.Output.IsJSON(), errNoHistorySegmentFound.Error(), errNoHistorySegmentFound)
    87  			os.Exit(1)
    88  		}
    89  
    90  		latestSegment = response.Segments[0]
    91  	} else {
    92  		// we don't need to fire up a whole IPFS node, lets just dip our fingers into the DB
    93  		idx, err := store.NewIndex(filepath.Join(vegaPaths.StatePathFor(paths.DataNodeNetworkHistoryHome), "store", "index"), log)
    94  		if err != nil {
    95  			handleErr(log, cmd.Output.IsJSON(), "failed to create new index", err)
    96  			os.Exit(1)
    97  		}
    98  		defer idx.Close()
    99  
   100  		segments, err := idx.ListAllEntriesOldestFirst()
   101  		if err != nil {
   102  			handleErr(log, cmd.Output.IsJSON(), "failed to list all network history segments", err)
   103  			os.Exit(1)
   104  		}
   105  
   106  		if len(segments) < 1 {
   107  			handleErr(log, cmd.Output.IsJSON(), errNoHistorySegmentFound.Error(), errNoHistorySegmentFound)
   108  			os.Exit(1)
   109  		}
   110  
   111  		latestSegmentIndex := segments[len(segments)-1]
   112  
   113  		latestSegment = &v2.HistorySegment{
   114  			FromHeight:               latestSegmentIndex.GetFromHeight(),
   115  			ToHeight:                 latestSegmentIndex.GetToHeight(),
   116  			HistorySegmentId:         latestSegmentIndex.GetHistorySegmentId(),
   117  			PreviousHistorySegmentId: latestSegmentIndex.GetPreviousHistorySegmentId(),
   118  		}
   119  	}
   120  
   121  	output := latestHistoryOutput{
   122  		LatestSegment: latestSegment,
   123  	}
   124  
   125  	if cmd.Output.IsJSON() {
   126  		if err := vgjson.Print(&output); err != nil {
   127  			handleErr(log, cmd.Output.IsJSON(), "failed to marshal output", err)
   128  			os.Exit(1)
   129  		}
   130  	} else {
   131  		output.printHuman()
   132  	}
   133  
   134  	return nil
   135  }