github.com/Finschia/finschia-sdk@v0.49.1/x/auth/ante/basic_test.go (about)

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