github.com/Finschia/finschia-sdk@v0.48.1/simapp/simd/cmd/root.go (about)

     1  package cmd
     2  
     3  import (
     4  	"errors"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"github.com/spf13/cast"
    10  	"github.com/spf13/cobra"
    11  	"github.com/spf13/viper"
    12  
    13  	ostcli "github.com/Finschia/ostracon/libs/cli"
    14  	"github.com/Finschia/ostracon/libs/log"
    15  	dbm "github.com/tendermint/tm-db"
    16  
    17  	"github.com/Finschia/finschia-sdk/baseapp"
    18  	"github.com/Finschia/finschia-sdk/client"
    19  	"github.com/Finschia/finschia-sdk/client/config"
    20  	"github.com/Finschia/finschia-sdk/client/debug"
    21  	"github.com/Finschia/finschia-sdk/client/flags"
    22  	"github.com/Finschia/finschia-sdk/client/keys"
    23  	"github.com/Finschia/finschia-sdk/client/pruning"
    24  	"github.com/Finschia/finschia-sdk/client/rpc"
    25  	"github.com/Finschia/finschia-sdk/server"
    26  	serverconfig "github.com/Finschia/finschia-sdk/server/config"
    27  	servertypes "github.com/Finschia/finschia-sdk/server/types"
    28  	"github.com/Finschia/finschia-sdk/simapp"
    29  	"github.com/Finschia/finschia-sdk/simapp/params"
    30  	"github.com/Finschia/finschia-sdk/snapshots"
    31  	"github.com/Finschia/finschia-sdk/store"
    32  	sdk "github.com/Finschia/finschia-sdk/types"
    33  	authcmd "github.com/Finschia/finschia-sdk/x/auth/client/cli"
    34  	"github.com/Finschia/finschia-sdk/x/auth/types"
    35  	banktypes "github.com/Finschia/finschia-sdk/x/bank/types"
    36  	"github.com/Finschia/finschia-sdk/x/crisis"
    37  	genutilcli "github.com/Finschia/finschia-sdk/x/genutil/client/cli"
    38  )
    39  
    40  // NewRootCmd creates a new root command for simd. It is called once in the
    41  // main function.
    42  func NewRootCmd() (*cobra.Command, params.EncodingConfig) {
    43  	encodingConfig := simapp.MakeTestEncodingConfig()
    44  	initClientCtx := client.Context{}.
    45  		WithCodec(encodingConfig.Marshaler).
    46  		WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
    47  		WithTxConfig(encodingConfig.TxConfig).
    48  		WithLegacyAmino(encodingConfig.Amino).
    49  		WithInput(os.Stdin).
    50  		WithAccountRetriever(types.AccountRetriever{}).
    51  		WithHomeDir(simapp.DefaultNodeHome).
    52  		WithViper("") // In simapp, we don't use any prefix for env variables.
    53  
    54  	rootCmd := &cobra.Command{
    55  		Use:   "simd",
    56  		Short: "simulation app",
    57  		PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
    58  			// set the default command outputs
    59  			cmd.SetOut(cmd.OutOrStdout())
    60  			cmd.SetErr(cmd.ErrOrStderr())
    61  
    62  			initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
    63  			if err != nil {
    64  				return err
    65  			}
    66  
    67  			initClientCtx, err = config.ReadFromClientConfig(initClientCtx)
    68  			if err != nil {
    69  				return err
    70  			}
    71  
    72  			if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
    73  				return err
    74  			}
    75  
    76  			customAppTemplate, customAppConfig := initAppConfig()
    77  
    78  			return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig)
    79  		},
    80  	}
    81  
    82  	initRootCmd(rootCmd, encodingConfig)
    83  
    84  	return rootCmd, encodingConfig
    85  }
    86  
    87  // initAppConfig helps to override default appConfig template and configs.
    88  // return "", nil if no custom configuration is required for the application.
    89  func initAppConfig() (string, interface{}) {
    90  	// The following code snippet is just for reference.
    91  
    92  	type CustomAppConfig struct {
    93  		serverconfig.Config
    94  	}
    95  
    96  	// Optionally allow the chain developer to overwrite the SDK's default
    97  	// server config.
    98  	srvCfg := serverconfig.DefaultConfig()
    99  	// The SDK's default minimum gas price is set to "" (empty value) inside
   100  	// app.toml. If left empty by validators, the node will halt on startup.
   101  	// However, the chain developer can set a default app.toml value for their
   102  	// validators here.
   103  	//
   104  	// In summary:
   105  	// - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their
   106  	//   own app.toml config,
   107  	// - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
   108  	//   own app.toml to override, or use this default value.
   109  	//
   110  	// In simapp, we set the min gas prices to 0.
   111  	srvCfg.MinGasPrices = "0stake"
   112  	// srvCfg.BaseConfig.IAVLDisableFastNode = true // disable fastnode by default
   113  
   114  	customAppConfig := CustomAppConfig{
   115  		Config: *srvCfg,
   116  	}
   117  
   118  	customAppTemplate := serverconfig.DefaultConfigTemplate
   119  
   120  	return customAppTemplate, customAppConfig
   121  }
   122  
   123  func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
   124  	cfg := sdk.GetConfig()
   125  	cfg.Seal()
   126  
   127  	a := appCreator{encodingConfig}
   128  	rootCmd.AddCommand(
   129  		genutilcli.InitCmd(simapp.ModuleBasics, simapp.DefaultNodeHome),
   130  		genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
   131  		genutilcli.GenTxCmd(simapp.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, simapp.DefaultNodeHome),
   132  		genutilcli.MigrateGenesisCmd(),
   133  		genutilcli.ValidateGenesisCmd(simapp.ModuleBasics),
   134  		AddGenesisAccountCmd(simapp.DefaultNodeHome),
   135  		ostcli.NewCompletionCmd(rootCmd, true),
   136  		testnetCmd(simapp.ModuleBasics, banktypes.GenesisBalancesIterator{}),
   137  		debug.Cmd(),
   138  		config.Cmd(),
   139  		pruning.PruningCmd(a.newApp),
   140  	)
   141  
   142  	server.AddCommands(rootCmd, simapp.DefaultNodeHome, a.newApp, a.appExport, addModuleInitFlags)
   143  
   144  	// add keybase, auxiliary RPC, query, and tx child commands
   145  	rootCmd.AddCommand(
   146  		rpc.StatusCommand(),
   147  		queryCommand(),
   148  		txCommand(),
   149  		keys.Commands(simapp.DefaultNodeHome),
   150  	)
   151  
   152  	// add rosetta
   153  	rootCmd.AddCommand(server.RosettaCommand(encodingConfig.InterfaceRegistry, encodingConfig.Marshaler))
   154  }
   155  
   156  func addModuleInitFlags(startCmd *cobra.Command) {
   157  	crisis.AddModuleInitFlags(startCmd)
   158  }
   159  
   160  func queryCommand() *cobra.Command {
   161  	cmd := &cobra.Command{
   162  		Use:                        "query",
   163  		Aliases:                    []string{"q"},
   164  		Short:                      "Querying subcommands",
   165  		DisableFlagParsing:         true,
   166  		SuggestionsMinimumDistance: 2,
   167  		RunE:                       client.ValidateCmd,
   168  	}
   169  
   170  	cmd.AddCommand(
   171  		authcmd.GetAccountCmd(),
   172  		rpc.ValidatorCommand(),
   173  		rpc.BlockCommand(),
   174  		authcmd.QueryTxsByEventsCmd(),
   175  		authcmd.QueryTxCmd(),
   176  	)
   177  
   178  	simapp.ModuleBasics.AddQueryCommands(cmd)
   179  	cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID")
   180  
   181  	return cmd
   182  }
   183  
   184  func txCommand() *cobra.Command {
   185  	cmd := &cobra.Command{
   186  		Use:                        "tx",
   187  		Short:                      "Transactions subcommands",
   188  		DisableFlagParsing:         true,
   189  		SuggestionsMinimumDistance: 2,
   190  		RunE:                       client.ValidateCmd,
   191  	}
   192  
   193  	cmd.AddCommand(
   194  		authcmd.GetSignCommand(),
   195  		authcmd.GetSignBatchCommand(),
   196  		authcmd.GetMultiSignCommand(),
   197  		authcmd.GetMultiSignBatchCmd(),
   198  		authcmd.GetValidateSignaturesCommand(),
   199  		authcmd.GetBroadcastCommand(),
   200  		authcmd.GetEncodeCommand(),
   201  		authcmd.GetDecodeCommand(),
   202  	)
   203  
   204  	simapp.ModuleBasics.AddTxCommands(cmd)
   205  	cmd.PersistentFlags().String(flags.FlagChainID, "", "The network chain ID")
   206  
   207  	return cmd
   208  }
   209  
   210  type appCreator struct {
   211  	encCfg params.EncodingConfig
   212  }
   213  
   214  // newApp is an AppCreator
   215  func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application {
   216  	var cache sdk.MultiStorePersistentCache
   217  
   218  	ibCacheMetricsProvider := baseapp.MetricsProvider(cast.ToBool(viper.GetBool(server.FlagPrometheus)))
   219  	if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) {
   220  		cache = store.NewCommitKVStoreCacheManager(
   221  			cast.ToInt(appOpts.Get(server.FlagInterBlockCacheSize)), ibCacheMetricsProvider)
   222  	}
   223  
   224  	skipUpgradeHeights := make(map[int64]bool)
   225  	for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
   226  		skipUpgradeHeights[int64(h)] = true
   227  	}
   228  
   229  	pruningOpts, err := server.GetPruningOptionsFromFlags(appOpts)
   230  	if err != nil {
   231  		panic(err)
   232  	}
   233  
   234  	snapshotDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data", "snapshots")
   235  	snapshotDB, err := sdk.NewLevelDB("metadata", snapshotDir)
   236  	if err != nil {
   237  		panic(err)
   238  	}
   239  	snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir)
   240  	if err != nil {
   241  		panic(err)
   242  	}
   243  
   244  	return simapp.NewSimApp(
   245  		logger, db, traceStore, true, skipUpgradeHeights,
   246  		cast.ToString(appOpts.Get(flags.FlagHome)),
   247  		cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)),
   248  		a.encCfg,
   249  		appOpts,
   250  		baseapp.SetPruning(pruningOpts),
   251  		baseapp.SetMinGasPrices(cast.ToString(appOpts.Get(server.FlagMinGasPrices))),
   252  		baseapp.SetHaltHeight(cast.ToUint64(appOpts.Get(server.FlagHaltHeight))),
   253  		baseapp.SetHaltTime(cast.ToUint64(appOpts.Get(server.FlagHaltTime))),
   254  		baseapp.SetMinRetainBlocks(cast.ToUint64(appOpts.Get(server.FlagMinRetainBlocks))),
   255  		baseapp.SetInterBlockCache(cache),
   256  		baseapp.SetTrace(cast.ToBool(appOpts.Get(server.FlagTrace))),
   257  		baseapp.SetIndexEvents(cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents))),
   258  		baseapp.SetSnapshotStore(snapshotStore),
   259  		baseapp.SetSnapshotInterval(cast.ToUint64(appOpts.Get(server.FlagStateSyncSnapshotInterval))),
   260  		baseapp.SetSnapshotKeepRecent(cast.ToUint32(appOpts.Get(server.FlagStateSyncSnapshotKeepRecent))),
   261  		baseapp.SetIAVLCacheSize(cast.ToInt(appOpts.Get(server.FlagIAVLCacheSize))),
   262  		baseapp.SetIAVLDisableFastNode(cast.ToBool(appOpts.Get(server.FlagIAVLFastNode))),
   263  		baseapp.SetChanCheckTxSize(cast.ToUint(appOpts.Get(server.FlagChanCheckTxSize))),
   264  	)
   265  }
   266  
   267  // appExport creates a new simapp (optionally at a given height)
   268  // and exports state.
   269  func (a appCreator) appExport(
   270  	logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string,
   271  	appOpts servertypes.AppOptions,
   272  ) (servertypes.ExportedApp, error) {
   273  	var simApp *simapp.SimApp
   274  	homePath, ok := appOpts.Get(flags.FlagHome).(string)
   275  	if !ok || homePath == "" {
   276  		return servertypes.ExportedApp{}, errors.New("application home not set")
   277  	}
   278  
   279  	if height != -1 {
   280  		simApp = simapp.NewSimApp(logger, db, traceStore, false, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts)
   281  
   282  		if err := simApp.LoadHeight(height); err != nil {
   283  			return servertypes.ExportedApp{}, err
   284  		}
   285  	} else {
   286  		simApp = simapp.NewSimApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts)
   287  	}
   288  
   289  	return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs)
   290  }