diff --git a/app/ante/ante.go b/app/ante/ante.go index 9fbded5a82..846ebf61c2 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/signing" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + paramkeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" ibcante "github.com/cosmos/ibc-go/v6/modules/core/ante" ibckeeper "github.com/cosmos/ibc-go/v6/modules/core/keeper" ) @@ -19,6 +20,7 @@ func NewAnteHandler( signModeHandler signing.SignModeHandler, sigGasConsumer ante.SignatureVerificationGasConsumer, channelKeeper *ibckeeper.Keeper, + paramKeeper paramkeeper.Keeper, msgVersioningGateKeeper *MsgVersioningGateKeeper, ) sdk.AnteHandler { return sdk.ChainAnteDecorators( @@ -43,7 +45,7 @@ func NewAnteHandler( ante.NewConsumeGasForTxSizeDecorator(accountKeeper), // Ensure the feepayer (fee granter or first signer) has enough funds to pay for the tx. // Side effect: deducts fees from the fee payer. Sets the tx priority in context. - ante.NewDeductFeeDecorator(accountKeeper, bankKeeper, feegrantKeeper, CheckTxFeeWithGlobalMinGasPrices), + ante.NewDeductFeeDecorator(accountKeeper, bankKeeper, feegrantKeeper, CheckTxFeeWithGlobalMinGasPricesWrapper(paramKeeper)), // Set public keys in the context for fee-payer and all signers. // Contract: must be called before all signature verification decorators. ante.NewSetPubKeyDecorator(accountKeeper), @@ -75,3 +77,11 @@ func NewAnteHandler( } var DefaultSigVerificationGasConsumer = ante.DefaultSigVerificationGasConsumer + +// The purpose of this wrapper is to enable the passing of an additional paramKeeper parameter +// whilst still satisfying the ante.TxFeeChecker type. +func CheckTxFeeWithGlobalMinGasPricesWrapper(paramKeeper paramkeeper.Keeper) ante.TxFeeChecker { + return func(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) { + return CheckTxFeeWithMinGasPrices(ctx, tx, paramKeeper) + } +} diff --git a/app/ante/fee_checker.go b/app/ante/fee_checker.go index 0764c01797..cb4cff93ed 100644 --- a/app/ante/fee_checker.go +++ b/app/ante/fee_checker.go @@ -1,13 +1,14 @@ package ante import ( - "fmt" - errors "cosmossdk.io/errors" + "cosmossdk.io/math" "github.com/celestiaorg/celestia-app/pkg/appconsts" v1 "github.com/celestiaorg/celestia-app/pkg/appconsts/v1" + "github.com/celestiaorg/celestia-app/x/minfee" sdk "github.com/cosmos/cosmos-sdk/types" sdkerror "github.com/cosmos/cosmos-sdk/types/errors" + params "github.com/cosmos/cosmos-sdk/x/params/keeper" ) const ( @@ -15,9 +16,10 @@ const ( priorityScalingFactor = 1_000_000 ) -// CheckTxFeeWithGlobalMinGasPrices implements the default fee logic, where the minimum price per -// unit of gas is fixed and set globally, and the tx priority is computed from the gas price. -func CheckTxFeeWithGlobalMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) { +// CheckTxFeeWithMinGasPrices implements default fee validation logic for transactions. +// It ensures that the provided transaction fee meets a minimum threshold for the validator +// as well as a global minimum threshold and computes the tx priority based on the gas price. +func CheckTxFeeWithMinGasPrices(ctx sdk.Context, tx sdk.Tx, paramKeeper params.Keeper) (sdk.Coins, int64, error) { feeTx, ok := tx.(sdk.FeeTx) if !ok { return nil, 0, errors.Wrap(sdkerror.ErrTxDecode, "Tx must be a FeeTx") @@ -25,23 +27,40 @@ func CheckTxFeeWithGlobalMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, in fee := feeTx.GetFee().AmountOf(appconsts.BondDenom) gas := feeTx.GetGas() - appVersion := ctx.BlockHeader().Version.App - // global minimum fee only applies to app versions greater than one - if appVersion > v1.Version { - globalMinGasPrice := appconsts.GlobalMinGasPrice(appVersion) + // Ensure that the provided fee meets a minimum threshold for the validator. + // This is only for local mempool purposes, and thus + // is only ran on check tx. + if ctx.IsCheckTx() { + minGasPrice := ctx.MinGasPrices().AmountOf(appconsts.BondDenom) + if !minGasPrice.IsZero() { + err := verifyMinFee(fee, gas, minGasPrice, "insufficient minimum gas price for this validator") + if err != nil { + return nil, 0, err + } + } + } - // convert the global minimum gas price to a big.Int - globalMinGasPriceInt, err := sdk.NewDecFromStr(fmt.Sprintf("%f", globalMinGasPrice)) - if err != nil { - return nil, 0, errors.Wrap(err, "invalid GlobalMinGasPrice") + // Ensure that the provided fee meets a global minimum threshold. + // Global minimum fee only applies to app versions greater than one + if ctx.BlockHeader().Version.App > v1.Version { + subspace, exists := paramKeeper.GetSubspace(minfee.ModuleName) + if !exists { + return nil, 0, errors.Wrap(sdkerror.ErrInvalidRequest, "minfee is not a registered subspace") + } + + if !subspace.Has(ctx, minfee.KeyGlobalMinGasPrice) { + return nil, 0, errors.Wrap(sdkerror.ErrKeyNotFound, "GlobalMinGasPrice") } - gasInt := sdk.NewIntFromUint64(gas) - minFee := globalMinGasPriceInt.MulInt(gasInt).RoundInt() + var globalMinGasPrice sdk.Dec + // Gets the global minimum gas price from the param store + // panics if not configured properly + subspace.Get(ctx, minfee.KeyGlobalMinGasPrice, &globalMinGasPrice) - if !fee.GTE(minFee) { - return nil, 0, errors.Wrapf(sdkerror.ErrInsufficientFee, "insufficient fees; got: %s required: %s", fee, minFee) + err := verifyMinFee(fee, gas, globalMinGasPrice, "insufficient gas price for the network") + if err != nil { + return nil, 0, err } } @@ -49,6 +68,17 @@ func CheckTxFeeWithGlobalMinGasPrices(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, in return feeTx.GetFee(), priority, nil } +// verifyMinFee validates that the provided transaction fee is sufficient given the provided minimum gas price. +func verifyMinFee(fee math.Int, gas uint64, minGasPrice sdk.Dec, errMsg string) error { + // Determine the required fee by multiplying required minimum gas + // price by the gas limit, where fee = minGasPrice * gas. + minFee := minGasPrice.MulInt(sdk.NewIntFromUint64(gas)).Ceil() + if fee.LT(minFee.TruncateInt()) { + return errors.Wrapf(sdkerror.ErrInsufficientFee, "%s; got: %s required at least: %s", errMsg, fee, minFee) + } + return nil +} + // getTxPriority returns a naive tx priority based on the amount of the smallest denomination of the gas price // provided in a transaction. // NOTE: This implementation should not be used for txs with multiple coins. diff --git a/app/ante/min_fee_test.go b/app/ante/min_fee_test.go index e4fec46d1a..2c6333b8fc 100644 --- a/app/ante/min_fee_test.go +++ b/app/ante/min_fee_test.go @@ -1,6 +1,7 @@ package ante_test import ( + "fmt" "math" "testing" @@ -8,12 +9,21 @@ import ( "github.com/celestiaorg/celestia-app/app/ante" "github.com/celestiaorg/celestia-app/app/encoding" "github.com/celestiaorg/celestia-app/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/pkg/appconsts/v2" "github.com/celestiaorg/celestia-app/test/util/testnode" + "github.com/celestiaorg/celestia-app/x/minfee" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + paramkeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/stretchr/testify/require" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" version "github.com/tendermint/tendermint/proto/tendermint/version" + tmdb "github.com/tendermint/tm-db" ) func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { @@ -27,46 +37,54 @@ func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { ) require.NoError(t, err) - feeAmount := int64(1000) + // Set the validator's fee + validatorMinGasPrice := 0.8 + validatorMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", validatorMinGasPrice)) + require.NoError(t, err) + validatorMinGasPriceCoin := sdk.NewDecCoinFromDec(appconsts.BondDenom, validatorMinGasPriceDec) - ctx := sdk.Context{} + feeAmount := int64(1000) - globalMinGasPrice := appconsts.DefaultGlobalMinGasPrice - require.NoError(t, err) + paramsKeeper, stateStore := setUp(t) testCases := []struct { name string fee sdk.Coins gasLimit uint64 appVersion uint64 + isCheckTx bool expErr bool }{ { name: "bad tx; fee below required minimum", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount-1)), - gasLimit: uint64(float64(feeAmount) / globalMinGasPrice), + gasLimit: uint64(float64(feeAmount) / v2.GlobalMinGasPrice), appVersion: uint64(2), + isCheckTx: false, expErr: true, }, { name: "good tx; fee equal to required minimum", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount)), - gasLimit: uint64(float64(feeAmount) / globalMinGasPrice), + gasLimit: uint64(float64(feeAmount) / v2.GlobalMinGasPrice), appVersion: uint64(2), + isCheckTx: false, expErr: false, }, { name: "good tx; fee above required minimum", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount+1)), - gasLimit: uint64(float64(feeAmount) / globalMinGasPrice), + gasLimit: uint64(float64(feeAmount) / v2.GlobalMinGasPrice), appVersion: uint64(2), + isCheckTx: false, expErr: false, }, { name: "good tx; with no fee (v1)", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount)), - gasLimit: uint64(float64(feeAmount) / globalMinGasPrice), + gasLimit: uint64(float64(feeAmount) / v2.GlobalMinGasPrice), appVersion: uint64(1), + isCheckTx: false, expErr: false, }, { @@ -74,6 +92,7 @@ func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, math.MaxInt64)), gasLimit: math.MaxUint64, appVersion: uint64(2), + isCheckTx: false, expErr: false, }, { @@ -81,6 +100,7 @@ func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, 0)), gasLimit: 0, appVersion: uint64(2), + isCheckTx: false, expErr: false, }, { @@ -88,8 +108,25 @@ func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount)), gasLimit: 400, appVersion: uint64(2), + isCheckTx: false, + expErr: false, + }, + { + name: "good tx; fee above node's required minimum", + fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount+1)), + gasLimit: uint64(float64(feeAmount) / validatorMinGasPrice), + appVersion: uint64(1), + isCheckTx: true, expErr: false, }, + { + name: "bad tx; fee below node's required minimum", + fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount-1)), + gasLimit: uint64(float64(feeAmount) / validatorMinGasPrice), + appVersion: uint64(1), + isCheckTx: true, + expErr: true, + }, } for _, tc := range testCases { @@ -98,12 +135,22 @@ func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { builder.SetFeeAmount(tc.fee) tx := builder.GetTx() - ctx = ctx.WithBlockHeader(tmproto.Header{ + ctx := sdk.NewContext(stateStore, tmproto.Header{ Version: version.Consensus{ App: tc.appVersion, }, - }) - _, _, err := ante.CheckTxFeeWithGlobalMinGasPrices(ctx, tx) + }, tc.isCheckTx, nil) + + ctx = ctx.WithMinGasPrices(sdk.DecCoins{validatorMinGasPriceCoin}) + + globalminGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", v2.GlobalMinGasPrice)) + require.NoError(t, err) + + subspace, _ := paramsKeeper.GetSubspace(minfee.ModuleName) + minfee.RegisterMinFeeParamTable(subspace) + subspace.Set(ctx, minfee.KeyGlobalMinGasPrice, globalminGasPriceDec) + + _, _, err = ante.CheckTxFeeWithMinGasPrices(ctx, tx, paramsKeeper) if tc.expErr { require.Error(t, err) } else { @@ -112,3 +159,22 @@ func TestCheckTxFeeWithGlobalMinGasPrices(t *testing.T) { }) } } + +func setUp(t *testing.T) (paramkeeper.Keeper, storetypes.CommitMultiStore) { + storeKey := sdk.NewKVStoreKey(paramtypes.StoreKey) + tStoreKey := storetypes.NewTransientStoreKey(paramtypes.TStoreKey) + + // Create the state store + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(tStoreKey, storetypes.StoreTypeTransient, nil) + require.NoError(t, stateStore.LoadLatestVersion()) + + registry := codectypes.NewInterfaceRegistry() + + // Create a params keeper and set the global min gas price + paramsKeeper := paramkeeper.NewKeeper(codec.NewProtoCodec(registry), codec.NewLegacyAmino(), storeKey, tStoreKey) + paramsKeeper.Subspace(minfee.ModuleName) + return paramsKeeper, stateStore +} diff --git a/app/app.go b/app/app.go index e79ba4d1af..31e11b06df 100644 --- a/app/app.go +++ b/app/app.go @@ -5,6 +5,7 @@ import ( "github.com/celestiaorg/celestia-app/app/module" "github.com/celestiaorg/celestia-app/app/posthandler" + "github.com/celestiaorg/celestia-app/x/minfee" "github.com/celestiaorg/celestia-app/x/mint" mintkeeper "github.com/celestiaorg/celestia-app/x/mint/keeper" minttypes "github.com/celestiaorg/celestia-app/x/mint/types" @@ -124,6 +125,7 @@ var ( blob.AppModuleBasic{}, blobstream.AppModuleBasic{}, upgrade.AppModuleBasic{}, + minfee.AppModuleBasic{}, ) // ModuleEncodingRegisters keeps track of all the module methods needed to @@ -456,6 +458,10 @@ func New( Module: upgrade.NewAppModule(app.UpgradeKeeper), FromVersion: v2, ToVersion: v2, }, + { + Module: minfee.NewAppModule(app.ParamsKeeper), + FromVersion: v2, ToVersion: v2, + }, }) if err != nil { panic(err) @@ -486,6 +492,7 @@ func New( authz.ModuleName, vestingtypes.ModuleName, upgradetypes.ModuleName, + minfee.ModuleName, ) app.mm.SetOrderEndBlockers( @@ -509,6 +516,7 @@ func New( authz.ModuleName, vestingtypes.ModuleName, upgradetypes.ModuleName, + minfee.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are @@ -516,6 +524,8 @@ func New( // NOTE: Capability module must occur first so that it can initialize any capabilities // so that other modules that want to create or claim capabilities afterwards in InitChain // can do so safely. + // NOTE: The minfee module must occur before genutil so DeliverTx can + // successfully pass the fee checking logic app.mm.SetOrderInitGenesis( capabilitytypes.ModuleName, authtypes.ModuleName, @@ -527,6 +537,7 @@ func New( minttypes.ModuleName, crisistypes.ModuleName, ibchost.ModuleName, + minfee.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName, @@ -569,6 +580,7 @@ func New( encodingConfig.TxConfig.SignModeHandler(), ante.DefaultSigVerificationGasConsumer, app.IBCKeeper, + app.ParamsKeeper, app.MsgGateKeeper, )) app.SetPostHandler(posthandler.New()) @@ -801,6 +813,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(ibchost.ModuleName) paramsKeeper.Subspace(blobtypes.ModuleName) paramsKeeper.Subspace(blobstreamtypes.ModuleName) + paramsKeeper.Subspace(minfee.ModuleName) return paramsKeeper } diff --git a/app/default_overrides.go b/app/default_overrides.go index d8e3ddd2a0..c07caafdd6 100644 --- a/app/default_overrides.go +++ b/app/default_overrides.go @@ -198,6 +198,17 @@ func getLegacyProposalHandlers() (result []govclient.ProposalHandler) { // DefaultConsensusParams returns a ConsensusParams with a MaxBytes // determined using a goal square size. func DefaultConsensusParams() *tmproto.ConsensusParams { + return &tmproto.ConsensusParams{ + Block: DefaultBlockParams(), + Evidence: DefaultEvidenceParams(), + Validator: coretypes.DefaultValidatorParams(), + Version: tmproto.VersionParams{ + AppVersion: appconsts.LatestVersion, + }, + } +} + +func DefaultInitialConsensusParams() *tmproto.ConsensusParams { return &tmproto.ConsensusParams{ Block: DefaultBlockParams(), Evidence: DefaultEvidenceParams(), diff --git a/app/prepare_proposal.go b/app/prepare_proposal.go index 1bd44c7a91..13f22056f0 100644 --- a/app/prepare_proposal.go +++ b/app/prepare_proposal.go @@ -44,6 +44,7 @@ func (app *App) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePr app.GetTxConfig().SignModeHandler(), ante.DefaultSigVerificationGasConsumer, app.IBCKeeper, + app.ParamsKeeper, app.MsgGateKeeper, ) diff --git a/app/process_proposal.go b/app/process_proposal.go index e5bd36e17c..02fd9f2ca0 100644 --- a/app/process_proposal.go +++ b/app/process_proposal.go @@ -45,6 +45,7 @@ func (app *App) ProcessProposal(req abci.RequestProcessProposal) (resp abci.Resp app.GetTxConfig().SignModeHandler(), ante.DefaultSigVerificationGasConsumer, app.IBCKeeper, + app.ParamsKeeper, app.MsgGateKeeper, ) sdkCtx := app.NewProposalContext(req.Header) diff --git a/go.work.sum b/go.work.sum index 3ae7215140..fe1a9b56bc 100644 --- a/go.work.sum +++ b/go.work.sum @@ -701,7 +701,11 @@ github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 h1:qwcF+vdFrvPSEUDSX5RVoRccG8a5DhOdWdQ4zN62zzo= @@ -710,15 +714,15 @@ github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8 github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/ethereum/go-ethereum v1.13.2/go.mod h1:gkQ5Ygi64ZBh9M/4iXY1R8WqoNCx1Ey0CkYn2BD4/fw= github.com/ethereum/go-ethereum v1.13.11/go.mod h1:gFtlVORuUcT+UUIcJ/veCNjkuOSujCi338uSHJrYAew= -github.com/ethereum/go-ethereum v1.13.12/go.mod h1:hKL2Qcj1OvStXNSEDbucexqnEt1Wh4Cz329XsjAalZY= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= @@ -750,6 +754,7 @@ github.com/go-git/go-git/v5 v5.6.1/go.mod h1:mvyoL6Unz0PiTQrGQfSfiLFhBH1c1e84ylC github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -799,14 +804,7 @@ github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8I github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= @@ -885,7 +883,6 @@ github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/reedsolomon v1.11.8/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ5MGv0Qd8a47h6A= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= @@ -922,12 +919,7 @@ github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJys github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/moricho/tparallel v0.3.0/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= @@ -1114,15 +1106,7 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= -golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= @@ -1155,7 +1139,6 @@ golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1190,12 +1173,6 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= @@ -1232,13 +1209,7 @@ golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY= -google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= -google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= -google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750= -google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI= -google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= @@ -1291,13 +1262,27 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= +k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM= +k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc= +k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A= +k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8= +k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4= +k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= +k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= +k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/proto/celestia/minfee/v1/genesis.proto b/proto/celestia/minfee/v1/genesis.proto new file mode 100644 index 0000000000..769b396921 --- /dev/null +++ b/proto/celestia/minfee/v1/genesis.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package celestia.minfee.v1; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/celestiaorg/celestia-app/x/minfee"; + +// GenesisState defines the minfee module's genesis state. +message GenesisState { + string global_min_gas_price = 1 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; +} diff --git a/specs/src/specs/params.md b/specs/src/specs/params.md index ddde19362a..9aeed355ee 100644 --- a/specs/src/specs/params.md +++ b/specs/src/specs/params.md @@ -64,5 +64,6 @@ are blocked by the `x/paramfilter` module. | staking.MaxValidators | 100 | Maximum number of validators. | True | | staking.MinCommissionRate | 0.05 (5%) | Minimum commission rate used by all validators. | True | | staking.UnbondingTime | 1814400 (21 days) | Duration of time for unbonding in seconds. | False | +| minfee.GlobalMinGasPrice | 0.002 | All transactions must have a gas price greater than or equal to this value | True | Note: none of the mint module parameters are governance modifiable because they have been converted into hardcoded constants. See the x/mint README.md for more details. diff --git a/test/util/malicious/out_of_order_prepare.go b/test/util/malicious/out_of_order_prepare.go index 08d867c6da..0ba9e39000 100644 --- a/test/util/malicious/out_of_order_prepare.go +++ b/test/util/malicious/out_of_order_prepare.go @@ -38,6 +38,7 @@ func (a *App) OutOfOrderPrepareProposal(req abci.RequestPrepareProposal) abci.Re a.GetTxConfig().SignModeHandler(), ante.DefaultSigVerificationGasConsumer, a.IBCKeeper, + a.ParamsKeeper, a.MsgGateKeeper, ) diff --git a/x/blob/types/estimate_gas_test.go b/x/blob/types/estimate_gas_test.go index 1a1216a070..cbc48ee88d 100644 --- a/x/blob/types/estimate_gas_test.go +++ b/x/blob/types/estimate_gas_test.go @@ -39,7 +39,7 @@ func TestPFBGasEstimation(t *testing.T) { for idx, tc := range testCases { t.Run(fmt.Sprintf("case %d", idx), func(t *testing.T) { accnts := testfactory.GenerateAccounts(1) - testApp, kr := testutil.SetupTestAppWithGenesisValSet(app.DefaultConsensusParams(), accnts...) + testApp, kr := testutil.SetupTestAppWithGenesisValSet(app.DefaultInitialConsensusParams(), accnts...) addr := testfactory.GetAddress(kr, accnts[0]) signer, err := user.NewSigner(kr, nil, addr, encCfg.TxConfig, testutil.ChainID, 1, 0, appconsts.LatestVersion) require.NoError(t, err) diff --git a/x/minfee/genesis.go b/x/minfee/genesis.go new file mode 100644 index 0000000000..c7748c45e4 --- /dev/null +++ b/x/minfee/genesis.go @@ -0,0 +1,37 @@ +package minfee + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + params "github.com/cosmos/cosmos-sdk/x/params/keeper" +) + +// DefaultGenesis returns the default genesis state. +func DefaultGenesis() *GenesisState { + return &GenesisState{ + GlobalMinGasPrice: DefaultGlobalMinGasPrice, + } +} + +// ValidateGenesis performs basic validation of genesis data returning an error for any failed validation criteria. +func ValidateGenesis(genesis *GenesisState) error { + if genesis.GlobalMinGasPrice.IsNegative() || genesis.GlobalMinGasPrice.IsZero() { + return fmt.Errorf("global min gas price cannot be negative: %g", genesis.GlobalMinGasPrice) + } + + return nil +} + +// ExportGenesis returns the minfee module's exported genesis. +func ExportGenesis(ctx sdk.Context, k params.Keeper) *GenesisState { + globalMinGasPrice, exists := k.GetSubspace(ModuleName) + + var minGasPrice sdk.Dec + globalMinGasPrice.Get(ctx, KeyGlobalMinGasPrice, &minGasPrice) + if !exists { + panic("minfee subspace not set") + } + + return &GenesisState{GlobalMinGasPrice: minGasPrice} +} diff --git a/x/minfee/genesis.pb.go b/x/minfee/genesis.pb.go new file mode 100644 index 0000000000..d2657a0103 --- /dev/null +++ b/x/minfee/genesis.pb.go @@ -0,0 +1,320 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: celestia/minfee/v1/genesis.proto + +package minfee + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the minfee module's genesis state. +type GenesisState struct { + GlobalMinGasPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=global_min_gas_price,json=globalMinGasPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"global_min_gas_price"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_40506204178306cf, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func init() { + proto.RegisterType((*GenesisState)(nil), "celestia.minfee.v1.GenesisState") +} + +func init() { proto.RegisterFile("celestia/minfee/v1/genesis.proto", fileDescriptor_40506204178306cf) } + +var fileDescriptor_40506204178306cf = []byte{ + // 249 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4e, 0xcd, 0x49, + 0x2d, 0x2e, 0xc9, 0x4c, 0xd4, 0xcf, 0xcd, 0xcc, 0x4b, 0x4b, 0x4d, 0xd5, 0x2f, 0x33, 0xd4, 0x4f, + 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x82, 0xa9, + 0xd0, 0x83, 0xa8, 0xd0, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x4b, 0xeb, 0x83, + 0x58, 0x10, 0x95, 0x52, 0x92, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0xf1, 0x10, 0x09, 0x08, 0x07, + 0x22, 0xa5, 0x54, 0xcb, 0xc5, 0xe3, 0x0e, 0x31, 0x35, 0xb8, 0x24, 0xb1, 0x24, 0x55, 0x28, 0x97, + 0x4b, 0x24, 0x3d, 0x27, 0x3f, 0x29, 0x31, 0x27, 0x3e, 0x37, 0x33, 0x2f, 0x3e, 0x3d, 0x11, 0xa4, + 0x29, 0x33, 0x39, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0xd3, 0xc9, 0xe6, 0xc4, 0x3d, 0x79, 0x86, + 0x5b, 0xf7, 0xe4, 0xd5, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xa1, 0xc6, + 0x41, 0x29, 0xdd, 0xe2, 0x94, 0x6c, 0xfd, 0x92, 0xca, 0x82, 0xd4, 0x62, 0x3d, 0x97, 0xd4, 0xe4, + 0x4b, 0x5b, 0x74, 0xb9, 0xa0, 0xb6, 0xb9, 0xa4, 0x26, 0x07, 0x09, 0x42, 0x4c, 0xf6, 0xcd, 0xcc, + 0x73, 0x4f, 0x2c, 0x0e, 0x00, 0x19, 0xeb, 0xe4, 0x76, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, + 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, + 0x72, 0x0c, 0x51, 0x3a, 0xc8, 0x56, 0x40, 0x3d, 0x9a, 0x5f, 0x94, 0x0e, 0x67, 0xeb, 0x26, 0x16, + 0x14, 0xe8, 0x57, 0x40, 0x03, 0x27, 0x89, 0x0d, 0xec, 0x1b, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x61, 0x71, 0xcd, 0x0a, 0x36, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.GlobalMinGasPrice.Size() + i -= size + if _, err := m.GlobalMinGasPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.GlobalMinGasPrice.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GlobalMinGasPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.GlobalMinGasPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/minfee/module.go b/x/minfee/module.go new file mode 100644 index 0000000000..04695e7938 --- /dev/null +++ b/x/minfee/module.go @@ -0,0 +1,145 @@ +package minfee + +import ( + "encoding/json" + "fmt" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkmodule "github.com/cosmos/cosmos-sdk/types/module" + params "github.com/cosmos/cosmos-sdk/x/params/keeper" +) + +var ( + _ sdkmodule.AppModule = AppModule{} + _ sdkmodule.AppModuleBasic = AppModuleBasic{} +) + +// AppModuleBasic defines the basic application module used by the minfee module. +type AppModuleBasic struct{} + +// RegisterInterfaces registers the module's interfaces with the interface registry. +func (AppModuleBasic) RegisterInterfaces(_ cdctypes.InterfaceRegistry) {} + +// Name returns the minfee module's name. +func (AppModuleBasic) Name() string { + return ModuleName +} + +// RegisterLegacyAminoCodec does nothing. MinFee doesn't use Amino. +func (AppModuleBasic) RegisterLegacyAminoCodec(*codec.LegacyAmino) {} + +// DefaultGenesis returns default genesis state as raw bytes for the minfee module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the minfee module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var data GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) + } + return ValidateGenesis(&data) +} + +// RegisterRESTRoutes registers the REST service handlers for the module. +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(_ client.Context, _ *runtime.ServeMux) {} + +// GetTxCmd returns the minfee module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + // Return a dummy command + return &cobra.Command{} +} + +// GetQueryCmd returns the a dummy command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + // Return a dummy command + return &cobra.Command{} +} + +// AppModule implements an application module for the minfee module. +type AppModule struct { + AppModuleBasic + paramsKeeper params.Keeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule(k params.Keeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + paramsKeeper: k, + } +} + +// RegisterInvariants registers the minfee module invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// Route returns the message routing key for the minfee module. +func (am AppModule) Route() sdk.Route { + return sdk.Route{} +} + +// QuerierRoute returns the minfee module's querier route name. +func (am AppModule) QuerierRoute() string { + return ModuleName +} + +// LegacyQuerierHandler returns the minfee module's Querier. +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(_ sdkmodule.Configurator) {} + +// InitGenesis performs genesis initialization for the minfee module. It returns no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genesisState GenesisState + cdc.MustUnmarshalJSON(gs, &genesisState) + + subspace, exists := am.paramsKeeper.GetSubspace(ModuleName) + if !exists { + panic("minfee subspace not set") + } + + RegisterMinFeeParamTable(subspace) + + // Set the global min gas price initial value + globalMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", genesisState.GlobalMinGasPrice)) + if err != nil { + panic("failed to convert GlobalMinGasPrice to sdk.Dec") + } + + subspace.SetParamSet(ctx, &Params{GlobalMinGasPrice: globalMinGasPriceDec}) + + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the minfee module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := ExportGenesis(ctx, am.paramsKeeper) + return cdc.MustMarshalJSON(gs) +} + +// BeginBlock returns the begin blocker for the minfee module. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {} + +// EndBlock returns the end blocker for the minfee module. It returns no validator updates. +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } diff --git a/x/minfee/params.go b/x/minfee/params.go new file mode 100644 index 0000000000..87c4954038 --- /dev/null +++ b/x/minfee/params.go @@ -0,0 +1,59 @@ +package minfee + +import ( + "fmt" + + "github.com/celestiaorg/celestia-app/pkg/appconsts" + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +const ModuleName = "minfee" + +var _ paramtypes.ParamSet = (*Params)(nil) + +var ( + KeyGlobalMinGasPrice = []byte("GlobalMinGasPrice") + DefaultGlobalMinGasPrice sdk.Dec +) + +func init() { + DefaultGlobalMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", appconsts.DefaultMinGasPrice)) + if err != nil { + panic(err) + } + DefaultGlobalMinGasPrice = DefaultGlobalMinGasPriceDec +} + +type Params struct { + GlobalMinGasPrice sdk.Dec +} + +// RegisterMinFeeParamTable attaches a key table to the provided subspace if it doesn't have one +func RegisterMinFeeParamTable(ps paramtypes.Subspace) { + if !ps.HasKeyTable() { + ps.WithKeyTable(ParamKeyTable()) + } +} + +// ParamKeyTable returns the param key table for the global min gas price module +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +// ParamSetPairs gets the param key-value pair +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyGlobalMinGasPrice, &p.GlobalMinGasPrice, ValidateMinGasPrice), + } +} + +// Validate validates the param type +func ValidateMinGasPrice(i interface{}) error { + _, ok := i.(sdk.Dec) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} diff --git a/x/minfee/upgrade_test.go b/x/minfee/upgrade_test.go new file mode 100644 index 0000000000..0e0152a39c --- /dev/null +++ b/x/minfee/upgrade_test.go @@ -0,0 +1,128 @@ +package minfee_test + +import ( + "encoding/json" + "fmt" + "strings" + "testing" + "time" + + "github.com/celestiaorg/celestia-app/app" + "github.com/celestiaorg/celestia-app/app/encoding" + "github.com/celestiaorg/celestia-app/x/minfee" + + v1 "github.com/celestiaorg/celestia-app/pkg/appconsts/v1" + v2 "github.com/celestiaorg/celestia-app/pkg/appconsts/v2" + "github.com/celestiaorg/celestia-app/test/util" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + "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" + version "github.com/tendermint/tendermint/proto/tendermint/version" + dbm "github.com/tendermint/tm-db" +) + +func TestUpgradeAppVersion(t *testing.T) { + testApp, _ := setupTestApp(t, 3) + + supportedVersions := []uint64{v1.Version, v2.Version} + + require.Equal(t, supportedVersions, testApp.SupportedVersions()) + + ctx := testApp.NewContext(true, tmproto.Header{ + Version: version.Consensus{ + App: 1, + }, + }) + testApp.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ + Height: 2, + Version: version.Consensus{App: 1}, + }}) + + // app version should not have changed yet + require.EqualValues(t, 1, testApp.AppVersion()) + + // global min gas price should not have been set yet + gotBefore, err := testApp.ParamsKeeper.Params(ctx, &proposal.QueryParamsRequest{ + Subspace: minfee.ModuleName, + Key: string(minfee.KeyGlobalMinGasPrice), + }) + require.Equal(t, "", gotBefore.Param.Value) + require.NoError(t, err) + + // now the app version changes + respEndBlock := testApp.EndBlock(abci.RequestEndBlock{Height: 2}) + testApp.Commit() + + require.NotNil(t, respEndBlock.ConsensusParamUpdates.Version) + require.EqualValues(t, 2, respEndBlock.ConsensusParamUpdates.Version.AppVersion) + require.EqualValues(t, 2, testApp.AppVersion()) + + // create a new context after endBlock + newCtx := testApp.NewContext(true, tmproto.Header{ + Version: version.Consensus{ + App: 2, + }, + }) + + // global min gas price should be set + got, err := testApp.ParamsKeeper.Params(newCtx, &proposal.QueryParamsRequest{ + Subspace: minfee.ModuleName, + Key: string(minfee.KeyGlobalMinGasPrice), + }) + require.NoError(t, err) + + want, err := sdk.NewDecFromStr(fmt.Sprintf("%f", v2.GlobalMinGasPrice)) + require.NoError(t, err) + require.Equal(t, want.String(), strings.Trim(got.Param.Value, "\"")) +} + +func setupTestApp(t *testing.T, upgradeHeight int64) (*app.App, keyring.Keyring) { + t.Helper() + + db := dbm.NewMemDB() + chainID := "test_chain" + encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) + testApp := app.New(log.NewNopLogger(), db, nil, true, 0, encCfg, upgradeHeight, util.EmptyAppOptions{}) + + genesisState, _, kr := util.GenesisStateWithSingleValidator(testApp, "account") + + stateBytes, err := json.MarshalIndent(genesisState, "", " ") + require.NoError(t, err) + infoResp := testApp.Info(abci.RequestInfo{}) + require.EqualValues(t, 0, infoResp.AppVersion) + + cp := app.DefaultInitialConsensusParams() + abciParams := &abci.ConsensusParams{ + Block: &abci.BlockParams{ + MaxBytes: cp.Block.MaxBytes, + MaxGas: cp.Block.MaxGas, + }, + Evidence: &cp.Evidence, + Validator: &cp.Validator, + Version: &cp.Version, + } + + _ = testApp.InitChain( + abci.RequestInitChain{ + Time: time.Now(), + Validators: []abci.ValidatorUpdate{}, + ConsensusParams: abciParams, + AppStateBytes: stateBytes, + ChainId: chainID, + }, + ) + + // assert that the chain starts with version provided in genesis + infoResp = testApp.Info(abci.RequestInfo{}) + require.EqualValues(t, app.DefaultInitialConsensusParams().Version.AppVersion, infoResp.AppVersion) + + _ = testApp.Commit() + return testApp, kr +} diff --git a/x/paramfilter/test/gov_params_test.go b/x/paramfilter/test/gov_params_test.go index 3261509db7..db171b8c38 100644 --- a/x/paramfilter/test/gov_params_test.go +++ b/x/paramfilter/test/gov_params_test.go @@ -13,6 +13,7 @@ import ( testutil "github.com/celestiaorg/celestia-app/test/util" blobtypes "github.com/celestiaorg/celestia-app/x/blob/types" bsmoduletypes "github.com/celestiaorg/celestia-app/x/blobstream/types" + minfeetypes "github.com/celestiaorg/celestia-app/x/minfee" "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -486,6 +487,23 @@ func (suite *GovParamsTestSuite) TestModifiableParams() { assert.Equal(want, got) }, }, + { + "minfee.GlobalMinGasPrice", + testProposal(proposal.ParamChange{ + Subspace: minfeetypes.ModuleName, + Key: string(minfeetypes.KeyGlobalMinGasPrice), + Value: `"0.1"`, + }), + func() { + var got sdk.Dec + subspace := suite.app.GetSubspace(minfeetypes.ModuleName) + subspace.Get(suite.ctx, minfeetypes.KeyGlobalMinGasPrice, &got) + + want, err := sdk.NewDecFromStr("0.1") + assert.NoError(err) + assert.Equal(want, got) + }, + }, } for _, tc := range testCases { diff --git a/x/upgrade/upgrade_test.go b/x/upgrade/upgrade_test.go index be4a7f5e1f..64a751344e 100644 --- a/x/upgrade/upgrade_test.go +++ b/x/upgrade/upgrade_test.go @@ -54,7 +54,7 @@ func setupTestApp(t *testing.T, upgradeHeight int64) (*app.App, keyring.Keyring) infoResp := testApp.Info(abci.RequestInfo{}) require.EqualValues(t, 0, infoResp.AppVersion) - cp := app.DefaultConsensusParams() + cp := app.DefaultInitialConsensusParams() abciParams := &abci.ConsensusParams{ Block: &abci.BlockParams{ MaxBytes: cp.Block.MaxBytes, @@ -77,7 +77,7 @@ func setupTestApp(t *testing.T, upgradeHeight int64) (*app.App, keyring.Keyring) // assert that the chain starts with version provided in genesis infoResp = testApp.Info(abci.RequestInfo{}) - require.EqualValues(t, app.DefaultConsensusParams().Version.AppVersion, infoResp.AppVersion) + require.EqualValues(t, app.DefaultInitialConsensusParams().Version.AppVersion, infoResp.AppVersion) _ = testApp.Commit() return testApp, kr