[ENG-702]: Caching context when iterating through auctions (#56)
This commit is contained in:
parent
acaf60e5b8
commit
06812560fc
66
abci/abci.go
66
abci/abci.go
@ -9,33 +9,32 @@ import (
|
||||
|
||||
abci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
"github.com/skip-mev/pob/mempool"
|
||||
)
|
||||
|
||||
type ProposalHandler struct {
|
||||
mempool *mempool.AuctionMempool
|
||||
logger log.Logger
|
||||
txVerifier baseapp.ProposalTxVerifier
|
||||
txEncoder sdk.TxEncoder
|
||||
txDecoder sdk.TxDecoder
|
||||
mempool *mempool.AuctionMempool
|
||||
logger log.Logger
|
||||
anteHandler sdk.AnteHandler
|
||||
txEncoder sdk.TxEncoder
|
||||
txDecoder sdk.TxDecoder
|
||||
}
|
||||
|
||||
func NewProposalHandler(
|
||||
mp *mempool.AuctionMempool,
|
||||
logger log.Logger,
|
||||
txVerifier baseapp.ProposalTxVerifier,
|
||||
anteHandler sdk.AnteHandler,
|
||||
txEncoder sdk.TxEncoder,
|
||||
txDecoder sdk.TxDecoder,
|
||||
) *ProposalHandler {
|
||||
return &ProposalHandler{
|
||||
mempool: mp,
|
||||
logger: logger,
|
||||
txVerifier: txVerifier,
|
||||
txEncoder: txEncoder,
|
||||
txDecoder: txDecoder,
|
||||
mempool: mp,
|
||||
logger: logger,
|
||||
anteHandler: anteHandler,
|
||||
txEncoder: txEncoder,
|
||||
txDecoder: txDecoder,
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,9 +55,10 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
|
||||
// bundled transactions are valid.
|
||||
selectBidTxLoop:
|
||||
for ; bidTxIterator != nil; bidTxIterator = bidTxIterator.Next() {
|
||||
cacheCtx, write := ctx.CacheContext()
|
||||
tmpBidTx := bidTxIterator.Tx()
|
||||
|
||||
bidTxBz, err := h.txVerifier.PrepareProposalVerifyTx(tmpBidTx)
|
||||
bidTxBz, err := h.PrepareProposalVerifyTx(cacheCtx, tmpBidTx)
|
||||
if err != nil {
|
||||
txsToRemove[tmpBidTx] = struct{}{}
|
||||
continue selectBidTxLoop
|
||||
@ -84,7 +84,7 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
|
||||
continue selectBidTxLoop
|
||||
}
|
||||
|
||||
if _, err := h.txVerifier.PrepareProposalVerifyTx(refTx); err != nil {
|
||||
if _, err := h.PrepareProposalVerifyTx(cacheCtx, refTx); err != nil {
|
||||
// Invalid bundled transaction, so we remove the bid transaction
|
||||
// and try the next top bid.
|
||||
txsToRemove[tmpBidTx] = struct{}{}
|
||||
@ -106,6 +106,10 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
|
||||
seenTxs[txHash] = struct{}{}
|
||||
}
|
||||
|
||||
// Write the cache context to the original context when we know we have a
|
||||
// valid top of block bundle.
|
||||
write()
|
||||
|
||||
break selectBidTxLoop
|
||||
}
|
||||
|
||||
@ -144,7 +148,7 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
|
||||
continue selectTxLoop
|
||||
}
|
||||
|
||||
txBz, err = h.txVerifier.PrepareProposalVerifyTx(memTx)
|
||||
txBz, err = h.PrepareProposalVerifyTx(ctx, memTx)
|
||||
if err != nil {
|
||||
txsToRemove[memTx] = struct{}{}
|
||||
continue selectTxLoop
|
||||
@ -174,7 +178,7 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
|
||||
func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
|
||||
return func(ctx sdk.Context, req abci.RequestProcessProposal) abci.ResponseProcessProposal {
|
||||
for index, txBz := range req.Txs {
|
||||
tx, err := h.txVerifier.ProcessProposalVerifyTx(txBz)
|
||||
tx, err := h.ProcessProposalVerifyTx(ctx, txBz)
|
||||
if err != nil {
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
|
||||
}
|
||||
@ -208,6 +212,36 @@ func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// PrepareProposalVerifyTx encodes a transaction and verifies it.
|
||||
func (h *ProposalHandler) PrepareProposalVerifyTx(ctx sdk.Context, tx sdk.Tx) ([]byte, error) {
|
||||
txBz, err := h.txEncoder(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return txBz, h.verifyTx(ctx, tx)
|
||||
}
|
||||
|
||||
// ProcessProposalVerifyTx decodes a transaction and verifies it.
|
||||
func (h *ProposalHandler) ProcessProposalVerifyTx(ctx sdk.Context, txBz []byte) (sdk.Tx, error) {
|
||||
tx, err := h.txDecoder(txBz)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tx, h.verifyTx(ctx, tx)
|
||||
}
|
||||
|
||||
// VerifyTx verifies a transaction against the application's state.
|
||||
func (h *ProposalHandler) verifyTx(ctx sdk.Context, tx sdk.Tx) error {
|
||||
if h.anteHandler != nil {
|
||||
_, err := h.anteHandler(ctx, tx, false)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *ProposalHandler) RemoveTx(tx sdk.Tx) {
|
||||
if err := h.mempool.RemoveWithoutRefTx(tx); err != nil && !errors.Is(err, sdkmempool.ErrTxNotFound) {
|
||||
panic(fmt.Errorf("failed to remove invalid transaction from the mempool: %w", err))
|
||||
|
||||
@ -107,60 +107,37 @@ func (suite *ABCITestSuite) SetupTest() {
|
||||
|
||||
// Proposal handler set up
|
||||
suite.logger = log.NewNopLogger()
|
||||
suite.proposalHandler = abci.NewProposalHandler(suite.mempool, suite.logger, suite, suite.encodingConfig.TxConfig.TxEncoder(), suite.encodingConfig.TxConfig.TxDecoder())
|
||||
suite.proposalHandler = abci.NewProposalHandler(suite.mempool, suite.logger, suite.anteHandler, suite.encodingConfig.TxConfig.TxEncoder(), suite.encodingConfig.TxConfig.TxDecoder())
|
||||
}
|
||||
|
||||
func (suite *ABCITestSuite) PrepareProposalVerifyTx(tx sdk.Tx) ([]byte, error) {
|
||||
_, err := suite.executeAnteHandler(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txBz, err := suite.encodingConfig.TxConfig.TxEncoder()(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hash := sha256.Sum256(txBz)
|
||||
txHash := hex.EncodeToString(hash[:])
|
||||
if _, ok := suite.txs[txHash]; ok {
|
||||
return nil, fmt.Errorf("tx already in mempool")
|
||||
}
|
||||
suite.txs[txHash] = struct{}{}
|
||||
|
||||
return txBz, nil
|
||||
}
|
||||
|
||||
func (suite *ABCITestSuite) ProcessProposalVerifyTx(txBz []byte) (sdk.Tx, error) {
|
||||
tx, err := suite.encodingConfig.TxConfig.TxDecoder()(txBz)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = suite.executeAnteHandler(tx)
|
||||
if err != nil {
|
||||
return tx, err
|
||||
}
|
||||
|
||||
hash := sha256.Sum256(txBz)
|
||||
txHash := hex.EncodeToString(hash[:])
|
||||
if _, ok := suite.txs[txHash]; ok {
|
||||
return nil, fmt.Errorf("tx already in mempool")
|
||||
}
|
||||
suite.txs[txHash] = struct{}{}
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
func (suite *ABCITestSuite) executeAnteHandler(tx sdk.Tx) (sdk.Context, error) {
|
||||
func (suite *ABCITestSuite) anteHandler(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
|
||||
signer := tx.GetMsgs()[0].GetSigners()[0]
|
||||
suite.bankKeeper.EXPECT().GetAllBalances(suite.ctx, signer).AnyTimes().Return(suite.balances)
|
||||
suite.bankKeeper.EXPECT().GetAllBalances(ctx, signer).AnyTimes().Return(suite.balances)
|
||||
|
||||
next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
return suite.builderDecorator.AnteHandle(suite.ctx, tx, false, next)
|
||||
ctx, err := suite.builderDecorator.AnteHandle(ctx, tx, false, next)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
bz, err := suite.encodingConfig.TxConfig.TxEncoder()(tx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
|
||||
if !simulate {
|
||||
hash := sha256.Sum256(bz)
|
||||
txHash := hex.EncodeToString(hash[:])
|
||||
if _, ok := suite.txs[txHash]; ok {
|
||||
return ctx, fmt.Errorf("tx already in mempool")
|
||||
}
|
||||
suite.txs[txHash] = struct{}{}
|
||||
}
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func (suite *ABCITestSuite) createFilledMempool(numNormalTxs, numAuctionTxs, numBundledTxs int, insertRefTxs bool) int {
|
||||
@ -790,6 +767,6 @@ func (suite *ABCITestSuite) isTopBidValid() bool {
|
||||
}
|
||||
|
||||
// check if the top bid is valid
|
||||
_, err := suite.executeAnteHandler(iterator.Tx())
|
||||
_, err := suite.anteHandler(suite.ctx, iterator.Tx(), true)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user