github.com/cosmos/cosmos-sdk@v0.50.10/x/auth/ante/fee_test.go (about)

     1  package ante_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/golang/mock/gomock"
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"cosmossdk.io/math"
    10  
    11  	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
    12  	"github.com/cosmos/cosmos-sdk/testutil/testdata"
    13  	sdk "github.com/cosmos/cosmos-sdk/types"
    14  	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
    15  	"github.com/cosmos/cosmos-sdk/types/tx/signing"
    16  	"github.com/cosmos/cosmos-sdk/x/auth/ante"
    17  	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    18  )
    19  
    20  func TestDeductFeeDecorator_ZeroGas(t *testing.T) {
    21  	s := SetupTestSuite(t, true)
    22  	s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder()
    23  
    24  	mfd := ante.NewDeductFeeDecorator(s.accountKeeper, s.bankKeeper, s.feeGrantKeeper, nil)
    25  	antehandler := sdk.ChainAnteDecorators(mfd)
    26  
    27  	// keys and addresses
    28  	accs := s.CreateTestAccounts(1)
    29  
    30  	// msg and signatures
    31  	msg := testdata.NewTestMsg(accs[0].acc.GetAddress())
    32  	require.NoError(t, s.txBuilder.SetMsgs(msg))
    33  
    34  	// set zero gas
    35  	s.txBuilder.SetGasLimit(0)
    36  
    37  	privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0}
    38  	tx, err := s.CreateTestTx(s.ctx, privs, accNums, accSeqs, s.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    39  	require.NoError(t, err)
    40  
    41  	// Set IsCheckTx to true
    42  	s.ctx = s.ctx.WithIsCheckTx(true)
    43  
    44  	_, err = antehandler(s.ctx, tx, false)
    45  	require.Error(t, err)
    46  
    47  	// zero gas is accepted in simulation mode
    48  	_, err = antehandler(s.ctx, tx, true)
    49  	require.NoError(t, err)
    50  }
    51  
    52  func TestEnsureMempoolFees(t *testing.T) {
    53  	s := SetupTestSuite(t, true) // setup
    54  	s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder()
    55  
    56  	mfd := ante.NewDeductFeeDecorator(s.accountKeeper, s.bankKeeper, s.feeGrantKeeper, nil)
    57  	antehandler := sdk.ChainAnteDecorators(mfd)
    58  
    59  	// keys and addresses
    60  	accs := s.CreateTestAccounts(1)
    61  
    62  	// msg and signatures
    63  	msg := testdata.NewTestMsg(accs[0].acc.GetAddress())
    64  	feeAmount := testdata.NewTestFeeAmount()
    65  	gasLimit := uint64(15)
    66  	require.NoError(t, s.txBuilder.SetMsgs(msg))
    67  	s.txBuilder.SetFeeAmount(feeAmount)
    68  	s.txBuilder.SetGasLimit(gasLimit)
    69  
    70  	s.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), authtypes.FeeCollectorName, feeAmount).Return(nil).Times(3)
    71  
    72  	privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0}
    73  	tx, err := s.CreateTestTx(s.ctx, privs, accNums, accSeqs, s.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    74  	require.NoError(t, err)
    75  
    76  	// Set high gas price so standard test fee fails
    77  	atomPrice := sdk.NewDecCoinFromDec("atom", math.LegacyNewDec(20))
    78  	highGasPrice := []sdk.DecCoin{atomPrice}
    79  	s.ctx = s.ctx.WithMinGasPrices(highGasPrice)
    80  
    81  	// Set IsCheckTx to true
    82  	s.ctx = s.ctx.WithIsCheckTx(true)
    83  
    84  	// antehandler errors with insufficient fees
    85  	_, err = antehandler(s.ctx, tx, false)
    86  	require.NotNil(t, err, "Decorator should have errored on too low fee for local gasPrice")
    87  
    88  	// antehandler should not error since we do not check minGasPrice in simulation mode
    89  	cacheCtx, _ := s.ctx.CacheContext()
    90  	_, err = antehandler(cacheCtx, tx, true)
    91  	require.Nil(t, err, "Decorator should not have errored in simulation mode")
    92  
    93  	// Set IsCheckTx to false
    94  	s.ctx = s.ctx.WithIsCheckTx(false)
    95  
    96  	// antehandler should not error since we do not check minGasPrice in DeliverTx
    97  	_, err = antehandler(s.ctx, tx, false)
    98  	require.Nil(t, err, "MempoolFeeDecorator returned error in DeliverTx")
    99  
   100  	// Set IsCheckTx back to true for testing sufficient mempool fee
   101  	s.ctx = s.ctx.WithIsCheckTx(true)
   102  
   103  	atomPrice = sdk.NewDecCoinFromDec("atom", math.LegacyNewDec(0).Quo(math.LegacyNewDec(100000)))
   104  	lowGasPrice := []sdk.DecCoin{atomPrice}
   105  	s.ctx = s.ctx.WithMinGasPrices(lowGasPrice)
   106  
   107  	newCtx, err := antehandler(s.ctx, tx, false)
   108  	require.Nil(t, err, "Decorator should not have errored on fee higher than local gasPrice")
   109  	// Priority is the smallest gas price amount in any denom. Since we have only 1 gas price
   110  	// of 10atom, the priority here is 10.
   111  	require.Equal(t, int64(10), newCtx.Priority())
   112  }
   113  
   114  func TestDeductFees(t *testing.T) {
   115  	s := SetupTestSuite(t, false)
   116  	s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder()
   117  
   118  	// keys and addresses
   119  	accs := s.CreateTestAccounts(1)
   120  
   121  	// msg and signatures
   122  	msg := testdata.NewTestMsg(accs[0].acc.GetAddress())
   123  	feeAmount := testdata.NewTestFeeAmount()
   124  	gasLimit := testdata.NewTestGasLimit()
   125  	require.NoError(t, s.txBuilder.SetMsgs(msg))
   126  	s.txBuilder.SetFeeAmount(feeAmount)
   127  	s.txBuilder.SetGasLimit(gasLimit)
   128  
   129  	privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{0}, []uint64{0}
   130  	tx, err := s.CreateTestTx(s.ctx, privs, accNums, accSeqs, s.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
   131  	require.NoError(t, err)
   132  
   133  	dfd := ante.NewDeductFeeDecorator(s.accountKeeper, s.bankKeeper, nil, nil)
   134  	antehandler := sdk.ChainAnteDecorators(dfd)
   135  	s.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(sdkerrors.ErrInsufficientFunds)
   136  
   137  	_, err = antehandler(s.ctx, tx, false)
   138  
   139  	require.NotNil(t, err, "Tx did not error when fee payer had insufficient funds")
   140  
   141  	s.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
   142  	_, err = antehandler(s.ctx, tx, false)
   143  
   144  	require.Nil(t, err, "Tx errored after account has been set with sufficient funds")
   145  }