diff --git a/abci/abci_test.go b/abci/abci_test.go index de46bb9..0e551c2 100644 --- a/abci/abci_test.go +++ b/abci/abci_test.go @@ -155,7 +155,7 @@ func (suite *ABCITestSuite) createFilledMempool(numNormalTxs, numAuctionTxs, num randomMsgs := testutils.CreateRandomMsgs(acc.Address, 3) nonce := suite.nonces[acc.Address.String()] - randomTx, err := testutils.CreateTx(suite.encodingConfig.TxConfig, acc, nonce, randomMsgs) + randomTx, err := testutils.CreateTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, randomMsgs) suite.Require().NoError(err) suite.nonces[acc.Address.String()]++ @@ -180,7 +180,7 @@ func (suite *ABCITestSuite) createFilledMempool(numNormalTxs, numAuctionTxs, num // create the auction tx nonce = suite.nonces[acc.Address.String()] - auctionTx, err := testutils.CreateTx(suite.encodingConfig.TxConfig, acc, nonce, []sdk.Msg{bidMsg}) + auctionTx, err := testutils.CreateTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, []sdk.Msg{bidMsg}) suite.Require().NoError(err) // insert the auction tx into the global mempool @@ -689,7 +689,7 @@ func (suite *ABCITestSuite) TestProcessProposal() { bidder := suite.accounts[0] bid := sdk.NewCoin("foo", sdk.NewInt(696969696969)) nonce := suite.nonces[bidder.Address.String()] - frontRunningTx, _ = testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, suite.accounts[0], bid, nonce+1, []testutils.Account{bidder, randomAccount}) + frontRunningTx, _ = testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, suite.accounts[0], bid, nonce+1, 1000, []testutils.Account{bidder, randomAccount}) suite.Require().NotNil(frontRunningTx) numNormalTxs = 100 @@ -708,7 +708,7 @@ func (suite *ABCITestSuite) TestProcessProposal() { bidder := suite.accounts[0] bid := sdk.NewCoin("foo", sdk.NewInt(696969696969)) nonce := suite.nonces[bidder.Address.String()] - frontRunningTx, _ = testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, suite.accounts[0], bid, nonce+1, []testutils.Account{bidder, randomAccount}) + frontRunningTx, _ = testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, suite.accounts[0], bid, nonce+1, 1000, []testutils.Account{bidder, randomAccount}) suite.Require().NotNil(frontRunningTx) numAuctionTxs = 0 diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 411859f..cf1c079 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -58,7 +58,7 @@ func (suite *IntegrationTestSuite) CreateFilledMempool(numNormalTxs, numAuctionT acc := suite.accounts[randomIndex] nonce := suite.nonces[acc.Address.String()] randomMsgs := testutils.CreateRandomMsgs(acc.Address, 3) - randomTx, err := testutils.CreateTx(suite.encCfg.TxConfig, acc, nonce, randomMsgs) + randomTx, err := testutils.CreateTx(suite.encCfg.TxConfig, acc, nonce, 100, randomMsgs) suite.Require().NoError(err) suite.nonces[acc.Address.String()]++ @@ -84,7 +84,7 @@ func (suite *IntegrationTestSuite) CreateFilledMempool(numNormalTxs, numAuctionT // create the auction tx nonce = suite.nonces[acc.Address.String()] - auctionTx, err := testutils.CreateTx(suite.encCfg.TxConfig, acc, nonce, []sdk.Msg{bidMsg}) + auctionTx, err := testutils.CreateTx(suite.encCfg.TxConfig, acc, nonce, 1000, []sdk.Msg{bidMsg}) suite.Require().NoError(err) // insert the auction tx into the global mempool diff --git a/testutils/utils.go b/testutils/utils.go index ba4eb03..cea9413 100644 --- a/testutils/utils.go +++ b/testutils/utils.go @@ -71,7 +71,7 @@ func RandomAccounts(r *rand.Rand, n int) []Account { return accs } -func CreateTx(txCfg client.TxConfig, account Account, nonce uint64, msgs []sdk.Msg) (authsigning.Tx, error) { +func CreateTx(txCfg client.TxConfig, account Account, nonce, timeout uint64, msgs []sdk.Msg) (authsigning.Tx, error) { txBuilder := txCfg.NewTxBuilder() if err := txBuilder.SetMsgs(msgs...); err != nil { return nil, err @@ -89,10 +89,12 @@ func CreateTx(txCfg client.TxConfig, account Account, nonce uint64, msgs []sdk.M return nil, err } + txBuilder.SetTimeoutHeight(timeout) + return txBuilder.GetTx(), nil } -func CreateRandomTx(txCfg client.TxConfig, account Account, nonce, numberMsgs uint64) (authsigning.Tx, error) { +func CreateRandomTx(txCfg client.TxConfig, account Account, nonce, numberMsgs, timeout uint64) (authsigning.Tx, error) { msgs := make([]sdk.Msg, numberMsgs) for i := 0; i < int(numberMsgs); i++ { msgs[i] = &banktypes.MsgSend{ @@ -118,10 +120,12 @@ func CreateRandomTx(txCfg client.TxConfig, account Account, nonce, numberMsgs ui return nil, err } + txBuilder.SetTimeoutHeight(timeout) + return txBuilder.GetTx(), nil } -func CreateAuctionTxWithSigners(txCfg client.TxConfig, bidder Account, bid sdk.Coin, nonce uint64, signers []Account) (authsigning.Tx, error) { +func CreateAuctionTxWithSigners(txCfg client.TxConfig, bidder Account, bid sdk.Coin, nonce, timeout uint64, signers []Account) (authsigning.Tx, error) { bidMsg := &buildertypes.MsgAuctionBid{ Bidder: bidder.Address.String(), Bid: bid, @@ -130,7 +134,7 @@ func CreateAuctionTxWithSigners(txCfg client.TxConfig, bidder Account, bid sdk.C for i := 0; i < len(signers); i++ { randomMsg := CreateRandomMsgs(signers[i].Address, 1) - randomTx, err := CreateTx(txCfg, signers[i], 0, randomMsg) + randomTx, err := CreateTx(txCfg, signers[i], 0, timeout, randomMsg) if err != nil { return nil, err } @@ -160,6 +164,8 @@ func CreateAuctionTxWithSigners(txCfg client.TxConfig, bidder Account, bid sdk.C return nil, err } + txBuilder.SetTimeoutHeight(timeout) + return txBuilder.GetTx(), nil } diff --git a/x/builder/ante/ante.go b/x/builder/ante/ante.go index 1998876..d0e169d 100644 --- a/x/builder/ante/ante.go +++ b/x/builder/ante/ante.go @@ -2,6 +2,7 @@ package ante import ( "bytes" + "fmt" "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,12 +12,20 @@ import ( var _ sdk.AnteDecorator = BuilderDecorator{} -type BuilderDecorator struct { - builderKeeper keeper.Keeper - txDecoder sdk.TxDecoder - txEncoder sdk.TxEncoder - mempool *mempool.AuctionMempool -} +type ( + BuilderDecorator struct { + builderKeeper keeper.Keeper + txDecoder sdk.TxDecoder + txEncoder sdk.TxEncoder + mempool *mempool.AuctionMempool + } + + TxWithTimeoutHeight interface { + sdk.Tx + + GetTimeoutHeight() uint64 + } +) func NewBuilderDecorator(ak keeper.Keeper, txDecoder sdk.TxDecoder, txEncoder sdk.TxEncoder, mempool *mempool.AuctionMempool) BuilderDecorator { return BuilderDecorator{ @@ -37,6 +46,16 @@ func (ad BuilderDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, // Validate the auction bid if one exists. if auctionMsg != nil { + auctionTx, ok := tx.(TxWithTimeoutHeight) + if !ok { + return ctx, fmt.Errorf("transaction does not implement TxWithTimeoutHeight") + } + + timeout := auctionTx.GetTimeoutHeight() + if timeout == 0 { + return ctx, fmt.Errorf("timeout height cannot be zero") + } + bidder, err := sdk.AccAddressFromBech32(auctionMsg.Bidder) if err != nil { return ctx, errors.Wrapf(err, "invalid bidder address (%s)", auctionMsg.Bidder) diff --git a/x/builder/ante/ante_test.go b/x/builder/ante/ante_test.go index da7c281..5838306 100644 --- a/x/builder/ante/ante_test.go +++ b/x/builder/ante/ante_test.go @@ -92,6 +92,7 @@ func (suite *AnteTestSuite) TestAnteHandler() { topBidder = testutils.RandomAccounts(suite.random, 1)[0] topBid = sdk.NewCoin("foo", sdk.NewInt(100)) insertTopBid = true + timeout = uint64(1000) // Auction setup maxBundleSize uint32 = 5 @@ -158,9 +159,17 @@ func (suite *AnteTestSuite) TestAnteHandler() { }, true, }, + { + "invalid auction bid tx with no timeout", + func() { + timeout = 0 + }, + false, + }, { "auction tx is the top bidding tx", func() { + timeout = 1000 balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000))) bid = sdk.NewCoin("foo", sdk.NewInt(1000)) reserveFee = sdk.NewCoin("foo", sdk.NewInt(100)) @@ -237,7 +246,7 @@ func (suite *AnteTestSuite) TestAnteHandler() { // Insert the top bid into the mempool mempool := mempool.NewAuctionMempool(suite.encodingConfig.TxConfig.TxDecoder(), 0) if insertTopBid { - topAuctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, topBidder, topBid, 0, []testutils.Account{}) + topAuctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, topBidder, topBid, 0, timeout, []testutils.Account{}) suite.Require().NoError(err) suite.Require().Equal(0, mempool.CountTx()) suite.Require().Equal(0, mempool.CountAuctionTx()) @@ -247,7 +256,7 @@ func (suite *AnteTestSuite) TestAnteHandler() { } // Create the actual auction tx and insert into the mempool - auctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, bidder, bid, 0, signers) + auctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, bidder, bid, 0, timeout, signers) suite.Require().NoError(err) // Execute the ante handler diff --git a/x/builder/keeper/auction_test.go b/x/builder/keeper/auction_test.go index a7e46dc..a14821f 100644 --- a/x/builder/keeper/auction_test.go +++ b/x/builder/keeper/auction_test.go @@ -183,7 +183,7 @@ func (suite *KeeperTestSuite) TestValidateAuctionMsg() { // Create the bundle of transactions ordered by accounts bundle := make([]sdk.Tx, 0) for _, acc := range accounts { - tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, acc, 0, 1) + tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, acc, 0, 1, 100) suite.Require().NoError(err) bundle = append(bundle, tx) } @@ -293,7 +293,7 @@ func (suite *KeeperTestSuite) TestValidateBundle() { bundle := make([]sdk.Tx, 0) for _, acc := range accounts { // Create a random tx - tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, acc, 0, 1) + tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, acc, 0, 1, 1000) suite.Require().NoError(err) bundle = append(bundle, tx) }