code.vegaprotocol.io/vega@v0.79.0/cmd/data-node/commands/networkhistory/fetch.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/datanode/config" 25 "code.vegaprotocol.io/vega/datanode/networkhistory" 26 "code.vegaprotocol.io/vega/datanode/service" 27 "code.vegaprotocol.io/vega/datanode/sqlstore" 28 "code.vegaprotocol.io/vega/logging" 29 "code.vegaprotocol.io/vega/paths" 30 31 "google.golang.org/grpc/status" 32 ) 33 34 type fetchCmd struct { 35 config.VegaHomeFlag 36 config.Config 37 } 38 39 func (cmd *fetchCmd) Execute(args []string) error { 40 ctx, cfunc := context.WithCancel(context.Background()) 41 defer cfunc() 42 cfg := logging.NewDefaultConfig() 43 cfg.Custom.Zap.Level = logging.InfoLevel 44 cfg.Environment = "custom" 45 log := logging.NewLoggerFromConfig( 46 cfg, 47 ) 48 defer log.AtExit() 49 50 if len(args) != 2 { 51 return errors.New("expected <history-segment-id> <num-blocks-to-fetch>") 52 } 53 54 rootSegmentID := args[0] 55 56 numBlocksToFetch, err := strconv.ParseInt(args[1], 10, 64) 57 if err != nil { 58 return fmt.Errorf("failed to parse number of blocks to fetch: %w", err) 59 } 60 61 vegaPaths := paths.New(cmd.VegaHome) 62 err = fixConfig(&cmd.Config, vegaPaths) 63 if err != nil { 64 return fmt.Errorf("failed to fix config:%w", err) 65 } 66 67 err = verifyChainID(ctx, cmd.SQLStore.ConnectionConfig, cmd.ChainID) 68 if err != nil { 69 return fmt.Errorf("failed to verify chain id:%w", err) 70 } 71 72 if !datanodeLive(cmd.Config) { 73 return fmt.Errorf("datanode must be running for this command to work") 74 } 75 76 client := getDatanodeAdminClient(log, cmd.Config) 77 blocksFetched, err := networkhistory.FetchHistoryBlocks(ctx, func(s string, args ...interface{}) { 78 fmt.Printf(s+"\n", args...) 79 }, rootSegmentID, 80 func(ctx context.Context, historySegmentId string) (networkhistory.FetchResult, error) { 81 resp, err := client.FetchNetworkHistorySegment(ctx, historySegmentId) 82 if err != nil { 83 return networkhistory.FetchResult{}, 84 errorFromGrpcError("failed to fetch network history segment", err) 85 } 86 87 return networkhistory.FetchResult{ 88 HeightFrom: resp.HeightFrom, 89 HeightTo: resp.HeightTo, 90 PreviousHistorySegmentID: resp.PreviousHistorySegmentID, 91 }, nil 92 }, numBlocksToFetch) 93 if err != nil { 94 return fmt.Errorf("failed to fetch history blocks:%w", err) 95 } 96 97 fmt.Printf("\nfinished fetching history, %d blocks retrieved \n", blocksFetched) 98 99 return nil 100 } 101 102 func verifyChainID(ctx context.Context, connConfig sqlstore.ConnectionConfig, chainID string) error { 103 connSource, err := sqlstore.NewTransactionalConnectionSource(ctx, logging.NewTestLogger(), connConfig) 104 if err != nil { 105 return fmt.Errorf("failed to create new transactional connection source: %w", err) 106 } 107 108 defer connSource.Close() 109 110 store := sqlstore.NewChain(connSource) 111 chainService := service.NewChain(store) 112 113 err = networkhistory.VerifyChainID(chainID, chainService) 114 if err != nil { 115 return fmt.Errorf("failed to verify chain id:%w", err) 116 } 117 return nil 118 } 119 120 func errorFromGrpcError(msg string, err error) error { 121 s, ok := status.FromError(err) 122 if !ok { 123 return fmt.Errorf("%s:%s", msg, err) 124 } 125 126 return fmt.Errorf("%s:%s", msg, s.Details()) 127 }