feat: simapp/v2 (#20412)
Co-authored-by: marbar3778 <marbar3778@yahoo.com> Co-authored-by: Marko <marko@baricevic.me> Co-authored-by: Likhita Polavarapu <78951027+likhita-809@users.noreply.github.com> Co-authored-by: unknown unknown <unknown@unknown>
This commit is contained in:
co-authored by
marbar3778
Marko
Likhita Polavarapu
unknown unknown
parent
ca195c1527
commit
2d014b26c2
@@ -0,0 +1,240 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"cosmossdk.io/client/v2/offchain"
|
||||
"cosmossdk.io/core/transaction"
|
||||
"cosmossdk.io/log"
|
||||
runtimev2 "cosmossdk.io/runtime/v2"
|
||||
"cosmossdk.io/server/v2/cometbft"
|
||||
"cosmossdk.io/simapp/v2"
|
||||
confixcmd "cosmossdk.io/tools/confix/cmd"
|
||||
authcmd "cosmossdk.io/x/auth/client/cli"
|
||||
|
||||
"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/keys"
|
||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
// TODO migrate all server dependencies to server/v2
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||
)
|
||||
|
||||
var _ transaction.Codec[transaction.Tx] = &temporaryTxDecoder{}
|
||||
|
||||
type temporaryTxDecoder struct {
|
||||
txConfig client.TxConfig
|
||||
}
|
||||
|
||||
// Decode implements transaction.Codec.
|
||||
func (t *temporaryTxDecoder) Decode(bz []byte) (transaction.Tx, error) {
|
||||
return t.txConfig.TxDecoder()(bz)
|
||||
}
|
||||
|
||||
// DecodeJSON implements transaction.Codec.
|
||||
func (t *temporaryTxDecoder) DecodeJSON(bz []byte) (transaction.Tx, error) {
|
||||
return t.txConfig.TxJSONDecoder()(bz)
|
||||
}
|
||||
|
||||
func initRootCmd(
|
||||
rootCmd *cobra.Command,
|
||||
txConfig client.TxConfig,
|
||||
_ codectypes.InterfaceRegistry,
|
||||
_ codec.Codec,
|
||||
moduleManager *runtimev2.MM,
|
||||
v1moduleManager *module.Manager,
|
||||
) {
|
||||
cfg := sdk.GetConfig()
|
||||
cfg.Seal()
|
||||
|
||||
rootCmd.AddCommand(
|
||||
genutilcli.InitCmd(moduleManager),
|
||||
debug.Cmd(),
|
||||
confixcmd.ConfigCommand(),
|
||||
startCommand(&temporaryTxDecoder{txConfig}),
|
||||
// TODO pruning.Cmd(newApp),
|
||||
// TODO snapshot.Cmd(newApp),
|
||||
)
|
||||
|
||||
// add keybase, auxiliary RPC, query, genesis, and tx child commands
|
||||
rootCmd.AddCommand(
|
||||
server.StatusCommand(),
|
||||
genesisCommand(txConfig, v1moduleManager, appExport),
|
||||
queryCommand(),
|
||||
txCommand(),
|
||||
keys.Commands(),
|
||||
offchain.OffChain(),
|
||||
)
|
||||
}
|
||||
|
||||
func startCommand(txCodec transaction.Codec[transaction.Tx]) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "Start the application",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
serverCtx := server.GetServerContextFromCmd(cmd)
|
||||
sa := simapp.NewSimApp(serverCtx.Logger, serverCtx.Viper)
|
||||
am := sa.App.AppManager
|
||||
serverCfg := cometbft.Config{CmtConfig: serverCtx.Config, ConsensusAuthority: sa.GetConsensusAuthority()}
|
||||
|
||||
cometServer := cometbft.NewCometBFTServer[transaction.Tx](
|
||||
am,
|
||||
sa.GetStore(),
|
||||
sa.GetLogger(),
|
||||
serverCfg,
|
||||
txCodec,
|
||||
)
|
||||
ctx := cmd.Context()
|
||||
ctx, cancelFn := context.WithCancel(ctx)
|
||||
g, _ := errgroup.WithContext(ctx)
|
||||
g.Go(func() error {
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
sig := <-sigCh
|
||||
cancelFn()
|
||||
cmd.Printf("caught %s signal\n", sig.String())
|
||||
|
||||
if err := cometServer.Stop(ctx); err != nil {
|
||||
cmd.PrintErrln("failed to stop servers:", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := cometServer.Start(ctx); err != nil {
|
||||
return fmt.Errorf("failed to start servers: %w", err)
|
||||
}
|
||||
return g.Wait()
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter
|
||||
func genesisCommand(
|
||||
txConfig client.TxConfig,
|
||||
moduleManager *module.Manager,
|
||||
appExport servertypes.AppExporter,
|
||||
cmds ...*cobra.Command,
|
||||
) *cobra.Command {
|
||||
cmd := genutilcli.Commands(txConfig, moduleManager, appExport)
|
||||
|
||||
for _, subCmd := range cmds {
|
||||
cmd.AddCommand(subCmd)
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func queryCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query",
|
||||
Aliases: []string{"q"},
|
||||
Short: "Querying subcommands",
|
||||
DisableFlagParsing: false,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
rpc.QueryEventForTxCmd(),
|
||||
server.QueryBlockCmd(),
|
||||
authcmd.QueryTxsByEventsCmd(),
|
||||
server.QueryBlocksCmd(),
|
||||
authcmd.QueryTxCmd(),
|
||||
server.QueryBlockResultsCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func txCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "tx",
|
||||
Short: "Transactions subcommands",
|
||||
DisableFlagParsing: false,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
authcmd.GetSignCommand(),
|
||||
authcmd.GetSignBatchCommand(),
|
||||
authcmd.GetMultiSignCommand(),
|
||||
authcmd.GetMultiSignBatchCmd(),
|
||||
authcmd.GetValidateSignaturesCommand(),
|
||||
authcmd.GetBroadcastCommand(),
|
||||
authcmd.GetEncodeCommand(),
|
||||
authcmd.GetDecodeCommand(),
|
||||
authcmd.GetSimulateCmd(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// appExport creates a new simapp (optionally at a given height) and exports state.
|
||||
func appExport(
|
||||
logger log.Logger,
|
||||
_ dbm.DB,
|
||||
_ io.Writer,
|
||||
height int64,
|
||||
forZeroHeight bool,
|
||||
jailAllowedAddrs []string,
|
||||
appOpts servertypes.AppOptions,
|
||||
modulesToExport []string,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
// this check is necessary as we use the flag in x/upgrade.
|
||||
// we can exit more gracefully by checking the flag here.
|
||||
homePath, ok := appOpts.Get(flags.FlagHome).(string)
|
||||
if !ok || homePath == "" {
|
||||
return servertypes.ExportedApp{}, errors.New("application home not set")
|
||||
}
|
||||
|
||||
viperAppOpts, ok := appOpts.(*viper.Viper)
|
||||
if !ok {
|
||||
return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper")
|
||||
}
|
||||
|
||||
// overwrite the FlagInvCheckPeriod
|
||||
viperAppOpts.Set(server.FlagInvCheckPeriod, 1)
|
||||
appOpts = viperAppOpts
|
||||
|
||||
var simApp *simapp.SimApp
|
||||
if height != -1 {
|
||||
simApp = simapp.NewSimApp(logger, appOpts)
|
||||
|
||||
if err := simApp.LoadHeight(uint64(height)); err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
} else {
|
||||
simApp = simapp.NewSimApp(logger, appOpts)
|
||||
}
|
||||
|
||||
return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
|
||||
}
|
||||
|
||||
var tempDir = func() string {
|
||||
dir, err := os.MkdirTemp("", "simapp")
|
||||
if err != nil {
|
||||
dir = simapp.DefaultNodeHome
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
return dir
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
cmtcfg "github.com/cometbft/cometbft/config"
|
||||
|
||||
clientconfig "github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||
)
|
||||
|
||||
// initCometBFTConfig helps to override default CometBFT Config values.
|
||||
// return cmtcfg.DefaultConfig if no custom configuration is required for the application.
|
||||
func initCometBFTConfig() *cmtcfg.Config {
|
||||
cfg := cmtcfg.DefaultConfig()
|
||||
|
||||
// only display only error logs by default except for p2p and state
|
||||
cfg.LogLevel = "*:error,p2p:info,state:info"
|
||||
|
||||
// these values put a higher strain on node memory
|
||||
// cfg.P2P.MaxNumInboundPeers = 100
|
||||
// cfg.P2P.MaxNumOutboundPeers = 40
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
// initAppConfig helps to override default client config template and configs.
|
||||
// return "", nil if no custom configuration is required for the application.
|
||||
func initClientConfig() (string, interface{}) {
|
||||
type GasConfig struct {
|
||||
GasAdjustment float64 `mapstructure:"gas-adjustment"`
|
||||
}
|
||||
|
||||
type CustomClientConfig struct {
|
||||
clientconfig.Config `mapstructure:",squash"`
|
||||
|
||||
GasConfig GasConfig `mapstructure:"gas"`
|
||||
}
|
||||
|
||||
// Optionally allow the chain developer to overwrite the SDK's default client config.
|
||||
clientCfg := clientconfig.DefaultConfig()
|
||||
|
||||
// The SDK's default keyring backend is set to "os".
|
||||
// This is more secure than "test" and is the recommended value.
|
||||
//
|
||||
// In simapp, we set the default keyring backend to test, as SimApp is meant
|
||||
// to be an example and testing application.
|
||||
clientCfg.KeyringBackend = keyring.BackendTest
|
||||
|
||||
// Now we set the custom config default values.
|
||||
customClientConfig := CustomClientConfig{
|
||||
Config: *clientCfg,
|
||||
GasConfig: GasConfig{
|
||||
GasAdjustment: 1.5,
|
||||
},
|
||||
}
|
||||
|
||||
// The default SDK app template is defined in serverconfig.DefaultConfigTemplate.
|
||||
// We append the custom config template to the default one.
|
||||
// And we set the default config to the custom app template.
|
||||
customClientConfigTemplate := clientconfig.DefaultClientConfigTemplate + strings.TrimSpace(`
|
||||
# This is default the gas adjustment factor used in tx commands.
|
||||
# It can be overwritten by the --gas-adjustment flag in each tx command.
|
||||
gas-adjustment = {{ .GasConfig.GasAdjustment }}
|
||||
`)
|
||||
|
||||
return customClientConfigTemplate, customClientConfig
|
||||
}
|
||||
|
||||
// initAppConfig helps to override default appConfig template and configs.
|
||||
// return "", nil if no custom configuration is required for the application.
|
||||
func initAppConfig() (string, interface{}) {
|
||||
// The following code snippet is just for reference.
|
||||
|
||||
// CustomConfig defines an arbitrary custom config to extend app.toml.
|
||||
// If you don't need it, you can remove it.
|
||||
// If you wish to add fields that correspond to flags that aren't in the SDK server config,
|
||||
// this custom config can as well help.
|
||||
type CustomConfig struct {
|
||||
CustomField string `mapstructure:"custom-field"`
|
||||
}
|
||||
|
||||
type CustomAppConfig struct {
|
||||
serverconfig.Config `mapstructure:",squash"`
|
||||
|
||||
Custom CustomConfig `mapstructure:"custom"`
|
||||
}
|
||||
|
||||
// Optionally allow the chain developer to overwrite the SDK's default
|
||||
// server config.
|
||||
srvCfg := serverconfig.DefaultConfig()
|
||||
// The SDK's default minimum gas price is set to "" (empty value) inside
|
||||
// app.toml. If left empty by validators, the node will halt on startup.
|
||||
// However, the chain developer can set a default app.toml value for their
|
||||
// validators here.
|
||||
//
|
||||
// In summary:
|
||||
// - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their
|
||||
// own app.toml config,
|
||||
// - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
|
||||
// own app.toml to override, or use this default value.
|
||||
//
|
||||
// In simapp, we set the min gas prices to 0.
|
||||
srvCfg.MinGasPrices = "0stake"
|
||||
// srvCfg.BaseConfig.IAVLDisableFastNode = true // disable fastnode by default
|
||||
|
||||
// Now we set the custom config default values.
|
||||
customAppConfig := CustomAppConfig{
|
||||
Config: *srvCfg,
|
||||
Custom: CustomConfig{
|
||||
CustomField: "anything",
|
||||
},
|
||||
}
|
||||
|
||||
// The default SDK app template is defined in serverconfig.DefaultConfigTemplate.
|
||||
// We append the custom config template to the default one.
|
||||
// And we set the default config to the custom app template.
|
||||
customAppTemplate := serverconfig.DefaultConfigTemplate + `
|
||||
[custom]
|
||||
# That field will be parsed by server.InterceptConfigsPreRunHandler and held by viper.
|
||||
# Do not forget to add quotes around the value if it is a string.
|
||||
custom-field = "{{ .Custom.CustomField }}"`
|
||||
|
||||
return customAppTemplate, customAppConfig
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"cosmossdk.io/client/v2/autocli"
|
||||
clientv2keyring "cosmossdk.io/client/v2/autocli/keyring"
|
||||
"cosmossdk.io/core/address"
|
||||
"cosmossdk.io/core/appmodule/v2"
|
||||
"cosmossdk.io/core/legacy"
|
||||
"cosmossdk.io/depinject"
|
||||
"cosmossdk.io/log"
|
||||
"cosmossdk.io/runtime/v2"
|
||||
"cosmossdk.io/simapp/v2"
|
||||
"cosmossdk.io/x/auth/tx"
|
||||
authtxconfig "cosmossdk.io/x/auth/tx/config"
|
||||
"cosmossdk.io/x/auth/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/server" // TODO: remove me: https://github.com/cosmos/cosmos-sdk/pull/20412/files#r1622878528
|
||||
"github.com/cosmos/cosmos-sdk/std"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
)
|
||||
|
||||
// NewRootCmd creates a new root command for simd. It is called once in the main function.
|
||||
func NewRootCmd() *cobra.Command {
|
||||
var (
|
||||
autoCliOpts autocli.AppOptions
|
||||
moduleManager *runtime.MM
|
||||
v1ModuleManager *module.Manager
|
||||
clientCtx client.Context
|
||||
)
|
||||
|
||||
if err := depinject.Inject(
|
||||
depinject.Configs(
|
||||
simapp.AppConfig(),
|
||||
depinject.Supply(
|
||||
log.NewNopLogger(),
|
||||
simtestutil.NewAppOptionsWithFlagHome(tempDir()),
|
||||
),
|
||||
depinject.Provide(
|
||||
codec.ProvideInterfaceRegistry,
|
||||
codec.ProvideAddressCodec,
|
||||
codec.ProvideProtoCodec,
|
||||
codec.ProvideLegacyAmino,
|
||||
ProvideClientContext,
|
||||
ProvideKeyring,
|
||||
ProvideV1ModuleManager,
|
||||
),
|
||||
depinject.Invoke(
|
||||
std.RegisterInterfaces,
|
||||
std.RegisterLegacyAminoCodec,
|
||||
),
|
||||
),
|
||||
&autoCliOpts,
|
||||
&moduleManager,
|
||||
&v1ModuleManager,
|
||||
&clientCtx,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "simd",
|
||||
Short: "simulation app",
|
||||
SilenceErrors: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||
// set the default command outputs
|
||||
cmd.SetOut(cmd.OutOrStdout())
|
||||
cmd.SetErr(cmd.ErrOrStderr())
|
||||
|
||||
clientCtx = clientCtx.WithCmdContext(cmd.Context()).WithViper("")
|
||||
clientCtx, err := client.ReadPersistentCommandFlags(clientCtx, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
customClientTemplate, customClientConfig := initClientConfig()
|
||||
clientCtx, err = config.CreateClientConfig(clientCtx, customClientTemplate, customClientConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
customAppTemplate, customAppConfig := initAppConfig()
|
||||
customCMTConfig := initCometBFTConfig()
|
||||
|
||||
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customCMTConfig)
|
||||
},
|
||||
}
|
||||
|
||||
initRootCmd(
|
||||
rootCmd,
|
||||
clientCtx.TxConfig,
|
||||
clientCtx.InterfaceRegistry,
|
||||
clientCtx.Codec,
|
||||
moduleManager,
|
||||
v1ModuleManager)
|
||||
|
||||
if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
func ProvideClientContext(
|
||||
appCodec codec.Codec,
|
||||
interfaceRegistry codectypes.InterfaceRegistry,
|
||||
txConfigOpts tx.ConfigOptions,
|
||||
legacyAmino legacy.Amino,
|
||||
addressCodec address.Codec,
|
||||
validatorAddressCodec address.ValidatorAddressCodec,
|
||||
consensusAddressCodec address.ConsensusAddressCodec,
|
||||
) client.Context {
|
||||
var err error
|
||||
|
||||
amino, ok := legacyAmino.(*codec.LegacyAmino)
|
||||
if !ok {
|
||||
panic("legacy.Amino must be an *codec.LegacyAmino instance for legacy ClientContext")
|
||||
}
|
||||
|
||||
clientCtx := client.Context{}.
|
||||
WithCodec(appCodec).
|
||||
WithInterfaceRegistry(interfaceRegistry).
|
||||
WithLegacyAmino(amino).
|
||||
WithInput(os.Stdin).
|
||||
WithAccountRetriever(types.AccountRetriever{}).
|
||||
WithAddressCodec(addressCodec).
|
||||
WithValidatorAddressCodec(validatorAddressCodec).
|
||||
WithConsensusAddressCodec(consensusAddressCodec).
|
||||
WithHomeDir(simapp.DefaultNodeHome).
|
||||
WithViper("") // uses by default the binary name as prefix
|
||||
|
||||
// Read the config to overwrite the default values with the values from the config file
|
||||
customClientTemplate, customClientConfig := initClientConfig()
|
||||
clientCtx, err = config.ReadDefaultValuesFromDefaultClientConfig(clientCtx, customClientTemplate, customClientConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// textual is enabled by default, we need to re-create the tx config grpc instead of bank keeper.
|
||||
txConfigOpts.TextualCoinMetadataQueryFn = authtxconfig.NewGRPCCoinMetadataQueryFn(clientCtx)
|
||||
txConfig, err := tx.NewTxConfigWithOptions(clientCtx.Codec, txConfigOpts)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
clientCtx = clientCtx.WithTxConfig(txConfig)
|
||||
|
||||
return clientCtx
|
||||
}
|
||||
|
||||
func ProvideKeyring(clientCtx client.Context, addressCodec address.Codec) (clientv2keyring.Keyring, error) {
|
||||
kb, err := client.NewKeyringFromBackend(clientCtx, clientCtx.Keyring.Backend())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return keyring.NewAutoCLIKeyring(kb)
|
||||
}
|
||||
|
||||
func ProvideV1ModuleManager(modules map[string]appmodule.AppModule) *module.Manager {
|
||||
return module.NewManagerFromMap(modules)
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package cmd_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"cosmossdk.io/simapp/v2"
|
||||
"cosmossdk.io/simapp/v2/simdv2/cmd"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||
)
|
||||
|
||||
func TestInitCmd(t *testing.T) {
|
||||
rootCmd := cmd.NewRootCmd()
|
||||
rootCmd.SetArgs([]string{
|
||||
"init", // Test the init cmd
|
||||
"simapp-test", // Moniker
|
||||
fmt.Sprintf("--%s=%s", cli.FlagOverwrite, "true"), // Overwrite genesis.json, in case it already exists
|
||||
})
|
||||
|
||||
require.NoError(t, svrcmd.Execute(rootCmd, "", simapp.DefaultNodeHome))
|
||||
}
|
||||
|
||||
func TestHomeFlagRegistration(t *testing.T) {
|
||||
homeDir := "/tmp/foo"
|
||||
|
||||
rootCmd := cmd.NewRootCmd()
|
||||
rootCmd.SetArgs([]string{
|
||||
"query",
|
||||
fmt.Sprintf("--%s", flags.FlagHome),
|
||||
homeDir,
|
||||
})
|
||||
|
||||
require.NoError(t, svrcmd.Execute(rootCmd, "", simapp.DefaultNodeHome))
|
||||
|
||||
result, err := rootCmd.Flags().GetString(flags.FlagHome)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, result, homeDir)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"cosmossdk.io/simapp/v2"
|
||||
"cosmossdk.io/simapp/v2/simdv2/cmd"
|
||||
|
||||
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rootCmd := cmd.NewRootCmd()
|
||||
if err := svrcmd.Execute(rootCmd, "", simapp.DefaultNodeHome); err != nil {
|
||||
fmt.Fprintln(rootCmd.OutOrStderr(), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user