code.vegaprotocol.io/vega@v0.79.0/core/admin/server.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 admin 17 18 import ( 19 "context" 20 "fmt" 21 "net" 22 "net/http" 23 "os" 24 25 "code.vegaprotocol.io/vega/core/nodewallets" 26 "code.vegaprotocol.io/vega/core/types" 27 "code.vegaprotocol.io/vega/logging" 28 "code.vegaprotocol.io/vega/paths" 29 30 "github.com/gorilla/mux" 31 "github.com/gorilla/rpc" 32 "github.com/gorilla/rpc/json" 33 ) 34 35 type ProtocolUpgradeService interface { 36 // is vega core ready to be stopped and upgraded 37 GetUpgradeStatus() types.UpgradeStatus 38 } 39 40 // Server implement a socket server allowing to run simple RPC commands. 41 type Server struct { 42 log *logging.Logger 43 cfg Config 44 srv *http.Server 45 46 nodeWallet *NodeWallet 47 protocolUpgradeService *ProtocolUpgradeAdminService 48 } 49 50 // NewNonValidatorServer returns a new instance of the non-validator RPC socket server. 51 func NewNonValidatorServer( 52 log *logging.Logger, 53 config Config, 54 protocolUpgradeService ProtocolUpgradeService, 55 ) (*Server, error) { 56 // setup logger 57 log = log.Named(nvServerNamedLogger) 58 log.SetLevel(config.Level.Get()) 59 60 return &Server{ 61 log: log, 62 cfg: config, 63 nodeWallet: nil, 64 srv: nil, 65 protocolUpgradeService: NewProtocolUpgradeService(protocolUpgradeService), 66 }, nil 67 } 68 69 // NewValidatorServer returns a new instance of the validator RPC socket server. 70 func NewValidatorServer( 71 log *logging.Logger, 72 config Config, 73 vegaPaths paths.Paths, 74 nodeWalletPassphrase string, 75 nodeWallets *nodewallets.NodeWallets, 76 protocolUpgradeService ProtocolUpgradeService, 77 ) (*Server, error) { 78 // setup logger 79 log = log.Named(vServerNamedLogger) 80 log.SetLevel(config.Level.Get()) 81 82 nodeWallet, err := NewNodeWallet(log, vegaPaths, nodeWalletPassphrase, nodeWallets) 83 if err != nil { 84 return nil, fmt.Errorf("failed to create node wallet service: %w", err) 85 } 86 87 return &Server{ 88 log: log, 89 cfg: config, 90 nodeWallet: nodeWallet, 91 srv: nil, 92 protocolUpgradeService: NewProtocolUpgradeService(protocolUpgradeService), 93 }, nil 94 } 95 96 // ReloadConf update the internal configuration of the server. 97 func (s *Server) ReloadConf(cfg Config) { 98 s.log.Info("reloading configuration") 99 if s.log.GetLevel() != cfg.Level.Get() { 100 s.log.Info("updating log level", 101 logging.String("old", s.log.GetLevel().String()), 102 logging.String("new", cfg.Level.String()), 103 ) 104 s.log.SetLevel(cfg.Level.Get()) 105 } 106 107 // TODO(): not updating the actual server for now, may need to look at this later 108 // e.g restart the http server on another port or whatever 109 s.cfg = cfg 110 } 111 112 // Start starts the server. 113 func (s *Server) Start() { 114 logger := s.log 115 116 logger.Info("Starting Server<>RPC based API", 117 logging.String("socket-path", s.cfg.Server.SocketPath), 118 logging.String("http-path", s.cfg.Server.HTTPPath)) 119 120 rs := rpc.NewServer() 121 rs.RegisterCodec(json.NewCodec(), "application/json") 122 rs.RegisterCodec(json.NewCodec(), "application/json;charset=UTF-8") 123 124 if s.nodeWallet != nil { 125 if err := rs.RegisterService(s.nodeWallet, ""); err != nil { 126 logger.Panic("Failed to register node wallet service", logging.Error(err)) 127 } 128 } 129 if err := rs.RegisterService(s.protocolUpgradeService, "protocolupgrade"); err != nil { 130 logger.Panic("Failed to register protocol upgrade service", logging.Error(err)) 131 } 132 133 r := mux.NewRouter() 134 r.Handle(s.cfg.Server.HTTPPath, rs) 135 136 // Try to remove just in case 137 os.Remove(s.cfg.Server.SocketPath) 138 139 l, err := net.Listen("unix", s.cfg.Server.SocketPath) 140 if err != nil { 141 logger.Panic("Failed to open unix socket", logging.Error(err)) 142 } 143 144 s.srv = &http.Server{ 145 Handler: r, 146 } 147 148 logger.Info("Serving Server<>RPC based API") 149 if err := s.srv.Serve(l); err != nil && err != http.ErrServerClosed { 150 logger.Error("Error serving admin API", logging.Error(err)) 151 } 152 } 153 154 // Stop stops the server. 155 func (s *Server) Stop() { 156 if s.srv != nil { 157 s.log.Info("Stopping Server<>RPC based API") 158 159 if err := s.srv.Shutdown(context.Background()); err != nil { 160 s.log.Error("Failed to stop Server<>RPC based API cleanly", 161 logging.Error(err)) 162 } 163 } 164 }