From f607439637cba37861e899aeaa75f13ae7583af7 Mon Sep 17 00:00:00 2001 From: David Terpay <35130517+davidterpay@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:17:56 -0500 Subject: [PATCH] fix: Make lanes mutually exclusive by default (#206) * lanes always mutually exclusive * nit 1.0.0.0 * gg adding back interface --------- Co-authored-by: Alex Johnson --- abci/abci_test.go | 67 +++-- abci/utils_test.go | 22 +- block/base/lane.go | 10 + block/lane.go | 3 + block/mempool.go | 216 +++++++++------- block/mempool_test.go | 241 +++++++++++++++--- block/mocks/lane.go | 21 +- block/mocks/lane_mempool.go | 5 +- block/proposals/proposals_test.go | 20 +- lanes/base/abci_test.go | 54 ++-- lanes/build-your-own/README.md | 5 +- lanes/mev/abci_test.go | 38 +-- lanes/mev/mev_test.go | 2 +- lanes/terminator/lane.go | 5 + tests/app/app.go | 9 +- .../integration/block_sdk_integration_test.go | 2 +- tests/integration/chain_setup.go | 2 +- 17 files changed, 475 insertions(+), 247 deletions(-) diff --git a/abci/abci_test.go b/abci/abci_test.go index 29ed6d4..bc63e2c 100644 --- a/abci/abci_test.go +++ b/abci/abci_test.go @@ -672,7 +672,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() { func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { s.Run("can build a proposal if a lane panics first", func() { - panicLane := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.25")) + panicLane := s.setUpPanicLane("panik1", math.LegacyMustNewDecFromStr("0.25")) tx, err := testutils.CreateRandomTx( s.encodingConfig.TxConfig, @@ -708,19 +708,21 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { }, } - mempool := block.NewLanedMempool( - log.NewTestLogger(s.T()), - false, + mempool, err := block.NewLanedMempool( + log.NewNopLogger(), + lanes, mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { return blocksdkmoduletypes.Lane{}, nil }, func() []blocksdkmoduletypes.Lane { return chainLanes }), - lanes..., ) + s.Require().NoError(err) + + defaultLane.SetIgnoreList(nil) proposalHandler := abci.NewProposalHandler( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxDecoder(), s.encodingConfig.TxConfig.TxEncoder(), mempool, @@ -748,7 +750,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { }) s.Run("can build a proposal if second lane panics", func() { - panicLane := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.25")) + panicLane := s.setUpPanicLane("panik1", math.LegacyMustNewDecFromStr("0.25")) tx, err := testutils.CreateRandomTx( s.encodingConfig.TxConfig, @@ -784,19 +786,21 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { }, } - mempool := block.NewLanedMempool( - log.NewTestLogger(s.T()), - false, + mempool, err := block.NewLanedMempool( + log.NewNopLogger(), + lanes, mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { return blocksdkmoduletypes.Lane{}, nil }, func() []blocksdkmoduletypes.Lane { return chainLanes }), - lanes..., ) + s.Require().NoError(err) + + defaultLane.SetIgnoreList(nil) proposalHandler := abci.NewProposalHandler( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxDecoder(), s.encodingConfig.TxConfig.TxEncoder(), mempool, @@ -824,8 +828,8 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { }) s.Run("can build a proposal if multiple consecutive lanes panic", func() { - panicLane := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.25")) - panicLane2 := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.25")) + panicLane := s.setUpPanicLane("panik1", math.LegacyMustNewDecFromStr("0.25")) + panicLane2 := s.setUpPanicLane("panik2", math.LegacyMustNewDecFromStr("0.25")) tx, err := testutils.CreateRandomTx( s.encodingConfig.TxConfig, @@ -867,18 +871,23 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { }, } - mempool := block.NewLanedMempool( - log.NewTestLogger(s.T()), - false, + mempool, err := block.NewLanedMempool( + log.NewNopLogger(), + lanes, mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { return blocksdkmoduletypes.Lane{}, nil }, func() []blocksdkmoduletypes.Lane { return chainLanes }), - lanes..., ) + s.Require().NoError(err) + + panicLane.SetIgnoreList(nil) + panicLane2.SetIgnoreList(nil) + defaultLane.SetIgnoreList(nil) + proposalHandler := abci.NewProposalHandler( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxDecoder(), s.encodingConfig.TxConfig.TxEncoder(), mempool, @@ -906,8 +915,8 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { }) s.Run("can build a proposal if the last few lanes panic", func() { - panicLane := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.25")) - panicLane2 := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.25")) + panicLane := s.setUpPanicLane("panik1", math.LegacyMustNewDecFromStr("0.25")) + panicLane2 := s.setUpPanicLane("panik2", math.LegacyMustNewDecFromStr("0.25")) tx, err := testutils.CreateRandomTx( s.encodingConfig.TxConfig, @@ -949,19 +958,23 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() { }, } - mempool := block.NewLanedMempool( - log.NewTestLogger(s.T()), - false, + mempool, err := block.NewLanedMempool( + log.NewNopLogger(), + lanes, mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { return blocksdkmoduletypes.Lane{}, nil }, func() []blocksdkmoduletypes.Lane { return chainLanes }), - lanes..., ) + s.Require().NoError(err) + + panicLane.SetIgnoreList(nil) + panicLane2.SetIgnoreList(nil) + defaultLane.SetIgnoreList(nil) proposalHandler := abci.NewProposalHandler( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxDecoder(), s.encodingConfig.TxConfig.TxEncoder(), mempool, @@ -1237,7 +1250,7 @@ func (s *ProposalsTestSuite) TestProcessProposal() { s.Run("rejects a proposal when a lane panics", func() { mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{}) - panicLane := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.0")) + panicLane := s.setUpPanicLane("default", math.LegacyMustNewDecFromStr("0.0")) txbz, err := testutils.CreateRandomTxBz( s.encodingConfig.TxConfig, diff --git a/abci/utils_test.go b/abci/utils_test.go index fdbaef0..453e674 100644 --- a/abci/utils_test.go +++ b/abci/utils_test.go @@ -60,7 +60,7 @@ 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()), + Logger: log.NewNopLogger(), TxEncoder: s.encodingConfig.TxConfig.TxEncoder(), TxDecoder: s.encodingConfig.TxConfig.TxDecoder(), AnteHandler: s.setUpAnteHandler(expectedExecution), @@ -74,7 +74,7 @@ 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()), + Logger: log.NewNopLogger(), TxEncoder: s.encodingConfig.TxConfig.TxEncoder(), TxDecoder: s.encodingConfig.TxConfig.TxDecoder(), AnteHandler: s.setUpAnteHandler(expectedExecution), @@ -87,7 +87,7 @@ func (s *ProposalsTestSuite) setUpTOBLane(maxBlockSpace math.LegacyDec, expected func (s *ProposalsTestSuite) setUpFreeLane(maxBlockSpace math.LegacyDec, expectedExecution map[sdk.Tx]bool) *free.FreeLane { cfg := base.LaneConfig{ - Logger: log.NewTestLogger(s.T()), + Logger: log.NewNopLogger(), TxEncoder: s.encodingConfig.TxConfig.TxEncoder(), TxDecoder: s.encodingConfig.TxConfig.TxDecoder(), AnteHandler: s.setUpAnteHandler(expectedExecution), @@ -98,9 +98,9 @@ func (s *ProposalsTestSuite) setUpFreeLane(maxBlockSpace math.LegacyDec, expecte return free.NewFreeLane(cfg, base.DefaultTxPriority(), free.DefaultMatchHandler()) } -func (s *ProposalsTestSuite) setUpPanicLane(maxBlockSpace math.LegacyDec) *base.BaseLane { +func (s *ProposalsTestSuite) setUpPanicLane(name string, maxBlockSpace math.LegacyDec) *base.BaseLane { cfg := base.LaneConfig{ - Logger: log.NewTestLogger(s.T()), + Logger: log.NewNopLogger(), TxEncoder: s.encodingConfig.TxConfig.TxEncoder(), TxDecoder: s.encodingConfig.TxConfig.TxDecoder(), MaxBlockSpace: maxBlockSpace, @@ -109,7 +109,7 @@ func (s *ProposalsTestSuite) setUpPanicLane(maxBlockSpace math.LegacyDec) *base. lane := base.NewBaseLane( cfg, - "panic", + name, base.NewMempool[string](base.DefaultTxPriority(), cfg.TxEncoder, cfg.SignerExtractor, 0), base.DefaultMatchHandler(), ) @@ -138,15 +138,15 @@ func (s *ProposalsTestSuite) setUpProposalHandlers(lanes []block.Lane) *abci.Pro return blocksdkLanes }) - mempool := block.NewLanedMempool(log.NewTestLogger( - s.T()), - false, + mempool, err := block.NewLanedMempool( + log.NewNopLogger(), + lanes, laneFetcher, - lanes..., ) + s.Require().NoError(err) return abci.NewProposalHandler( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxDecoder(), s.encodingConfig.TxConfig.TxEncoder(), mempool, diff --git a/block/base/lane.go b/block/base/lane.go index b332071..e6b0568 100644 --- a/block/base/lane.go +++ b/block/base/lane.go @@ -128,6 +128,10 @@ func (l *BaseLane) Match(ctx sdk.Context, tx sdk.Tx) bool { // list is utilized to prevent transactions that should be considered in other lanes // from being considered from this lane. func (l *BaseLane) CheckIgnoreList(ctx sdk.Context, tx sdk.Tx) bool { + if l.cfg.IgnoreList == nil { + return false + } + for _, lane := range l.cfg.IgnoreList { if lane.Match(ctx, tx) { return true @@ -148,6 +152,12 @@ func (l *BaseLane) SetIgnoreList(lanes []block.Lane) { l.cfg.IgnoreList = lanes } +// GetIgnoreList returns the ignore list for the lane. The ignore list is a list +// of lanes that the lane should ignore when processing transactions. +func (l *BaseLane) GetIgnoreList() []block.Lane { + return l.cfg.IgnoreList +} + // SetAnteHandler sets the ante handler for the lane. func (l *BaseLane) SetAnteHandler(anteHandler sdk.AnteHandler) { l.cfg.AnteHandler = anteHandler diff --git a/block/lane.go b/block/lane.go index f3dd80b..137cb85 100644 --- a/block/lane.go +++ b/block/lane.go @@ -69,6 +69,9 @@ type Lane interface { // SetIgnoreList sets the lanes that should be ignored by this lane. SetIgnoreList(ignoreList []Lane) + // GetIgnoreList returns the lanes that should be ignored by this lane. + GetIgnoreList() []Lane + // Match determines if a transaction belongs to this lane. Match(ctx sdk.Context, tx sdk.Tx) bool } diff --git a/block/mempool.go b/block/mempool.go index f4c5b3c..e82faea 100644 --- a/block/mempool.go +++ b/block/mempool.go @@ -3,7 +3,6 @@ package block import ( "context" "fmt" - "strings" "cosmossdk.io/log" "cosmossdk.io/math" @@ -13,6 +12,12 @@ import ( blocksdkmoduletypes "github.com/skip-mev/block-sdk/x/blocksdk/types" ) +const ( + // DefaultLaneName is the default lane name. We enforce that a lane with the name + // "default" is provided when constructing the mempool. + DefaultLaneName = "default" +) + var _ Mempool = (*LanedMempool)(nil) // LaneFetcher defines the interface to get a lane stored in the x/blocksdk module. @@ -53,19 +58,65 @@ type ( ) // NewLanedMempool returns a new Block SDK LanedMempool. The laned mempool comprises +// a registry of lanes. Each lane is responsible for selecting transactions according +// to its own selection logic. The lanes are ordered according to their priority. The +// first lane in the registry has the highest priority. Proposals are verified according +// to the order of the lanes in the registry. Each transaction SHOULD only belong in one lane. +// To enforce that transactions only belong to one lane, each lane has an ignore list. // -// a registry of lanes. Each lane is responsible for selecting +// For example, say we have three lanes, MEV, default, and free. The ignore list of each +// lane will look like the following: +// - MEV: free +// - default: MEV, free +// - free: MEV. // -// transactions according to its own selection logic. The lanes are ordered -// according to their priority. The first lane in the registry has the highest -// priority. Proposals are verified according to the order of the lanes in the -// registry. Each transaction should only belong in one lane but this is NOT enforced. -// To enforce that each transaction belong to a single lane, you must configure the -// ignore list of each lane to include all preceding lanes. Basic mempool API will -// attempt to insert, remove transactions from all lanes it belongs to. It is recommended, -// that mutex is set to true when creating the mempool. This will ensure that each -// transaction cannot be inserted into the lanes before it. -func NewLanedMempool(logger log.Logger, mutex bool, laneFetcher LaneFetcher, lanes ...Lane) Mempool { +// Note that a name with the value "default" MUST be provided. +func NewLanedMempool( + logger log.Logger, + lanes []Lane, + laneFetcher LaneFetcher, +) (*LanedMempool, error) { + laneCache := make(map[Lane]struct{}) + seenDefault := false + + // Ensure that each of the lanes are mutually exclusive. The default lane should + // ignore all other lanes, while all other lanes should ignore every lane except + // the default lane. + for index, lane := range lanes { + if lane.Name() == DefaultLaneName { + lowerIgnoreList := make([]Lane, index) + copy(lowerIgnoreList, lanes[:index]) + + upperIgnoreList := make([]Lane, len(lanes)-index-1) + copy(upperIgnoreList, lanes[index+1:]) + + lane.SetIgnoreList(append(lowerIgnoreList, upperIgnoreList...)) + seenDefault = true + } else { + laneCache[lane] = struct{}{} + } + } + + if !seenDefault { + return nil, fmt.Errorf("default lane not found. a lane with the name %s must be provided", DefaultLaneName) + } + + for _, lane := range lanes { + if lane.Name() == DefaultLaneName { + continue + } + + delete(laneCache, lane) + + ignoreList := make([]Lane, 0) + for otherLane := range laneCache { + ignoreList = append(ignoreList, otherLane) + } + + lane.SetIgnoreList(ignoreList) + laneCache[lane] = struct{}{} + } + mempool := &LanedMempool{ logger: logger, registry: lanes, @@ -73,22 +124,10 @@ func NewLanedMempool(logger log.Logger, mutex bool, laneFetcher LaneFetcher, lan } if err := mempool.ValidateBasic(); err != nil { - panic(err) + return nil, err } - // Set the ignore list for each lane - if mutex { - // perform full copy to prevent GC - registry := make([]Lane, len(mempool.registry)) - copy(registry, mempool.registry) - for index, lane := range registry { - if index > 0 { - lane.SetIgnoreList(registry[:index]) - } - } - } - - return mempool + return mempool, nil } // CountTx returns the total number of transactions in the mempool. This will @@ -123,25 +162,14 @@ func (m *LanedMempool) Insert(ctx context.Context, tx sdk.Tx) (err error) { } }() - var errors []string - unwrappedCtx := sdk.UnwrapSDKContext(ctx) for _, lane := range m.registry { - if !lane.Match(unwrappedCtx, tx) { - continue - } - - if err := lane.Insert(ctx, tx); err != nil { - m.logger.Debug("failed to insert tx into lane", "lane", lane.Name(), "err", err) - errors = append(errors, fmt.Sprintf("failed to insert tx into lane %s: %s", lane.Name(), err.Error())) + if lane.Match(unwrappedCtx, tx) { + return lane.Insert(ctx, tx) } } - if len(errors) == 0 { - return nil - } - - return fmt.Errorf(strings.Join(errors, ";")) + return nil } // Insert returns a nil iterator. @@ -154,7 +182,8 @@ func (m *LanedMempool) Select(_ context.Context, _ [][]byte) sdkmempool.Iterator return nil } -// Remove removes a transaction from all of the lanes it is currently in. +// Remove removes a transaction from the mempool. This assumes that the transaction +// is contained in only one of the lanes. func (m *LanedMempool) Remove(tx sdk.Tx) (err error) { defer func() { if r := recover(); r != nil { @@ -163,33 +192,13 @@ func (m *LanedMempool) Remove(tx sdk.Tx) (err error) { } }() - var errors []string - for _, lane := range m.registry { - if !lane.Contains(tx) { - continue - } - - if err := lane.Remove(tx); err != nil { - m.logger.Debug("failed to remove tx from lane", "lane", lane.Name(), "err", err) - - // We only care about errors that are not "tx not found" errors. - // - // TODO: Figure out whether we should be erroring in the mempool if - // the tx is not found in the lane. Downstream, if the removal fails runTx will - // error out and will NOT execute runMsgs (which is where the tx is actually - // executed). - if err != sdkmempool.ErrTxNotFound { - errors = append(errors, fmt.Sprintf("failed to remove tx from lane %s: %s;", lane.Name(), err.Error())) - } + if lane.Contains(tx) { + return lane.Remove(tx) } } - if len(errors) == 0 { - return nil - } - - return fmt.Errorf(strings.Join(errors, ";")) + return nil } // Contains returns true if the transaction is contained in any of the lanes. @@ -210,40 +219,6 @@ func (m *LanedMempool) Contains(tx sdk.Tx) (contains bool) { return false } -// ValidateBasic validates the mempools configuration. ValidateBasic ensures -// the following: -// - The sum of the lane max block space percentages is less than or equal to 1. -// - There is no unused block space. -func (m *LanedMempool) ValidateBasic() error { - sum := math.LegacyZeroDec() - seenZeroMaxBlockSpace := false - - for _, lane := range m.registry { - maxBlockSpace := lane.GetMaxBlockSpace() - if maxBlockSpace.IsZero() { - seenZeroMaxBlockSpace = true - } - - sum = sum.Add(lane.GetMaxBlockSpace()) - } - - switch { - // Ensure that the sum of the lane max block space percentages is less than - // or equal to 1. - case sum.GT(math.LegacyOneDec()): - return fmt.Errorf("sum of lane max block space percentages must be less than or equal to 1, got %s", sum) - // Ensure that there is no unused block space. - case sum.LT(math.LegacyOneDec()) && !seenZeroMaxBlockSpace: - return fmt.Errorf("sum of total block space percentages will be less than 1") - } - - if m.moduleLaneFetcher == nil { - return fmt.Errorf("moduleLaneFetcher muset be set on mempool") - } - - return nil -} - // Registry returns the mempool's lane registry. func (m *LanedMempool) Registry(ctx sdk.Context) (newRegistry []Lane, err error) { if m.moduleLaneFetcher == nil { @@ -284,3 +259,48 @@ func (m *LanedMempool) OrderLanes(chainLanes []blocksdkmoduletypes.Lane) (ordere return orderedLanes, nil } + +// ValidateBasic validates the mempools configuration. ValidateBasic ensures +// the following: +// - The sum of the lane max block space percentages is less than or equal to 1. +// - There is no unused block space. +func (m *LanedMempool) ValidateBasic() error { + if len(m.registry) == 0 { + return fmt.Errorf("registry cannot be nil; must configure at least one lane") + } + + sum := math.LegacyZeroDec() + seenZeroMaxBlockSpace := false + seenLanes := make(map[string]struct{}) + + for _, lane := range m.registry { + name := lane.Name() + if _, seen := seenLanes[name]; seen { + return fmt.Errorf("duplicate lane name %s", name) + } + + maxBlockSpace := lane.GetMaxBlockSpace() + if maxBlockSpace.IsZero() { + seenZeroMaxBlockSpace = true + } + + sum = sum.Add(lane.GetMaxBlockSpace()) + seenLanes[name] = struct{}{} + } + + switch { + // Ensure that the sum of the lane max block space percentages is less than + // or equal to 1. + case sum.GT(math.LegacyOneDec()): + return fmt.Errorf("sum of lane max block space percentages must be less than or equal to 1, got %s", sum) + // Ensure that there is no unused block space. + case sum.LT(math.LegacyOneDec()) && !seenZeroMaxBlockSpace: + return fmt.Errorf("sum of total block space percentages will be less than 1") + } + + if m.moduleLaneFetcher == nil { + return fmt.Errorf("moduleLaneFetcher muset be set on mempool") + } + + return nil +} diff --git a/block/mempool_test.go b/block/mempool_test.go index c827f51..46c2f36 100644 --- a/block/mempool_test.go +++ b/block/mempool_test.go @@ -46,7 +46,7 @@ type BlockBusterTestSuite struct { chainLanes []blocksdkmoduletypes.Lane lanes []block.Lane - mempool block.Mempool + mempool *block.LanedMempool // account set up accounts []testutils.Account @@ -132,16 +132,18 @@ func (suite *BlockBusterTestSuite) SetupTest() { // Mempool set up suite.lanes = []block.Lane{suite.mevLane, suite.freeLane, suite.baseLane} suite.chainLanes = []blocksdkmoduletypes.Lane{suite.mevSDKLane, suite.freeSDKLane, suite.baseSDKLane} - suite.mempool = block.NewLanedMempool( + + var err error + suite.mempool, err = block.NewLanedMempool( log.NewTestLogger(suite.T()), - true, + suite.lanes, mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { return suite.baseSDKLane, nil }, func() []blocksdkmoduletypes.Lane { return suite.chainLanes }), - suite.lanes..., ) + suite.Require().NoError(err) // Accounts set up suite.accounts = testutils.RandomAccounts(suite.random, 10) @@ -151,6 +153,192 @@ func (suite *BlockBusterTestSuite) SetupTest() { } } +func (suite *BlockBusterTestSuite) TestNewMempool() { + fetcher := mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { + return blocksdkmoduletypes.Lane{}, nil + }, func() []blocksdkmoduletypes.Lane { + return nil + }) + + baseConfig := base.LaneConfig{ + Logger: log.NewNopLogger(), + TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(), + TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(), + SignerExtractor: signer_extraction.NewDefaultAdapter(), + AnteHandler: nil, + MaxBlockSpace: math.LegacyZeroDec(), + } + + defaultLane := defaultlane.NewDefaultLane(baseConfig) + mevLane := mev.NewMEVLane( + baseConfig, + mev.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder(), signer_extraction.NewDefaultAdapter()), + ) + freeLane := free.NewFreeLane( + baseConfig, + base.DefaultTxPriority(), + free.DefaultMatchHandler(), + ) + + suite.Run("works with a single lane", func() { + lanes := []block.Lane{defaultLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().NoError(err) + + ignoreList := defaultLane.GetIgnoreList() + suite.Require().Equal(0, len(ignoreList)) + }) + + suite.Run("works mev and default lane", func() { + lanes := []block.Lane{mevLane, defaultLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().NoError(err) + + ignoreList := defaultLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + + ignoreList = mevLane.GetIgnoreList() + suite.Require().Equal(0, len(ignoreList)) + }) + + suite.Run("works mev and default lane in reverse order", func() { + lanes := []block.Lane{mevLane, defaultLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().NoError(err) + + ignoreList := defaultLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + + ignoreList = mevLane.GetIgnoreList() + suite.Require().Equal(0, len(ignoreList)) + }) + + suite.Run("works with mev, free, and default lane", func() { + lanes := []block.Lane{mevLane, freeLane, defaultLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().NoError(err) + + ignoreList := defaultLane.GetIgnoreList() + suite.Require().Equal(2, len(ignoreList)) + + ignoreList = mevLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(freeLane, ignoreList[0]) + + ignoreList = freeLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(mevLane, ignoreList[0]) + }) + + suite.Run("works with mev, default, free lane", func() { + lanes := []block.Lane{mevLane, defaultLane, freeLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().NoError(err) + + ignoreList := defaultLane.GetIgnoreList() + suite.Require().Equal(2, len(ignoreList)) + + ignoreList = mevLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(freeLane, ignoreList[0]) + + ignoreList = freeLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(mevLane, ignoreList[0]) + }) + + suite.Run("works with free, mev, and default lane", func() { + lanes := []block.Lane{freeLane, mevLane, defaultLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().NoError(err) + + ignoreList := defaultLane.GetIgnoreList() + suite.Require().Equal(2, len(ignoreList)) + + ignoreList = mevLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(freeLane, ignoreList[0]) + + ignoreList = freeLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(mevLane, ignoreList[0]) + }) + + suite.Run("works with default, free, mev lanes", func() { + lanes := []block.Lane{defaultLane, freeLane, mevLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().NoError(err) + + ignoreList := defaultLane.GetIgnoreList() + suite.Require().Equal(2, len(ignoreList)) + + ignoreList = mevLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(freeLane, ignoreList[0]) + + ignoreList = freeLane.GetIgnoreList() + suite.Require().Equal(1, len(ignoreList)) + suite.Require().Equal(mevLane, ignoreList[0]) + }) + + suite.Run("default lane not included", func() { + lanes := []block.Lane{mevLane, freeLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().Error(err) + }) + + suite.Run("duplicate lanes", func() { + lanes := []block.Lane{mevLane, defaultLane, mevLane} + + _, err := block.NewLanedMempool( + log.NewTestLogger(suite.T()), + lanes, + fetcher, + ) + suite.Require().Error(err) + }) +} + func (suite *BlockBusterTestSuite) TestInsert() { cases := []struct { name string @@ -463,20 +651,6 @@ func (suite *BlockBusterTestSuite) TestLanedMempool_Registry() { }, wantErr: true, }, - { - name: "invalid duplicate lanes in registry", - chainLanes: []blocksdkmoduletypes.Lane{ - suite.mevSDKLane, // order = 0 - suite.freeSDKLane, // order = 1 - suite.baseSDKLane, // order = 2 - }, - registryLanes: []block.Lane{ - suite.freeLane, - suite.baseLane, - suite.baseLane, - }, - wantErr: true, - }, { name: "valid reorder", chainLanes: []blocksdkmoduletypes.Lane{ @@ -519,16 +693,16 @@ func (suite *BlockBusterTestSuite) TestLanedMempool_Registry() { for _, tc := range tests { suite.Run(tc.name, func() { // setup mock mempool - mempool := block.NewLanedMempool( + mempool, err := block.NewLanedMempool( log.NewTestLogger(suite.T()), - true, + tc.registryLanes, mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { return blocksdkmoduletypes.Lane{}, nil }, func() []blocksdkmoduletypes.Lane { return tc.chainLanes }), - tc.registryLanes..., ) + suite.Require().NoError(err) gotOrderedLanes, err := mempool.Registry(suite.ctx) if tc.wantErr { @@ -590,20 +764,6 @@ func (suite *BlockBusterTestSuite) TestLanedMempool_OrderLanes() { }, wantErr: true, }, - { - name: "invalid duplicate lanes in registry", - chainLanes: []blocksdkmoduletypes.Lane{ - suite.mevSDKLane, // order = 0 - suite.freeSDKLane, // order = 1 - suite.baseSDKLane, // order = 2 - }, - registryLanes: []block.Lane{ - suite.freeLane, - suite.baseLane, - suite.baseLane, - }, - wantErr: true, - }, { name: "valid reorder", chainLanes: []blocksdkmoduletypes.Lane{ @@ -646,21 +806,18 @@ func (suite *BlockBusterTestSuite) TestLanedMempool_OrderLanes() { for _, tc := range tests { suite.Run(tc.name, func() { // setup mock mempool - mempool := block.NewLanedMempool( + mempool, err := block.NewLanedMempool( log.NewTestLogger(suite.T()), - true, + tc.registryLanes, mocks.NewMockLaneFetcher(func() (blocksdkmoduletypes.Lane, error) { return blocksdkmoduletypes.Lane{}, nil }, func() []blocksdkmoduletypes.Lane { return []blocksdkmoduletypes.Lane{} }), - tc.registryLanes..., ) + suite.Require().NoError(err) - lanedMempool, ok := mempool.(*block.LanedMempool) - suite.Require().True(ok) - - gotOrderedLanes, err := lanedMempool.OrderLanes(tc.chainLanes) + gotOrderedLanes, err := mempool.OrderLanes(tc.chainLanes) if tc.wantErr { suite.Require().Error(err) return diff --git a/block/mocks/lane.go b/block/mocks/lane.go index cd17e4e..7100a21 100644 --- a/block/mocks/lane.go +++ b/block/mocks/lane.go @@ -1,4 +1,4 @@ -// Code generated by mockery v0.0.0-dev. DO NOT EDIT. +// Code generated by mockery v2.30.1. DO NOT EDIT. package mocks @@ -75,6 +75,22 @@ func (_m *Lane) CountTx() int { return r0 } +// GetIgnoreList provides a mock function with given fields: +func (_m *Lane) GetIgnoreList() []block.Lane { + ret := _m.Called() + + var r0 []block.Lane + if rf, ok := ret.Get(0).(func() []block.Lane); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]block.Lane) + } + } + + return r0 +} + // GetMaxBlockSpace provides a mock function with given fields: func (_m *Lane) GetMaxBlockSpace() math.LegacyDec { ret := _m.Called() @@ -229,8 +245,7 @@ func (_m *Lane) SetMaxBlockSpace(_a0 math.LegacyDec) { func NewLane(t interface { mock.TestingT Cleanup(func()) -}, -) *Lane { +}) *Lane { mock := &Lane{} mock.Mock.Test(t) diff --git a/block/mocks/lane_mempool.go b/block/mocks/lane_mempool.go index e9d674c..cecf96f 100644 --- a/block/mocks/lane_mempool.go +++ b/block/mocks/lane_mempool.go @@ -1,4 +1,4 @@ -// Code generated by mockery v0.0.0-dev. DO NOT EDIT. +// Code generated by mockery v2.30.1. DO NOT EDIT. package mocks @@ -117,8 +117,7 @@ func (_m *LaneMempool) Select(_a0 context.Context, _a1 [][]byte) mempool.Iterato func NewLaneMempool(t interface { mock.TestingT Cleanup(func()) -}, -) *LaneMempool { +}) *LaneMempool { mock := &LaneMempool{} mock.Mock.Test(t) diff --git a/block/proposals/proposals_test.go b/block/proposals/proposals_test.go index 77d37bd..3b0655c 100644 --- a/block/proposals/proposals_test.go +++ b/block/proposals/proposals_test.go @@ -29,7 +29,7 @@ func TestUpdateProposal(t *testing.T) { lane.On("GetMaxBlockSpace").Return(math.LegacyNewDec(1)).Maybe() t.Run("can update with no transactions", func(t *testing.T) { - proposal := proposals.NewProposal(log.NewTestLogger(t), nil, 100, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), nil, 100, 100) err := proposal.UpdateProposal(lane, nil) require.NoError(t, err) @@ -61,7 +61,7 @@ func TestUpdateProposal(t *testing.T) { size := len(txBzs[0]) gasLimit := 100 - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) err = proposal.UpdateProposal(lane, []sdk.Tx{tx}) require.NoError(t, err) @@ -107,7 +107,7 @@ func TestUpdateProposal(t *testing.T) { gasLimit += 100 } - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), int64(size), gasLimit) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), int64(size), gasLimit) err = proposal.UpdateProposal(lane, txs) require.NoError(t, err) @@ -144,7 +144,7 @@ func TestUpdateProposal(t *testing.T) { size := int64(len(txBzs[0])) gasLimit := uint64(100) - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), size, gasLimit) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), size, gasLimit) err = proposal.UpdateProposal(lane, []sdk.Tx{tx}) require.NoError(t, err) @@ -204,7 +204,7 @@ func TestUpdateProposal(t *testing.T) { size := len(txBzs[0]) + len(txBzs[1]) gasLimit := 200 - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) err = proposal.UpdateProposal(lane, []sdk.Tx{tx}) require.NoError(t, err) @@ -242,7 +242,7 @@ func TestUpdateProposal(t *testing.T) { size := len(txBzs[0]) gasLimit := 100 - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) lane := mocks.NewLane(t) @@ -280,7 +280,7 @@ func TestUpdateProposal(t *testing.T) { size := len(txBzs[0]) gasLimit := 100 - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)) lane := mocks.NewLane(t) @@ -318,7 +318,7 @@ func TestUpdateProposal(t *testing.T) { size := len(txBzs[0]) gasLimit := 100 - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), int64(size)-1, uint64(gasLimit)) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), int64(size)-1, uint64(gasLimit)) err = proposal.UpdateProposal(lane, []sdk.Tx{tx}) require.Error(t, err) @@ -351,7 +351,7 @@ func TestUpdateProposal(t *testing.T) { size := len(txBzs[0]) gasLimit := 100 - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)-1) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), int64(size), uint64(gasLimit)-1) err = proposal.UpdateProposal(lane, []sdk.Tx{tx}) require.Error(t, err) @@ -392,7 +392,7 @@ func TestUpdateProposal(t *testing.T) { txBzs, err := utils.GetEncodedTxs(encodingConfig.TxConfig.TxEncoder(), []sdk.Tx{tx, tx2}) require.NoError(t, err) - proposal := proposals.NewProposal(log.NewTestLogger(t), encodingConfig.TxConfig.TxEncoder(), 10000, 10000) + proposal := proposals.NewProposal(log.NewNopLogger(), encodingConfig.TxConfig.TxEncoder(), 10000, 10000) err = proposal.UpdateProposal(lane, []sdk.Tx{tx}) require.NoError(t, err) diff --git a/lanes/base/abci_test.go b/lanes/base/abci_test.go index dc71783..c0636bc 100644 --- a/lanes/base/abci_test.go +++ b/lanes/base/abci_test.go @@ -45,7 +45,7 @@ func (s *BaseTestSuite) TestPrepareLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), int64(len(txBz)), 1, @@ -89,7 +89,7 @@ func (s *BaseTestSuite) TestPrepareLane() { MaxGasLimit: 10, } emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), limit.MaxTxBytes, limit.MaxGasLimit, @@ -134,7 +134,7 @@ func (s *BaseTestSuite) TestPrepareLane() { MaxGasLimit: 10, } emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), limit.MaxTxBytes, limit.MaxGasLimit, @@ -178,7 +178,7 @@ func (s *BaseTestSuite) TestPrepareLane() { MaxGasLimit: 10, } emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), limit.MaxTxBytes, limit.MaxGasLimit, @@ -219,7 +219,7 @@ func (s *BaseTestSuite) TestPrepareLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), int64(len(txBz)), 10, @@ -279,7 +279,7 @@ func (s *BaseTestSuite) TestPrepareLane() { size := int64(len(txBz1)) + int64(len(txBz2)) gasLimit := uint64(20) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), size, gasLimit, @@ -336,7 +336,7 @@ func (s *BaseTestSuite) TestPrepareLane() { size := int64(len(txBz1)) + int64(len(txBz2)) gasLimit := uint64(2) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), size, gasLimit, @@ -396,7 +396,7 @@ func (s *BaseTestSuite) TestPrepareLane() { size := int64(len(txBz1)) + int64(len(txBz2)) - 1 gasLimit := uint64(3) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), size, gasLimit, @@ -456,7 +456,7 @@ func (s *BaseTestSuite) TestPrepareLane() { size := int64(len(txBz1)) + int64(len(txBz2)) - 1 gasLimit := uint64(1) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), size, gasLimit, @@ -498,7 +498,7 @@ func (s *BaseTestSuite) TestPrepareLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), int64(len(txBz))*10, 1000000, @@ -564,7 +564,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -627,7 +627,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -703,7 +703,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -739,7 +739,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -775,7 +775,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -834,7 +834,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -883,7 +883,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -932,7 +932,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -984,7 +984,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 100000, 100000, @@ -1020,7 +1020,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), maxSize, 1000000, @@ -1057,7 +1057,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), maxSize, 9, @@ -1105,7 +1105,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), maxSize, 19, @@ -1154,7 +1154,7 @@ func (s *BaseTestSuite) TestProcessLane() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), maxSize, 20, @@ -1206,7 +1206,7 @@ func (s *BaseTestSuite) TestPrepareProcessParity() { // Construct a block proposal with the transactions in the mempool emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 1000000000000000, 1000000000000000, @@ -1224,7 +1224,7 @@ func (s *BaseTestSuite) TestPrepareProcessParity() { // Verify the same proposal with the process lanes handler emptyProposal = proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 1000000000000000, 1000000000000000, @@ -1286,7 +1286,7 @@ func (s *BaseTestSuite) TestIterateMempoolAndProcessProposalParity() { s.Require().NoError(err) emptyProposal := proposals.NewProposal( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), 1000000000000000, 1000000000000000, @@ -1310,7 +1310,7 @@ func (s *BaseTestSuite) initLane( expectedExecution map[sdk.Tx]bool, ) *defaultlane.DefaultLane { config := base.NewLaneConfig( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encodingConfig.TxConfig.TxEncoder(), s.encodingConfig.TxConfig.TxDecoder(), s.setUpAnteHandler(expectedExecution), diff --git a/lanes/build-your-own/README.md b/lanes/build-your-own/README.md index d5ecc61..33c6e67 100644 --- a/lanes/build-your-own/README.md +++ b/lanes/build-your-own/README.md @@ -432,7 +432,10 @@ For example, say there are two lanes: default and free. The free lane is processed after the default lane. In this case, the free lane should be added to the ignore list of the default lane. Otherwise, the transactions that belong to the free lane will be processed by the default lane (which accepts all -transactions by default). +transactions by default). + +**NOTE**: By default, we set the ignore list such that each lane is mutually +exclusive when constructing the mempool. ### Set up diff --git a/lanes/mev/abci_test.go b/lanes/mev/abci_test.go index 3cb2ad2..00366e7 100644 --- a/lanes/mev/abci_test.go +++ b/lanes/mev/abci_test.go @@ -16,7 +16,7 @@ func (s *MEVTestSuite) TestPrepareLane() { s.Run("can prepare a lane with no txs in mempool", func() { lane := s.initLane(math.LegacyOneDec(), nil) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200, 100) proposal, err := lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler()) s.Require().NoError(err) @@ -42,7 +42,7 @@ func (s *MEVTestSuite) TestPrepareLane() { lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true}) s.Require().NoError(lane.Insert(s.ctx, bidTx)) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200, 100) proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler()) s.Require().NoError(err) @@ -84,7 +84,7 @@ func (s *MEVTestSuite) TestPrepareLane() { s.Require().NoError(lane.Insert(s.ctx, bidTx1)) s.Require().NoError(lane.Insert(s.ctx, bidTx2)) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 20000, 100000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 20000, 100000) proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler()) s.Require().NoError(err) @@ -126,7 +126,7 @@ func (s *MEVTestSuite) TestPrepareLane() { s.Require().NoError(lane.Insert(s.ctx, bidTx1)) s.Require().NoError(lane.Insert(s.ctx, bidTx2)) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 20000, 100000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 20000, 100000) proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler()) s.Require().NoError(err) @@ -156,7 +156,7 @@ func (s *MEVTestSuite) TestPrepareLane() { lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true}) s.Require().NoError(lane.Insert(s.ctx, bidTx)) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 20000, 100000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 20000, 100000) proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler()) s.Require().NoError(err) @@ -187,7 +187,7 @@ func (s *MEVTestSuite) TestPrepareLane() { lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true}) s.Require().NoError(lane.Insert(s.ctx, bidTx)) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), s.getTxSize(bidTx), 100000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), s.getTxSize(bidTx), 100000) proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler()) s.Require().NoError(err) @@ -212,7 +212,7 @@ func (s *MEVTestSuite) TestPrepareLane() { lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true}) s.Require().NoError(lane.Insert(s.ctx, bidTx)) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), s.getTxSize(bidTx), 99) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), s.getTxSize(bidTx), 99) proposal, err = lane.PrepareLane(s.ctx, proposal, block.NoOpPrepareLanesHandler()) s.Require().NoError(err) @@ -228,7 +228,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Run("can process an empty proposal", func() { lane := s.initLane(math.LegacyOneDec(), nil) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200, 100) proposal, err := lane.ProcessLane(s.ctx, proposal, nil, block.NoOpProcessLanesHandler()) s.Require().NoError(err) @@ -243,7 +243,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), nil) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200, 100) _, err = lane.ProcessLane(s.ctx, proposal, [][]byte{txBz}, block.NoOpProcessLanesHandler()) s.Require().Error(err) @@ -265,7 +265,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: false}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().Error(err) @@ -287,7 +287,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: false}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().Error(err) @@ -309,7 +309,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().Error(err) @@ -331,7 +331,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().Error(err) @@ -353,7 +353,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().NoError(err) @@ -375,7 +375,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200000, 1000000) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().NoError(err) @@ -397,7 +397,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 20000, 99) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 20000, 99) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().Error(err) @@ -419,7 +419,7 @@ func (s *MEVTestSuite) TestProcessLane() { s.Require().NoError(err) lane := s.initLane(math.LegacyOneDec(), map[sdk.Tx]bool{bidTx: true, bundle[0]: true, bundle[1]: true}) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200, 100) _, err = lane.ProcessLane(s.ctx, proposal, partialProposal, block.NoOpProcessLanesHandler()) s.Require().Error(err) @@ -428,7 +428,7 @@ func (s *MEVTestSuite) TestProcessLane() { func (s *MEVTestSuite) TestVerifyBidBasic() { lane := s.initLane(math.LegacyOneDec(), nil) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), 200, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), 200, 100) limits := proposal.GetLaneLimits(lane.GetMaxBlockSpace()) s.Run("can verify a bid with no bundled txs", func() { @@ -492,7 +492,7 @@ func (s *MEVTestSuite) TestVerifyBidBasic() { s.Require().NoError(err) size := s.getTxSize(bidTx) - proposal := proposals.NewProposal(log.NewTestLogger(s.T()), s.encCfg.TxConfig.TxEncoder(), size-1, 100) + proposal := proposals.NewProposal(log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), size-1, 100) limits := proposal.GetLaneLimits(lane.GetMaxBlockSpace()) _, err = lane.VerifyBidBasic(bidTx, proposal, limits) diff --git a/lanes/mev/mev_test.go b/lanes/mev/mev_test.go index effa9b5..d9f37bc 100644 --- a/lanes/mev/mev_test.go +++ b/lanes/mev/mev_test.go @@ -55,7 +55,7 @@ func (s *MEVTestSuite) initLane( expectedExecution map[sdk.Tx]bool, ) *mev.MEVLane { config := base.NewLaneConfig( - log.NewTestLogger(s.T()), + log.NewNopLogger(), s.encCfg.TxConfig.TxEncoder(), s.encCfg.TxConfig.TxDecoder(), s.setUpAnteHandler(expectedExecution), diff --git a/lanes/terminator/lane.go b/lanes/terminator/lane.go index 0e0a534..0dd70d5 100644 --- a/lanes/terminator/lane.go +++ b/lanes/terminator/lane.go @@ -74,6 +74,11 @@ func (t Terminator) SetAnteHandler(sdk.AnteHandler) {} // SetIgnoreList is a no-op func (t Terminator) SetIgnoreList([]block.Lane) {} +// GetIgnoreList is a no-op +func (t Terminator) GetIgnoreList() []block.Lane { + return nil +} + // Match is a no-op func (t Terminator) Match(sdk.Context, sdk.Tx) bool { return false diff --git a/tests/app/app.go b/tests/app/app.go index d18faf9..5a3ab5b 100644 --- a/tests/app/app.go +++ b/tests/app/app.go @@ -265,12 +265,15 @@ func New( freeLane, defaultLane, } - mempool := block.NewLanedMempool( + mempool, err := block.NewLanedMempool( app.Logger(), - true, + lanes, &app.blocksdkKeeper, - lanes..., ) + if err != nil { + panic(err) + } + app.App.SetMempool(mempool) // Create a global ante handler that will be called on each transaction when diff --git a/tests/integration/block_sdk_integration_test.go b/tests/integration/block_sdk_integration_test.go index 0298eb5..7d891f8 100644 --- a/tests/integration/block_sdk_integration_test.go +++ b/tests/integration/block_sdk_integration_test.go @@ -23,7 +23,7 @@ import ( var ( // config params - numValidators = 1 + numValidators = 4 numFullNodes = 0 denom = "stake" diff --git a/tests/integration/chain_setup.go b/tests/integration/chain_setup.go index 3946f21..a5aeeb5 100644 --- a/tests/integration/chain_setup.go +++ b/tests/integration/chain_setup.go @@ -47,7 +47,7 @@ type KeyringOverride struct { // and returns the associated chain func ChainBuilderFromChainSpec(t *testing.T, spec *interchaintest.ChainSpec) ibc.Chain { // require that NumFullNodes == NumValidators == 4 - require.Equal(t, *spec.NumValidators, 1) + require.Equal(t, *spec.NumValidators, 4) cf := interchaintest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*interchaintest.ChainSpec{spec})