feat(bb): Defer in proposal handlers, more interfaces for lanes, clean up (#165)
This commit is contained in:
+14
-7
@@ -7,32 +7,39 @@ import (
|
||||
|
||||
"cosmossdk.io/errors"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/skip-mev/pob/mempool"
|
||||
"github.com/skip-mev/pob/x/builder/keeper"
|
||||
"github.com/skip-mev/pob/x/builder/types"
|
||||
)
|
||||
|
||||
var _ sdk.AnteDecorator = BuilderDecorator{}
|
||||
|
||||
type (
|
||||
// TOBLane is an interface that defines the methods required to interact with the top of block
|
||||
// lane.
|
||||
TOBLane interface {
|
||||
GetAuctionBidInfo(tx sdk.Tx) (*types.BidInfo, error)
|
||||
GetTopAuctionTx(ctx context.Context) sdk.Tx
|
||||
}
|
||||
|
||||
// Mempool is an interface that defines the methods required to interact with the application-side mempool.
|
||||
Mempool interface {
|
||||
Contains(tx sdk.Tx) (bool, error)
|
||||
GetAuctionBidInfo(tx sdk.Tx) (*mempool.AuctionBidInfo, error)
|
||||
GetTopAuctionTx(ctx context.Context) sdk.Tx
|
||||
}
|
||||
|
||||
// BuilderDecorator is an AnteDecorator that validates the auction bid and bundled transactions.
|
||||
BuilderDecorator struct {
|
||||
builderKeeper keeper.Keeper
|
||||
txEncoder sdk.TxEncoder
|
||||
lane TOBLane
|
||||
mempool Mempool
|
||||
}
|
||||
)
|
||||
|
||||
func NewBuilderDecorator(ak keeper.Keeper, txEncoder sdk.TxEncoder, mempool Mempool) BuilderDecorator {
|
||||
func NewBuilderDecorator(ak keeper.Keeper, txEncoder sdk.TxEncoder, lane TOBLane, mempool Mempool) BuilderDecorator {
|
||||
return BuilderDecorator{
|
||||
builderKeeper: ak,
|
||||
txEncoder: txEncoder,
|
||||
lane: lane,
|
||||
mempool: mempool,
|
||||
}
|
||||
}
|
||||
@@ -52,7 +59,7 @@ func (bd BuilderDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
}
|
||||
}
|
||||
|
||||
bidInfo, err := bd.mempool.GetAuctionBidInfo(tx)
|
||||
bidInfo, err := bd.lane.GetAuctionBidInfo(tx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
@@ -70,7 +77,7 @@ func (bd BuilderDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
// poor liveness guarantees.
|
||||
topBid := sdk.Coin{}
|
||||
if ctx.IsCheckTx() || ctx.IsReCheckTx() {
|
||||
if topBidTx := bd.mempool.GetTopAuctionTx(ctx); topBidTx != nil {
|
||||
if topBidTx := bd.lane.GetTopAuctionTx(ctx); topBidTx != nil {
|
||||
topBidBz, err := bd.txEncoder(topBidTx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
@@ -83,7 +90,7 @@ func (bd BuilderDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
|
||||
// Compare the bytes to see if the current transaction is the highest bidding transaction.
|
||||
if !bytes.Equal(topBidBz, currentTxBz) {
|
||||
topBidInfo, err := bd.mempool.GetAuctionBidInfo(topBidTx)
|
||||
topBidInfo, err := bd.lane.GetAuctionBidInfo(topBidTx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
+52
-14
@@ -9,7 +9,9 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/skip-mev/pob/mempool"
|
||||
"github.com/skip-mev/pob/blockbuster"
|
||||
"github.com/skip-mev/pob/blockbuster/lanes/auction"
|
||||
"github.com/skip-mev/pob/blockbuster/lanes/base"
|
||||
testutils "github.com/skip-mev/pob/testutils"
|
||||
"github.com/skip-mev/pob/x/builder/ante"
|
||||
"github.com/skip-mev/pob/x/builder/keeper"
|
||||
@@ -21,7 +23,6 @@ type AnteTestSuite struct {
|
||||
suite.Suite
|
||||
ctx sdk.Context
|
||||
|
||||
// mempool setup
|
||||
encodingConfig testutils.EncodingConfig
|
||||
random *rand.Rand
|
||||
|
||||
@@ -34,6 +35,15 @@ type AnteTestSuite struct {
|
||||
builderDecorator ante.BuilderDecorator
|
||||
key *storetypes.KVStoreKey
|
||||
authorityAccount sdk.AccAddress
|
||||
|
||||
// mempool and lane set up
|
||||
mempool blockbuster.Mempool
|
||||
tobLane *auction.TOBLane
|
||||
baseLane *base.DefaultLane
|
||||
lanes []blockbuster.Lane
|
||||
|
||||
// Account set up
|
||||
balance sdk.Coins
|
||||
}
|
||||
|
||||
func TestAnteTestSuite(t *testing.T) {
|
||||
@@ -67,17 +77,40 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
)
|
||||
err := suite.builderKeeper.SetParams(suite.ctx, buildertypes.DefaultParams())
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Lanes configuration
|
||||
//
|
||||
// TOB lane set up
|
||||
config := blockbuster.BaseLaneConfig{
|
||||
Logger: suite.ctx.Logger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: suite.anteHandler,
|
||||
MaxBlockSpace: sdk.ZeroDec(),
|
||||
}
|
||||
suite.tobLane = auction.NewTOBLane(
|
||||
config,
|
||||
0, // No bound on the number of transactions in the lane
|
||||
auction.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
|
||||
)
|
||||
|
||||
// Base lane set up
|
||||
suite.baseLane = base.NewDefaultLane(config)
|
||||
|
||||
// Mempool set up
|
||||
suite.lanes = []blockbuster.Lane{suite.tobLane, suite.baseLane}
|
||||
suite.mempool = blockbuster.NewMempool(suite.lanes...)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) executeAnteHandler(tx sdk.Tx, balance sdk.Coins) (sdk.Context, error) {
|
||||
func (suite *AnteTestSuite) anteHandler(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
|
||||
signer := tx.GetMsgs()[0].GetSigners()[0]
|
||||
suite.bankKeeper.EXPECT().GetAllBalances(suite.ctx, signer).AnyTimes().Return(balance)
|
||||
suite.bankKeeper.EXPECT().GetAllBalances(ctx, signer).AnyTimes().Return(suite.balance)
|
||||
|
||||
next := func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) {
|
||||
next := func(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
return suite.builderDecorator.AnteHandle(suite.ctx, tx, false, next)
|
||||
return suite.builderDecorator.AnteHandle(ctx, tx, false, next)
|
||||
}
|
||||
|
||||
func (suite *AnteTestSuite) TestAnteHandler() {
|
||||
@@ -232,15 +265,19 @@ func (suite *AnteTestSuite) TestAnteHandler() {
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Insert the top bid into the mempool
|
||||
config := mempool.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder())
|
||||
mempool := mempool.NewAuctionMempool(suite.encodingConfig.TxConfig.TxDecoder(), suite.encodingConfig.TxConfig.TxEncoder(), 0, config)
|
||||
if insertTopBid {
|
||||
topAuctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, topBidder, topBid, 0, timeout, []testutils.Account{})
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(0, mempool.CountTx())
|
||||
suite.Require().Equal(0, mempool.CountAuctionTx())
|
||||
suite.Require().NoError(mempool.Insert(suite.ctx, topAuctionTx))
|
||||
suite.Require().Equal(1, mempool.CountAuctionTx())
|
||||
|
||||
distribution := suite.mempool.GetTxDistribution()
|
||||
suite.Require().Equal(0, distribution[auction.LaneName])
|
||||
suite.Require().Equal(0, distribution[base.LaneName])
|
||||
|
||||
suite.Require().NoError(suite.mempool.Insert(suite.ctx, topAuctionTx))
|
||||
|
||||
distribution = suite.mempool.GetTxDistribution()
|
||||
suite.Require().Equal(1, distribution[auction.LaneName])
|
||||
suite.Require().Equal(0, distribution[base.LaneName])
|
||||
}
|
||||
|
||||
// Create the actual auction tx and insert into the mempool
|
||||
@@ -248,8 +285,9 @@ func (suite *AnteTestSuite) TestAnteHandler() {
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Execute the ante handler
|
||||
suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxEncoder(), mempool)
|
||||
_, err = suite.executeAnteHandler(auctionTx, balance)
|
||||
suite.balance = balance
|
||||
suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxEncoder(), suite.tobLane, suite.mempool)
|
||||
_, err = suite.anteHandler(suite.ctx, auctionTx, false)
|
||||
if tc.pass {
|
||||
suite.Require().NoError(err)
|
||||
} else {
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/skip-mev/pob/mempool"
|
||||
"github.com/skip-mev/pob/x/builder/types"
|
||||
)
|
||||
|
||||
// ValidateBidInfo validates that the bid can be included in the auction.
|
||||
func (k Keeper) ValidateBidInfo(ctx sdk.Context, highestBid sdk.Coin, bidInfo *mempool.AuctionBidInfo) error {
|
||||
func (k Keeper) ValidateBidInfo(ctx sdk.Context, highestBid sdk.Coin, bidInfo *types.BidInfo) error {
|
||||
// Validate the bundle size.
|
||||
maxBundleSize, err := k.GetMaxBundleSize(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -5,10 +5,9 @@ import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/skip-mev/pob/mempool"
|
||||
testutils "github.com/skip-mev/pob/testutils"
|
||||
"github.com/skip-mev/pob/x/builder/keeper"
|
||||
buildertypes "github.com/skip-mev/pob/x/builder/types"
|
||||
"github.com/skip-mev/pob/x/builder/types"
|
||||
)
|
||||
|
||||
func (suite *KeeperTestSuite) TestValidateBidInfo() {
|
||||
@@ -162,7 +161,7 @@ func (suite *KeeperTestSuite) TestValidateBidInfo() {
|
||||
suite.stakingKeeper,
|
||||
suite.authorityAccount.String(),
|
||||
)
|
||||
params := buildertypes.Params{
|
||||
params := types.Params{
|
||||
MaxBundleSize: maxBundleSize,
|
||||
ReserveFee: reserveFee,
|
||||
EscrowAccountAddress: escrowAddress.String(),
|
||||
@@ -191,7 +190,7 @@ func (suite *KeeperTestSuite) TestValidateBidInfo() {
|
||||
signers[index] = txSigners
|
||||
}
|
||||
|
||||
bidInfo := &mempool.AuctionBidInfo{
|
||||
bidInfo := &types.BidInfo{
|
||||
Bidder: bidder.Address,
|
||||
Bid: bid,
|
||||
Transactions: bundle,
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/skip-mev/pob/mempool"
|
||||
testutils "github.com/skip-mev/pob/testutils"
|
||||
"github.com/skip-mev/pob/x/builder/keeper"
|
||||
"github.com/skip-mev/pob/x/builder/types"
|
||||
@@ -28,8 +27,6 @@ type KeeperTestSuite struct {
|
||||
msgServer types.MsgServer
|
||||
key *storetypes.KVStoreKey
|
||||
authorityAccount sdk.AccAddress
|
||||
|
||||
mempool *mempool.AuctionMempool
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
@@ -64,7 +61,5 @@ func (suite *KeeperTestSuite) SetupTest() {
|
||||
err := suite.builderKeeper.SetParams(suite.ctx, types.DefaultParams())
|
||||
suite.Require().NoError(err)
|
||||
|
||||
config := mempool.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder())
|
||||
suite.mempool = mempool.NewAuctionMempool(suite.encCfg.TxConfig.TxDecoder(), suite.encCfg.TxConfig.TxEncoder(), 0, config)
|
||||
suite.msgServer = keeper.NewMsgServerImpl(suite.builderKeeper)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package types
|
||||
|
||||
import sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
// BidInfo defines the information about a bid to the auction house.
|
||||
type BidInfo struct {
|
||||
Bidder sdk.AccAddress
|
||||
Bid sdk.Coin
|
||||
Transactions [][]byte
|
||||
Timeout uint64
|
||||
Signers []map[string]struct{}
|
||||
}
|
||||
Reference in New Issue
Block a user