feat(MEV): Updating MEV Lane with Testing + Cleaner Implementation (#134)
* updating mev lane with cleaner impl * nit * lint
This commit is contained in:
parent
b9d6761776
commit
d495b38954
@ -24,7 +24,6 @@ func ChainPrepareLanes(chain []block.Lane) block.PrepareLanesHandler {
|
||||
|
||||
return func(ctx sdk.Context, partialProposal proposals.Proposal) (finalProposal proposals.Proposal, err error) {
|
||||
lane := chain[0]
|
||||
lane.Logger().Info("preparing lane", "lane", lane.Name())
|
||||
|
||||
// Cache the context in the case where any of the lanes fail to prepare the proposal.
|
||||
cacheCtx, write := ctx.CacheContext()
|
||||
@ -35,9 +34,6 @@ func ChainPrepareLanes(chain []block.Lane) block.PrepareLanesHandler {
|
||||
// and call the next lane in the chain to the prepare the proposal.
|
||||
defer func() {
|
||||
if rec := recover(); rec != nil || err != nil {
|
||||
lane.Logger().Error("failed to prepare lane", "lane", lane.Name(), "err", err, "recover_error", rec)
|
||||
lane.Logger().Info("skipping lane", "lane", lane.Name())
|
||||
|
||||
if len(chain) <= 2 {
|
||||
// If there are only two lanes remaining, then the first lane in the chain
|
||||
// is the lane that failed to prepare the partial proposal and the second lane in the
|
||||
@ -85,9 +81,6 @@ func ChainProcessLanes(partialProposals [][][]byte, chain []block.Lane) block.Pr
|
||||
return func(ctx sdk.Context, proposal proposals.Proposal) (proposals.Proposal, error) {
|
||||
lane := chain[0]
|
||||
partialProposal := partialProposals[0]
|
||||
|
||||
lane.Logger().Info("processing lane", "lane", chain[0].Name())
|
||||
|
||||
return lane.ProcessLane(ctx, proposal, partialProposal, ChainProcessLanes(partialProposals[1:], chain[1:]))
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,12 +17,19 @@ func (l *BaseLane) PrepareLane(
|
||||
proposal proposals.Proposal,
|
||||
next block.PrepareLanesHandler,
|
||||
) (proposals.Proposal, error) {
|
||||
limit := proposal.GetLaneLimits(l.cfg.MaxBlockSpace)
|
||||
l.Logger().Info("preparing lane", "lane", l.Name())
|
||||
|
||||
// Select transactions from the lane respecting the selection logic of the lane and the
|
||||
// max block space for the lane.
|
||||
limit := proposal.GetLaneLimits(l.cfg.MaxBlockSpace)
|
||||
txsToInclude, txsToRemove, err := l.prepareLaneHandler(ctx, proposal, limit)
|
||||
if err != nil {
|
||||
l.Logger().Error(
|
||||
"failed to prepare lane",
|
||||
"lane", l.Name(),
|
||||
"err", err,
|
||||
)
|
||||
|
||||
return proposal, err
|
||||
}
|
||||
|
||||
@ -68,6 +75,8 @@ func (l *BaseLane) ProcessLane(
|
||||
txs [][]byte,
|
||||
next block.ProcessLanesHandler,
|
||||
) (proposals.Proposal, error) {
|
||||
l.Logger().Info("processing lane", "lane", l.Name(), "num_txs_to_verify", len(txs))
|
||||
|
||||
// Assume that this lane is processing sdk.Tx's and decode the transactions.
|
||||
decodedTxs, err := utils.GetDecodedTxs(l.TxDecoder(), txs)
|
||||
if err != nil {
|
||||
@ -82,6 +91,13 @@ func (l *BaseLane) ProcessLane(
|
||||
|
||||
// Verify the transactions that belong to this lane according to the verification logic of the lane.
|
||||
if err := l.processLaneHandler(ctx, decodedTxs); err != nil {
|
||||
l.Logger().Error(
|
||||
"failed to process lane",
|
||||
"lane", l.Name(),
|
||||
"err", err,
|
||||
"num_txs_to_verify", len(decodedTxs),
|
||||
)
|
||||
|
||||
return proposal, err
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package block
|
||||
|
||||
import (
|
||||
"cosmossdk.io/log"
|
||||
"cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
@ -57,9 +56,6 @@ type Lane interface {
|
||||
// GetMaxBlockSpace returns the max block space for the lane as a relative percentage.
|
||||
GetMaxBlockSpace() math.LegacyDec
|
||||
|
||||
// Logger returns the lane's logger.
|
||||
Logger() log.Logger
|
||||
|
||||
// Name returns the name of the lane.
|
||||
Name() string
|
||||
|
||||
|
||||
@ -7,8 +7,6 @@ import (
|
||||
|
||||
block "github.com/skip-mev/block-sdk/block"
|
||||
|
||||
log "cosmossdk.io/log"
|
||||
|
||||
math "cosmossdk.io/math"
|
||||
|
||||
mempool "github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
@ -95,22 +93,6 @@ func (_m *Lane) Insert(_a0 context.Context, _a1 types.Tx) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Logger provides a mock function with given fields:
|
||||
func (_m *Lane) Logger() log.Logger {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 log.Logger
|
||||
if rf, ok := ret.Get(0).(func() log.Logger); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(log.Logger)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Match provides a mock function with given fields: ctx, tx
|
||||
func (_m *Lane) Match(ctx types.Context, tx types.Tx) bool {
|
||||
ret := _m.Called(ctx, tx)
|
||||
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"github.com/skip-mev/block-sdk/block/base"
|
||||
"github.com/skip-mev/block-sdk/block/proposals"
|
||||
"github.com/skip-mev/block-sdk/block/utils"
|
||||
"github.com/skip-mev/block-sdk/x/auction/types"
|
||||
)
|
||||
|
||||
// PrepareLaneHandler will attempt to select the highest bid transaction that is valid
|
||||
@ -26,148 +25,36 @@ func (l *MEVLane) PrepareLaneHandler() base.PrepareLaneHandler {
|
||||
|
||||
// Attempt to select the highest bid transaction that is valid and whose
|
||||
// bundled transactions are valid.
|
||||
bidTxIterator := l.Select(ctx, nil)
|
||||
selectBidTxLoop:
|
||||
for ; bidTxIterator != nil; bidTxIterator = bidTxIterator.Next() {
|
||||
for iterator := l.Select(ctx, nil); iterator != nil; iterator = iterator.Next() {
|
||||
bidTx := iterator.Tx()
|
||||
|
||||
if !l.Match(ctx, bidTx) {
|
||||
l.Logger().Info("failed to select auction bid tx for lane; tx does not match lane")
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue
|
||||
}
|
||||
|
||||
bundle, err := l.VerifyBidBasic(bidTx, proposal, limit)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx is invalid",
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue
|
||||
}
|
||||
|
||||
cacheCtx, write := ctx.CacheContext()
|
||||
bidTx := bidTxIterator.Tx()
|
||||
|
||||
txInfo, err := utils.GetTxInfo(l.TxEncoder(), bidTx)
|
||||
if err != nil {
|
||||
l.Logger().Info("failed to get hash of auction bid tx", "err", err)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// if the transaction is already in the (partial) block proposal, we skip it.
|
||||
//
|
||||
// TODO: Should we really be panic'ing here?
|
||||
if proposal.Contains(txInfo.Hash) {
|
||||
if err := l.VerifyBidTx(cacheCtx, bidTx, bundle); err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx is already in proposal",
|
||||
"tx_hash", txInfo.Hash,
|
||||
)
|
||||
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
if txInfo.Size > limit.MaxTxBytes {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx size is too large",
|
||||
"tx_size", txInfo.Size,
|
||||
"max_size", limit.MaxTxBytes,
|
||||
"tx_hash", txInfo.Hash,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
if txInfo.GasLimit > limit.MaxGasLimit {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx gas limit is too large",
|
||||
"tx_gas_limit", txInfo.GasLimit,
|
||||
"max_gas_limit", limit.MaxGasLimit,
|
||||
"tx_hash", txInfo.Hash,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// Build the partial proposal by selecting the bid transaction and all of
|
||||
// its bundled transactions.
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to get auction bid info",
|
||||
"tx_hash", txInfo.Hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
// Some transactions in the bundle may be malformed or invalid, so we
|
||||
// remove the bid transaction and try the next top bid.
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// Verify the bid transaction and all of its bundled transactions.
|
||||
if err := l.VerifyTx(cacheCtx, bidTx, bidInfo); err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to verify auction bid tx",
|
||||
"tx_hash", txInfo.Hash,
|
||||
"failed to select auction bid tx for lane; tx is invalid",
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// store the bytes of each ref tx as sdk.Tx bytes in order to build a valid proposal
|
||||
gasLimitSum := txInfo.GasLimit
|
||||
bundledTxs := make([]sdk.Tx, len(bidInfo.Transactions))
|
||||
for index, bundledTxBz := range bidInfo.Transactions {
|
||||
bundleTx, err := l.WrapBundleTransaction(bundledTxBz)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to wrap bundled tx",
|
||||
"tx_hash", txInfo.Hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
bundledTxInfo, err := utils.GetTxInfo(l.TxEncoder(), bundleTx)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to get hash of bundled tx",
|
||||
"tx_hash", txInfo.Hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// if the transaction is already in the (partial) block proposal, we skip it.
|
||||
if proposal.Contains(bundledTxInfo.Hash) {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx is already in proposal",
|
||||
"tx_hash", bundledTxInfo.Hash,
|
||||
)
|
||||
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// If the bundled transaction is a bid transaction, we skip it.
|
||||
if l.Match(ctx, bundleTx) {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; bundled tx is another bid transaction",
|
||||
"tx_hash", bundledTxInfo.Hash,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
if gasLimitSum += bundledTxInfo.GasLimit; gasLimitSum > limit.MaxGasLimit {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx gas limit is too large",
|
||||
"tx_gas_limit", gasLimitSum,
|
||||
"max_gas_limit", limit.MaxGasLimit,
|
||||
"tx_hash", txInfo.Hash,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, bidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
bundleTxBz := make([]byte, bundledTxInfo.Size)
|
||||
copy(bundleTxBz, bundledTxInfo.TxBytes)
|
||||
bundledTxs[index] = bundleTx
|
||||
continue
|
||||
}
|
||||
|
||||
// At this point, both the bid transaction itself and all the bundled
|
||||
@ -175,13 +62,13 @@ func (l *MEVLane) PrepareLaneHandler() base.PrepareLaneHandler {
|
||||
// all the bundled transactions. We also mark these transactions as seen and
|
||||
// update the total size selected thus far.
|
||||
txsToInclude = append(txsToInclude, bidTx)
|
||||
txsToInclude = append(txsToInclude, bundledTxs...)
|
||||
txsToInclude = append(txsToInclude, bundle...)
|
||||
|
||||
// Write the cache context to the original context when we know we have a
|
||||
// valid bundle.
|
||||
write()
|
||||
|
||||
break selectBidTxLoop
|
||||
break
|
||||
}
|
||||
|
||||
return txsToInclude, txsToRemove, nil
|
||||
@ -213,6 +100,10 @@ func (l *MEVLane) ProcessLaneHandler() base.ProcessLaneHandler {
|
||||
return fmt.Errorf("failed to get bid info from auction bid tx for lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if bidInfo == nil {
|
||||
return fmt.Errorf("bid info is nil")
|
||||
}
|
||||
|
||||
// Check that all bundled transactions were included.
|
||||
if len(bidInfo.Transactions)+1 != len(partialProposal) {
|
||||
return fmt.Errorf(
|
||||
@ -223,46 +114,118 @@ func (l *MEVLane) ProcessLaneHandler() base.ProcessLaneHandler {
|
||||
)
|
||||
}
|
||||
|
||||
// Verify the top-level bid transaction.
|
||||
if ctx, err = l.AnteVerifyTx(ctx, bidTx, false); err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to execute ante handler: %w", err)
|
||||
}
|
||||
|
||||
// Verify all of the bundled transactions.
|
||||
// Ensure the transactions in the proposal match the bundled transactions in the bid transaction.
|
||||
bundle := partialProposal[1:]
|
||||
for index, bundledTxBz := range bidInfo.Transactions {
|
||||
bundledTx, err := l.WrapBundleTransaction(bundledTxBz)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to decode bundled tx: %w", err)
|
||||
}
|
||||
|
||||
txBz, err := l.TxEncoder()(partialProposal[index+1])
|
||||
expectedTxBz, err := l.TxEncoder()(bundledTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to encode bundled tx: %w", err)
|
||||
}
|
||||
|
||||
actualTxBz, err := l.TxEncoder()(bundle[index])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to encode tx: %w", err)
|
||||
}
|
||||
|
||||
// Verify that the bundled transaction matches the transaction in the block proposal.
|
||||
if !bytes.Equal(bundledTxBz, txBz) {
|
||||
if !bytes.Equal(actualTxBz, expectedTxBz) {
|
||||
return fmt.Errorf("invalid bid tx; bundled tx does not match tx in block proposal")
|
||||
}
|
||||
}
|
||||
|
||||
// Verify this is not another bid transaction.
|
||||
if l.Match(ctx, bundledTx) {
|
||||
return fmt.Errorf("invalid bid tx; bundled tx is another bid transaction")
|
||||
}
|
||||
|
||||
if ctx, err = l.AnteVerifyTx(ctx, bundledTx, false); err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to execute bundled transaction: %w", err)
|
||||
}
|
||||
// Verify the top-level bid transaction.
|
||||
if err := l.VerifyBidTx(ctx, bidTx, bundle); err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to verify bid tx: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyTx will verify that the bid transaction and all of its bundled
|
||||
// transactions are valid. It will return an error if any of the transactions
|
||||
// are invalid.
|
||||
func (l *MEVLane) VerifyTx(ctx sdk.Context, bidTx sdk.Tx, bidInfo *types.BidInfo) (err error) {
|
||||
// VerifyBidBasic will verify that the bid transaction and all of its bundled
|
||||
// transactions respect the basic invariants of the lane (e.g. size, gas limit).
|
||||
func (l *MEVLane) VerifyBidBasic(
|
||||
bidTx sdk.Tx,
|
||||
proposal proposals.Proposal,
|
||||
limit proposals.LaneLimits,
|
||||
) ([]sdk.Tx, error) {
|
||||
// Verify the transaction is a bid transaction.
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get bid info from auction bid tx for lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if bidInfo == nil {
|
||||
return nil, fmt.Errorf("bid info is nil")
|
||||
}
|
||||
|
||||
txInfo, err := utils.GetTxInfo(l.TxEncoder(), bidTx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("err retrieving transaction info: %s", err)
|
||||
}
|
||||
|
||||
// This should never happen, but we check just in case.
|
||||
if proposal.Contains(txInfo.Hash) {
|
||||
return nil, fmt.Errorf("invalid bid tx; bid tx is already in the proposal")
|
||||
}
|
||||
|
||||
totalSize := txInfo.Size
|
||||
totalGasLimit := txInfo.GasLimit
|
||||
bundle := make([]sdk.Tx, len(bidInfo.Transactions))
|
||||
|
||||
// Verify size and gas limit of the bundled transactions.
|
||||
for index, bundledTxBz := range bidInfo.Transactions {
|
||||
bundledTx, err := l.WrapBundleTransaction(bundledTxBz)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid bid tx; failed to decode bundled tx: %w", err)
|
||||
}
|
||||
|
||||
bundledTxInfo, err := utils.GetTxInfo(l.TxEncoder(), bundledTx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("err retrieving transaction info: %s", err)
|
||||
}
|
||||
|
||||
if proposal.Contains(bundledTxInfo.Hash) {
|
||||
return nil, fmt.Errorf("invalid bid tx; bundled tx is already in the proposal")
|
||||
}
|
||||
|
||||
totalSize += bundledTxInfo.Size
|
||||
totalGasLimit += bundledTxInfo.GasLimit
|
||||
bundle[index] = bundledTx
|
||||
}
|
||||
|
||||
if totalSize > limit.MaxTxBytes {
|
||||
return nil, fmt.Errorf(
|
||||
"partial proposal is too large: %d > %d",
|
||||
totalSize,
|
||||
limit.MaxTxBytes,
|
||||
)
|
||||
}
|
||||
|
||||
if totalGasLimit > limit.MaxGasLimit {
|
||||
return nil, fmt.Errorf(
|
||||
"partial proposal consumes too much gas: %d > %d",
|
||||
totalGasLimit,
|
||||
limit.MaxGasLimit,
|
||||
)
|
||||
}
|
||||
|
||||
return bundle, nil
|
||||
}
|
||||
|
||||
// VerifyBidTx will verify that the bid transaction and all of its bundled
|
||||
// transactions are valid.
|
||||
func (l *MEVLane) VerifyBidTx(ctx sdk.Context, bidTx sdk.Tx, bundle []sdk.Tx) error {
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get bid info from auction bid tx for lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if bidInfo == nil {
|
||||
return fmt.Errorf("bid info is nil")
|
||||
}
|
||||
@ -273,10 +236,9 @@ func (l *MEVLane) VerifyTx(ctx sdk.Context, bidTx sdk.Tx, bidInfo *types.BidInfo
|
||||
}
|
||||
|
||||
// verify all of the bundled transactions
|
||||
for _, tx := range bidInfo.Transactions {
|
||||
bundledTx, err := l.WrapBundleTransaction(tx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to decode bundled tx: %w", err)
|
||||
for _, bundledTx := range bundle {
|
||||
if l.Match(ctx, bundledTx) {
|
||||
return fmt.Errorf("invalid bid tx; bundled tx is another bid transaction")
|
||||
}
|
||||
|
||||
if ctx, err = l.AnteVerifyTx(ctx, bundledTx, false); err != nil {
|
||||
|
||||
598
lanes/mev/abci_test.go
Normal file
598
lanes/mev/abci_test.go
Normal file
@ -0,0 +1,598 @@
|
||||
package mev_test
|
||||
|
||||
import (
|
||||
"cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/skip-mev/block-sdk/block"
|
||||
"github.com/skip-mev/block-sdk/block/proposals"
|
||||
"github.com/skip-mev/block-sdk/block/utils"
|
||||
testutils "github.com/skip-mev/block-sdk/testutils"
|
||||
)
|
||||
|
||||
func (s *MEVTestSuite) TestPrepareLane() {
|
||||
s.Run("can prepare a lane with no txs in mempool", func() {
|
||||
lane := s.initLane(math.LegacyOneDec(), nil)
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200, 100)
|
||||
|
||||
proposal, err := lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(0, len(proposal.Txs))
|
||||
s.Require().Equal(0, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(int64(0), proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(0), proposal.Info.GasLimit)
|
||||
})
|
||||
|
||||
s.Run("can prepare a lane with a single bid tx in mempool", func() {
|
||||
bidTx, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
size := s.getTxSize(bidTx)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true})
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx))
|
||||
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200, 100)
|
||||
|
||||
proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(proposal.Txs))
|
||||
s.Require().Equal(1, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(size, proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(100), proposal.Info.GasLimit)
|
||||
|
||||
expectedProposal := []sdk.Tx{bidTx}
|
||||
txBzs, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), expectedProposal)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(txBzs[0], proposal.Txs[0])
|
||||
})
|
||||
|
||||
s.Run("can prepare a lane with multiple bid txs where highest bid fails", func() {
|
||||
bidTx1, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
bidTx2, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[1],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(200)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx1: true, bidTx2: false})
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx1))
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx2))
|
||||
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 20000, 100000)
|
||||
|
||||
proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(proposal.Txs))
|
||||
s.Require().Equal(1, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(s.getTxSize(bidTx1), proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(100), proposal.Info.GasLimit)
|
||||
|
||||
expectedProposal := []sdk.Tx{bidTx1}
|
||||
txBzs, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), expectedProposal)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(txBzs[0], proposal.Txs[0])
|
||||
})
|
||||
|
||||
s.Run("can prepare a lane with multiple bid txs where highest bid passes", func() {
|
||||
bidTx1, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
bidTx2, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[1],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(200)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx1: false, bidTx2: true})
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx1))
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx2))
|
||||
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 20000, 100000)
|
||||
|
||||
proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(1, len(proposal.Txs))
|
||||
s.Require().Equal(1, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(s.getTxSize(bidTx2), proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(100), proposal.Info.GasLimit)
|
||||
|
||||
expectedProposal := []sdk.Tx{bidTx2}
|
||||
txBzs, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), expectedProposal)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(txBzs[0], proposal.Txs[0])
|
||||
})
|
||||
|
||||
s.Run("can build a proposal with bid tx that has a bundle", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true})
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx))
|
||||
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 20000, 100000)
|
||||
|
||||
proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(3, len(proposal.Txs))
|
||||
s.Require().Equal(1, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(uint64(3), proposal.Info.TxsByLane[lane.Name()])
|
||||
s.Require().Equal(s.getTxSize(bidTx)+s.getTxSize(bundle[0])+s.getTxSize(bundle[1]), proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(100), proposal.Info.GasLimit)
|
||||
|
||||
expectedProposal := []sdk.Tx{bidTx, bundle[0], bundle[1]}
|
||||
txBzs, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), expectedProposal)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(txBzs, proposal.Txs)
|
||||
})
|
||||
|
||||
s.Run("can reject a bid that is too large", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(200)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true})
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx))
|
||||
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), s.getTxSize(bidTx), 100000)
|
||||
|
||||
proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(0, len(proposal.Txs))
|
||||
s.Require().Equal(0, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(int64(0), proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(0), proposal.Info.GasLimit)
|
||||
})
|
||||
|
||||
s.Run("can reject a bid that is too gas intensive", func() {
|
||||
bidTx, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(200)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true})
|
||||
s.Require().NoError(lane.Insert(s.ctx, bidTx))
|
||||
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), s.getTxSize(bidTx), 99)
|
||||
|
||||
proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(0, len(proposal.Txs))
|
||||
s.Require().Equal(0, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(int64(0), proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(0), proposal.Info.GasLimit)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *MEVTestSuite) TestProcessLane() {
|
||||
s.Run("can process an empty proposal", func() {
|
||||
lane := s.initLane(math.LegacyOneDec(), nil)
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200, 100)
|
||||
|
||||
proposal, err := lane.ProcessLane(s.ctx, proposal, nil, block.NoOpProcessLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(0, len(proposal.Txs))
|
||||
s.Require().Equal(0, len(proposal.Info.TxsByLane))
|
||||
s.Require().Equal(int64(0), proposal.Info.BlockSize)
|
||||
s.Require().Equal(uint64(0), proposal.Info.GasLimit)
|
||||
})
|
||||
|
||||
s.Run("can process a proposal with tx that does not belong to this lane", func() {
|
||||
txBz, err := testutils.CreateRandomTxBz(s.encCfg.TxConfig, s.accounts[0], 0, 1, 0, 100)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), nil)
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200, 100)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, [][]byte{txBz}, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can process a proposal with bad bid tx", func() {
|
||||
bidTx, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: false})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200000, 1000000)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can process a proposal with a bad bundled tx", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx, bundle[0], bundle[1]})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: false})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200000, 1000000)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can process a proposal with mismatching txs in bundle", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx, bundle[1], bundle[0]})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200000, 1000000)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can process a proposal with missing bundle tx", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx, bundle[0]})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200000, 1000000)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can process a valid proposal", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx, bundle[0], bundle[1]})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200000, 1000000)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
})
|
||||
|
||||
s.Run("can process a valid proposal with a single bid with no bundle", func() {
|
||||
bidTx, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin("stake", math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200000, 1000000)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().NoError(err)
|
||||
})
|
||||
|
||||
s.Run("can reject a block proposal that exceeds its gas limit", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin("stake", math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx, bundle[0], bundle[1]})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 20000, 99)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can reject a block proposal that exceeds its block size", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin("stake", math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
partialProposal, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), []sdk.Tx{bidTx, bundle[0], bundle[1]})
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true})
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200, 100)
|
||||
|
||||
_, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler())
|
||||
s.Require().Error(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *MEVTestSuite) TestVerifyBidBasic() {
|
||||
lane := s.initLane(math.LegacyOneDec(), nil)
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), 200, 100)
|
||||
limits := proposal.GetLaneLimits(lane.GetMaxBlockSpace())
|
||||
|
||||
s.Run("can verify a bid with no bundled txs", func() {
|
||||
bidTx, expectedBundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
bundle, err := lane.VerifyBidBasic(bidTx, proposal, limits)
|
||||
s.Require().NoError(err)
|
||||
s.compare(bundle, expectedBundle)
|
||||
})
|
||||
|
||||
s.Run("can reject a tx that is not a bid", func() {
|
||||
tx, err := testutils.CreateRandomTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = lane.VerifyBidBasic(tx, proposal, limits)
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can reject a bundle that is too gas intensive", func() {
|
||||
bidTx, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
101,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = lane.VerifyBidBasic(bidTx, proposal, limits)
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can reject a bundle that is too large", func() {
|
||||
bidTx, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
size := s.getTxSize(bidTx)
|
||||
proposal := proposals.NewProposal(s.encCfg.TxConfig.TxEncoder(), size-1, 100)
|
||||
limits := proposal.GetLaneLimits(lane.GetMaxBlockSpace())
|
||||
|
||||
_, err = lane.VerifyBidBasic(bidTx, proposal, limits)
|
||||
s.Require().Error(err)
|
||||
})
|
||||
|
||||
s.Run("can reject a bundle with malformed txs", func() {
|
||||
bidMsg, err := testutils.CreateMsgAuctionBid(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
3,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
bidMsg.Transactions[2] = []byte("invalid")
|
||||
|
||||
bidTx, err := testutils.CreateTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
0,
|
||||
0,
|
||||
[]sdk.Msg{bidMsg},
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = lane.VerifyBidBasic(bidTx, proposal, limits)
|
||||
s.Require().Error(err)
|
||||
})
|
||||
}
|
||||
|
||||
func (s *MEVTestSuite) TestVerifyBidTx() {
|
||||
s.Run("can verify a valid bid", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true})
|
||||
s.Require().NoError(lane.VerifyBidTx(s.ctx, bidTx, bundle))
|
||||
})
|
||||
|
||||
s.Run("can reject a bid transaction", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: false})
|
||||
s.Require().Error(lane.VerifyBidTx(s.ctx, bidTx, bundle))
|
||||
})
|
||||
|
||||
s.Run("can reject a bid transaction with a bad bundle", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: false})
|
||||
s.Require().Error(lane.VerifyBidTx(s.ctx, bidTx, bundle))
|
||||
})
|
||||
|
||||
s.Run("can reject a bid transaction with a bundle that has another bid tx", func() {
|
||||
bidTx, bundle, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
s.accounts[0:2],
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
otherBidTx, _, err := testutils.CreateAuctionTx(
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin(s.gasTokenDenom, math.NewInt(100)),
|
||||
0,
|
||||
0,
|
||||
nil,
|
||||
100,
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
bundle = append(bundle, otherBidTx)
|
||||
|
||||
lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true, otherBidTx: true})
|
||||
s.Require().Error(lane.VerifyBidTx(s.ctx, bidTx, bundle))
|
||||
})
|
||||
}
|
||||
@ -9,7 +9,7 @@ import (
|
||||
testutils "github.com/skip-mev/block-sdk/testutils"
|
||||
)
|
||||
|
||||
func (suite *MEVTestSuite) TestIsAuctionTx() {
|
||||
func (s *MEVTestSuite) TestIsAuctionTx() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
createTx func() sdk.Tx
|
||||
@ -19,8 +19,8 @@ func (suite *MEVTestSuite) TestIsAuctionTx() {
|
||||
{
|
||||
"normal sdk tx",
|
||||
func() sdk.Tx {
|
||||
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 2, 0, 0)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateRandomTx(s.encCfg.TxConfig, s.accounts[0], 0, 2, 0, 0)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
false,
|
||||
@ -29,14 +29,14 @@ func (suite *MEVTestSuite) TestIsAuctionTx() {
|
||||
{
|
||||
"malformed auction bid tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := testutils.CreateRandomMsgs(suite.accounts[0].Address, 2)
|
||||
msgs := testutils.CreateRandomMsgs(s.accounts[0].Address, 2)
|
||||
msgs = append(msgs, msgAuctionBid)
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
false,
|
||||
@ -45,13 +45,13 @@ func (suite *MEVTestSuite) TestIsAuctionTx() {
|
||||
{
|
||||
"valid auction bid tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
true,
|
||||
@ -60,16 +60,16 @@ func (suite *MEVTestSuite) TestIsAuctionTx() {
|
||||
{
|
||||
"tx with multiple MsgAuctionBid messages",
|
||||
func() sdk.Tx {
|
||||
bid1, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
bid1, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
bid2, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 1, 2)
|
||||
suite.Require().NoError(err)
|
||||
bid2, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 1, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{bid1, bid2}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
false,
|
||||
@ -78,22 +78,22 @@ func (suite *MEVTestSuite) TestIsAuctionTx() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
s.Run(tc.name, func() {
|
||||
tx := tc.createTx()
|
||||
|
||||
bidInfo, err := suite.config.GetAuctionBidInfo(tx)
|
||||
bidInfo, err := s.config.GetAuctionBidInfo(tx)
|
||||
|
||||
suite.Require().Equal(tc.isAuctionTx, bidInfo != nil)
|
||||
s.Require().Equal(tc.isAuctionTx, bidInfo != nil)
|
||||
if tc.expectedError {
|
||||
suite.Require().Error(err)
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *MEVTestSuite) TestGetTransactionSigners() {
|
||||
func (s *MEVTestSuite) TestGetTransactionSigners() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
createTx func() sdk.Tx
|
||||
@ -104,20 +104,20 @@ func (suite *MEVTestSuite) TestGetTransactionSigners() {
|
||||
"normal auction tx",
|
||||
func() sdk.Tx {
|
||||
tx, err := testutils.CreateAuctionTxWithSigners(
|
||||
suite.encCfg.TxConfig,
|
||||
suite.accounts[0],
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin("stake", math.NewInt(100)),
|
||||
1,
|
||||
0,
|
||||
suite.accounts[0:1],
|
||||
s.accounts[0:1],
|
||||
)
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx
|
||||
},
|
||||
[]map[string]struct{}{
|
||||
{
|
||||
suite.accounts[0].Address.String(): {},
|
||||
s.accounts[0].Address.String(): {},
|
||||
},
|
||||
},
|
||||
false,
|
||||
@ -125,8 +125,8 @@ func (suite *MEVTestSuite) TestGetTransactionSigners() {
|
||||
{
|
||||
"normal sdk tx",
|
||||
func() sdk.Tx {
|
||||
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 10, 0, 0)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateRandomTx(s.encCfg.TxConfig, s.accounts[0], 0, 10, 0, 0)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx
|
||||
},
|
||||
@ -137,26 +137,26 @@ func (suite *MEVTestSuite) TestGetTransactionSigners() {
|
||||
"multiple signers on auction tx",
|
||||
func() sdk.Tx {
|
||||
tx, err := testutils.CreateAuctionTxWithSigners(
|
||||
suite.encCfg.TxConfig,
|
||||
suite.accounts[0],
|
||||
s.encCfg.TxConfig,
|
||||
s.accounts[0],
|
||||
sdk.NewCoin("stake", math.NewInt(100)),
|
||||
1,
|
||||
0,
|
||||
suite.accounts[0:3],
|
||||
s.accounts[0:3],
|
||||
)
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx
|
||||
},
|
||||
[]map[string]struct{}{
|
||||
{
|
||||
suite.accounts[0].Address.String(): {},
|
||||
s.accounts[0].Address.String(): {},
|
||||
},
|
||||
{
|
||||
suite.accounts[1].Address.String(): {},
|
||||
s.accounts[1].Address.String(): {},
|
||||
},
|
||||
{
|
||||
suite.accounts[2].Address.String(): {},
|
||||
s.accounts[2].Address.String(): {},
|
||||
},
|
||||
},
|
||||
false,
|
||||
@ -164,20 +164,20 @@ func (suite *MEVTestSuite) TestGetTransactionSigners() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
s.Run(tc.name, func() {
|
||||
tx := tc.createTx()
|
||||
|
||||
bidInfo, _ := suite.config.GetAuctionBidInfo(tx)
|
||||
bidInfo, _ := s.config.GetAuctionBidInfo(tx)
|
||||
if tc.expectedError {
|
||||
suite.Require().Nil(bidInfo)
|
||||
s.Require().Nil(bidInfo)
|
||||
} else {
|
||||
suite.Require().Equal(tc.expectedSigners, bidInfo.Signers)
|
||||
s.Require().Equal(tc.expectedSigners, bidInfo.Signers)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *MEVTestSuite) TestWrapBundleTransaction() {
|
||||
func (s *MEVTestSuite) TestWrapBundleTransaction() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
createBundleTx func() (sdk.Tx, []byte)
|
||||
@ -186,11 +186,11 @@ func (suite *MEVTestSuite) TestWrapBundleTransaction() {
|
||||
{
|
||||
"normal sdk tx",
|
||||
func() (sdk.Tx, []byte) {
|
||||
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 1, 0, 0)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateRandomTx(s.encCfg.TxConfig, s.accounts[0], 0, 1, 0, 0)
|
||||
s.Require().NoError(err)
|
||||
|
||||
bz, err := suite.encCfg.TxConfig.TxEncoder()(tx)
|
||||
suite.Require().NoError(err)
|
||||
bz, err := s.encCfg.TxConfig.TxEncoder()(tx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx, bz
|
||||
},
|
||||
@ -209,28 +209,28 @@ func (suite *MEVTestSuite) TestWrapBundleTransaction() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
s.Run(tc.name, func() {
|
||||
tx, bz := tc.createBundleTx()
|
||||
|
||||
wrappedTx, err := suite.config.WrapBundleTransaction(bz)
|
||||
wrappedTx, err := s.config.WrapBundleTransaction(bz)
|
||||
if tc.expectedError {
|
||||
suite.Require().Error(err)
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
txBytes, err := suite.encCfg.TxConfig.TxEncoder()(tx)
|
||||
suite.Require().NoError(err)
|
||||
txBytes, err := s.encCfg.TxConfig.TxEncoder()(tx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
wrappedTxBytes, err := suite.encCfg.TxConfig.TxEncoder()(wrappedTx)
|
||||
suite.Require().NoError(err)
|
||||
wrappedTxBytes, err := s.encCfg.TxConfig.TxEncoder()(wrappedTx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
suite.Require().Equal(txBytes, wrappedTxBytes)
|
||||
s.Require().Equal(txBytes, wrappedTxBytes)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *MEVTestSuite) TestGetBidder() {
|
||||
func (s *MEVTestSuite) TestGetBidder() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
createTx func() sdk.Tx
|
||||
@ -241,8 +241,8 @@ func (suite *MEVTestSuite) TestGetBidder() {
|
||||
{
|
||||
"normal sdk tx",
|
||||
func() sdk.Tx {
|
||||
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 1, 0, 0)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateRandomTx(s.encCfg.TxConfig, s.accounts[0], 0, 1, 0, 0)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx
|
||||
},
|
||||
@ -253,32 +253,32 @@ func (suite *MEVTestSuite) TestGetBidder() {
|
||||
{
|
||||
"valid auction tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
suite.accounts[0].Address.String(),
|
||||
s.accounts[0].Address.String(),
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid auction tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]
|
||||
suite.Require().NoError(err)
|
||||
randomMsg := testutils.CreateRandomMsgs(s.accounts[0].Address, 1)[0]
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid, randomMsg}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
"",
|
||||
@ -288,24 +288,24 @@ func (suite *MEVTestSuite) TestGetBidder() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
s.Run(tc.name, func() {
|
||||
tx := tc.createTx()
|
||||
|
||||
bidInfo, err := suite.config.GetAuctionBidInfo(tx)
|
||||
bidInfo, err := s.config.GetAuctionBidInfo(tx)
|
||||
if tc.expectedError {
|
||||
suite.Require().Error(err)
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
if tc.isAuctionTx {
|
||||
suite.Require().Equal(tc.expectedBidder, bidInfo.Bidder.String())
|
||||
s.Require().Equal(tc.expectedBidder, bidInfo.Bidder.String())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *MEVTestSuite) TestGetBid() {
|
||||
func (s *MEVTestSuite) TestGetBid() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
createTx func() sdk.Tx
|
||||
@ -316,8 +316,8 @@ func (suite *MEVTestSuite) TestGetBid() {
|
||||
{
|
||||
"normal sdk tx",
|
||||
func() sdk.Tx {
|
||||
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 1, 0, 0)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateRandomTx(s.encCfg.TxConfig, s.accounts[0], 0, 1, 0, 0)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx
|
||||
},
|
||||
@ -328,13 +328,13 @@ func (suite *MEVTestSuite) TestGetBid() {
|
||||
{
|
||||
"valid auction tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
sdk.NewInt64Coin("stake", 100),
|
||||
@ -344,16 +344,16 @@ func (suite *MEVTestSuite) TestGetBid() {
|
||||
{
|
||||
"invalid auction tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]
|
||||
suite.Require().NoError(err)
|
||||
randomMsg := testutils.CreateRandomMsgs(s.accounts[0].Address, 1)[0]
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid, randomMsg}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
sdk.Coin{},
|
||||
@ -363,24 +363,24 @@ func (suite *MEVTestSuite) TestGetBid() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
s.Run(tc.name, func() {
|
||||
tx := tc.createTx()
|
||||
|
||||
bidInfo, err := suite.config.GetAuctionBidInfo(tx)
|
||||
bidInfo, err := s.config.GetAuctionBidInfo(tx)
|
||||
if tc.expectedError {
|
||||
suite.Require().Error(err)
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
if tc.isAuctionTx {
|
||||
suite.Require().Equal(tc.expectedBid, bidInfo.Bid)
|
||||
s.Require().Equal(tc.expectedBid, bidInfo.Bid)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *MEVTestSuite) TestGetBundledTransactions() {
|
||||
func (s *MEVTestSuite) TestGetBundledTransactions() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
createTx func() (sdk.Tx, [][]byte)
|
||||
@ -390,8 +390,8 @@ func (suite *MEVTestSuite) TestGetBundledTransactions() {
|
||||
{
|
||||
"normal sdk tx",
|
||||
func() (sdk.Tx, [][]byte) {
|
||||
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 1, 0, 0)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateRandomTx(s.encCfg.TxConfig, s.accounts[0], 0, 1, 0, 0)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx, nil
|
||||
},
|
||||
@ -401,13 +401,13 @@ func (suite *MEVTestSuite) TestGetBundledTransactions() {
|
||||
{
|
||||
"valid auction tx",
|
||||
func() (sdk.Tx, [][]byte) {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx, msgAuctionBid.Transactions
|
||||
},
|
||||
false,
|
||||
@ -416,16 +416,16 @@ func (suite *MEVTestSuite) TestGetBundledTransactions() {
|
||||
{
|
||||
"invalid auction tx",
|
||||
func() (sdk.Tx, [][]byte) {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]
|
||||
suite.Require().NoError(err)
|
||||
randomMsg := testutils.CreateRandomMsgs(s.accounts[0].Address, 1)[0]
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid, randomMsg}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 0, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 0, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx, nil
|
||||
},
|
||||
true,
|
||||
@ -434,24 +434,24 @@ func (suite *MEVTestSuite) TestGetBundledTransactions() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
s.Run(tc.name, func() {
|
||||
tx, expectedBundledTxs := tc.createTx()
|
||||
|
||||
bidInfo, err := suite.config.GetAuctionBidInfo(tx)
|
||||
bidInfo, err := s.config.GetAuctionBidInfo(tx)
|
||||
if tc.expectedError {
|
||||
suite.Require().Error(err)
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
if tc.isAuctionTx {
|
||||
suite.Require().Equal(expectedBundledTxs, bidInfo.Transactions)
|
||||
s.Require().Equal(expectedBundledTxs, bidInfo.Transactions)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *MEVTestSuite) TestGetTimeout() {
|
||||
func (s *MEVTestSuite) TestGetTimeout() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
createTx func() sdk.Tx
|
||||
@ -462,8 +462,8 @@ func (suite *MEVTestSuite) TestGetTimeout() {
|
||||
{
|
||||
"normal sdk tx",
|
||||
func() sdk.Tx {
|
||||
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 1, 1, 0)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateRandomTx(s.encCfg.TxConfig, s.accounts[0], 0, 1, 1, 0)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return tx
|
||||
},
|
||||
@ -474,13 +474,13 @@ func (suite *MEVTestSuite) TestGetTimeout() {
|
||||
{
|
||||
"valid auction tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 10, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 10, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
false,
|
||||
@ -490,16 +490,16 @@ func (suite *MEVTestSuite) TestGetTimeout() {
|
||||
{
|
||||
"invalid auction tx",
|
||||
func() sdk.Tx {
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
suite.Require().NoError(err)
|
||||
msgAuctionBid, err := testutils.CreateMsgAuctionBid(s.encCfg.TxConfig, s.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]
|
||||
suite.Require().NoError(err)
|
||||
randomMsg := testutils.CreateRandomMsgs(s.accounts[0].Address, 1)[0]
|
||||
s.Require().NoError(err)
|
||||
|
||||
msgs := []sdk.Msg{msgAuctionBid, randomMsg}
|
||||
|
||||
tx, err := testutils.CreateTx(suite.encCfg.TxConfig, suite.accounts[0], 0, 10, msgs)
|
||||
suite.Require().NoError(err)
|
||||
tx, err := testutils.CreateTx(s.encCfg.TxConfig, s.accounts[0], 0, 10, msgs)
|
||||
s.Require().NoError(err)
|
||||
return tx
|
||||
},
|
||||
true,
|
||||
@ -509,17 +509,17 @@ func (suite *MEVTestSuite) TestGetTimeout() {
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.name, func() {
|
||||
s.Run(tc.name, func() {
|
||||
tx := tc.createTx()
|
||||
|
||||
bidInfo, err := suite.config.GetAuctionBidInfo(tx)
|
||||
bidInfo, err := s.config.GetAuctionBidInfo(tx)
|
||||
if tc.expectedError {
|
||||
suite.Require().Error(err)
|
||||
s.Require().Error(err)
|
||||
} else {
|
||||
suite.Require().NoError(err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
if tc.isAuctionTx {
|
||||
suite.Require().Equal(tc.expectedTimeout, bidInfo.Timeout)
|
||||
s.Require().Equal(tc.expectedTimeout, bidInfo.Timeout)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@ -1,16 +1,23 @@
|
||||
package mev_test
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"cosmossdk.io/math"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
signer_extraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
|
||||
"github.com/skip-mev/block-sdk/block/base"
|
||||
"github.com/skip-mev/block-sdk/block/utils"
|
||||
"github.com/skip-mev/block-sdk/lanes/mev"
|
||||
testutils "github.com/skip-mev/block-sdk/testutils"
|
||||
)
|
||||
@ -18,30 +25,93 @@ import (
|
||||
type MEVTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
encCfg testutils.EncodingConfig
|
||||
config mev.Factory
|
||||
ctx sdk.Context
|
||||
random *rand.Rand
|
||||
accounts []testutils.Account
|
||||
nonces map[string]uint64
|
||||
encCfg testutils.EncodingConfig
|
||||
config mev.Factory
|
||||
ctx sdk.Context
|
||||
accounts []testutils.Account
|
||||
gasTokenDenom string
|
||||
}
|
||||
|
||||
func TestMempoolTestSuite(t *testing.T) {
|
||||
func TestMEVTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(MEVTestSuite))
|
||||
}
|
||||
|
||||
func (suite *MEVTestSuite) SetupTest() {
|
||||
// Mempool setup
|
||||
suite.encCfg = testutils.CreateTestEncodingConfig()
|
||||
suite.config = mev.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder(), signer_extraction.NewDefaultAdapter())
|
||||
suite.ctx = sdk.NewContext(nil, cmtproto.Header{}, false, log.NewTestLogger(suite.T()))
|
||||
func (s *MEVTestSuite) SetupTest() {
|
||||
// Init encoding config
|
||||
s.encCfg = testutils.CreateTestEncodingConfig()
|
||||
s.config = mev.NewDefaultAuctionFactory(s.encCfg.TxConfig.TxDecoder(), signer_extraction.NewDefaultAdapter())
|
||||
testCtx := testutil.DefaultContextWithDB(s.T(), storetypes.NewKVStoreKey("test"), storetypes.NewTransientStoreKey("transient_test"))
|
||||
s.ctx = testCtx.Ctx.WithIsCheckTx(true)
|
||||
|
||||
// Init accounts
|
||||
suite.random = rand.New(rand.NewSource(time.Now().Unix()))
|
||||
suite.accounts = testutils.RandomAccounts(suite.random, 10)
|
||||
|
||||
suite.nonces = make(map[string]uint64)
|
||||
for _, acc := range suite.accounts {
|
||||
suite.nonces[acc.Address.String()] = 0
|
||||
}
|
||||
random := rand.New(rand.NewSource(time.Now().Unix()))
|
||||
s.accounts = testutils.RandomAccounts(random, 10)
|
||||
s.gasTokenDenom = "stake"
|
||||
}
|
||||
|
||||
func (s *MEVTestSuite) initLane(
|
||||
maxBlockSpace math.LegacyDec,
|
||||
expectedExecution map[sdk.Tx]bool,
|
||||
) *mev.MEVLane {
|
||||
config := base.NewLaneConfig(
|
||||
log.NewTestLogger(s.T()),
|
||||
s.encCfg.TxConfig.TxEncoder(),
|
||||
s.encCfg.TxConfig.TxDecoder(),
|
||||
s.setUpAnteHandler(expectedExecution),
|
||||
signer_extraction.NewDefaultAdapter(),
|
||||
maxBlockSpace,
|
||||
)
|
||||
|
||||
factory := mev.NewDefaultAuctionFactory(s.encCfg.TxConfig.TxDecoder(), signer_extraction.NewDefaultAdapter())
|
||||
return mev.NewMEVLane(config, factory)
|
||||
}
|
||||
|
||||
func (s *MEVTestSuite) setUpAnteHandler(expectedExecution map[sdk.Tx]bool) sdk.AnteHandler {
|
||||
txCache := make(map[string]bool)
|
||||
for tx, pass := range expectedExecution {
|
||||
bz, err := s.encCfg.TxConfig.TxEncoder()(tx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
hash := sha256.Sum256(bz)
|
||||
hashStr := hex.EncodeToString(hash[:])
|
||||
txCache[hashStr] = pass
|
||||
}
|
||||
|
||||
anteHandler := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
|
||||
bz, err := s.encCfg.TxConfig.TxEncoder()(tx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
hash := sha256.Sum256(bz)
|
||||
hashStr := hex.EncodeToString(hash[:])
|
||||
|
||||
pass, found := txCache[hashStr]
|
||||
if !found {
|
||||
return ctx, fmt.Errorf("tx not found")
|
||||
}
|
||||
|
||||
if pass {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
return ctx, fmt.Errorf("tx failed")
|
||||
}
|
||||
|
||||
return anteHandler
|
||||
}
|
||||
|
||||
func (s *MEVTestSuite) getTxSize(tx sdk.Tx) int64 {
|
||||
txBz, err := s.encCfg.TxConfig.TxEncoder()(tx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return int64(len(txBz))
|
||||
}
|
||||
|
||||
func (s *MEVTestSuite) compare(first, second []sdk.Tx) {
|
||||
firstBytes, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), first)
|
||||
s.Require().NoError(err)
|
||||
|
||||
secondBytes, err := utils.GetEncodedTxs(s.encCfg.TxConfig.TxEncoder(), second)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Equal(firstBytes, secondBytes)
|
||||
}
|
||||
|
||||
@ -3,7 +3,12 @@ package integration
|
||||
import (
|
||||
"context"
|
||||
|
||||
"bytes"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
rpctypes "github.com/cometbft/cometbft/rpc/core/types"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
@ -12,10 +17,6 @@ import (
|
||||
"github.com/strangelove-ventures/interchaintest/v7/ibc"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
rpctypes "github.com/cometbft/cometbft/rpc/core/types"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -62,8 +63,8 @@ func (s *IntegrationTestSuite) WithDenom(denom string) *IntegrationTestSuite {
|
||||
|
||||
func (s *IntegrationTestSuite) WithKeyringOptions(cdc codec.Codec, opts keyring.Option) {
|
||||
s.broadcasterOverrides = &KeyringOverride{
|
||||
cdc: cdc,
|
||||
keyringOptions: opts,
|
||||
cdc: cdc,
|
||||
keyringOptions: opts,
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +144,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast + wait for the tx to be included in a block
|
||||
res := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
res := s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -177,7 +178,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
|
||||
// create the MsgAuctionBid
|
||||
bidAmt := params.ReserveFee
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: msgs[0:1],
|
||||
@ -205,8 +206,8 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
expTxs := make(chan committedTx, 2)
|
||||
|
||||
regular_txs := s.BroadcastTxsWithCallback(
|
||||
context.Background(),
|
||||
s.chain.(*cosmos.CosmosChain),
|
||||
context.Background(),
|
||||
s.chain.(*cosmos.CosmosChain),
|
||||
msgsToBcast,
|
||||
func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTxs <- committedTx{tx, resp}
|
||||
@ -217,7 +218,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
|
||||
// get the height of the block that the bid was included in
|
||||
var commitHeight int64
|
||||
|
||||
|
||||
tx1 := <-expTxs
|
||||
tx2 := <-expTxs
|
||||
|
||||
@ -265,10 +266,10 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
}
|
||||
// create bundle
|
||||
bidAmt := params.ReserveFee
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, txs)
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, txs)
|
||||
// create 2 more bundle w same txs from same user
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), txs)
|
||||
bid3, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement).Add(params.MinBidIncrement), txs)
|
||||
bid2, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), txs)
|
||||
bid3, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement).Add(params.MinBidIncrement), txs)
|
||||
|
||||
// query height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
@ -279,7 +280,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
height++
|
||||
|
||||
// broadcast all bids
|
||||
broadcastedTxs := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
broadcastedTxs := s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -345,18 +346,18 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
|
||||
// broadcast txs in the bundle to network + bundle + extra
|
||||
broadcastedTxs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
Height: height + 3,
|
||||
}, {
|
||||
User: s.user3,
|
||||
Msgs: []sdk.Msg{banktypes.NewMsgSend(s.user3.Address(), s.user1.Address(), sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(100))))},
|
||||
Height: height + 3,
|
||||
}},
|
||||
func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTxs <- committedTx{tx, resp}
|
||||
})
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
Height: height + 3,
|
||||
}, {
|
||||
User: s.user3,
|
||||
Msgs: []sdk.Msg{banktypes.NewMsgSend(s.user3.Address(), s.user1.Address(), sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(100))))},
|
||||
Height: height + 3,
|
||||
}},
|
||||
func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTxs <- committedTx{tx, resp}
|
||||
})
|
||||
close(expTxs)
|
||||
|
||||
var bidTxHeight int64
|
||||
@ -379,7 +380,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
}
|
||||
|
||||
type committedTx struct {
|
||||
tx []byte
|
||||
tx []byte
|
||||
res *rpctypes.ResultTx
|
||||
}
|
||||
|
||||
@ -410,7 +411,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid 2
|
||||
msg2 := Tx{
|
||||
@ -419,7 +420,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
SequenceIncrement: 1,
|
||||
}
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, bundledTxs2 := s.CreateAuctionBidMsg( context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg2})
|
||||
bid2, bundledTxs2 := s.CreateAuctionBidMsg(context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg2})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -430,9 +431,9 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
// broadcast both bids (with ample time to be committed (instead of timing out))
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
},
|
||||
{
|
||||
User: s.user2,
|
||||
@ -442,7 +443,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
txsCh <- committedTx{tx, resp}
|
||||
})
|
||||
|
||||
|
||||
// check txs were committed
|
||||
require.Len(s.T(), txsCh, 2)
|
||||
close(txsCh)
|
||||
@ -450,7 +451,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
tx1 := <-txsCh
|
||||
tx2 := <-txsCh
|
||||
|
||||
// query next block
|
||||
// query next block
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), tx1.res.Height)
|
||||
|
||||
// check bid2 was included first
|
||||
@ -481,7 +482,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx})
|
||||
|
||||
// create bid 2
|
||||
tx2 := Tx{
|
||||
@ -490,7 +491,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
SequenceIncrement: 1,
|
||||
}
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx2})
|
||||
bid2, _ := s.CreateAuctionBidMsg(context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx2})
|
||||
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
@ -543,7 +544,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid 2
|
||||
msg2 := Tx{
|
||||
@ -553,7 +554,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg2})
|
||||
bid2, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg2})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -568,10 +569,10 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
Height: height + 4,
|
||||
},
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 4,
|
||||
ExpectFail: true,
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 4,
|
||||
ExpectFail: true,
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTx <- committedTx{tx, resp}
|
||||
@ -605,10 +606,10 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
bid2, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -618,9 +619,9 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
// broadcast both bids
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
SkipInclusionCheck: true,
|
||||
},
|
||||
{
|
||||
@ -663,10 +664,10 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
bid2, _ := s.CreateAuctionBidMsg(context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -676,9 +677,9 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
// broadcast both bids
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
SkipInclusionCheck: true,
|
||||
},
|
||||
{
|
||||
@ -721,7 +722,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid2
|
||||
// create a second message
|
||||
@ -743,9 +744,9 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
// broadcast both bids
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 4,
|
||||
},
|
||||
{
|
||||
User: s.user2,
|
||||
@ -754,7 +755,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
committedTxs <- committedTx{
|
||||
tx: tx,
|
||||
tx: tx,
|
||||
res: resp,
|
||||
}
|
||||
})
|
||||
@ -797,11 +798,11 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
SequenceIncrement: 2,
|
||||
}
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
// wrap bidTx in another tx
|
||||
wrappedBid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
wrappedBid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -813,7 +814,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{wrappedBid},
|
||||
@ -831,7 +832,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
SequenceIncrement: 2,
|
||||
}
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(1000000000000000000))
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -858,7 +859,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
}
|
||||
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg, msg2, msg3})
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg, msg2, msg3})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -875,13 +876,13 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
SequenceIncrement: 2,
|
||||
}
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -901,7 +902,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create bid smaller than reserve
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(0))
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -924,7 +925,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create bid smaller than reserve
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(0))
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, msgs)
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, msgs)
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
@ -943,7 +944,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create bid smaller than reserve
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(0))
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
s.SimulateTx(context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, 0, true, []sdk.Msg{bid}...)
|
||||
@ -959,7 +960,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create the MsgAuctioBid (this should fail b.c same tx is repeated twice)
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
bid, _ := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -976,7 +977,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast + wait for the tx to be included in a block
|
||||
txs := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
txs := s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -1022,7 +1023,7 @@ func (s *IntegrationTestSuite) TestFreeLane() {
|
||||
balanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user1.FormattedAddress(), s.denom)
|
||||
|
||||
// create a free tx (MsgDelegate), broadcast and wait for commit
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -1085,7 +1086,7 @@ func (s *IntegrationTestSuite) TestFreeLane() {
|
||||
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
|
||||
|
||||
// user1 submits a free-tx, user2 submits a free tx
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -1242,7 +1243,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -1392,7 +1393,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
txs := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
txs := s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user3,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
|
||||
@ -196,14 +196,14 @@ func CreateTxWithSigners(txCfg client.TxConfig, nonce, timeout uint64, signers [
|
||||
return txBuilder.GetTx(), nil
|
||||
}
|
||||
|
||||
func CreateAuctionTx(txCfg client.TxConfig, bidder Account, bid sdk.Coin, nonce, timeout uint64, signers []Account, gasLimit uint64) (authsigning.Tx, []authsigning.Tx, error) {
|
||||
func CreateAuctionTx(txCfg client.TxConfig, bidder Account, bid sdk.Coin, nonce, timeout uint64, signers []Account, gasLimit uint64) (sdk.Tx, []sdk.Tx, error) {
|
||||
bidMsg := &auctiontypes.MsgAuctionBid{
|
||||
Bidder: bidder.Address.String(),
|
||||
Bid: bid,
|
||||
Transactions: make([][]byte, len(signers)),
|
||||
}
|
||||
|
||||
txs := []authsigning.Tx{}
|
||||
txs := []sdk.Tx{}
|
||||
|
||||
for i := 0; i < len(signers); i++ {
|
||||
randomMsg := CreateRandomMsgs(signers[i].Address, 1)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user