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 }