code.vegaprotocol.io/vega@v0.79.0/wallet/version/helpers.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 version 17 18 import ( 19 "context" 20 "errors" 21 "fmt" 22 "net/http" 23 "strings" 24 "time" 25 26 apipb "code.vegaprotocol.io/vega/protos/vega/api/v1" 27 28 "google.golang.org/grpc" 29 "google.golang.org/grpc/credentials" 30 "google.golang.org/grpc/credentials/insecure" 31 ) 32 33 var ( 34 ErrConnectionError = errors.New("verify you are connected to the internet") 35 ErrCouldNotConnectNodes = errors.New("could not connect to any nodes: verify your network configuration is up to date") 36 ) 37 38 func GetNetworkVersionThroughGRPC(hosts []string) (string, error) { 39 for _, host := range hosts { 40 version, err := queryNetworkVersion(host) 41 if err != nil { 42 continue 43 } 44 return version, nil 45 } 46 47 // Before advising the users to check their network configuration, the software 48 // pings vega.xyz to verify whether or not they are connected to the internet. 49 // This should help the user with troubleshooting their setup. 50 ctx, cancelFn := context.WithTimeout(context.Background(), 10*time.Second) 51 defer cancelFn() 52 req, err := http.NewRequestWithContext(ctx, http.MethodHead, "https://vega.xyz", nil) 53 if err != nil { 54 return "", fmt.Errorf("could not build the request that verifies the network connection: %w", err) 55 } 56 resp, err := http.DefaultClient.Do(req) 57 if err != nil || resp.StatusCode != http.StatusOK { 58 return "", ErrConnectionError 59 } 60 if resp.Body != nil { 61 _ = resp.Body.Close() 62 } 63 64 // If it reaches that point, it's been possible to get a response to the ping to 65 // `vega.xyz`, which suggest the issue comes from the network configuration 66 // (outdated, or misconfigured), or from the nodes themselves (not responding, 67 // or giving unexpected responses). 68 return "", ErrCouldNotConnectNodes 69 } 70 71 func queryNetworkVersion(host string) (string, error) { 72 useTLS := strings.HasPrefix(host, "tls://") 73 74 var creds credentials.TransportCredentials 75 if useTLS { 76 host = host[6:] 77 creds = credentials.NewClientTLSFromCert(nil, "") 78 } else { 79 creds = insecure.NewCredentials() 80 } 81 82 connection, err := grpc.Dial(host, grpc.WithTransportCredentials(creds)) 83 if err != nil { 84 return "", fmt.Errorf("couldn't initialize gRPC client: %w", err) 85 } 86 defer func() { 87 _ = connection.Close() 88 }() 89 90 client := apipb.NewCoreServiceClient(connection) 91 92 timeout, cancelFn := context.WithTimeout(context.Background(), 5*time.Second) 93 defer cancelFn() 94 95 statistics, err := client.Statistics(timeout, &apipb.StatisticsRequest{}) 96 if err != nil { 97 return "", err 98 } 99 100 return statistics.Statistics.AppVersion, nil 101 }