github.com/iotexproject/iotex-core@v1.14.1-rc1/server/main.go (about) 1 // Copyright (c) 2022 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 // Usage: 7 // make build 8 // ./bin/server -config-file=./config.yaml 9 // 10 11 package main 12 13 import ( 14 "context" 15 "flag" 16 "fmt" 17 glog "log" 18 "os" 19 "os/signal" 20 "strings" 21 "syscall" 22 23 "github.com/iotexproject/go-pkgs/hash" 24 "go.uber.org/automaxprocs/maxprocs" 25 "go.uber.org/zap" 26 27 "github.com/iotexproject/iotex-core/blockchain/block" 28 "github.com/iotexproject/iotex-core/blockchain/genesis" 29 "github.com/iotexproject/iotex-core/config" 30 "github.com/iotexproject/iotex-core/db/trie/mptrie" 31 "github.com/iotexproject/iotex-core/pkg/log" 32 "github.com/iotexproject/iotex-core/pkg/probe" 33 "github.com/iotexproject/iotex-core/pkg/recovery" 34 "github.com/iotexproject/iotex-core/server/itx" 35 ) 36 37 /** 38 * overwritePath is the path to the config file which overwrite default values 39 * secretPath is the path to the config file store secret values 40 */ 41 var ( 42 _genesisPath string 43 _overwritePath string 44 _secretPath string 45 _subChainPath string 46 _plugins strs 47 ) 48 49 type strs []string 50 51 func (ss *strs) String() string { 52 return strings.Join(*ss, ",") 53 } 54 55 func (ss *strs) Set(str string) error { 56 *ss = append(*ss, str) 57 return nil 58 } 59 60 func init() { 61 // set max number of CPUs, disable log printing 62 maxprocs.Set(maxprocs.Logger(nil)) 63 flag.StringVar(&_genesisPath, "genesis-path", "", "Genesis path") 64 flag.StringVar(&_overwritePath, "config-path", "", "Config path") 65 flag.StringVar(&_secretPath, "secret-path", "", "Secret path") 66 flag.StringVar(&_subChainPath, "sub-config-path", "", "Sub chain Config path") 67 flag.Var(&_plugins, "plugin", "Plugin of the node") 68 flag.Usage = func() { 69 _, _ = fmt.Fprintf(os.Stderr, 70 "usage: server -config-path=[string]\n") 71 flag.PrintDefaults() 72 os.Exit(2) 73 } 74 flag.Parse() 75 } 76 77 func main() { 78 stop := make(chan os.Signal, 1) 79 signal.Notify(stop, os.Interrupt) 80 signal.Notify(stop, syscall.SIGTERM) 81 ctx, cancel := context.WithCancel(context.Background()) 82 stopped := make(chan struct{}) 83 livenessCtx, livenessCancel := context.WithCancel(context.Background()) 84 85 genesisCfg, err := genesis.New(_genesisPath) 86 if err != nil { 87 glog.Fatalln("Failed to new genesis config.", zap.Error(err)) 88 } 89 // set genesis timestamp 90 genesis.SetGenesisTimestamp(genesisCfg.Timestamp) 91 if genesis.Timestamp() == 0 { 92 glog.Fatalln("Genesis timestamp is not set, call genesis.New() first") 93 } 94 // load genesis block's hash 95 block.LoadGenesisHash(&genesisCfg) 96 if block.GenesisHash() == hash.ZeroHash256 { 97 glog.Fatalln("Genesis hash is not set, call block.LoadGenesisHash() first") 98 } 99 100 cfg, err := config.New([]string{_overwritePath, _secretPath}, _plugins) 101 if err != nil { 102 glog.Fatalln("Failed to new config.", zap.Error(err)) 103 } 104 if err = initLogger(cfg); err != nil { 105 glog.Fatalln("Cannot config global logger, use default one: ", zap.Error(err)) 106 } 107 108 if err = recovery.SetCrashlogDir(cfg.System.SystemLogDBPath); err != nil { 109 glog.Fatalln("Failed to set directory of crashlog: ", zap.Error(err)) 110 } 111 defer recovery.Recover() 112 113 // check EVM network ID and chain ID 114 if cfg.Chain.EVMNetworkID == 0 || cfg.Chain.ID == 0 { 115 glog.Fatalln("EVM Network ID or Chain ID is not set, call config.New() first") 116 } 117 118 cfg.Genesis = genesisCfg 119 cfgToLog := cfg 120 cfgToLog.Chain.ProducerPrivKey = "" 121 cfgToLog.Network.MasterKey = "" 122 log.S().Infof("Config in use: %+v", cfgToLog) 123 log.S().Infof("EVM Network ID: %d, Chain ID: %d", cfg.Chain.EVMNetworkID, cfg.Chain.ID) 124 log.S().Infof("Genesis timestamp: %d", genesisCfg.Timestamp) 125 log.S().Infof("Genesis hash: %x", block.GenesisHash()) 126 127 // liveness start 128 probeSvr := probe.New(cfg.System.HTTPStatsPort) 129 if err := probeSvr.Start(ctx); err != nil { 130 log.L().Fatal("Failed to start probe server.", zap.Error(err)) 131 } 132 go func() { 133 <-stop 134 // start stopping 135 cancel() 136 <-stopped 137 138 // liveness end 139 if err := probeSvr.Stop(livenessCtx); err != nil { 140 log.L().Error("Error when stopping probe server.", zap.Error(err)) 141 } 142 livenessCancel() 143 }() 144 145 if cfg.System.MptrieLogPath != "" { 146 if err = mptrie.OpenLogDB(cfg.System.MptrieLogPath); err != nil { 147 log.L().Fatal("Failed to open mptrie log DB.", zap.Error(err)) 148 } 149 defer func() { 150 if err = mptrie.CloseLogDB(); err != nil { 151 log.L().Error("Failed to close mptrie log DB.", zap.Error(err)) 152 } 153 }() 154 } 155 // create and start the node 156 svr, err := itx.NewServer(cfg) 157 if err != nil { 158 log.L().Fatal("Failed to create server.", zap.Error(err)) 159 } 160 161 var cfgsub config.Config 162 if _subChainPath != "" { 163 cfgsub, err = config.NewSub([]string{_secretPath, _subChainPath}) 164 if err != nil { 165 log.L().Fatal("Failed to new sub chain config.", zap.Error(err)) 166 } 167 } else { 168 cfgsub = config.Config{} 169 } 170 171 if cfgsub.Chain.ID != 0 { 172 if err := svr.NewSubChainService(cfgsub); err != nil { 173 log.L().Fatal("Failed to new sub chain.", zap.Error(err)) 174 } 175 } 176 177 itx.StartServer(ctx, svr, probeSvr, cfg) 178 close(stopped) 179 <-livenessCtx.Done() 180 } 181 182 func initLogger(cfg config.Config) error { 183 addr := cfg.Chain.ProducerAddress() 184 return log.InitLoggers(cfg.Log, cfg.SubLogs, zap.AddCaller(), zap.Fields( 185 zap.String("ioAddr", addr.String()), 186 )) 187 }