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

     1  package ante_test
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	storetypes "cosmossdk.io/store/types"
    10  
    11  	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
    12  	"github.com/cosmos/cosmos-sdk/crypto/types/multisig"
    13  	"github.com/cosmos/cosmos-sdk/testutil/testdata"
    14  	sdk "github.com/cosmos/cosmos-sdk/types"
    15  	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
    16  	"github.com/cosmos/cosmos-sdk/types/tx/signing"
    17  	"github.com/cosmos/cosmos-sdk/x/auth/ante"
    18  )
    19  
    20  func TestValidateBasic(t *testing.T) {
    21  	suite := SetupTestSuite(t, true)
    22  	suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
    23  
    24  	// keys and addresses
    25  	priv1, _, addr1 := testdata.KeyTestPubAddr()
    26  
    27  	// msg and signatures
    28  	msg := testdata.NewTestMsg(addr1)
    29  	feeAmount := testdata.NewTestFeeAmount()
    30  	gasLimit := testdata.NewTestGasLimit()
    31  	require.NoError(t, suite.txBuilder.SetMsgs(msg))
    32  	suite.txBuilder.SetFeeAmount(feeAmount)
    33  	suite.txBuilder.SetGasLimit(gasLimit)
    34  
    35  	privs, accNums, accSeqs := []cryptotypes.PrivKey{}, []uint64{}, []uint64{}
    36  	invalidTx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    37  	require.NoError(t, err)
    38  
    39  	vbd := ante.NewValidateBasicDecorator()
    40  	antehandler := sdk.ChainAnteDecorators(vbd)
    41  	_, err = antehandler(suite.ctx, invalidTx, false)
    42  
    43  	require.ErrorIs(t, err, sdkerrors.ErrNoSignatures, "Did not error on invalid tx")
    44  
    45  	privs, accNums, accSeqs = []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
    46  	validTx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    47  	require.NoError(t, err)
    48  
    49  	_, err = antehandler(suite.ctx, validTx, false)
    50  	require.Nil(t, err, "ValidateBasicDecorator returned error on valid tx. err: %v", err)
    51  
    52  	// test decorator skips on recheck
    53  	suite.ctx = suite.ctx.WithIsReCheckTx(true)
    54  
    55  	// decorator should skip processing invalidTx on recheck and thus return nil-error
    56  	_, err = antehandler(suite.ctx, invalidTx, false)
    57  
    58  	require.Nil(t, err, "ValidateBasicDecorator ran on ReCheck")
    59  }
    60  
    61  func TestValidateMemo(t *testing.T) {
    62  	suite := SetupTestSuite(t, true)
    63  	suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
    64  
    65  	// keys and addresses
    66  	priv1, _, addr1 := testdata.KeyTestPubAddr()
    67  
    68  	// msg and signatures
    69  	msg := testdata.NewTestMsg(addr1)
    70  	feeAmount := testdata.NewTestFeeAmount()
    71  	gasLimit := testdata.NewTestGasLimit()
    72  	require.NoError(t, suite.txBuilder.SetMsgs(msg))
    73  	suite.txBuilder.SetFeeAmount(feeAmount)
    74  	suite.txBuilder.SetGasLimit(gasLimit)
    75  
    76  	privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
    77  	suite.txBuilder.SetMemo(strings.Repeat("01234567890", 500))
    78  	invalidTx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    79  	require.NoError(t, err)
    80  
    81  	// require that long memos get rejected
    82  	vmd := ante.NewValidateMemoDecorator(suite.accountKeeper)
    83  	antehandler := sdk.ChainAnteDecorators(vmd)
    84  	_, err = antehandler(suite.ctx, invalidTx, false)
    85  
    86  	require.ErrorIs(t, err, sdkerrors.ErrMemoTooLarge, "Did not error on tx with high memo")
    87  
    88  	suite.txBuilder.SetMemo(strings.Repeat("01234567890", 10))
    89  	validTx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    90  	require.NoError(t, err)
    91  
    92  	// require small memos pass ValidateMemo Decorator
    93  	_, err = antehandler(suite.ctx, validTx, false)
    94  	require.Nil(t, err, "ValidateBasicDecorator returned error on valid tx. err: %v", err)
    95  }
    96  
    97  func TestConsumeGasForTxSize(t *testing.T) {
    98  	suite := SetupTestSuite(t, true)
    99  
   100  	// keys and addresses
   101  	priv1, _, addr1 := testdata.KeyTestPubAddr()
   102  
   103  	// msg and signatures
   104  	msg := testdata.NewTestMsg(addr1)
   105  	feeAmount := testdata.NewTestFeeAmount()
   106  	gasLimit := testdata.NewTestGasLimit()
   107  
   108  	cgtsd := ante.NewConsumeGasForTxSizeDecorator(suite.accountKeeper)
   109  	antehandler := sdk.ChainAnteDecorators(cgtsd)
   110  
   111  	testCases := []struct {
   112  		name  string
   113  		sigV2 signing.SignatureV2
   114  	}{
   115  		{"SingleSignatureData", signing.SignatureV2{PubKey: priv1.PubKey()}},
   116  		{"MultiSignatureData", signing.SignatureV2{PubKey: priv1.PubKey(), Data: multisig.NewMultisig(2)}},
   117  	}
   118  
   119  	for _, tc := range testCases {
   120  		t.Run(tc.name, func(t *testing.T) {
   121  			suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
   122  			require.NoError(t, suite.txBuilder.SetMsgs(msg))
   123  			suite.txBuilder.SetFeeAmount(feeAmount)
   124  			suite.txBuilder.SetGasLimit(gasLimit)
   125  			suite.txBuilder.SetMemo(strings.Repeat("01234567890", 10))
   126  
   127  			privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
   128  			tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
   129  			require.NoError(t, err)
   130  
   131  			txBytes, err := suite.clientCtx.TxConfig.TxJSONEncoder()(tx)
   132  			require.Nil(t, err, "Cannot marshal tx: %v", err)
   133  
   134  			params := suite.accountKeeper.GetParams(suite.ctx)
   135  			expectedGas := storetypes.Gas(len(txBytes)) * params.TxSizeCostPerByte
   136  
   137  			// Set suite.ctx with TxBytes manually
   138  			suite.ctx = suite.ctx.WithTxBytes(txBytes)
   139  
   140  			// track how much gas is necessary to retrieve parameters
   141  			beforeGas := suite.ctx.GasMeter().GasConsumed()
   142  			suite.accountKeeper.GetParams(suite.ctx)
   143  			afterGas := suite.ctx.GasMeter().GasConsumed()
   144  			expectedGas += afterGas - beforeGas
   145  
   146  			beforeGas = suite.ctx.GasMeter().GasConsumed()
   147  			suite.ctx, err = antehandler(suite.ctx, tx, false)
   148  			require.Nil(t, err, "ConsumeTxSizeGasDecorator returned error: %v", err)
   149  
   150  			// require that decorator consumes expected amount of gas
   151  			consumedGas := suite.ctx.GasMeter().GasConsumed() - beforeGas
   152  			require.Equal(t, expectedGas, consumedGas, "Decorator did not consume the correct amount of gas")
   153  
   154  			// simulation must not underestimate gas of this decorator even with nil signatures
   155  			txBuilder, err := suite.clientCtx.TxConfig.WrapTxBuilder(tx)
   156  			require.NoError(t, err)
   157  			require.NoError(t, txBuilder.SetSignatures(tc.sigV2))
   158  			tx = txBuilder.GetTx()
   159  
   160  			simTxBytes, err := suite.clientCtx.TxConfig.TxJSONEncoder()(tx)
   161  			require.Nil(t, err, "Cannot marshal tx: %v", err)
   162  			// require that simulated tx is smaller than tx with signatures
   163  			require.True(t, len(simTxBytes) < len(txBytes), "simulated tx still has signatures")
   164  
   165  			// Set suite.ctx with smaller simulated TxBytes manually
   166  			suite.ctx = suite.ctx.WithTxBytes(simTxBytes)
   167  
   168  			beforeSimGas := suite.ctx.GasMeter().GasConsumed()
   169  
   170  			// run antehandler with simulate=true
   171  			suite.ctx, err = antehandler(suite.ctx, tx, true)
   172  			consumedSimGas := suite.ctx.GasMeter().GasConsumed() - beforeSimGas
   173  
   174  			// require that antehandler passes and does not underestimate decorator cost
   175  			require.Nil(t, err, "ConsumeTxSizeGasDecorator returned error: %v", err)
   176  			require.True(t, consumedSimGas >= expectedGas, "Simulate mode underestimates gas on AnteDecorator. Simulated cost: %d, expected cost: %d", consumedSimGas, expectedGas)
   177  		})
   178  	}
   179  }
   180  
   181  func TestTxHeightTimeoutDecorator(t *testing.T) {
   182  	suite := SetupTestSuite(t, true)
   183  
   184  	antehandler := sdk.ChainAnteDecorators(ante.NewTxTimeoutHeightDecorator())
   185  
   186  	// keys and addresses
   187  	priv1, _, addr1 := testdata.KeyTestPubAddr()
   188  
   189  	// msg and signatures
   190  	msg := testdata.NewTestMsg(addr1)
   191  	feeAmount := testdata.NewTestFeeAmount()
   192  	gasLimit := testdata.NewTestGasLimit()
   193  
   194  	testCases := []struct {
   195  		name        string
   196  		timeout     uint64
   197  		height      int64
   198  		expectedErr error
   199  	}{
   200  		{"default value", 0, 10, nil},
   201  		{"no timeout (greater height)", 15, 10, nil},
   202  		{"no timeout (same height)", 10, 10, nil},
   203  		{"timeout (smaller height)", 9, 10, sdkerrors.ErrTxTimeoutHeight},
   204  	}
   205  
   206  	for _, tc := range testCases {
   207  		tc := tc
   208  
   209  		t.Run(tc.name, func(t *testing.T) {
   210  			suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
   211  
   212  			require.NoError(t, suite.txBuilder.SetMsgs(msg))
   213  
   214  			suite.txBuilder.SetFeeAmount(feeAmount)
   215  			suite.txBuilder.SetGasLimit(gasLimit)
   216  			suite.txBuilder.SetMemo(strings.Repeat("01234567890", 10))
   217  			suite.txBuilder.SetTimeoutHeight(tc.timeout)
   218  
   219  			privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
   220  			tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
   221  			require.NoError(t, err)
   222  
   223  			ctx := suite.ctx.WithBlockHeight(tc.height)
   224  			_, err = antehandler(ctx, tx, true)
   225  			require.ErrorIs(t, err, tc.expectedErr)
   226  		})
   227  	}
   228  }