github.com/aergoio/aergo@v1.3.1/cmd/aergosvr/aergosvr.go (about) 1 /** 2 * @file 3 * @copyright defined in aergo/LICENSE.txt 4 */ 5 package main 6 7 import ( 8 "fmt" 9 "net/http" 10 _ "net/http/pprof" 11 "os" 12 "strconv" 13 "strings" 14 15 "github.com/aergoio/aergo/p2p/p2pkey" 16 17 "github.com/aergoio/aergo-lib/log" 18 "github.com/aergoio/aergo/account" 19 "github.com/aergoio/aergo/chain" 20 "github.com/aergoio/aergo/config" 21 "github.com/aergoio/aergo/consensus" 22 "github.com/aergoio/aergo/consensus/impl" 23 "github.com/aergoio/aergo/internal/common" 24 "github.com/aergoio/aergo/mempool" 25 "github.com/aergoio/aergo/p2p" 26 "github.com/aergoio/aergo/pkg/component" 27 polarisclient "github.com/aergoio/aergo/polaris/client" 28 "github.com/aergoio/aergo/rpc" 29 "github.com/aergoio/aergo/syncer" 30 "github.com/opentracing/opentracing-go" 31 zipkin "github.com/openzipkin-contrib/zipkin-go-opentracing" 32 "github.com/spf13/cobra" 33 ) 34 35 var ( 36 gitRevision, gitBranch string 37 ) 38 39 func main() { 40 if err := rootCmd.Execute(); err != nil { 41 os.Exit(1) 42 } 43 } 44 45 var ( 46 rootCmd = &cobra.Command{ 47 Use: "aergosvr", 48 Short: "Aergo Server", 49 Long: "Aergo Server Full-node implementation", 50 PersistentPreRun: func(cmd *cobra.Command, args []string) { 51 if homePath != "" && configFilePath != "" && verbose { 52 fmt.Println("ignore home path if given config file has valid configuration") 53 } 54 }, 55 Run: rootRun, 56 } 57 homePath string 58 configFilePath string 59 enableTestmode bool 60 useTestnet bool 61 62 verbose bool 63 64 svrlog *log.Logger 65 66 cfg *config.Config 67 ) 68 69 func init() { 70 cobra.OnInitialize(initConfig) 71 72 localFlags := rootCmd.Flags() 73 localFlags.SortFlags = false 74 localFlags.BoolVar(&useTestnet, "testnet", false, "use Aergo TestNet; this only affects if there's no genesis block") 75 localFlags.BoolVar(&enableTestmode, "testmode", false, "enable unsafe test mode (skips certain validations); can NOT use with --testnet") 76 77 fs := rootCmd.PersistentFlags() 78 fs.StringVar(&homePath, "home", "", "path of aergo home") 79 fs.StringVar(&configFilePath, "config", "", "path of configuration file") 80 fs.BoolVarP(&verbose, "verbose", "v", false, "verbose mode") 81 82 } 83 84 func initConfig() { 85 serverCtx := config.NewServerContext(homePath, configFilePath) 86 cfg = serverCtx.GetDefaultConfig().(*config.Config) 87 err := serverCtx.LoadOrCreateConfig(cfg) 88 if err != nil { 89 fmt.Printf("Fail to load configuration file %v: %v", serverCtx.Vc.ConfigFileUsed(), err.Error()) 90 os.Exit(1) 91 } 92 if enableTestmode { 93 cfg.EnableTestmode = true 94 } 95 if useTestnet { 96 cfg.UseTestnet = true 97 } 98 if cfg.EnableTestmode && cfg.UseTestnet { 99 fmt.Println("Turn off test mode for Aergo Public Chains") 100 os.Exit(1) 101 } 102 } 103 104 func configureZipkin() { 105 protocol := cfg.Monitor.ServerProtocol 106 endpoint := cfg.Monitor.ServerEndpoint 107 var collector zipkin.Collector 108 var err error 109 if "http" == protocol || "https" == protocol { 110 zipkinURL := fmt.Sprintf("%s://%s/api/v1/spans", protocol, endpoint) 111 collector, err = zipkin.NewHTTPCollector(zipkinURL) 112 if err != nil { 113 panic("Error connecting to zipkin server at " + zipkinURL + ". Error: " + err.Error()) 114 } 115 } else if "kafka" == protocol { 116 endpoints := strings.Split(endpoint, ",") 117 collector, err = zipkin.NewKafkaCollector(endpoints) 118 if err != nil { 119 panic("Error connecting to kafka endpoints at " + endpoint + ". Error: " + err.Error()) 120 } 121 } 122 123 if nil != collector { 124 myEndpoint := cfg.RPC.NetServiceAddr + ":" + strconv.Itoa(cfg.RPC.NetServicePort) 125 tracer, err := zipkin.NewTracer(zipkin.NewRecorder(collector, false, myEndpoint, "aergosvr")) 126 if err != nil { 127 panic("Error starting new zipkin tracer. Error: " + err.Error()) 128 } 129 opentracing.InitGlobalTracer(tracer) 130 } 131 } 132 133 func rootRun(cmd *cobra.Command, args []string) { 134 135 svrlog = log.NewLogger("asvr") 136 svrlog.Info().Str("revision", gitRevision).Str("branch", gitBranch).Msg("AERGO SVR STARTED") 137 138 configureZipkin() 139 140 if cfg.EnableProfile { 141 svrlog.Info().Msgf("Enable Profiling on localhost: %d", cfg.ProfilePort) 142 go func() { 143 err := http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", cfg.ProfilePort), nil) 144 svrlog.Info().Err(err).Msg("Run Profile Server") 145 }() 146 } 147 148 if cfg.EnableTestmode { 149 svrlog.Warn().Msgf("Running with unsafe test mode. Turn off test mode for production use!") 150 } 151 152 p2pkey.InitNodeInfo(&cfg.BaseConfig, cfg.P2P, githash, svrlog) 153 154 compMng := component.NewComponentHub() 155 156 chainSvc := chain.NewChainService(cfg) 157 158 mpoolSvc := mempool.NewMemPoolService(cfg, chainSvc) 159 rpcSvc := rpc.NewRPC(cfg, chainSvc, githash) 160 syncSvc := syncer.NewSyncer(cfg, chainSvc, nil) 161 p2pSvc := p2p.NewP2P(cfg, chainSvc) 162 pmapSvc := polarisclient.NewPolarisConnectSvc(cfg.P2P, p2pSvc) 163 164 var accountSvc component.IComponent 165 if cfg.Personal { 166 accountSvc = account.NewAccountService(cfg, chainSvc.SDB()) 167 } 168 169 // Register services to Hub. Don't need to do nil-check since Register 170 // function skips nil parameters. 171 if !cfg.Blockchain.VerifyOnly { 172 compMng.Register(chainSvc, mpoolSvc, rpcSvc, syncSvc, p2pSvc, accountSvc, pmapSvc) 173 } else { 174 compMng.Register(chainSvc, mpoolSvc, rpcSvc) 175 } 176 177 consensusSvc, err := impl.New(cfg, compMng, chainSvc, p2pSvc, rpcSvc) 178 if err != nil { 179 svrlog.Error().Err(err).Msg("Failed to start consensus service.") 180 os.Exit(1) 181 } 182 183 // All the services objects including Consensus must be created before the 184 // actors are started. 185 compMng.Start() 186 187 if cfg.Consensus.EnableBp { 188 // Warning: The consensus service must start after all the other 189 // services. 190 consensus.Start(consensusSvc) 191 } 192 193 var interrupt = common.HandleKillSig(func() { 194 consensus.Stop(consensusSvc) 195 compMng.Stop() 196 }, svrlog) 197 198 // Wait main routine to stop 199 <-interrupt.C 200 }