init
This commit is contained in:
parent
7005d4c8a3
commit
605d94f201
@ -7,257 +7,247 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/skip-mev/pob/blockbuster"
|
||||
"github.com/skip-mev/pob/blockbuster/utils"
|
||||
"github.com/skip-mev/pob/x/builder/types"
|
||||
)
|
||||
|
||||
// PrepareLane will attempt to select the highest bid transaction that is valid
|
||||
// PrepareLaneHandler will attempt to select the highest bid transaction that is valid
|
||||
// and whose bundled transactions are valid and include them in the proposal. It
|
||||
// will return an empty partial proposal if no valid bids are found.
|
||||
func (l *TOBLane) PrepareLane(
|
||||
ctx sdk.Context,
|
||||
proposal blockbuster.BlockProposal,
|
||||
maxTxBytes int64,
|
||||
next blockbuster.PrepareLanesHandler,
|
||||
) (blockbuster.BlockProposal, error) {
|
||||
// Define all of the info we need to select transactions for the partial proposal.
|
||||
var (
|
||||
txs [][]byte
|
||||
txsToRemove = make(map[sdk.Tx]struct{}, 0)
|
||||
)
|
||||
// will return no transactions if no valid bids are found. If any of the bids are invalid,
|
||||
// it will return them and will only remove the bids and not the bundled transactions.
|
||||
func (l *TOBLane) PrepareLaneHandler() blockbuster.PrepareLaneHandler {
|
||||
return func(ctx sdk.Context, proposal blockbuster.BlockProposal, maxTxBytes int64) ([][]byte, []sdk.Tx, error) {
|
||||
// Define all of the info we need to select transactions for the partial proposal.
|
||||
var (
|
||||
txs [][]byte
|
||||
txsToRemove []sdk.Tx
|
||||
)
|
||||
|
||||
// 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() {
|
||||
cacheCtx, write := ctx.CacheContext()
|
||||
tmpBidTx := bidTxIterator.Tx()
|
||||
// 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() {
|
||||
cacheCtx, write := ctx.CacheContext()
|
||||
tmpBidTx := bidTxIterator.Tx()
|
||||
|
||||
bidTxBz, hash, err := utils.GetTxHashStr(l.Cfg.TxEncoder, tmpBidTx)
|
||||
if err != nil {
|
||||
l.Logger().Info("failed to get hash of auction bid tx", "err", err)
|
||||
bidTxBz, hash, err := utils.GetTxHashStr(l.TxEncoder(), tmpBidTx)
|
||||
if err != nil {
|
||||
l.Logger().Info("failed to get hash of auction bid tx", "err", err)
|
||||
|
||||
txsToRemove[tmpBidTx] = struct{}{}
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
txsToRemove = append(txsToRemove, tmpBidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// if the transaction is already in the (partial) block proposal, we skip it.
|
||||
if proposal.Contains(bidTxBz) {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx is already in proposal",
|
||||
"tx_hash", hash,
|
||||
)
|
||||
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
bidTxSize := int64(len(bidTxBz))
|
||||
if bidTxSize <= maxTxBytes {
|
||||
// Build the partial proposal by selecting the bid transaction and all of
|
||||
// its bundled transactions.
|
||||
bidInfo, err := l.GetAuctionBidInfo(tmpBidTx)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to get auction bid info",
|
||||
"tx_hash", 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, tmpBidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// Verify the bid transaction and all of its bundled transactions.
|
||||
if err := l.VerifyTx(cacheCtx, tmpBidTx, bidInfo); err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to verify auction bid tx",
|
||||
"tx_hash", hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, tmpBidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// store the bytes of each ref tx as sdk.Tx bytes in order to build a valid proposal
|
||||
bundledTxBz := make([][]byte, len(bidInfo.Transactions))
|
||||
for index, rawRefTx := range bidInfo.Transactions {
|
||||
sdkTx, err := l.WrapBundleTransaction(rawRefTx)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to wrap bundled tx",
|
||||
"tx_hash", hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, tmpBidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
sdkTxBz, _, err := utils.GetTxHashStr(l.TxEncoder(), sdkTx)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to get hash of bundled tx",
|
||||
"tx_hash", hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove = append(txsToRemove, tmpBidTx)
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// if the transaction is already in the (partial) block proposal, we skip it.
|
||||
if proposal.Contains(sdkTxBz) {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx is already in proposal",
|
||||
"tx_hash", hash,
|
||||
)
|
||||
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
bundleTxBz := make([]byte, len(sdkTxBz))
|
||||
copy(bundleTxBz, sdkTxBz)
|
||||
bundledTxBz[index] = sdkTxBz
|
||||
}
|
||||
|
||||
// At this point, both the bid transaction itself and all the bundled
|
||||
// transactions are valid. So we select the bid transaction along with
|
||||
// all the bundled transactions. We also mark these transactions as seen and
|
||||
// update the total size selected thus far.
|
||||
txs = append(txs, bidTxBz)
|
||||
txs = append(txs, bundledTxBz...)
|
||||
|
||||
// Write the cache context to the original context when we know we have a
|
||||
// valid top of block bundle.
|
||||
write()
|
||||
|
||||
break selectBidTxLoop
|
||||
}
|
||||
|
||||
// if the transaction is already in the (partial) block proposal, we skip it.
|
||||
if proposal.Contains(bidTxBz) {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx is already in proposal",
|
||||
"tx_hash", hash,
|
||||
"failed to select auction bid tx for lane; tx size is too large",
|
||||
"tx_size", bidTxSize,
|
||||
"max_size", maxTxBytes,
|
||||
)
|
||||
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
bidTxSize := int64(len(bidTxBz))
|
||||
if bidTxSize <= maxTxBytes {
|
||||
// Verify the bid transaction and all of its bundled transactions.
|
||||
if err := l.VerifyTx(cacheCtx, tmpBidTx); err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to verify auction bid tx",
|
||||
"tx_hash", hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove[tmpBidTx] = struct{}{}
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// Build the partial proposal by selecting the bid transaction and all of
|
||||
// its bundled transactions.
|
||||
bidInfo, err := l.GetAuctionBidInfo(tmpBidTx)
|
||||
if bidInfo == nil || err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to get auction bid info",
|
||||
"tx_hash", 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[tmpBidTx] = struct{}{}
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// store the bytes of each ref tx as sdk.Tx bytes in order to build a valid proposal
|
||||
bundledTxBz := make([][]byte, len(bidInfo.Transactions))
|
||||
for index, rawRefTx := range bidInfo.Transactions {
|
||||
sdkTx, err := l.WrapBundleTransaction(rawRefTx)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to wrap bundled tx",
|
||||
"tx_hash", hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove[tmpBidTx] = struct{}{}
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
sdkTxBz, _, err := utils.GetTxHashStr(l.Cfg.TxEncoder, sdkTx)
|
||||
if err != nil {
|
||||
l.Logger().Info(
|
||||
"failed to get hash of bundled tx",
|
||||
"tx_hash", hash,
|
||||
"err", err,
|
||||
)
|
||||
|
||||
txsToRemove[tmpBidTx] = struct{}{}
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
// if the transaction is already in the (partial) block proposal, we skip it.
|
||||
if proposal.Contains(sdkTxBz) {
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx is already in proposal",
|
||||
"tx_hash", hash,
|
||||
)
|
||||
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
bundleTxBz := make([]byte, len(sdkTxBz))
|
||||
copy(bundleTxBz, sdkTxBz)
|
||||
bundledTxBz[index] = sdkTxBz
|
||||
}
|
||||
|
||||
// At this point, both the bid transaction itself and all the bundled
|
||||
// transactions are valid. So we select the bid transaction along with
|
||||
// all the bundled transactions. We also mark these transactions as seen and
|
||||
// update the total size selected thus far.
|
||||
txs = append(txs, bidTxBz)
|
||||
txs = append(txs, bundledTxBz...)
|
||||
|
||||
// Write the cache context to the original context when we know we have a
|
||||
// valid top of block bundle.
|
||||
write()
|
||||
|
||||
break selectBidTxLoop
|
||||
}
|
||||
|
||||
l.Logger().Info(
|
||||
"failed to select auction bid tx for lane; tx size is too large",
|
||||
"tx_size", bidTxSize,
|
||||
"max_size", maxTxBytes,
|
||||
)
|
||||
return txs, txsToRemove, nil
|
||||
}
|
||||
|
||||
// Remove all transactions that were invalid during the creation of the partial proposal.
|
||||
if err := utils.RemoveTxsFromLane(txsToRemove, l.Mempool); err != nil {
|
||||
l.Logger().Error(
|
||||
"failed to remove transactions from lane",
|
||||
"lane", l.Name(),
|
||||
"err", err,
|
||||
)
|
||||
|
||||
return proposal, err
|
||||
}
|
||||
|
||||
// Update the proposal with the selected transactions. This will only return an error
|
||||
// if the invarient checks are not passed. In the case when this errors, the original proposal
|
||||
// will be returned (without the selected transactions from this lane).
|
||||
if err := proposal.UpdateProposal(l, txs); err != nil {
|
||||
return proposal, err
|
||||
}
|
||||
|
||||
return next(ctx, proposal)
|
||||
}
|
||||
|
||||
// ProcessLane will ensure that block proposals that include transactions from
|
||||
// ProcessLaneHandler will ensure that block proposals that include transactions from
|
||||
// the top-of-block auction lane are valid.
|
||||
func (l *TOBLane) ProcessLane(ctx sdk.Context, txs []sdk.Tx, next blockbuster.ProcessLanesHandler) (sdk.Context, error) {
|
||||
if len(txs) == 0 {
|
||||
return next(ctx, txs)
|
||||
}
|
||||
func (l *TOBLane) ProcessLaneHandler() blockbuster.ProcessLaneHandler {
|
||||
return func(ctx sdk.Context, txs []sdk.Tx) ([]sdk.Tx, error) {
|
||||
if len(txs) == 0 {
|
||||
return txs, nil
|
||||
}
|
||||
|
||||
bidTx := txs[0]
|
||||
if !l.Match(ctx, bidTx) {
|
||||
return next(ctx, txs)
|
||||
}
|
||||
bidTx := txs[0]
|
||||
if !l.Match(ctx, bidTx) {
|
||||
return txs, nil
|
||||
}
|
||||
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
return ctx, fmt.Errorf("failed to get bid info for lane %s: %w", l.Name(), err)
|
||||
}
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get bid info for lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if err := l.VerifyTx(ctx, bidTx); err != nil {
|
||||
return ctx, fmt.Errorf("invalid bid tx: %w", err)
|
||||
}
|
||||
if err := l.VerifyTx(ctx, bidTx, bidInfo); err != nil {
|
||||
return nil, fmt.Errorf("invalid bid tx: %w", err)
|
||||
}
|
||||
|
||||
return next(ctx, txs[len(bidInfo.Transactions)+1:])
|
||||
return txs[len(bidInfo.Transactions)+1:], nil
|
||||
}
|
||||
}
|
||||
|
||||
// ProcessLaneBasic ensures that if a bid transaction is present in a proposal,
|
||||
// CheckOrderHandler ensures that if a bid transaction is present in a proposal,
|
||||
// - it is the first transaction in the partial proposal
|
||||
// - all of the bundled transactions are included after the bid transaction in the order
|
||||
// they were included in the bid transaction.
|
||||
// - there are no other bid transactions in the proposal
|
||||
func (l *TOBLane) ProcessLaneBasic(ctx sdk.Context, txs []sdk.Tx) error {
|
||||
if len(txs) == 0 {
|
||||
return nil
|
||||
}
|
||||
// - transactions from other lanes are not interleaved with transactions from the bid
|
||||
// transaction.
|
||||
func (l *TOBLane) CheckOrderHandler() blockbuster.CheckOrderHandler {
|
||||
return func(ctx sdk.Context, txs []sdk.Tx) error {
|
||||
if len(txs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
bidTx := txs[0]
|
||||
bidTx := txs[0]
|
||||
|
||||
// If there is a bid transaction, it must be the first transaction in the block proposal.
|
||||
if !l.Match(ctx, bidTx) {
|
||||
for _, tx := range txs[1:] {
|
||||
// If there is a bid transaction, it must be the first transaction in the block proposal.
|
||||
if !l.Match(ctx, bidTx) {
|
||||
for _, tx := range txs[1:] {
|
||||
if l.Match(ctx, tx) {
|
||||
return fmt.Errorf("misplaced bid transactions in lane %s", l.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get bid info for lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if len(txs) < len(bidInfo.Transactions)+1 {
|
||||
return fmt.Errorf(
|
||||
"invalid number of transactions in lane %s; expected at least %d, got %d",
|
||||
l.Name(),
|
||||
len(bidInfo.Transactions)+1,
|
||||
len(txs),
|
||||
)
|
||||
}
|
||||
|
||||
// Ensure that the order of transactions in the bundle is preserved.
|
||||
for i, bundleTx := range txs[1 : len(bidInfo.Transactions)+1] {
|
||||
if l.Match(ctx, bundleTx) {
|
||||
return fmt.Errorf("multiple bid transactions in lane %s", l.Name())
|
||||
}
|
||||
|
||||
txBz, err := l.TxEncoder()(bundleTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode bundled tx in lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(txBz, bidInfo.Transactions[i]) {
|
||||
return fmt.Errorf("invalid order of transactions in lane %s", l.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that there are no more bid transactions in the block proposal.
|
||||
for _, tx := range txs[len(bidInfo.Transactions)+1:] {
|
||||
if l.Match(ctx, tx) {
|
||||
return fmt.Errorf("misplaced bid transactions in lane %s", l.Name())
|
||||
return fmt.Errorf("multiple bid transactions in lane %s", l.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get bid info for lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if len(txs) < len(bidInfo.Transactions)+1 {
|
||||
return fmt.Errorf("invalid number of transactions in lane %s; expected at least %d, got %d", l.Name(), len(bidInfo.Transactions)+1, len(txs))
|
||||
}
|
||||
|
||||
// Ensure that the order of transactions in the bundle is preserved.
|
||||
for i, bundleTx := range txs[1 : len(bidInfo.Transactions)+1] {
|
||||
if l.Match(ctx, bundleTx) {
|
||||
return fmt.Errorf("multiple bid transactions in lane %s", l.Name())
|
||||
}
|
||||
|
||||
txBz, err := l.Cfg.TxEncoder(bundleTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode bundled tx in lane %s: %w", l.Name(), err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(txBz, bidInfo.Transactions[i]) {
|
||||
return fmt.Errorf("invalid order of transactions in lane %s", l.Name())
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that there are no more bid transactions in the block proposal.
|
||||
for _, tx := range txs[len(bidInfo.Transactions)+1:] {
|
||||
if l.Match(ctx, tx) {
|
||||
return fmt.Errorf("multiple bid transactions in lane %s", l.Name())
|
||||
}
|
||||
}
|
||||
|
||||
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 *TOBLane) VerifyTx(ctx sdk.Context, bidTx sdk.Tx) error {
|
||||
bidInfo, err := l.GetAuctionBidInfo(bidTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get auction bid info: %w", err)
|
||||
func (l *TOBLane) VerifyTx(ctx sdk.Context, bidTx sdk.Tx, bidInfo *types.BidInfo) (err error) {
|
||||
if bidInfo == nil {
|
||||
return fmt.Errorf("bid info is nil")
|
||||
}
|
||||
|
||||
// verify the top-level bid transaction
|
||||
ctx, err = l.verifyTx(ctx, bidTx)
|
||||
if err != nil {
|
||||
if ctx, err = l.AnteVerifyTx(ctx, bidTx, false); err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to execute ante handler: %w", err)
|
||||
}
|
||||
|
||||
@ -268,27 +258,10 @@ func (l *TOBLane) VerifyTx(ctx sdk.Context, bidTx sdk.Tx) error {
|
||||
return fmt.Errorf("invalid bid tx; failed to decode bundled tx: %w", err)
|
||||
}
|
||||
|
||||
// bid txs cannot be included in bundled txs
|
||||
bidInfo, _ := l.GetAuctionBidInfo(bundledTx)
|
||||
if bidInfo != nil {
|
||||
return fmt.Errorf("invalid bid tx; bundled tx cannot be a bid tx")
|
||||
}
|
||||
|
||||
if ctx, err = l.verifyTx(ctx, bundledTx); err != nil {
|
||||
if ctx, err = l.AnteVerifyTx(ctx, bundledTx, false); err != nil {
|
||||
return fmt.Errorf("invalid bid tx; failed to execute bundled transaction: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// verifyTx will execute the ante handler on the transaction and return the
|
||||
// resulting context and error.
|
||||
func (l *TOBLane) verifyTx(ctx sdk.Context, tx sdk.Tx) (sdk.Context, error) {
|
||||
if l.Cfg.AnteHandler != nil {
|
||||
newCtx, err := l.Cfg.AnteHandler(ctx, tx, false)
|
||||
return newCtx, err
|
||||
}
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@ type IntegrationTestSuite struct {
|
||||
|
||||
encCfg testutils.EncodingConfig
|
||||
config auction.Factory
|
||||
mempool auction.Mempool
|
||||
ctx sdk.Context
|
||||
random *rand.Rand
|
||||
accounts []testutils.Account
|
||||
@ -33,7 +32,6 @@ func (suite *IntegrationTestSuite) SetupTest() {
|
||||
// Mempool setup
|
||||
suite.encCfg = testutils.CreateTestEncodingConfig()
|
||||
suite.config = auction.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder())
|
||||
suite.mempool = auction.NewMempool(suite.encCfg.TxConfig.TxEncoder(), 0, suite.config)
|
||||
suite.ctx = sdk.NewContext(nil, cmtproto.Header{}, false, log.NewTestLogger(suite.T()))
|
||||
|
||||
// Init accounts
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/skip-mev/pob/blockbuster"
|
||||
"github.com/skip-mev/pob/x/builder/types"
|
||||
)
|
||||
|
||||
@ -21,6 +22,9 @@ type (
|
||||
|
||||
// GetAuctionBidInfo defines a function that returns the bid info from an auction transaction.
|
||||
GetAuctionBidInfo(tx sdk.Tx) (*types.BidInfo, error)
|
||||
|
||||
// MatchHandler defines a function that checks if a transaction matches the auction lane.
|
||||
MatchHandler() blockbuster.MatchHandler
|
||||
}
|
||||
|
||||
// DefaultAuctionFactory defines a default implmentation for the auction factory interface for processing auction transactions.
|
||||
@ -91,6 +95,13 @@ func (config *DefaultAuctionFactory) GetAuctionBidInfo(tx sdk.Tx) (*types.BidInf
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (config *DefaultAuctionFactory) MatchHandler() blockbuster.MatchHandler {
|
||||
return func(ctx sdk.Context, tx sdk.Tx) bool {
|
||||
bidInfo, err := config.GetAuctionBidInfo(tx)
|
||||
return bidInfo != nil && err == nil
|
||||
}
|
||||
}
|
||||
|
||||
// getBundleSigners defines a default function that returns the signers of all transactions in
|
||||
// a bundle. In the default case, each bundle transaction will be an sdk.Tx and the
|
||||
// signers are the signers of each sdk.Msg in the transaction.
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package auction
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/skip-mev/pob/blockbuster"
|
||||
"github.com/skip-mev/pob/blockbuster/lanes/base"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -12,8 +13,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
_ blockbuster.Lane = (*TOBLane)(nil)
|
||||
_ Factory = (*TOBLane)(nil)
|
||||
_ TOBLaneI = (*TOBLane)(nil)
|
||||
)
|
||||
|
||||
// TOBLane defines a top-of-block auction lane. The top of block auction lane
|
||||
@ -22,43 +22,53 @@ var (
|
||||
// their bid price. The highest valid bid transaction is selected for inclusion in the
|
||||
// next block. The bundled transactions of the selected bid transaction are also
|
||||
// included in the next block.
|
||||
type TOBLane struct {
|
||||
// Mempool defines the mempool for the lane.
|
||||
Mempool
|
||||
type (
|
||||
// TOBLaneI defines the interface for the top-of-block auction lane. This interface
|
||||
// is utilized by both the x/builder module and the checkTx handler.
|
||||
TOBLaneI interface {
|
||||
blockbuster.Lane
|
||||
Factory
|
||||
GetTopAuctionTx(ctx context.Context) sdk.Tx
|
||||
}
|
||||
|
||||
// LaneConfig defines the base lane configuration.
|
||||
*base.DefaultLane
|
||||
TOBLane struct {
|
||||
// LaneConfig defines the base lane configuration.
|
||||
*blockbuster.LaneConstructor[string]
|
||||
|
||||
// Factory defines the API/functionality which is responsible for determining
|
||||
// if a transaction is a bid transaction and how to extract relevant
|
||||
// information from the transaction (bid, timeout, bidder, etc.).
|
||||
Factory
|
||||
}
|
||||
// Factory defines the API/functionality which is responsible for determining
|
||||
// if a transaction is a bid transaction and how to extract relevant
|
||||
// information from the transaction (bid, timeout, bidder, etc.).
|
||||
Factory
|
||||
}
|
||||
)
|
||||
|
||||
// NewTOBLane returns a new TOB lane.
|
||||
func NewTOBLane(
|
||||
cfg blockbuster.BaseLaneConfig,
|
||||
maxTx int,
|
||||
af Factory,
|
||||
cfg blockbuster.LaneConfig,
|
||||
factory Factory,
|
||||
) *TOBLane {
|
||||
if err := cfg.ValidateBasic(); err != nil {
|
||||
panic(err)
|
||||
lane := &TOBLane{
|
||||
LaneConstructor: blockbuster.NewLaneConstructor[string](
|
||||
cfg,
|
||||
LaneName,
|
||||
blockbuster.NewConstructorMempool[string](
|
||||
TxPriority(factory),
|
||||
cfg.TxEncoder,
|
||||
cfg.MaxTxs,
|
||||
),
|
||||
factory.MatchHandler(),
|
||||
),
|
||||
Factory: factory,
|
||||
}
|
||||
|
||||
return &TOBLane{
|
||||
Mempool: NewMempool(cfg.TxEncoder, maxTx, af),
|
||||
DefaultLane: base.NewDefaultLane(cfg).WithName(LaneName),
|
||||
Factory: af,
|
||||
}
|
||||
}
|
||||
|
||||
// Match returns true if the transaction is a bid transaction. This is determined
|
||||
// by the AuctionFactory.
|
||||
func (l *TOBLane) Match(ctx sdk.Context, tx sdk.Tx) bool {
|
||||
if l.MatchIgnoreList(ctx, tx) {
|
||||
return false
|
||||
}
|
||||
|
||||
bidInfo, err := l.GetAuctionBidInfo(tx)
|
||||
return bidInfo != nil && err == nil
|
||||
// Set the prepare lane handler to the TOB one
|
||||
lane.SetPrepareLaneHandler(lane.PrepareLaneHandler())
|
||||
|
||||
// Set the process lane handler to the TOB one
|
||||
lane.SetProcessLaneHandler(lane.ProcessLaneHandler())
|
||||
|
||||
// Set the check order handler to the TOB one
|
||||
lane.SetCheckOrderHandler(lane.CheckOrderHandler())
|
||||
|
||||
return lane
|
||||
}
|
||||
|
||||
@ -2,48 +2,9 @@ package auction
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
"github.com/skip-mev/pob/blockbuster"
|
||||
"github.com/skip-mev/pob/blockbuster/utils"
|
||||
)
|
||||
|
||||
var _ Mempool = (*TOBMempool)(nil)
|
||||
|
||||
type (
|
||||
// Mempool defines the interface of the auction mempool.
|
||||
Mempool interface {
|
||||
sdkmempool.Mempool
|
||||
|
||||
// GetTopAuctionTx returns the highest bidding transaction in the auction mempool.
|
||||
GetTopAuctionTx(ctx context.Context) sdk.Tx
|
||||
|
||||
// Contains returns true if the transaction is contained in the mempool.
|
||||
Contains(tx sdk.Tx) bool
|
||||
}
|
||||
|
||||
// TOBMempool defines an auction mempool. It can be seen as an extension of
|
||||
// an SDK PriorityNonceMempool, i.e. a mempool that supports <sender, nonce>
|
||||
// two-dimensional priority ordering, with the additional support of prioritizing
|
||||
// and indexing auction bids.
|
||||
TOBMempool struct {
|
||||
// index defines an index of auction bids.
|
||||
index sdkmempool.Mempool
|
||||
|
||||
// txEncoder defines the sdk.Tx encoder that allows us to encode transactions
|
||||
// to bytes.
|
||||
txEncoder sdk.TxEncoder
|
||||
|
||||
// txIndex is a map of all transactions in the mempool. It is used
|
||||
// to quickly check if a transaction is already in the mempool.
|
||||
txIndex map[string]struct{}
|
||||
|
||||
// Factory implements the functionality required to process auction transactions.
|
||||
Factory
|
||||
}
|
||||
)
|
||||
|
||||
// TxPriority returns a TxPriority over auction bid transactions only. It
|
||||
@ -89,78 +50,13 @@ func TxPriority(config Factory) blockbuster.TxPriority[string] {
|
||||
}
|
||||
}
|
||||
|
||||
// NewMempool returns a new auction mempool.
|
||||
func NewMempool(txEncoder sdk.TxEncoder, maxTx int, config Factory) *TOBMempool {
|
||||
return &TOBMempool{
|
||||
index: blockbuster.NewPriorityMempool(
|
||||
blockbuster.PriorityNonceMempoolConfig[string]{
|
||||
TxPriority: TxPriority(config),
|
||||
MaxTx: maxTx,
|
||||
},
|
||||
),
|
||||
txEncoder: txEncoder,
|
||||
txIndex: make(map[string]struct{}),
|
||||
Factory: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Insert inserts a transaction into the auction mempool.
|
||||
func (am *TOBMempool) Insert(ctx context.Context, tx sdk.Tx) error {
|
||||
if err := am.index.Insert(ctx, tx); err != nil {
|
||||
return fmt.Errorf("failed to insert tx into auction index: %w", err)
|
||||
}
|
||||
|
||||
_, txHashStr, err := utils.GetTxHashStr(am.txEncoder, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
am.txIndex[txHashStr] = struct{}{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes a transaction from the mempool based.
|
||||
func (am *TOBMempool) Remove(tx sdk.Tx) error {
|
||||
if err := am.index.Remove(tx); err != nil && !errors.Is(err, sdkmempool.ErrTxNotFound) {
|
||||
return fmt.Errorf("failed to remove invalid transaction from the mempool: %w", err)
|
||||
}
|
||||
|
||||
_, txHashStr, err := utils.GetTxHashStr(am.txEncoder, tx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get tx hash string: %w", err)
|
||||
}
|
||||
|
||||
delete(am.txIndex, txHashStr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTopAuctionTx returns the highest bidding transaction in the auction mempool.
|
||||
func (am *TOBMempool) GetTopAuctionTx(ctx context.Context) sdk.Tx {
|
||||
iterator := am.index.Select(ctx, nil)
|
||||
// This is primarily a helper function for the x/builder module.
|
||||
func (l *TOBLane) GetTopAuctionTx(ctx context.Context) sdk.Tx {
|
||||
iterator := l.Select(ctx, nil)
|
||||
if iterator == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return iterator.Tx()
|
||||
}
|
||||
|
||||
func (am *TOBMempool) Select(ctx context.Context, txs [][]byte) sdkmempool.Iterator {
|
||||
return am.index.Select(ctx, txs)
|
||||
}
|
||||
|
||||
func (am *TOBMempool) CountTx() int {
|
||||
return am.index.CountTx()
|
||||
}
|
||||
|
||||
// Contains returns true if the transaction is contained in the mempool.
|
||||
func (am *TOBMempool) Contains(tx sdk.Tx) bool {
|
||||
_, txHashStr, err := utils.GetTxHashStr(am.txEncoder, tx)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
_, ok := am.txIndex[txHashStr]
|
||||
return ok
|
||||
}
|
||||
|
||||
@ -31,11 +31,15 @@ type (
|
||||
GetLane(name string) (Lane, error)
|
||||
}
|
||||
|
||||
// Mempool defines the Blockbuster mempool implement. It contains a registry
|
||||
// BBMempool defines the Blockbuster mempool implementation. It contains a registry
|
||||
// of lanes, which allows for customizable block proposal construction.
|
||||
BBMempool struct {
|
||||
logger log.Logger
|
||||
|
||||
// registry contains the lanes in the mempool. The lanes are ordered
|
||||
// according to their priority. The first lane in the registry has the
|
||||
// highest priority and the last lane has the lowest priority.
|
||||
registry []Lane
|
||||
logger log.Logger
|
||||
}
|
||||
)
|
||||
|
||||
@ -47,8 +51,10 @@ type (
|
||||
// registry. Each transaction should only belong in one lane but this is NOT enforced.
|
||||
// To enforce that each transaction belong to a single lane, you must configure the
|
||||
// ignore list of each lane to include all preceding lanes. Basic mempool API will
|
||||
// attempt to insert, remove transactions from all lanes it belongs to.
|
||||
func NewMempool(logger log.Logger, lanes ...Lane) *BBMempool {
|
||||
// attempt to insert, remove transactions from all lanes it belongs to. It is recommended,
|
||||
// that mutex is set to true when creating the mempool. This will ensure that each
|
||||
// transaction cannot be inserted into the lanes before it.
|
||||
func NewMempool(logger log.Logger, mutex bool, lanes ...Lane) *BBMempool {
|
||||
mempool := &BBMempool{
|
||||
logger: logger,
|
||||
registry: lanes,
|
||||
@ -58,6 +64,16 @@ func NewMempool(logger log.Logger, lanes ...Lane) *BBMempool {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Set the ignore list for each lane
|
||||
if mutex {
|
||||
registry := mempool.registry
|
||||
for index, lane := range mempool.registry {
|
||||
if index > 0 {
|
||||
lane.SetIgnoreList(registry[:index])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mempool
|
||||
}
|
||||
|
||||
@ -85,7 +101,14 @@ func (m *BBMempool) GetTxDistribution() map[string]int {
|
||||
|
||||
// Insert will insert a transaction into the mempool. It inserts the transaction
|
||||
// into the first lane that it matches.
|
||||
func (m *BBMempool) Insert(ctx context.Context, tx sdk.Tx) error {
|
||||
func (m *BBMempool) Insert(ctx context.Context, tx sdk.Tx) (err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
m.logger.Error("panic in Insert", "err", r)
|
||||
err = fmt.Errorf("panic in Insert: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
var errors []string
|
||||
|
||||
unwrappedCtx := sdk.UnwrapSDKContext(ctx)
|
||||
@ -118,7 +141,14 @@ func (m *BBMempool) Select(_ context.Context, _ [][]byte) sdkmempool.Iterator {
|
||||
}
|
||||
|
||||
// Remove removes a transaction from all of the lanes it is currently in.
|
||||
func (m *BBMempool) Remove(tx sdk.Tx) error {
|
||||
func (m *BBMempool) Remove(tx sdk.Tx) (err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
m.logger.Error("panic in Remove", "err", r)
|
||||
err = fmt.Errorf("panic in Remove: %v", r)
|
||||
}
|
||||
}()
|
||||
|
||||
var errors []string
|
||||
|
||||
for _, lane := range m.registry {
|
||||
@ -149,7 +179,14 @@ func (m *BBMempool) Remove(tx sdk.Tx) error {
|
||||
}
|
||||
|
||||
// Contains returns true if the transaction is contained in any of the lanes.
|
||||
func (m *BBMempool) Contains(tx sdk.Tx) bool {
|
||||
func (m *BBMempool) Contains(tx sdk.Tx) (contains bool) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
m.logger.Error("panic in Contains", "err", r)
|
||||
contains = false
|
||||
}
|
||||
}()
|
||||
|
||||
for _, lane := range m.registry {
|
||||
if lane.Contains(tx) {
|
||||
return true
|
||||
@ -164,7 +201,10 @@ func (m *BBMempool) Registry() []Lane {
|
||||
return m.registry
|
||||
}
|
||||
|
||||
// ValidateBasic validates the mempools configuration.
|
||||
// ValidateBasic validates the mempools configuration. ValidateBasic ensures
|
||||
// the following:
|
||||
// - The sum of the lane max block space percentages is less than or equal to 1.
|
||||
// - There is no unused block space.
|
||||
func (m *BBMempool) ValidateBasic() error {
|
||||
sum := math.LegacyZeroDec()
|
||||
seenZeroMaxBlockSpace := false
|
||||
|
||||
@ -27,9 +27,10 @@ type BlockBusterTestSuite struct {
|
||||
encodingConfig testutils.EncodingConfig
|
||||
|
||||
// Define all of the lanes utilized in the test suite
|
||||
tobLane *auction.TOBLane
|
||||
baseLane *base.DefaultLane
|
||||
freeLane *free.Lane
|
||||
tobLane *auction.TOBLane
|
||||
baseLane *base.DefaultLane
|
||||
freeLane *free.FreeLane
|
||||
gasTokenDenom string
|
||||
|
||||
lanes []blockbuster.Lane
|
||||
mempool blockbuster.Mempool
|
||||
@ -55,7 +56,8 @@ func (suite *BlockBusterTestSuite) SetupTest() {
|
||||
// Lanes configuration
|
||||
//
|
||||
// TOB lane set up
|
||||
tobConfig := blockbuster.BaseLaneConfig{
|
||||
suite.gasTokenDenom = "stake"
|
||||
tobConfig := blockbuster.LaneConfig{
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
@ -64,37 +66,30 @@ func (suite *BlockBusterTestSuite) SetupTest() {
|
||||
}
|
||||
suite.tobLane = auction.NewTOBLane(
|
||||
tobConfig,
|
||||
0, // No bound on the number of transactions in the lane
|
||||
auction.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
|
||||
)
|
||||
|
||||
// Free lane set up
|
||||
freeConfig := blockbuster.BaseLaneConfig{
|
||||
freeConfig := blockbuster.LaneConfig{
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []blockbuster.Lane{
|
||||
suite.tobLane,
|
||||
},
|
||||
}
|
||||
suite.freeLane = free.NewFreeLane(
|
||||
freeConfig,
|
||||
free.NewDefaultFreeFactory(suite.encodingConfig.TxConfig.TxDecoder()),
|
||||
blockbuster.DefaultTxPriority(),
|
||||
free.DefaultMatchHandler(),
|
||||
)
|
||||
|
||||
// Base lane set up
|
||||
baseConfig := blockbuster.BaseLaneConfig{
|
||||
baseConfig := blockbuster.LaneConfig{
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []blockbuster.Lane{
|
||||
suite.tobLane,
|
||||
suite.freeLane,
|
||||
},
|
||||
}
|
||||
suite.baseLane = base.NewDefaultLane(
|
||||
baseConfig,
|
||||
@ -102,7 +97,7 @@ func (suite *BlockBusterTestSuite) SetupTest() {
|
||||
|
||||
// Mempool set up
|
||||
suite.lanes = []blockbuster.Lane{suite.tobLane, suite.freeLane, suite.baseLane}
|
||||
suite.mempool = blockbuster.NewMempool(log.NewTestLogger(suite.T()), suite.lanes...)
|
||||
suite.mempool = blockbuster.NewMempool(log.NewTestLogger(suite.T()), true, suite.lanes...)
|
||||
|
||||
// Accounts set up
|
||||
suite.accounts = testutils.RandomAccounts(suite.random, 10)
|
||||
@ -328,12 +323,12 @@ func (suite *BlockBusterTestSuite) fillBaseLane(numTxs int) {
|
||||
// create a few random msgs and construct the tx
|
||||
nonce := suite.nonces[acc.Address.String()]
|
||||
randomMsgs := testutils.CreateRandomMsgs(acc.Address, 3)
|
||||
tx, err := testutils.CreateTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, randomMsgs)
|
||||
priority := suite.random.Int63n(100) + 1
|
||||
tx, err := testutils.CreateTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, randomMsgs, sdk.NewCoin(suite.gasTokenDenom, math.NewInt(priority)))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// insert the tx into the lane and update the account
|
||||
suite.nonces[acc.Address.String()]++
|
||||
priority := suite.random.Int63n(100) + 1
|
||||
suite.Require().NoError(suite.mempool.Insert(suite.ctx.WithPriority(priority), tx))
|
||||
}
|
||||
}
|
||||
@ -348,7 +343,7 @@ func (suite *BlockBusterTestSuite) fillTOBLane(numTxs int) {
|
||||
// create a randomized auction transaction
|
||||
nonce := suite.nonces[acc.Address.String()]
|
||||
bidAmount := math.NewInt(int64(suite.random.Intn(1000) + 1))
|
||||
bid := sdk.NewCoin("stake", bidAmount)
|
||||
bid := sdk.NewCoin(suite.gasTokenDenom, bidAmount)
|
||||
tx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, acc, bid, nonce, 1000, nil)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
@ -367,7 +362,7 @@ func (suite *BlockBusterTestSuite) fillFreeLane(numTxs int) {
|
||||
|
||||
// create a few random msgs and construct the tx
|
||||
nonce := suite.nonces[acc.Address.String()]
|
||||
tx, err := testutils.CreateFreeTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, "val1", sdk.NewCoin("stake", math.NewInt(100)))
|
||||
tx, err := testutils.CreateFreeTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, "val1", sdk.NewCoin(suite.gasTokenDenom, math.NewInt(100)), sdk.NewCoin(suite.gasTokenDenom, math.NewInt(100)))
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// insert the tx into the lane and update the account
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
// Lane defines the required functionality for a lane. The ignore decorator
|
||||
// Lane defines the required API dependencies for the IgnoreDecorator. The ignore decorator
|
||||
// will check if a transaction belongs to a lane by calling the Match function.
|
||||
Lane interface {
|
||||
Match(ctx sdk.Context, tx sdk.Tx) bool
|
||||
|
||||
@ -62,10 +62,10 @@ import (
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
|
||||
"github.com/skip-mev/pob/blockbuster"
|
||||
"github.com/skip-mev/pob/blockbuster/abci"
|
||||
"github.com/skip-mev/pob/blockbuster/lanes/auction"
|
||||
"github.com/skip-mev/pob/blockbuster/lanes/base"
|
||||
"github.com/skip-mev/pob/blockbuster/lanes/free"
|
||||
"github.com/skip-mev/pob/blockbuster/proposals"
|
||||
buildermodule "github.com/skip-mev/pob/x/builder"
|
||||
builderkeeper "github.com/skip-mev/pob/x/builder/keeper"
|
||||
)
|
||||
@ -139,7 +139,7 @@ type TestApp struct {
|
||||
FeeGrantKeeper feegrantkeeper.Keeper
|
||||
|
||||
// custom checkTx handler
|
||||
checkTxHandler abci.CheckTx
|
||||
checkTxHandler proposals.CheckTx
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -262,43 +262,39 @@ func New(
|
||||
// NOTE: The lanes are ordered by priority. The first lane is the highest priority
|
||||
// lane and the last lane is the lowest priority lane.
|
||||
// Top of block lane allows transactions to bid for inclusion at the top of the next block.
|
||||
tobConfig := blockbuster.BaseLaneConfig{
|
||||
tobConfig := blockbuster.LaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(), // This means the lane has no limit on block space.
|
||||
MaxTxs: 0, // This means the lane has no limit on the number of transactions it can store.
|
||||
}
|
||||
tobLane := auction.NewTOBLane(
|
||||
tobConfig,
|
||||
0,
|
||||
auction.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
|
||||
)
|
||||
|
||||
// Free lane allows transactions to be included in the next block for free.
|
||||
freeConfig := blockbuster.BaseLaneConfig{
|
||||
freeConfig := blockbuster.LaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []blockbuster.Lane{
|
||||
tobLane,
|
||||
},
|
||||
MaxTxs: 0,
|
||||
}
|
||||
freeLane := free.NewFreeLane(
|
||||
freeConfig,
|
||||
free.NewDefaultFreeFactory(app.txConfig.TxDecoder()),
|
||||
blockbuster.DefaultTxPriority(),
|
||||
free.DefaultMatchHandler(),
|
||||
)
|
||||
|
||||
// Default lane accepts all other transactions.
|
||||
defaultConfig := blockbuster.BaseLaneConfig{
|
||||
defaultConfig := blockbuster.LaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []blockbuster.Lane{
|
||||
tobLane,
|
||||
freeLane,
|
||||
},
|
||||
MaxTxs: 0,
|
||||
}
|
||||
defaultLane := base.NewDefaultLane(defaultConfig)
|
||||
|
||||
@ -308,7 +304,7 @@ func New(
|
||||
freeLane,
|
||||
defaultLane,
|
||||
}
|
||||
mempool := blockbuster.NewMempool(app.Logger(), lanes...)
|
||||
mempool := blockbuster.NewMempool(app.Logger(), true, lanes...)
|
||||
app.App.SetMempool(mempool)
|
||||
|
||||
// Create a global ante handler that will be called on each transaction when
|
||||
@ -338,16 +334,16 @@ func New(
|
||||
app.App.SetAnteHandler(anteHandler)
|
||||
|
||||
// Set the proposal handlers on base app
|
||||
proposalHandler := abci.NewProposalHandler(
|
||||
proposalHandler := proposals.NewProposalHandler(
|
||||
app.Logger(),
|
||||
app.TxConfig().TxDecoder(),
|
||||
mempool,
|
||||
lanes,
|
||||
)
|
||||
app.App.SetPrepareProposal(proposalHandler.PrepareProposalHandler())
|
||||
app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
|
||||
|
||||
// Set the custom CheckTx handler on BaseApp.
|
||||
checkTxHandler := abci.NewCheckTxHandler(
|
||||
checkTxHandler := proposals.NewCheckTxHandler(
|
||||
app.App,
|
||||
app.txConfig.TxDecoder(),
|
||||
tobLane,
|
||||
@ -396,7 +392,7 @@ func (app *TestApp) CheckTx(req *cometabci.RequestCheckTx) (*cometabci.ResponseC
|
||||
}
|
||||
|
||||
// SetCheckTx sets the checkTxHandler for the app.
|
||||
func (app *TestApp) SetCheckTx(handler abci.CheckTx) {
|
||||
func (app *TestApp) SetCheckTx(handler proposals.CheckTx) {
|
||||
app.checkTxHandler = handler
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
// Lanes configuration
|
||||
//
|
||||
// TOB lane set up
|
||||
tobConfig := blockbuster.BaseLaneConfig{
|
||||
tobConfig := blockbuster.LaneConfig{
|
||||
Logger: suite.ctx.Logger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
@ -92,12 +92,11 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
}
|
||||
suite.tobLane = auction.NewTOBLane(
|
||||
tobConfig,
|
||||
0, // No bound on the number of transactions in the lane
|
||||
auction.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
|
||||
)
|
||||
|
||||
// Base lane set up
|
||||
baseConfig := blockbuster.BaseLaneConfig{
|
||||
baseConfig := blockbuster.LaneConfig{
|
||||
Logger: suite.ctx.Logger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
@ -109,7 +108,7 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
|
||||
// Mempool set up
|
||||
suite.lanes = []blockbuster.Lane{suite.tobLane, suite.baseLane}
|
||||
suite.mempool = blockbuster.NewMempool(log.NewTestLogger(suite.T()), suite.lanes...)
|
||||
suite.mempool = blockbuster.NewMempool(log.NewTestLogger(suite.T()), true, suite.lanes...)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) anteHandler(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user