@@ -10,6 +10,7 @@ import (
1010
1111 dbm "github.com/cometbft/cometbft-db"
1212 abci "github.com/cometbft/cometbft/abci/types"
13+ cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
1314 tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
1415 "github.com/cosmos/gogoproto/jsonpb"
1516 "github.com/stretchr/testify/require"
@@ -1693,3 +1694,97 @@ func TestABCI_Proposal_Reset_State_Between_Calls(t *testing.T) {
16931694 Header : tmproto.Header {Height : suite .baseApp .LastBlockHeight () + 1 },
16941695 })
16951696}
1697+
1698+ func TestABCI_Proposal_FailReCheckTx (t * testing.T ) {
1699+ pool := mempool .NewSenderNonceMempool ()
1700+
1701+ anteOpt := func (bapp * baseapp.BaseApp ) {
1702+ bapp .SetAnteHandler (func (ctx sdk.Context , tx sdk.Tx , simulate bool ) (sdk.Context , error ) {
1703+ // always fail on recheck, just to test the recheck logic
1704+ if ctx .IsReCheckTx () {
1705+ return ctx , errors .New ("recheck failed in ante handler" )
1706+ }
1707+
1708+ return ctx , nil
1709+ })
1710+ }
1711+
1712+ suite := NewBaseAppSuite (t , anteOpt , baseapp .SetMempool (pool ))
1713+ baseapptestutil .RegisterKeyValueServer (suite .baseApp .MsgServiceRouter (), MsgKeyValueImpl {})
1714+ baseapptestutil .RegisterCounterServer (suite .baseApp .MsgServiceRouter (), NoopCounterServerImpl {})
1715+
1716+ suite .baseApp .InitChain (abci.RequestInitChain {
1717+ ConsensusParams : & cmtproto.ConsensusParams {},
1718+ })
1719+
1720+ tx := newTxCounter (t , suite .txConfig , 0 , 1 )
1721+ txBytes , err := suite .txConfig .TxEncoder ()(tx )
1722+ require .NoError (t , err )
1723+
1724+ reqCheckTx := abci.RequestCheckTx {
1725+ Tx : txBytes ,
1726+ Type : abci .CheckTxType_New ,
1727+ }
1728+ _ = suite .baseApp .CheckTx (reqCheckTx )
1729+
1730+ tx2 := newTxCounter (t , suite .txConfig , 1 , 1 )
1731+
1732+ tx2Bytes , err := suite .txConfig .TxEncoder ()(tx2 )
1733+ require .NoError (t , err )
1734+
1735+ err = pool .Insert (sdk.Context {}, tx2 )
1736+ require .NoError (t , err )
1737+
1738+ require .Equal (t , 2 , pool .CountTx ())
1739+
1740+ // call prepareProposal before calling recheck tx, just as a sanity check
1741+ reqPrepareProposal := abci.RequestPrepareProposal {
1742+ MaxTxBytes : 1000 ,
1743+ Height : 1 ,
1744+ }
1745+ resPrepareProposal := suite .baseApp .PrepareProposal (reqPrepareProposal )
1746+ require .Equal (t , 2 , len (resPrepareProposal .Txs ))
1747+
1748+ // call recheck on the first tx, it MUST return an error
1749+ reqReCheckTx := abci.RequestCheckTx {
1750+ Tx : txBytes ,
1751+ Type : abci .CheckTxType_Recheck ,
1752+ }
1753+ resp := suite .baseApp .CheckTx (reqReCheckTx )
1754+
1755+ require .True (t , resp .IsErr ())
1756+ require .Equal (t , "recheck failed in ante handler" , resp .Log )
1757+
1758+ // call prepareProposal again, should return only the second tx
1759+ resPrepareProposal = suite .baseApp .PrepareProposal (reqPrepareProposal )
1760+ require .Equal (t , 1 , len (resPrepareProposal .Txs ))
1761+ require .Equal (t , tx2Bytes , resPrepareProposal .Txs [0 ])
1762+
1763+ // check the mempool, it should have only the second tx
1764+ require .Equal (t , 1 , pool .CountTx ())
1765+
1766+ reqProposalTxBytes := tx2Bytes
1767+
1768+ reqProcessProposal := abci.RequestProcessProposal {
1769+ Txs : [][]byte {reqProposalTxBytes },
1770+ Height : reqPrepareProposal .Height ,
1771+ }
1772+
1773+ resProcessProposal := suite .baseApp .ProcessProposal (reqProcessProposal )
1774+ require .Equal (t , abci .ResponseProcessProposal_ACCEPT , resProcessProposal .Status )
1775+
1776+ suite .baseApp .BeginBlock (abci.RequestBeginBlock {
1777+ Header : tmproto.Header {Height : suite .baseApp .LastBlockHeight () + 1 },
1778+ })
1779+
1780+ // the same txs as in PrepareProposal
1781+ res := suite .baseApp .DeliverTx (abci.RequestDeliverTx {
1782+ Tx : reqProposalTxBytes ,
1783+ })
1784+ require .NoError (t , err )
1785+
1786+ require .Equal (t , 0 , pool .CountTx ())
1787+
1788+ require .NotEmpty (t , res .Events )
1789+ require .True (t , res .IsOK (), fmt .Sprintf ("%v" , res ))
1790+ }
0 commit comments