feat(adapters): Add SignerExtractionAdapter [ENG-1916] (#114)
* add a signer-extraction-adapter * linting * feat(adapters/mev-lane): Use the SignerExtractionAdapter in the Mev-Lane [ENG-1917] (#115) * use SignerExtractionAdapter in the Factory * feat(e2e): block sdk integration updates (#122) * cherry-pick from injective * remove transactions from app-side mempool on failed re-checktx
This commit is contained in:
+16
-5
@@ -7,6 +7,7 @@ import (
|
||||
"cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
signer_extraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
|
||||
"github.com/skip-mev/block-sdk/block"
|
||||
)
|
||||
|
||||
@@ -17,6 +18,10 @@ type LaneConfig struct {
|
||||
TxDecoder sdk.TxDecoder
|
||||
AnteHandler sdk.AnteHandler
|
||||
|
||||
// SignerExtractor defines the interface used for extracting the expected signers of a transaction
|
||||
// from the transaction.
|
||||
SignerExtractor signer_extraction.Adapter
|
||||
|
||||
// MaxBlockSpace defines the relative percentage of block space that can be
|
||||
// used by this lane. NOTE: If this is set to zero, then there is no limit
|
||||
// on the number of transactions that can be included in the block for this
|
||||
@@ -47,14 +52,16 @@ func NewLaneConfig(
|
||||
txEncoder sdk.TxEncoder,
|
||||
txDecoder sdk.TxDecoder,
|
||||
anteHandler sdk.AnteHandler,
|
||||
signerExtractor signer_extraction.Adapter,
|
||||
maxBlockSpace math.LegacyDec,
|
||||
) LaneConfig {
|
||||
return LaneConfig{
|
||||
Logger: logger,
|
||||
TxEncoder: txEncoder,
|
||||
TxDecoder: txDecoder,
|
||||
AnteHandler: anteHandler,
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
Logger: logger,
|
||||
TxEncoder: txEncoder,
|
||||
TxDecoder: txDecoder,
|
||||
AnteHandler: anteHandler,
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
SignerExtractor: signerExtractor,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +79,10 @@ func (c *LaneConfig) ValidateBasic() error {
|
||||
return fmt.Errorf("tx decoder cannot be nil")
|
||||
}
|
||||
|
||||
if c.SignerExtractor == nil {
|
||||
return fmt.Errorf("signer extractor cannot be nil")
|
||||
}
|
||||
|
||||
if c.MaxBlockSpace.IsNil() || c.MaxBlockSpace.IsNegative() || c.MaxBlockSpace.GT(math.LegacyOneDec()) {
|
||||
return fmt.Errorf("max block space must be set to a value between 0 and 1")
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
|
||||
signer_extraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
|
||||
"github.com/skip-mev/block-sdk/block/utils"
|
||||
)
|
||||
|
||||
@@ -81,13 +82,14 @@ func DefaultTxPriority() TxPriority[string] {
|
||||
}
|
||||
|
||||
// NewMempool returns a new Mempool.
|
||||
func NewMempool[C comparable](txPriority TxPriority[C], txEncoder sdk.TxEncoder, maxTx int) *Mempool[C] {
|
||||
func NewMempool[C comparable](txPriority TxPriority[C], txEncoder sdk.TxEncoder, extractor signer_extraction.Adapter, maxTx int) *Mempool[C] {
|
||||
return &Mempool[C]{
|
||||
index: NewPriorityMempool(
|
||||
PriorityNonceMempoolConfig[C]{
|
||||
TxPriority: txPriority,
|
||||
MaxTx: maxTx,
|
||||
},
|
||||
extractor,
|
||||
),
|
||||
txPriority: txPriority,
|
||||
txEncoder: txEncoder,
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
signer_extraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -62,11 +62,12 @@ type (
|
||||
// priority to other sender txs and must be partially ordered by both sender-nonce
|
||||
// and priority.
|
||||
PriorityNonceMempool[C comparable] struct {
|
||||
priorityIndex *skiplist.SkipList
|
||||
priorityCounts map[C]int
|
||||
senderIndices map[string]*skiplist.SkipList
|
||||
scores map[txMeta[C]]txMeta[C]
|
||||
cfg PriorityNonceMempoolConfig[C]
|
||||
priorityIndex *skiplist.SkipList
|
||||
priorityCounts map[C]int
|
||||
senderIndices map[string]*skiplist.SkipList
|
||||
scores map[txMeta[C]]txMeta[C]
|
||||
cfg PriorityNonceMempoolConfig[C]
|
||||
signerExtractor signer_extraction.Adapter
|
||||
}
|
||||
|
||||
// PriorityNonceIterator defines an iterator that is used for mempool iteration
|
||||
@@ -167,21 +168,22 @@ func skiplistComparable[C comparable](txPriority TxPriority[C]) skiplist.Compara
|
||||
|
||||
// NewPriorityMempool returns the SDK's default mempool implementation which
|
||||
// returns txs in a partial order by 2 dimensions; priority, and sender-nonce.
|
||||
func NewPriorityMempool[C comparable](cfg PriorityNonceMempoolConfig[C]) *PriorityNonceMempool[C] {
|
||||
func NewPriorityMempool[C comparable](cfg PriorityNonceMempoolConfig[C], extractor signer_extraction.Adapter) *PriorityNonceMempool[C] {
|
||||
mp := &PriorityNonceMempool[C]{
|
||||
priorityIndex: skiplist.New(skiplistComparable(cfg.TxPriority)),
|
||||
priorityCounts: make(map[C]int),
|
||||
senderIndices: make(map[string]*skiplist.SkipList),
|
||||
scores: make(map[txMeta[C]]txMeta[C]),
|
||||
cfg: cfg,
|
||||
priorityIndex: skiplist.New(skiplistComparable(cfg.TxPriority)),
|
||||
priorityCounts: make(map[C]int),
|
||||
senderIndices: make(map[string]*skiplist.SkipList),
|
||||
scores: make(map[txMeta[C]]txMeta[C]),
|
||||
cfg: cfg,
|
||||
signerExtractor: extractor,
|
||||
}
|
||||
|
||||
return mp
|
||||
}
|
||||
|
||||
// DefaultPriorityMempool returns a priorityNonceMempool with no options.
|
||||
func DefaultPriorityMempool() *PriorityNonceMempool[int64] {
|
||||
return NewPriorityMempool(DefaultPriorityNonceMempoolConfig())
|
||||
func DefaultPriorityMempool(extractor signer_extraction.DefaultAdapter) *PriorityNonceMempool[int64] {
|
||||
return NewPriorityMempool(DefaultPriorityNonceMempoolConfig(), extractor)
|
||||
}
|
||||
|
||||
// NextSenderTx returns the next transaction for a given sender by nonce order,
|
||||
@@ -213,18 +215,18 @@ func (mp *PriorityNonceMempool[C]) Insert(ctx context.Context, tx sdk.Tx) error
|
||||
return nil
|
||||
}
|
||||
|
||||
sigs, err := tx.(signing.SigVerifiableTx).GetSignaturesV2()
|
||||
signers, err := mp.signerExtractor.GetSigners(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sigs) == 0 {
|
||||
if len(signers) == 0 {
|
||||
return fmt.Errorf("tx must have at least one signer")
|
||||
}
|
||||
|
||||
sig := sigs[0]
|
||||
sender := sdk.AccAddress(sig.PubKey.Address()).String()
|
||||
signer := signers[0]
|
||||
sender := signer.Signer.String()
|
||||
priority := mp.cfg.TxPriority.GetTxPriority(ctx, tx)
|
||||
nonce := sig.Sequence
|
||||
nonce := signer.Sequence
|
||||
key := txMeta[C]{nonce: nonce, priority: priority, sender: sender}
|
||||
|
||||
senderIndex, ok := mp.senderIndices[sender]
|
||||
@@ -427,16 +429,16 @@ func (mp *PriorityNonceMempool[C]) CountTx() int {
|
||||
// Remove removes a transaction from the mempool in O(log n) time, returning an
|
||||
// error if unsuccessful.
|
||||
func (mp *PriorityNonceMempool[C]) Remove(tx sdk.Tx) error {
|
||||
sigs, err := tx.(signing.SigVerifiableTx).GetSignaturesV2()
|
||||
signers, err := mp.signerExtractor.GetSigners(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(sigs) == 0 {
|
||||
if len(signers) == 0 {
|
||||
return fmt.Errorf("attempted to remove a tx with no signatures")
|
||||
}
|
||||
|
||||
sig := sigs[0]
|
||||
sender := sdk.AccAddress(sig.PubKey.Address()).String()
|
||||
sig := signers[0]
|
||||
sender := sig.Signer.String()
|
||||
nonce := sig.Sequence
|
||||
|
||||
scoreKey := txMeta[C]{nonce: nonce, sender: sender}
|
||||
|
||||
+20
-16
@@ -12,6 +12,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
signer_extraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
|
||||
"github.com/skip-mev/block-sdk/block"
|
||||
"github.com/skip-mev/block-sdk/block/base"
|
||||
defaultlane "github.com/skip-mev/block-sdk/lanes/base"
|
||||
@@ -60,24 +61,26 @@ func (suite *BlockBusterTestSuite) SetupTest() {
|
||||
// TOB lane set up
|
||||
suite.gasTokenDenom = "stake"
|
||||
mevConfig := base.LaneConfig{
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
}
|
||||
suite.mevLane = mev.NewMEVLane(
|
||||
mevConfig,
|
||||
mev.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
|
||||
mev.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder(), signer_extraction.NewDefaultAdapter()),
|
||||
)
|
||||
|
||||
// Free lane set up
|
||||
freeConfig := base.LaneConfig{
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
}
|
||||
suite.freeLane = free.NewFreeLane(
|
||||
freeConfig,
|
||||
@@ -87,11 +90,12 @@ func (suite *BlockBusterTestSuite) SetupTest() {
|
||||
|
||||
// Base lane set up
|
||||
baseConfig := base.LaneConfig{
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
Logger: log.NewNopLogger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
AnteHandler: nil,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
}
|
||||
suite.baseLane = defaultlane.NewDefaultLane(
|
||||
baseConfig,
|
||||
|
||||
Reference in New Issue
Block a user