From 5283734e81fa7a77a45dbc427874d5dcfe60bd1f Mon Sep 17 00:00:00 2001 From: Lukasz Cwik Date: Mon, 23 Oct 2023 10:33:59 -0700 Subject: [PATCH] [CLOB-930, CORE-29] Extend the e2e test framework to start the cosmos app using cmd. This works towards enabling and passing in flags for flag based testing. This also works towards enabling daemons on e2e app start-up once the daemons can be cleaned up. This relies on https://github.com/dydxprotocol/cosmos-sdk/pull/29 --- protocol/app/ante/gas_test.go | 9 +- protocol/app/app_test.go | 5 +- .../full_node_prepare_proposal_test.go | 17 +- protocol/cmd/dydxprotocold/cmd/config.go | 4 +- protocol/cmd/dydxprotocold/cmd/root.go | 43 +++- protocol/go.mod | 2 +- protocol/go.sum | 4 +- protocol/testutil/app/app.go | 196 +++++++++++++++++- protocol/x/clob/e2e/order_removal_test.go | 2 + protocol/x/sending/app_test.go | 15 +- 10 files changed, 261 insertions(+), 36 deletions(-) diff --git a/protocol/app/ante/gas_test.go b/protocol/app/ante/gas_test.go index 5352e1be3bd..b6255ab962a 100644 --- a/protocol/app/ante/gas_test.go +++ b/protocol/app/ante/gas_test.go @@ -3,9 +3,7 @@ package ante_test import ( "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/baseapp" bank "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/dydxprotocol/v4-chain/protocol/cmd/dydxprotocold/cmd" testapp "github.com/dydxprotocol/v4-chain/protocol/testutil/app" assets "github.com/dydxprotocol/v4-chain/protocol/x/assets/types" "reflect" @@ -180,12 +178,7 @@ func TestSubmitTxnWithGas(t *testing.T) { }, } - tApp := testapp.NewTestAppBuilder(t). - WithAppOptions( - map[string]interface{}{}, - baseapp.SetMinGasPrices(cmd.MinGasPrice), - ). - Build() + tApp := testapp.NewTestAppBuilder(t).Build() ctx := tApp.InitChain() msgSendCheckTx := testapp.MustMakeCheckTxWithPrivKeySupplier( diff --git a/protocol/app/app_test.go b/protocol/app/app_test.go index 208a313b34d..6e1f0f0ce3e 100644 --- a/protocol/app/app_test.go +++ b/protocol/app/app_test.go @@ -93,8 +93,9 @@ func TestAppIsFullyInitialized(t *testing.T) { } for name, tc := range tests { t.Run(name, func(t *testing.T) { - dydxApp := testapp.DefaultTestApp(tc.customFlags) - uninitializedFields := getUninitializedStructFields(reflect.ValueOf(*dydxApp)) + tApp := testapp.NewTestAppBuilder(t).WithAppOptions(tc.customFlags).Build() + tApp.InitChain() + uninitializedFields := getUninitializedStructFields(reflect.ValueOf(*tApp.App)) // Note that the PriceFeedClient is currently hard coded as disabled in GetDefaultTestAppOptions. // Normally it would be only disabled for non-validating full nodes or for nodes where the diff --git a/protocol/app/prepare/full_node_prepare_proposal_test.go b/protocol/app/prepare/full_node_prepare_proposal_test.go index 8380fb3e33d..04be88f822a 100644 --- a/protocol/app/prepare/full_node_prepare_proposal_test.go +++ b/protocol/app/prepare/full_node_prepare_proposal_test.go @@ -16,19 +16,22 @@ import ( // TestFullNodePrepareProposalHandler test that the full-node PrepareProposal handler always returns // an empty result. func TestFullNodePrepareProposalHandler(t *testing.T) { - t.Cleanup(gometrics.Shutdown) - - conf := gometrics.DefaultConfig("service") - sink := gometrics.NewInmemSink(time.Hour, time.Hour) - _, err := gometrics.NewGlobal(conf, sink) - require.NoError(t, err) - logger, logBuffer := testlog.TestLogger() appOpts := map[string]interface{}{ flags.NonValidatingFullNodeFlag: true, testlog.LoggerInstanceForTest: logger, } tApp := testApp.NewTestAppBuilder(t).WithAppOptions(appOpts).Build() + tApp.InitChain() + + // Set up metrics after test app initialization to override the telemetry that it sets up. + // TODO(CLOB-930): Expose test app telemetry directly instead of requiring tests to do this setup and clean-up + // themselves. + t.Cleanup(gometrics.Shutdown) + conf := gometrics.DefaultConfig("service") + sink := gometrics.NewInmemSink(time.Hour, time.Hour) + _, err := gometrics.NewGlobal(conf, sink) + require.NoError(t, err) found := false tApp.AdvanceToBlock(2, testApp.AdvanceToBlockOptions{ diff --git a/protocol/cmd/dydxprotocold/cmd/config.go b/protocol/cmd/dydxprotocold/cmd/config.go index 1d305f5ad93..e3183f0f83f 100644 --- a/protocol/cmd/dydxprotocold/cmd/config.go +++ b/protocol/cmd/dydxprotocold/cmd/config.go @@ -31,7 +31,7 @@ type DydxAppConfig struct { // initAppConfig helps to override default appConfig template and configs. // return "", nil if no custom configuration is required for the application. -func initAppConfig() (string, interface{}) { +func initAppConfig() (string, *DydxAppConfig) { // Optionally allow the chain developer to overwrite the SDK's default // server config. srvCfg := serverconfig.DefaultConfig() @@ -68,7 +68,7 @@ func initAppConfig() (string, interface{}) { appTemplate := serverconfig.DefaultConfigTemplate - return appTemplate, appConfig + return appTemplate, &appConfig } // initTendermintConfig helps to override default Tendermint Config values. diff --git a/protocol/cmd/dydxprotocold/cmd/root.go b/protocol/cmd/dydxprotocold/cmd/root.go index 35523d552f7..91f5c9c64cd 100644 --- a/protocol/cmd/dydxprotocold/cmd/root.go +++ b/protocol/cmd/dydxprotocold/cmd/root.go @@ -50,7 +50,29 @@ const ( // TODO(DEC-1097): improve `cmd/` by adding tests, custom app configs, custom init cmd, and etc. // NewRootCmd creates a new root command for `dydxprotocold`. It is called once in the main function. -func NewRootCmd(option *RootCmdOption) *cobra.Command { +func NewRootCmd( + option *RootCmdOption, +) *cobra.Command { + return NewRootCmdWithInterceptors( + option, + func(serverCtxPtr *server.Context) { + + }, + func(s string, appConfig *DydxAppConfig) (string, *DydxAppConfig) { + return s, appConfig + }, + func(app *dydxapp.App) *dydxapp.App { + return app + }, + ) +} + +func NewRootCmdWithInterceptors( + option *RootCmdOption, + serverCtxInterceptor func(serverCtxPtr *server.Context), + appConfigInterceptor func(string, *DydxAppConfig) (string, *DydxAppConfig), + appInterceptor func(app *dydxapp.App) *dydxapp.App, +) *cobra.Command { encodingConfig := dydxapp.GetEncodingConfig() initClientCtx := client.Context{}. WithCodec(encodingConfig.Codec). @@ -85,7 +107,7 @@ func NewRootCmd(option *RootCmdOption) *cobra.Command { return err } - customAppTemplate, customAppConfig := initAppConfig() + customAppTemplate, customAppConfig := appConfigInterceptor(initAppConfig()) customTMConfig := initTendermintConfig() if err := server.InterceptConfigsPreRunHandler( @@ -97,18 +119,25 @@ func NewRootCmd(option *RootCmdOption) *cobra.Command { return err } + serverCtxInterceptor(server.GetServerContextFromCmd(cmd)) + return nil }, SilenceUsage: true, } - initRootCmd(rootCmd, option, encodingConfig) + initRootCmd(rootCmd, option, encodingConfig, appInterceptor) return rootCmd } // initRootCmd initializes the app's root command with useful commands. -func initRootCmd(rootCmd *cobra.Command, option *RootCmdOption, encodingConfig dydxapp.EncodingConfig) { +func initRootCmd( + rootCmd *cobra.Command, + option *RootCmdOption, + encodingConfig dydxapp.EncodingConfig, + appInterceptor func(app *dydxapp.App) *dydxapp.App, +) { gentxModule := basic_manager.ModuleBasics[genutiltypes.ModuleName].(genutil.AppModuleBasic) rootCmd.AddCommand( genutilcli.InitCmd(basic_manager.ModuleBasics, dydxapp.DefaultNodeHome), @@ -131,7 +160,9 @@ func initRootCmd(rootCmd *cobra.Command, option *RootCmdOption, encodingConfig d server.AddCommands( rootCmd, dydxapp.DefaultNodeHome, - a.newApp, + func(logger log.Logger, db dbm.DB, writer io.Writer, options servertypes.AppOptions) servertypes.Application { + return appInterceptor(a.newApp(logger, db, writer, options)) + }, a.appExport, func(cmd *cobra.Command) { addModuleInitFlags(cmd) @@ -222,7 +253,7 @@ func (a appCreator) newApp( db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions, -) servertypes.Application { +) *dydxapp.App { var cache sdk.MultiStorePersistentCache if cast.ToBool(appOpts.Get(server.FlagInterBlockCache)) { diff --git a/protocol/go.mod b/protocol/go.mod index fb835c9966c..47c74b6621e 100644 --- a/protocol/go.mod +++ b/protocol/go.mod @@ -375,7 +375,7 @@ replace ( // Use dYdX fork of CometBFT github.com/cometbft/cometbft => github.com/dydxprotocol/cometbft v0.37.3-0.20230908230338-65f7a2f25c18 // Use dYdX fork of Cosmos SDK - github.com/cosmos/cosmos-sdk => github.com/dydxprotocol/cosmos-sdk v0.47.5-0.20231011192538-b95c66dedbd5 + github.com/cosmos/cosmos-sdk => github.com/dydxprotocol/cosmos-sdk v0.47.5-0.20231025201005-bef8a051e94f // Cosmos SDK 0.47.x upgrade guide (https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md#replaces) mentions // that there are stability issues. See https://github.com/cosmos/cosmos-sdk/issues/14949 and // https://github.com/ethereum/go-ethereum/pull/25413 for further context. diff --git a/protocol/go.sum b/protocol/go.sum index 00166e554ff..ffd7b309181 100644 --- a/protocol/go.sum +++ b/protocol/go.sum @@ -505,8 +505,8 @@ github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQx github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/dydxprotocol/cometbft v0.37.3-0.20230908230338-65f7a2f25c18 h1:1RIco92QcPS24BeNCNWJC4zXza4GEHHuoviWIQEQ/NI= github.com/dydxprotocol/cometbft v0.37.3-0.20230908230338-65f7a2f25c18/go.mod h1:cpghf0+1GJpJvrqpTHE6UyTcD05m/xllo0xpufL3PgA= -github.com/dydxprotocol/cosmos-sdk v0.47.5-0.20231011192538-b95c66dedbd5 h1:9lSntpmEJcEhc3al6YmRh51ZHINjqJmzL5it9tMK5+0= -github.com/dydxprotocol/cosmos-sdk v0.47.5-0.20231011192538-b95c66dedbd5/go.mod h1:iaAXVu5Jcd//vREctLTuxLqj5ScUP4psgqW7M6XsaQ8= +github.com/dydxprotocol/cosmos-sdk v0.47.5-0.20231025201005-bef8a051e94f h1:q1WhMJ0EjcF2Tj7MBPd+nacxmj3juiRwz11MZ+m6WAE= +github.com/dydxprotocol/cosmos-sdk v0.47.5-0.20231025201005-bef8a051e94f/go.mod h1:iaAXVu5Jcd//vREctLTuxLqj5ScUP4psgqW7M6XsaQ8= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.3.0 h1:RRL0nge+cWGlxXbUzJ7yMcq6w2XBEr19dCN6HECGaT0= github.com/eapache/go-resiliency v1.3.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho= diff --git a/protocol/testutil/app/app.go b/protocol/testutil/app/app.go index db30882c1b2..abc0fb21aa9 100644 --- a/protocol/testutil/app/app.go +++ b/protocol/testutil/app/app.go @@ -2,12 +2,21 @@ package app import ( "bytes" + "context" "encoding/json" "errors" "fmt" + tmcfg "github.com/cometbft/cometbft/config" + tmcli "github.com/cometbft/cometbft/libs/cli" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/server" + svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + srvtypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/dydxprotocol/v4-chain/protocol/cmd/dydxprotocold/cmd" "math" "math/rand" "os" + "path/filepath" "sync" "testing" "time" @@ -51,6 +60,29 @@ import ( "golang.org/x/exp/slices" ) +// localdydxprotocol Alice config/priv_validator_key.json. +const alicePrivValidatorKeyJson = `{ + "address": "124B880684400B4C0086BD4EE882DCC5B61CF7E3", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "YiARx8259Z+fGFUxQLrz/5FU2RYRT6f5yzvt7D7CrQM=" + }, + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "65frslxv5ig0KSNKlJOHT2FKTkOzkb/66eDPsiBaNUtiIBHHzbn1n58YVTFAuvP/kVTZFhFPp/nLO+3sPsKtAw==" + } +} +` + +// localdydxprotocol Alice config/node_key.json. +const aliceNodeKeyJson = `{ + "priv_key": { + "type": "tendermint/PrivKeyEd25519", + "value": "8EGQBxfGMcRfH0C45UTedEG5Xi3XAcukuInLUqFPpskjp1Ny0c5XvwlKevAwtVvkwoeYYQSe0geQG/cF3GAcUA==" + } +} +` + // MustMakeCheckTxOptions is a struct containing options for MustMakeCheckTx.* functions. type MustMakeCheckTxOptions struct { // AccAddressForSigning is the account that's used to sign the transaction. @@ -263,7 +295,6 @@ type TestAppBuilder struct { genesisDocFn GenesisDocCreatorFn usesDefaultAppConfig bool appOptions map[string]interface{} - baseAppOptions []func(*baseapp.BaseApp) executeCheckTxs ExecuteCheckTxs t testing.TB } @@ -278,10 +309,8 @@ func (tApp TestAppBuilder) WithGenesisDocFn(fn GenesisDocCreatorFn) TestAppBuild // WithAppOptions returns a builder like this one with the specified app options. func (tApp TestAppBuilder) WithAppOptions( appOptions map[string]interface{}, - baseAppOptions ...func(*baseapp.BaseApp), ) TestAppBuilder { tApp.appOptions = appOptions - tApp.baseAppOptions = baseAppOptions tApp.usesDefaultAppConfig = false return tApp } @@ -340,12 +369,40 @@ func (tApp *TestApp) initChainIfNeeded() { // Get the initial genesis state and initialize the chain and commit the results of the initialization. tApp.genesis = tApp.builder.genesisDocFn() - tApp.App = DefaultTestApp(tApp.builder.appOptions, tApp.builder.baseAppOptions...) + + // Prevent Cosmos SDK code from waiting for 5 seconds on each start-up. + // TODO(CORE-538): Remove this during the upgrade since 0.50 Cosmos SDK no longer relies on this. + // There is a benign race here where another instance of the app running at the same time might use the shared + // value which will lead to possibly using the wrong server start time. + originalServerStartTime := srvtypes.ServerStartTime.Load() + srvtypes.ServerStartTime.Store(int64(time.Millisecond * 10)) + + validatorHomeDir, app, shutdownFn, err := launchValidator(tApp.genesis, tApp.builder.appOptions) + if err != nil { + tApp.builder.t.Fatal(err) + } + tApp.App = app + + tApp.builder.t.Cleanup(func() { + doneErr := shutdownFn() + + // Clean-up the home directory. + if err := os.RemoveAll(validatorHomeDir); err != nil { + tApp.builder.t.Logf("Failed to clean-up temporary validator dir %s", validatorHomeDir) + } + + // Restore the original server time. + srvtypes.ServerStartTime.Store(originalServerStartTime) + + if doneErr != nil { + tApp.builder.t.Fatal(doneErr) + } + }) + if tApp.builder.usesDefaultAppConfig { tApp.App.Server.DisableUpdateMonitoringForTesting() } - baseapp.SetChainID(tApp.genesis.ChainID)(tApp.App.GetBaseApp()) if tApp.genesis.GenesisTime.UnixNano() <= time.UnixMilli(0).UnixNano() { panic(fmt.Errorf( "Unable to start chain at time %v, must be greater than unix epoch.", @@ -603,6 +660,135 @@ func (tApp *TestApp) PrepareProposal() abcitypes.ResponsePrepareProposal { }) } +// launchValidator launches a validator using the `start` command with the specified genesis doc and application +// options. `shutdownFn` must be invoked to cancel the execution of the app. It will block till the application +// shuts down. +func launchValidator( + genesis types.GenesisDoc, + appOptions map[string]interface{}, +) (homeDir string, a *app.App, shutdownFn func() error, err error) { + // Create the validators home directory as a temporary directory and fill it with: + // - config/priv_validator_key.json + // - config/node_key.json + // - config/genesis.json + validatorHomeDir := filepath.Join(os.TempDir(), fmt.Sprint(time.Now().UnixNano())) + if err = os.MkdirAll(fmt.Sprintf("%s/config/", validatorHomeDir), 0755); err != nil { + return "", nil, nil, err + } + if err = os.WriteFile( + filepath.Join(validatorHomeDir, "config", "priv_validator_key.json"), + []byte(alicePrivValidatorKeyJson), + 0755, + ); err != nil { + return "", nil, nil, err + } + if err = os.WriteFile( + filepath.Join(validatorHomeDir, "config", "node_key.json"), + []byte(aliceNodeKeyJson), + 0755, + ); err != nil { + return "", nil, nil, err + } + if err = genesis.SaveAs(filepath.Join(validatorHomeDir, "config", "genesis.json")); err != nil { + return "", nil, nil, err + } + + // Create a context that can be cancelled to stop the Cosmos App. + done := make(chan error, 1) + parentCtx, cancelFn := context.WithCancel(context.Background()) + + appCaptor := make(chan *app.App, 1) + // Set up the root command using https://github.com/dydxprotocol/v4-chain/blob/ + // 1fa21ed5d848ed7cc6a98053838cadb68422079f/protocol/cmd/dydxprotocold/main.go#L12 as a basis. + option := cmd.GetOptionWithCustomStartCmd() + rootCmd := cmd.NewRootCmdWithInterceptors( + option, + // Inject the app options and logger + func(serverCtxPtr *server.Context) { + for key, value := range appOptions { + serverCtxPtr.Viper.Set(key, value) + } + + // Set the test logger instance based upon AppOptions. + if logger, ok := appOptions[testlog.LoggerInstanceForTest]; ok { + serverCtxPtr.Logger = logger.(log.Logger) + } + }, + // Override the addresses to use domain sockets to avoid port conflicts. + func(s string, appConfig *cmd.DydxAppConfig) (string, *cmd.DydxAppConfig) { + // Note that the domain sockets need to typically be ~100 bytes or fewer otherwise they will fail to be + // created. The actual limit is OS specific. + apiSocketPath := filepath.Join(validatorHomeDir, "api_socket") + grpcSocketPath := filepath.Join(validatorHomeDir, "grpc_socket") + grpcWebSocketPath := filepath.Join(validatorHomeDir, "grpc_web_socket") + appConfig.API.Address = fmt.Sprintf("unix://%s", apiSocketPath) + appConfig.GRPC.Address = fmt.Sprintf("unix://%s", grpcSocketPath) + appConfig.GRPCWeb.Address = fmt.Sprintf("unix://%s", grpcWebSocketPath) + + // TODO(CORE-29): This disables launching the daemons since not all daemons currently shutdown as needed. + appConfig.API.Enable = false + return s, appConfig + }, + // Capture the application instance. + func(app *app.App) *app.App { + appCaptor <- app + return app + }, + ) + + // Specify the start-up flags. + // TODO(CLOB-930): Allow for these flags to be overridden. + rootCmd.SetArgs([]string{ + "start", + // Do not start tendermint. + "--grpc-only", + "true", + "--home", + validatorHomeDir, + // TODO(CORE-29): Allow the daemons to be launched and cleaned-up successfully by default. + "--price-daemon-enabled", + "false", + "--bridge-daemon-enabled", + "false", + "--liquidation-daemon-enabled", + "false", + }) + + ctx := svrcmd.CreateExecuteContext(parentCtx) + rootCmd.PersistentFlags().String( + flags.FlagLogLevel, + tmcfg.DefaultLogLevel, + "The logging level (trace|debug|info|warn|error|fatal|panic)", + ) + rootCmd.PersistentFlags().String( + flags.FlagLogFormat, + tmcfg.LogFormatPlain, + "The logging format (json|plain)", + ) + executor := tmcli.PrepareBaseCmd(rootCmd, app.AppDaemonName, app.DefaultNodeHome) + // We need to launch the root command in a separate go routine since it only returns once the app is shutdown. + // So we wait for either the app to be captured representing a successful start or capture an error. + go func() { + // ExecuteContext will block and will only return if interrupted. + done <- executor.ExecuteContext(ctx) + }() + select { + case a = <-appCaptor: + case err = <-done: + // Send the error to done channel so that `Cleanup` function will not block. + cancelFn() + done <- err + return "", nil, nil, err + } + + shutdownFn = func() error { + cancelFn() + return <-done + } + + return validatorHomeDir, a, shutdownFn, nil +} + // MustMakeCheckTxsWithClobMsg creates one signed RequestCheckTx for each msg passed in. // The messsage must use one of the hard-coded well known subaccount owners otherwise this will panic. func MustMakeCheckTxsWithClobMsg[T clobtypes.MsgPlaceOrder | clobtypes.MsgCancelOrder]( diff --git a/protocol/x/clob/e2e/order_removal_test.go b/protocol/x/clob/e2e/order_removal_test.go index 0858d2d2a7e..e564ffa71fa 100644 --- a/protocol/x/clob/e2e/order_removal_test.go +++ b/protocol/x/clob/e2e/order_removal_test.go @@ -332,6 +332,7 @@ func TestConditionalOrderRemoval(t *testing.T) { testapp.MustMakeCheckTxOptions{ AccAddressForSigning: testtx.MustGetOnlySignerAddress(tc.withdrawal), Gas: 100_000, + FeeAmt: constants.TestFeeCoins_5Cents, }, tc.withdrawal, ) @@ -923,6 +924,7 @@ func TestOrderRemoval(t *testing.T) { testapp.MustMakeCheckTxOptions{ AccAddressForSigning: testtx.MustGetOnlySignerAddress(tc.withdrawal), Gas: 100_000, + FeeAmt: constants.TestFeeCoins_5Cents, }, tc.withdrawal, ) diff --git a/protocol/x/sending/app_test.go b/protocol/x/sending/app_test.go index 88de257123c..f1836549d9e 100644 --- a/protocol/x/sending/app_test.go +++ b/protocol/x/sending/app_test.go @@ -120,6 +120,7 @@ func TestMsgDepositToSubaccount(t *testing.T) { testapp.MustMakeCheckTxOptions{ AccAddressForSigning: testtx.MustGetOnlySignerAddress(&msgDepositToSubaccount), Gas: 100_000, + FeeAmt: constants.TestFeeCoins_5Cents, }, &msgDepositToSubaccount, ) @@ -143,7 +144,11 @@ func TestMsgDepositToSubaccount(t *testing.T) { // Check expected account balance. accountBalanceAfterDeposit := tApp.App.BankKeeper.GetBalance(ctx, tc.accountAccAddress, tc.asset.Denom) - require.Equal(t, accountBalanceAfterDeposit, accountBalanceBeforeDeposit.Sub(transferredCoin)) + require.Equal( + t, + accountBalanceAfterDeposit, + accountBalanceBeforeDeposit.Sub(transferredCoin).Sub(constants.TestFeeCoins_5Cents[0]), + ) // Check expected subaccount asset position. subaccountQuantumsAfterDeposit := getSubaccountAssetQuantums(tApp.App.SubaccountsKeeper, ctx, tc.subaccountId, tc.asset) @@ -308,7 +313,8 @@ func TestMsgWithdrawFromSubaccount(t *testing.T) { tApp.App, testapp.MustMakeCheckTxOptions{ AccAddressForSigning: testtx.MustGetOnlySignerAddress(&msgWithdrawFromSubaccount), - Gas: 100_000, + Gas: constants.TestGasLimit, + FeeAmt: constants.TestFeeCoins_5Cents, }, &msgWithdrawFromSubaccount, ) @@ -332,6 +338,9 @@ func TestMsgWithdrawFromSubaccount(t *testing.T) { // Check expected account balance. accountBalanceAfterWithdraw := tApp.App.BankKeeper.GetBalance(ctx, tc.accountAccAddress, tc.asset.Denom) + if tc.subaccountId.Owner == tc.accountAccAddress.String() { + accountBalanceAfterWithdraw = accountBalanceAfterWithdraw.Add(constants.TestFeeCoins_5Cents[0]) + } require.Equal(t, accountBalanceAfterWithdraw, accountBalanceBeforeWithdraw.Add(transferredCoin)) // Check expected subaccount asset position. subaccountQuantumsAfterWithdraw := @@ -424,7 +433,7 @@ func testNonExistentSender( rand.NewRand(), tApp.App.TxConfig(), []sdk.Msg{message}, - sdk.Coins{}, + constants.TestFeeCoins_5Cents, 100_000, // gas ctx.ChainID(), []uint64{0}, // dummy account number