code.vegaprotocol.io/vega@v0.79.0/cmd/data-node/commands/networkhistory/latest_history_segment_from_peers.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  
    23  	coreConfig "code.vegaprotocol.io/vega/core/config"
    24  	"code.vegaprotocol.io/vega/datanode/config"
    25  	"code.vegaprotocol.io/vega/datanode/networkhistory"
    26  	vgjson "code.vegaprotocol.io/vega/libs/json"
    27  	"code.vegaprotocol.io/vega/logging"
    28  	"code.vegaprotocol.io/vega/paths"
    29  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    30  )
    31  
    32  type latestHistorySegmentFromPeers struct {
    33  	config.VegaHomeFlag
    34  	coreConfig.OutputFlag
    35  	config.Config
    36  }
    37  
    38  type segmentInfo struct {
    39  	Peer         string
    40  	SwarmKeySeed string
    41  	Segment      *v2.HistorySegment
    42  }
    43  
    44  type latestHistorFromPeersyOutput struct {
    45  	Segments              []segmentInfo
    46  	SuggestedFetchSegment *v2.HistorySegment
    47  }
    48  
    49  func (o *latestHistorFromPeersyOutput) printHuman() {
    50  	segmentsInfo := "Most Recent History Segments:\n\n"
    51  	for _, segment := range o.Segments {
    52  		segmentsInfo += fmt.Sprintf("Peer:%-39s,  Swarm Key:%s, Segment{%s}\n\n", segment.Peer, segment.SwarmKeySeed, segment.Segment)
    53  	}
    54  	fmt.Println(segmentsInfo)
    55  	fmt.Printf("Suggested segment to use to fetch network history data {%s}\n\n", o.SuggestedFetchSegment)
    56  }
    57  
    58  func (cmd *latestHistorySegmentFromPeers) Execute(_ []string) error {
    59  	ctx, cfunc := context.WithCancel(context.Background())
    60  	defer cfunc()
    61  	cfg := logging.NewDefaultConfig()
    62  	cfg.Custom.Zap.Level = logging.InfoLevel
    63  	cfg.Environment = "custom"
    64  	log := logging.NewLoggerFromConfig(
    65  		cfg,
    66  	)
    67  	defer log.AtExit()
    68  
    69  	vegaPaths := paths.New(cmd.VegaHome)
    70  	err := fixConfig(&cmd.Config, vegaPaths)
    71  	if err != nil {
    72  		handleErr(log, cmd.Output.IsJSON(), "failed to fix config", err)
    73  		os.Exit(1)
    74  	}
    75  
    76  	if !datanodeLive(cmd.Config) {
    77  		return fmt.Errorf("datanode must be running for this command to work")
    78  	}
    79  
    80  	client, conn, err := getDatanodeClient(cmd.Config)
    81  	if err != nil {
    82  		handleErr(log, cmd.Output.IsJSON(), "failed to get datanode client", err)
    83  		os.Exit(1)
    84  	}
    85  	defer func() { _ = conn.Close() }()
    86  
    87  	resp, err := client.GetActiveNetworkHistoryPeerAddresses(ctx, &v2.GetActiveNetworkHistoryPeerAddressesRequest{})
    88  	if err != nil {
    89  		handleErr(log, cmd.Output.IsJSON(), "failed to get active peer addresses", errorFromGrpcError("", err))
    90  		os.Exit(1)
    91  	}
    92  
    93  	peerAddresses := resp.IpAddresses
    94  
    95  	grpcAPIPorts := []int{cmd.Config.API.Port}
    96  	grpcAPIPorts = append(grpcAPIPorts, cmd.Config.NetworkHistory.Initialise.GrpcAPIPorts...)
    97  	selectedResponse, peerToResponse, err := networkhistory.GetMostRecentHistorySegmentFromPeersAddresses(ctx, peerAddresses,
    98  		cmd.Config.NetworkHistory.Store.GetSwarmKeySeed(log, cmd.Config.ChainID), grpcAPIPorts)
    99  	if err != nil {
   100  		handleErr(log, cmd.Output.IsJSON(), "failed to get most recent history segment from peers", err)
   101  		os.Exit(1)
   102  	}
   103  
   104  	output := latestHistorFromPeersyOutput{}
   105  	output.Segments = []segmentInfo{}
   106  
   107  	for peer, segment := range peerToResponse {
   108  		output.Segments = append(output.Segments, segmentInfo{
   109  			Peer:         peer,
   110  			SwarmKeySeed: segment.SwarmKeySeed,
   111  			Segment:      segment.Segment,
   112  		})
   113  	}
   114  
   115  	if selectedResponse != nil {
   116  		output.SuggestedFetchSegment = selectedResponse.Response.Segment
   117  	}
   118  
   119  	if cmd.Output.IsJSON() {
   120  		if err := vgjson.Print(&output); err != nil {
   121  			handleErr(log, cmd.Output.IsJSON(), "failed to marshal output", err)
   122  			os.Exit(1)
   123  		}
   124  		return nil
   125  	}
   126  	output.printHuman()
   127  
   128  	return nil
   129  }