From 5231cafbd42c313cf90bac69ae2c84fbd2805ea9 Mon Sep 17 00:00:00 2001 From: David Terpay <35130517+davidterpay@users.noreply.github.com> Date: Mon, 24 Apr 2023 12:13:09 -0400 Subject: [PATCH] fix(timeouts): [ENG-749] Making timeouts configurable (#79) Co-authored-by: Aleksandr Bezobchuk --- mempool/config.go | 22 ++++++++++++++++++++++ mempool/mempool.go | 8 ++++---- mempool/tx.go | 9 +++++++++ x/builder/ante/ante.go | 27 +++++++++------------------ 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/mempool/config.go b/mempool/config.go index 1d918b9..1f8822e 100644 --- a/mempool/config.go +++ b/mempool/config.go @@ -12,6 +12,7 @@ type ( Bidder sdk.AccAddress Bid sdk.Coin Transactions [][]byte + Timeout uint64 } // Config defines the configuration for processing auction transactions. It is @@ -38,12 +39,23 @@ type ( // GetBundledTransactions defines a function that returns the bundled transactions // that the user wants to execute at the top of the block given an auction transaction. GetBundledTransactions(tx sdk.Tx) ([][]byte, error) + + // GetTimeout defines a function that returns the timeout of an auction transaction. + GetTimeout(tx sdk.Tx) (uint64, error) } // DefaultConfig defines a default configuration for processing auction transactions. DefaultConfig struct { txDecoder sdk.TxDecoder } + + // TxWithTimeoutHeight is used to extract timeouts from sdk.Tx transactions. In the case where, + // timeouts are explicitly set on the sdk.Tx, we can use this interface to extract the timeout. + TxWithTimeoutHeight interface { + sdk.Tx + + GetTimeoutHeight() uint64 + } ) var _ Config = (*DefaultConfig)(nil) @@ -133,3 +145,13 @@ func (config *DefaultConfig) GetBundledTransactions(tx sdk.Tx) ([][]byte, error) return msg.Transactions, nil } + +// GetTimeout defines a default function that returns the timeout of an auction transaction. +func (config *DefaultConfig) GetTimeout(tx sdk.Tx) (uint64, error) { + timeoutTx, ok := tx.(TxWithTimeoutHeight) + if !ok { + return 0, fmt.Errorf("transaction does not implement TxWithTimeoutHeight") + } + + return timeoutTx.GetTimeoutHeight(), nil +} diff --git a/mempool/mempool.go b/mempool/mempool.go index 0246cc0..749c5aa 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -44,15 +44,15 @@ type AuctionMempool struct { // AuctionTxPriority returns a TxPriority over auction bid transactions only. It // is to be used in the auction index only. -func AuctionTxPriority() TxPriority[string] { +func AuctionTxPriority(config Config) TxPriority[string] { return TxPriority[string]{ GetTxPriority: func(goCtx context.Context, tx sdk.Tx) string { - msgAuctionBid, err := GetMsgAuctionBidFromTx(tx) + bid, err := config.GetBid(tx) if err != nil { panic(err) } - return msgAuctionBid.Bid.String() + return bid.String() }, Compare: func(a, b string) int { aCoins, _ := sdk.ParseCoinsNormalized(a) @@ -95,7 +95,7 @@ func NewAuctionMempool(txDecoder sdk.TxDecoder, txEncoder sdk.TxEncoder, maxTx i ), auctionIndex: NewPriorityMempool( PriorityNonceMempoolConfig[string]{ - TxPriority: AuctionTxPriority(), + TxPriority: AuctionTxPriority(config), MaxTx: maxTx, }, ), diff --git a/mempool/tx.go b/mempool/tx.go index cae6d26..44e735e 100644 --- a/mempool/tx.go +++ b/mempool/tx.go @@ -73,6 +73,15 @@ func (am *AuctionMempool) GetBundledTransactions(tx sdk.Tx) ([][]byte, error) { return am.config.GetBundledTransactions(tx) } +// GetTimeout returns the timeout of an auction transaction. +func (am *AuctionMempool) GetTimeout(tx sdk.Tx) (uint64, error) { + if isAuctionTx, err := am.IsAuctionTx(tx); err != nil || !isAuctionTx { + return 0, fmt.Errorf("transaction is not an auction transaction") + } + + return am.config.GetTimeout(tx) +} + // GetBundleSigners returns all of the signers for each transaction in the bundle. func (am *AuctionMempool) GetBundleSigners(txs [][]byte) ([]map[string]struct{}, error) { signers := make([]map[string]struct{}, len(txs)) diff --git a/x/builder/ante/ante.go b/x/builder/ante/ante.go index 5f9aabc..9003e91 100644 --- a/x/builder/ante/ante.go +++ b/x/builder/ante/ante.go @@ -12,20 +12,12 @@ import ( var _ sdk.AnteDecorator = BuilderDecorator{} -type ( - BuilderDecorator struct { - builderKeeper keeper.Keeper - txDecoder sdk.TxDecoder - txEncoder sdk.TxEncoder - mempool *mempool.AuctionMempool - } - - TxWithTimeoutHeight interface { - sdk.Tx - - GetTimeoutHeight() uint64 - } -) +type BuilderDecorator struct { + builderKeeper keeper.Keeper + txDecoder sdk.TxDecoder + txEncoder sdk.TxEncoder + mempool *mempool.AuctionMempool +} func NewBuilderDecorator(ak keeper.Keeper, txDecoder sdk.TxDecoder, txEncoder sdk.TxEncoder, mempool *mempool.AuctionMempool) BuilderDecorator { return BuilderDecorator{ @@ -134,12 +126,11 @@ func (ad BuilderDecorator) IsTopBidTx(ctx sdk.Context, tx sdk.Tx) (bool, error) // HasValidTimeout returns true if the transaction has a valid timeout height. func (ad BuilderDecorator) HasValidTimeout(ctx sdk.Context, tx sdk.Tx) error { - auctionTx, ok := tx.(TxWithTimeoutHeight) - if !ok { - return fmt.Errorf("transaction does not implement TxWithTimeoutHeight") + timeout, err := ad.mempool.GetTimeout(tx) + if err != nil { + return err } - timeout := auctionTx.GetTimeoutHeight() if timeout == 0 { return fmt.Errorf("timeout height cannot be zero") }