[ENG-680]: Enforcing auction txs to have timeouts (#52)

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
David Terpay 2023-04-10 12:19:25 -04:00 committed by GitHub
parent 89d111aa43
commit fe35a9eeb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 20 deletions

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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)

View File

@ -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

View File

@ -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)
}