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

     1  package ante_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
     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/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  )
    18  
    19  func TestSetupDecorator_BlockMaxGas(t *testing.T) {
    20  	suite := SetupTestSuite(t, true)
    21  	suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
    22  
    23  	// keys and addresses
    24  	priv1, _, addr1 := testdata.KeyTestPubAddr()
    25  
    26  	// msg and signatures
    27  	msg := testdata.NewTestMsg(addr1)
    28  	feeAmount := testdata.NewTestFeeAmount()
    29  	require.NoError(t, suite.txBuilder.SetMsgs(msg))
    30  	suite.txBuilder.SetFeeAmount(feeAmount)
    31  	suite.txBuilder.SetGasLimit(101)
    32  
    33  	privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
    34  	tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    35  	require.NoError(t, err)
    36  
    37  	sud := ante.NewSetUpContextDecorator()
    38  	antehandler := sdk.ChainAnteDecorators(sud)
    39  
    40  	suite.ctx = suite.ctx.
    41  		WithBlockHeight(1).
    42  		WithGasMeter(storetypes.NewGasMeter(0)).
    43  		WithConsensusParams(cmtproto.ConsensusParams{
    44  			Block: &cmtproto.BlockParams{
    45  				MaxGas: 100,
    46  			},
    47  		})
    48  
    49  	_, err = antehandler(suite.ctx, tx, false)
    50  	require.Error(t, err)
    51  }
    52  
    53  func TestSetup(t *testing.T) {
    54  	suite := SetupTestSuite(t, true)
    55  	suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
    56  
    57  	// keys and addresses
    58  	priv1, _, addr1 := testdata.KeyTestPubAddr()
    59  
    60  	// msg and signatures
    61  	msg := testdata.NewTestMsg(addr1)
    62  	feeAmount := testdata.NewTestFeeAmount()
    63  	gasLimit := testdata.NewTestGasLimit()
    64  	require.NoError(t, suite.txBuilder.SetMsgs(msg))
    65  	suite.txBuilder.SetFeeAmount(feeAmount)
    66  	suite.txBuilder.SetGasLimit(gasLimit)
    67  
    68  	privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
    69  	tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
    70  	require.NoError(t, err)
    71  
    72  	sud := ante.NewSetUpContextDecorator()
    73  	antehandler := sdk.ChainAnteDecorators(sud)
    74  
    75  	// Set height to non-zero value for GasMeter to be set
    76  	suite.ctx = suite.ctx.WithBlockHeight(1).WithGasMeter(storetypes.NewGasMeter(0))
    77  
    78  	// Context GasMeter Limit not set
    79  	require.Equal(t, uint64(0), suite.ctx.GasMeter().Limit(), "GasMeter set with limit before setup")
    80  
    81  	newCtx, err := antehandler(suite.ctx, tx, false)
    82  	require.Nil(t, err, "SetUpContextDecorator returned error")
    83  
    84  	// Context GasMeter Limit should be set after SetUpContextDecorator runs
    85  	require.Equal(t, gasLimit, newCtx.GasMeter().Limit(), "GasMeter not set correctly")
    86  }
    87  
    88  func TestRecoverPanic(t *testing.T) {
    89  	suite := SetupTestSuite(t, true)
    90  	suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder()
    91  
    92  	// keys and addresses
    93  	priv1, _, addr1 := testdata.KeyTestPubAddr()
    94  
    95  	// msg and signatures
    96  	msg := testdata.NewTestMsg(addr1)
    97  	feeAmount := testdata.NewTestFeeAmount()
    98  	gasLimit := testdata.NewTestGasLimit()
    99  	require.NoError(t, suite.txBuilder.SetMsgs(msg))
   100  	suite.txBuilder.SetFeeAmount(feeAmount)
   101  	suite.txBuilder.SetGasLimit(gasLimit)
   102  
   103  	privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
   104  	tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
   105  	require.NoError(t, err)
   106  
   107  	sud := ante.NewSetUpContextDecorator()
   108  	antehandler := sdk.ChainAnteDecorators(sud, OutOfGasDecorator{})
   109  
   110  	// Set height to non-zero value for GasMeter to be set
   111  	suite.ctx = suite.ctx.WithBlockHeight(1)
   112  
   113  	newCtx, err := antehandler(suite.ctx, tx, false)
   114  
   115  	require.NotNil(t, err, "Did not return error on OutOfGas panic")
   116  
   117  	require.True(t, sdkerrors.ErrOutOfGas.Is(err), "Returned error is not an out of gas error")
   118  	require.Equal(t, gasLimit, newCtx.GasMeter().Limit())
   119  
   120  	antehandler = sdk.ChainAnteDecorators(sud, PanicDecorator{})
   121  	require.Panics(t, func() { antehandler(suite.ctx, tx, false) }, "Recovered from non-Out-of-Gas panic")
   122  }
   123  
   124  type OutOfGasDecorator struct{}
   125  
   126  // AnteDecorator that will throw OutOfGas panic
   127  func (ogd OutOfGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
   128  	overLimit := ctx.GasMeter().Limit() + 1
   129  
   130  	// Should panic with outofgas error
   131  	ctx.GasMeter().ConsumeGas(overLimit, "test panic")
   132  
   133  	// not reached
   134  	return next(ctx, tx, simulate)
   135  }
   136  
   137  type PanicDecorator struct{}
   138  
   139  func (pd PanicDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
   140  	panic("random error")
   141  }