github.com/number571/tendermint@v0.34.11-gost/cmd/priv_val_server/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "crypto/tls" 6 "crypto/x509" 7 "flag" 8 "fmt" 9 "io/ioutil" 10 "net" 11 "net/http" 12 "os" 13 "time" 14 15 grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" 16 "github.com/prometheus/client_golang/prometheus" 17 "github.com/prometheus/client_golang/prometheus/promhttp" 18 "google.golang.org/grpc" 19 "google.golang.org/grpc/credentials" 20 21 "github.com/number571/tendermint/libs/log" 22 tmnet "github.com/number571/tendermint/libs/net" 23 tmos "github.com/number571/tendermint/libs/os" 24 "github.com/number571/tendermint/privval" 25 grpcprivval "github.com/number571/tendermint/privval/grpc" 26 privvalproto "github.com/number571/tendermint/proto/tendermint/privval" 27 ) 28 29 var ( 30 // Create a metrics registry. 31 reg = prometheus.NewRegistry() 32 33 // Create some standard server metrics. 34 grpcMetrics = grpc_prometheus.NewServerMetrics() 35 ) 36 37 func main() { 38 var ( 39 addr = flag.String("addr", "127.0.0.1:26659", "Address to listen on (host:port)") 40 chainID = flag.String("chain-id", "mychain", "chain id") 41 privValKeyPath = flag.String("priv-key", "", "priv val key file path") 42 privValStatePath = flag.String("priv-state", "", "priv val state file path") 43 insecure = flag.Bool("insecure", false, "allow server to run insecurely (no TLS)") 44 certFile = flag.String("certfile", "", "absolute path to server certificate") 45 keyFile = flag.String("keyfile", "", "absolute path to server key") 46 rootCA = flag.String("rootcafile", "", "absolute path to root CA") 47 prometheusAddr = flag.String("prometheus-addr", "", "address for prometheus endpoint (host:port)") 48 49 logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false). 50 With("module", "priv_val") 51 ) 52 flag.Parse() 53 54 logger.Info( 55 "Starting private validator", 56 "addr", *addr, 57 "chainID", *chainID, 58 "privKeyPath", *privValKeyPath, 59 "privStatePath", *privValStatePath, 60 "insecure", *insecure, 61 "certFile", *certFile, 62 "keyFile", *keyFile, 63 "rootCA", *rootCA, 64 ) 65 66 pv, err := privval.LoadFilePV(*privValKeyPath, *privValStatePath) 67 if err != nil { 68 fmt.Fprint(os.Stderr, err) 69 os.Exit(1) 70 } 71 72 opts := []grpc.ServerOption{} 73 if !*insecure { 74 certificate, err := tls.LoadX509KeyPair(*certFile, *keyFile) 75 if err != nil { 76 fmt.Fprintf(os.Stderr, "failed to load X509 key pair: %v", err) 77 os.Exit(1) 78 } 79 80 certPool := x509.NewCertPool() 81 bs, err := ioutil.ReadFile(*rootCA) 82 if err != nil { 83 fmt.Fprintf(os.Stderr, "failed to read client ca cert: %s", err) 84 os.Exit(1) 85 } 86 87 if ok := certPool.AppendCertsFromPEM(bs); !ok { 88 fmt.Fprintf(os.Stderr, "failed to append client certs") 89 os.Exit(1) 90 } 91 92 tlsConfig := &tls.Config{ 93 ClientAuth: tls.RequireAndVerifyClientCert, 94 Certificates: []tls.Certificate{certificate}, 95 ClientCAs: certPool, 96 MinVersion: tls.VersionTLS13, 97 } 98 99 creds := grpc.Creds(credentials.NewTLS(tlsConfig)) 100 opts = append(opts, creds) 101 logger.Info("SignerServer: Creating security credentials") 102 } else { 103 logger.Info("SignerServer: You are using an insecure gRPC connection!") 104 } 105 106 // add prometheus metrics for unary RPC calls 107 opts = append(opts, grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor)) 108 109 ss := grpcprivval.NewSignerServer(*chainID, pv, logger) 110 111 protocol, address := tmnet.ProtocolAndAddress(*addr) 112 113 lis, err := net.Listen(protocol, address) 114 if err != nil { 115 fmt.Fprintf(os.Stderr, "SignerServer: Failed to listen %v", err) 116 os.Exit(1) 117 } 118 119 s := grpc.NewServer(opts...) 120 121 privvalproto.RegisterPrivValidatorAPIServer(s, ss) 122 123 var httpSrv *http.Server 124 if *prometheusAddr != "" { 125 httpSrv = registerPrometheus(*prometheusAddr, s) 126 } 127 128 logger.Info("SignerServer: Starting grpc server") 129 if err := s.Serve(lis); err != nil { 130 fmt.Fprintf(os.Stderr, "Unable to listen on port %s: %v", *addr, err) 131 os.Exit(1) 132 } 133 134 // Stop upon receiving SIGTERM or CTRL-C. 135 tmos.TrapSignal(logger, func() { 136 logger.Debug("SignerServer: calling Close") 137 if *prometheusAddr != "" { 138 ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) 139 defer cancel() 140 if err := httpSrv.Shutdown(ctx); err != nil { 141 fmt.Fprintf(os.Stderr, "Unable to stop http server: %v", err) 142 os.Exit(1) 143 } 144 } 145 s.GracefulStop() 146 }) 147 148 // Run forever. 149 select {} 150 } 151 152 func registerPrometheus(addr string, s *grpc.Server) *http.Server { 153 // Initialize all metrics. 154 grpcMetrics.InitializeMetrics(s) 155 // create http server to serve prometheus 156 httpServer := &http.Server{Handler: promhttp.HandlerFor(reg, promhttp.HandlerOpts{}), Addr: addr} 157 158 go func() { 159 if err := httpServer.ListenAndServe(); err != nil { 160 fmt.Fprintf(os.Stderr, "Unable to start a http server: %v", err) 161 os.Exit(1) 162 } 163 }() 164 165 return httpServer 166 }