diff --git a/cmd/tendermint/commands/gen_validator.go b/cmd/tendermint/commands/gen_validator.go new file mode 100644 index 000000000..a1217e1f0 --- /dev/null +++ b/cmd/tendermint/commands/gen_validator.go @@ -0,0 +1,27 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/tendermint/go-wire" + "github.com/tendermint/tendermint/types" +) + +var genValidatorCmd = &cobra.Command{ + Use: "gen_validator", + Short: "Generate new validator keypair", + Run: genValidator, +} + +func init() { + RootCmd.AddCommand(genValidatorCmd) +} + +func genValidator(cmd *cobra.Command, args []string) { + privValidator := types.GenPrivValidator() + privValidatorJSONBytes := wire.JSONBytesPretty(privValidator) + fmt.Printf(`%v +`, string(privValidatorJSONBytes)) +} diff --git a/cmd/tendermint/init.go b/cmd/tendermint/commands/init.go similarity index 78% rename from cmd/tendermint/init.go rename to cmd/tendermint/commands/init.go index 5ec1efefb..366ca4e84 100644 --- a/cmd/tendermint/init.go +++ b/cmd/tendermint/commands/init.go @@ -1,13 +1,25 @@ -package main +package commands import ( "os" + "github.com/spf13/cobra" + cmn "github.com/tendermint/go-common" "github.com/tendermint/tendermint/types" ) -func init_files() { +var initFilesCmd = &cobra.Command{ + Use: "init", + Short: "Initialize Tendermint", + Run: initFiles, +} + +func init() { + RootCmd.AddCommand(initFilesCmd) +} + +func initFiles(cmd *cobra.Command, args []string) { privValFile := config.GetString("priv_validator_file") if _, err := os.Stat(privValFile); os.IsNotExist(err) { privValidator := types.GenPrivValidator() diff --git a/cmd/tendermint/probe_upnp.go b/cmd/tendermint/commands/probe_upnp.go similarity index 55% rename from cmd/tendermint/probe_upnp.go rename to cmd/tendermint/commands/probe_upnp.go index 5dcadddcd..bff433bc9 100644 --- a/cmd/tendermint/probe_upnp.go +++ b/cmd/tendermint/commands/probe_upnp.go @@ -1,13 +1,25 @@ -package main +package commands import ( "encoding/json" "fmt" + "github.com/spf13/cobra" + "github.com/tendermint/go-p2p/upnp" ) -func probe_upnp() { +var probeUpnpCmd = &cobra.Command{ + Use: "probe_upnp", + Short: "Test UPnP functionality", + Run: probeUpnp, +} + +func init() { + RootCmd.AddCommand(probeUpnpCmd) +} + +func probeUpnp(cmd *cobra.Command, args []string) { capabilities, err := upnp.Probe() if err != nil { diff --git a/cmd/tendermint/commands/replay.go b/cmd/tendermint/commands/replay.go new file mode 100644 index 000000000..4579ea5ef --- /dev/null +++ b/cmd/tendermint/commands/replay.go @@ -0,0 +1,40 @@ +package commands + +import ( + "fmt" + + "github.com/tendermint/tendermint/consensus" + + "github.com/spf13/cobra" +) + +var replayCmd = &cobra.Command{ + Use: "replay", + Short: "Replay messages from WAL", + Run: func(cmd *cobra.Command, args []string) { + + if len(args) > 1 { + consensus.RunReplayFile(config, args[1], false) + } else { + fmt.Println("replay requires an argument (walfile)") + } + }, +} + +var replayConsoleCmd = &cobra.Command{ + Use: "replay_console", + Short: "Replay messages from WAL in a console", + Run: func(cmd *cobra.Command, args []string) { + + if len(args) > 1 { + consensus.RunReplayFile(config, args[1], true) + } else { + fmt.Println("replay_console requires an argument (walfile)") + } + }, +} + +func init() { + RootCmd.AddCommand(replayCmd) + RootCmd.AddCommand(replayConsoleCmd) +} diff --git a/cmd/tendermint/reset_priv_validator.go b/cmd/tendermint/commands/reset_priv_validator.go similarity index 57% rename from cmd/tendermint/reset_priv_validator.go rename to cmd/tendermint/commands/reset_priv_validator.go index 5bf3ba69b..217c387a5 100644 --- a/cmd/tendermint/reset_priv_validator.go +++ b/cmd/tendermint/commands/reset_priv_validator.go @@ -1,22 +1,41 @@ -package main +package commands import ( "os" + "github.com/spf13/cobra" + "github.com/tendermint/tendermint/types" ) +var resetAllCmd = &cobra.Command{ + Use: "unsafe_reset_all", + Short: "(unsafe) Remove all the data and WAL, reset this node's validator", + Run: resetAll, +} + +var resetPrivValidatorCmd = &cobra.Command{ + Use: "unsafe_reset_priv_validator", + Short: "(unsafe) Reset this node's validator", + Run: resetPrivValidator, +} + +func init() { + RootCmd.AddCommand(resetAllCmd) + RootCmd.AddCommand(resetPrivValidatorCmd) +} + // XXX: this is totally unsafe. // it's only suitable for testnets. -func reset_all() { - reset_priv_validator() +func resetAll(cmd *cobra.Command, args []string) { + resetPrivValidator(cmd, args) os.RemoveAll(config.GetString("db_dir")) os.Remove(config.GetString("cs_wal_file")) } // XXX: this is totally unsafe. // it's only suitable for testnets. -func reset_priv_validator() { +func resetPrivValidator(cmd *cobra.Command, args []string) { // Get PrivValidator var privValidator *types.PrivValidator privValidatorFile := config.GetString("priv_validator_file") diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go new file mode 100644 index 000000000..8916ad8a1 --- /dev/null +++ b/cmd/tendermint/commands/root.go @@ -0,0 +1,76 @@ +package commands + +import ( + "github.com/spf13/cobra" + + cfg "github.com/tendermint/go-config" + "github.com/tendermint/go-logger" + tmcfg "github.com/tendermint/tendermint/config/tendermint" +) + +var config cfg.Config +var log = logger.New("module", "main") + +//global flags +var ( + printHelp bool + moniker string + nodeLaddr string + seeds string + fastSync bool + skipUPNP bool + rpcLaddr string + grpcLaddr string + logLevel string + proxyApp string + abciTransport string + + pex bool +) + +var RootCmd = &cobra.Command{ + Use: "tendermint", + Short: "Tendermint Core (BFT Consensus) in Go", +} + +func init() { + + // Get configuration + config = tmcfg.GetConfig("") + + ///////////////////// + // parse flags + + // configuration options + RootCmd.PersistentFlags().StringVar(&moniker, "moniker", config.GetString("moniker"), "Node Name") + RootCmd.PersistentFlags().StringVar(&nodeLaddr, "node_laddr", config.GetString("node_laddr"), "Node listen address. (0.0.0.0:0 means any interface, any port)") + RootCmd.PersistentFlags().StringVar(&seeds, "seeds", config.GetString("seeds"), "Comma delimited host:port seed nodes") + RootCmd.PersistentFlags().BoolVar(&fastSync, "fast_sync", config.GetBool("fast_sync"), "Fast blockchain syncing") + RootCmd.PersistentFlags().BoolVar(&skipUPNP, "skip_upnp", config.GetBool("skip_upnp"), "Skip UPNP configuration") + RootCmd.PersistentFlags().StringVar(&rpcLaddr, "rpc_laddr", config.GetString("rpc_laddr"), "RPC listen address. Port required") + RootCmd.PersistentFlags().StringVar(&grpcLaddr, "grpc_laddr", config.GetString("grpc_laddr"), "GRPC listen address (BroadcastTx only). Port required") + RootCmd.PersistentFlags().StringVar(&logLevel, "log_level", config.GetString("log_level"), "Log level") + RootCmd.PersistentFlags().StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"), "Proxy app address, or 'nilapp' or 'dummy' for local testing.") + RootCmd.PersistentFlags().StringVar(&abciTransport, "abci", config.GetString("abci"), "Specify abci transport (socket | grpc)") + + // feature flags + RootCmd.PersistentFlags().BoolVar(&pex, "pex", config.GetBool("pex_reactor"), "Enable Peer-Exchange (dev feature)") + + //------------------ + + // Merge parsed flag values onto config + config.Set("moniker", moniker) + config.Set("node_laddr", nodeLaddr) + config.Set("seeds", seeds) + config.Set("fast_sync", fastSync) + config.Set("skip_upnp", skipUPNP) + config.Set("rpc_laddr", rpcLaddr) + config.Set("grpc_laddr", grpcLaddr) + config.Set("log_level", logLevel) + config.Set("proxy_app", proxyApp) + config.Set("abci", abciTransport) + config.Set("pex_reactor", pex) + + // set the log level + logger.SetLogLevel(config.GetString("log_level")) +} diff --git a/cmd/tendermint/run_node.go b/cmd/tendermint/commands/run_node.go similarity index 86% rename from cmd/tendermint/run_node.go rename to cmd/tendermint/commands/run_node.go index 1940a6056..b16c1ab07 100644 --- a/cmd/tendermint/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -1,22 +1,33 @@ -package main +package commands import ( "io/ioutil" "time" + "github.com/spf13/cobra" + . "github.com/tendermint/go-common" - cfg "github.com/tendermint/go-config" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/types" ) +var runNodeCmd = &cobra.Command{ + Use: "node", + Short: "Run the tendermint node", + Run: runNode, +} + +func init() { + RootCmd.AddCommand(runNodeCmd) +} + // Users wishing to: // * Use an external signer for their validators // * Supply an in-proc abci app // should import github.com/tendermint/tendermint/node and implement // their own run_node to call node.NewNode (instead of node.NewNodeDefault) // with their custom priv validator and/or custom proxy.ClientCreator -func run_node(config cfg.Config) { +func runNode(cmd *cobra.Command, args []string) { // Wait until the genesis doc becomes available // This is for Mintnet compatibility. @@ -55,5 +66,4 @@ func run_node(config cfg.Config) { // Trap signal, run forever. n.RunForever() - } diff --git a/cmd/tendermint/show_validator.go b/cmd/tendermint/commands/show_validator.go similarity index 50% rename from cmd/tendermint/show_validator.go rename to cmd/tendermint/commands/show_validator.go index e6c68e31f..4aa80ae14 100644 --- a/cmd/tendermint/show_validator.go +++ b/cmd/tendermint/commands/show_validator.go @@ -1,13 +1,25 @@ -package main +package commands import ( "fmt" + "github.com/spf13/cobra" + "github.com/tendermint/go-wire" "github.com/tendermint/tendermint/types" ) -func show_validator() { +var showValidatorCmd = &cobra.Command{ + Use: "show_validator", + Short: "Show this node's validator info", + Run: showValidator, +} + +func init() { + RootCmd.AddCommand(showValidatorCmd) +} + +func showValidator(cmd *cobra.Command, args []string) { privValidatorFile := config.GetString("priv_validator_file") privValidator := types.LoadOrGenPrivValidator(privValidatorFile) fmt.Println(string(wire.JSONBytesPretty(privValidator.PubKey))) diff --git a/cmd/tendermint/commands/version.go b/cmd/tendermint/commands/version.go new file mode 100644 index 000000000..5c92160ea --- /dev/null +++ b/cmd/tendermint/commands/version.go @@ -0,0 +1,21 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/tendermint/tendermint/version" +) + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Show version info", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(version.Version) + }, +} + +func init() { + RootCmd.AddCommand(versionCmd) +} diff --git a/cmd/tendermint/flags.go b/cmd/tendermint/flags.go deleted file mode 100644 index fdf43b657..000000000 --- a/cmd/tendermint/flags.go +++ /dev/null @@ -1,66 +0,0 @@ -package main - -import ( - flag "github.com/spf13/pflag" - "os" - - cfg "github.com/tendermint/go-config" -) - -func parseFlags(config cfg.Config, args []string) { - var ( - printHelp bool - moniker string - nodeLaddr string - seeds string - fastSync bool - skipUPNP bool - rpcLaddr string - grpcLaddr string - logLevel string - proxyApp string - abciTransport string - - pex bool - ) - - // Declare flags - var flags = flag.NewFlagSet("main", flag.ExitOnError) - flags.BoolVar(&printHelp, "help", false, "Print this help message.") - - // configuration options - flags.StringVar(&moniker, "moniker", config.GetString("moniker"), "Node Name") - flags.StringVar(&nodeLaddr, "node_laddr", config.GetString("node_laddr"), "Node listen address. (0.0.0.0:0 means any interface, any port)") - flags.StringVar(&seeds, "seeds", config.GetString("seeds"), "Comma delimited host:port seed nodes") - flags.BoolVar(&fastSync, "fast_sync", config.GetBool("fast_sync"), "Fast blockchain syncing") - flags.BoolVar(&skipUPNP, "skip_upnp", config.GetBool("skip_upnp"), "Skip UPNP configuration") - flags.StringVar(&rpcLaddr, "rpc_laddr", config.GetString("rpc_laddr"), "RPC listen address. Port required") - flags.StringVar(&grpcLaddr, "grpc_laddr", config.GetString("grpc_laddr"), "GRPC listen address (BroadcastTx only). Port required") - flags.StringVar(&logLevel, "log_level", config.GetString("log_level"), "Log level") - flags.StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"), - "Proxy app address, or 'nilapp' or 'dummy' for local testing.") - flags.StringVar(&abciTransport, "abci", config.GetString("abci"), "Specify abci transport (socket | grpc)") - - // feature flags - flags.BoolVar(&pex, "pex", config.GetBool("pex_reactor"), "Enable Peer-Exchange (dev feature)") - - flags.Parse(args) - if printHelp { - flags.PrintDefaults() - os.Exit(0) - } - - // Merge parsed flag values onto app. - config.Set("moniker", moniker) - config.Set("node_laddr", nodeLaddr) - config.Set("seeds", seeds) - config.Set("fast_sync", fastSync) - config.Set("skip_upnp", skipUPNP) - config.Set("rpc_laddr", rpcLaddr) - config.Set("grpc_laddr", grpcLaddr) - config.Set("log_level", logLevel) - config.Set("proxy_app", proxyApp) - config.Set("abci", abciTransport) - - config.Set("pex_reactor", pex) -} diff --git a/cmd/tendermint/gen_validator.go b/cmd/tendermint/gen_validator.go deleted file mode 100644 index 0fc0e1661..000000000 --- a/cmd/tendermint/gen_validator.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/tendermint/go-wire" - "github.com/tendermint/tendermint/types" -) - -func gen_validator() { - privValidator := types.GenPrivValidator() - privValidatorJSONBytes := wire.JSONBytesPretty(privValidator) - fmt.Printf(`%v -`, string(privValidatorJSONBytes)) -} diff --git a/cmd/tendermint/log.go b/cmd/tendermint/log.go deleted file mode 100644 index ce626d2e9..000000000 --- a/cmd/tendermint/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import ( - "github.com/tendermint/go-logger" -) - -var log = logger.New("module", "main") diff --git a/cmd/tendermint/main.go b/cmd/tendermint/main.go index 640f2c275..9c2b9aa33 100644 --- a/cmd/tendermint/main.go +++ b/cmd/tendermint/main.go @@ -4,76 +4,12 @@ import ( "fmt" "os" - cfg "github.com/tendermint/go-config" - "github.com/tendermint/go-logger" - tmcfg "github.com/tendermint/tendermint/config/tendermint" - "github.com/tendermint/tendermint/consensus" - "github.com/tendermint/tendermint/version" + cmd "github.com/tendermint/tendermint/cmd/tendermint/commands" ) -var config cfg.Config - func main() { - - args := os.Args[1:] - if len(args) == 0 { - fmt.Println(`Tendermint - -Commands: - init Initialize tendermint - node Run the tendermint node - show_validator Show this node's validator info - gen_validator Generate new validator keypair - probe_upnp Test UPnP functionality - replay Replay messages from WAL - replay_console Replay messages from WAL in a console - unsafe_reset_all (unsafe) Remove all the data and WAL, reset this node's validator - unsafe_reset_priv_validator (unsafe) Reset this node's validator - version Show version info -`) - return - } - - // Get configuration - config = tmcfg.GetConfig("") - parseFlags(config, args[1:]) // Command line overrides - - // set the log level - logger.SetLogLevel(config.GetString("log_level")) - - switch args[0] { - case "node": - run_node(config) - case "replay": - if len(args) > 1 { - consensus.RunReplayFile(config, args[1], false) - } else { - fmt.Println("replay requires an argument (walfile)") - os.Exit(1) - } - case "replay_console": - if len(args) > 1 { - consensus.RunReplayFile(config, args[1], true) - } else { - fmt.Println("replay_console requires an argument (walfile)") - os.Exit(1) - } - case "init": - init_files() - case "show_validator": - show_validator() - case "gen_validator": - gen_validator() - case "probe_upnp": - probe_upnp() - case "unsafe_reset_all": - reset_all() - case "unsafe_reset_priv_validator": - reset_priv_validator() - case "version": - fmt.Println(version.Version) - default: - fmt.Printf("Unknown command %v\n", args[0]) + if err := cmd.RootCmd.Execute(); err != nil { + fmt.Println(err) os.Exit(1) } }