github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/app/ante/ante_test.go (about)

     1  package ante_test
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/require"
    10  
    11  	ethcmn "github.com/ethereum/go-ethereum/common"
    12  
    13  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    14  	tmcrypto "github.com/fibonacci-chain/fbc/libs/tendermint/crypto"
    15  
    16  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    17  
    18  	"github.com/fibonacci-chain/fbc/app"
    19  	"github.com/fibonacci-chain/fbc/app/ante"
    20  	"github.com/fibonacci-chain/fbc/app/types"
    21  	evmtypes "github.com/fibonacci-chain/fbc/x/evm/types"
    22  )
    23  
    24  func requireValidTx(
    25  	t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context, tx sdk.Tx, sim bool,
    26  ) {
    27  	_, err := anteHandler(ctx, tx, sim)
    28  	require.NoError(t, err)
    29  }
    30  
    31  func requireInvalidTx(
    32  	t *testing.T, anteHandler sdk.AnteHandler, ctx sdk.Context,
    33  	tx sdk.Tx, sim bool,
    34  ) {
    35  	_, err := anteHandler(ctx, tx, sim)
    36  	require.Error(t, err)
    37  }
    38  
    39  func (suite *AnteTestSuite) TestValidEthTx() {
    40  	suite.ctx.SetBlockHeight(1)
    41  
    42  	addr1, priv1 := newTestAddrKey()
    43  	addr2, _ := newTestAddrKey()
    44  
    45  	acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
    46  	_ = acc1.SetCoins(newTestCoins())
    47  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc1)
    48  
    49  	acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2)
    50  	_ = acc2.SetCoins(newTestCoins())
    51  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc2)
    52  
    53  	// require a valid Ethereum tx to pass
    54  	to := ethcmn.BytesToAddress(addr2.Bytes())
    55  	amt := big.NewInt(32)
    56  	gas := big.NewInt(20)
    57  	ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
    58  
    59  	tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
    60  	suite.Require().NoError(err)
    61  	requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
    62  }
    63  
    64  func (suite *AnteTestSuite) TestValidTx() {
    65  	suite.ctx.SetBlockHeight(1)
    66  
    67  	addr1, priv1 := newTestAddrKey()
    68  	addr2, priv2 := newTestAddrKey()
    69  
    70  	acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
    71  	_ = acc1.SetCoins(newTestCoins())
    72  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc1)
    73  
    74  	acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2)
    75  	_ = acc2.SetCoins(newTestCoins())
    76  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc2)
    77  
    78  	// require a valid SDK tx to pass
    79  	fee := newTestStdFee()
    80  	msg1 := newTestMsg(addr1, addr2)
    81  	msgs := []sdk.Msg{msg1}
    82  
    83  	privKeys := []tmcrypto.PrivKey{priv1, priv2}
    84  	accNums := []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()}
    85  	accSeqs := []uint64{acc1.GetSequence(), acc2.GetSequence()}
    86  
    87  	tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee)
    88  
    89  	requireValidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
    90  }
    91  
    92  func (suite *AnteTestSuite) TestSDKInvalidSigs() {
    93  	suite.ctx.SetBlockHeight(1)
    94  
    95  	addr1, priv1 := newTestAddrKey()
    96  	addr2, priv2 := newTestAddrKey()
    97  	addr3, priv3 := newTestAddrKey()
    98  
    99  	acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
   100  	_ = acc1.SetCoins(newTestCoins())
   101  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc1)
   102  
   103  	acc2 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr2)
   104  	_ = acc2.SetCoins(newTestCoins())
   105  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc2)
   106  
   107  	fee := newTestStdFee()
   108  	msg1 := newTestMsg(addr1, addr2)
   109  
   110  	// require validation failure with no signers
   111  	msgs := []sdk.Msg{msg1}
   112  
   113  	privKeys := []tmcrypto.PrivKey{}
   114  	accNums := []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()}
   115  	accSeqs := []uint64{acc1.GetSequence(), acc2.GetSequence()}
   116  
   117  	tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee)
   118  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   119  
   120  	// require validation failure with invalid number of signers
   121  	msgs = []sdk.Msg{msg1}
   122  
   123  	privKeys = []tmcrypto.PrivKey{priv1}
   124  	accNums = []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber()}
   125  	accSeqs = []uint64{acc1.GetSequence(), acc2.GetSequence()}
   126  
   127  	tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee)
   128  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   129  
   130  	// require validation failure with an invalid signer
   131  	msg2 := newTestMsg(addr1, addr3)
   132  	msgs = []sdk.Msg{msg1, msg2}
   133  
   134  	privKeys = []tmcrypto.PrivKey{priv1, priv2, priv3}
   135  	accNums = []uint64{acc1.GetAccountNumber(), acc2.GetAccountNumber(), 0}
   136  	accSeqs = []uint64{acc1.GetSequence(), acc2.GetSequence(), 0}
   137  
   138  	tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee)
   139  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   140  }
   141  
   142  func (suite *AnteTestSuite) TestSDKInvalidAcc() {
   143  	suite.ctx.SetBlockHeight(1)
   144  
   145  	addr1, priv1 := newTestAddrKey()
   146  
   147  	acc1 := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
   148  	_ = acc1.SetCoins(newTestCoins())
   149  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc1)
   150  
   151  	fee := newTestStdFee()
   152  	msg1 := newTestMsg(addr1)
   153  	msgs := []sdk.Msg{msg1}
   154  	privKeys := []tmcrypto.PrivKey{priv1}
   155  
   156  	// require validation failure with invalid account number
   157  	accNums := []uint64{1}
   158  	accSeqs := []uint64{acc1.GetSequence()}
   159  
   160  	tx := newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee)
   161  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   162  
   163  	// require validation failure with invalid sequence (nonce)
   164  	accNums = []uint64{acc1.GetAccountNumber()}
   165  	accSeqs = []uint64{1}
   166  
   167  	tx = newTestSDKTx(suite.ctx, msgs, privKeys, accNums, accSeqs, fee)
   168  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   169  }
   170  
   171  func (suite *AnteTestSuite) TestEthInvalidSig() {
   172  	suite.ctx.SetBlockHeight(1)
   173  
   174  	_, priv1 := newTestAddrKey()
   175  	addr2, _ := newTestAddrKey()
   176  	to := ethcmn.BytesToAddress(addr2.Bytes())
   177  	amt := big.NewInt(32)
   178  	gas := big.NewInt(20)
   179  	ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
   180  
   181  	tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
   182  	suite.Require().NoError(err)
   183  
   184  	ctx := suite.ctx
   185  	ctx.SetChainID("ethermint-4")
   186  	requireInvalidTx(suite.T(), suite.anteHandler, ctx, tx, false)
   187  }
   188  
   189  func (suite *AnteTestSuite) TestEthInvalidNonce() {
   190  
   191  	suite.ctx.SetBlockHeight(1)
   192  
   193  	addr1, priv1 := newTestAddrKey()
   194  	addr2, _ := newTestAddrKey()
   195  
   196  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
   197  	err := acc.SetSequence(10)
   198  	suite.Require().NoError(err)
   199  	_ = acc.SetCoins(newTestCoins())
   200  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   201  
   202  	// require a valid Ethereum tx to pass
   203  	to := ethcmn.BytesToAddress(addr2.Bytes())
   204  	amt := big.NewInt(32)
   205  	gas := big.NewInt(20)
   206  	ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
   207  
   208  	tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
   209  	suite.Require().NoError(err)
   210  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   211  }
   212  
   213  func (suite *AnteTestSuite) TestEthInsufficientBalance() {
   214  	suite.ctx.SetBlockHeight(1)
   215  
   216  	addr1, priv1 := newTestAddrKey()
   217  	addr2, _ := newTestAddrKey()
   218  
   219  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
   220  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   221  
   222  	// require a valid Ethereum tx to pass
   223  	to := ethcmn.BytesToAddress(addr2.Bytes())
   224  	amt := big.NewInt(32)
   225  	gas := big.NewInt(20)
   226  	ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("test"))
   227  
   228  	tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
   229  	suite.Require().NoError(err)
   230  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   231  }
   232  
   233  func (suite *AnteTestSuite) TestEthInvalidIntrinsicGas() {
   234  	suite.ctx.SetBlockHeight(1)
   235  
   236  	addr1, priv1 := newTestAddrKey()
   237  	addr2, _ := newTestAddrKey()
   238  
   239  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
   240  	_ = acc.SetCoins(newTestCoins())
   241  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   242  
   243  	// require a valid Ethereum tx to pass
   244  	to := ethcmn.BytesToAddress(addr2.Bytes())
   245  	amt := big.NewInt(32)
   246  	gas := big.NewInt(20)
   247  	gasLimit := uint64(1000)
   248  	ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, gasLimit, gas, []byte("test"))
   249  
   250  	tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
   251  	suite.Require().NoError(err)
   252  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx.WithIsCheckTx(true), tx, false)
   253  }
   254  
   255  func (suite *AnteTestSuite) TestEthInvalidMempoolFees() {
   256  	// setup app with checkTx = true
   257  	suite.app = app.Setup(true)
   258  	suite.ctx = suite.app.BaseApp.NewContext(true, abci.Header{Height: 1, ChainID: "ethermint-3", Time: time.Now().UTC()})
   259  	suite.app.EvmKeeper.SetParams(suite.ctx, evmtypes.DefaultParams())
   260  
   261  	suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.EvmKeeper, suite.app.SupplyKeeper, nil, suite.app.WasmHandler, suite.app.IBCKeeper, suite.app.StakingKeeper, suite.app.ParamsKeeper)
   262  	suite.ctx.SetMinGasPrices(sdk.NewDecCoins(sdk.NewDecCoinFromDec(types.NativeToken, sdk.NewDecFromBigIntWithPrec(big.NewInt(500000), sdk.Precision))))
   263  	addr1, priv1 := newTestAddrKey()
   264  	addr2, _ := newTestAddrKey()
   265  
   266  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr1)
   267  	_ = acc.SetCoins(newTestCoins())
   268  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   269  
   270  	// require a valid Ethereum tx to pass
   271  	to := ethcmn.BytesToAddress(addr2.Bytes())
   272  	amt := big.NewInt(32)
   273  	gas := big.NewInt(20)
   274  	ethMsg := evmtypes.NewMsgEthereumTx(0, &to, amt, 22000, gas, []byte("payload"))
   275  
   276  	tx, err := newTestEthTx(suite.ctx, ethMsg, priv1)
   277  	suite.Require().NoError(err)
   278  	requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, tx, false)
   279  }
   280  
   281  // TestCase represents a test case used in test tables.
   282  type TestCase struct {
   283  	desc     string
   284  	simulate bool
   285  	expPass  bool
   286  }
   287  
   288  func (suite *AnteTestSuite) TestAnteHandlerSequences() {
   289  	addr, priv := newTestAddrKey()
   290  	acc := suite.app.AccountKeeper.NewAccountWithAddress(suite.ctx, addr)
   291  	_ = acc.SetCoins(newTestCoins())
   292  	suite.app.AccountKeeper.SetAccount(suite.ctx, acc)
   293  
   294  	testCases := []TestCase{
   295  		{
   296  			"good ibctx with right sequence",
   297  			false,
   298  			true,
   299  		},
   300  		{
   301  			"bad ibctx with wrong sequence (replay protected)",
   302  			false,
   303  			false,
   304  		},
   305  	}
   306  	ibcTx := mockIbcTx([]uint64{acc.GetAccountNumber()}, []uint64{acc.GetSequence()}, priv, suite.ctx.ChainID(), addr)
   307  	suite.Require().NotNil(ibcTx)
   308  	for _, tc := range testCases {
   309  		suite.Run(fmt.Sprintf("Case %s", tc.desc), func() {
   310  			if tc.expPass {
   311  				requireValidTx(suite.T(), suite.anteHandler, suite.ctx, *ibcTx, false)
   312  			} else {
   313  				requireInvalidTx(suite.T(), suite.anteHandler, suite.ctx, *ibcTx, false)
   314  			}
   315  		})
   316  	}
   317  }