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 }