github.com/lazyledger/lazyledger-core@v0.35.0-dev.0.20210613111200-4c651f053571/test/e2e/app/main.go (about)

     1  package main
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"time"
     9  
    10  	"github.com/spf13/viper"
    11  
    12  	"github.com/lazyledger/lazyledger-core/config"
    13  	"github.com/lazyledger/lazyledger-core/crypto/ed25519"
    14  	"github.com/lazyledger/lazyledger-core/ipfs"
    15  	tmflags "github.com/lazyledger/lazyledger-core/libs/cli/flags"
    16  	"github.com/lazyledger/lazyledger-core/libs/log"
    17  	tmnet "github.com/lazyledger/lazyledger-core/libs/net"
    18  	"github.com/lazyledger/lazyledger-core/node"
    19  	"github.com/lazyledger/lazyledger-core/p2p"
    20  	"github.com/lazyledger/lazyledger-core/privval"
    21  	"github.com/lazyledger/lazyledger-core/proxy"
    22  )
    23  
    24  var logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))
    25  
    26  // main is the binary entrypoint.
    27  func main() {
    28  	if len(os.Args) != 2 {
    29  		fmt.Printf("Usage: %v <configfile>", os.Args[0])
    30  		return
    31  	}
    32  	configFile := ""
    33  	if len(os.Args) == 2 {
    34  		configFile = os.Args[1]
    35  	}
    36  
    37  	if err := run(configFile); err != nil {
    38  		logger.Error(err.Error())
    39  		os.Exit(1)
    40  	}
    41  }
    42  
    43  // run runs the application - basically like main() with error handling.
    44  func run(configFile string) error {
    45  	cfg, err := LoadConfig(configFile)
    46  	if err != nil {
    47  		return err
    48  	}
    49  
    50  	// Start remote signer (must start before node if running builtin).
    51  	if cfg.PrivValServer != "" {
    52  		if err = startSigner(cfg); err != nil {
    53  			return err
    54  		}
    55  		if cfg.Protocol == "builtin" {
    56  			time.Sleep(1 * time.Second)
    57  		}
    58  	}
    59  
    60  	// Start app server.
    61  	switch cfg.Protocol {
    62  	case "builtin":
    63  		// FIXME: Temporarily remove maverick until it is redesigned
    64  		// if len(cfg.Misbehaviors) == 0 {
    65  		err = startNode(cfg)
    66  		// } else {
    67  		// 	err = startMaverick(cfg)
    68  		// }
    69  	default:
    70  		err = fmt.Errorf("invalid protocol %q", cfg.Protocol)
    71  	}
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	// Apparently there's no way to wait for the server, so we just sleep
    77  	for {
    78  		time.Sleep(1 * time.Hour)
    79  	}
    80  }
    81  
    82  // startNode starts a Tendermint node running the application directly. It assumes the Tendermint
    83  // configuration is in $TMHOME/config/tendermint.toml.
    84  //
    85  // FIXME There is no way to simply load the configuration from a file, so we need to pull in Viper.
    86  func startNode(cfg *Config) error {
    87  	app, err := NewApplication(cfg)
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	tmcfg, nodeLogger, nodeKey, err := setupNode()
    93  	if err != nil {
    94  		return fmt.Errorf("failed to setup config: %w", err)
    95  	}
    96  
    97  	pval, err := privval.LoadOrGenFilePV(tmcfg.PrivValidatorKeyFile(), tmcfg.PrivValidatorStateFile())
    98  	if err != nil {
    99  		return err
   100  	}
   101  	n, err := node.NewNode(tmcfg,
   102  		pval,
   103  		*nodeKey,
   104  		proxy.NewLocalClientCreator(app),
   105  		node.DefaultGenesisDocProviderFunc(tmcfg),
   106  		node.DefaultDBProvider,
   107  		ipfs.Embedded(true, ipfs.DefaultConfig(), nodeLogger),
   108  		node.DefaultMetricsProvider(tmcfg.Instrumentation),
   109  		nodeLogger,
   110  	)
   111  	if err != nil {
   112  		return err
   113  	}
   114  	return n.Start()
   115  }
   116  
   117  // FIXME: Temporarily disconnected maverick until it is redesigned
   118  // startMaverick starts a Maverick node that runs the application directly. It assumes the Tendermint
   119  // configuration is in $TMHOME/config/tendermint.toml.
   120  // func startMaverick(cfg *Config) error {
   121  // 	app, err := NewApplication(cfg)
   122  // 	if err != nil {
   123  // 		return err
   124  // 	}
   125  
   126  // 	tmcfg, logger, nodeKey, err := setupNode()
   127  // 	if err != nil {
   128  // 		return fmt.Errorf("failed to setup config: %w", err)
   129  // 	}
   130  
   131  // 	misbehaviors := make(map[int64]mcs.Misbehavior, len(cfg.Misbehaviors))
   132  // 	for heightString, misbehaviorString := range cfg.Misbehaviors {
   133  // 		height, _ := strconv.ParseInt(heightString, 10, 64)
   134  // 		misbehaviors[height] = mcs.MisbehaviorList[misbehaviorString]
   135  // 	}
   136  
   137  // 	n, err := maverick.NewNode(tmcfg,
   138  // 		maverick.LoadOrGenFilePV(tmcfg.PrivValidatorKeyFile(), tmcfg.PrivValidatorStateFile()),
   139  // 		*nodeKey,
   140  // 		proxy.NewLocalClientCreator(app),
   141  // 		maverick.DefaultGenesisDocProviderFunc(tmcfg),
   142  // 		maverick.DefaultDBProvider,
   143  // 		maverick.DefaultMetricsProvider(tmcfg.Instrumentation),
   144  // 		logger,
   145  // 		misbehaviors,
   146  // 	)
   147  // 	if err != nil {
   148  // 		return err
   149  // 	}
   150  
   151  // 	return n.Start()
   152  // }
   153  
   154  // startSigner starts a signer server connecting to the given endpoint.
   155  func startSigner(cfg *Config) error {
   156  	filePV := privval.LoadFilePV(cfg.PrivValKey, cfg.PrivValState)
   157  
   158  	protocol, address := tmnet.ProtocolAndAddress(cfg.PrivValServer)
   159  	var dialFn privval.SocketDialer
   160  	switch protocol {
   161  	case "tcp":
   162  		dialFn = privval.DialTCPFn(address, 3*time.Second, ed25519.GenPrivKey())
   163  	case "unix":
   164  		dialFn = privval.DialUnixFn(address)
   165  	default:
   166  		return fmt.Errorf("invalid privval protocol %q", protocol)
   167  	}
   168  
   169  	endpoint := privval.NewSignerDialerEndpoint(logger, dialFn,
   170  		privval.SignerDialerEndpointRetryWaitInterval(1*time.Second),
   171  		privval.SignerDialerEndpointConnRetries(100))
   172  	err := privval.NewSignerServer(endpoint, cfg.ChainID, filePV).Start()
   173  	if err != nil {
   174  		return err
   175  	}
   176  	logger.Info(fmt.Sprintf("Remote signer connecting to %v", cfg.PrivValServer))
   177  	return nil
   178  }
   179  
   180  func setupNode() (*config.Config, log.Logger, *p2p.NodeKey, error) {
   181  	var tmcfg *config.Config
   182  
   183  	home := os.Getenv("TMHOME")
   184  	if home == "" {
   185  		return nil, nil, nil, errors.New("TMHOME not set")
   186  	}
   187  	viper.AddConfigPath(filepath.Join(home, "config"))
   188  	viper.SetConfigName("config")
   189  	err := viper.ReadInConfig()
   190  	if err != nil {
   191  		return nil, nil, nil, err
   192  	}
   193  	tmcfg = config.DefaultConfig()
   194  	err = viper.Unmarshal(tmcfg)
   195  	if err != nil {
   196  		return nil, nil, nil, err
   197  	}
   198  	tmcfg.SetRoot(home)
   199  	if err = tmcfg.ValidateBasic(); err != nil {
   200  		return nil, nil, nil, fmt.Errorf("error in config file: %w", err)
   201  	}
   202  	if tmcfg.LogFormat == config.LogFormatJSON {
   203  		logger = log.NewTMJSONLogger(log.NewSyncWriter(os.Stdout))
   204  	}
   205  	nodeLogger, err := tmflags.ParseLogLevel(tmcfg.LogLevel, logger, config.DefaultLogLevel())
   206  	if err != nil {
   207  		return nil, nil, nil, err
   208  	}
   209  	nodeLogger = nodeLogger.With("module", "main")
   210  
   211  	nodeKey, err := p2p.LoadOrGenNodeKey(tmcfg.NodeKeyFile())
   212  	if err != nil {
   213  		return nil, nil, nil, fmt.Errorf("failed to load or gen node key %s: %w", tmcfg.NodeKeyFile(), err)
   214  	}
   215  
   216  	return tmcfg, nodeLogger, &nodeKey, nil
   217  }