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 }