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  }