|
|
- package main
-
- import (
- "fmt"
- "os"
- "path/filepath"
-
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-
- cmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
- "github.com/tendermint/tendermint/cmd/tendermint/commands/debug"
- cfg "github.com/tendermint/tendermint/config"
- "github.com/tendermint/tendermint/libs/cli"
- tmflags "github.com/tendermint/tendermint/libs/cli/flags"
- "github.com/tendermint/tendermint/libs/log"
- tmos "github.com/tendermint/tendermint/libs/os"
- tmrand "github.com/tendermint/tendermint/libs/rand"
- "github.com/tendermint/tendermint/p2p"
- cs "github.com/tendermint/tendermint/test/maverick/consensus"
- nd "github.com/tendermint/tendermint/test/maverick/node"
- "github.com/tendermint/tendermint/types"
- tmtime "github.com/tendermint/tendermint/types/time"
- )
-
- var (
- config = cfg.DefaultConfig()
- logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout))
- misbehaviorFlag = ""
- )
-
- func init() {
- registerFlagsRootCmd(RootCmd)
- }
-
- func registerFlagsRootCmd(command *cobra.Command) {
- command.PersistentFlags().String("log_level", config.LogLevel, "Log level")
- }
-
- func ParseConfig() (*cfg.Config, error) {
- conf := cfg.DefaultConfig()
- err := viper.Unmarshal(conf)
- if err != nil {
- return nil, err
- }
- conf.SetRoot(conf.RootDir)
- cfg.EnsureRoot(conf.RootDir)
- if err = conf.ValidateBasic(); err != nil {
- return nil, fmt.Errorf("error in config file: %v", err)
- }
- return conf, err
- }
-
- // RootCmd is the root command for Tendermint core.
- var RootCmd = &cobra.Command{
- Use: "maverick",
- Short: "Tendermint Maverick Node",
- Long: "Tendermint Maverick Node for testing with faulty consensus misbehaviors in a testnet. Contains " +
- "all the functionality of a normal node but custom misbehaviors can be injected when running the node " +
- "through a flag. See maverick node --help for how the misbehavior flag is constructured",
- PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) {
- fmt.Printf("use: %v, args: %v", cmd.Use, cmd.Args)
-
- config, err = ParseConfig()
- if err != nil {
- return err
- }
-
- if config.LogFormat == cfg.LogFormatJSON {
- logger = log.NewTMJSONLogger(log.NewSyncWriter(os.Stdout))
- }
-
- logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel)
- if err != nil {
- return err
- }
-
- if viper.GetBool(cli.TraceFlag) {
- logger = log.NewTracingLogger(logger)
- }
-
- logger = logger.With("module", "main")
- return nil
- },
- }
-
- func main() {
- rootCmd := RootCmd
- rootCmd.AddCommand(
- ListMisbehaviorCmd,
- cmd.GenValidatorCmd,
- InitFilesCmd,
- cmd.ProbeUpnpCmd,
- cmd.ReplayCmd,
- cmd.ReplayConsoleCmd,
- cmd.ResetAllCmd,
- cmd.ResetPrivValidatorCmd,
- cmd.ShowValidatorCmd,
- cmd.ShowNodeIDCmd,
- cmd.GenNodeKeyCmd,
- cmd.VersionCmd,
- debug.DebugCmd,
- cli.NewCompletionCmd(rootCmd, true),
- )
-
- nodeCmd := &cobra.Command{
- Use: "node",
- Short: "Run the maverick node",
- RunE: func(command *cobra.Command, args []string) error {
- return startNode(config, logger, misbehaviorFlag)
- },
- }
-
- cmd.AddNodeFlags(nodeCmd)
-
- // Create & start node
- rootCmd.AddCommand(nodeCmd)
-
- // add special flag for misbehaviors
- nodeCmd.Flags().StringVar(
- &misbehaviorFlag,
- "misbehaviors",
- "",
- "Select the misbehaviors of the node (comma-separated, no spaces in between): \n"+
- "e.g. --misbehaviors double-prevote,3\n"+
- "You can also have multiple misbehaviors: e.g. double-prevote,3,no-vote,5")
-
- cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTendermintDir)))
- if err := cmd.Execute(); err != nil {
- panic(err)
- }
- }
-
- func startNode(config *cfg.Config, logger log.Logger, misbehaviorFlag string) error {
- misbehaviors, err := nd.ParseMisbehaviors(misbehaviorFlag)
- if err != nil {
- return err
- }
-
- node, err := nd.DefaultNewNode(config, logger, misbehaviors)
- if err != nil {
- return fmt.Errorf("failed to create node: %w", err)
- }
-
- if err := node.Start(); err != nil {
- return fmt.Errorf("failed to start node: %w", err)
- }
-
- logger.Info("Started node", "nodeInfo", node.Switch().NodeInfo())
-
- // Stop upon receiving SIGTERM or CTRL-C.
- tmos.TrapSignal(logger, func() {
- if node.IsRunning() {
- if err := node.Stop(); err != nil {
- logger.Error("unable to stop the node", "error", err)
- }
- }
- })
-
- // Run forever.
- select {}
- }
-
- var InitFilesCmd = &cobra.Command{
- Use: "init",
- Short: "Initialize Tendermint",
- RunE: initFiles,
- }
-
- func initFiles(cmd *cobra.Command, args []string) error {
- return initFilesWithConfig(config)
- }
-
- func initFilesWithConfig(config *cfg.Config) error {
- // private validator
- privValKeyFile := config.PrivValidatorKeyFile()
- privValStateFile := config.PrivValidatorStateFile()
- var pv *nd.FilePV
- if tmos.FileExists(privValKeyFile) {
- pv = nd.LoadFilePV(privValKeyFile, privValStateFile)
- logger.Info("Found private validator", "keyFile", privValKeyFile,
- "stateFile", privValStateFile)
- } else {
- pv = nd.GenFilePV(privValKeyFile, privValStateFile)
- pv.Save()
- logger.Info("Generated private validator", "keyFile", privValKeyFile,
- "stateFile", privValStateFile)
- }
-
- nodeKeyFile := config.NodeKeyFile()
- if tmos.FileExists(nodeKeyFile) {
- logger.Info("Found node key", "path", nodeKeyFile)
- } else {
- if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil {
- return err
- }
- logger.Info("Generated node key", "path", nodeKeyFile)
- }
-
- // genesis file
- genFile := config.GenesisFile()
- if tmos.FileExists(genFile) {
- logger.Info("Found genesis file", "path", genFile)
- } else {
- genDoc := types.GenesisDoc{
- ChainID: fmt.Sprintf("test-chain-%v", tmrand.Str(6)),
- GenesisTime: tmtime.Now(),
- ConsensusParams: types.DefaultConsensusParams(),
- }
- pubKey, err := pv.GetPubKey()
- if err != nil {
- return fmt.Errorf("can't get pubkey: %w", err)
- }
- genDoc.Validators = []types.GenesisValidator{{
- Address: pubKey.Address(),
- PubKey: pubKey,
- Power: 10,
- }}
-
- if err := genDoc.SaveAs(genFile); err != nil {
- return err
- }
- logger.Info("Generated genesis file", "path", genFile)
- }
-
- return nil
- }
-
- var ListMisbehaviorCmd = &cobra.Command{
- Use: "misbehaviors",
- Short: "Lists possible misbehaviors",
- RunE: listMisbehaviors,
- }
-
- func listMisbehaviors(cmd *cobra.Command, args []string) error {
- str := "Currently registered misbehaviors: \n"
- for key := range cs.MisbehaviorList {
- str += fmt.Sprintf("- %s\n", key)
- }
- fmt.Println(str)
- return nil
- }
|