feat(bb): Defer in proposal handlers, more interfaces for lanes, clean up (#165)

This commit is contained in:
David Terpay
2023-06-07 13:47:34 +00:00
committed by GitHub
parent 61b6759e92
commit b7780a3140
41 changed files with 1798 additions and 3320 deletions
+14 -7
View File
@@ -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
View File
@@ -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 {
+2 -2
View File
@@ -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 {
+3 -4
View File
@@ -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,
-5
View File
@@ -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)
}
+12
View File
@@ -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{}
}