package main import ( "errors" "io" "os" "path/filepath" "github.com/spf13/cast" "github.com/spf13/cobra" tmcli "github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/debug" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/rpc" sdkserver "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" "github.com/cosmos/cosmos-sdk/simapp/params" "github.com/cosmos/cosmos-sdk/snapshots" "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" authclient "github.com/cosmos/cosmos-sdk/x/auth/client" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" "github.com/cosmos/cosmos-sdk/x/auth/types" vestingcli "github.com/cosmos/cosmos-sdk/x/auth/vesting/client/cli" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/crisis" genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" "github.com/cosmos/ethermint/app" ethermintclient "github.com/cosmos/ethermint/client" ethermintclientKey "github.com/cosmos/ethermint/client/keys" "github.com/cosmos/ethermint/server" ) // NewRootCmd creates a new root command for simd. It is called once in the // main function. func NewRootCmd() (*cobra.Command, params.EncodingConfig) { encodingConfig := app.MakeEncodingConfig() initClientCtx := client.Context{}. WithJSONMarshaler(encodingConfig.Marshaler). WithInterfaceRegistry(encodingConfig.InterfaceRegistry). WithTxConfig(encodingConfig.TxConfig). WithLegacyAmino(encodingConfig.Amino). WithInput(os.Stdin). WithAccountRetriever(types.AccountRetriever{}). WithBroadcastMode(flags.BroadcastSync). WithHomeDir(app.DefaultNodeHome) rootCmd := &cobra.Command{ Use: "ethermintd", Short: "ethermint app daemon", PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil { return err } return server.InterceptConfigsPreRunHandler(cmd) }, } initRootCmd(rootCmd, encodingConfig) return rootCmd, encodingConfig } func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { authclient.Codec = encodingConfig.Marshaler rootCmd.AddCommand( ethermintclient.GenerateChainID( ethermintclient.ValidateChainID( genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), ), ), genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.MigrateGenesisCmd(), genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.ValidateGenesisCmd(app.ModuleBasics), AddGenesisAccountCmd(app.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), ethermintclient.TestnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), ) a := appCreator{encCfg: encodingConfig} server.AddCommands(rootCmd, app.DefaultNodeHome, a.newApp, a.appExport, addModuleInitFlags) // add keybase, auxiliary RPC, query, and tx child commands rootCmd.AddCommand( rpc.StatusCommand(), queryCommand(), txCommand(), ethermintclientKey.Commands(app.DefaultNodeHome), ) } func addModuleInitFlags(startCmd *cobra.Command) { crisis.AddModuleInitFlags(startCmd) } func queryCommand() *cobra.Command { cmd := &cobra.Command{ Use: "query", Aliases: []string{"q"}, Short: "Querying subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, } cmd.AddCommand( authcmd.GetAccountCmd(), rpc.ValidatorCommand(), rpc.BlockCommand(), authcmd.QueryTxsByEventsCmd(), authcmd.QueryTxCmd(), ) app.ModuleBasics.AddQueryCommands(cmd) cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") return cmd } func txCommand() *cobra.Command { cmd := &cobra.Command{ Use: "tx", Short: "Transactions subcommands", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, } cmd.AddCommand( authcmd.GetSignCommand(), authcmd.GetSignBatchCommand(), authcmd.GetMultiSignCommand(), authcmd.GetValidateSignaturesCommand(), flags.LineBreak, authcmd.GetBroadcastCommand(), authcmd.GetEncodeCommand(), authcmd.GetDecodeCommand(), flags.LineBreak, vestingcli.GetTxCmd(), ) app.ModuleBasics.AddTxCommands(cmd) cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID") return cmd } type appCreator struct { encCfg params.EncodingConfig } // newApp create a new SDK application binary func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application { var cache sdk.MultiStorePersistentCache if cast.ToBool(appOpts.Get(sdkserver.FlagInterBlockCache)) { cache = store.NewCommitKVStoreCacheManager() } skipUpgradeHeights := make(map[int64]bool) for _, h := range cast.ToIntSlice(appOpts.Get(sdkserver.FlagUnsafeSkipUpgrades)) { skipUpgradeHeights[int64(h)] = true } pruningOpts, err := sdkserver.GetPruningOptionsFromFlags(appOpts) if err != nil { panic(err) } snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots") snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir) if err != nil { panic(err) } snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) if err != nil { panic(err) } return app.NewEthermintApp( logger, db, traceStore, true, skipUpgradeHeights, cast.ToString(appOpts.Get(flags.FlagHome)), cast.ToUint(appOpts.Get(sdkserver.FlagInvCheckPeriod)), a.encCfg, appOpts, baseapp.SetPruning(pruningOpts), baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(sdkserver.FlagMinGasPrices))), baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(sdkserver.FlagHaltHeight))), baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(sdkserver.FlagHaltTime))), baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(sdkserver.FlagMinRetainBlocks))), baseapp.SetInterBlockCache(cache), baseapp.SetTrace(cast.ToBool(appOpts.Get(sdkserver.FlagTrace))), baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(sdkserver.FlagIndexEvents))), baseapp.SetSnapshotStore(snapshotStore), baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(sdkserver.FlagStateSyncSnapshotInterval))), baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(sdkserver.FlagStateSyncSnapshotKeepRecent))), ) } // appExport creates a new Ethermint app (optionally at a given height) // and exports state. func (a appCreator) appExport( logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOpts servertypes.AppOptions) (servertypes.ExportedApp, error) { var ethermintApp *app.EthermintApp homePath, ok := appOpts.Get(flags.FlagHome).(string) if !ok || homePath == "" { return servertypes.ExportedApp{}, errors.New("application home not set") } if height != -1 { ethermintApp = app.NewEthermintApp(logger, db, traceStore, false, map[int64]bool{}, homePath, 0, a.encCfg, appOpts) if err := ethermintApp.LoadHeight(height); err != nil { return servertypes.ExportedApp{}, err } } else { ethermintApp = app.NewEthermintApp(logger, db, traceStore, true, map[int64]bool{}, homePath, 0, a.encCfg, appOpts) } return ethermintApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) }