github.com/vipernet-xyz/tm@v0.34.24/test/maverick/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 8 "github.com/spf13/cobra" 9 "github.com/spf13/viper" 10 11 cmd "github.com/vipernet-xyz/tm/cmd/tendermint/commands" 12 "github.com/vipernet-xyz/tm/cmd/tendermint/commands/debug" 13 cfg "github.com/vipernet-xyz/tm/config" 14 "github.com/vipernet-xyz/tm/libs/cli" 15 tmflags "github.com/vipernet-xyz/tm/libs/cli/flags" 16 "github.com/vipernet-xyz/tm/libs/log" 17 tmos "github.com/vipernet-xyz/tm/libs/os" 18 tmrand "github.com/vipernet-xyz/tm/libs/rand" 19 "github.com/vipernet-xyz/tm/p2p" 20 cs "github.com/vipernet-xyz/tm/test/maverick/consensus" 21 nd "github.com/vipernet-xyz/tm/test/maverick/node" 22 "github.com/vipernet-xyz/tm/types" 23 tmtime "github.com/vipernet-xyz/tm/types/time" 24 ) 25 26 var ( 27 config = cfg.DefaultConfig() 28 logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) 29 misbehaviorFlag = "" 30 ) 31 32 func init() { 33 registerFlagsRootCmd(RootCmd) 34 } 35 36 func registerFlagsRootCmd(command *cobra.Command) { 37 command.PersistentFlags().String("log_level", config.LogLevel, "Log level") 38 } 39 40 func ParseConfig() (*cfg.Config, error) { 41 conf := cfg.DefaultConfig() 42 err := viper.Unmarshal(conf) 43 if err != nil { 44 return nil, err 45 } 46 conf.SetRoot(conf.RootDir) 47 cfg.EnsureRoot(conf.RootDir) 48 if err = conf.ValidateBasic(); err != nil { 49 return nil, fmt.Errorf("error in config file: %v", err) 50 } 51 return conf, err 52 } 53 54 // RootCmd is the root command for Tendermint core. 55 var RootCmd = &cobra.Command{ 56 Use: "maverick", 57 Short: "Tendermint Maverick Node", 58 Long: "Tendermint Maverick Node for testing with faulty consensus misbehaviors in a testnet. Contains " + 59 "all the functionality of a normal node but custom misbehaviors can be injected when running the node " + 60 "through a flag. See maverick node --help for how the misbehavior flag is constructured", 61 PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { 62 fmt.Printf("use: %v, args: %v", cmd.Use, cmd.Args) 63 64 config, err = ParseConfig() 65 if err != nil { 66 return err 67 } 68 69 if config.LogFormat == cfg.LogFormatJSON { 70 logger = log.NewTMJSONLogger(log.NewSyncWriter(os.Stdout)) 71 } 72 73 logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel) 74 if err != nil { 75 return err 76 } 77 78 if viper.GetBool(cli.TraceFlag) { 79 logger = log.NewTracingLogger(logger) 80 } 81 82 logger = logger.With("module", "main") 83 return nil 84 }, 85 } 86 87 func main() { 88 rootCmd := RootCmd 89 rootCmd.AddCommand( 90 ListMisbehaviorCmd, 91 cmd.GenValidatorCmd, 92 InitFilesCmd, 93 cmd.ProbeUpnpCmd, 94 cmd.ReplayCmd, 95 cmd.ReplayConsoleCmd, 96 cmd.ResetAllCmd, 97 cmd.ResetPrivValidatorCmd, 98 cmd.ShowValidatorCmd, 99 cmd.ShowNodeIDCmd, 100 cmd.GenNodeKeyCmd, 101 cmd.VersionCmd, 102 debug.DebugCmd, 103 cli.NewCompletionCmd(rootCmd, true), 104 ) 105 106 nodeCmd := &cobra.Command{ 107 Use: "node", 108 Short: "Run the maverick node", 109 RunE: func(command *cobra.Command, args []string) error { 110 return startNode(config, logger, misbehaviorFlag) 111 }, 112 } 113 114 cmd.AddNodeFlags(nodeCmd) 115 116 // Create & start node 117 rootCmd.AddCommand(nodeCmd) 118 119 // add special flag for misbehaviors 120 nodeCmd.Flags().StringVar( 121 &misbehaviorFlag, 122 "misbehaviors", 123 "", 124 "Select the misbehaviors of the node (comma-separated, no spaces in between): \n"+ 125 "e.g. --misbehaviors double-prevote,3\n"+ 126 "You can also have multiple misbehaviors: e.g. double-prevote,3,no-vote,5") 127 128 cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTendermintDir))) 129 if err := cmd.Execute(); err != nil { 130 panic(err) 131 } 132 } 133 134 func startNode(config *cfg.Config, logger log.Logger, misbehaviorFlag string) error { 135 misbehaviors, err := nd.ParseMisbehaviors(misbehaviorFlag) 136 if err != nil { 137 return err 138 } 139 140 node, err := nd.DefaultNewNode(config, logger, misbehaviors) 141 if err != nil { 142 return fmt.Errorf("failed to create node: %w", err) 143 } 144 145 if err := node.Start(); err != nil { 146 return fmt.Errorf("failed to start node: %w", err) 147 } 148 149 logger.Info("Started node", "nodeInfo", node.Switch().NodeInfo()) 150 151 // Stop upon receiving SIGTERM or CTRL-C. 152 tmos.TrapSignal(logger, func() { 153 if node.IsRunning() { 154 if err := node.Stop(); err != nil { 155 logger.Error("unable to stop the node", "error", err) 156 } 157 } 158 }) 159 160 // Run forever. 161 select {} 162 } 163 164 var InitFilesCmd = &cobra.Command{ 165 Use: "init", 166 Short: "Initialize Tendermint", 167 RunE: initFiles, 168 } 169 170 func initFiles(cmd *cobra.Command, args []string) error { 171 return initFilesWithConfig(config) 172 } 173 174 func initFilesWithConfig(config *cfg.Config) error { 175 // private validator 176 privValKeyFile := config.PrivValidatorKeyFile() 177 privValStateFile := config.PrivValidatorStateFile() 178 var pv *nd.FilePV 179 if tmos.FileExists(privValKeyFile) { 180 pv = nd.LoadFilePV(privValKeyFile, privValStateFile) 181 logger.Info("Found private validator", "keyFile", privValKeyFile, 182 "stateFile", privValStateFile) 183 } else { 184 pv = nd.GenFilePV(privValKeyFile, privValStateFile) 185 pv.Save() 186 logger.Info("Generated private validator", "keyFile", privValKeyFile, 187 "stateFile", privValStateFile) 188 } 189 190 nodeKeyFile := config.NodeKeyFile() 191 if tmos.FileExists(nodeKeyFile) { 192 logger.Info("Found node key", "path", nodeKeyFile) 193 } else { 194 if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil { 195 return err 196 } 197 logger.Info("Generated node key", "path", nodeKeyFile) 198 } 199 200 // genesis file 201 genFile := config.GenesisFile() 202 if tmos.FileExists(genFile) { 203 logger.Info("Found genesis file", "path", genFile) 204 } else { 205 genDoc := types.GenesisDoc{ 206 ChainID: fmt.Sprintf("test-chain-%v", tmrand.Str(6)), 207 GenesisTime: tmtime.Now(), 208 ConsensusParams: types.DefaultConsensusParams(), 209 } 210 pubKey, err := pv.GetPubKey() 211 if err != nil { 212 return fmt.Errorf("can't get pubkey: %w", err) 213 } 214 genDoc.Validators = []types.GenesisValidator{{ 215 Address: pubKey.Address(), 216 PubKey: pubKey, 217 Power: 10, 218 }} 219 220 if err := genDoc.SaveAs(genFile); err != nil { 221 return err 222 } 223 logger.Info("Generated genesis file", "path", genFile) 224 } 225 226 return nil 227 } 228 229 var ListMisbehaviorCmd = &cobra.Command{ 230 Use: "misbehaviors", 231 Short: "Lists possible misbehaviors", 232 RunE: listMisbehaviors, 233 } 234 235 func listMisbehaviors(cmd *cobra.Command, args []string) error { 236 str := "Currently registered misbehaviors: \n" 237 for key := range cs.MisbehaviorList { 238 str += fmt.Sprintf("- %s\n", key) 239 } 240 fmt.Println(str) 241 return nil 242 }