From 7ca8bf42fa6c6f79dab2305bf316c75481bc1b5c Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Feb 2023 14:47:22 +0100 Subject: [PATCH 01/42] - Update doc to follow Go conventions - Improve code readability --- docs/modules/globalfee.md | 5 +- x/globalfee/ante/fee.go | 100 +++++++++++++++++++++------------- x/globalfee/ante/fee_utils.go | 63 +++++++-------------- 3 files changed, 83 insertions(+), 85 deletions(-) diff --git a/docs/modules/globalfee.md b/docs/modules/globalfee.md index 6a69e882d76..11543a7324f 100644 --- a/docs/modules/globalfee.md +++ b/docs/modules/globalfee.md @@ -201,10 +201,9 @@ Note that the required amount of `uatom` in globalfee is overwritten by the amou ### Case 7 -**Setting:** globalfee=[0.1uatom], minimum-gas-prices=0.2uatom,1stake, gas=200000, bypass-min-fee-msg-types = ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"] +**Setting:** globalfee=[0.1uatom], minimum-gas-prices=[0.2uatom, 1stake], gas=200000, bypass-min-fee-msg-types = ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"] -Note that the required amount of `uatom` in globalfee is overwritten by the amount in minimum-gas-prices. -Also, the `1stake` in minimum-gas-prices is ignored. +Note that the required amounts of `uatom` and `stake` in minimum-gas-prices is are ignored. - msg withdraw-all-rewards with paidfee="", `pass` - msg withdraw-all-rewards with paidfee="200000 * 0.05uatom", `pass` diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index e818e7d398b..deab27887ab 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -10,9 +10,10 @@ import ( "github.com/cosmos/gaia/v9/x/globalfee/types" "github.com/cosmos/gaia/v9/x/globalfee" + tmstrings "github.com/tendermint/tendermint/libs/strings" ) -// FeeWithBypassDecorator will check if the transaction's fee is at least as large +// FeeWithBypassDecorator checks if the transaction's fee is at least as large // as the local validator's minimum gasFee (defined in validator config) and global fee, and the fee denom should be in the global fees' denoms. // // If fee is too low, decorator returns error and tx is rejected from mempool. @@ -49,58 +50,43 @@ func NewFeeDecorator(bypassMsgTypes []string, globalfeeSubspace, stakingSubspace } } +// AnteHandle implements the AnteDecorator interface func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { // please note: after parsing feeflag, the zero fees are removed already feeTx, ok := tx.(sdk.FeeTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") } + + // Only check for minimum fees and global fee if the execution mode is CheckTx + if !ctx.IsCheckTx() || simulate { + return next(ctx, tx, simulate) + } + + // sort fee tx's coins feeCoins := feeTx.GetFee().Sort() gas := feeTx.GetGas() msgs := feeTx.GetMsgs() - // Accept zero fee transactions only if both of the following statements are true: - // - the tx contains only message types that can bypass the minimum fee, - // see BypassMinFeeMsgTypes; - // - the total gas limit per message does not exceed MaxTotalBypassMinFeeMsgGasUsage, - // i.e., totalGas <= MaxTotalBypassMinFeeMsgGasUsage - // Otherwise, minimum fees and global fees are checked to prevent spam. - doesNotExceedMaxGasUsage := gas <= mfd.MaxTotalBypassMinFeeMsgGasUsage - allowedToBypassMinFee := mfd.containsOnlyBypassMinFeeMsgs(msgs) && doesNotExceedMaxGasUsage - - var allFees sdk.Coins + // Get required Global Fee and min gas price requiredGlobalFees, err := mfd.getGlobalFee(ctx, feeTx) if err != nil { panic(err) } requiredFees := getMinGasPrice(ctx, feeTx) - // Only check for minimum fees and global fee if the execution mode is CheckTx - if !ctx.IsCheckTx() || simulate { - return next(ctx, tx, simulate) - } - - if !allowedToBypassMinFee { - // Either the transaction contains at least on message of a type - // that cannot bypass the minimum fee or the total gas limit exceeds - // the imposed threshold. As a result, check that the fees are in - // expected denominations and the amounts are greater or equal than - // the expected amounts. - - allFees = CombinedFeeRequirement(requiredGlobalFees, requiredFees) + // Accept zero fee transactions only if both of the following statements are true: + // + // - the tx contains only message types that can bypass the minimum fee, + // see BypassMinFeeMsgTypes; + // - the total gas limit per message does not exceed MaxBypassMinFeeMsgGasUsage, + // i.e., totalGas <= len(msgs) * MaxBypassMinFeeMsgGasUsage + // + // Otherwise, minimum fees and global fees are checked to prevent spam. + doesNotExceedMaxGasUsage := gas <= uint64(len(msgs))*mfd.MaxBypassMinFeeMsgGasUsage + allowedToBypassMinFee := mfd.containsOnlyBypassMinFeeMsgs(msgs) && doesNotExceedMaxGasUsage - // Check that the fees are in expected denominations. Note that a zero fee - // is accepted if the global fee has an entry with a zero amount, e.g., 0uatoms. - if !DenomsSubsetOfIncludingZero(feeCoins, allFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, allFees) - } - // Check that the amounts of the fees are greater or equal than - // the expected amounts, i.e., at least one feeCoin amount must - // be greater or equal to one of the combined required fees. - if !IsAnyGTEIncludingZero(feeCoins, allFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, allFees) - } - } else { + if allowedToBypassMinFee { // Transactions with zero fees are accepted if len(feeCoins) == 0 { return next(ctx, tx, simulate) @@ -112,10 +98,32 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne } } + // Either the transaction contains at least on message of a type + // that cannot bypass the minimum fee or the total gas limit exceeds + // the imposed threshold. As a result, check that the fees are in + // expected denominations and the amounts are greater or equal than + // the expected amounts. + + allFees := CombinedFeeRequirement(requiredGlobalFees, requiredFees) + + // Check that the fees are in expected denominations. Note that a zero fee + // is accepted if the global fee has an entry with a zero amount, e.g., 0uatoms. + if !DenomsSubsetOfIncludingZero(feeCoins, allFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, allFees) + } + // Check that the amounts of the fees are greater or equal than + // the expected amounts, i.e., at least one feeCoin amount must + // be greater or equal to one of the combined required fees. + if !IsAnyGTEIncludingZero(feeCoins, allFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, allFees) + } + return next(ctx, tx, simulate) } -// ParamStoreKeyMinGasPrices type require coins sorted. getGlobalFee will also return sorted coins (might return 0denom if globalMinGasPrice is 0) +// getGlobalFee returns the global fees for a given fee tx's gas (might also returns 0denom if globalMinGasPrice is 0) +// sorted in ascending order. +// Note that ParamStoreKeyMinGasPrices type requires coins sorted. func (mfd FeeDecorator) getGlobalFee(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, error) { var ( globalMinGasPrices sdk.DecCoins @@ -128,6 +136,9 @@ func (mfd FeeDecorator) getGlobalFee(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coin // global fee is empty set, set global fee to 0uatom if len(globalMinGasPrices) == 0 { globalMinGasPrices, err = mfd.DefaultZeroGlobalFee(ctx) + if err != nil { + return sdk.Coins{}, err + } } requiredGlobalFees := make(sdk.Coins, len(globalMinGasPrices)) // Determine the required fees by multiplying each required minimum gas @@ -138,7 +149,7 @@ func (mfd FeeDecorator) getGlobalFee(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coin requiredGlobalFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) } - return requiredGlobalFees.Sort(), err + return requiredGlobalFees.Sort(), nil } func (mfd FeeDecorator) DefaultZeroGlobalFee(ctx sdk.Context) ([]sdk.DecCoin, error) { @@ -158,3 +169,16 @@ func (mfd FeeDecorator) getBondDenom(ctx sdk.Context) string { return bondDenom } + +// containsOnlyBypassMinFeeMsgs returns true if all the given msgs type are listed +// in the BypassMinFeeMsgTypes of the FeeDecorator. +func (mfd FeeDecorator) containsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { + for _, msg := range msgs { + if tmstrings.StringInSlice(sdk.MsgTypeURL(msg), mfd.BypassMinFeeMsgTypes) { + continue + } + return false + } + + return true +} diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 9fa48b01e99..891b5b8d5b0 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -1,13 +1,11 @@ package ante import ( - "math" - sdk "github.com/cosmos/cosmos-sdk/types" - tmstrings "github.com/tendermint/tendermint/libs/strings" ) -// getMinGasPrice will also return sorted coins +// getMinGasPrice returns the validator's minimum gas prices +// for a given fee tx's gas sorted in ascending order func getMinGasPrice(ctx sdk.Context, feeTx sdk.FeeTx) sdk.Coins { minGasPrices := ctx.MinGasPrices() gas := feeTx.GetGas() @@ -27,22 +25,14 @@ func getMinGasPrice(ctx sdk.Context, feeTx sdk.FeeTx) sdk.Coins { return requiredFees.Sort() } -func (mfd FeeDecorator) containsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { - for _, msg := range msgs { - if tmstrings.StringInSlice(sdk.MsgTypeURL(msg), mfd.BypassMinFeeMsgTypes) { - continue - } - return false - } - - return true -} - -// DenomsSubsetOfIncludingZero and IsAnyGTEIncludingZero are similar to DenomsSubsetOf and IsAnyGTE in sdk. Since we allow zero coins in global fee(zero coins means the chain does not want to set a global fee but still want to define the fee's denom) +// DenomsSubsetOfIncludingZero and IsAnyGTEIncludingZero are similar to DenomsSubsetOf and IsAnyGTE in sdk. +// Since we allow zero coins in global fee(zero coins means the chain does not want to set a global fee but still want to define the fee's denom) // -// overwrite DenomsSubsetOfIncludingZero from sdk, to allow zero amt coins in superset. e.g. 1stake is DenomsSubsetOfIncludingZero 0stake. [] is the DenomsSubsetOfIncludingZero of [0stake] but not [1stake]. +// DenomsSubsetOfIncludingZero overwrites DenomsSubsetOf from sdk, to allow zero amt coins in superset. e.g. +// e.g. [1stake] is the DenomsSubsetOfIncludingZero of [0stake] and +// [] is the DenomsSubsetOfIncludingZero of [0stake] but not [1stake]. // DenomsSubsetOfIncludingZero returns true if coins's denoms is subset of coinsB's denoms. -// if coins is empty set, empty set is any sets' subset +// If coins is empty set, empty set is any sets' subset func DenomsSubsetOfIncludingZero(coins, coinsB sdk.Coins) bool { // more denoms in B than in receiver if len(coins) > len(coinsB) { @@ -67,9 +57,9 @@ func DenomsSubsetOfIncludingZero(coins, coinsB sdk.Coins) bool { return true } -// overwrite the IsAnyGTEIncludingZero from sdk to allow zero coins in coins and coinsB. -// IsAnyGTEIncludingZero returns true if coins contain at least one denom that is present at a greater or equal amount in coinsB; it returns false otherwise. -// if CoinsB is emptyset, no coins sets are IsAnyGTEIncludingZero coinsB unless coins is also empty set. +// IsAnyGTEIncludingZero overwrites the IsAnyGTE from sdk to allow zero coins in coins and coinsB. +// IsAnyGTEIncludingZero returns true if coins contain at least one denom that is present at a greater or equal amount in coinsB; +// it returns false otherwise. If CoinsB is emptyset, no coins sets are IsAnyGTEIncludingZero coinsB unless coins is also empty set. // NOTE: IsAnyGTEIncludingZero operates under the invariant that both coin sets are sorted by denoms. // contract !!!! coins must be DenomsSubsetOfIncludingZero of coinsB func IsAnyGTEIncludingZero(coins, coinsB sdk.Coins) bool { @@ -103,13 +93,13 @@ func IsAnyGTEIncludingZero(coins, coinsB sdk.Coins) bool { return false } -// return true if coinsB is empty or contains zero coins, -// CoinsB must be validate coins !!! -func ContainZeroCoins(coinsB sdk.Coins) bool { - if len(coinsB) == 0 { +// ContainZeroCoins returns true if the given coins is empty or contains zero coins, +// Note that the coins denoms must be validated, see sdk.ValidateDenom +func ContainZeroCoins(coins sdk.Coins) bool { + if len(coins) == 0 { return true } - for _, coin := range coinsB { + for _, coin := range coins { if coin.IsZero() { return true } @@ -118,7 +108,9 @@ func ContainZeroCoins(coinsB sdk.Coins) bool { return false } -// CombinedFeeRequirement will combine the global fee and min_gas_price. Both globalFees and minGasPrices must be valid, but CombinedFeeRequirement does not validate them, so it may return 0denom. +// CombinedFeeRequirement returns the global fee and min_gas_price combined and sorted. +// Both globalFees and minGasPrices must be valid, but CombinedFeeRequirement +// does not validate them, so it may return 0denom. func CombinedFeeRequirement(globalFees, minGasPrices sdk.Coins) sdk.Coins { // empty min_gas_price if len(minGasPrices) == 0 { @@ -144,23 +136,6 @@ func CombinedFeeRequirement(globalFees, minGasPrices sdk.Coins) sdk.Coins { return allFees.Sort() } -// getTxPriority returns a naive tx priority based on the amount of the smallest denomination of the fee -// provided in a transaction. -func GetTxPriority(fee sdk.Coins) int64 { - var priority int64 - for _, c := range fee { - p := int64(math.MaxInt64) - if c.Amount.IsInt64() { - p = c.Amount.Int64() - } - if priority == 0 || p < priority { - priority = p - } - } - - return priority -} - // Find replaces the functionality of Coins.Find from SDK v0.46.x func Find(coins sdk.Coins, denom string) (bool, sdk.Coin) { switch len(coins) { From 52efa9db8c03bf737a5a41ad5076f3c6ec2b76ad Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Feb 2023 09:58:58 +0100 Subject: [PATCH 02/42] update params --- x/globalfee/module.go | 6 +++- x/globalfee/types/params.go | 60 ++++++++++++-------------------- x/globalfee/types/params_test.go | 12 +++++++ 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/x/globalfee/module.go b/x/globalfee/module.go index 484bb7778ec..2549e8403ce 100644 --- a/x/globalfee/module.go +++ b/x/globalfee/module.go @@ -58,7 +58,11 @@ func (a AppModuleBasic) RegisterRESTRoutes(context client.Context, router *mux.R } func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - _ = types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } } func (a AppModuleBasic) GetTxCmd() *cobra.Command { diff --git a/x/globalfee/types/params.go b/x/globalfee/types/params.go index 59aa38cc568..305849ea836 100644 --- a/x/globalfee/types/params.go +++ b/x/globalfee/types/params.go @@ -45,53 +45,37 @@ func validateMinimumGasPrices(i interface{}) error { return dec.Validate() } -// Validate checks that the DecCoins are sorted, have nonnegtive amount, with a valid and unique -// denomination (i.e no duplicates). Otherwise, it returns an error. type DecCoins sdk.DecCoins +// Validate checks that the DecCoins are sorted, have nonnegtive amount, with a valid and unique +// denomination (i.e no duplicates). Otherwise, it returns an error. func (coins DecCoins) Validate() error { - switch len(coins) { - case 0: + if len(coins) == 0 { return nil + } - case 1: - // match the denom reg expr - if err := sdk.ValidateDenom(coins[0].Denom); err != nil { - return err - } - if coins[0].IsNegative() { - return fmt.Errorf("coin %s amount is negtive", coins[0]) + lowDenom := "" + seenDenoms := make(map[string]bool) + + for _, coin := range coins { + if seenDenoms[coin.Denom] { + return fmt.Errorf("duplicate denomination %s", coin.Denom) } - return nil - default: - // check single coin case - if err := (DecCoins{coins[0]}).Validate(); err != nil { + if err := sdk.ValidateDenom(coin.Denom); err != nil { return err } - - lowDenom := coins[0].Denom - seenDenoms := make(map[string]bool) - seenDenoms[lowDenom] = true - - for _, coin := range coins[1:] { - if seenDenoms[coin.Denom] { - return fmt.Errorf("duplicate denomination %s", coin.Denom) - } - if err := sdk.ValidateDenom(coin.Denom); err != nil { - return err - } - if coin.Denom <= lowDenom { - return fmt.Errorf("denomination %s is not sorted", coin.Denom) - } - if coin.IsNegative() { - return fmt.Errorf("coin %s amount is negtive", coin.Denom) - } - - // we compare each coin against the last denom - lowDenom = coin.Denom - seenDenoms[coin.Denom] = true + if coin.Denom <= lowDenom { + return fmt.Errorf("denomination %s is not sorted", coin.Denom) + } + if coin.IsNegative() { + return fmt.Errorf("coin %s amount is negative", coin.Amount) } - return nil + // we compare each coin against the last denom + lowDenom = coin.Denom + seenDenoms[coin.Denom] = true } + + return nil + } diff --git a/x/globalfee/types/params_test.go b/x/globalfee/types/params_test.go index b4e67379f33..ba53a7f1f7f 100644 --- a/x/globalfee/types/params_test.go +++ b/x/globalfee/types/params_test.go @@ -46,6 +46,18 @@ func Test_validateParams(t *testing.T) { }, true, }, + "negative amount, fail": { + sdk.DecCoins{ + sdk.DecCoin{Denom: "photon", Amount: sdk.OneDec().Neg()}, + }, + true, + }, + "invalid denom, fail": { + sdk.DecCoins{ + sdk.DecCoin{Denom: "photon!", Amount: sdk.OneDec().Neg()}, + }, + true, + }, } for name, test := range tests { From d47a2af2988bb3b6b924c380b43b05aa84866035 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Thu, 16 Mar 2023 17:14:17 +0100 Subject: [PATCH 03/42] rebase and fix nits --- x/globalfee/ante/fee.go | 54 ++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index deab27887ab..100d72b40c5 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -58,6 +58,13 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") } + // Get required Global Fee and min gas price + requiredGlobalFees, err := mfd.getGlobalFee(ctx, feeTx) + if err != nil { + panic(err) + } + requiredFees := getMinGasPrice(ctx, feeTx) + // Only check for minimum fees and global fee if the execution mode is CheckTx if !ctx.IsCheckTx() || simulate { return next(ctx, tx, simulate) @@ -68,13 +75,6 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne gas := feeTx.GetGas() msgs := feeTx.GetMsgs() - // Get required Global Fee and min gas price - requiredGlobalFees, err := mfd.getGlobalFee(ctx, feeTx) - if err != nil { - panic(err) - } - requiredFees := getMinGasPrice(ctx, feeTx) - // Accept zero fee transactions only if both of the following statements are true: // // - the tx contains only message types that can bypass the minimum fee, @@ -96,26 +96,26 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne if !DenomsSubsetOfIncludingZero(feeCoins, requiredGlobalFees) { return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fees denom is wrong; got: %s required: %s", feeCoins, requiredGlobalFees) } - } - - // Either the transaction contains at least on message of a type - // that cannot bypass the minimum fee or the total gas limit exceeds - // the imposed threshold. As a result, check that the fees are in - // expected denominations and the amounts are greater or equal than - // the expected amounts. - - allFees := CombinedFeeRequirement(requiredGlobalFees, requiredFees) - - // Check that the fees are in expected denominations. Note that a zero fee - // is accepted if the global fee has an entry with a zero amount, e.g., 0uatoms. - if !DenomsSubsetOfIncludingZero(feeCoins, allFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, allFees) - } - // Check that the amounts of the fees are greater or equal than - // the expected amounts, i.e., at least one feeCoin amount must - // be greater or equal to one of the combined required fees. - if !IsAnyGTEIncludingZero(feeCoins, allFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, allFees) + } else { + // Either the transaction contains at least on message of a type + // that cannot bypass the minimum fee or the total gas limit exceeds + // the imposed threshold. As a result, check that the fees are in + // expected denominations and the amounts are greater or equal than + // the expected amounts. + + combinedFees := CombinedFeeRequirement(requiredGlobalFees, requiredFees) + + // Check that the fees are in expected denominations. Note that a zero fee + // is accepted if the global fee has an entry with a zero amount, e.g., 0uatoms. + if !DenomsSubsetOfIncludingZero(feeCoins, combinedFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFees) + } + // Check that the amounts of the fees are greater or equal than + // the expected amounts, i.e., at least one feeCoin amount must + // be greater or equal to one of the combined required fees. + if !IsAnyGTEIncludingZero(feeCoins, combinedFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFees) + } } return next(ctx, tx, simulate) From 2d8257627dca8ec4901f3038d49975fe69b3d342 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Fri, 17 Mar 2023 11:37:55 +0100 Subject: [PATCH 04/42] add GetMinGasPrice UT --- x/globalfee/ante/antetest/fee_test.go | 57 ++++++++++++++++++- x/globalfee/ante/fee.go | 25 +++++++- x/globalfee/ante/fee_utils.go | 21 ------- .../ante/{antetest => }/fee_utils_test.go | 37 +++++++++--- 4 files changed, 108 insertions(+), 32 deletions(-) rename x/globalfee/ante/{antetest => }/fee_utils_test.go (92%) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 2cb1aeffdca..f5ee458cfe5 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/suite" gaiaapp "github.com/cosmos/gaia/v9/app" + "github.com/cosmos/gaia/v9/x/globalfee/ante" gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" ) @@ -636,6 +637,58 @@ func newTestGasLimit() uint64 { return 200000 } -func newTestMaxTotalBypassMinFeeMsgGasUsage() uint64 { - return 1000000 +func (s *IntegrationTestSuite) TestGetMinGasPrice() { + // set globalfees and min gas price + + expCoins := sdk.Coins{ + sdk.NewCoin("photon", sdk.NewInt(2000)), + sdk.NewCoin("uatom", sdk.NewInt(3000)), + } + + testCases := []struct { + name string + minGasPrice []sdk.DecCoin + feeTxGasLimit uint64 + expCoins sdk.Coins + }{{ + "empty min gas price should return zero coins", + []sdk.DecCoin{}, + uint64(1000), + sdk.Coins{}, + }, { + "unsorted min gas price", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + }, + uint64(1000), + expCoins, + }, { + "sorted min gas price", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + }, + uint64(1000), + expCoins, + }, { + "sorted min gas price", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + }, + uint64(1000), + expCoins, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, &globfeetypes.Params{}) + + fees := ante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) + // s.Require().True(sort.IsSorted(fees)) + s.Require().True(tc.expCoins.Sort().IsEqual(fees)) + }) + } } diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 100d72b40c5..5209b5ccf88 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -63,7 +63,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne if err != nil { panic(err) } - requiredFees := getMinGasPrice(ctx, feeTx) + requiredFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) // Only check for minimum fees and global fee if the execution mode is CheckTx if !ctx.IsCheckTx() || simulate { @@ -97,7 +97,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fees denom is wrong; got: %s required: %s", feeCoins, requiredGlobalFees) } } else { - // Either the transaction contains at least on message of a type + // Either the transaction contains at least one message of a type // that cannot bypass the minimum fee or the total gas limit exceeds // the imposed threshold. As a result, check that the fees are in // expected denominations and the amounts are greater or equal than @@ -182,3 +182,24 @@ func (mfd FeeDecorator) containsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { return true } + +// GetMinGasPrice returns the validator's minimum gas prices +// fees given a gas limit +func GetMinGasPrice(ctx sdk.Context, gasLimit int64) sdk.Coins { + minGasPrices := ctx.MinGasPrices() + // special case: if minGasPrices=[], requiredFees=[] + requiredFees := make(sdk.Coins, len(minGasPrices)) + // if not all coins are zero, check fee with min_gas_price + if !minGasPrices.IsZero() { + // Determine the required fees by multiplying each required minimum gas + // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). + glDec := sdk.NewDec(gasLimit) + + for i, gp := range minGasPrices { + fee := gp.Amount.Mul(glDec) + requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) + } + } + + return requiredFees.Sort() +} diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 891b5b8d5b0..2b4f54115a7 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -4,27 +4,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// getMinGasPrice returns the validator's minimum gas prices -// for a given fee tx's gas sorted in ascending order -func getMinGasPrice(ctx sdk.Context, feeTx sdk.FeeTx) sdk.Coins { - minGasPrices := ctx.MinGasPrices() - gas := feeTx.GetGas() - // special case: if minGasPrices=[], requiredFees=[] - requiredFees := make(sdk.Coins, len(minGasPrices)) - // if not all coins are zero, check fee with min_gas_price - if !minGasPrices.IsZero() { - // 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()) - } - } - - return requiredFees.Sort() -} - // DenomsSubsetOfIncludingZero and IsAnyGTEIncludingZero are similar to DenomsSubsetOf and IsAnyGTE in sdk. // Since we allow zero coins in global fee(zero coins means the chain does not want to set a global fee but still want to define the fee's denom) // diff --git a/x/globalfee/ante/antetest/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go similarity index 92% rename from x/globalfee/ante/antetest/fee_utils_test.go rename to x/globalfee/ante/fee_utils_test.go index 86dae805cf7..b1a62386885 100644 --- a/x/globalfee/ante/antetest/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -1,12 +1,11 @@ -package antetest +package ante import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/gaia/v9/x/globalfee/ante/antetest" "github.com/stretchr/testify/suite" - - "github.com/cosmos/gaia/v9/x/globalfee/ante" ) type feeUtilsTestSuite struct { @@ -57,7 +56,7 @@ func (s *feeUtilsTestSuite) TestContainZeroCoins() { } for _, test := range tests { - ok := ante.ContainZeroCoins(test.c) + ok := ContainZeroCoins(test.c) s.Require().Equal(test.ok, ok) } } @@ -162,7 +161,7 @@ func (s *feeUtilsTestSuite) TestCombinedFeeRequirement() { for name, test := range tests { s.Run(name, func() { - allFees := ante.CombinedFeeRequirement(test.cGlobal, test.c) + allFees := CombinedFeeRequirement(test.cGlobal, test.c) s.Require().Equal(test.combined, allFees) }) } @@ -267,7 +266,7 @@ func (s *feeUtilsTestSuite) TestDenomsSubsetOfIncludingZero() { for name, test := range tests { s.Run(name, func() { - subset := ante.DenomsSubsetOfIncludingZero(test.set, test.superset) + subset := DenomsSubsetOfIncludingZero(test.set, test.superset) s.Require().Equal(test.subset, subset) }) } @@ -408,8 +407,32 @@ func (s *feeUtilsTestSuite) TestIsAnyGTEIncludingZero() { for name, test := range tests { s.Run(name, func() { - gte := ante.IsAnyGTEIncludingZero(test.c2, test.c1) + gte := IsAnyGTEIncludingZero(test.c2, test.c1) s.Require().Equal(test.gte, gte) }) } } + +func (s *antetest.IntegrationTestSuite) TestGetMinGasPrice(t *testing.T) { + // app := gaiahelpers.Setup(t) + // ctx := app.BaseApp.NewContext(false, tmproto.Header{ + // ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), + // Height: 1, + // }) + + // testCases := []struct { + // minGasPrice []sdk.DecCoin + // feeTxGasLimit uint64 + // expCoins []sdk.Coin + // }{{ + // minGasPrice: []sdk.DecCoin{sdk.NewDecCoinFromDec("uatom", sdk.NewDec(1))}, + // feeTxGasLimit: uint64(1000), + // expCoins: []sdk.Coin{sdk.NewCoin("uatom", sdk.NewInt(1))}, + // }, + // } + + // for _, tc := range testCases { + // ctx.Set + // GetMinGasPrice(ctx, int64(tc.feeTxGasLimit)) + // } +} From 90be614d0d886acacb4895bccf20ed3ff7df3ebc Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Fri, 17 Mar 2023 12:01:45 +0100 Subject: [PATCH 05/42] remove unused feetestsuite --- x/globalfee/ante/antetest/fee_test.go | 3 +- x/globalfee/ante/fee_utils_test.go | 59 ++++++--------------------- 2 files changed, 14 insertions(+), 48 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index f5ee458cfe5..094c7e7a366 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -12,7 +12,6 @@ import ( "github.com/stretchr/testify/suite" gaiaapp "github.com/cosmos/gaia/v9/app" - "github.com/cosmos/gaia/v9/x/globalfee/ante" gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" ) @@ -686,7 +685,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { s.Run(tc.name, func() { s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, &globfeetypes.Params{}) - fees := ante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) + fees := gaiafeeante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) // s.Require().True(sort.IsSorted(fees)) s.Require().True(tc.expCoins.Sort().IsEqual(fees)) }) diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index b1a62386885..d503591477f 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -4,19 +4,10 @@ import ( "testing" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/gaia/v9/x/globalfee/ante/antetest" - "github.com/stretchr/testify/suite" + "github.com/stretchr/testify/require" ) -type feeUtilsTestSuite struct { - suite.Suite -} - -func TestFeeUtilsTestSuite(t *testing.T) { - suite.Run(t, new(feeUtilsTestSuite)) -} - -func (s *feeUtilsTestSuite) TestContainZeroCoins() { +func TestContainZeroCoins(t *testing.T) { zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) zeroCoin2 := sdk.NewCoin("stake", sdk.ZeroInt()) coin1 := sdk.NewCoin("photon", sdk.NewInt(1)) @@ -56,12 +47,12 @@ func (s *feeUtilsTestSuite) TestContainZeroCoins() { } for _, test := range tests { - ok := ContainZeroCoins(test.c) - s.Require().Equal(test.ok, ok) + _ = ContainZeroCoins(test.c) + // require().Equal(test.ok, ok) } } -func (s *feeUtilsTestSuite) TestCombinedFeeRequirement() { +func TestCombinedFeeRequirement(t *testing.T) { zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) zeroCoin2 := sdk.NewCoin("stake", sdk.ZeroInt()) zeroCoin3 := sdk.NewCoin("quark", sdk.ZeroInt()) @@ -160,14 +151,14 @@ func (s *feeUtilsTestSuite) TestCombinedFeeRequirement() { } for name, test := range tests { - s.Run(name, func() { + t.Run(name, func(t *testing.T) { allFees := CombinedFeeRequirement(test.cGlobal, test.c) - s.Require().Equal(test.combined, allFees) + require.Equal(t, test.combined, allFees) }) } } -func (s *feeUtilsTestSuite) TestDenomsSubsetOfIncludingZero() { +func TestDenomsSubsetOfIncludingZero(t *testing.T) { emptyCoins := sdk.Coins{} zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) @@ -265,14 +256,14 @@ func (s *feeUtilsTestSuite) TestDenomsSubsetOfIncludingZero() { } for name, test := range tests { - s.Run(name, func() { + t.Run(name, func(t *testing.T) { subset := DenomsSubsetOfIncludingZero(test.set, test.superset) - s.Require().Equal(test.subset, subset) + require.Equal(t, test.subset, subset) }) } } -func (s *feeUtilsTestSuite) TestIsAnyGTEIncludingZero() { +func TestIsAnyGTEIncludingZero(t *testing.T) { emptyCoins := sdk.Coins{} zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) @@ -406,33 +397,9 @@ func (s *feeUtilsTestSuite) TestIsAnyGTEIncludingZero() { } for name, test := range tests { - s.Run(name, func() { + t.Run(name, func(t *testing.T) { gte := IsAnyGTEIncludingZero(test.c2, test.c1) - s.Require().Equal(test.gte, gte) + require.Equal(t, test.gte, gte) }) } } - -func (s *antetest.IntegrationTestSuite) TestGetMinGasPrice(t *testing.T) { - // app := gaiahelpers.Setup(t) - // ctx := app.BaseApp.NewContext(false, tmproto.Header{ - // ChainID: fmt.Sprintf("test-chain-%s", tmrand.Str(4)), - // Height: 1, - // }) - - // testCases := []struct { - // minGasPrice []sdk.DecCoin - // feeTxGasLimit uint64 - // expCoins []sdk.Coin - // }{{ - // minGasPrice: []sdk.DecCoin{sdk.NewDecCoinFromDec("uatom", sdk.NewDec(1))}, - // feeTxGasLimit: uint64(1000), - // expCoins: []sdk.Coin{sdk.NewCoin("uatom", sdk.NewInt(1))}, - // }, - // } - - // for _, tc := range testCases { - // ctx.Set - // GetMinGasPrice(ctx, int64(tc.feeTxGasLimit)) - // } -} From c29fbfe250c83a14bc0a916634f7deb5d96baa66 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Mon, 20 Mar 2023 10:39:16 +0100 Subject: [PATCH 06/42] rebase --- x/globalfee/ante/antetest/fee_test.go | 260 ++++++++++++++++---------- x/globalfee/ante/fee.go | 12 +- x/globalfee/types/params.go | 1 - 3 files changed, 169 insertions(+), 104 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 094c7e7a366..a5b20f56cec 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -1,6 +1,7 @@ package antetest import ( + "fmt" "testing" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -16,6 +17,12 @@ import ( globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" ) +var ( + testBondDenom = "uatom" + testTotalMaxGasLimit = uint64(200_000) + newTestTotalMaxGasLimit = uint64(1_000_000) +) + func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) } @@ -26,19 +33,18 @@ func (s *IntegrationTestSuite) TestGetDefaultGlobalFees() { // set staking params stakingParam := stakingtypes.DefaultParams() - bondDenom := "uatom" - stakingParam.BondDenom = bondDenom + stakingParam.BondDenom = testBondDenom stakingSubspace := s.SetupTestStakingSubspace(stakingParam) // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, newTestGasLimit()) + mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, newTestTotalMaxGasLimit) defaultGlobalFees, err := mfd.DefaultZeroGlobalFee(s.ctx) s.Require().NoError(err) s.Require().Greater(len(defaultGlobalFees), 0) - if defaultGlobalFees[0].Denom != bondDenom { - s.T().Fatalf("bond denom: %s, default global fee denom: %s", bondDenom, defaultGlobalFees[0].Denom) + if defaultGlobalFees[0].Denom != testBondDenom { + s.T().Fatalf("bond denom: %s, default global fee denom: %s", testBondDenom, defaultGlobalFees[0].Denom) } } @@ -46,8 +52,6 @@ func (s *IntegrationTestSuite) TestGetDefaultGlobalFees() { // please note even globalfee=0, min_gas_price=0, we do not let fee=0random_denom pass // paid fees are already sanitized by removing zero coins(through feeFlag parsing), so use sdk.NewCoins() to create it. func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { - // setup test - s.SetupTest() s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() priv1, _, addr1 := testdata.KeyTestPubAddr() privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} @@ -110,12 +114,11 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { "empty min_gas_price, nonempty global fee, fee higher/equal than global_fee": { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParamsHigh, - // sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()) - gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testdata.NewTestGasLimit(), - txMsg: testdata.NewTestMsg(addr1), - txCheck: true, - expErr: false, + gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), + gasLimit: testdata.NewTestGasLimit(), + txMsg: testdata.NewTestMsg(addr1), + txCheck: true, + expErr: false, }, "empty min_gas_price, nonempty global fee, fee lower than global_fee": { minGasPrice: minGasPriceEmpty, @@ -216,7 +219,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsEmpty, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -225,7 +228,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsEmpty, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -234,7 +237,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsEmpty, gasPrice: sdk.NewCoins(sdk.NewCoin("quark", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -244,7 +247,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -253,7 +256,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -262,7 +265,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -271,7 +274,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -281,7 +284,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -291,7 +294,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsHigh, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -300,7 +303,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsHigh, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -311,7 +314,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("photon", lowFeeAmt), sdk.NewCoin("quark", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -320,7 +323,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsHigh, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -329,7 +332,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -339,7 +342,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -348,7 +351,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -357,7 +360,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -367,7 +370,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsNewDenom, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -376,7 +379,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsNewDenom, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -387,7 +390,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("uatom", highFeeAmt), sdk.NewCoin("quark", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -397,7 +400,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt), sdk.NewCoin("quark", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -411,7 +414,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsContain0, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", lowFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -422,7 +425,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("photon", lowFeeAmt), sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -431,7 +434,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsContain0, gasPrice: sdk.Coins{}, - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -442,7 +445,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("photon", lowFeeAmt), sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -454,7 +457,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { sdk.NewCoin("photon", sdk.ZeroInt()), sdk.NewCoin("uatom", sdk.ZeroInt()), ), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -463,7 +466,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsContain0, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -472,7 +475,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -482,7 +485,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: newTestTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 1, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -492,7 +495,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: newTestTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -502,7 +505,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: 2 * newTestMaxTotalBypassMinFeeMsgGasUsage(), + gasLimit: 2 * newTestTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -512,7 +515,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestMaxTotalBypassMinFeeMsgGasUsage(), + gasLimit: newTestTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 3, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -522,7 +525,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -532,7 +535,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -542,7 +545,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -552,7 +555,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.Coins{}, - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -562,7 +565,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -571,7 +574,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.Coins{}, - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -580,7 +583,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -589,7 +592,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: false, expErr: false, @@ -598,31 +601,35 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("quark", sdk.ZeroInt())), - gasLimit: newTestGasLimit(), + gasLimit: testTotalMaxGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: false, expErr: false, }, } - for name, testCase := range testCases { + for name, tc := range testCases { s.Run(name, func() { + fmt.Println(name) + fmt.Println("gas price", tc.gasPrice) + fmt.Println("min gas price", tc.minGasPrice) + fmt.Println("global fee", tc.globalFeeParams.MinimumGasPrices.String()) // set globalfees and min gas price - globalfeeSubspace := s.SetupTestGlobalFeeStoreAndMinGasPrice(testCase.minGasPrice, testCase.globalFeeParams) + globalfeeSubspace := s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, tc.globalFeeParams) stakingParam := stakingtypes.DefaultParams() - stakingParam.BondDenom = "uatom" + stakingParam.BondDenom = testBondDenom stakingSubspace := s.SetupTestStakingSubspace(stakingParam) // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, newTestMaxTotalBypassMinFeeMsgGasUsage()) + mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, newTestTotalMaxGasLimit) antehandler := sdk.ChainAnteDecorators(mfd) - s.Require().NoError(s.txBuilder.SetMsgs(testCase.txMsg)) - s.txBuilder.SetFeeAmount(testCase.gasPrice) - s.txBuilder.SetGasLimit(testCase.gasLimit) + s.Require().NoError(s.txBuilder.SetMsgs(tc.txMsg)) + s.txBuilder.SetFeeAmount(tc.gasPrice) + s.txBuilder.SetGasLimit(tc.gasLimit) tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID()) s.Require().NoError(err) - s.ctx = s.ctx.WithIsCheckTx(testCase.txCheck) + s.ctx = s.ctx.WithIsCheckTx(tc.txCheck) _, err = antehandler(s.ctx, tx, false) - if !testCase.expErr { + if !tc.expErr { s.Require().NoError(err) } else { s.Require().Error(err) @@ -631,11 +638,6 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { } } -// helpers -func newTestGasLimit() uint64 { - return 200000 -} - func (s *IntegrationTestSuite) TestGetMinGasPrice() { // set globalfees and min gas price @@ -649,36 +651,37 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { minGasPrice []sdk.DecCoin feeTxGasLimit uint64 expCoins sdk.Coins - }{{ - "empty min gas price should return zero coins", - []sdk.DecCoin{}, - uint64(1000), - sdk.Coins{}, - }, { - "unsorted min gas price", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), - sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), - }, - uint64(1000), - expCoins, - }, { - "sorted min gas price", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), - }, - uint64(1000), - expCoins, - }, { - "sorted min gas price", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), - }, - uint64(1000), - expCoins, - }, + }{ + { + "empty min gas price should return zero coins", + []sdk.DecCoin{}, + uint64(1000), + sdk.Coins{}, + }, { + "unsorted min gas price", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + }, + uint64(1000), + expCoins, + }, { + "sorted min gas price", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + }, + uint64(1000), + expCoins, + }, { + "sorted min gas price", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), + }, + uint64(1000), + expCoins, + }, } for _, tc := range testCases { @@ -691,3 +694,66 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { }) } } + +func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { + // set globalfees and min gas price + globalfeeSubspace := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) + stakingParam := stakingtypes.DefaultParams() + stakingParam.BondDenom = testBondDenom + stakingSubspace := s.SetupTestStakingSubspace(stakingParam) + // setup antehandler + mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testTotalMaxGasLimit) + + sdk.ChainAnteDecorators(mfd) + + testCases := []struct { + name string + msgs []sdk.Msg + expPass bool + }{ + { + "expect empty msgs to pass", + []sdk.Msg{}, + true, + }, + { + "expect a single bypass min fee msg to pass", + []sdk.Msg{ + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), + }, + true, + }, + { + "expect bypass min fee msgs to pass", + []sdk.Msg{ + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), + }, + true, + }, + { + "expect mixed msg type to not pass", + []sdk.Msg{ + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), + }, + false, + }, + { + "expect non bypass fee msgs to not pass", + []sdk.Msg{ + ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), + stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), + }, + false, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + res := mfd.ContainsOnlyBypassMinFeeMsgs(tc.msgs) + s.Require().True(tc.expPass == res) + }) + } +} diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 5209b5ccf88..02b6057939a 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -79,12 +79,12 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // // - the tx contains only message types that can bypass the minimum fee, // see BypassMinFeeMsgTypes; - // - the total gas limit per message does not exceed MaxBypassMinFeeMsgGasUsage, - // i.e., totalGas <= len(msgs) * MaxBypassMinFeeMsgGasUsage + // - the total gas limit per message does not exceed MaxTotalBypassMinFeeMsgGasUsage, + // i.e., totalGas <= MaxBypassMinFeeMsgGasUsage // // Otherwise, minimum fees and global fees are checked to prevent spam. - doesNotExceedMaxGasUsage := gas <= uint64(len(msgs))*mfd.MaxBypassMinFeeMsgGasUsage - allowedToBypassMinFee := mfd.containsOnlyBypassMinFeeMsgs(msgs) && doesNotExceedMaxGasUsage + doesNotExceedMaxGasUsage := gas <= mfd.MaxTotalBypassMinFeeMsgGasUsage + allowedToBypassMinFee := mfd.ContainsOnlyBypassMinFeeMsgs(msgs) && doesNotExceedMaxGasUsage if allowedToBypassMinFee { // Transactions with zero fees are accepted @@ -170,9 +170,9 @@ func (mfd FeeDecorator) getBondDenom(ctx sdk.Context) string { return bondDenom } -// containsOnlyBypassMinFeeMsgs returns true if all the given msgs type are listed +// ContainsOnlyBypassMinFeeMsgs returns true if all the given msgs type are listed // in the BypassMinFeeMsgTypes of the FeeDecorator. -func (mfd FeeDecorator) containsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { +func (mfd FeeDecorator) ContainsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { for _, msg := range msgs { if tmstrings.StringInSlice(sdk.MsgTypeURL(msg), mfd.BypassMinFeeMsgTypes) { continue diff --git a/x/globalfee/types/params.go b/x/globalfee/types/params.go index 305849ea836..c18e403e50d 100644 --- a/x/globalfee/types/params.go +++ b/x/globalfee/types/params.go @@ -77,5 +77,4 @@ func (coins DecCoins) Validate() error { } return nil - } From f41c3a3359f075b0eff1905a8a93c050b87f2381 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Mon, 20 Mar 2023 11:27:10 +0100 Subject: [PATCH 07/42] update doc --- docs/modules/globalfee.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/modules/globalfee.md b/docs/modules/globalfee.md index 11543a7324f..ea72e7f6aa2 100644 --- a/docs/modules/globalfee.md +++ b/docs/modules/globalfee.md @@ -203,7 +203,8 @@ Note that the required amount of `uatom` in globalfee is overwritten by the amou **Setting:** globalfee=[0.1uatom], minimum-gas-prices=[0.2uatom, 1stake], gas=200000, bypass-min-fee-msg-types = ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"] -Note that the required amounts of `uatom` and `stake` in minimum-gas-prices is are ignored. +Note that the required amount of `uatom` in globalfee is overwritten by the amount in minimum-gas-prices. +Also, the `1stake` in minimum-gas-prices is ignored. - msg withdraw-all-rewards with paidfee="", `pass` - msg withdraw-all-rewards with paidfee="200000 * 0.05uatom", `pass` From b086f143c10a0dedaf60580c18330a657fa9d84b Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Mon, 20 Mar 2023 11:40:12 +0100 Subject: [PATCH 08/42] nits --- x/globalfee/ante/antetest/fee_test.go | 9 ++++----- x/globalfee/ante/fee_utils.go | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index a5b20f56cec..a74bc327674 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -717,7 +717,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { true, }, { - "expect a single bypass min fee msg to pass", + "expect ibc msg to pass", []sdk.Msg{ ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), @@ -725,7 +725,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { true, }, { - "expect bypass min fee msgs to pass", + "expect ibc msgs to pass", []sdk.Msg{ ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), @@ -733,7 +733,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { true, }, { - "expect mixed msg type to not pass", + "msgs contains non-ibc msg - should not pass", []sdk.Msg{ ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), @@ -741,9 +741,8 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { false, }, { - "expect non bypass fee msgs to not pass", + "non-ibc msgs - should not pass", []sdk.Msg{ - ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), }, false, diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 2b4f54115a7..737e6b17530 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -72,7 +72,7 @@ func IsAnyGTEIncludingZero(coins, coinsB sdk.Coins) bool { return false } -// ContainZeroCoins returns true if the given coins is empty or contains zero coins, +// ContainZeroCoins returns true if the given coins are empty or contain zero coins, // Note that the coins denoms must be validated, see sdk.ValidateDenom func ContainZeroCoins(coins sdk.Coins) bool { if len(coins) == 0 { From 2ff680a57b8619e16f573993e67dbc7c8a3cc54d Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 10:29:12 +0100 Subject: [PATCH 09/42] nits --- ante/ante.go | 15 ++--- x/globalfee/ante/antetest/fee_test.go | 97 +++++++++++++-------------- x/globalfee/ante/fee_utils_test.go | 4 +- 3 files changed, 55 insertions(+), 61 deletions(-) diff --git a/ante/ante.go b/ante/ante.go index f2b06bd8ee0..16c82eb6dd4 100644 --- a/ante/ante.go +++ b/ante/ante.go @@ -13,6 +13,13 @@ import ( gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" ) +// maxTotalBypassMinFeeMsgGasUsage is the allowed maximum gas usage +// for all the bypass msgs in a transactions. +// A transaction that contains only bypass message types and the gas usage does not +// exceed maxTotalBypassMinFeeMsgGasUsage can be accepted with a zero fee. +// For details, see gaiafeeante.NewFeeDecorator() +var maxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000 + // HandlerOptions extend the SDK's AnteHandler options by requiring the IBC // channel keeper. type HandlerOptions struct { @@ -53,13 +60,6 @@ func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) { sigGasConsumer = ante.DefaultSigVerificationGasConsumer } - // maxTotalBypassMinFeeMsgGasUsage is the allowed maximum gas usage - // for all the bypass msgs in a transactions. - // A transaction that contains only bypass message types and the gas usage does not - // exceed maxTotalBypassMinFeeMsgGasUsage can be accepted with a zero fee. - // For details, see gaiafeeante.NewFeeDecorator() - var maxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000 - anteDecorators := []sdk.AnteDecorator{ ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first ante.NewRejectExtensionOptionsDecorator(), @@ -69,7 +69,6 @@ func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) { ante.NewConsumeGasForTxSizeDecorator(opts.AccountKeeper), NewGovPreventSpamDecorator(opts.Codec, opts.GovKeeper), gaiafeeante.NewFeeDecorator(opts.BypassMinFeeMsgTypes, opts.GlobalFeeSubspace, opts.StakingSubspace, maxTotalBypassMinFeeMsgGasUsage), - ante.NewDeductFeeDecorator(opts.AccountKeeper, opts.BankKeeper, opts.FeegrantKeeper), ante.NewSetPubKeyDecorator(opts.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewValidateSigCountDecorator(opts.AccountKeeper), diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index a74bc327674..19a2c6716ef 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -1,7 +1,6 @@ package antetest import ( - "fmt" "testing" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -18,9 +17,9 @@ import ( ) var ( - testBondDenom = "uatom" - testTotalMaxGasLimit = uint64(200_000) - newTestTotalMaxGasLimit = uint64(1_000_000) + testBondDenom = "uatom" + testGasLimit uint64 = 200_000 + testMaxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000 ) func TestIntegrationTestSuite(t *testing.T) { @@ -37,7 +36,7 @@ func (s *IntegrationTestSuite) TestGetDefaultGlobalFees() { stakingSubspace := s.SetupTestStakingSubspace(stakingParam) // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, newTestTotalMaxGasLimit) + mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testMaxTotalBypassMinFeeMsgGasUsage) defaultGlobalFees, err := mfd.DefaultZeroGlobalFee(s.ctx) s.Require().NoError(err) @@ -219,7 +218,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsEmpty, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -228,7 +227,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsEmpty, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -237,7 +236,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsEmpty, gasPrice: sdk.NewCoins(sdk.NewCoin("quark", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -247,7 +246,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -256,7 +255,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -265,7 +264,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -274,7 +273,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPriceEmpty, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -284,7 +283,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -294,7 +293,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsHigh, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -303,7 +302,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsHigh, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -314,7 +313,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("photon", lowFeeAmt), sdk.NewCoin("quark", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -323,7 +322,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsHigh, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -332,7 +331,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -342,7 +341,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", lowFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -351,7 +350,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", medFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -360,7 +359,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParams0, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -370,7 +369,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsNewDenom, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -379,7 +378,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsNewDenom, gasPrice: sdk.NewCoins(sdk.NewCoin("stake", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -390,7 +389,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("uatom", highFeeAmt), sdk.NewCoin("quark", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -400,7 +399,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt), sdk.NewCoin("quark", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -414,7 +413,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsContain0, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", lowFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -425,7 +424,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("photon", lowFeeAmt), sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -434,7 +433,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsContain0, gasPrice: sdk.Coins{}, - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -445,7 +444,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { gasPrice: sdk.NewCoins( sdk.NewCoin("photon", lowFeeAmt), sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -457,7 +456,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { sdk.NewCoin("photon", sdk.ZeroInt()), sdk.NewCoin("uatom", sdk.ZeroInt()), ), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -466,7 +465,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice0, globalFeeParams: globalfeeParamsContain0, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -475,7 +474,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -485,7 +484,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 1, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -495,7 +494,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -505,7 +504,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: 2 * newTestTotalMaxGasLimit, + gasLimit: 2 * testGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -515,7 +514,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: newTestTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 3, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -525,7 +524,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -535,7 +534,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -545,7 +544,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -555,7 +554,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.Coins{}, - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: ibcchanneltypes.NewMsgRecvPacket( ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -565,7 +564,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: false, @@ -574,7 +573,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.Coins{}, - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -583,7 +582,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("photon", highFeeAmt)), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: true, expErr: true, @@ -592,7 +591,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: false, expErr: false, @@ -601,7 +600,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("quark", sdk.ZeroInt())), - gasLimit: testTotalMaxGasLimit, + gasLimit: testGasLimit, txMsg: testdata.NewTestMsg(addr1), txCheck: false, expErr: false, @@ -609,17 +608,13 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { } for name, tc := range testCases { s.Run(name, func() { - fmt.Println(name) - fmt.Println("gas price", tc.gasPrice) - fmt.Println("min gas price", tc.minGasPrice) - fmt.Println("global fee", tc.globalFeeParams.MinimumGasPrices.String()) // set globalfees and min gas price globalfeeSubspace := s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, tc.globalFeeParams) stakingParam := stakingtypes.DefaultParams() stakingParam.BondDenom = testBondDenom stakingSubspace := s.SetupTestStakingSubspace(stakingParam) // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, newTestTotalMaxGasLimit) + mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testGasLimit) antehandler := sdk.ChainAnteDecorators(mfd) s.Require().NoError(s.txBuilder.SetMsgs(tc.txMsg)) s.txBuilder.SetFeeAmount(tc.gasPrice) @@ -702,7 +697,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { stakingParam.BondDenom = testBondDenom stakingSubspace := s.SetupTestStakingSubspace(stakingParam) // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testTotalMaxGasLimit) + mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testMaxTotalBypassMinFeeMsgGasUsage) sdk.ChainAnteDecorators(mfd) diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index d503591477f..b3af0e34e3d 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -47,8 +47,8 @@ func TestContainZeroCoins(t *testing.T) { } for _, test := range tests { - _ = ContainZeroCoins(test.c) - // require().Equal(test.ok, ok) + ok := ContainZeroCoins(test.c) + require.Equal(t, test.ok, ok) } } From 4c26632475dfb8ff7e951ddf981afbefa34f04c9 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 11:03:01 +0100 Subject: [PATCH 10/42] refactor fee tests setup --- x/globalfee/ante/antetest/fee_test.go | 43 +++++---------------- x/globalfee/ante/antetest/fee_test_setup.go | 24 ++++++++++-- 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 19a2c6716ef..7b9c352ceca 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -11,16 +11,11 @@ import ( ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types" "github.com/stretchr/testify/suite" - gaiaapp "github.com/cosmos/gaia/v9/app" gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" ) -var ( - testBondDenom = "uatom" - testGasLimit uint64 = 200_000 - testMaxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000 -) +var testGasLimit uint64 = 200_000 func TestIntegrationTestSuite(t *testing.T) { suite.Run(t, new(IntegrationTestSuite)) @@ -28,17 +23,9 @@ func TestIntegrationTestSuite(t *testing.T) { func (s *IntegrationTestSuite) TestGetDefaultGlobalFees() { // set globalfees and min gas price - globalfeeSubspace := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) - - // set staking params - stakingParam := stakingtypes.DefaultParams() - stakingParam.BondDenom = testBondDenom - stakingSubspace := s.SetupTestStakingSubspace(stakingParam) - - // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testMaxTotalBypassMinFeeMsgGasUsage) + feeDecorator, _ := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) - defaultGlobalFees, err := mfd.DefaultZeroGlobalFee(s.ctx) + defaultGlobalFees, err := feeDecorator.DefaultZeroGlobalFee(s.ctx) s.Require().NoError(err) s.Require().Greater(len(defaultGlobalFees), 0) @@ -504,7 +491,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { minGasPrice: minGasPrice, globalFeeParams: globalfeeParamsLow, gasPrice: sdk.NewCoins(sdk.NewCoin("uatom", sdk.ZeroInt())), - gasLimit: 2 * testGasLimit, + gasLimit: 2 * testMaxTotalBypassMinFeeMsgGasUsage, txMsg: ibcchanneltypes.NewMsgTimeout( ibcchanneltypes.Packet{}, 2, nil, ibcclienttypes.Height{}, ""), txCheck: true, @@ -609,13 +596,10 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { for name, tc := range testCases { s.Run(name, func() { // set globalfees and min gas price - globalfeeSubspace := s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, tc.globalFeeParams) - stakingParam := stakingtypes.DefaultParams() - stakingParam.BondDenom = testBondDenom - stakingSubspace := s.SetupTestStakingSubspace(stakingParam) - // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testGasLimit) - antehandler := sdk.ChainAnteDecorators(mfd) + _, antehandler := s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, tc.globalFeeParams) + + // set fee decorator to ante handler + s.Require().NoError(s.txBuilder.SetMsgs(tc.txMsg)) s.txBuilder.SetFeeAmount(tc.gasPrice) s.txBuilder.SetGasLimit(tc.gasLimit) @@ -692,14 +676,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { // set globalfees and min gas price - globalfeeSubspace := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) - stakingParam := stakingtypes.DefaultParams() - stakingParam.BondDenom = testBondDenom - stakingSubspace := s.SetupTestStakingSubspace(stakingParam) - // setup antehandler - mfd := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), globalfeeSubspace, stakingSubspace, testMaxTotalBypassMinFeeMsgGasUsage) - - sdk.ChainAnteDecorators(mfd) + feeDecorator, _ := s.SetupTestGlobalFeeStoreAndMinGasPrice([]sdk.DecCoin{}, &globfeetypes.Params{}) testCases := []struct { name string @@ -746,7 +723,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { for _, tc := range testCases { s.Run(tc.name, func() { - res := mfd.ContainsOnlyBypassMinFeeMsgs(tc.msgs) + res := feeDecorator.ContainsOnlyBypassMinFeeMsgs(tc.msgs) s.Require().True(tc.expPass == res) }) } diff --git a/x/globalfee/ante/antetest/fee_test_setup.go b/x/globalfee/ante/antetest/fee_test_setup.go index b8adf80ce0a..c1508126a63 100644 --- a/x/globalfee/ante/antetest/fee_test_setup.go +++ b/x/globalfee/ante/antetest/fee_test_setup.go @@ -12,11 +12,13 @@ import ( xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - gaiahelpers "github.com/cosmos/gaia/v9/app/helpers" "github.com/stretchr/testify/suite" tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + gaiahelpers "github.com/cosmos/gaia/v9/app/helpers" + gaiafeeante "github.com/cosmos/gaia/v9/x/globalfee/ante" + gaiaapp "github.com/cosmos/gaia/v9/app" "github.com/cosmos/gaia/v9/x/globalfee" globfeetypes "github.com/cosmos/gaia/v9/x/globalfee/types" @@ -31,6 +33,11 @@ type IntegrationTestSuite struct { txBuilder client.TxBuilder } +var ( + testBondDenom = "uatom" + testMaxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000 +) + func (s *IntegrationTestSuite) SetupTest() { app := gaiahelpers.Setup(s.T()) ctx := app.BaseApp.NewContext(false, tmproto.Header{ @@ -47,12 +54,23 @@ func (s *IntegrationTestSuite) SetupTest() { s.clientCtx = client.Context{}.WithTxConfig(encodingConfig.TxConfig) } -func (s *IntegrationTestSuite) SetupTestGlobalFeeStoreAndMinGasPrice(minGasPrice []sdk.DecCoin, globalFeeParams *globfeetypes.Params) types.Subspace { +func (s *IntegrationTestSuite) SetupTestGlobalFeeStoreAndMinGasPrice(minGasPrice []sdk.DecCoin, globalFeeParams *globfeetypes.Params) (gaiafeeante.FeeDecorator, sdk.AnteHandler) { subspace := s.app.GetSubspace(globalfee.ModuleName) subspace.SetParamSet(s.ctx, globalFeeParams) s.ctx = s.ctx.WithMinGasPrices(minGasPrice).WithIsCheckTx(true) - return subspace + // set staking params + stakingParam := stakingtypes.DefaultParams() + stakingParam.BondDenom = testBondDenom + stakingSubspace := s.SetupTestStakingSubspace(stakingParam) + + // build fee decorator + feeDecorator := gaiafeeante.NewFeeDecorator(gaiaapp.GetDefaultBypassFeeMessages(), subspace, stakingSubspace, uint64(1_000_000)) + + // chain fee decorator to antehandler + antehandler := sdk.ChainAnteDecorators(feeDecorator) + + return feeDecorator, antehandler } // SetupTestStakingSubspace sets uatom as bond denom for the fee tests. From 5d3a6cd3f1866111bd49a5f4eb228fe70526fd90 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 11:05:28 +0100 Subject: [PATCH 11/42] remove comments --- x/globalfee/ante/antetest/fee_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 7b9c352ceca..02e55967c15 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -618,7 +618,6 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { } func (s *IntegrationTestSuite) TestGetMinGasPrice() { - // set globalfees and min gas price expCoins := sdk.Coins{ sdk.NewCoin("photon", sdk.NewInt(2000)), @@ -668,7 +667,6 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, &globfeetypes.Params{}) fees := gaiafeeante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) - // s.Require().True(sort.IsSorted(fees)) s.Require().True(tc.expCoins.Sort().IsEqual(fees)) }) } From 007030659cda346ec907bc18665a03f1180c9e07 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 16:19:25 +0100 Subject: [PATCH 12/42] Update x/globalfee/ante/antetest/fee_test.go Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com> --- x/globalfee/ante/antetest/fee_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 7b9c352ceca..bfbcd292172 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -632,7 +632,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { expCoins sdk.Coins }{ { - "empty min gas price should return zero coins", + "empty min gas price should return empty coins", []sdk.DecCoin{}, uint64(1000), sdk.Coins{}, From e9c4bf8c10268ae8fc6964eafc7b3c3cd7af8db7 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 16:43:54 +0100 Subject: [PATCH 13/42] Update x/globalfee/ante/antetest/fee_test.go Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com> --- x/globalfee/ante/antetest/fee_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index bfbcd292172..775c6fd11c7 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -713,7 +713,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { false, }, { - "non-ibc msgs - should not pass", + "msgs contain only non-bypass msgs - should not pass", []sdk.Msg{ stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), }, From 6c3a5a68ef2f4466a1b75b0abfaa676964beae71 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 16:44:11 +0100 Subject: [PATCH 14/42] Update x/globalfee/ante/antetest/fee_test.go Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com> --- x/globalfee/ante/antetest/fee_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 775c6fd11c7..63f3e429359 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -705,7 +705,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { true, }, { - "msgs contains non-ibc msg - should not pass", + "msgs contain non-bypass msg - should not pass", []sdk.Msg{ ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), stakingtypes.NewMsgDelegate(sdk.AccAddress{}, sdk.ValAddress{}, sdk.Coin{}), From cbfa4193aa7940d317f1772023a5caa88de496fd Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 16:44:18 +0100 Subject: [PATCH 15/42] Update x/globalfee/ante/antetest/fee_test.go Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com> --- x/globalfee/ante/antetest/fee_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 63f3e429359..9de0dcb4e6b 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -697,7 +697,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { true, }, { - "expect ibc msgs to pass", + "expect default bypass msgs to pass", []sdk.Msg{ ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), From 547c55afe0f6f52764bf80d99758cdf23b3a23d3 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 16:44:39 +0100 Subject: [PATCH 16/42] Update x/globalfee/ante/antetest/fee_test.go Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com> --- x/globalfee/ante/antetest/fee_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 9de0dcb4e6b..1a3c35032ec 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -689,7 +689,7 @@ func (s *IntegrationTestSuite) TestContainsOnlyBypassMinFeeMsgs() { true, }, { - "expect ibc msg to pass", + "expect default bypass msg to pass", []sdk.Msg{ ibcchanneltypes.NewMsgRecvPacket(ibcchanneltypes.Packet{}, nil, ibcclienttypes.Height{}, ""), ibcchanneltypes.NewMsgAcknowledgement(ibcchanneltypes.Packet{}, []byte{1}, []byte{1}, ibcclienttypes.Height{}, ""), From 76dea00bd6d11bfef043f6062f41e858225820ab Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Tue, 21 Mar 2023 16:46:46 +0100 Subject: [PATCH 17/42] Update x/globalfee/ante/antetest/fee_test.go --- x/globalfee/ante/antetest/fee_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 1a3c35032ec..1626094f8ae 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -617,6 +617,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { } } +// TestGetMinGasPrice tests the parsing of minGasPrice from app.toml. func (s *IntegrationTestSuite) TestGetMinGasPrice() { // set globalfees and min gas price From fdaa76f954ef42ed44dda3cbb2596d08475f1f9f Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 09:42:29 +0100 Subject: [PATCH 18/42] fix GetMinGasPrice to not return nil coins --- x/globalfee/ante/antetest/fee_test.go | 42 +++++++++++++++++++++++++-- x/globalfee/ante/fee.go | 17 ++++++----- x/globalfee/ante/fee_utils_test.go | 6 ++++ 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 639bdbba9da..b366fd2c615 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -1,6 +1,7 @@ package antetest import ( + "fmt" "testing" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -631,12 +632,40 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { feeTxGasLimit uint64 expCoins sdk.Coins }{ + { + "zero coins min gas price should return empty coins", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(0)), + }, + uint64(1000), + sdk.Coins{}, + }, + { + "zero coins, non-zero coins mix should return the non-zero coins only", + []sdk.DecCoin{ + sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), + sdk.NewDecCoinFromDec("uatom", sdk.NewDec(1)), + }, + uint64(1000), + sdk.Coins{ + sdk.NewCoin("stake", sdk.NewInt(0)), + sdk.NewCoin("uatom", sdk.NewInt(1000)), + }, + }, + { + "zero gas limit should return min gas price", + []sdk.DecCoin{}, + uint64(0), + sdk.Coins{}, + }, { "empty min gas price should return empty coins", []sdk.DecCoin{}, uint64(1000), sdk.Coins{}, - }, { + }, + { "unsorted min gas price", []sdk.DecCoin{ sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), @@ -644,7 +673,8 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { }, uint64(1000), expCoins, - }, { + }, + { "sorted min gas price", []sdk.DecCoin{ sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), @@ -652,7 +682,8 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { }, uint64(1000), expCoins, - }, { + }, + { "sorted min gas price", []sdk.DecCoin{ sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), @@ -668,6 +699,11 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, &globfeetypes.Params{}) fees := gaiafeeante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) + fmt.Println(tc.name) + fmt.Println("fees:") + fmt.Printf("%#+v\n", fees) + fmt.Println("exp fees") + fmt.Printf("%#+v\n", tc.expCoins.Sort()) s.Require().True(tc.expCoins.Sort().IsEqual(fees)) }) } diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 02b6057939a..dec61507c1a 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -7,10 +7,12 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/gaia/v9/x/globalfee/types" - "github.com/cosmos/gaia/v9/x/globalfee" tmstrings "github.com/tendermint/tendermint/libs/strings" + + "github.com/cosmos/gaia/v9/x/globalfee" ) // FeeWithBypassDecorator checks if the transaction's fee is at least as large @@ -61,7 +63,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // Get required Global Fee and min gas price requiredGlobalFees, err := mfd.getGlobalFee(ctx, feeTx) if err != nil { - panic(err) + return ctx, err } requiredFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) @@ -185,21 +187,20 @@ func (mfd FeeDecorator) ContainsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { // GetMinGasPrice returns the validator's minimum gas prices // fees given a gas limit -func GetMinGasPrice(ctx sdk.Context, gasLimit int64) sdk.Coins { +func GetMinGasPrice(ctx sdk.Context, gasLimit int64) (requiredFees sdk.Coins) { minGasPrices := ctx.MinGasPrices() - // special case: if minGasPrices=[], requiredFees=[] - requiredFees := make(sdk.Coins, len(minGasPrices)) // if not all coins are zero, check fee with min_gas_price if !minGasPrices.IsZero() { // Determine the required fees by multiplying each required minimum gas // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). glDec := sdk.NewDec(gasLimit) - for i, gp := range minGasPrices { + for _, gp := range minGasPrices { fee := gp.Amount.Mul(glDec) - requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) + requiredFees = append(requiredFees, sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())) } + requiredFees.Sort() } - return requiredFees.Sort() + return } diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index b3af0e34e3d..538ed05eec0 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -73,11 +73,17 @@ func TestCombinedFeeRequirement(t *testing.T) { coinsCointainZero := sdk.Coins{coin1, zeroCoin2}.Sort() coinsCointainZeroNewDenom := sdk.Coins{coin1, zeroCoin3}.Sort() coinsAllZero := sdk.Coins{zeroCoin1, zeroCoin2}.Sort() + twoNilsCoins := make(sdk.Coins, 2) tests := map[string]struct { cGlobal sdk.Coins c sdk.Coins combined sdk.Coins }{ + "min fee is two nils": { + cGlobal: coinsAllZero, + c: twoNilsCoins, + combined: coinsCointainZero, + }, "global fee empty, min fee empty, combined fee empty": { cGlobal: coinsEmpty, c: coinsEmpty, From ed130077c2abe36f33a805fcf645b05b335f77fc Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 11:25:51 +0100 Subject: [PATCH 19/42] min gas price zero coins edge cases --- x/globalfee/ante/antetest/fee_test.go | 40 ++++++++++----------------- x/globalfee/ante/fee.go | 27 +++++++++--------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index b366fd2c615..89352c0ebf0 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -618,7 +618,11 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { } } -// TestGetMinGasPrice tests the parsing of minGasPrice from app.toml. +// TestGetMinGasPrice tests how the operator fees are determined using various min gas prices. +// +// Note that in a real Gaia deployment the parsing of minGasPrice removed all the zero coins. +// This sanitzing happens when the SDK base app sets the minGasPrice into the context. +// (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func (s *IntegrationTestSuite) TestGetMinGasPrice() { expCoins := sdk.Coins{ @@ -632,6 +636,12 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { feeTxGasLimit uint64 expCoins sdk.Coins }{ + { + "empty min gas price should return empty coins", + []sdk.DecCoin{}, + uint64(1000), + sdk.Coins{}, + }, { "zero coins min gas price should return empty coins", []sdk.DecCoin{ @@ -642,7 +652,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { sdk.Coins{}, }, { - "zero coins, non-zero coins mix should return the non-zero coins only", + "zero coins, non-zero coins mix should return zero coin and non-zero coins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), sdk.NewDecCoinFromDec("uatom", sdk.NewDec(1)), @@ -653,20 +663,9 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { sdk.NewCoin("uatom", sdk.NewInt(1000)), }, }, + { - "zero gas limit should return min gas price", - []sdk.DecCoin{}, - uint64(0), - sdk.Coins{}, - }, - { - "empty min gas price should return empty coins", - []sdk.DecCoin{}, - uint64(1000), - sdk.Coins{}, - }, - { - "unsorted min gas price", + "unsorted min gas price should return sorted coins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), @@ -675,16 +674,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { expCoins, }, { - "sorted min gas price", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), - }, - uint64(1000), - expCoins, - }, - { - "sorted min gas price", + "sorted min gas price should return same conins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index dec61507c1a..0bd7ee1a0c2 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -187,20 +187,21 @@ func (mfd FeeDecorator) ContainsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { // GetMinGasPrice returns the validator's minimum gas prices // fees given a gas limit -func GetMinGasPrice(ctx sdk.Context, gasLimit int64) (requiredFees sdk.Coins) { +func GetMinGasPrice(ctx sdk.Context, gasLimit int64) sdk.Coins { minGasPrices := ctx.MinGasPrices() - // if not all coins are zero, check fee with min_gas_price - if !minGasPrices.IsZero() { - // Determine the required fees by multiplying each required minimum gas - // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). - glDec := sdk.NewDec(gasLimit) - - for _, gp := range minGasPrices { - fee := gp.Amount.Mul(glDec) - requiredFees = append(requiredFees, sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())) - } - requiredFees.Sort() + // special case: if minGasPrices=[], requiredFees=[] + if minGasPrices.IsZero() { + return sdk.Coins{} + } + + 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(gasLimit) + for i, gp := range minGasPrices { + fee := gp.Amount.Mul(glDec) + requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) } - return + return requiredFees.Sort() } From 8f20d5344d9aa17169740a5349196827219aa76a Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 11:25:51 +0100 Subject: [PATCH 20/42] min gas price zero coins edge cases --- x/globalfee/ante/antetest/fee_test.go | 46 +++++++++++---------------- x/globalfee/ante/fee.go | 27 ++++++++-------- 2 files changed, 32 insertions(+), 41 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index b366fd2c615..bec43d3c14b 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -35,9 +35,9 @@ func (s *IntegrationTestSuite) TestGetDefaultGlobalFees() { } } -// test global fees and min_gas_price with bypass msg types. -// please note even globalfee=0, min_gas_price=0, we do not let fee=0random_denom pass -// paid fees are already sanitized by removing zero coins(through feeFlag parsing), so use sdk.NewCoins() to create it. +// Test global fees and min_gas_price with bypass msg types. +// Please note even globalfee=0, min_gas_price=0, we do not let fee=0random_denom pass. +// Paid fees are already sanitized by removing zero coins(through feeFlag parsing), so use sdk.NewCoins() to create it. func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder() priv1, _, addr1 := testdata.KeyTestPubAddr() @@ -618,7 +618,11 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { } } -// TestGetMinGasPrice tests the parsing of minGasPrice from app.toml. +// Test how the operator fees are determined using various min gas prices. +// +// Note that in a real Gaia deployment the parsing of minGasPrice removed all the zero coins. +// This sanitzing happens when the SDK base app sets the minGasPrice into the context. +// (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func (s *IntegrationTestSuite) TestGetMinGasPrice() { expCoins := sdk.Coins{ @@ -632,6 +636,12 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { feeTxGasLimit uint64 expCoins sdk.Coins }{ + { + "empty min gas price should return empty coins", + []sdk.DecCoin{}, + uint64(1000), + sdk.Coins{}, + }, { "zero coins min gas price should return empty coins", []sdk.DecCoin{ @@ -642,7 +652,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { sdk.Coins{}, }, { - "zero coins, non-zero coins mix should return the non-zero coins only", + "zero coins, non-zero coins mix should return zero coin and non-zero coins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), sdk.NewDecCoinFromDec("uatom", sdk.NewDec(1)), @@ -653,20 +663,9 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { sdk.NewCoin("uatom", sdk.NewInt(1000)), }, }, + { - "zero gas limit should return min gas price", - []sdk.DecCoin{}, - uint64(0), - sdk.Coins{}, - }, - { - "empty min gas price should return empty coins", - []sdk.DecCoin{}, - uint64(1000), - sdk.Coins{}, - }, - { - "unsorted min gas price", + "unsorted min gas price should return sorted coins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), @@ -675,16 +674,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { expCoins, }, { - "sorted min gas price", - []sdk.DecCoin{ - sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), - sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), - }, - uint64(1000), - expCoins, - }, - { - "sorted min gas price", + "sorted min gas price should return same conins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("photon", sdk.NewDec(2)), sdk.NewDecCoinFromDec("uatom", sdk.NewDec(3)), diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index dec61507c1a..0bd7ee1a0c2 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -187,20 +187,21 @@ func (mfd FeeDecorator) ContainsOnlyBypassMinFeeMsgs(msgs []sdk.Msg) bool { // GetMinGasPrice returns the validator's minimum gas prices // fees given a gas limit -func GetMinGasPrice(ctx sdk.Context, gasLimit int64) (requiredFees sdk.Coins) { +func GetMinGasPrice(ctx sdk.Context, gasLimit int64) sdk.Coins { minGasPrices := ctx.MinGasPrices() - // if not all coins are zero, check fee with min_gas_price - if !minGasPrices.IsZero() { - // Determine the required fees by multiplying each required minimum gas - // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). - glDec := sdk.NewDec(gasLimit) - - for _, gp := range minGasPrices { - fee := gp.Amount.Mul(glDec) - requiredFees = append(requiredFees, sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())) - } - requiredFees.Sort() + // special case: if minGasPrices=[], requiredFees=[] + if minGasPrices.IsZero() { + return sdk.Coins{} + } + + 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(gasLimit) + for i, gp := range minGasPrices { + fee := gp.Amount.Mul(glDec) + requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) } - return + return requiredFees.Sort() } From 0922810f2c25c741a94415dc763ecd85095ee3b2 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 11:57:12 +0100 Subject: [PATCH 21/42] remove debug logs --- x/globalfee/ante/antetest/fee_test.go | 6 ------ x/globalfee/ante/fee_utils_test.go | 9 +++------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index bec43d3c14b..a38fcd0201f 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -1,7 +1,6 @@ package antetest import ( - "fmt" "testing" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -689,11 +688,6 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { s.SetupTestGlobalFeeStoreAndMinGasPrice(tc.minGasPrice, &globfeetypes.Params{}) fees := gaiafeeante.GetMinGasPrice(s.ctx, int64(tc.feeTxGasLimit)) - fmt.Println(tc.name) - fmt.Println("fees:") - fmt.Printf("%#+v\n", fees) - fmt.Println("exp fees") - fmt.Printf("%#+v\n", tc.expCoins.Sort()) s.Require().True(tc.expCoins.Sort().IsEqual(fees)) }) } diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index 538ed05eec0..7259fdca2a8 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -52,6 +52,9 @@ func TestContainZeroCoins(t *testing.T) { } } +// Note that in a real Gaia deployment the parsing of minGasPrice removed all the zero coins. +// This sanitzing happens when the SDK base app sets the minGasPrice into the context. +// (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func TestCombinedFeeRequirement(t *testing.T) { zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) zeroCoin2 := sdk.NewCoin("stake", sdk.ZeroInt()) @@ -73,17 +76,11 @@ func TestCombinedFeeRequirement(t *testing.T) { coinsCointainZero := sdk.Coins{coin1, zeroCoin2}.Sort() coinsCointainZeroNewDenom := sdk.Coins{coin1, zeroCoin3}.Sort() coinsAllZero := sdk.Coins{zeroCoin1, zeroCoin2}.Sort() - twoNilsCoins := make(sdk.Coins, 2) tests := map[string]struct { cGlobal sdk.Coins c sdk.Coins combined sdk.Coins }{ - "min fee is two nils": { - cGlobal: coinsAllZero, - c: twoNilsCoins, - combined: coinsCointainZero, - }, "global fee empty, min fee empty, combined fee empty": { cGlobal: coinsEmpty, c: coinsEmpty, From 679c2e568838f3562350766c4b1e431515e3eb6b Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 12:00:28 +0100 Subject: [PATCH 22/42] udpate comments --- x/globalfee/ante/antetest/fee_test.go | 4 ++-- x/globalfee/ante/fee_utils_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index a38fcd0201f..615f2dec68a 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -619,8 +619,8 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { // Test how the operator fees are determined using various min gas prices. // -// Note that in a real Gaia deployment the parsing of minGasPrice removed all the zero coins. -// This sanitzing happens when the SDK base app sets the minGasPrice into the context. +// Note that in a real Gaia deployment all zero coins are removed from minGasPrice. +// This sanitzing happens when the minGasPrice is set into the context. // (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func (s *IntegrationTestSuite) TestGetMinGasPrice() { diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index 7259fdca2a8..a3036d190e5 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -52,8 +52,8 @@ func TestContainZeroCoins(t *testing.T) { } } -// Note that in a real Gaia deployment the parsing of minGasPrice removed all the zero coins. -// This sanitzing happens when the SDK base app sets the minGasPrice into the context. +// Note that in a real Gaia deployment all zero coins are removed from minGasPrice. +// This sanitzing happens when the minGasPrice is set into the context. // (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func TestCombinedFeeRequirement(t *testing.T) { zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) From 3bb55cf09f7e55f220789363fd1033aa2a131615 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 12:01:52 +0100 Subject: [PATCH 23/42] udpate comments --- x/globalfee/ante/antetest/fee_test.go | 2 +- x/globalfee/ante/fee_utils_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index 615f2dec68a..f161479f66d 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -620,7 +620,7 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { // Test how the operator fees are determined using various min gas prices. // // Note that in a real Gaia deployment all zero coins are removed from minGasPrice. -// This sanitzing happens when the minGasPrice is set into the context. +// This sanitizing happens when the minGasPrice is set into the context. // (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func (s *IntegrationTestSuite) TestGetMinGasPrice() { diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index a3036d190e5..f0232832b8a 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -53,7 +53,7 @@ func TestContainZeroCoins(t *testing.T) { } // Note that in a real Gaia deployment all zero coins are removed from minGasPrice. -// This sanitzing happens when the minGasPrice is set into the context. +// This sanitizing happens when the minGasPrice is set into the context. // (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func TestCombinedFeeRequirement(t *testing.T) { zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) From 9ca89a4d2709fe7ac31ff3f340a46934e2324c98 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 13:32:31 +0100 Subject: [PATCH 24/42] add comment --- x/globalfee/ante/antetest/fee_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index f161479f66d..5bbcd194070 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -642,6 +642,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { sdk.Coins{}, }, { + // should never happen due to sanitizing "zero coins min gas price should return empty coins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), @@ -651,6 +652,7 @@ func (s *IntegrationTestSuite) TestGetMinGasPrice() { sdk.Coins{}, }, { + // should never happen due to sanitizing "zero coins, non-zero coins mix should return zero coin and non-zero coins", []sdk.DecCoin{ sdk.NewDecCoinFromDec("stake", sdk.NewDec(0)), From b923ed221c3ac29117336863b08c98d4d4e54e76 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 16:19:30 +0100 Subject: [PATCH 25/42] Update x/globalfee/types/params.go Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com> --- x/globalfee/types/params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/globalfee/types/params.go b/x/globalfee/types/params.go index c18e403e50d..a2e1838964a 100644 --- a/x/globalfee/types/params.go +++ b/x/globalfee/types/params.go @@ -57,7 +57,7 @@ func (coins DecCoins) Validate() error { lowDenom := "" seenDenoms := make(map[string]bool) - for _, coin := range coins { + for i, coin := range coins { if seenDenoms[coin.Denom] { return fmt.Errorf("duplicate denomination %s", coin.Denom) } From 81d7e496c472b1067a433bebdd18165c9b809802 Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 22 Mar 2023 16:20:03 +0100 Subject: [PATCH 26/42] Update x/globalfee/types/params.go Co-authored-by: yaruwangway <69694322+yaruwangway@users.noreply.github.com> --- x/globalfee/types/params.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/globalfee/types/params.go b/x/globalfee/types/params.go index a2e1838964a..fdadfe4e31a 100644 --- a/x/globalfee/types/params.go +++ b/x/globalfee/types/params.go @@ -64,7 +64,8 @@ func (coins DecCoins) Validate() error { if err := sdk.ValidateDenom(coin.Denom); err != nil { return err } - if coin.Denom <= lowDenom { +// skip the denom order check for the first denom in the coins list + if i != 0 && coin.Denom <= lowDenom { return fmt.Errorf("denomination %s is not sorted", coin.Denom) } if coin.IsNegative() { From c6bde62b512a32d22895b70aa2cd4fb2c4bd7ecf Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Thu, 23 Mar 2023 10:23:37 +0100 Subject: [PATCH 27/42] fix: lint Signed-off-by: Yaru Wang --- x/globalfee/ante/antetest/fee_test.go | 1 - x/globalfee/types/params.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/x/globalfee/ante/antetest/fee_test.go b/x/globalfee/ante/antetest/fee_test.go index ff2c47edc59..cf144b1f616 100644 --- a/x/globalfee/ante/antetest/fee_test.go +++ b/x/globalfee/ante/antetest/fee_test.go @@ -623,7 +623,6 @@ func (s *IntegrationTestSuite) TestGlobalFeeMinimumGasFeeAnteHandler() { // This sanitizing happens when the minGasPrice is set into the context. // (see baseapp.SetMinGasPrices in gaia/cmd/root.go line 221) func (s *IntegrationTestSuite) TestGetMinGasPrice() { - expCoins := sdk.Coins{ sdk.NewCoin("photon", sdk.NewInt(2000)), sdk.NewCoin("uatom", sdk.NewInt(3000)), diff --git a/x/globalfee/types/params.go b/x/globalfee/types/params.go index fdadfe4e31a..7161b2c3e6f 100644 --- a/x/globalfee/types/params.go +++ b/x/globalfee/types/params.go @@ -64,7 +64,7 @@ func (coins DecCoins) Validate() error { if err := sdk.ValidateDenom(coin.Denom); err != nil { return err } -// skip the denom order check for the first denom in the coins list + // skip the denom order check for the first denom in the coins list if i != 0 && coin.Denom <= lowDenom { return fmt.Errorf("denomination %s is not sorted", coin.Denom) } From b658d2789e5ee5ce114a6aa64e9f2714ac7113a0 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Thu, 23 Mar 2023 15:08:43 +0100 Subject: [PATCH 28/42] refactor: global fee zero coins --- x/globalfee/ante/fee.go | 60 ++++--- x/globalfee/ante/fee_utils.go | 80 ++------- x/globalfee/ante/fee_utils_test.go | 274 +++++------------------------ 3 files changed, 95 insertions(+), 319 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 0bd7ee1a0c2..ad7207785ba 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -60,11 +60,12 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") } - // Get required Global Fee and min gas price - requiredGlobalFees, err := mfd.getGlobalFee(ctx, feeTx) + // Get required Global Fees(nonzero globalfee coins, all globalfee coins and zero globalfees denom) + nonZeroGlobalFees, globalFeesAll, zeroGlobalFeesDenom, err := mfd.getGlobalFees(ctx, feeTx) if err != nil { return ctx, err } + // get minimum-gas-prices from app.toml or cli flag requiredFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) // Only check for minimum fees and global fee if the execution mode is CheckTx @@ -72,11 +73,17 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return next(ctx, tx, simulate) } - // sort fee tx's coins + // sort fee tx's coins, feeCoins' zero coins are already removed feeCoins := feeTx.GetFee().Sort() gas := feeTx.GetGas() msgs := feeTx.GetMsgs() + // feeCoinsNoZeroDenomCoins is feeCoins after removing the coins whose denom is zero coins' denom in globalfees + // e.g. feeCoins=[1atom,2photon], globalfee=[0atom,1photon,1quark], then feeCoinsNoZeroDenomCoins = [2photon] + // feeCoinsNoZeroDenomCoins are used to check if the fees are meet the requirement imposed by combinedNonZeroFees + // the coins in feeCoins that is in the denom of globalfees's zero coins do not need to check the feeCoin amount + feeCoinsNoZeroDenomCoins := RemovingZeroDenomCoins(feeCoins, zeroGlobalFeesDenom) + // Accept zero fee transactions only if both of the following statements are true: // // - the tx contains only message types that can bypass the minimum fee, @@ -95,8 +102,9 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne } // If the transaction fee is non-zero, then check that the fees are in // expected denominations. - if !DenomsSubsetOfIncludingZero(feeCoins, requiredGlobalFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fees denom is wrong; got: %s required: %s", feeCoins, requiredGlobalFees) + // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroGlobalFees) = true + if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroGlobalFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fees denom is wrong; got: %s required: %s", feeCoins, globalFeesAll) } } else { // Either the transaction contains at least one message of a type @@ -105,28 +113,30 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // expected denominations and the amounts are greater or equal than // the expected amounts. - combinedFees := CombinedFeeRequirement(requiredGlobalFees, requiredFees) + // combinedNonZeroFees only contains non-zero coins in global fee and minimum-gas-prices setup by a node + combinedNonZeroFees := CombinedFeeRequirement(nonZeroGlobalFees, requiredFees) - // Check that the fees are in expected denominations. Note that a zero fee - // is accepted if the global fee has an entry with a zero amount, e.g., 0uatoms. - if !DenomsSubsetOfIncludingZero(feeCoins, combinedFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFees) + // Check that the fees are in expected denominations. + // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroGlobalFees) = true + if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(combinedNonZeroFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedNonZeroFees) } // Check that the amounts of the fees are greater or equal than // the expected amounts, i.e., at least one feeCoin amount must // be greater or equal to one of the combined required fees. - if !IsAnyGTEIncludingZero(feeCoins, combinedFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFees) + // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.IsAnyGTE(combinedNonZeroFees) = false + if !feeCoinsNoZeroDenomCoins.IsAnyGTE(combinedNonZeroFees) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedNonZeroFees) } } return next(ctx, tx, simulate) } -// getGlobalFee returns the global fees for a given fee tx's gas (might also returns 0denom if globalMinGasPrice is 0) +// getGlobalFee returns the global fees(nonzero coins and all coins in global fee, and zero denoms in globalfee) for a given fee tx's gas // sorted in ascending order. // Note that ParamStoreKeyMinGasPrices type requires coins sorted. -func (mfd FeeDecorator) getGlobalFee(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, error) { +func (mfd FeeDecorator) getGlobalFees(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, sdk.Coins, map[string]bool, error) { var ( globalMinGasPrices sdk.DecCoins err error @@ -139,19 +149,29 @@ func (mfd FeeDecorator) getGlobalFee(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coin if len(globalMinGasPrices) == 0 { globalMinGasPrices, err = mfd.DefaultZeroGlobalFee(ctx) if err != nil { - return sdk.Coins{}, err + return nil, nil, nil, err } } - requiredGlobalFees := make(sdk.Coins, len(globalMinGasPrices)) + requiredGlobalFeesNonZero := sdk.Coins{} + requiredGlobalFeesAll := sdk.Coins{} + requiredGlobalFeesZeroDenom := map[string]bool{} + // Determine the required fees by multiplying each required minimum gas // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). glDec := sdk.NewDec(int64(feeTx.GetGas())) - for i, gp := range globalMinGasPrices { - fee := gp.Amount.Mul(glDec) - requiredGlobalFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) + var fee sdk.Dec + for _, gp := range globalMinGasPrices { + fee = gp.Amount.Mul(glDec) + // if globalfee is zerocoins, record it in requiredGlobalFeesZeroDenom + if fee.IsZero() { + requiredGlobalFeesZeroDenom[gp.Denom] = true + } else { + requiredGlobalFeesNonZero = append(requiredGlobalFeesNonZero, sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())) + } + requiredGlobalFeesAll = append(requiredGlobalFeesAll, sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())) } - return requiredGlobalFees.Sort(), nil + return requiredGlobalFeesNonZero.Sort(), requiredGlobalFeesAll.Sort(), requiredGlobalFeesZeroDenom, nil } func (mfd FeeDecorator) DefaultZeroGlobalFee(ctx sdk.Context) ([]sdk.DecCoin, error) { diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 737e6b17530..964d044ca0a 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -4,74 +4,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// DenomsSubsetOfIncludingZero and IsAnyGTEIncludingZero are similar to DenomsSubsetOf and IsAnyGTE in sdk. -// Since we allow zero coins in global fee(zero coins means the chain does not want to set a global fee but still want to define the fee's denom) -// -// DenomsSubsetOfIncludingZero overwrites DenomsSubsetOf from sdk, to allow zero amt coins in superset. e.g. -// e.g. [1stake] is the DenomsSubsetOfIncludingZero of [0stake] and -// [] is the DenomsSubsetOfIncludingZero of [0stake] but not [1stake]. -// DenomsSubsetOfIncludingZero returns true if coins's denoms is subset of coinsB's denoms. -// If coins is empty set, empty set is any sets' subset -func DenomsSubsetOfIncludingZero(coins, coinsB sdk.Coins) bool { - // more denoms in B than in receiver - if len(coins) > len(coinsB) { - return false - } - // coins=[], coinsB=[0stake] - // let all len(coins) == 0 pass and reject later at IsAnyGTEIncludingZero - if len(coins) == 0 && ContainZeroCoins(coinsB) { - return true - } - // coins=1stake, coinsB=[0stake,1uatom] - for _, coin := range coins { - err := sdk.ValidateDenom(coin.Denom) - if err != nil { - panic(err) - } - if ok, _ := Find(coinsB, coin.Denom); !ok { - return false - } - } - - return true -} - -// IsAnyGTEIncludingZero overwrites the IsAnyGTE from sdk to allow zero coins in coins and coinsB. -// IsAnyGTEIncludingZero returns true if coins contain at least one denom that is present at a greater or equal amount in coinsB; -// it returns false otherwise. If CoinsB is emptyset, no coins sets are IsAnyGTEIncludingZero coinsB unless coins is also empty set. -// NOTE: IsAnyGTEIncludingZero operates under the invariant that both coin sets are sorted by denoms. -// contract !!!! coins must be DenomsSubsetOfIncludingZero of coinsB -func IsAnyGTEIncludingZero(coins, coinsB sdk.Coins) bool { - // no set is empty set's subset except empty set - // this is different from sdk, sdk return false for coinsB empty - if len(coinsB) == 0 && len(coins) == 0 { - return true - } - // nothing is gte empty coins - if len(coinsB) == 0 && len(coins) != 0 { - return false - } - // if feecoins empty (len(coins)==0 && len(coinsB) != 0 ), and globalfee has one denom of amt zero, return true - if len(coins) == 0 { - return ContainZeroCoins(coinsB) - } - - // len(coinsB) != 0 && len(coins) != 0 - // special case: coins=1stake, coinsB=[2stake,0uatom], fail - for _, coin := range coins { - // not find coin in CoinsB - if ok, _ := Find(coinsB, coin.Denom); ok { - // find coin in coinsB, and if the amt == 0, mean either coin=0denom or coinsB=0denom...both true - amt := coinsB.AmountOf(coin.Denom) - if coin.Amount.GTE(amt) { - return true - } - } - } - - return false -} - // ContainZeroCoins returns true if the given coins are empty or contain zero coins, // Note that the coins denoms must be validated, see sdk.ValidateDenom func ContainZeroCoins(coins sdk.Coins) bool { @@ -141,3 +73,15 @@ func Find(coins sdk.Coins, denom string) (bool, sdk.Coin) { } } } + +// RemovingZeroDenomCoins return feeCoins with removing coins whose denom is zero coin's denom in globalfees +func RemovingZeroDenomCoins(feeCoins sdk.Coins, zeroGlobalFeesDenom map[string]bool) sdk.Coins { + feeCoinsNoZeroDenomCoins := []sdk.Coin{} + for _, fc := range feeCoins { + if _, found := zeroGlobalFeesDenom[fc.Denom]; !found { + feeCoinsNoZeroDenomCoins = append(feeCoinsNoZeroDenomCoins, fc) + } + } + + return feeCoinsNoZeroDenomCoins +} diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index f7d7aa944be..032cbadfd95 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -161,248 +161,60 @@ func TestCombinedFeeRequirement(t *testing.T) { } } -func TestDenomsSubsetOfIncludingZero(t *testing.T) { - emptyCoins := sdk.Coins{} - - zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) - zeroCoin2 := sdk.NewCoin("stake", sdk.ZeroInt()) - zeroCoin3 := sdk.NewCoin("quark", sdk.ZeroInt()) - - coin1 := sdk.NewCoin("photon", sdk.NewInt(1)) - coin2 := sdk.NewCoin("stake", sdk.NewInt(2)) - coin3 := sdk.NewCoin("quark", sdk.NewInt(3)) - - coinNewDenom1 := sdk.NewCoin("newphoton", sdk.NewInt(1)) - coinNewDenom2 := sdk.NewCoin("newstake", sdk.NewInt(2)) - coinNewDenom3 := sdk.NewCoin("newquark", sdk.NewInt(3)) - coinNewDenom1Zero := sdk.NewCoin("newphoton", sdk.ZeroInt()) - // coins must be valid !!! and sorted!!! - coinsAllZero := sdk.Coins{zeroCoin1, zeroCoin2, zeroCoin3}.Sort() - coinsAllZeroShort := sdk.Coins{zeroCoin1, zeroCoin2}.Sort() - coinsContainZero := sdk.Coins{zeroCoin1, zeroCoin2, coin3}.Sort() - coinsContainZeroNewDenoms := sdk.Coins{zeroCoin1, zeroCoin2, coinNewDenom1Zero}.Sort() - coins := sdk.Coins{coin1, coin2, coin3}.Sort() - coinsShort := sdk.Coins{coin1, coin2}.Sort() - coinsAllNewDenom := sdk.Coins{coinNewDenom1, coinNewDenom2, coinNewDenom3}.Sort() - coinsOldNewDenom := sdk.Coins{coin1, coin2, coinNewDenom1}.Sort() - - tests := map[string]struct { - superset sdk.Coins - set sdk.Coins - subset bool - }{ - "empty coins is a DenomsSubsetOf empty coins": { - superset: emptyCoins, - set: emptyCoins, - subset: true, - }, - "nonempty coins is not a DenomsSubsetOf empty coins": { - superset: emptyCoins, - set: coins, - subset: false, - }, - "empty coins is not a DenomsSubsetOf nonempty, nonzero coins": { - superset: emptyCoins, - set: coins, - subset: false, - }, - "empty coins is a DenomsSubsetOf coins of all zeros": { - superset: coinsAllZero, - set: emptyCoins, - subset: true, - }, - "empty coins is a DenomsSubsetOf coinsContainZero": { - superset: coinsContainZero, - set: emptyCoins, - subset: true, - }, - "two sets no denoms overlapping, DenomsSubsetOf = false": { - superset: coins, - set: coinsAllNewDenom, - subset: false, - }, - "two sets have partially overlapping denoms, DenomsSubsetOf = false": { - superset: coins, - set: coinsOldNewDenom, - subset: false, - }, - "two sets are nonzero, set's denoms are all in superset, DenomsSubsetOf = true": { - superset: coins, - set: coinsShort, - subset: true, - }, - "supersets are zero coins, set's denoms are all in superset, DenomsSubsetOf = true": { - superset: coinsAllZero, - set: coinsShort, - subset: true, - }, - "supersets contains zero coins, set's denoms are all in superset, DenomsSubsetOf = true": { - superset: coinsContainZero, - set: coinsShort, - subset: true, - }, - "supersets contains zero coins, set's denoms contains zero coins, denoms are overlapping DenomsSubsetOf = true": { - superset: coinsContainZero, - set: coinsContainZero, - subset: true, - }, - "supersets contains zero coins, set's denoms contains zero coins, denoms are not overlapping DenomsSubsetOf = false": { - superset: coinsContainZero, - set: coinsContainZeroNewDenoms, - subset: false, - }, - "two sets of all zero coins, have the same denoms, DenomsSubsetOf = true": { - superset: coinsAllZero, - set: coinsAllZeroShort, - subset: true, - }, +func TestRemovingZeroDenomCoins(t *testing.T) { + zeroGlobalFeesDenom0 := map[string]bool{} + zeroGlobalFeesDenom1 := map[string]bool{ + "uatom": true, + "photon": true, } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - subset := DenomsSubsetOfIncludingZero(test.set, test.superset) - require.Equal(t, test.subset, subset) - }) + zeroGlobalFeesDenom2 := map[string]bool{ + "uatom": true, + } + zeroGlobalFeesDenom3 := map[string]bool{ + "stake": true, } -} - -func TestIsAnyGTEIncludingZero(t *testing.T) { - emptyCoins := sdk.Coins{} - - zeroCoin1 := sdk.NewCoin("photon", sdk.ZeroInt()) - zeroCoin2 := sdk.NewCoin("stake", sdk.ZeroInt()) - zeroCoin3 := sdk.NewCoin("quark", sdk.ZeroInt()) - - coin1 := sdk.NewCoin("photon", sdk.NewInt(10)) - coin1Low := sdk.NewCoin("photon", sdk.NewInt(1)) - coin1High := sdk.NewCoin("photon", sdk.NewInt(100)) - coin2 := sdk.NewCoin("stake", sdk.NewInt(20)) - coin2Low := sdk.NewCoin("stake", sdk.NewInt(2)) - coin2High := sdk.NewCoin("stake", sdk.NewInt(200)) - coin3 := sdk.NewCoin("quark", sdk.NewInt(30)) - coinNewDenom1 := sdk.NewCoin("newphoton", sdk.NewInt(10)) - coinNewDenom2 := sdk.NewCoin("newstake", sdk.NewInt(20)) - coinNewDenom3 := sdk.NewCoin("newquark", sdk.NewInt(30)) - zeroCoinNewDenom1 := sdk.NewCoin("newphoton", sdk.NewInt(10)) - zeroCoinNewDenom2 := sdk.NewCoin("newstake", sdk.NewInt(20)) - zeroCoinNewDenom3 := sdk.NewCoin("newquark", sdk.NewInt(30)) - // coins must be valid !!! and sorted!!! - coinsAllZero := sdk.Coins{zeroCoin1, zeroCoin2, zeroCoin3}.Sort() - coinsAllNewDenomAllZero := sdk.Coins{zeroCoinNewDenom1, zeroCoinNewDenom2, zeroCoinNewDenom3}.Sort() - coinsAllZeroShort := sdk.Coins{zeroCoin1, zeroCoin2}.Sort() - coinsContainZero := sdk.Coins{zeroCoin1, zeroCoin2, coin3}.Sort() + photon := sdk.NewCoin("photon", sdk.OneInt()) + uatom := sdk.NewCoin("uatom", sdk.OneInt()) + feeCoins := sdk.NewCoins(photon, uatom) - coins := sdk.Coins{coin1, coin2, coin3}.Sort() - coinsHighHigh := sdk.Coins{coin1High, coin2High} - coinsHighLow := sdk.Coins{coin1High, coin2Low}.Sort() - coinsLowLow := sdk.Coins{coin1Low, coin2Low}.Sort() - // coinsShort := sdk.Coins{coin1, coin2}.Sort() - coinsAllNewDenom := sdk.Coins{coinNewDenom1, coinNewDenom2, coinNewDenom3}.Sort() - coinsOldNewDenom := sdk.Coins{coin1, coinNewDenom1, coinNewDenom2}.Sort() - coinsOldLowNewDenom := sdk.Coins{coin1Low, coinNewDenom1, coinNewDenom2}.Sort() tests := map[string]struct { - c1 sdk.Coins - c2 sdk.Coins - gte bool // greater or equal + feeCoins sdk.Coins + zeroGlobalFeesDenom map[string]bool + expectedCoins sdk.Coins }{ - "zero coins are GTE zero coins": { - c1: coinsAllZero, - c2: coinsAllZero, - gte: true, - }, - "zero coins(short) are GTE zero coins": { - c1: coinsAllZero, - c2: coinsAllZeroShort, - gte: true, - }, - "zero coins are GTE zero coins(short)": { - c1: coinsAllZeroShort, - c2: coinsAllZero, - gte: true, - }, - "c2 is all zero coins, with different denoms from c1 which are all zero coins too": { - c1: coinsAllZero, - c2: coinsAllNewDenomAllZero, - gte: false, - }, - "empty coins are GTE empty coins": { - c1: emptyCoins, - c2: emptyCoins, - gte: true, - }, - "empty coins are GTE zero coins": { - c1: coinsAllZero, - c2: emptyCoins, - gte: true, - }, - "empty coins are GTE coins that contain zero denom": { - c1: coinsContainZero, - c2: emptyCoins, - gte: true, - }, - "zero coins are not GTE empty coins": { - c1: emptyCoins, - c2: coinsAllZero, - gte: false, - }, - "empty coins are not GTE nonzero coins": { - c1: coins, - c2: emptyCoins, - gte: false, - }, - // special case, not the opposite result of the above case - "nonzero coins are not GTE empty coins": { - c1: emptyCoins, - c2: coins, - gte: false, - }, - "nonzero coins are GTE zero coins, has overlapping denom": { - c1: coinsAllZero, - c2: coins, - gte: true, - }, - "nonzero coins are GTE coins contain zero coins, zero coin is overlapping denom": { - c1: coinsContainZero, - c2: coins, - gte: true, - }, - "one denom amount higher, one denom amount lower": { - c1: coins, - c2: coinsHighLow, - gte: true, - }, - "all coins amounts are lower, denom overlapping": { - c1: coins, - c2: coinsLowLow, - gte: false, - }, - "all coins amounts are higher, denom overlapping": { - c1: coins, - c2: coinsHighHigh, - gte: true, - }, - "denoms are all not overlapping": { - c1: coins, - c2: coinsAllNewDenom, - gte: false, - }, - "denom not all overlapping, one overlapping denom is gte": { - c1: coins, - c2: coinsOldNewDenom, - gte: true, - }, - "denom not all overlapping, the only one overlapping denom is smaller": { - c1: coins, - c2: coinsOldLowNewDenom, - gte: false, + "no zero coins in global fees": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom0, + expectedCoins: feeCoins, + }, + "no removal of fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom3, + expectedCoins: feeCoins, + }, + "remove some of the fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom2, + expectedCoins: sdk.NewCoins(photon), + }, + "remove all of the fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom1, + expectedCoins: sdk.Coins{}, + }, + "fee coins are empty": { + feeCoins: sdk.Coins{}, + zeroGlobalFeesDenom: zeroGlobalFeesDenom1, + expectedCoins: sdk.Coins{}, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - gte := IsAnyGTEIncludingZero(test.c2, test.c1) - require.Equal(t, test.gte, gte) + feeCoinsNoZeroDenoms := RemovingZeroDenomCoins(test.feeCoins, test.zeroGlobalFeesDenom) + require.Equal(t, test.expectedCoins, feeCoinsNoZeroDenoms) }) } + } From 37f4aec2a3dc77dde88d06b8462330ba8cc9859b Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Thu, 23 Mar 2023 15:55:08 +0100 Subject: [PATCH 29/42] refactor: add splitGlobalFees() --- x/globalfee/ante/fee.go | 36 ++++++++++++----------------------- x/globalfee/ante/fee_utils.go | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index ad7207785ba..a06ef44be3e 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -59,9 +59,12 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") } - + globalFeesAll, err := mfd.getGlobalFees(ctx, feeTx) + if err != nil { + return ctx, err + } // Get required Global Fees(nonzero globalfee coins, all globalfee coins and zero globalfees denom) - nonZeroGlobalFees, globalFeesAll, zeroGlobalFeesDenom, err := mfd.getGlobalFees(ctx, feeTx) + nonZeroGlobalFees, zeroGlobalFeesDenom := splitGlobalFees(globalFeesAll) if err != nil { return ctx, err } @@ -133,10 +136,8 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return next(ctx, tx, simulate) } -// getGlobalFee returns the global fees(nonzero coins and all coins in global fee, and zero denoms in globalfee) for a given fee tx's gas -// sorted in ascending order. -// Note that ParamStoreKeyMinGasPrices type requires coins sorted. -func (mfd FeeDecorator) getGlobalFees(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, sdk.Coins, map[string]bool, error) { +// ParamStoreKeyMinGasPrices type require coins sorted. getGlobalFee will also return sorted coins (might return 0denom if globalMinGasPrice is 0) +func (mfd FeeDecorator) getGlobalFees(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, error) { var ( globalMinGasPrices sdk.DecCoins err error @@ -148,30 +149,17 @@ func (mfd FeeDecorator) getGlobalFees(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coi // global fee is empty set, set global fee to 0uatom if len(globalMinGasPrices) == 0 { globalMinGasPrices, err = mfd.DefaultZeroGlobalFee(ctx) - if err != nil { - return nil, nil, nil, err - } } - requiredGlobalFeesNonZero := sdk.Coins{} - requiredGlobalFeesAll := sdk.Coins{} - requiredGlobalFeesZeroDenom := map[string]bool{} - + requiredGlobalFees := make(sdk.Coins, len(globalMinGasPrices)) // Determine the required fees by multiplying each required minimum gas // price by the gas limit, where fee = ceil(minGasPrice * gasLimit). glDec := sdk.NewDec(int64(feeTx.GetGas())) - var fee sdk.Dec - for _, gp := range globalMinGasPrices { - fee = gp.Amount.Mul(glDec) - // if globalfee is zerocoins, record it in requiredGlobalFeesZeroDenom - if fee.IsZero() { - requiredGlobalFeesZeroDenom[gp.Denom] = true - } else { - requiredGlobalFeesNonZero = append(requiredGlobalFeesNonZero, sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())) - } - requiredGlobalFeesAll = append(requiredGlobalFeesAll, sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())) + for i, gp := range globalMinGasPrices { + fee := gp.Amount.Mul(glDec) + requiredGlobalFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) } - return requiredGlobalFeesNonZero.Sort(), requiredGlobalFeesAll.Sort(), requiredGlobalFeesZeroDenom, nil + return requiredGlobalFees.Sort(), err } func (mfd FeeDecorator) DefaultZeroGlobalFee(ctx sdk.Context) ([]sdk.DecCoin, error) { diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 964d044ca0a..d914b6fc18d 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -85,3 +85,21 @@ func RemovingZeroDenomCoins(feeCoins sdk.Coins, zeroGlobalFeesDenom map[string]b return feeCoinsNoZeroDenomCoins } + +// splitGlobalFees returns the sorted nonzero coins and zero denoms in globalfee +func splitGlobalFees(globalfees sdk.Coins) (sdk.Coins, map[string]bool) { + + requiredGlobalFeesNonZero := sdk.Coins{} + requiredGlobalFeesZeroDenom := map[string]bool{} + + for _, gf := range globalfees { + + if gf.IsZero() { + requiredGlobalFeesZeroDenom[gf.Denom] = true + } else { + requiredGlobalFeesNonZero = append(requiredGlobalFeesNonZero, gf) + } + } + + return requiredGlobalFeesNonZero.Sort(), requiredGlobalFeesZeroDenom +} From 274983c34b6cc1df9ea28b692e1e27a89b77b789 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Thu, 23 Mar 2023 17:29:20 +0100 Subject: [PATCH 30/42] fix: globalfee antehandler --- x/globalfee/ante/fee.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index a06ef44be3e..4a12af3c3b9 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -128,7 +128,8 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // the expected amounts, i.e., at least one feeCoin amount must // be greater or equal to one of the combined required fees. // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.IsAnyGTE(combinedNonZeroFees) = false - if !feeCoinsNoZeroDenomCoins.IsAnyGTE(combinedNonZeroFees) { + // len(feeCoins) == len(feeCoinsNoZeroDenomCoins) means feeCoins do not contain globalfee zero Coins'denom + if !feeCoinsNoZeroDenomCoins.IsAnyGTE(combinedNonZeroFees) && len(feeCoins) == len(feeCoinsNoZeroDenomCoins) { return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedNonZeroFees) } } From d3c381e1a962949ade9b12912232114796bcd894 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Fri, 24 Mar 2023 10:23:13 +0100 Subject: [PATCH 31/42] fix: add test helper func --- x/globalfee/ante/fee_utils.go | 3 ++- x/globalfee/ante/fee_utils_test.go | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index d914b6fc18d..89936690915 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -22,6 +22,7 @@ func ContainZeroCoins(coins sdk.Coins) bool { // CombinedFeeRequirement returns the global fee and min_gas_price combined and sorted. // Both globalFees and minGasPrices must be valid, but CombinedFeeRequirement // does not validate them, so it may return 0denom. +// if globalfee is empty, CombinedFeeRequirement return sdk.Coins{} func CombinedFeeRequirement(globalFees, minGasPrices sdk.Coins) sdk.Coins { // empty min_gas_price if len(minGasPrices) == 0 { @@ -29,7 +30,7 @@ func CombinedFeeRequirement(globalFees, minGasPrices sdk.Coins) sdk.Coins { } // empty global fee is not possible if we set default global fee if len(globalFees) == 0 && len(minGasPrices) != 0 { - return globalFees + return sdk.Coins{} } // if min_gas_price denom is in globalfee, and the amount is higher than globalfee, add min_gas_price to allFees diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index 032cbadfd95..ed2b0feff20 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -216,5 +216,21 @@ func TestRemovingZeroDenomCoins(t *testing.T) { require.Equal(t, test.expectedCoins, feeCoinsNoZeroDenoms) }) } +} + +func equalMap(a, b map[string]bool) bool { + if len(a) == 0 && len(b) == 0 { + return true + } + if len(a) == 0 { + return false + } + + for k, _ := range a { + if _, ok := b[k]; !ok { + return false + } + } + return true } From d046942239653e87c1b60c6acf5eb7a972ab8baf Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Fri, 24 Mar 2023 11:11:39 +0100 Subject: [PATCH 32/42] update according to PR comments --- x/globalfee/ante/fee.go | 12 ++++++------ x/globalfee/ante/fee_utils.go | 2 -- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 0bd7ee1a0c2..82a2d09d159 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -60,6 +60,11 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") } + // Only check for minimum fees and global fee if the execution mode is CheckTx + if !ctx.IsCheckTx() || simulate { + return next(ctx, tx, simulate) + } + // Get required Global Fee and min gas price requiredGlobalFees, err := mfd.getGlobalFee(ctx, feeTx) if err != nil { @@ -67,11 +72,6 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne } requiredFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) - // Only check for minimum fees and global fee if the execution mode is CheckTx - if !ctx.IsCheckTx() || simulate { - return next(ctx, tx, simulate) - } - // sort fee tx's coins feeCoins := feeTx.GetFee().Sort() gas := feeTx.GetGas() @@ -82,7 +82,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // - the tx contains only message types that can bypass the minimum fee, // see BypassMinFeeMsgTypes; // - the total gas limit per message does not exceed MaxTotalBypassMinFeeMsgGasUsage, - // i.e., totalGas <= MaxBypassMinFeeMsgGasUsage + // i.e., totalGas <= MaxTotalBypassMinFeeMsgGasUsage // // Otherwise, minimum fees and global fees are checked to prevent spam. doesNotExceedMaxGasUsage := gas <= mfd.MaxTotalBypassMinFeeMsgGasUsage diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 737e6b17530..de63e98e40c 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -5,7 +5,6 @@ import ( ) // DenomsSubsetOfIncludingZero and IsAnyGTEIncludingZero are similar to DenomsSubsetOf and IsAnyGTE in sdk. -// Since we allow zero coins in global fee(zero coins means the chain does not want to set a global fee but still want to define the fee's denom) // // DenomsSubsetOfIncludingZero overwrites DenomsSubsetOf from sdk, to allow zero amt coins in superset. e.g. // e.g. [1stake] is the DenomsSubsetOfIncludingZero of [0stake] and @@ -73,7 +72,6 @@ func IsAnyGTEIncludingZero(coins, coinsB sdk.Coins) bool { } // ContainZeroCoins returns true if the given coins are empty or contain zero coins, -// Note that the coins denoms must be validated, see sdk.ValidateDenom func ContainZeroCoins(coins sdk.Coins) bool { if len(coins) == 0 { return true From 5eeaac624c16d3ebd17a2fd66514230bfc529348 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Fri, 24 Mar 2023 12:41:12 +0100 Subject: [PATCH 33/42] test: add test for splitGlobalFees() --- x/globalfee/ante/fee_utils_test.go | 55 ++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index ed2b0feff20..45894e85186 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -218,7 +218,62 @@ func TestRemovingZeroDenomCoins(t *testing.T) { } } +func TestSplitGlobalFees(t *testing.T) { + photon0 := sdk.NewCoin("photon", sdk.ZeroInt()) + uatom0 := sdk.NewCoin("uatom", sdk.ZeroInt()) + photon1 := sdk.NewCoin("photon", sdk.OneInt()) + uatom1 := sdk.NewCoin("uatom", sdk.OneInt()) + + globalFeesEmpty := sdk.Coins{} + globalFees := sdk.Coins{photon1, uatom1}.Sort() + globalFeesZeroCoins := sdk.Coins{photon0, uatom0}.Sort() + globalFeesMix := sdk.Coins{photon0, uatom1}.Sort() + + tests := map[string]struct { + globalfees sdk.Coins + zeroGlobalFeesDenom map[string]bool + globalfeesNonZero sdk.Coins + }{ + "empty global fees": { + globalfees: globalFeesEmpty, + zeroGlobalFeesDenom: map[string]bool{}, + globalfeesNonZero: sdk.Coins{}, + }, + "nonzero coins global fees": { + globalfees: globalFees, + zeroGlobalFeesDenom: map[string]bool{}, + globalfeesNonZero: globalFees, + }, + "zero coins global fees": { + globalfees: globalFeesZeroCoins, + zeroGlobalFeesDenom: map[string]bool{ + "photon": true, + "uatom": true, + }, + globalfeesNonZero: sdk.Coins{}, + }, + "mix zero, nonzero coins global fees": { + globalfees: globalFeesMix, + zeroGlobalFeesDenom: map[string]bool{ + "photon": true, + }, + globalfeesNonZero: sdk.NewCoins(uatom1), + }, + } + + for name, test := range tests { + t.Run(name, func(t *testing.T) { + nonZeroCoins, zeroCoinsMap := splitGlobalFees(test.globalfees) + require.True(t, nonZeroCoins.IsEqual(test.globalfeesNonZero)) + require.True(t, equalMap(zeroCoinsMap, test.zeroGlobalFeesDenom)) + }) + } +} + func equalMap(a, b map[string]bool) bool { + if len(a) != len(b) { + return false + } if len(a) == 0 && len(b) == 0 { return true } From 211a99e5dbbd7c1794ceb87fb88564b5c43b8bb3 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Fri, 24 Mar 2023 13:05:25 +0100 Subject: [PATCH 34/42] code improvement --- x/globalfee/ante/fee.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index b94be1dd741..cbb0eaea2d2 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -152,6 +152,9 @@ func (mfd FeeDecorator) getGlobalFees(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coi // global fee is empty set, set global fee to 0uatom if len(globalMinGasPrices) == 0 { globalMinGasPrices, err = mfd.DefaultZeroGlobalFee(ctx) + if err != nil { + return sdk.Coins{}, err + } } requiredGlobalFees := make(sdk.Coins, len(globalMinGasPrices)) // Determine the required fees by multiplying each required minimum gas @@ -162,7 +165,7 @@ func (mfd FeeDecorator) getGlobalFees(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coi requiredGlobalFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) } - return requiredGlobalFees.Sort(), err + return requiredGlobalFees.Sort(), nil } func (mfd FeeDecorator) DefaultZeroGlobalFee(ctx sdk.Context) ([]sdk.DecCoin, error) { From 0e677aabaa5baace3d60fcbbe2c5af2c44e72a24 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Fri, 24 Mar 2023 18:08:26 +0100 Subject: [PATCH 35/42] refactor: globalfee antehandler --- x/globalfee/ante/fee.go | 64 +++++++++++++++++++----------- x/globalfee/ante/fee_utils.go | 16 ++++---- x/globalfee/ante/fee_utils_test.go | 2 +- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index cbb0eaea2d2..80af3dc140a 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -2,12 +2,10 @@ package ante import ( "errors" - sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/gaia/v9/x/globalfee/types" tmstrings "github.com/tendermint/tendermint/libs/strings" @@ -65,29 +63,32 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return next(ctx, tx, simulate) } + // sort fee tx's coins, feeCoins' zero coins are already removed + feeCoins := feeTx.GetFee().Sort() + gas := feeTx.GetGas() + msgs := feeTx.GetMsgs() + // Get required Global Fee and min gas price globalFeesAll, err := mfd.getGlobalFees(ctx, feeTx) if err != nil { return ctx, err } - // Get required Global Fees(nonzero globalfee coins, all globalfee coins and zero globalfees denom) - nonZeroGlobalFees, zeroGlobalFeesDenom := splitGlobalFees(globalFeesAll) - if err != nil { - return ctx, err - } + // get minimum-gas-prices from app.toml or cli flag - requiredFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) + localFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) - // sort fee tx's coins, feeCoins' zero coins are already removed - feeCoins := feeTx.GetFee().Sort() - gas := feeTx.GetGas() - msgs := feeTx.GetMsgs() + combinedFeeRequirement := CombinedFeeRequirement(globalFeesAll, localFees) + if len(combinedFeeRequirement) == 0 { + // todo return err + return ctx, nil + } + nonZeroCoinFeesReq, zeroCoinFeesDenomReq := splitFees(combinedFeeRequirement) // feeCoinsNoZeroDenomCoins is feeCoins after removing the coins whose denom is zero coins' denom in globalfees // e.g. feeCoins=[1atom,2photon], globalfee=[0atom,1photon,1quark], then feeCoinsNoZeroDenomCoins = [2photon] // feeCoinsNoZeroDenomCoins are used to check if the fees are meet the requirement imposed by combinedNonZeroFees // the coins in feeCoins that is in the denom of globalfees's zero coins do not need to check the feeCoin amount - feeCoinsNoZeroDenomCoins := RemovingZeroDenomCoins(feeCoins, zeroGlobalFeesDenom) + feeCoinsNoZeroDenomCoins := RemovingZeroDenomCoins(feeCoins, zeroCoinFeesDenomReq) // Accept zero fee transactions only if both of the following statements are true: // @@ -108,8 +109,8 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // If the transaction fee is non-zero, then check that the fees are in // expected denominations. // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroGlobalFees) = true - if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroGlobalFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fees denom is wrong; got: %s required: %s", feeCoins, globalFeesAll) + if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroCoinFeesReq) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fees denom is wrong; got: %s required: %s", feeCoins, combinedFeeRequirement) } } else { // Either the transaction contains at least one message of a type @@ -118,21 +119,36 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // expected denominations and the amounts are greater or equal than // the expected amounts. - // combinedNonZeroFees only contains non-zero coins in global fee and minimum-gas-prices setup by a node - combinedNonZeroFees := CombinedFeeRequirement(nonZeroGlobalFees, requiredFees) + //// feeCoins=[] while there is no zero coins in combinedFeeRequirement, return err + //if len(feeCoins) == 0 && len(zeroCoinFeesDenomReq) != 0 { + // return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) + //} // Check that the fees are in expected denominations. - // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroGlobalFees) = true - if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(combinedNonZeroFees) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedNonZeroFees) + // if len(feeCoinsNoZeroDenomCoins) = 0, DenomsSubsetOf returns true + if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroCoinFeesReq) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) } + + // this ensured len(nonZeroCoinFeesReq) != 0 + if len(zeroCoinFeesDenomReq) != 0 { + return next(ctx, tx, simulate) + } + // Check that the amounts of the fees are greater or equal than // the expected amounts, i.e., at least one feeCoin amount must // be greater or equal to one of the combined required fees. - // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.IsAnyGTE(combinedNonZeroFees) = false - // len(feeCoins) == len(feeCoinsNoZeroDenomCoins) means feeCoins do not contain globalfee zero Coins'denom - if !feeCoinsNoZeroDenomCoins.IsAnyGTE(combinedNonZeroFees) && len(feeCoins) == len(feeCoinsNoZeroDenomCoins) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedNonZeroFees) + // if feeCoins with removing coins of combinedFee zero coins denom is + // not paying enough fees, and feeCoins does not contain + // combinedFeeRequirement zero coins denom, fail the transaction + + // A.IsAnyGTE(B), if len(A) = 0 || if len(B) = 0, return false + + // 1. if feeCoins(empty or not) do not contain required zero coins + // 2. if feeCoins does not IsAnyGTE the nonZeroCoinFeesReq, return err + if !feeCoinsNoZeroDenomCoins.IsAnyGTE(nonZeroCoinFeesReq) { // nonZeroCoinFeesReq is not empty + + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) } } diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 89936690915..482eb4d385d 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -87,20 +87,20 @@ func RemovingZeroDenomCoins(feeCoins sdk.Coins, zeroGlobalFeesDenom map[string]b return feeCoinsNoZeroDenomCoins } -// splitGlobalFees returns the sorted nonzero coins and zero denoms in globalfee -func splitGlobalFees(globalfees sdk.Coins) (sdk.Coins, map[string]bool) { +// splitFees returns the sorted nonzero coins and zero denoms in globalfee +func splitFees(fees sdk.Coins) (sdk.Coins, map[string]bool) { - requiredGlobalFeesNonZero := sdk.Coins{} - requiredGlobalFeesZeroDenom := map[string]bool{} + requiredFeesNonZero := sdk.Coins{} + requiredFeesZeroDenom := map[string]bool{} - for _, gf := range globalfees { + for _, gf := range fees { if gf.IsZero() { - requiredGlobalFeesZeroDenom[gf.Denom] = true + requiredFeesZeroDenom[gf.Denom] = true } else { - requiredGlobalFeesNonZero = append(requiredGlobalFeesNonZero, gf) + requiredFeesNonZero = append(requiredFeesNonZero, gf) } } - return requiredGlobalFeesNonZero.Sort(), requiredGlobalFeesZeroDenom + return requiredFeesNonZero.Sort(), requiredFeesZeroDenom } diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index 45894e85186..290cea8297b 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -263,7 +263,7 @@ func TestSplitGlobalFees(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - nonZeroCoins, zeroCoinsMap := splitGlobalFees(test.globalfees) + nonZeroCoins, zeroCoinsMap := splitFees(test.globalfees) require.True(t, nonZeroCoins.IsEqual(test.globalfeesNonZero)) require.True(t, equalMap(zeroCoinsMap, test.zeroGlobalFeesDenom)) }) From 6bd7872b707a261e0bb7c57d58686f8243b047d6 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Fri, 24 Mar 2023 18:17:07 +0100 Subject: [PATCH 36/42] refactor: bypass logic --- x/globalfee/ante/fee.go | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 80af3dc140a..2ce3fbe3bd4 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -101,18 +101,13 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne doesNotExceedMaxGasUsage := gas <= mfd.MaxTotalBypassMinFeeMsgGasUsage allowedToBypassMinFee := mfd.ContainsOnlyBypassMinFeeMsgs(msgs) && doesNotExceedMaxGasUsage - if allowedToBypassMinFee { - // Transactions with zero fees are accepted - if len(feeCoins) == 0 { - return next(ctx, tx, simulate) - } - // If the transaction fee is non-zero, then check that the fees are in - // expected denominations. - // special case: if len(feeCoinsNoZeroDenomCoins) = 0, feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroGlobalFees) = true - if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroCoinFeesReq) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fees denom is wrong; got: %s required: %s", feeCoins, combinedFeeRequirement) - } - } else { + // Check that the fees are in expected denominations. + // if len(feeCoinsNoZeroDenomCoins) = 0, DenomsSubsetOf returns true + if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroCoinFeesReq) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) + } + + if !allowedToBypassMinFee { // Either the transaction contains at least one message of a type // that cannot bypass the minimum fee or the total gas limit exceeds // the imposed threshold. As a result, check that the fees are in @@ -124,13 +119,8 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) //} - // Check that the fees are in expected denominations. - // if len(feeCoinsNoZeroDenomCoins) = 0, DenomsSubsetOf returns true - if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroCoinFeesReq) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) - } - - // this ensured len(nonZeroCoinFeesReq) != 0 + // if fee denoms are subset of combinedFeeRequirement, pass the transaction. + // this ensured len(nonZeroCoinFeesReq) != 0 later if len(zeroCoinFeesDenomReq) != 0 { return next(ctx, tx, simulate) } @@ -147,7 +137,6 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // 1. if feeCoins(empty or not) do not contain required zero coins // 2. if feeCoins does not IsAnyGTE the nonZeroCoinFeesReq, return err if !feeCoinsNoZeroDenomCoins.IsAnyGTE(nonZeroCoinFeesReq) { // nonZeroCoinFeesReq is not empty - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) } } From ac3d5c863da45f24384ab3f634bdb0aebd496217 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Tue, 28 Mar 2023 20:09:55 +0100 Subject: [PATCH 37/42] refactor: fee check logic --- x/globalfee/ante/fee.go | 61 +++++++++++++----------------- x/globalfee/ante/fee_utils.go | 18 ++++++--- x/globalfee/ante/fee_utils_test.go | 53 +++++++++++++++----------- 3 files changed, 69 insertions(+), 63 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 2ce3fbe3bd4..4a56fe9073d 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -84,11 +84,18 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne } nonZeroCoinFeesReq, zeroCoinFeesDenomReq := splitFees(combinedFeeRequirement) - // feeCoinsNoZeroDenomCoins is feeCoins after removing the coins whose denom is zero coins' denom in globalfees - // e.g. feeCoins=[1atom,2photon], globalfee=[0atom,1photon,1quark], then feeCoinsNoZeroDenomCoins = [2photon] - // feeCoinsNoZeroDenomCoins are used to check if the fees are meet the requirement imposed by combinedNonZeroFees - // the coins in feeCoins that is in the denom of globalfees's zero coins do not need to check the feeCoin amount - feeCoinsNoZeroDenomCoins := RemovingZeroDenomCoins(feeCoins, zeroCoinFeesDenomReq) + // feeCoinsNoZeroDenom is feeCoins after removing the coins whose denom is zero coins' denom in globalfees + // e.g. feeCoins=[1atom,2photon], globalfee=[0atom,1photon,1quark], then feeCoinsNoZeroDenom = [2photon] + // feeCoinsNoZeroDenom are used to check if the fees are meet the requirement imposed by combinedNonZeroFees + // when feeCoins does not contain zero coins'denoms in combinedFeeRequirement + feeCoinsNoZeroDenom, feeCoinsZeroDenom := SplitCoinsByDenoms(feeCoins, zeroCoinFeesDenomReq) + + // Check that the fees are in expected denominations. + // if len(feeCoinsNoZeroDenom) = 0, DenomsSubsetOf returns true + // if len(feeCoinsNoZeroDenom) != 0 && len(nonZeroCoinFeesReq) = 0, return false + if !feeCoinsNoZeroDenom.DenomsSubsetOf(nonZeroCoinFeesReq) { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) + } // Accept zero fee transactions only if both of the following statements are true: // @@ -101,42 +108,28 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne doesNotExceedMaxGasUsage := gas <= mfd.MaxTotalBypassMinFeeMsgGasUsage allowedToBypassMinFee := mfd.ContainsOnlyBypassMinFeeMsgs(msgs) && doesNotExceedMaxGasUsage - // Check that the fees are in expected denominations. - // if len(feeCoinsNoZeroDenomCoins) = 0, DenomsSubsetOf returns true - if !feeCoinsNoZeroDenomCoins.DenomsSubsetOf(nonZeroCoinFeesReq) { - return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) - } - - if !allowedToBypassMinFee { - // Either the transaction contains at least one message of a type - // that cannot bypass the minimum fee or the total gas limit exceeds - // the imposed threshold. As a result, check that the fees are in - // expected denominations and the amounts are greater or equal than - // the expected amounts. - - //// feeCoins=[] while there is no zero coins in combinedFeeRequirement, return err - //if len(feeCoins) == 0 && len(zeroCoinFeesDenomReq) != 0 { - // return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) - //} - - // if fee denoms are subset of combinedFeeRequirement, pass the transaction. - // this ensured len(nonZeroCoinFeesReq) != 0 later - if len(zeroCoinFeesDenomReq) != 0 { + // Either the transaction contains at least one message of a type + // that cannot bypass the minimum fee or the total gas limit exceeds + // the imposed threshold. As a result, besides check the fees are in + // expected denominations, check the amounts are greater or equal than + // the expected amounts. + + // only check feeCoinsNoZeroDenom has coins IsAnyGTE than nonZeroCoinFeesReq + // when feeCoins does not contain denoms of zero denoms in combinedFeeRequirement + if !allowedToBypassMinFee && len(feeCoinsZeroDenom) == 0 { + // This is for dealing special case when feeCoins=[] + if len(feeCoins) == 0 && len(zeroCoinFeesDenomReq) != 0 { return next(ctx, tx, simulate) } // Check that the amounts of the fees are greater or equal than // the expected amounts, i.e., at least one feeCoin amount must // be greater or equal to one of the combined required fees. - // if feeCoins with removing coins of combinedFee zero coins denom is - // not paying enough fees, and feeCoins does not contain - // combinedFeeRequirement zero coins denom, fail the transaction - - // A.IsAnyGTE(B), if len(A) = 0 || if len(B) = 0, return false - // 1. if feeCoins(empty or not) do not contain required zero coins - // 2. if feeCoins does not IsAnyGTE the nonZeroCoinFeesReq, return err - if !feeCoinsNoZeroDenomCoins.IsAnyGTE(nonZeroCoinFeesReq) { // nonZeroCoinFeesReq is not empty + // if len(feeCoinsNoZeroDenom) = 0, return false + // if len(nonZeroCoinFeesReq) = 0, return false (this situation should not happen + // because when nonZeroCoinFeesReq empty, the denom check already failed before) + if !feeCoinsNoZeroDenom.IsAnyGTE(nonZeroCoinFeesReq) { return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) } } diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 482eb4d385d..ea3540b28af 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -75,16 +75,22 @@ func Find(coins sdk.Coins, denom string) (bool, sdk.Coin) { } } -// RemovingZeroDenomCoins return feeCoins with removing coins whose denom is zero coin's denom in globalfees -func RemovingZeroDenomCoins(feeCoins sdk.Coins, zeroGlobalFeesDenom map[string]bool) sdk.Coins { - feeCoinsNoZeroDenomCoins := []sdk.Coin{} +// SplitCoinsByDenoms return feeCoins with splitting coins +// according to a denom map +func SplitCoinsByDenoms(feeCoins sdk.Coins, zeroDenom map[string]bool) (sdk.Coins, sdk.Coins) { + feeCoinsNoZeroDenom := []sdk.Coin{} + feeCoinsZeroDenom := []sdk.Coin{} + for _, fc := range feeCoins { - if _, found := zeroGlobalFeesDenom[fc.Denom]; !found { - feeCoinsNoZeroDenomCoins = append(feeCoinsNoZeroDenomCoins, fc) + _, found := zeroDenom[fc.Denom] + if found { + feeCoinsZeroDenom = append(feeCoinsZeroDenom, fc) + } else { + feeCoinsNoZeroDenom = append(feeCoinsNoZeroDenom, fc) } } - return feeCoinsNoZeroDenomCoins + return feeCoinsNoZeroDenom, feeCoinsZeroDenom } // splitFees returns the sorted nonzero coins and zero denoms in globalfee diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index 290cea8297b..0d6f4bd6501 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -161,7 +161,7 @@ func TestCombinedFeeRequirement(t *testing.T) { } } -func TestRemovingZeroDenomCoins(t *testing.T) { +func TestSplitCoinsByDenoms(t *testing.T) { zeroGlobalFeesDenom0 := map[string]bool{} zeroGlobalFeesDenom1 := map[string]bool{ "uatom": true, @@ -179,41 +179,48 @@ func TestRemovingZeroDenomCoins(t *testing.T) { feeCoins := sdk.NewCoins(photon, uatom) tests := map[string]struct { - feeCoins sdk.Coins - zeroGlobalFeesDenom map[string]bool - expectedCoins sdk.Coins + feeCoins sdk.Coins + zeroGlobalFeesDenom map[string]bool + expectedNonZeroCoins sdk.Coins + expectedZeroCoins sdk.Coins }{ "no zero coins in global fees": { - feeCoins: feeCoins, - zeroGlobalFeesDenom: zeroGlobalFeesDenom0, - expectedCoins: feeCoins, + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom0, + expectedNonZeroCoins: feeCoins, + expectedZeroCoins: sdk.Coins{}, }, - "no removal of fee coins": { - feeCoins: feeCoins, - zeroGlobalFeesDenom: zeroGlobalFeesDenom3, - expectedCoins: feeCoins, + "no split of fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom3, + expectedNonZeroCoins: feeCoins, + expectedZeroCoins: sdk.Coins{}, }, - "remove some of the fee coins": { - feeCoins: feeCoins, - zeroGlobalFeesDenom: zeroGlobalFeesDenom2, - expectedCoins: sdk.NewCoins(photon), + "split the fee coins": { + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom2, + expectedNonZeroCoins: sdk.NewCoins(photon), + expectedZeroCoins: sdk.NewCoins(uatom), }, "remove all of the fee coins": { - feeCoins: feeCoins, - zeroGlobalFeesDenom: zeroGlobalFeesDenom1, - expectedCoins: sdk.Coins{}, + feeCoins: feeCoins, + zeroGlobalFeesDenom: zeroGlobalFeesDenom1, + expectedNonZeroCoins: sdk.Coins{}, + expectedZeroCoins: feeCoins, }, "fee coins are empty": { - feeCoins: sdk.Coins{}, - zeroGlobalFeesDenom: zeroGlobalFeesDenom1, - expectedCoins: sdk.Coins{}, + feeCoins: sdk.Coins{}, + zeroGlobalFeesDenom: zeroGlobalFeesDenom1, + expectedNonZeroCoins: sdk.Coins{}, + expectedZeroCoins: sdk.Coins{}, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - feeCoinsNoZeroDenoms := RemovingZeroDenomCoins(test.feeCoins, test.zeroGlobalFeesDenom) - require.Equal(t, test.expectedCoins, feeCoinsNoZeroDenoms) + feeCoinsNoZeroDenoms, feeCoinsZeroDenoms := SplitCoinsByDenoms(test.feeCoins, test.zeroGlobalFeesDenom) + require.Equal(t, test.expectedNonZeroCoins, feeCoinsNoZeroDenoms) + require.Equal(t, test.expectedZeroCoins, feeCoinsZeroDenoms) }) } } From 7f8dd99dc5d4d524969dbe17e62b9a1358e080cf Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Tue, 28 Mar 2023 22:58:05 +0100 Subject: [PATCH 38/42] fix: lint --- x/globalfee/ante/fee.go | 1 + x/globalfee/ante/fee_utils.go | 2 -- x/globalfee/ante/fee_utils_test.go | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 4a56fe9073d..771db07d1aa 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -2,6 +2,7 @@ package ante import ( "errors" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index ea3540b28af..2223c0c934f 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -95,12 +95,10 @@ func SplitCoinsByDenoms(feeCoins sdk.Coins, zeroDenom map[string]bool) (sdk.Coin // splitFees returns the sorted nonzero coins and zero denoms in globalfee func splitFees(fees sdk.Coins) (sdk.Coins, map[string]bool) { - requiredFeesNonZero := sdk.Coins{} requiredFeesZeroDenom := map[string]bool{} for _, gf := range fees { - if gf.IsZero() { requiredFeesZeroDenom[gf.Denom] = true } else { diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index 0d6f4bd6501..bebc5d9d168 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -288,7 +288,7 @@ func equalMap(a, b map[string]bool) bool { return false } - for k, _ := range a { + for k := range a { if _, ok := b[k]; !ok { return false } From cc9254e9c86bb5d661b2f1ceeda40b5804be1d45 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Thu, 30 Mar 2023 10:25:10 +0100 Subject: [PATCH 39/42] fix: return err when required fees are not set up --- x/globalfee/ante/fee.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 771db07d1aa..16b528cc208 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -80,8 +80,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne combinedFeeRequirement := CombinedFeeRequirement(globalFeesAll, localFees) if len(combinedFeeRequirement) == 0 { - // todo return err - return ctx, nil + return ctx, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "required fees are not setup.") } nonZeroCoinFeesReq, zeroCoinFeesDenomReq := splitFees(combinedFeeRequirement) From 3a252bd38eb9442fd661a71a9827ef9bce2903f7 Mon Sep 17 00:00:00 2001 From: Yaru Wang Date: Mon, 3 Apr 2023 14:08:39 +0200 Subject: [PATCH 40/42] chore: clean comments --- x/globalfee/ante/fee.go | 36 ++++++++++++++++-------------- x/globalfee/ante/fee_utils.go | 8 +++---- x/globalfee/ante/fee_utils_test.go | 2 +- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index f0f7622f5a9..49a150ba266 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -52,7 +52,6 @@ func NewFeeDecorator(bypassMsgTypes []string, globalfeeSubspace, stakingSubspace // AnteHandle implements the AnteDecorator interface func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { - // please note: after parsing feeflag, the zero fees are removed already feeTx, ok := tx.(sdk.FeeTx) if !ok { return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") @@ -63,35 +62,34 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return next(ctx, tx, simulate) } - // sort fee tx's coins, feeCoins' zero coins are already removed + // sort fee tx's coins, zero coins in feeCoins are already removed feeCoins := feeTx.GetFee().Sort() gas := feeTx.GetGas() msgs := feeTx.GetMsgs() - // Get required Global Fee and min gas price - globalFeesAll, err := mfd.getGlobalFees(ctx, feeTx) + // Get required Global Fee + requiredGlobalFees, err := mfd.GetGlobalFee(ctx, feeTx) if err != nil { return ctx, err } - // get minimum-gas-prices from app.toml or cli flag + // get local minimum-gas-prices localFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) - combinedFeeRequirement := CombinedFeeRequirement(globalFeesAll, localFees) + combinedFeeRequirement := CombinedFeeRequirement(requiredGlobalFees, localFees) if len(combinedFeeRequirement) == 0 { return ctx, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "required fees are not setup.") } nonZeroCoinFeesReq, zeroCoinFeesDenomReq := splitFees(combinedFeeRequirement) - // feeCoinsNoZeroDenom is feeCoins after removing the coins whose denom is zero coins' denom in globalfees - // e.g. feeCoins=[1atom,2photon], globalfee=[0atom,1photon,1quark], then feeCoinsNoZeroDenom = [2photon] + // feeCoinsNoZeroDenom is feeCoins after removing the coins whose denom is zero coins' denom in combinedFeeRequirement // feeCoinsNoZeroDenom are used to check if the fees are meet the requirement imposed by combinedNonZeroFees // when feeCoins does not contain zero coins'denoms in combinedFeeRequirement - feeCoinsNoZeroDenom, feeCoinsZeroDenom := SplitCoinsByDenoms(feeCoins, zeroCoinFeesDenomReq) + feeCoinsNoZeroDenom, feeCoinsZeroDenom := splitCoinsByDenoms(feeCoins, zeroCoinFeesDenomReq) // Check that the fees are in expected denominations. - // if len(feeCoinsNoZeroDenom) = 0, DenomsSubsetOf returns true - // if len(feeCoinsNoZeroDenom) != 0 && len(nonZeroCoinFeesReq) = 0, return false + // if feeCoinsNoZeroDenom=[], DenomsSubsetOf returns true + // if feeCoinsNoZeroDenom is not empty, but nonZeroCoinFeesReq empty, return false if !feeCoinsNoZeroDenom.DenomsSubsetOf(nonZeroCoinFeesReq) { return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) } @@ -116,7 +114,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // only check feeCoinsNoZeroDenom has coins IsAnyGTE than nonZeroCoinFeesReq // when feeCoins does not contain denoms of zero denoms in combinedFeeRequirement if !allowedToBypassMinFee && len(feeCoinsZeroDenom) == 0 { - // This is for dealing special case when feeCoins=[] + // special case: when feeCoins=[] and there is zero coin in fee requirement if len(feeCoins) == 0 && len(zeroCoinFeesDenomReq) != 0 { return next(ctx, tx, simulate) } @@ -125,9 +123,10 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // the expected amounts, i.e., at least one feeCoin amount must // be greater or equal to one of the combined required fees. - // if len(feeCoinsNoZeroDenom) = 0, return false - // if len(nonZeroCoinFeesReq) = 0, return false (this situation should not happen - // because when nonZeroCoinFeesReq empty, the denom check already failed before) + // if feeCoinsNoZeroDenom=[], return false + // if nonZeroCoinFeesReq=[], return false (this situation should not happen + // because when nonZeroCoinFeesReq empty, and DenomsSubsetOf check passed, + // the tx should already passed before) if !feeCoinsNoZeroDenom.IsAnyGTE(nonZeroCoinFeesReq) { return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) } @@ -136,8 +135,11 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return next(ctx, tx, simulate) } -// ParamStoreKeyMinGasPrices type require coins sorted. getGlobalFee will also return sorted coins (might return 0denom if globalMinGasPrice is 0) -func (mfd FeeDecorator) getGlobalFees(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, error) { +// GetGlobalFee returns the global fees for a given fee tx's gas +// (might also return 0denom if globalMinGasPrice is 0) +// sorted in ascending order. +// Note that ParamStoreKeyMinGasPrices type requires coins sorted. +func (mfd FeeDecorator) GetGlobalFee(ctx sdk.Context, feeTx sdk.FeeTx) (sdk.Coins, error) { var ( globalMinGasPrices sdk.DecCoins err error diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 2223c0c934f..d8ddb034c70 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -75,14 +75,14 @@ func Find(coins sdk.Coins, denom string) (bool, sdk.Coin) { } } -// SplitCoinsByDenoms return feeCoins with splitting coins +// splitCoinsByDenoms return feeCoins with splitting coins // according to a denom map -func SplitCoinsByDenoms(feeCoins sdk.Coins, zeroDenom map[string]bool) (sdk.Coins, sdk.Coins) { +func splitCoinsByDenoms(feeCoins sdk.Coins, denomMap map[string]bool) (sdk.Coins, sdk.Coins) { feeCoinsNoZeroDenom := []sdk.Coin{} feeCoinsZeroDenom := []sdk.Coin{} for _, fc := range feeCoins { - _, found := zeroDenom[fc.Denom] + _, found := denomMap[fc.Denom] if found { feeCoinsZeroDenom = append(feeCoinsZeroDenom, fc) } else { @@ -93,7 +93,7 @@ func SplitCoinsByDenoms(feeCoins sdk.Coins, zeroDenom map[string]bool) (sdk.Coin return feeCoinsNoZeroDenom, feeCoinsZeroDenom } -// splitFees returns the sorted nonzero coins and zero denoms in globalfee +// splitFees returns the sorted nonzero coins and a Map of zero denoms in feeRequirement func splitFees(fees sdk.Coins) (sdk.Coins, map[string]bool) { requiredFeesNonZero := sdk.Coins{} requiredFeesZeroDenom := map[string]bool{} diff --git a/x/globalfee/ante/fee_utils_test.go b/x/globalfee/ante/fee_utils_test.go index bebc5d9d168..a9114f971bd 100644 --- a/x/globalfee/ante/fee_utils_test.go +++ b/x/globalfee/ante/fee_utils_test.go @@ -218,7 +218,7 @@ func TestSplitCoinsByDenoms(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { - feeCoinsNoZeroDenoms, feeCoinsZeroDenoms := SplitCoinsByDenoms(test.feeCoins, test.zeroGlobalFeesDenom) + feeCoinsNoZeroDenoms, feeCoinsZeroDenoms := splitCoinsByDenoms(test.feeCoins, test.zeroGlobalFeesDenom) require.Equal(t, test.expectedNonZeroCoins, feeCoinsNoZeroDenoms) require.Equal(t, test.expectedZeroCoins, feeCoinsZeroDenoms) }) From 3e4c0a500823ccf9954ab3fb9e06d01c9a768ceb Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Thu, 6 Apr 2023 12:08:02 +0200 Subject: [PATCH 41/42] Sainoe/globalfee coins (#2378) * chore(deps): bump github.com/golangci/golangci-lint (#2319) Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.51.2 to 1.52.1. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.51.2...v1.52.1) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marius Poke Co-authored-by: Milan Mulji <98309852+mmulji-ic@users.noreply.github.com> * chore(deps): bump github.com/docker/docker (#2365) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 20.10.19+incompatible to 20.10.24+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v20.10.19...v20.10.24) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Removed trust node in docs (#2359) * update ditrosless image url in Dockerfiles * nits --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Marius Poke Co-authored-by: Milan Mulji <98309852+mmulji-ic@users.noreply.github.com> --- Dockerfile | 2 +- docs/hub-tutorials/gaiad.md | 8 -- docs/hub-tutorials/live-upgrade-tutorial.md | 1 - e2e.Dockerfile | 2 +- go.mod | 72 +++++------ go.sum | 125 ++++++++++++-------- x/globalfee/ante/fee.go | 15 +-- x/globalfee/ante/fee_utils.go | 16 ++- 8 files changed, 127 insertions(+), 114 deletions(-) diff --git a/Dockerfile b/Dockerfile index b97fbfc34ab..5caba870955 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache $PACKAGES RUN CGO_ENABLED=0 make install # Add to a distroless container -FROM distroless.dev/static:$IMG_TAG +FROM cgr.dev/chainguard/static:$IMG_TAG ARG IMG_TAG COPY --from=gaiad-builder /go/bin/gaiad /usr/local/bin/ EXPOSE 26656 26657 1317 9090 diff --git a/docs/hub-tutorials/gaiad.md b/docs/hub-tutorials/gaiad.md index bc5caec839e..3012ab3b7c1 100644 --- a/docs/hub-tutorials/gaiad.md +++ b/docs/hub-tutorials/gaiad.md @@ -29,14 +29,6 @@ gaiad config node : If you run your own full-node, just use `tcp://localhost:26657` as the address. -Then, let us set the default value of the `--trust-node` flag: - -```bash -gaiad config trust-node true - -# Set to true if you trust the full-node you are connecting to, false otherwise -``` - Finally, let us set the `chain-id` of the blockchain we want to interact with: ```bash diff --git a/docs/hub-tutorials/live-upgrade-tutorial.md b/docs/hub-tutorials/live-upgrade-tutorial.md index f311801bd03..db20c550b3e 100644 --- a/docs/hub-tutorials/live-upgrade-tutorial.md +++ b/docs/hub-tutorials/live-upgrade-tutorial.md @@ -15,7 +15,6 @@ governance process. $ gaiad start # set up the cli config - $ gaiad config trust-node true $ gaiad config chain-id testing # create an upgrade governance proposal diff --git a/e2e.Dockerfile b/e2e.Dockerfile index b941c2628dd..c0a8c80a4e1 100644 --- a/e2e.Dockerfile +++ b/e2e.Dockerfile @@ -11,7 +11,7 @@ RUN apk add --no-cache $PACKAGES RUN CGO_ENABLED=0 make install # Add to a distroless container -FROM distroless.dev/static:$IMG_TAG +FROM cgr.dev/chainguard/static:$IMG_TAG ARG IMG_TAG COPY --from=gaiad-builder /go/bin/gaiad /usr/local/bin/ EXPOSE 26656 26657 1317 9090 diff --git a/go.mod b/go.mod index 5874bd749f0..08d47ec4706 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cosmos/interchain-security v1.1.0 github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.3 - github.com/golangci/golangci-lint v1.51.2 + github.com/golangci/golangci-lint v1.52.1 github.com/gorilla/mux v1.8.0 github.com/gravity-devs/liquidity v1.5.3 github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -41,9 +41,9 @@ require ( filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect - github.com/Abirdcfly/dupword v0.0.9 // indirect - github.com/Antonboom/errname v0.1.7 // indirect - github.com/Antonboom/nilnil v0.1.1 // indirect + github.com/Abirdcfly/dupword v0.0.11 // indirect + github.com/Antonboom/errname v0.1.9 // indirect + github.com/Antonboom/nilnil v0.1.3 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/BurntSushi/toml v1.2.1 // indirect github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect @@ -59,22 +59,22 @@ require ( github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/ashanbrown/forbidigo v1.4.0 // indirect + github.com/ashanbrown/forbidigo v1.5.1 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bkielbasa/cyclop v1.2.0 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect github.com/bombsimon/wsl/v3 v3.4.0 // indirect - github.com/breml/bidichk v0.2.3 // indirect - github.com/breml/errchkjson v0.3.0 // indirect + github.com/breml/bidichk v0.2.4 // indirect + github.com/breml/errchkjson v0.3.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/butuzov/ireturn v0.1.1 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/charithe/durationcheck v0.0.9 // indirect - github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 // indirect + github.com/charithe/durationcheck v0.0.10 // indirect + github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20220817183557-09c6e030a677 // indirect @@ -91,7 +91,7 @@ require ( github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect - github.com/daixiang0/gci v0.9.1 // indirect + github.com/daixiang0/gci v0.10.1 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect @@ -101,26 +101,26 @@ require ( github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/cli v20.10.17+incompatible // indirect - github.com/docker/docker v20.10.19+incompatible // indirect + github.com/docker/docker v20.10.24+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/dvsekhvalnov/jose2go v1.5.0 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/getsentry/sentry-go v0.17.0 // indirect - github.com/go-critic/go-critic v0.6.7 // indirect + github.com/go-critic/go-critic v0.7.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect - github.com/go-toolsmith/astcopy v1.0.3 // indirect + github.com/go-toolsmith/astcopy v1.1.0 // indirect github.com/go-toolsmith/astequal v1.1.0 // indirect github.com/go-toolsmith/astfmt v1.1.0 // indirect github.com/go-toolsmith/astp v1.1.0 // indirect @@ -176,10 +176,10 @@ require ( github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/julz/importas v0.1.0 // indirect - github.com/junk1tm/musttag v0.4.5 // indirect + github.com/junk1tm/musttag v0.5.0 // indirect github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.3 // indirect + github.com/kkHAIKE/contextcheck v1.1.4 // indirect github.com/klauspost/compress v1.15.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -195,26 +195,26 @@ require ( github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/maratori/testableexamples v1.0.0 // indirect - github.com/maratori/testpackage v1.1.0 // indirect - github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect + github.com/maratori/testpackage v1.1.1 // indirect + github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.2.5 // indirect + github.com/mgechev/revive v1.3.1 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect - github.com/moricho/tparallel v0.2.1 // indirect + github.com/moricho/tparallel v0.3.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect github.com/nishanths/exhaustive v0.9.5 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.8.1 // indirect + github.com/nunnatsa/ginkgolinter v0.9.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect @@ -223,14 +223,14 @@ require ( github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.1.0 // indirect + github.com/polyfloyd/go-errorlint v1.4.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/quasilyte/go-ruleguard v0.3.19 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect - github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect + github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect @@ -249,7 +249,7 @@ require ( github.com/sivchari/containedctx v1.0.2 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect github.com/sivchari/tenv v1.7.1 // indirect - github.com/sonatard/noctx v0.0.1 // indirect + github.com/sonatard/noctx v0.0.2 // indirect github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -259,15 +259,15 @@ require ( github.com/subosito/gotenv v1.4.2 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect - github.com/tdakkota/asciicheck v0.1.1 // indirect + github.com/tdakkota/asciicheck v0.2.0 // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tendermint/spm v0.1.9 // indirect github.com/tetafro/godot v1.4.11 // indirect github.com/tidwall/btree v1.5.0 // indirect github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect - github.com/timonwong/loggercheck v0.9.3 // indirect - github.com/tomarrell/wrapcheck/v2 v2.8.0 // indirect + github.com/timonwong/loggercheck v0.9.4 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.0.3 // indirect github.com/ultraware/whitespace v0.0.5 // indirect @@ -283,22 +283,22 @@ require ( go.etcd.io/bbolt v1.3.6 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.23.0 // indirect + go.uber.org/zap v1.24.0 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect - golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/net v0.8.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.6.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + golang.org/x/tools v0.7.0 // indirect google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.4.2 // indirect + honnef.co/go/tools v0.4.3 // indirect mvdan.cc/gofumpt v0.4.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect diff --git a/go.sum b/go.sum index a1ee3e153ca..e6da31c8ff0 100644 --- a/go.sum +++ b/go.sum @@ -428,15 +428,17 @@ git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDf github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/Abirdcfly/dupword v0.0.7/go.mod h1:K/4M1kj+Zh39d2aotRwypvasonOyAMH1c/IZJzE0dmk= -github.com/Abirdcfly/dupword v0.0.9 h1:MxprGjKq3yDBICXDgEEsyGirIXfMYXkLNT/agPsE1tk= -github.com/Abirdcfly/dupword v0.0.9/go.mod h1:PzmHVLLZ27MvHSzV7eFmMXSFArWXZPZmfuuziuUrf2g= +github.com/Abirdcfly/dupword v0.0.11 h1:z6v8rMETchZXUIuHxYNmlUAuKuB21PeaSymTed16wgU= +github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA= github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= github.com/AkihiroSuda/containerd-fuse-overlayfs v1.0.0/go.mod h1:0mMDvQFeLbbn1Wy8P2j3hwFhqBq+FKn8OZPno8WLmp8= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= -github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= +github.com/Antonboom/errname v0.1.9 h1:BZDX4r3l4TBZxZ2o2LNrlGxSHran4d1u4veZdoORTT4= +github.com/Antonboom/errname v0.1.9/go.mod h1:nLTcJzevREuAsgTbG85UsuiWpMpAqbKD1HNZ29OzE58= github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= +github.com/Antonboom/nilnil v0.1.3 h1:6RTbx3d2mcEu3Zwq9TowQpQMVpP75zugwOtqY1RTtcE= +github.com/Antonboom/nilnil v0.1.3/go.mod h1:iOov/7gRcXkeEU+EMGpBu2ORih3iyVEiWjeste1SJm8= github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= @@ -652,8 +654,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= -github.com/ashanbrown/forbidigo v1.4.0 h1:spdPbupaSqtWORq1Q4eHBoPBmHtwVyLKwaedbSLc5Sw= -github.com/ashanbrown/forbidigo v1.4.0/go.mod h1:IvgwB5Y4fzqSAj/WVXKWigoTkB0dzI2FBbpKWuh7ph8= +github.com/ashanbrown/forbidigo v1.5.1 h1:WXhzLjOlnuDYPYQo/eFlcFMi8X/kLfvWLYu6CSoebis= +github.com/ashanbrown/forbidigo v1.5.1/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= @@ -724,10 +726,12 @@ github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2 github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU= github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= -github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI= github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= -github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw= +github.com/breml/bidichk v0.2.4 h1:i3yedFWWQ7YzjdZJHnPo9d/xURinSq3OM+gyM43K4/8= +github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s= github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= +github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjoxQ= +github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/btcsuite/btcd v0.22.2 h1:vBZ+lGGd1XubpOWO67ITJpAEsICWhA0YzqkcpkgNBfo= github.com/btcsuite/btcd v0.22.2/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= @@ -785,11 +789,12 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= +github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= -github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 h1:cy5GCEZLUCshCGCRRUjxHrDUqkB4l5cuUt3ShEckQEo= -github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348/go.mod h1:f/miWtG3SSuTxKsNK3o58H1xl+XV6ZIfbC6p7lPPB8U= +github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 h1:W9o46d2kbNL06lq7UNDPV0zYLzkrde/bjIqO02eoll0= +github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= @@ -1041,8 +1046,8 @@ github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/daixiang0/gci v0.8.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= -github.com/daixiang0/gci v0.9.1 h1:jBrwBmBZTDsGsXiaCTLIe9diotp1X4X64zodFrh7l+c= -github.com/daixiang0/gci v0.9.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/daixiang0/gci v0.10.1 h1:eheNA3ljF6SxnPD/vE4lCBusVHmV3Rs3dkKvFrJ7MR0= +github.com/daixiang0/gci v0.10.1/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI= github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= @@ -1111,8 +1116,9 @@ github.com/docker/docker v20.10.0-beta1.0.20201110211921-af34b94a78a1+incompatib github.com/docker/docker v20.10.3-0.20211208011758-87521affb077+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE= +github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= @@ -1177,8 +1183,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= -github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= @@ -1240,8 +1246,8 @@ github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITL github.com/go-critic/go-critic v0.4.1/go.mod h1:7/14rZGnZbY6E38VEGk2kVhoq6itzc1E68facVDK23g= github.com/go-critic/go-critic v0.4.3/go.mod h1:j4O3D4RoIwRqlZw5jJpx0BNfXWWbpcJoKu5cYSe4YmQ= github.com/go-critic/go-critic v0.6.5/go.mod h1:ezfP/Lh7MA6dBNn4c6ab5ALv3sKnZVLx37tr00uuaOY= -github.com/go-critic/go-critic v0.6.7 h1:1evPrElnLQ2LZtJfmNDzlieDhjnq36SLgNzisx06oPM= -github.com/go-critic/go-critic v0.6.7/go.mod h1:fYZUijFdcnxgx6wPjQA2QEjIRaNCT0gO8bhexy6/QmE= +github.com/go-critic/go-critic v0.7.0 h1:tqbKzB8pqi0NsRZ+1pyU4aweAF7A7QN0Pi4Q02+rYnQ= +github.com/go-critic/go-critic v0.7.0/go.mod h1:moYzd7GdVXE2C2hYTwd7h0CPcqlUeclsyBRwMa38v64= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= @@ -1318,8 +1324,8 @@ github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLR github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= github.com/go-toolsmith/astcopy v1.0.2/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= -github.com/go-toolsmith/astcopy v1.0.3 h1:r0bgSRlMOAgO+BdQnVAcpMSMkrQCnV6ZJmIkrJgcJj0= -github.com/go-toolsmith/astcopy v1.0.3/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= +github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= +github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= github.com/go-toolsmith/astequal v0.0.0-20180903214952-dcb477bfacd6/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= @@ -1337,8 +1343,8 @@ github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnp github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= github.com/go-toolsmith/pkgload v0.0.0-20181119091011-e9e65178eee8/go.mod h1:WoMrjiy4zvdS+Bg6z9jZH82QXwkcgCBX6nOfnmdaHks= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5 h1:eD9POs68PHkwrx7hAB78z1cb6PfGq/jyWn3wJywsH1o= github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= +github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= @@ -1460,8 +1466,8 @@ github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyD github.com/golangci/golangci-lint v1.23.7/go.mod h1:g/38bxfhp4rI7zeWSxcdIeHTQGS58TCak8FYcyCmavQ= github.com/golangci/golangci-lint v1.27.0/go.mod h1:+eZALfxIuthdrHPtfM7w/R3POJLjHDfJJw8XZl9xOng= github.com/golangci/golangci-lint v1.50.1/go.mod h1:AQjHBopYS//oB8xs0y0M/dtxdKHkdhl0RvmjUct0/4w= -github.com/golangci/golangci-lint v1.51.2 h1:yIcsT1X9ZYHdSpeWXRT1ORC/FPGSqDHbHsu9uk4FK7M= -github.com/golangci/golangci-lint v1.51.2/go.mod h1:KH9Q7/3glwpYSknxUgUyLlAv46A8fsSKo1hH2wDvkr8= +github.com/golangci/golangci-lint v1.52.1 h1:TwQtQi5dGE/uFOxYGKwddJo7T9sHsRfTUN00HZMl5Jo= +github.com/golangci/golangci-lint v1.52.1/go.mod h1:wlTh+d/oVlgZC2yCe6nlxrxNAnuhEQC0Zdygoh72Uak= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= @@ -1870,8 +1876,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/junk1tm/musttag v0.4.5 h1:d+mpJ1vn6WFEVKHwkgJiIedis1u/EawKOuUTygAUtCo= -github.com/junk1tm/musttag v0.4.5/go.mod h1:XkcL/9O6RmD88JBXb+I15nYRl9W4ExhgQeCBEhfMC8U= +github.com/junk1tm/musttag v0.5.0 h1:bV1DTdi38Hi4pG4OVWa7Kap0hi0o7EczuK6wQt9zPOM= +github.com/junk1tm/musttag v0.5.0/go.mod h1:PcR7BA+oREQYvHwgjIDmw3exJeds5JzRcvEJTfjrA0M= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= @@ -1901,8 +1907,9 @@ github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw= github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo= +github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= +github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= @@ -2016,12 +2023,14 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= -github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= +github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= +github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= @@ -2082,8 +2091,8 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/mediocregopher/radix/v3 v3.8.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= github.com/mgechev/revive v1.2.4/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= -github.com/mgechev/revive v1.2.5 h1:UF9AR8pOAuwNmhXj2odp4mxv9Nx2qUIwVz8ZsU+Mbec= -github.com/mgechev/revive v1.2.5/go.mod h1:nFOXent79jMTISAfOAasKfy0Z2Ejq0WX7Qn/KAdYopI= +github.com/mgechev/revive v1.3.1 h1:OlQkcH40IB2cGuprTPcjB0iIUddgVZgGmDX3IAMR8D4= +github.com/mgechev/revive v1.3.1/go.mod h1:YlD6TTWl2B8A103R9KWJSPVI9DrEf+oqr15q21Ld+5I= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= @@ -2162,8 +2171,9 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/moricho/tparallel v0.3.0 h1:8dDx3S3e+jA+xiQXC7O3dvfRTe/J+FYlTDDW01Y7z/Q= +github.com/moricho/tparallel v0.3.0/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= @@ -2224,8 +2234,8 @@ github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwp github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.8.1 h1:/y4o/0hV+ruUHj4xXh89xlFjoaitnI4LnkpuYs02q1c= -github.com/nunnatsa/ginkgolinter v0.8.1/go.mod h1:FYYLtszIdmzCH8XMaMPyxPVXZ7VCaIm55bA+gugx+14= +github.com/nunnatsa/ginkgolinter v0.9.0 h1:Sm0zX5QfjJzkeCjEp+t6d3Ha0jwvoDjleP9XCsrEzOA= +github.com/nunnatsa/ginkgolinter v0.9.0/go.mod h1:FHaMLURXP7qImeH6bvxWJUpyH+2tuqe5j4rW1gxJRmI= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -2396,8 +2406,8 @@ github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= -github.com/polyfloyd/go-errorlint v1.1.0 h1:VKoEFg5yxSgJ2yFPVhxW7oGz+f8/OVcuMeNvcPIi6Eg= -github.com/polyfloyd/go-errorlint v1.1.0/go.mod h1:Uss7Bc/izYG0leCMRx3WVlrpqWedSZk7V/FUQW6VJ6U= +github.com/polyfloyd/go-errorlint v1.4.0 h1:b+sQ5HibPIAjEZwtuwU8Wz/u0dMZ7YL+bk+9yWyHVJk= +github.com/polyfloyd/go-errorlint v1.4.0/go.mod h1:qJCkPeBn+0EXkdKTrUCcuFStM2xrDKfxI3MGLXPexUs= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= @@ -2475,8 +2485,9 @@ github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mo github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= @@ -2609,8 +2620,9 @@ github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4S github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= +github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/sourcegraph/go-diff v0.5.3/go.mod h1:v9JDtjCE4HHHCZGId75rg8gkKKa98RVjBcBGsVmMmak= @@ -2723,8 +2735,9 @@ github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cb github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= +github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= github.com/tdewolff/minify/v2 v2.12.1/go.mod h1:p5pwbvNs1ghbFED/ZW1towGsnnWwzvM8iz8l0eURi9g= github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk= github.com/tdewolff/parse/v2 v2.6.3/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= @@ -2760,8 +2773,9 @@ github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiff github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e h1:MV6KaVu/hzByHP0UvJ4HcMGE/8a6A4Rggc/0wx2AvJo= github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= -github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw= +github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= +github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= @@ -2777,8 +2791,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck/v2 v2.7.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= -github.com/tomarrell/wrapcheck/v2 v2.8.0 h1:qDzbir0xmoE+aNxGCPrn+rUSxAX+nG6vREgbbXAR81I= -github.com/tomarrell/wrapcheck/v2 v2.8.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= +github.com/tomarrell/wrapcheck/v2 v2.8.1 h1:HxSqDSN0sAt0yJYsrcYVoEeyM4aI9yAm3KQpIXDJRhQ= +github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= @@ -3006,8 +3020,9 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= golang.org/x/build v0.0.0-20190314133821-5284462c4bec/go.mod h1:atTaCNAy0f16Ah5aV1gMSwgiKVHwu/JncqDpuRr7lS4= @@ -3094,8 +3109,9 @@ golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9 h1:6WHiuFL9FNjg8RljAaT7FNUuKDbvMqS1i5cr2OE2sLQ= 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 h1:J74nGeMgeFnYQJN59eFwh06jX/V8g0lB7LWpjSLxtgU= +golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -3128,8 +3144,9 @@ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -3234,8 +3251,10 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -3470,8 +3489,9 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -3484,8 +3504,9 @@ golang.org/x/term v0.1.0/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.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3500,8 +3521,9 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3649,8 +3671,9 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -3987,8 +4010,8 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= -honnef.co/go/tools v0.4.2 h1:6qXr+R5w+ktL5UkwEbPp+fEvfyoMPche6GkOpGHZcLc= -honnef.co/go/tools v0.4.2/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= +honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= +honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= k8s.io/api v0.0.0-20180904230853-4e7be11eab3f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.17.4/go.mod h1:5qxx6vjmwUVG2nHQTKGlLts8Tbok8PzHl4vHtVFuZCA= k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index 49a150ba266..a0dd87338c4 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -62,7 +62,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return next(ctx, tx, simulate) } - // sort fee tx's coins, zero coins in feeCoins are already removed + // Sort fee tx's coins, zero coins in feeCoins are already removed feeCoins := feeTx.GetFee().Sort() gas := feeTx.GetGas() msgs := feeTx.GetMsgs() @@ -73,24 +73,25 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne return ctx, err } - // get local minimum-gas-prices + // Get local minimum-gas-prices localFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) combinedFeeRequirement := CombinedFeeRequirement(requiredGlobalFees, localFees) if len(combinedFeeRequirement) == 0 { return ctx, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "required fees are not setup.") } + nonZeroCoinFeesReq, zeroCoinFeesDenomReq := splitFees(combinedFeeRequirement) // feeCoinsNoZeroDenom is feeCoins after removing the coins whose denom is zero coins' denom in combinedFeeRequirement - // feeCoinsNoZeroDenom are used to check if the fees are meet the requirement imposed by combinedNonZeroFees - // when feeCoins does not contain zero coins'denoms in combinedFeeRequirement - feeCoinsNoZeroDenom, feeCoinsZeroDenom := splitCoinsByDenoms(feeCoins, zeroCoinFeesDenomReq) + // feeCoinsNoZeroDenom is used to check if the fees meets the requirement imposed by nonZeroCoinFeesReq + // when feeCoins does not contain zero coins' denoms in combinedFeeRequirement + feeCoinsNonZeroDenom, feeCoinsZeroDenom := splitCoinsByDenoms(feeCoins, zeroCoinFeesDenomReq) // Check that the fees are in expected denominations. // if feeCoinsNoZeroDenom=[], DenomsSubsetOf returns true // if feeCoinsNoZeroDenom is not empty, but nonZeroCoinFeesReq empty, return false - if !feeCoinsNoZeroDenom.DenomsSubsetOf(nonZeroCoinFeesReq) { + if !feeCoinsNonZeroDenom.DenomsSubsetOf(nonZeroCoinFeesReq) { return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "fee is not a subset of required fees; got %s, required: %s", feeCoins, combinedFeeRequirement) } @@ -127,7 +128,7 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // if nonZeroCoinFeesReq=[], return false (this situation should not happen // because when nonZeroCoinFeesReq empty, and DenomsSubsetOf check passed, // the tx should already passed before) - if !feeCoinsNoZeroDenom.IsAnyGTE(nonZeroCoinFeesReq) { + if !feeCoinsNonZeroDenom.IsAnyGTE(nonZeroCoinFeesReq) { return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeCoins, combinedFeeRequirement) } } diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index d8ddb034c70..1b8b535399f 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -75,25 +75,23 @@ func Find(coins sdk.Coins, denom string) (bool, sdk.Coin) { } } -// splitCoinsByDenoms return feeCoins with splitting coins -// according to a denom map -func splitCoinsByDenoms(feeCoins sdk.Coins, denomMap map[string]bool) (sdk.Coins, sdk.Coins) { - feeCoinsNoZeroDenom := []sdk.Coin{} - feeCoinsZeroDenom := []sdk.Coin{} - +// splitCoinsByDenoms returns the given coins split in two whether +// their demon is or isn't found in the given denom map. +func splitCoinsByDenoms(feeCoins sdk.Coins, denomMap map[string]bool) (feeCoinsNonZeroDenom sdk.Coins, feeCoinsZeroDenom sdk.Coins) { for _, fc := range feeCoins { _, found := denomMap[fc.Denom] if found { feeCoinsZeroDenom = append(feeCoinsZeroDenom, fc) } else { - feeCoinsNoZeroDenom = append(feeCoinsNoZeroDenom, fc) + feeCoinsNonZeroDenom = append(feeCoinsNonZeroDenom, fc) } } - return feeCoinsNoZeroDenom, feeCoinsZeroDenom + return feeCoinsNonZeroDenom.Sort(), feeCoinsZeroDenom.Sort() } -// splitFees returns the sorted nonzero coins and a Map of zero denoms in feeRequirement +// splitFees returns the given fees nonzero coins +// and a map storing the zero coins's denoms func splitFees(fees sdk.Coins) (sdk.Coins, map[string]bool) { requiredFeesNonZero := sdk.Coins{} requiredFeesZeroDenom := map[string]bool{} From 663c718ef660b8729924877db6734098b1b4adfb Mon Sep 17 00:00:00 2001 From: Simon Noetzlin Date: Wed, 12 Apr 2023 15:27:44 +0200 Subject: [PATCH 42/42] fix nits --- x/globalfee/ante/fee.go | 9 ++++++--- x/globalfee/ante/fee_utils.go | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/x/globalfee/ante/fee.go b/x/globalfee/ante/fee.go index a0dd87338c4..909fac4a765 100644 --- a/x/globalfee/ante/fee.go +++ b/x/globalfee/ante/fee.go @@ -54,7 +54,7 @@ func NewFeeDecorator(bypassMsgTypes []string, globalfeeSubspace, stakingSubspace func (mfd FeeDecorator) 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") + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must implement the sdk.FeeTx interface") } // Only check for minimum fees and global fee if the execution mode is CheckTx @@ -76,14 +76,17 @@ func (mfd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne // Get local minimum-gas-prices localFees := GetMinGasPrice(ctx, int64(feeTx.GetGas())) + // CombinedFeeRequirement should never be empty since + // global fee is set to its default value, i.e. 0uatom, if empty combinedFeeRequirement := CombinedFeeRequirement(requiredGlobalFees, localFees) if len(combinedFeeRequirement) == 0 { return ctx, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "required fees are not setup.") } - nonZeroCoinFeesReq, zeroCoinFeesDenomReq := splitFees(combinedFeeRequirement) + nonZeroCoinFeesReq, zeroCoinFeesDenomReq := getNonZeroFees(combinedFeeRequirement) - // feeCoinsNoZeroDenom is feeCoins after removing the coins whose denom is zero coins' denom in combinedFeeRequirement + // feeCoinsNonZeroDenom contains non-zero denominations from the combinedFeeRequirement + // // feeCoinsNoZeroDenom is used to check if the fees meets the requirement imposed by nonZeroCoinFeesReq // when feeCoins does not contain zero coins' denoms in combinedFeeRequirement feeCoinsNonZeroDenom, feeCoinsZeroDenom := splitCoinsByDenoms(feeCoins, zeroCoinFeesDenomReq) diff --git a/x/globalfee/ante/fee_utils.go b/x/globalfee/ante/fee_utils.go index 1b8b535399f..c30cc508440 100644 --- a/x/globalfee/ante/fee_utils.go +++ b/x/globalfee/ante/fee_utils.go @@ -90,9 +90,9 @@ func splitCoinsByDenoms(feeCoins sdk.Coins, denomMap map[string]bool) (feeCoinsN return feeCoinsNonZeroDenom.Sort(), feeCoinsZeroDenom.Sort() } -// splitFees returns the given fees nonzero coins +// getNonZeroFees returns the given fees nonzero coins // and a map storing the zero coins's denoms -func splitFees(fees sdk.Coins) (sdk.Coins, map[string]bool) { +func getNonZeroFees(fees sdk.Coins) (sdk.Coins, map[string]bool) { requiredFeesNonZero := sdk.Coins{} requiredFeesZeroDenom := map[string]bool{}