From 8e65cbe62a12e433fc7a7104e14ee36ccf539e8d Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Tue, 3 May 2022 13:47:13 -0400 Subject: [PATCH] feat: bypass min fee check for custom message types (backport #1447) (#1457) --- CHANGELOG.md | 5 ++ app/ante_handler.go => ante/ante.go | 36 ++++++----- ante/ante_test.go | 99 +++++++++++++++++++++++++++++ ante/fee.go | 75 ++++++++++++++++++++++ ante/fee_test.go | 59 +++++++++++++++++ app/app.go | 11 ++-- app/helpers/test_helpers.go | 81 +++++++++++++++++++++++ app/params/config.go | 35 ++++++++++ cmd/gaiad/cmd/root.go | 21 +++--- cmd/gaiad/cmd/root_test.go | 3 +- cmd/gaiad/cmd/testnet.go | 13 +++- 11 files changed, 403 insertions(+), 35 deletions(-) rename app/ante_handler.go => ante/ante.go (55%) create mode 100644 ante/ante_test.go create mode 100644 ante/fee.go create mode 100644 ante/fee_test.go create mode 100644 app/params/config.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ed85ba0cf5..88aa8375ff1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,11 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +* [#1447](https://github.com/cosmos/gaia/pull/1447) Support custom message types to bypass minimum fee checks for. + If a transaction contains only bypassed message types, the transaction will not have minimum fee + checks performed during `CheckTx`. Operators can supply these message types via the `bypass-min-fee-msg-types` + configuration in `app.toml`. Note, by default they include various IBC message types. + ## [v7.0.1] -2022-04-13 * (gaia) bump [cosmos-sdk](https://github.com/cosmos/cosmos-sdk) to [v0.45.3](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.45.3). See [CHANGELOG.md](https://github.com/cosmos/cosmos-sdk/blob/v0.45.3/CHANGELOG.md#v0453---2022-04-12) for details. diff --git a/app/ante_handler.go b/ante/ante.go similarity index 55% rename from app/ante_handler.go rename to ante/ante.go index fb0dc91f3e0..ae54c73794c 100644 --- a/app/ante_handler.go +++ b/ante/ante.go @@ -1,4 +1,4 @@ -package gaia +package ante import ( sdk "github.com/cosmos/cosmos-sdk/types" @@ -12,21 +12,23 @@ import ( // channel keeper. type HandlerOptions struct { ante.HandlerOptions - IBCkeeper *ibckeeper.Keeper + + IBCkeeper *ibckeeper.Keeper + BypassMinFeeMsgTypes []string } -func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { - if options.AccountKeeper == nil { +func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) { + if opts.AccountKeeper == nil { return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "account keeper is required for AnteHandler") } - if options.BankKeeper == nil { + if opts.BankKeeper == nil { return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "bank keeper is required for AnteHandler") } - if options.SignModeHandler == nil { + if opts.SignModeHandler == nil { return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "sign mode handler is required for ante builder") } - var sigGasConsumer = options.SigGasConsumer + var sigGasConsumer = opts.SigGasConsumer if sigGasConsumer == nil { sigGasConsumer = ante.DefaultSigVerificationGasConsumer } @@ -34,19 +36,19 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { anteDecorators := []sdk.AnteDecorator{ ante.NewSetUpContextDecorator(), ante.NewRejectExtensionOptionsDecorator(), - ante.NewMempoolFeeDecorator(), + NewMempoolFeeDecorator(opts.BypassMinFeeMsgTypes), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), - ante.NewValidateMemoDecorator(options.AccountKeeper), - ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), - ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), + ante.NewValidateMemoDecorator(opts.AccountKeeper), + ante.NewConsumeGasForTxSizeDecorator(opts.AccountKeeper), + ante.NewDeductFeeDecorator(opts.AccountKeeper, opts.BankKeeper, opts.FeegrantKeeper), // SetPubKeyDecorator must be called before all signature verification decorators - ante.NewSetPubKeyDecorator(options.AccountKeeper), - ante.NewValidateSigCountDecorator(options.AccountKeeper), - ante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), - ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), - ante.NewIncrementSequenceDecorator(options.AccountKeeper), - ibcante.NewAnteDecorator(options.IBCkeeper), + ante.NewSetPubKeyDecorator(opts.AccountKeeper), + ante.NewValidateSigCountDecorator(opts.AccountKeeper), + ante.NewSigGasConsumeDecorator(opts.AccountKeeper, sigGasConsumer), + ante.NewSigVerificationDecorator(opts.AccountKeeper, opts.SignModeHandler), + ante.NewIncrementSequenceDecorator(opts.AccountKeeper), + ibcante.NewAnteDecorator(opts.IBCkeeper), } return sdk.ChainAnteDecorators(anteDecorators...), nil diff --git a/ante/ante_test.go b/ante/ante_test.go new file mode 100644 index 00000000000..c0e5b08d3ab --- /dev/null +++ b/ante/ante_test.go @@ -0,0 +1,99 @@ +package ante_test + +import ( + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/stretchr/testify/suite" + tmrand "github.com/tendermint/tendermint/libs/rand" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + gaiaapp "github.com/cosmos/gaia/v7/app" + gaiahelpers "github.com/cosmos/gaia/v7/app/helpers" +) + +type IntegrationTestSuite struct { + suite.Suite + + app *gaiaapp.GaiaApp + anteHandler sdk.AnteHandler + ctx sdk.Context + clientCtx client.Context + txBuilder client.TxBuilder +} + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +func (s *IntegrationTestSuite) SetupTest() { + app := gaiahelpers.Setup(s.T(), false, 1) + ctx := app.BaseApp.NewContext(false, tmproto.Header{ + ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), + Height: 1, + }) + + encodingConfig := simapp.MakeTestEncodingConfig() + encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) + testdata.RegisterInterfaces(encodingConfig.InterfaceRegistry) + + s.app = app + s.ctx = ctx + s.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig) +} + +func (s *IntegrationTestSuite) CreateTestTx(privs []cryptotypes.PrivKey, accNums []uint64, accSeqs []uint64, chainID string) (xauthsigning.Tx, error) { + var sigsV2 []signing.SignatureV2 + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: s.clientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: accSeqs[i], + } + + sigsV2 = append(sigsV2, sigV2) + } + + if err := s.txBuilder.SetSignatures(sigsV2...); err != nil { + return nil, err + } + + sigsV2 = []signing.SignatureV2{} + for i, priv := range privs { + signerData := xauthsigning.SignerData{ + ChainID: chainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + } + sigV2, err := tx.SignWithPrivKey( + s.clientCtx.TxConfig.SignModeHandler().DefaultMode(), + signerData, + s.txBuilder, + priv, + s.clientCtx.TxConfig, + accSeqs[i], + ) + if err != nil { + return nil, err + } + + sigsV2 = append(sigsV2, sigV2) + } + + if err := s.txBuilder.SetSignatures(sigsV2...); err != nil { + return nil, err + } + + return s.txBuilder.GetTx(), nil +} diff --git a/ante/fee.go b/ante/fee.go new file mode 100644 index 00000000000..2d1cb083358 --- /dev/null +++ b/ante/fee.go @@ -0,0 +1,75 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + tmstrings "github.com/tendermint/tendermint/libs/strings" +) + +const maxBypassMinFeeMsgGasUsage = uint64(200_000) + +// MempoolFeeDecorator will check if the transaction's fee is at least as large +// as the local validator's minimum gasFee (defined in validator config). +// +// If fee is too low, decorator returns error and tx is rejected from mempool. +// Note this only applies when ctx.CheckTx = true. If fee is high enough or not +// CheckTx, then call next AnteHandler. +// +// CONTRACT: Tx must implement FeeTx to use MempoolFeeDecorator +type MempoolFeeDecorator struct { + BypassMinFeeMsgTypes []string +} + +func NewMempoolFeeDecorator(bypassMsgTypes []string) MempoolFeeDecorator { + return MempoolFeeDecorator{ + BypassMinFeeMsgTypes: bypassMsgTypes, + } +} + +func (mfd MempoolFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") + } + + feeCoins := feeTx.GetFee() + gas := feeTx.GetGas() + msgs := feeTx.GetMsgs() + + // Only check for minimum fees if the execution mode is CheckTx and the tx does + // not contain operator configured bypass messages. If the tx does contain + // operator configured bypass messages only, it's total gas must be less than + // or equal to a constant, otherwise minimum fees are checked to prevent spam. + if ctx.IsCheckTx() && !simulate && !(mfd.bypassMinFeeMsgs(msgs) && gas <= uint64(len(msgs))*maxBypassMinFeeMsgGasUsage) { + minGasPrices := ctx.MinGasPrices() + if !minGasPrices.IsZero() { + requiredFees := make(sdk.Coins, len(minGasPrices)) + + // Determine the required fees by multiplying each required minimum gas + // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). + glDec := sdk.NewDec(int64(gas)) + for i, gp := range minGasPrices { + fee := gp.Amount.Mul(glDec) + requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) + } + + if !feeCoins.IsAnyGTE(requiredFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, requiredFees) + } + } + } + + return next(ctx, tx, simulate) +} + +func (mfd MempoolFeeDecorator) bypassMinFeeMsgs(msgs []sdk.Msg) bool { + for _, msg := range msgs { + if tmstrings.StringInSlice(sdk.MsgTypeURL(msg), mfd.BypassMinFeeMsgTypes) { + continue + } + + return false + } + + return true +} diff --git a/ante/fee_test.go b/ante/fee_test.go new file mode 100644 index 00000000000..0d454868d56 --- /dev/null +++ b/ante/fee_test.go @@ -0,0 +1,59 @@ +package ante_test + +import ( + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + + "github.com/cosmos/gaia/v7/ante" +) + +func (s *IntegrationTestSuite) TestMempoolFeeDecorator() { + s.SetupTest() + s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewMempoolFeeDecorator([]string{ + sdk.MsgTypeURL(&ibcchanneltypes.MsgRecvPacket{}), + sdk.MsgTypeURL(&ibcchanneltypes.MsgAcknowledgement{}), + sdk.MsgTypeURL(&ibcclienttypes.MsgUpdateClient{}), + }) + antehandler := sdk.ChainAnteDecorators(mfd) + priv1, _, addr1 := testdata.KeyTestPubAddr() + + msg := testdata.NewTestMsg(addr1) + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + s.Require().NoError(s.txBuilder.SetMsgs(msg)) + s.txBuilder.SetFeeAmount(feeAmount) + s.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) + s.Require().NoError(err) + + // Set high gas price so standard test fee fails + feeAmt := sdk.NewDecCoinFromDec("uatom", sdk.NewDec(200).Quo(sdk.NewDec(100000))) + minGasPrice := []sdk.DecCoin{feeAmt} + s.ctx = s.ctx.WithMinGasPrices(minGasPrice).WithIsCheckTx(true) + + // antehandler errors with insufficient fees + _, err = antehandler(s.ctx, tx, false) + s.Require().Error(err, "expected error due to low fee") + + // ensure no fees for certain IBC msgs + s.Require().NoError(s.txBuilder.SetMsgs( + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + )) + + oracleTx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) + _, err = antehandler(s.ctx, oracleTx, false) + s.Require().NoError(err, "expected min fee bypass for IBC messages") + + s.ctx = s.ctx.WithIsCheckTx(false) + + // antehandler should not error since we do not check min gas prices in DeliverTx + _, err = antehandler(s.ctx, tx, false) + s.Require().NoError(err, "unexpected error during DeliverTx") +} diff --git a/app/app.go b/app/app.go index 31d7534c499..8b2ee1b7cea 100644 --- a/app/app.go +++ b/app/app.go @@ -104,11 +104,13 @@ import ( tmos "github.com/tendermint/tendermint/libs/os" dbm "github.com/tendermint/tm-db" - gaiaappparams "github.com/cosmos/gaia/v7/app/params" "github.com/strangelove-ventures/packet-forward-middleware/v2/router" routerkeeper "github.com/strangelove-ventures/packet-forward-middleware/v2/router/keeper" routertypes "github.com/strangelove-ventures/packet-forward-middleware/v2/router/types" + gaiaante "github.com/cosmos/gaia/v7/ante" + gaiaappparams "github.com/cosmos/gaia/v7/app/params" + // unnamed import of statik for swagger UI support _ "github.com/cosmos/cosmos-sdk/client/docs/statik" ) @@ -602,8 +604,8 @@ func NewGaiaApp( app.MountTransientStores(tkeys) app.MountMemoryStores(memKeys) - anteHandler, err := NewAnteHandler( - HandlerOptions{ + anteHandler, err := gaiaante.NewAnteHandler( + gaiaante.HandlerOptions{ HandlerOptions: ante.HandlerOptions{ AccountKeeper: app.AccountKeeper, BankKeeper: app.BankKeeper, @@ -611,7 +613,8 @@ func NewGaiaApp( SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, - IBCkeeper: app.IBCKeeper, + IBCkeeper: app.IBCKeeper, + BypassMinFeeMsgTypes: cast.ToStringSlice(appOpts.Get(gaiaappparams.BypassMinFeeMsgTypesKey)), }, ) if err != nil { diff --git a/app/helpers/test_helpers.go b/app/helpers/test_helpers.go index 4f6ec87af43..d131e7ed654 100644 --- a/app/helpers/test_helpers.go +++ b/app/helpers/test_helpers.go @@ -1,6 +1,87 @@ package helpers +import ( + "encoding/json" + "testing" + "time" + + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" + dbm "github.com/tendermint/tm-db" + + gaiaapp "github.com/cosmos/gaia/v7/app" +) + // SimAppChainID hardcoded chainID for simulation const ( SimAppChainID = "gaia-app" ) + +// DefaultConsensusParams defines the default Tendermint consensus params used +// in GaiaApp testing. +var DefaultConsensusParams = &abci.ConsensusParams{ + Block: &abci.BlockParams{ + MaxBytes: 200000, + MaxGas: 2000000, + }, + Evidence: &tmproto.EvidenceParams{ + MaxAgeNumBlocks: 302400, + MaxAgeDuration: 504 * time.Hour, // 3 weeks is the max duration + MaxBytes: 10000, + }, + Validator: &tmproto.ValidatorParams{ + PubKeyTypes: []string{ + tmtypes.ABCIPubKeyTypeEd25519, + }, + }, +} + +type EmptyAppOptions struct{} + +func (EmptyAppOptions) Get(o string) interface{} { return nil } + +func Setup(t *testing.T, isCheckTx bool, invCheckPeriod uint) *gaiaapp.GaiaApp { + t.Helper() + + app, genesisState := setup(!isCheckTx, invCheckPeriod) + if !isCheckTx { + // InitChain must be called to stop deliverState from being nil + stateBytes, err := json.MarshalIndent(genesisState, "", " ") + require.NoError(t, err) + + // Initialize the chain + app.InitChain( + abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + ConsensusParams: DefaultConsensusParams, + AppStateBytes: stateBytes, + }, + ) + } + + return app +} + +func setup(withGenesis bool, invCheckPeriod uint) (*gaiaapp.GaiaApp, gaiaapp.GenesisState) { + db := dbm.NewMemDB() + encCdc := gaiaapp.MakeEncodingConfig() + app := gaiaapp.NewGaiaApp( + log.NewNopLogger(), + db, + nil, + true, + map[int64]bool{}, + gaiaapp.DefaultNodeHome, + invCheckPeriod, + encCdc, + EmptyAppOptions{}, + ) + if withGenesis { + return app, gaiaapp.NewDefaultGenesisState() + } + + return app, gaiaapp.GenesisState{} +} diff --git a/app/params/config.go b/app/params/config.go new file mode 100644 index 00000000000..aead6b5e680 --- /dev/null +++ b/app/params/config.go @@ -0,0 +1,35 @@ +package params + +import ( + serverconfig "github.com/cosmos/cosmos-sdk/server/config" +) + +var ( + // BypassMinFeeMsgTypesKey defines the configuration key for the + // BypassMinFeeMsgTypes value. + // nolint: gosec + BypassMinFeeMsgTypesKey = "bypass-min-fee-msg-types" + + // CustomConfigTemplate defines Gaia's custom application configuration TOML + // template. It extends the core SDK template. + CustomConfigTemplate = serverconfig.DefaultConfigTemplate + ` +############################################################################### +### Custom Gaia Configuration ### +############################################################################### +# bypass-min-fee-msg-types defines custom message types the operator may set that +# will bypass minimum fee checks during CheckTx. +# +# Example: +# ["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.channel.v1.MsgAcknowledgement", ...] +bypass-min-fee-msg-types = [{{ range .BypassMinFeeMsgTypes }}{{ printf "%q, " . }}{{end}}] +` +) + +// CustomAppConfig defines Gaia's custom application configuration. +type CustomAppConfig struct { + serverconfig.Config + + // BypassMinFeeMsgTypes defines custom message types the operator may set that + // will bypass minimum fee checks during CheckTx. + BypassMinFeeMsgTypes []string `mapstructure:"bypass-min-fee-msg-types"` +} diff --git a/cmd/gaiad/cmd/root.go b/cmd/gaiad/cmd/root.go index 251ef05884f..111ad1e86b0 100644 --- a/cmd/gaiad/cmd/root.go +++ b/cmd/gaiad/cmd/root.go @@ -24,6 +24,8 @@ import ( 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" + ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" "github.com/spf13/cast" "github.com/spf13/cobra" tmcli "github.com/tendermint/tendermint/libs/cli" @@ -77,21 +79,18 @@ func NewRootCmd() (*cobra.Command, params.EncodingConfig) { } func initAppConfig() (string, interface{}) { - - type CustomAppConfig struct { - serverconfig.Config - } - - // Allow overrides to the SDK default server config srvCfg := serverconfig.DefaultConfig() srvCfg.StateSync.SnapshotInterval = 1000 srvCfg.StateSync.SnapshotKeepRecent = 10 - GaiaAppCfg := CustomAppConfig{Config: *srvCfg} - - GaiaAppTemplate := serverconfig.DefaultConfigTemplate - - return GaiaAppTemplate, GaiaAppCfg + return params.CustomConfigTemplate, params.CustomAppConfig{ + Config: *srvCfg, + BypassMinFeeMsgTypes: []string{ + sdk.MsgTypeURL(&ibcchanneltypes.MsgRecvPacket{}), + sdk.MsgTypeURL(&ibcchanneltypes.MsgAcknowledgement{}), + sdk.MsgTypeURL(&ibcclienttypes.MsgUpdateClient{}), + }, + } } func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { diff --git a/cmd/gaiad/cmd/root_test.go b/cmd/gaiad/cmd/root_test.go index 1077e98bac8..b88cdbb8a15 100644 --- a/cmd/gaiad/cmd/root_test.go +++ b/cmd/gaiad/cmd/root_test.go @@ -4,14 +4,13 @@ import ( "testing" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" + "github.com/stretchr/testify/require" app "github.com/cosmos/gaia/v7/app" "github.com/cosmos/gaia/v7/cmd/gaiad/cmd" - "github.com/stretchr/testify/require" ) func TestRootCmdConfig(t *testing.T) { - rootCmd, _ := cmd.NewRootCmd() rootCmd.SetArgs([]string{ "config", // Test the config cmd diff --git a/cmd/gaiad/cmd/testnet.go b/cmd/gaiad/cmd/testnet.go index 8dcd767ae3c..063f37fc5b4 100644 --- a/cmd/gaiad/cmd/testnet.go +++ b/cmd/gaiad/cmd/testnet.go @@ -33,6 +33,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + ibcclienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" + ibcchanneltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + + "github.com/cosmos/gaia/v7/app/params" ) var ( @@ -121,13 +125,20 @@ func InitTestnet( nodeIDs := make([]string, numValidators) valPubKeys := make([]cryptotypes.PubKey, numValidators) - simappConfig := srvconfig.DefaultConfig() + simappConfig := params.CustomAppConfig{ + Config: *srvconfig.DefaultConfig(), + } simappConfig.MinGasPrices = minGasPrices simappConfig.API.Enable = true simappConfig.Telemetry.Enabled = true simappConfig.Telemetry.PrometheusRetentionTime = 60 simappConfig.Telemetry.EnableHostnameLabel = false simappConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", chainID}} + simappConfig.BypassMinFeeMsgTypes = []string{ + sdk.MsgTypeURL(&ibcchanneltypes.MsgRecvPacket{}), + sdk.MsgTypeURL(&ibcchanneltypes.MsgAcknowledgement{}), + sdk.MsgTypeURL(&ibcclienttypes.MsgUpdateClient{}), + } var ( genAccounts []authtypes.GenesisAccount