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:
parent
3e5fce9a54
commit
3abfde4f34
2
Makefile
2
Makefile
@ -119,7 +119,7 @@ TEST_INTEGRATION_TAGS = integration
|
||||
|
||||
test-integration: $(TEST_INTEGRATION_DEPS)
|
||||
@ echo "Running integration tests..."
|
||||
@go test ./tests/integration/block_sdk_integration_test.go -timeout 30m -race -v -tags='$(TEST_INTEGRATION_TAGS)'
|
||||
@go test ./tests/integration/block_sdk_integration_test.go -timeout 30m -p 1 -race -v -tags='$(TEST_INTEGRATION_TAGS)'
|
||||
|
||||
test: use-main
|
||||
@go test -v -race $(shell go list ./... | grep -v tests/)
|
||||
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/skip-mev/block-sdk/abci"
|
||||
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"
|
||||
@ -735,11 +736,12 @@ func (s *ProposalsTestSuite) setUpAnteHandler(expectedExecution map[sdk.Tx]bool)
|
||||
|
||||
func (s *ProposalsTestSuite) setUpStandardLane(maxBlockSpace math.LegacyDec, expectedExecution map[sdk.Tx]bool) *defaultlane.DefaultLane {
|
||||
cfg := base.LaneConfig{
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: s.setUpAnteHandler(expectedExecution),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
AnteHandler: s.setUpAnteHandler(expectedExecution),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
}
|
||||
|
||||
return defaultlane.NewDefaultLane(cfg)
|
||||
@ -747,23 +749,25 @@ func (s *ProposalsTestSuite) setUpStandardLane(maxBlockSpace math.LegacyDec, exp
|
||||
|
||||
func (s *ProposalsTestSuite) setUpTOBLane(maxBlockSpace math.LegacyDec, expectedExecution map[sdk.Tx]bool) *mev.MEVLane {
|
||||
cfg := base.LaneConfig{
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: s.setUpAnteHandler(expectedExecution),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: s.setUpAnteHandler(expectedExecution),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
}
|
||||
|
||||
return mev.NewMEVLane(cfg, mev.NewDefaultAuctionFactory(cfg.TxDecoder))
|
||||
return mev.NewMEVLane(cfg, mev.NewDefaultAuctionFactory(cfg.TxDecoder, signer_extraction.NewDefaultAdapter()))
|
||||
}
|
||||
|
||||
func (s *ProposalsTestSuite) setUpFreeLane(maxBlockSpace math.LegacyDec, expectedExecution map[sdk.Tx]bool) *free.FreeLane {
|
||||
cfg := base.LaneConfig{
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: s.setUpAnteHandler(expectedExecution),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: s.setUpAnteHandler(expectedExecution),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
}
|
||||
|
||||
return free.NewFreeLane(cfg, base.DefaultTxPriority(), free.DefaultMatchHandler())
|
||||
@ -771,16 +775,17 @@ func (s *ProposalsTestSuite) setUpFreeLane(maxBlockSpace math.LegacyDec, expecte
|
||||
|
||||
func (s *ProposalsTestSuite) setUpPanicLane(maxBlockSpace math.LegacyDec) *base.BaseLane {
|
||||
cfg := base.LaneConfig{
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
Logger: log.NewTestLogger(s.T()),
|
||||
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
MaxBlockSpace: maxBlockSpace,
|
||||
}
|
||||
|
||||
lane := base.NewBaseLane(
|
||||
cfg,
|
||||
"panic",
|
||||
base.NewMempool[string](base.DefaultTxPriority(), cfg.TxEncoder, 0),
|
||||
base.NewMempool[string](base.DefaultTxPriority(), cfg.TxEncoder, signer_extraction.NewDefaultAdapter(), 0),
|
||||
base.DefaultMatchHandler(),
|
||||
)
|
||||
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
package signerextraction
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
)
|
||||
|
||||
type SignerData struct {
|
||||
Signer sdk.AccAddress
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
// SignerExtractionAdapter is an interface used to determine how the signers of a transaction should be extracted
|
||||
// from the transaction.
|
||||
type Adapter interface {
|
||||
GetSigners(sdk.Tx) ([]SignerData, error)
|
||||
}
|
||||
|
||||
var _ Adapter = DefaultAdapter{}
|
||||
|
||||
// DefaultSignerExtractionAdapter is the default implementation of SignerExtractionAdapter. It extracts the signers
|
||||
// from a cosmos-sdk tx via GetSignaturesV2.
|
||||
type DefaultAdapter struct{}
|
||||
|
||||
func NewDefaultAdapter() DefaultAdapter {
|
||||
return DefaultAdapter{}
|
||||
}
|
||||
|
||||
func (DefaultAdapter) GetSigners(tx sdk.Tx) ([]SignerData, error) {
|
||||
sigTx, ok := tx.(signing.SigVerifiableTx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("tx of type %T does not implement SigVerifiableTx", tx)
|
||||
}
|
||||
|
||||
sigs, err := sigTx.GetSignaturesV2()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signers := make([]SignerData, len(sigs))
|
||||
for i, sig := range sigs {
|
||||
signers[i] = SignerData{
|
||||
Signer: sig.PubKey.Address().Bytes(),
|
||||
Sequence: sig.Sequence,
|
||||
}
|
||||
}
|
||||
|
||||
return signers, nil
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package signerextraction_test
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
signer_extraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
|
||||
testutils "github.com/skip-mev/block-sdk/testutils"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type SignerExtractionAdapterTestSuite struct {
|
||||
suite.Suite
|
||||
txConfig client.TxConfig
|
||||
accts []testutils.Account
|
||||
adapter signer_extraction.DefaultAdapter
|
||||
}
|
||||
|
||||
func TestSignerExtractionAdapterTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(SignerExtractionAdapterTestSuite))
|
||||
}
|
||||
|
||||
func (s *SignerExtractionAdapterTestSuite) SetupTest() {
|
||||
encodingConfig := testutils.CreateTestEncodingConfig()
|
||||
s.txConfig = encodingConfig.TxConfig
|
||||
|
||||
accts := testutils.RandomAccounts(rand.New(rand.NewSource(1)), 2)
|
||||
|
||||
s.accts = accts
|
||||
}
|
||||
|
||||
func (s *SignerExtractionAdapterTestSuite) TestGetSigners() {
|
||||
acct := s.accts[0]
|
||||
tx, err := testutils.CreateTx(s.txConfig, acct, 1, 1, []sdk.Msg{
|
||||
&banktypes.MsgSend{
|
||||
FromAddress: acct.Address.String(),
|
||||
ToAddress: acct.Address.String(),
|
||||
Amount: sdk.NewCoins(sdk.NewInt64Coin("test", 1)),
|
||||
},
|
||||
}, sdk.NewCoins(sdk.NewCoin("test", math.NewInt(1)))...)
|
||||
s.Require().NoError(err)
|
||||
|
||||
signers, err := s.adapter.GetSigners(tx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Len(signers, 1)
|
||||
s.Require().Equal(acct.Address.String(), signers[0].Signer.String())
|
||||
s.Require().Equal(uint64(1), signers[0].Sequence)
|
||||
}
|
||||
@ -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}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -9,6 +9,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"
|
||||
"github.com/skip-mev/block-sdk/block/base"
|
||||
"github.com/skip-mev/block-sdk/block/utils/mocks"
|
||||
@ -509,6 +510,7 @@ func (s *BaseTestSuite) initLane(
|
||||
s.encodingConfig.TxConfig.TxEncoder(),
|
||||
s.encodingConfig.TxConfig.TxDecoder(),
|
||||
s.setUpAnteHandler(expectedExecution),
|
||||
signer_extraction.NewDefaultAdapter(),
|
||||
maxBlockSpace,
|
||||
)
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ func NewDefaultLane(cfg base.LaneConfig) *DefaultLane {
|
||||
base.NewMempool[string](
|
||||
base.DefaultTxPriority(),
|
||||
cfg.TxEncoder,
|
||||
cfg.SignerExtractor,
|
||||
cfg.MaxTxs,
|
||||
),
|
||||
base.DefaultMatchHandler(),
|
||||
|
||||
@ -4,6 +4,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/base"
|
||||
testutils "github.com/skip-mev/block-sdk/testutils"
|
||||
)
|
||||
@ -85,7 +86,7 @@ func (s *BaseTestSuite) TestCompareTxPriority() {
|
||||
}
|
||||
|
||||
func (s *BaseTestSuite) TestInsert() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
s.Run("should be able to insert a transaction", func() {
|
||||
tx, err := testutils.CreateRandomTx(
|
||||
@ -137,7 +138,7 @@ func (s *BaseTestSuite) TestInsert() {
|
||||
}
|
||||
|
||||
func (s *BaseTestSuite) TestRemove() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
s.Run("should be able to remove a transaction", func() {
|
||||
tx, err := testutils.CreateRandomTx(
|
||||
@ -175,7 +176,7 @@ func (s *BaseTestSuite) TestRemove() {
|
||||
|
||||
func (s *BaseTestSuite) TestSelect() {
|
||||
s.Run("should be able to select transactions in the correct order", func() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
@ -214,7 +215,7 @@ func (s *BaseTestSuite) TestSelect() {
|
||||
})
|
||||
|
||||
s.Run("should be able to select a single transaction", func() {
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
|
||||
mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), signer_extraction.NewDefaultAdapter(), 3)
|
||||
|
||||
tx1, err := testutils.CreateRandomTx(
|
||||
s.encodingConfig.TxConfig,
|
||||
|
||||
@ -33,6 +33,7 @@ func NewFreeLane(
|
||||
base.NewMempool[string](
|
||||
txPriority,
|
||||
cfg.TxEncoder,
|
||||
cfg.SignerExtractor,
|
||||
cfg.MaxTxs,
|
||||
),
|
||||
matchFn,
|
||||
|
||||
@ -118,7 +118,7 @@ func (handler *CheckTxHandler) CheckTx() CheckTx {
|
||||
0,
|
||||
nil,
|
||||
false,
|
||||
), err
|
||||
), nil
|
||||
}
|
||||
|
||||
// Attempt to get the bid info of the transaction.
|
||||
@ -135,7 +135,7 @@ func (handler *CheckTxHandler) CheckTx() CheckTx {
|
||||
0,
|
||||
nil,
|
||||
false,
|
||||
), err
|
||||
), nil
|
||||
}
|
||||
|
||||
// If this is not a bid transaction, we just execute it normally.
|
||||
@ -162,17 +162,35 @@ func (handler *CheckTxHandler) CheckTx() CheckTx {
|
||||
handler.baseApp.Logger().Info(
|
||||
"invalid bid tx",
|
||||
"err", err,
|
||||
"tx", req.Tx,
|
||||
"removing tx from mempool", true,
|
||||
)
|
||||
|
||||
// attempt to remove the bid from the MEVLane (if it exists)
|
||||
if handler.mevLane.Contains(tx) {
|
||||
if err := handler.mevLane.Remove(tx); err != nil {
|
||||
handler.baseApp.Logger().Error(
|
||||
"failed to remove bid transaction from mev-lane",
|
||||
"err", err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return sdkerrors.ResponseCheckTxWithEvents(
|
||||
fmt.Errorf("invalid bid tx: %w", err),
|
||||
gasInfo.GasWanted,
|
||||
gasInfo.GasUsed,
|
||||
nil,
|
||||
false,
|
||||
), err
|
||||
), nil
|
||||
}
|
||||
|
||||
handler.baseApp.Logger().Info(
|
||||
"valid bid tx",
|
||||
"tx", req.Tx,
|
||||
"inserting tx into mempool", true,
|
||||
)
|
||||
|
||||
// If the bid transaction is valid, we know we can insert it into the mempool for consideration in the next block.
|
||||
if err := handler.mevLane.Insert(ctx, tx); err != nil {
|
||||
handler.baseApp.Logger().Info(
|
||||
@ -186,7 +204,7 @@ func (handler *CheckTxHandler) CheckTx() CheckTx {
|
||||
gasInfo.GasUsed,
|
||||
nil,
|
||||
false,
|
||||
), err
|
||||
), nil
|
||||
}
|
||||
|
||||
return &cometabci.ResponseCheckTx{
|
||||
|
||||
@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
|
||||
signer_extraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
|
||||
"github.com/skip-mev/block-sdk/block/base"
|
||||
"github.com/skip-mev/block-sdk/x/auction/types"
|
||||
)
|
||||
@ -30,7 +30,8 @@ type (
|
||||
|
||||
// DefaultAuctionFactory defines a default implmentation for the auction factory interface for processing auction transactions.
|
||||
DefaultAuctionFactory struct {
|
||||
txDecoder sdk.TxDecoder
|
||||
txDecoder sdk.TxDecoder
|
||||
signerExtractor signer_extraction.Adapter
|
||||
}
|
||||
|
||||
// TxWithTimeoutHeight is used to extract timeouts from sdk.Tx transactions. In the case where,
|
||||
@ -45,9 +46,10 @@ type (
|
||||
var _ Factory = (*DefaultAuctionFactory)(nil)
|
||||
|
||||
// NewDefaultAuctionFactory returns a default auction factory interface implementation.
|
||||
func NewDefaultAuctionFactory(txDecoder sdk.TxDecoder) Factory {
|
||||
func NewDefaultAuctionFactory(txDecoder sdk.TxDecoder, extractor signer_extraction.Adapter) Factory {
|
||||
return &DefaultAuctionFactory{
|
||||
txDecoder: txDecoder,
|
||||
txDecoder: txDecoder,
|
||||
signerExtractor: extractor,
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,20 +117,15 @@ func (config *DefaultAuctionFactory) getBundleSigners(bundle [][]byte) ([]map[st
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigTx, ok := sdkTx.(signing.SigVerifiableTx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("transaction is not valid")
|
||||
}
|
||||
|
||||
txSigners := make(map[string]struct{})
|
||||
|
||||
signers, err := sigTx.GetSigners()
|
||||
signers, err := config.signerExtractor.GetSigners(sdkTx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, signer := range signers {
|
||||
txSigners[sdk.AccAddress(signer).String()] = struct{}{}
|
||||
txSigners[signer.Signer.String()] = struct{}{}
|
||||
}
|
||||
|
||||
bundleSigners = append(bundleSigners, txSigners)
|
||||
|
||||
@ -53,6 +53,7 @@ func NewMEVLane(
|
||||
base.NewMempool[string](
|
||||
TxPriority(factory),
|
||||
cfg.TxEncoder,
|
||||
cfg.SignerExtractor,
|
||||
cfg.MaxTxs,
|
||||
),
|
||||
factory.MatchHandler(),
|
||||
|
||||
@ -10,6 +10,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/lanes/mev"
|
||||
testutils "github.com/skip-mev/block-sdk/testutils"
|
||||
)
|
||||
@ -32,7 +33,7 @@ func TestMempoolTestSuite(t *testing.T) {
|
||||
func (suite *MEVTestSuite) SetupTest() {
|
||||
// Mempool setup
|
||||
suite.encCfg = testutils.CreateTestEncodingConfig()
|
||||
suite.config = mev.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder())
|
||||
suite.config = mev.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder(), signer_extraction.NewDefaultAdapter())
|
||||
suite.ctx = sdk.NewContext(nil, cmtproto.Header{}, false, log.NewTestLogger(suite.T()))
|
||||
|
||||
// Init accounts
|
||||
|
||||
@ -62,6 +62,7 @@ import (
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
|
||||
"github.com/skip-mev/block-sdk/abci"
|
||||
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"
|
||||
@ -264,24 +265,26 @@ func New(
|
||||
// lane and the last lane is the lowest priority lane.
|
||||
// MEV lane allows transactions to bid for inclusion at the top of the next block.
|
||||
mevConfig := base.LaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(), // This means the lane has no limit on block space.
|
||||
MaxTxs: 0, // This means the lane has no limit on the number of transactions it can store.
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(), // This means the lane has no limit on block space.
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
MaxTxs: 0, // This means the lane has no limit on the number of transactions it can store.
|
||||
}
|
||||
mevLane := mev.NewMEVLane(
|
||||
mevConfig,
|
||||
mev.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
|
||||
mev.NewDefaultAuctionFactory(app.txConfig.TxDecoder(), signer_extraction.NewDefaultAdapter()),
|
||||
)
|
||||
|
||||
// Free lane allows transactions to be included in the next block for free.
|
||||
freeConfig := base.LaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
MaxTxs: 0,
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
MaxTxs: 0,
|
||||
}
|
||||
freeLane := free.NewFreeLane(
|
||||
freeConfig,
|
||||
@ -291,11 +294,12 @@ func New(
|
||||
|
||||
// Default lane accepts all other transactions.
|
||||
defaultConfig := base.LaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
MaxTxs: 0,
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
MaxTxs: 0,
|
||||
}
|
||||
defaultLane := defaultlane.NewDefaultLane(defaultConfig)
|
||||
|
||||
|
||||
@ -12,6 +12,10 @@ import (
|
||||
"github.com/strangelove-ventures/interchaintest/v7/ibc"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
rpctypes "github.com/cometbft/cometbft/rpc/core/types"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -31,6 +35,12 @@ type IntegrationTestSuite struct {
|
||||
user1, user2, user3 ibc.Wallet
|
||||
// denom
|
||||
denom string
|
||||
|
||||
// overrides for key-ring configuration of the broadcaster
|
||||
broadcasterOverrides *KeyringOverride
|
||||
|
||||
// broadcaster is the RPC interface to the ITS network
|
||||
bc *cosmos.Broadcaster
|
||||
}
|
||||
|
||||
func NewIntegrationTestSuiteFromSpec(spec *interchaintest.ChainSpec) *IntegrationTestSuite {
|
||||
@ -50,6 +60,13 @@ func (s *IntegrationTestSuite) WithDenom(denom string) *IntegrationTestSuite {
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) WithKeyringOptions(cdc codec.Codec, opts keyring.Option) {
|
||||
s.broadcasterOverrides = &KeyringOverride{
|
||||
cdc: cdc,
|
||||
keyringOptions: opts,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
// build the chain
|
||||
s.T().Log("building chain with spec", s.spec)
|
||||
@ -64,6 +81,10 @@ func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.user1 = interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), initBalance, s.chain)[0]
|
||||
s.user2 = interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), initBalance, s.chain)[0]
|
||||
s.user3 = interchaintest.GetAndFundTestUsers(s.T(), ctx, s.T().Name(), initBalance, s.chain)[0]
|
||||
|
||||
// create the broadcaster
|
||||
s.T().Log("creating broadcaster")
|
||||
s.setupBroadcaster()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
@ -108,7 +129,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
|
||||
// create the MsgAuctioBid
|
||||
bidAmt := params.ReserveFee
|
||||
bid, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -122,7 +143,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast + wait for the tx to be included in a block
|
||||
res := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
res := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -156,7 +177,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
|
||||
// create the MsgAuctionBid
|
||||
bidAmt := params.ReserveFee
|
||||
bid, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: msgs[0:1],
|
||||
@ -172,24 +193,52 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
msgsToBcast = append(msgsToBcast, Tx{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
Height: height + 1,
|
||||
Height: height + 3,
|
||||
})
|
||||
|
||||
msgsToBcast = append(msgsToBcast, Tx{
|
||||
User: s.user2,
|
||||
Msgs: msgs[1:2],
|
||||
Height: height + 1,
|
||||
Height: height + 3,
|
||||
})
|
||||
|
||||
regular_txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), msgsToBcast)
|
||||
expTxs := make(chan committedTx, 2)
|
||||
|
||||
regular_txs := s.BroadcastTxsWithCallback(
|
||||
context.Background(),
|
||||
s.chain.(*cosmos.CosmosChain),
|
||||
msgsToBcast,
|
||||
func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTxs <- committedTx{tx, resp}
|
||||
},
|
||||
)
|
||||
close(expTxs)
|
||||
s.Require().Len(expTxs, 2)
|
||||
|
||||
// get the height of the block that the bid was included in
|
||||
var commitHeight int64
|
||||
|
||||
tx1 := <-expTxs
|
||||
tx2 := <-expTxs
|
||||
|
||||
// determine which tx is the bid
|
||||
if bytes.Equal(tx1.tx, regular_txs[0]) {
|
||||
commitHeight = tx1.res.Height
|
||||
} else {
|
||||
commitHeight = tx2.res.Height
|
||||
}
|
||||
|
||||
// if they were committed in the same height
|
||||
if tx1.res.Height == tx2.res.Height {
|
||||
bundledTxs = append(bundledTxs, regular_txs[1:]...)
|
||||
}
|
||||
|
||||
// get the block at the next height
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), commitHeight)
|
||||
|
||||
// verify the block
|
||||
bidTxHash := TxHash(regular_txs[0])
|
||||
VerifyBlock(s.T(), block, 0, bidTxHash, append(bundledTxs, regular_txs[1:]...))
|
||||
VerifyBlock(s.T(), block, 0, bidTxHash, bundledTxs)
|
||||
|
||||
// ensure that escrow account has the correct balance
|
||||
escrowAcctBalanceAfterBid := QueryAccountBalance(s.T(), s.chain, escrowAddr, params.ReserveFee.Denom)
|
||||
@ -216,10 +265,10 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
}
|
||||
// create bundle
|
||||
bidAmt := params.ReserveFee
|
||||
bid, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, txs)
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, txs)
|
||||
// create 2 more bundle w same txs from same user
|
||||
bid2, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), txs)
|
||||
bid3, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement).Add(params.MinBidIncrement), txs)
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), txs)
|
||||
bid3, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement).Add(params.MinBidIncrement), txs)
|
||||
|
||||
// query height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
@ -230,7 +279,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
height++
|
||||
|
||||
// broadcast all bids
|
||||
broadcastedTxs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
broadcastedTxs := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -286,28 +335,41 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
|
||||
// create bundle
|
||||
bidAmt := params.ReserveFee
|
||||
bid, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt, txs)
|
||||
bid, bundledTxs := s.CreateAuctionBidMsg(context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt, txs)
|
||||
|
||||
// get chain height
|
||||
height, err = s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
expTxs := make(chan committedTx, 4)
|
||||
|
||||
// broadcast txs in the bundle to network + bundle + extra
|
||||
broadcastedTxs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{txs[0], txs[1], {
|
||||
broadcastedTxs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
Height: height + 1,
|
||||
Height: height + 3,
|
||||
}, {
|
||||
User: s.user3,
|
||||
Msgs: []sdk.Msg{banktypes.NewMsgSend(s.user3.Address(), s.user1.Address(), sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(100))))},
|
||||
}})
|
||||
Height: height + 3,
|
||||
}},
|
||||
func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTxs <- committedTx{tx, resp}
|
||||
})
|
||||
close(expTxs)
|
||||
|
||||
// query next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
var bidTxHeight int64
|
||||
for tx := range expTxs {
|
||||
if bytes.Equal(tx.tx, broadcastedTxs[0]) {
|
||||
bidTxHeight = tx.res.Height
|
||||
}
|
||||
}
|
||||
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), bidTxHeight)
|
||||
|
||||
// check block
|
||||
VerifyBlock(s.T(), block, 0, TxHash(broadcastedTxs[2]), append(bundledTxs, broadcastedTxs[3]))
|
||||
VerifyBlock(s.T(), block, 0, TxHash(broadcastedTxs[0]), bundledTxs)
|
||||
|
||||
// check escrow account balance
|
||||
escrowAcctBalanceAfterBid := QueryAccountBalance(s.T(), s.chain, escrowAddr, params.ReserveFee.Denom)
|
||||
@ -316,6 +378,11 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
})
|
||||
}
|
||||
|
||||
type committedTx struct {
|
||||
tx []byte
|
||||
res *rpctypes.ResultTx
|
||||
}
|
||||
|
||||
// TestMultipleBids tests the execution of various valid auction bids in the same block. There are a few
|
||||
// invariants that are tested:
|
||||
//
|
||||
@ -343,7 +410,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid 2
|
||||
msg2 := Tx{
|
||||
@ -352,36 +419,45 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
SequenceIncrement: 1,
|
||||
}
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, bundledTxs2 := CreateAuctionBidMsg(s.T(), context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg2})
|
||||
bid2, bundledTxs2 := s.CreateAuctionBidMsg( context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg2})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast both bids
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
// create channel to receive txs
|
||||
txsCh := make(chan committedTx, 2)
|
||||
|
||||
// broadcast both bids (with ample time to be committed (instead of timing out))
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 2,
|
||||
SkipInclusionCheck: true,
|
||||
Height: height + 4,
|
||||
},
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 1,
|
||||
Height: height + 3,
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
txsCh <- committedTx{tx, resp}
|
||||
})
|
||||
|
||||
// check txs were committed
|
||||
require.Len(s.T(), txsCh, 2)
|
||||
close(txsCh)
|
||||
|
||||
// query next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
tx1 := <-txsCh
|
||||
tx2 := <-txsCh
|
||||
|
||||
// query next block
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), tx1.res.Height)
|
||||
|
||||
// check bid2 was included first
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[1]), bundledTxs2)
|
||||
|
||||
// check next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+2)
|
||||
block = Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+2))
|
||||
block = Block(s.T(), s.chain.(*cosmos.CosmosChain), tx2.res.Height)
|
||||
|
||||
// check bid1 was included second
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTxs)
|
||||
@ -405,7 +481,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx})
|
||||
|
||||
// create bid 2
|
||||
tx2 := Tx{
|
||||
@ -414,30 +490,36 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
SequenceIncrement: 1,
|
||||
}
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx2})
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{tx2})
|
||||
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast both bids
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
expTx := make(chan committedTx, 1)
|
||||
|
||||
// broadcast both bids (wait for the first to be committed)
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 1,
|
||||
Height: height + 4,
|
||||
},
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 1,
|
||||
Height: height + 3,
|
||||
ExpectFail: true,
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTx <- committedTx{tx, resp}
|
||||
})
|
||||
|
||||
close(expTx)
|
||||
commitTx := <-expTx
|
||||
|
||||
// query next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), commitTx.res.Height)
|
||||
|
||||
// check bid2 was included first
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTxs)
|
||||
@ -461,7 +543,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid 2
|
||||
msg2 := Tx{
|
||||
@ -469,33 +551,39 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
Msgs: []sdk.Msg{banktypes.NewMsgSend(s.user2.Address(), s.user3.Address(), sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(100))))},
|
||||
SequenceIncrement: 1,
|
||||
}
|
||||
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg2})
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg2})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
expTx := make(chan committedTx, 1)
|
||||
|
||||
// broadcast both bids
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 1,
|
||||
Height: height + 4,
|
||||
},
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
SequenceIncrement: 1,
|
||||
Height: height + 1,
|
||||
Height: height + 4,
|
||||
ExpectFail: true,
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
expTx <- committedTx{tx, resp}
|
||||
})
|
||||
close(expTx)
|
||||
|
||||
commitTx := <-expTx
|
||||
|
||||
// query next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), commitTx.res.Height)
|
||||
|
||||
// check bid2 was included first
|
||||
// check bid1 was included first
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTxs)
|
||||
|
||||
// check escrow balance
|
||||
@ -517,41 +605,49 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
commitTx := make(chan committedTx, 1)
|
||||
|
||||
// broadcast both bids
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 1,
|
||||
},
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 2,
|
||||
SequenceIncrement: 1,
|
||||
ExpectFail: true,
|
||||
Height: height + 4,
|
||||
SkipInclusionCheck: true,
|
||||
},
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 3,
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
commitTx <- committedTx{tx, resp}
|
||||
})
|
||||
close(commitTx)
|
||||
|
||||
expTx := <-commitTx
|
||||
|
||||
// query next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), expTx.res.Height)
|
||||
|
||||
// check bid2 was included first
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTxs)
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[1]), bundledTxs)
|
||||
|
||||
// check escrow balance
|
||||
escrowAcctBalanceAfterBid := QueryAccountBalance(s.T(), s.chain, escrowAddr, params.ReserveFee.Denom)
|
||||
expectedIncrement := escrowAddressIncrement(bidAmt.Add(params.MinBidIncrement).Amount, params.ProposerFee)
|
||||
require.Equal(s.T(), escrowAcctBalanceBeforeBid+expectedIncrement, escrowAcctBalanceAfterBid)
|
||||
|
||||
// wait for next block for mempool to clear
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+3)
|
||||
})
|
||||
|
||||
s.Run("Multiple transactions from diff. account with increasing bids but first bid has same bundle so it should fail in later block", func() {
|
||||
@ -567,40 +663,49 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
bid2, _ := s.CreateAuctionBidMsg( context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
commitTx := make(chan committedTx, 1)
|
||||
|
||||
// broadcast both bids
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 1,
|
||||
},
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 1,
|
||||
ExpectFail: true,
|
||||
Height: height + 4,
|
||||
SkipInclusionCheck: true,
|
||||
},
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 3,
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
commitTx <- committedTx{tx, resp}
|
||||
})
|
||||
close(commitTx)
|
||||
|
||||
expTx := <-commitTx
|
||||
|
||||
// query next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), expTx.res.Height)
|
||||
|
||||
// check bid2 was included first
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTxs)
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[1]), bundledTxs)
|
||||
|
||||
// check escrow balance
|
||||
escrowAcctBalanceAfterBid := QueryAccountBalance(s.T(), s.chain, escrowAddr, params.ReserveFee.Denom)
|
||||
expectedIncrement := escrowAddressIncrement(bidAmt.Add(params.MinBidIncrement).Amount, params.ProposerFee)
|
||||
require.Equal(s.T(), escrowAcctBalanceBeforeBid+expectedIncrement, escrowAcctBalanceAfterBid)
|
||||
|
||||
// wait for next block for mempool to clear
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+3)
|
||||
})
|
||||
|
||||
s.Run("Multiple transactions with increasing bids and different bundles", func() {
|
||||
@ -616,7 +721,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
// create bid1
|
||||
bidAmt := params.ReserveFee
|
||||
bid1, bundledTxs := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid1, bundledTxs := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// create bid2
|
||||
// create a second message
|
||||
@ -627,36 +732,48 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
|
||||
// create bid2 w/ higher bid than bid1
|
||||
bid2, bundledTxs2 := CreateAuctionBidMsg(s.T(), context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg2})
|
||||
bid2, bundledTxs2 := s.CreateAuctionBidMsg(context.Background(), s.user2, s.chain.(*cosmos.CosmosChain), bidAmt.Add(params.MinBidIncrement), []Tx{msg2})
|
||||
// get chain height
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// make channel for committedTxs (expect 2 txs to be committed)
|
||||
committedTxs := make(chan committedTx, 2)
|
||||
|
||||
// broadcast both bids
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid1},
|
||||
Height: height + 2,
|
||||
SkipInclusionCheck: true,
|
||||
Height: height + 4,
|
||||
},
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{bid2},
|
||||
Height: height + 1,
|
||||
Height: height + 3,
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
committedTxs <- committedTx{
|
||||
tx: tx,
|
||||
res: resp,
|
||||
}
|
||||
})
|
||||
|
||||
// close the channel when finished
|
||||
close(committedTxs)
|
||||
|
||||
// expect 2 txs
|
||||
tx1 := <-committedTxs
|
||||
tx2 := <-committedTxs
|
||||
|
||||
// query next block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), tx1.res.Height)
|
||||
|
||||
// check bid2 was included first
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[1]), bundledTxs2)
|
||||
|
||||
// query next block and check tx inclusion
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+2)
|
||||
block = Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+2))
|
||||
block = Block(s.T(), s.chain.(*cosmos.CosmosChain), tx2.res.Height)
|
||||
|
||||
// check bid1 was included second
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTxs)
|
||||
@ -680,11 +797,11 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
SequenceIncrement: 2,
|
||||
}
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
// wrap bidTx in another tx
|
||||
wrappedBid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
wrappedBid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -696,7 +813,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{wrappedBid},
|
||||
@ -714,13 +831,13 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
SequenceIncrement: 2,
|
||||
}
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(1000000000000000000))
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
SimulateTx(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
s.SimulateTx(context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
})
|
||||
|
||||
s.Run("Invalid bid that is attempting to front-run/sandwich", func() {
|
||||
@ -741,13 +858,13 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
}
|
||||
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg, msg2, msg3})
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg, msg2, msg3})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
SimulateTx(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
s.SimulateTx(context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
})
|
||||
|
||||
s.Run("Invalid bid that includes an invalid bundle tx", func() {
|
||||
@ -758,13 +875,13 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
SequenceIncrement: 2,
|
||||
}
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -784,13 +901,13 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create bid smaller than reserve
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(0))
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
SimulateTx(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
s.SimulateTx(context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
})
|
||||
|
||||
s.Run("Invalid auction bid with too many transactions in the bundle", func() {
|
||||
@ -807,13 +924,13 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create bid smaller than reserve
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(0))
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, msgs)
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, msgs)
|
||||
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
SimulateTx(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
s.SimulateTx(context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, height+1, true, []sdk.Msg{bid}...)
|
||||
})
|
||||
|
||||
s.Run("invalid auction bid that has an invalid timeout", func() {
|
||||
@ -826,10 +943,10 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create bid smaller than reserve
|
||||
bidAmt := sdk.NewCoin(s.denom, math.NewInt(0))
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{msg})
|
||||
|
||||
// broadcast wrapped bid, and expect a failure
|
||||
SimulateTx(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, 0, true, []sdk.Msg{bid}...)
|
||||
s.SimulateTx(context.Background(), s.chain.(*cosmos.CosmosChain), s.user1, 0, true, []sdk.Msg{bid}...)
|
||||
})
|
||||
|
||||
s.Run("Invalid bid that includes valid transactions that are in the mempool", func() {
|
||||
@ -842,7 +959,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// create the MsgAuctioBid (this should fail b.c same tx is repeated twice)
|
||||
bidAmt := params.ReserveFee
|
||||
bid, _ := CreateAuctionBidMsg(s.T(), context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
bid, _ := s.CreateAuctionBidMsg( context.Background(), s.user1, s.chain.(*cosmos.CosmosChain), bidAmt, []Tx{
|
||||
{
|
||||
User: s.user2,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -859,7 +976,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// broadcast + wait for the tx to be included in a block
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
txs := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -905,7 +1022,7 @@ func (s *IntegrationTestSuite) TestFreeLane() {
|
||||
balanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user1.FormattedAddress(), s.denom)
|
||||
|
||||
// create a free tx (MsgDelegate), broadcast and wait for commit
|
||||
BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -929,7 +1046,7 @@ func (s *IntegrationTestSuite) TestFreeLane() {
|
||||
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
|
||||
|
||||
// user1 submits a free-tx, user2 submits a normal tx
|
||||
BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -968,7 +1085,7 @@ func (s *IntegrationTestSuite) TestFreeLane() {
|
||||
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
|
||||
|
||||
// user1 submits a free-tx, user2 submits a free tx
|
||||
BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{
|
||||
@ -1012,8 +1129,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
|
||||
|
||||
// create free-tx, bid-tx, and normal-tx\
|
||||
bid, bundledTx := CreateAuctionBidMsg(
|
||||
s.T(),
|
||||
bid, bundledTx := s.CreateAuctionBidMsg(
|
||||
context.Background(),
|
||||
s.user1,
|
||||
s.chain.(*cosmos.CosmosChain),
|
||||
@ -1036,11 +1152,13 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
committedTxs := make(chan committedTx, 3)
|
||||
|
||||
txs := s.BroadcastTxsWithCallback(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
Height: height + 1,
|
||||
Height: height + 3,
|
||||
},
|
||||
{
|
||||
User: s.user2,
|
||||
@ -1063,13 +1181,23 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
},
|
||||
},
|
||||
},
|
||||
}, func(tx []byte, resp *rpctypes.ResultTx) {
|
||||
committedTxs <- committedTx{tx: tx, res: resp}
|
||||
})
|
||||
close(committedTxs)
|
||||
|
||||
// check block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
// find height of committed tx
|
||||
var committedHeight int64
|
||||
for tx := range committedTxs {
|
||||
if bytes.Equal(tx.tx, txs[0]) {
|
||||
committedHeight = tx.res.Height
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), append(bundledTx, txs[1:]...))
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), committedHeight)
|
||||
|
||||
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTx)
|
||||
|
||||
// check user2 balance expect no fee deduction
|
||||
user2BalanceAfter := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
|
||||
@ -1080,8 +1208,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
|
||||
user1Balance := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user1.FormattedAddress(), s.denom)
|
||||
// create free-tx, bid-tx, and normal-tx\
|
||||
bid, _ := CreateAuctionBidMsg(
|
||||
s.T(),
|
||||
bid, _ := s.CreateAuctionBidMsg(
|
||||
context.Background(),
|
||||
s.user1,
|
||||
s.chain.(*cosmos.CosmosChain),
|
||||
@ -1115,7 +1242,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user1,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -1145,12 +1272,6 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
},
|
||||
})
|
||||
|
||||
// check block
|
||||
WaitForHeight(s.T(), s.chain.(*cosmos.CosmosChain), height+1)
|
||||
block := Block(s.T(), s.chain.(*cosmos.CosmosChain), int64(height+1))
|
||||
|
||||
VerifyBlock(s.T(), block, 0, "", txs[1:])
|
||||
|
||||
// check user2 balance expect no fee deduction
|
||||
user2BalanceAfter := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
|
||||
require.Equal(s.T(), user2BalanceBefore, user2BalanceAfter+delegation.Amount.Int64())
|
||||
@ -1171,8 +1292,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
GasPrice: 10,
|
||||
}
|
||||
|
||||
bid, bundledTx := CreateAuctionBidMsg(
|
||||
s.T(),
|
||||
bid, bundledTx := s.CreateAuctionBidMsg(
|
||||
context.Background(),
|
||||
s.user3,
|
||||
s.chain.(*cosmos.CosmosChain),
|
||||
@ -1196,7 +1316,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
txs := s.BroadcastTxs(context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user3,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
@ -1248,8 +1368,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
|
||||
// create bid-tx w/ user3 DelegateTx
|
||||
|
||||
bid, bundledTx := CreateAuctionBidMsg(
|
||||
s.T(),
|
||||
bid, bundledTx := s.CreateAuctionBidMsg(
|
||||
context.Background(),
|
||||
s.user3,
|
||||
s.chain.(*cosmos.CosmosChain),
|
||||
@ -1273,7 +1392,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
height, err := s.chain.(*cosmos.CosmosChain).Height(context.Background())
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
txs := BroadcastTxs(s.T(), context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
txs := s.BroadcastTxs( context.Background(), s.chain.(*cosmos.CosmosChain), []Tx{
|
||||
{
|
||||
User: s.user3,
|
||||
Msgs: []sdk.Msg{bid},
|
||||
|
||||
@ -7,6 +7,14 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
"os"
|
||||
"io"
|
||||
"path"
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
rpctypes "github.com/cometbft/cometbft/rpc/core/types"
|
||||
@ -29,6 +37,11 @@ import (
|
||||
auctiontypes "github.com/skip-mev/block-sdk/x/auction/types"
|
||||
)
|
||||
|
||||
type KeyringOverride struct {
|
||||
keyringOptions keyring.Option
|
||||
cdc codec.Codec
|
||||
}
|
||||
|
||||
// ChainBuilderFromChainSpec creates an interchaintest chain builder factory given a ChainSpec
|
||||
// and returns the associated chain
|
||||
func ChainBuilderFromChainSpec(t *testing.T, spec *interchaintest.ChainSpec) ibc.Chain {
|
||||
@ -73,19 +86,18 @@ func BuildInterchain(t *testing.T, ctx context.Context, chain ibc.Chain) *interc
|
||||
}
|
||||
|
||||
// CreateTx creates a new transaction to be signed by the given user, including a provided set of messages
|
||||
func CreateTx(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user cosmos.User, seqIncrement, height uint64, GasPrice int64, msgs ...sdk.Msg) []byte {
|
||||
// create a broadcaster
|
||||
broadcaster := cosmos.NewBroadcaster(t, chain)
|
||||
|
||||
func (s *IntegrationTestSuite) CreateTx(ctx context.Context, chain *cosmos.CosmosChain, user cosmos.User, seqIncrement, height uint64, GasPrice int64, msgs ...sdk.Msg) []byte {
|
||||
// create tx factory + Client Context
|
||||
txf, err := broadcaster.GetFactory(ctx, user)
|
||||
require.NoError(t, err)
|
||||
txf, err := s.bc.GetFactory(ctx, user)
|
||||
s.Require().NoError(err)
|
||||
|
||||
cc, err := broadcaster.GetClientContext(ctx, user)
|
||||
require.NoError(t, err)
|
||||
cc, err := s.bc.GetClientContext(ctx, user)
|
||||
s.Require().NoError(err)
|
||||
|
||||
txf = txf.WithSimulateAndExecute(true)
|
||||
|
||||
txf, err = txf.Prepare(cc)
|
||||
require.NoError(t, err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// set timeout height
|
||||
if height != 0 {
|
||||
@ -94,7 +106,7 @@ func CreateTx(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user
|
||||
|
||||
// get gas for tx
|
||||
_, gas, err := tx.CalculateGas(cc, txf, msgs...)
|
||||
require.NoError(t, err)
|
||||
s.Require().NoError(err)
|
||||
txf.WithGas(gas)
|
||||
|
||||
// update sequence number
|
||||
@ -103,30 +115,27 @@ func CreateTx(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user
|
||||
|
||||
// sign the tx
|
||||
txBuilder, err := txf.BuildUnsignedTx(msgs...)
|
||||
require.NoError(t, err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
require.NoError(t, tx.Sign(ctx, txf, cc.GetFromName(), txBuilder, true))
|
||||
s.Require().NoError(tx.Sign(cc.CmdContext, txf, cc.GetFromName(), txBuilder, true))
|
||||
|
||||
// encode and return
|
||||
bz, err := cc.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
require.NoError(t, err)
|
||||
s.Require().NoError(err)
|
||||
return bz
|
||||
}
|
||||
|
||||
// SimulateTx simulates the provided messages, and checks whether the provided failure condition is met
|
||||
func SimulateTx(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, user cosmos.User, height uint64, expectFail bool, msgs ...sdk.Msg) {
|
||||
// create a broadcaster
|
||||
broadcaster := cosmos.NewBroadcaster(t, chain)
|
||||
|
||||
func (s *IntegrationTestSuite) SimulateTx(ctx context.Context, chain *cosmos.CosmosChain, user cosmos.User, height uint64, expectFail bool, msgs ...sdk.Msg) {
|
||||
// create tx factory + Client Context
|
||||
txf, err := broadcaster.GetFactory(ctx, user)
|
||||
require.NoError(t, err)
|
||||
txf, err := s.bc.GetFactory(ctx, user)
|
||||
s.Require().NoError(err)
|
||||
|
||||
cc, err := broadcaster.GetClientContext(ctx, user)
|
||||
require.NoError(t, err)
|
||||
cc, err := s.bc.GetClientContext(ctx, user)
|
||||
s.Require().NoError(err)
|
||||
|
||||
txf, err = txf.Prepare(cc)
|
||||
require.NoError(t, err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// set timeout height
|
||||
if height != 0 {
|
||||
@ -135,7 +144,7 @@ func SimulateTx(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, us
|
||||
|
||||
// get gas for tx
|
||||
_, _, err = tx.CalculateGas(cc, txf, msgs...)
|
||||
require.Equal(t, err != nil, expectFail)
|
||||
s.Require().Equal(err != nil, expectFail)
|
||||
}
|
||||
|
||||
type Tx struct {
|
||||
@ -149,16 +158,16 @@ type Tx struct {
|
||||
}
|
||||
|
||||
// CreateAuctionBidMsg creates a new AuctionBid tx signed by the given user, the order of txs in the MsgAuctionBid will be determined by the contents + order of the MessageForUsers
|
||||
func CreateAuctionBidMsg(t *testing.T, ctx context.Context, searcher cosmos.User, chain *cosmos.CosmosChain, bid sdk.Coin, txsPerUser []Tx) (*auctiontypes.MsgAuctionBid, [][]byte) {
|
||||
func (s *IntegrationTestSuite) CreateAuctionBidMsg(ctx context.Context, searcher cosmos.User, chain *cosmos.CosmosChain, bid sdk.Coin, txsPerUser []Tx) (*auctiontypes.MsgAuctionBid, [][]byte) {
|
||||
// for each MessagesForUser get the signed bytes
|
||||
txs := make([][]byte, len(txsPerUser))
|
||||
for i, tx := range txsPerUser {
|
||||
txs[i] = CreateTx(t, ctx, chain, tx.User, tx.SequenceIncrement, tx.Height, tx.GasPrice, tx.Msgs...)
|
||||
txs[i] = s.CreateTx(ctx, chain, tx.User, tx.SequenceIncrement, tx.Height, tx.GasPrice, tx.Msgs...)
|
||||
}
|
||||
|
||||
bech32SearcherAddress := searcher.FormattedAddress()
|
||||
accAddr, err := sdk.AccAddressFromBech32(bech32SearcherAddress)
|
||||
require.NoError(t, err)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// create a message auction bid
|
||||
return auctiontypes.NewMsgAuctionBid(
|
||||
@ -171,26 +180,43 @@ func CreateAuctionBidMsg(t *testing.T, ctx context.Context, searcher cosmos.User
|
||||
// BroadcastTxs broadcasts the given messages for each user. This function returns the broadcasted txs. If a message
|
||||
// is not expected to be included in a block, set SkipInclusionCheck to true and the method
|
||||
// will not block on the tx's inclusion in a block, otherwise this method will block on the tx's inclusion
|
||||
func BroadcastTxs(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain, msgsPerUser []Tx) [][]byte {
|
||||
func (s *IntegrationTestSuite) BroadcastTxs(ctx context.Context, chain *cosmos.CosmosChain, msgsPerUser []Tx) [][]byte {
|
||||
return s.BroadcastTxsWithCallback(ctx, chain, msgsPerUser, nil)
|
||||
}
|
||||
|
||||
// BroadcastTxs broadcasts the given messages for each user. This function returns the broadcasted txs. If a message
|
||||
// is not expected to be included in a block, set SkipInclusionCheck to true and the method
|
||||
// will not block on the tx's inclusion in a block, otherwise this method will block on the tx's inclusion. The callback
|
||||
// function is called for each tx that is included in a block.
|
||||
func (s *IntegrationTestSuite) BroadcastTxsWithCallback(
|
||||
ctx context.Context,
|
||||
chain *cosmos.CosmosChain,
|
||||
msgsPerUser []Tx,
|
||||
cb func(tx []byte, resp *rpctypes.ResultTx),
|
||||
) [][]byte {
|
||||
txs := make([][]byte, len(msgsPerUser))
|
||||
|
||||
for i, msg := range msgsPerUser {
|
||||
txs[i] = CreateTx(t, ctx, chain, msg.User, msg.SequenceIncrement, msg.Height, msg.GasPrice, msg.Msgs...)
|
||||
txs[i] = s.CreateTx(ctx, chain, msg.User, msg.SequenceIncrement, msg.Height, msg.GasPrice, msg.Msgs...)
|
||||
}
|
||||
|
||||
// broadcast each tx
|
||||
require.True(t, len(chain.Nodes()) > 0)
|
||||
s.Require().True(len(chain.Nodes()) > 0)
|
||||
client := chain.Nodes()[0].Client
|
||||
|
||||
for i, tx := range txs {
|
||||
// broadcast tx
|
||||
_, err := client.BroadcastTxSync(ctx, tx)
|
||||
resp, err := client.BroadcastTxSync(ctx, tx)
|
||||
|
||||
// check execution was successful
|
||||
if !msgsPerUser[i].ExpectFail {
|
||||
require.NoError(t, err)
|
||||
s.Require().Equal(resp.Code, uint32(0))
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
if resp != nil {
|
||||
s.Require().NotEqual(resp.Code, uint32(0))
|
||||
} else {
|
||||
s.Require().Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -205,18 +231,22 @@ func BroadcastTxs(t *testing.T, ctx context.Context, chain *cosmos.CosmosChain,
|
||||
|
||||
tx := tx // pin
|
||||
eg.Go(func() error {
|
||||
return testutil.WaitForCondition(4*time.Second, 500*time.Millisecond, func() (bool, error) {
|
||||
return testutil.WaitForCondition(30*time.Second, 500*time.Millisecond, func() (bool, error) {
|
||||
res, err := client.Tx(context.Background(), comettypes.Tx(tx).Hash(), false)
|
||||
|
||||
if err != nil || res.TxResult.Code != uint32(0) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if cb != nil {
|
||||
cb(tx, res)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
require.NoError(t, eg.Wait())
|
||||
s.Require().NoError(eg.Wait())
|
||||
|
||||
return txs
|
||||
}
|
||||
@ -313,12 +343,12 @@ func Block(t *testing.T, chain *cosmos.CosmosChain, height int64) *rpctypes.Resu
|
||||
// WaitForHeight waits for the chain to reach the given height
|
||||
func WaitForHeight(t *testing.T, chain *cosmos.CosmosChain, height uint64) {
|
||||
// wait for next height
|
||||
err := testutil.WaitForCondition(30*time.Second, time.Second, func() (bool, error) {
|
||||
err := testutil.WaitForCondition(30*time.Second, 100 * time.Millisecond, func() (bool, error) {
|
||||
pollHeight, err := chain.Height(context.Background())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return pollHeight == height, nil
|
||||
return pollHeight >= height, nil
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@ -340,3 +370,73 @@ func VerifyBlock(t *testing.T, block *rpctypes.ResultBlock, offset int, bidTxHas
|
||||
func TxHash(tx []byte) string {
|
||||
return strings.ToUpper(hex.EncodeToString(comettypes.Tx(tx).Hash()))
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) setupBroadcaster() {
|
||||
bc := cosmos.NewBroadcaster(s.T(), s.chain.(*cosmos.CosmosChain))
|
||||
|
||||
if s.broadcasterOverrides == nil {
|
||||
s.bc = bc
|
||||
return
|
||||
}
|
||||
|
||||
// get the key-ring-dir from the node locally
|
||||
keyringDir := s.keyringDirFromNode()
|
||||
|
||||
// create a new keyring
|
||||
kr, err := keyring.New("", keyring.BackendTest, keyringDir, os.Stdin, s.broadcasterOverrides.cdc, s.broadcasterOverrides.keyringOptions)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// override factory + client context keyrings
|
||||
bc.ConfigureFactoryOptions(
|
||||
func(factory tx.Factory) tx.Factory {
|
||||
return factory.WithKeybase(kr)
|
||||
},
|
||||
)
|
||||
|
||||
bc.ConfigureClientContextOptions(
|
||||
func(cc client.Context) client.Context {
|
||||
return cc.WithKeyring(kr)
|
||||
},
|
||||
)
|
||||
|
||||
s.bc = bc
|
||||
}
|
||||
|
||||
// sniped from here: https://github.com/strangelove-ventures/interchaintest ref: 9341b001214d26be420f1ca1ab0f15bad17faee6
|
||||
func (s *IntegrationTestSuite) keyringDirFromNode() (string) {
|
||||
node := s.chain.(*cosmos.CosmosChain).Nodes()[0]
|
||||
|
||||
// create a temp-dir
|
||||
localDir := s.T().TempDir()
|
||||
|
||||
containerKeyringDir := path.Join(node.HomeDir(), "keyring-test")
|
||||
reader, _, err := node.DockerClient.CopyFromContainer(context.Background(), node.ContainerID(), containerKeyringDir)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().NoError(os.Mkdir(path.Join(localDir, "keyring-test"), os.ModePerm))
|
||||
|
||||
tr := tar.NewReader(reader)
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
break // End of archive
|
||||
}
|
||||
s.Require().NoError(err)
|
||||
|
||||
var fileBuff bytes.Buffer
|
||||
_, err = io.Copy(&fileBuff, tr)
|
||||
s.Require().NoError(err)
|
||||
|
||||
name := hdr.Name
|
||||
extractedFileName := path.Base(name)
|
||||
isDirectory := extractedFileName == ""
|
||||
if isDirectory {
|
||||
continue
|
||||
}
|
||||
|
||||
filePath := path.Join(localDir, "keyring-test", extractedFileName)
|
||||
s.Require().NoError(os.WriteFile(filePath, fileBuff.Bytes(), os.ModePerm))
|
||||
}
|
||||
|
||||
return localDir
|
||||
}
|
||||
|
||||
@ -16,9 +16,9 @@ require (
|
||||
github.com/cometbft/cometbft v0.38.0
|
||||
github.com/cosmos/cosmos-sdk v0.50.0-rc.0
|
||||
github.com/skip-mev/block-sdk v1.0.0 // reference local
|
||||
github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230721183422-fb937bb0e165
|
||||
github.com/strangelove-ventures/interchaintest/v7 v7.0.0-20230905210439-3e17efc70581
|
||||
github.com/stretchr/testify v1.8.4
|
||||
go.uber.org/zap v1.24.0
|
||||
go.uber.org/zap v1.25.0
|
||||
golang.org/x/sync v0.3.0
|
||||
google.golang.org/grpc v1.58.1
|
||||
)
|
||||
@ -46,7 +46,7 @@ require (
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/avast/retry-go/v4 v4.5.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.224 // indirect
|
||||
github.com/benbjohnson/clock v1.1.0 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
|
||||
@ -185,7 +185,6 @@ require (
|
||||
github.com/zondax/ledger-go v0.14.1 // indirect
|
||||
go.etcd.io/bbolt v1.3.7 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
|
||||
|
||||
@ -266,8 +266,9 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX
|
||||
github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ=
|
||||
github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@ -1069,11 +1070,9 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
@ -1083,8 +1082,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
|
||||
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
|
||||
@ -48,13 +48,6 @@ func NewAuctionDecorator(ak keeper.Keeper, txEncoder sdk.TxEncoder, lane MEVLane
|
||||
// AnteHandle validates that the auction bid is valid if one exists. If valid it will deduct the entrance fee from the
|
||||
// bidder's account.
|
||||
func (ad AuctionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||
// If comet is re-checking a transaction, we only need to check if the transaction is in the application-side mempool.
|
||||
if ctx.IsReCheckTx() {
|
||||
if !ad.mempool.Contains(tx) {
|
||||
return ctx, fmt.Errorf("transaction not found in application-side mempool")
|
||||
}
|
||||
}
|
||||
|
||||
bidInfo, err := ad.lane.GetAuctionBidInfo(tx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
@ -62,6 +55,13 @@ func (ad AuctionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
|
||||
// Validate the auction bid if one exists.
|
||||
if bidInfo != nil {
|
||||
// If comet is re-checking a transaction, we only need to check if the transaction is in the application-side mempool.
|
||||
if ctx.IsReCheckTx() {
|
||||
if !ad.mempool.Contains(tx) {
|
||||
return ctx, fmt.Errorf("transaction not found in application-side mempool")
|
||||
}
|
||||
}
|
||||
|
||||
// Auction transactions must have a timeout set to a valid block height.
|
||||
if err := ad.ValidateTimeout(ctx, int64(bidInfo.Timeout)); err != nil {
|
||||
return ctx, err
|
||||
@ -71,6 +71,7 @@ func (ad AuctionDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
// is checkTx or recheckTx. Otherwise, the ABCI handlers (VerifyVoteExtension, ExtendVoteExtension, etc.)
|
||||
// will always compare the auction bid to the highest bidding transaction in the mempool leading to
|
||||
// poor liveness guarantees.
|
||||
// TODO(nikhil/david): refactor this logic (is this necessary?)
|
||||
topBid := sdk.Coin{}
|
||||
if ctx.IsCheckTx() || ctx.IsReCheckTx() {
|
||||
if topBidTx := ad.lane.GetTopAuctionTx(ctx); topBidTx != nil {
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"github.com/golang/mock/gomock"
|
||||
"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"
|
||||
@ -86,25 +87,27 @@ func (suite *AnteTestSuite) SetupTest() {
|
||||
//
|
||||
// TOB lane set up
|
||||
mevConfig := base.LaneConfig{
|
||||
Logger: suite.ctx.Logger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: suite.anteHandler,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
Logger: suite.ctx.Logger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
AnteHandler: suite.anteHandler,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
}
|
||||
suite.mevLane = mev.NewMEVLane(
|
||||
mevConfig,
|
||||
mev.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
|
||||
mev.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder(), signer_extraction.NewDefaultAdapter()),
|
||||
)
|
||||
|
||||
// Base lane set up
|
||||
baseConfig := base.LaneConfig{
|
||||
Logger: suite.ctx.Logger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: suite.anteHandler,
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []block.Lane{suite.mevLane},
|
||||
Logger: suite.ctx.Logger(),
|
||||
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
|
||||
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
|
||||
AnteHandler: suite.anteHandler,
|
||||
SignerExtractor: signer_extraction.NewDefaultAdapter(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []block.Lane{suite.mevLane},
|
||||
}
|
||||
suite.baseLane = defaultlane.NewDefaultLane(baseConfig)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user