diff --git a/README.md b/README.md
index 7865804..92c62bb 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
Protocol-Owned Builder
+Block SDK π§±
@@ -9,337 +9,21 @@
[](https://github.com/skip-mev/pob/blob/main/LICENSE)
[](https://github.com/skip-mev/pob)
-Skip Protocol's Protocol-Owned Builder (POB) is a set of Cosmos SDK and ABCI++
-primitives that provide application developers the ability to define how their
-apps construct and validate blocks on-chain in a transparent, enforceable way,
-such as giving complete control to the protocol to recapture, control, and
-redistribute MEV.
+### π€Β What is the Block SDK?
-Skip's POB provides developers with a set of a few core primitives:
-
-* `BlockBuster`: BlockBuster is a generalized block-building and mempool SDK
- that allows developers to define how their applications construct and validate blocks
- on-chain in a transparent, enforceable way. At its core, BlockBuster is an app-side mempool + set
- of proposal handlers (`PrepareProposal`/`ProcessProposal`) that allow developers to configure
- modular lanes of transactions in their blocks with distinct validation/ordering logic. For more
- information, see the [BlockBuster README](/blockbuster/README.md).
-* `x/builder`: This Cosmos SDK module gives applications the ability to process
- MEV bundled transactions in addition to having the ability to define how searchers
- and block proposers are rewarded. In addition, the module defines a `AuctionDecorator`,
- which is an AnteHandler decorator that enforces various chain configurable MEV
- rules.
-
-## Releases
-
-### Release Compatibility Matrix
-
-| POB Version | Cosmos SDK |
-| :---------: | :--------: |
-| v1.x.x | v0.47.x |
-| v1.x.x | v0.48.x |
-| v1.x.x | v0.49.x |
-| v1.x.x | v0.50.x |
-
-## Install
-
-```shell
-$ go install github.com/skip-mev/pob
-```
-
-## Setup
-
->This set up guide will walk you through the process of setting up a POB application. In particular, we will configure an application with the following features:
->
->* Top of block lane (auction lane). This will create an auction lane where users can bid to have their
-> transactions executed at the top of the block.
->* Free lane. This will create a free lane where users can submit transactions that will be executed
-> for free (no fees).
->* Default lane. This will create a default lane where users can submit transactions that will be executed
-> with the default app logic.
->* Builder module that pairs with the auction lane to process auction transactions and distribute revenue
-> to the auction house.
->
-> To build your own custom BlockBuster Lane, please see the [BlockBuster README](/blockbuster/README.md).
-
-1. Import the necessary dependencies into your application. This includes the
- blockbuster proposal handlers +mempool, keeper, builder types, and builder module. This
- tutorial will go into more detail into each of the dependencies.
-
- ```go
- import (
- ...
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/abci"
- "github.com/skip-mev/pob/blockbuster/lanes/auction"
- "github.com/skip-mev/pob/blockbuster/lanes/base"
- "github.com/skip-mev/pob/blockbuster/lanes/free"
- buildermodule "github.com/skip-mev/pob/x/builder"
- builderkeeper "github.com/skip-mev/pob/x/builder/keeper"
- ...
- )
- ```
-
-2. Add your module to the the `AppModuleBasic` manager. This manager is in
- charge of setting up basic, non-dependent module elements such as codec
- registration and genesis verification. This will register the special
- `MsgAuctionBid` message. When users want to bid for top of block execution,
- they will submit a transaction - which we call an auction transaction - that
- includes a single `MsgAuctionBid`. We prevent any other messages from being
- included in auction transaction to prevent malicious behavior - such as front
- running or sandwiching.
-
- ```go
- var (
- ModuleBasics = module.NewBasicManager(
- ...
- buildermodule.AppModuleBasic{},
- )
- ...
- )
- ```
-
-3. The builder `Keeper` is POB's gateway to processing special `MsgAuctionBid`
- messages that allow users to participate in the top of block auction, distribute
- revenue to the auction house, and ensure the validity of auction transactions.
-
- a. First add the keeper to the app's struct definition. We also want to add POB's custom
- checkTx handler to the app's struct definition. This will allow us to override the
- default checkTx handler to process bid transactions before they are inserted into the mempool.
- NOTE: The custom handler is required as otherwise the auction can be held hostage by a malicious
- users.
-
- ```go
- type App struct {
- ...
- // BuilderKeeper is the keeper that handles processing auction transactions
- BuilderKeeper builderkeeper.Keeper
-
- // Custom checkTx handler
- checkTxHandler abci.CheckTx
- }
- ```
-
- b. Add the builder module to the list of module account permissions. This will
- instantiate the builder module account on genesis.
-
- ```go
- maccPerms = map[string][]string{
- builder.ModuleName: nil,
- ...
- }
- ```
-
- c. Instantiate the blockbuster mempool with the application's desired lanes.
-
- ```go
- // Set the blockbuster mempool into the app.
- // Create the lanes.
- //
- // NOTE: The lanes are ordered by priority. The first lane is the highest priority
- // lane and the last lane is the lowest priority lane.
- // Top of block lane allows transactions to bid for inclusion at the top of the next block.
- //
- // blockbuster.BaseLaneConfig is utilized for basic encoding/decoding of transactions.
- tobConfig := blockbuster.BaseLaneConfig{
- Logger: app.Logger(),
- TxEncoder: app.txConfig.TxEncoder(),
- TxDecoder: app.txConfig.TxDecoder(),
- // the desired portion of total block space to be reserved for the lane. a value of 0
- // indicates that the lane can use all available block space.
- MaxBlockSpace: sdk.ZeroDec(),
- }
- tobLane := auction.NewTOBLane(
- tobConfig,
- // the maximum number of transactions that the mempool can store. a value of 0 indicates
- // that the mempool can store an unlimited number of transactions.
- 0,
- // AuctionFactory is responsible for determining what is an auction bid transaction and
- // how to extract the bid information from the transaction. There is a default implementation
- // that can be used or application developers can implement their own.
- auction.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
- )
-
- // Free lane allows transactions to be included in the next block for free.
- freeConfig := blockbuster.BaseLaneConfig{
- Logger: app.Logger(),
- TxEncoder: app.txConfig.TxEncoder(),
- TxDecoder: app.txConfig.TxDecoder(),
- MaxBlockSpace: sdk.ZeroDec(),
- // IgnoreList is a list of lanes that if a transaction should be included in, it will be
- // ignored by the lane. For example, if a transaction should belong to the tob lane, it
- // will be ignored by the free lane.
- IgnoreList: []blockbuster.Lane{
- tobLane,
- },
- }
- freeLane := free.NewFreeLane(
- freeConfig,
- free.NewDefaultFreeFactory(app.txConfig.TxDecoder()),
- )
-
- // Default lane accepts all other transactions.
- defaultConfig := blockbuster.BaseLaneConfig{
- Logger: app.Logger(),
- TxEncoder: app.txConfig.TxEncoder(),
- TxDecoder: app.txConfig.TxDecoder(),
- MaxBlockSpace: sdk.ZeroDec(),
- IgnoreList: []blockbuster.Lane{
- tobLane,
- freeLane,
- },
- }
- defaultLane := base.NewDefaultLane(defaultConfig)
-
- // Set the lanes into the mempool.
- lanes := []blockbuster.Lane{
- tobLane,
- freeLane,
- defaultLane,
- }
- mempool := blockbuster.NewMempool(lanes...)
- app.App.SetMempool(mempool)
- ```
-
- d. Instantiate the antehandler chain for the application with awareness of the
- blockbuster mempool. This will allow the application to verify the validity
- of a transaction respecting the desired logic of a given lane. In this walkthrough,
- we want the `FeeDecorator` to be ignored for all transactions that should belong to the
- free lane. Additionally, we want to add the `x/builder` module's `AuctionDecorator` to the
- ante-handler chain. The `AuctionDecorator` is an AnteHandler decorator that enforces various
- chain configurable MEV rules.
-
- ```go
- import (
- ...
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/utils"
- builderante "github.com/skip-mev/pob/x/builder/ante"
- ...
- )
-
- anteDecorators := []sdk.AnteDecorator{
- ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
- ...
- // The IgnoreDecorator allows for certain decorators to be ignored for certain transactions. In
- // this case, we want to ignore the FeeDecorator for all transactions that should belong to the
- // free lane.
- utils.NewIgnoreDecorator(
- ante.NewDeductFeeDecorator(
- options.BaseOptions.AccountKeeper,
- options.BaseOptions.BankKeeper,
- options.BaseOptions.FeegrantKeeper,
- options.BaseOptions.TxFeeChecker,
- ),
- options.FreeLane,
- ),
- ...
- builderante.NewBuilderDecorator(options.BuilderKeeper, options.TxEncoder, options.TOBLane, options.Mempool),
- }
-
- anteHandler := sdk.ChainAnteDecorators(anteDecorators...)
- app.SetAnteHandler(anteHandler)
-
- // Set the antehandlers on the lanes.
- for _, lane := range lanes {
- lane.SetAnteHandler(anteHandler)
- }
- app.App.SetAnteHandler(anteHandler)
- ```
-
- e. Instantiate the builder keeper, store keys, and module manager. Note, be
- sure to do this after all the required keeper dependencies have been instantiated.
-
- ```go
- keys := storetypes.NewKVStoreKeys(
- buildertypes.StoreKey,
- ...
- )
-
- ...
- app.BuilderKeeper := builderkeeper.NewKeeper(
- appCodec,
- keys[buildertypes.StoreKey],
- app.AccountKeeper,
- app.BankKeeper,
- app.DistrKeeper,
- app.StakingKeeper,
- authtypes.NewModuleAddress(govv1.ModuleName).String(),
- )
-
-
- app.ModuleManager = module.NewManager(
- builder.NewAppModule(appCodec, app.BuilderKeeper),
- ...
- )
- ```
-
- e. With Cosmos SDK version 0.47.0, the process of building blocks has been
- updated and moved from the consensus layer, CometBFT, to the application layer.
- When a new block is requested, the proposer for that height will utilize the
- `PrepareProposal` handler to build a block while the `ProcessProposal` handler
- will verify the contents of the block proposal by all validators. The
- combination of the `BlockBuster` mempool + `PrepareProposal`/`ProcessProposal`
- handlers allows the application to verifiably build valid blocks with
- top-of-block block space reserved for auctions and partial block for free transactions.
- Additionally, we override the `BaseApp`'s `CheckTx` handler with our own custom
- `CheckTx` handler that will be responsible for checking the validity of transactions.
- We override the `CheckTx` handler so that we can verify auction transactions before they are
- inserted into the mempool. With the POB `CheckTx`, we can verify the auction
- transaction and all of the bundled transactions before inserting the auction
- transaction into the mempool. This is important because we otherwise there may be
- discrepencies between the auction transaction and the bundled transactions
- are validated in `CheckTx` and `PrepareProposal` such that the auction can be
- griefed. All other transactions will be executed with base app's `CheckTx`.
-
- ```go
-
- // Create the proposal handler that will be used to build and validate blocks.
- proposalHandler := abci.NewProposalHandler(
- app.Logger(),
- app.txConfig.TxDecoder(),
- mempool,
- )
- app.App.SetPrepareProposal(proposalHandler.PrepareProposalHandler())
- app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
+**π The Block SDK is a toolkit for building customized blocks**. The Block SDK is a set of Cosmos SDK and ABCI++ primitives that allow chains to fully customize blocks to specific use cases. It turns your chain's blocks into a **`highway`** consisting of individual **`lanes`** with their own special functionality.
- // Set the custom CheckTx handler on BaseApp.
- checkTxHandler := abci.NewCheckTxHandler(
- app.App,
- app.txConfig.TxDecoder(),
- tobLane,
- anteHandler,
- app.ChainID(),
- )
- app.SetCheckTx(checkTxHandler.CheckTx())
- ...
+Skip has built out a number of plug-and-play `lanes` on the SDK that your protocol can use, including in-protocol MEV recapture and Oracles! Additionally, the Block SDK can be extended to add **your own custom `lanes`** to configure your blocks to exactly fit your application needs.
- // CheckTx will check the transaction with the provided checkTxHandler. We override the default
- // handler so that we can verify bid transactions before they are inserted into the mempool.
- // With the POB CheckTx, we can verify the bid transaction and all of the bundled transactions
- // before inserting the bid transaction into the mempool.
- func (app *TestApp) CheckTx(req cometabci.RequestCheckTx) cometabci.ResponseCheckTx {
- return app.checkTxHandler(req)
- }
+### π Block SDK Documentation
- // SetCheckTx sets the checkTxHandler for the app.
- func (app *TestApp) SetCheckTx(handler abci.CheckTx) {
- app.checkTxHandler = handler
- }
- ```
+To read more about how the Block SDK works, check out the [How it Works](https://docs.skip.money/chains/overview).
- f. Finally, update the app's `InitGenesis` order and ante-handler chain.
+#### Lane "App Store"
- ```go
- genesisModuleOrder := []string{
- buildertypes.ModuleName,
- ...,
- }
- ```
+To read more about Skip's pre-built `lanes` and how to use them, check out the [Lane App Store](https://docs.skip.money/chains/lanes/existing-lanes/default).
-## Params
+#### Lane Development
-Note, before building or upgrading the application, make sure to initialize the
-escrow address for POB in the parameters of the module. The default parameters
-initialize the escrow address to be the module account address. The escrow address
-will be the address that is receiving a portion of auction house revenue alongside the proposer (or custom rewards providers).
+To read more about how to build your own custom `lanes`, check out the [Build Your Own Lane](https://docs.skip.money/chains/lanes/build-your-own-lane).
diff --git a/SPEC.md b/SPEC.md
deleted file mode 100644
index d71156c..0000000
--- a/SPEC.md
+++ /dev/null
@@ -1,311 +0,0 @@
-
-# POB Specification
-
-## Abstract
-
-The `x/builder` module is a Cosmos SDK module that allows Cosmos chains to host
-top-of-block auctions directly in-protocol with auction revenue (MEV) being
-redistributed according to the preferences of the chain. The `x/builder` module
-introduces a new `MsgAuctionBid` message that allows users to submit a bid
-alongside an ordered list of transactions, i.e. a **bundle**, that they want
-executed at top-of-block before any other transactions are executed for that
-block. The `x/builder` module works alongside the `AuctionMempool` such that:
-
-* Auctions are held directly in the `AuctionMempool`, where a winner is determined
- when the proposer proposes a new block in `PrepareProposal`.
-* `x/builder` provides the necessary validation of auction bids and subsequent
- state transitions to extract bids.
-
-## Concepts
-
-### Miner Extractable Value (MEV)
-
-MEV refers to the potential profit that miners, or validators in a Proof-of-Stake
-system, can make by strategically ordering, selecting, or even censoring
-transactions in the blocks they produce. MEV can be classified into "good MEV"
-and "bad MEV" based on the effects it has on the blockchain ecosystem and its
-users. It's important to note that these classifications are subjective and may
-vary depending on one's perspective.
-
-**Good MEV** refers to the value that validators can extract while contributing
-positively to the blockchain ecosystem. This typically includes activities that
-enhance network efficiency, maintain fairness, and align incentives with the
-intended use of the system. Examples of good MEV include:
-
-* **Back-running**: Validators can place their own transactions immediately
- after a profitable transaction, capitalizing on the changes caused by the
- preceding transaction.
-* **Arbitrage**: By exploiting price differences across decentralized exchanges
- or other DeFi platforms, validators help maintain more consistent price levels
- across the ecosystem, ultimately contributing to its stability.
-* **Liquidations**: In DeFi platforms, when users' collateral falls below a
- specific threshold, validators can liquidate these positions, thereby maintaining
- the overall health of the platform and protecting its users from insolvency risks.
-
-**Bad MEV** refers to the value that validators can extract through activities
-that harm the blockchain ecosystem, lead to unfair advantages, or exploit users.
-Examples of bad MEV include:
-
-* **Front-running**: Validators can observe pending transactions in the mempool
- (the pool of unconfirmed transactions) and insert their own transactions ahead
- of them. This can be particularly profitable in decentralized finance (DeFi)
- applications, where a validator could front-run a large trade to take advantage
- of price movements.
-* **Sandwich attacks**: Validators can surround a user's transaction with their
- own transactions, effectively manipulating the market price for their benefit.
-* **Censorship**: Validators can selectively exclude certain transactions from
- blocks to benefit their own transactions or to extract higher fees from users.
-
-MEV is a topic of concern in the blockchain community because it can lead to
-unfair advantages for validators, reduced trust in the system, and a potential
-concentration of power. Various approaches have been proposed to mitigate MEV,
-such as proposer-builder separation (described below) and transparent and fair
-transaction ordering mechanisms at the protocol-level (`POB`) to make MEV
-extraction more incentive aligned with the users and blockchain ecosystem.
-
-### Proposer Builder Separation (PBS)
-
-Proposer-builder separation is a concept in the design of blockchain protocols,
-specifically in the context of transaction ordering within a block. In traditional
-blockchain systems, validators perform two main tasks: they create new blocks
-(acting as proposers) and determine the ordering of transactions within those
-blocks (acting as builders).
-
-
-**Proposers**: They are responsible for creating and broadcasting new blocks,
-just like in traditional blockchain systems. *However, they no longer determine
-the ordering of transactions within those blocks*.
-
-**Builders**: They have the exclusive role of determining the order of transactions
-within a block - can be full or partial block. Builders submit their proposed
-transaction orderings to an auction mechanism, which selects the winning template
-based on predefined criteria, e.g. highest bid.
-
-This dual role can lead to potential issues, such as front-running and other
-manipulations that benefit the miners/builders themselves.
-
-* *Increased complexity*: Introducing PBS adds an extra layer of complexity to
- the blockchain protocol. Designing, implementing, and maintaining an auction
- mechanism for transaction ordering requires additional resources and may
- introduce new vulnerabilities or points of failure in the system.
-* *Centralization risks*: With PBS, there's a risk that a few dominant builders
- may emerge, leading to centralization of transaction ordering. This centralization
- could result in a lack of diversity in transaction ordering algorithms and an
- increased potential for collusion or manipulation by the dominant builders.
-* *Incentive misalignments*: The bidding process may create perverse incentives
- for builders. For example, builders may be incentivized to include only high-fee
- transactions to maximize their profits, potentially leading to a neglect of
- lower-fee transactions. Additionally, builders may be incentivized to build
- blocks that include **bad-MEV** strategies because they are more profitable.
-
-## Specification
-
-### Mempool
-
-As the lifeblood of blockchains, mempools serve as the intermediary space for
-pending transactions, playing a vital role in transaction management, fee markets,
-and network health. With ABCI++, mempools can be defined at the application layer
-instead of the consensus layer (CometBFT). This means applications can define
-their own mempools that have their own custom verification, block building, and
-state transition logic. Adding on, these changes make it such that blocks are
-built (`PrepareProposal`) and verified (`ProcessProposal`) directly in the
-application layer.
-
-The `x/builder` module implements an application-side mempool, `AuctionMempool`,
-that implements the `sdk.Mempool` interface. The mempool is composed of two
-primary indexes, a global index that contains all non-auction transactions and
-an index that only contains auction transactions, i.e. transactions with a single
-`MsgAuctionBid` message. Both indexes order transactions based on priority respecting
-the sender's sequence number. The global index prioritizes transactions based on
-`ctx.Priority()` and the auction index prioritizes transactions based on the
-bid.
-
-### Configuration
-
-The `AuctionMempool` mempool implementation accepts a `AuctionFactory`
-interface that allows the mempool to be generic across many Cosmos SDK
-applications, such that it allows the ability for the application developer to
-define their business logic in terms of how to perform things such as the following:
-
-* Getting tx signers
-* Getting bundled tx signers
-* Retrieving bid information
-
-
-```go
-// AuctionFactory defines the interface for processing auction transactions.
-// It is a wrapper around all of the functionality that each application chain
-// must implement in order for auction processing to work.
-type AuctionFactory interface {
- // WrapBundleTransaction defines a function that wraps a bundle transaction
- // into a sdk.Tx. Since this is a potentially expensive operation, we allow
- // each application chain to define how they want to wrap the transaction
- // such that it is only called when necessary (i.e. when the transaction is
- // being considered in the proposal handlers).
- WrapBundleTransaction(tx []byte) (sdk.Tx, error)
-
- // GetAuctionBidInfo defines a function that returns the bid info from an
- // auction transaction.
- GetAuctionBidInfo(tx sdk.Tx) (*AuctionBidInfo, error)
-}
-```
-
-### PrepareProposal
-
-After the proposer of the next block has been selected, the CometBFT client will
-call `PrepareProposal` to build the next block. The block will be built in two
-stages. First, it will host the auction and include the winning bidder's bundle
-as the first set of transactions for the block, i.e. it will select the bid
-transaction itself along with automatically including all the bundled transactions
-in the specified order they appear in the bid's `transactions` field.
-
-The auction currently supports only a single winner. Selecting the auction winner
-involves a greedy search for a valid auction transaction starting from highest
-paying bid, respecting user nonce, in the `AuctionMempool`. The `x/builder`'s
-ante handler is responsible for verifying the auction transaction based on the
-criteria described below (see **Ante Handler**).
-
-Then, it will build the rest of the block by reaping and validating the transactions
-in the global index. The second portion of block building iterates from highest
-to lowest priority transactions in the global index and adds them to the proposal
-if they are valid. If the proposer comes across a transaction that was already
-included in the top of block, it will be ignored.
-
-### ProcessProposal
-
-After the proposer proposes a block of transactions for the next block, the
-block will be verified by other nodes in the network in `ProcessProposal`. If
-there is an auction transaction in the proposal, it must be the first transaction
-in the proposal and all bundled transactions must follow the auction transaction
-in the exact order we would expect them to be seen. If this fails, the proposal
-is rejected. If this passes, the validator will then run `CheckTx` on all of the
-transactions in the block in the order in which they were provided in the proposal.
-
-### Ante Handler
-
-When users want to bid for the rights for top-of-block execution they will submit
-a normal `sdk.Tx` transaction with a single `MsgAuctionBid`. The ante handler is
-responsible for verification of this transaction. The ante handler will verify that:
-
-1. The auction transaction specifies a timeout height where the bid is no longer
- considered valid. Note, it is REQUIRED that all bid transactions include a
- height timeout.
-2. The auction transaction includes less than `MaxBundleSize` transactions in
- its bundle.
-3. The auction transaction includes only a SINGLE `MsgAuctionBid` message. We
- enforce that no other messages are included to prevent front-running.
-4. Enforce that the user has sufficient funds to pay the bid they entered while
- covering all relevant auction fees.
-5. Enforce that the transaction's min bid increment greater than the local highest
- bid in the mempool.
-6. Enforce that the bundle of transactions the bidder provided does not front-run
- or sandwich (if enabled).
-
-Note, the process of selecting auction winners occurs in a greedy manner. In
-`PrepareProposal`, the `AuctionMempool` will iterate from largest to smallest
-bidding transaction until it finds the first valid bid transaction.
-
-### State
-
-The `x/builder` module stores the following state objects:
-
-```protobuf
-message Params {
- option (amino.name) = "cosmos-sdk/x/builder/Params";
-
- // max_bundle_size is the maximum number of transactions that can be bundled
- // in a single bundle.
- uint32 max_bundle_size = 1;
-
- // escrow_account_address is the address of the account that will receive a
- // portion of the bid proceeds.
- string escrow_account_address = 2;
-
- // reserve_fee specifies the bid floor for the auction.
- cosmos.base.v1beta1.Coin reserve_fee = 3
- [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
-
- // min_buy_in_fee specifies the fee that the bidder must pay to enter the
- // auction.
- cosmos.base.v1beta1.Coin min_buy_in_fee = 4
- [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
-
- // min_bid_increment specifies the minimum amount that the next bid must be
- // greater than the previous bid.
- cosmos.base.v1beta1.Coin min_bid_increment = 5
- [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
-
- // front_running_protection specifies whether front running and sandwich
- // attack protection is enabled.
- bool front_running_protection = 6;
-
- // proposer_fee defines the portion of the winning bid that goes to the block
- // proposer that proposed the block.
- string proposer_fee = 7 [
- (gogoproto.nullable) = false,
- (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec"
- ];
-}
-```
-
-## Messages
-
-### MsgAuctionBid
-
-POB defines a new Cosmos SDK `Message`, `MsgAuctionBid`, that allows users to
-create an auction bid and participate in a top-of-block auction. The `MsgAuctionBid`
-message defines a bidder and a series of embedded transactions, i.e. the bundle.
-
-```protobuf
-message MsgAuctionBid {
- option (cosmos.msg.v1.signer) = "bidder";
- option (amino.name) = "pob/x/builder/MsgAuctionBid";
-
- option (gogoproto.equal) = false;
-
- // bidder is the address of the account that is submitting a bid to the
- // auction.
- string bidder = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
- // bid is the amount of coins that the bidder is bidding to participate in the
- // auction.
- cosmos.base.v1beta1.Coin bid = 3
- [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
- // transactions are the bytes of the transactions that the bidder wants to
- // bundle together.
- repeated bytes transactions = 4;
-}
-```
-
-Note, the `transactions` may or may not exist in a node's application mempool. If
-a transaction containing a single `MsgAuctionBid` wins the auction, the block
-proposal will automatically include the `MsgAuctionBid` transaction along with
-injecting all the bundled transactions such that they are executed in the same
-order after the `MsgAuctionBid` transaction.
-
-When processing a `MsgAuctionBid`, the `x/builder` module will perform two primary
-actions:
-
-1. Ensure the bid is valid per the module's parameters and configuration.
-2. Extract fee payments from the bidder's account and escrow them to the module's
- escrow account and the proposer that included the winning bid in the block
- proposal.
-
-### MsgUpdateParams
-
-The `MsgUpdateParams` message allows for an authority, typically the `x/gov`
-module account, to update the `x/builder`'s parameters.
-
-```protobuf
-message MsgUpdateParams {
- option (cosmos.msg.v1.signer) = "authority";
- option (amino.name) = "pob/x/builder/MsgUpdateParams";
-
- option (gogoproto.equal) = false;
-
- // authority is the address of the account that is authorized to update the
- // x/builder module parameters.
- string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
- // params is the new parameters for the x/builder module.
- Params params = 2 [ (gogoproto.nullable) = false ];
-}
-```
diff --git a/blockbuster/abci/abci.go b/abci/abci.go
similarity index 92%
rename from blockbuster/abci/abci.go
rename to abci/abci.go
index dd8feb6..1e203af 100644
--- a/blockbuster/abci/abci.go
+++ b/abci/abci.go
@@ -6,9 +6,9 @@ import (
"cosmossdk.io/log"
abci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/lanes/terminator"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/utils"
+ "github.com/skip-mev/pob/lanes/terminator"
)
type (
@@ -17,14 +17,14 @@ type (
ProposalHandler struct {
logger log.Logger
txDecoder sdk.TxDecoder
- prepareLanesHandler blockbuster.PrepareLanesHandler
- processLanesHandler blockbuster.ProcessLanesHandler
+ prepareLanesHandler block.PrepareLanesHandler
+ processLanesHandler block.ProcessLanesHandler
}
)
// NewProposalHandler returns a new abci++ proposal handler. This proposal handler will
// iteratively call each of the lanes in the chain to prepare and process the proposal.
-func NewProposalHandler(logger log.Logger, txDecoder sdk.TxDecoder, lanes []blockbuster.Lane) *ProposalHandler {
+func NewProposalHandler(logger log.Logger, txDecoder sdk.TxDecoder, lanes []block.Lane) *ProposalHandler {
return &ProposalHandler{
logger: logger,
txDecoder: txDecoder,
@@ -48,7 +48,7 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
}
}()
- proposal, err := h.prepareLanesHandler(ctx, blockbuster.NewProposal(req.MaxTxBytes))
+ proposal, err := h.prepareLanesHandler(ctx, block.NewProposal(req.MaxTxBytes))
if err != nil {
h.logger.Error("failed to prepare proposal", "err", err)
return &abci.ResponsePrepareProposal{Txs: make([][]byte, 0)}, err
@@ -114,7 +114,7 @@ func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
//
// In the case where any of the lanes fail to prepare the partial proposal, the lane that failed
// will be skipped and the next lane in the chain will be called to prepare the proposal.
-func ChainPrepareLanes(chain ...blockbuster.Lane) blockbuster.PrepareLanesHandler {
+func ChainPrepareLanes(chain ...block.Lane) block.PrepareLanesHandler {
if len(chain) == 0 {
return nil
}
@@ -124,7 +124,7 @@ func ChainPrepareLanes(chain ...blockbuster.Lane) blockbuster.PrepareLanesHandle
chain = append(chain, terminator.Terminator{})
}
- return func(ctx sdk.Context, partialProposal blockbuster.BlockProposal) (finalProposal blockbuster.BlockProposal, err error) {
+ return func(ctx sdk.Context, partialProposal block.BlockProposal) (finalProposal block.BlockProposal, err error) {
lane := chain[0]
lane.Logger().Info("preparing lane", "lane", lane.Name())
@@ -182,7 +182,7 @@ func ChainPrepareLanes(chain ...blockbuster.Lane) blockbuster.PrepareLanesHandle
// ChainProcessLanes chains together the proposal verification logic from each lane
// into a single function. The first lane in the chain is the first lane to be verified and
// the last lane in the chain is the last lane to be verified.
-func ChainProcessLanes(chain ...blockbuster.Lane) blockbuster.ProcessLanesHandler {
+func ChainProcessLanes(chain ...block.Lane) block.ProcessLanesHandler {
if len(chain) == 0 {
return nil
}
diff --git a/blockbuster/abci/abci_test.go b/abci/abci_test.go
similarity index 77%
rename from blockbuster/abci/abci_test.go
rename to abci/abci_test.go
index 0a6fd51..dace5ed 100644
--- a/blockbuster/abci/abci_test.go
+++ b/abci/abci_test.go
@@ -13,11 +13,12 @@ import (
cometabci "github.com/cometbft/cometbft/abci/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/abci"
- "github.com/skip-mev/pob/blockbuster/lanes/auction"
- "github.com/skip-mev/pob/blockbuster/lanes/base"
- "github.com/skip-mev/pob/blockbuster/lanes/free"
+ "github.com/skip-mev/pob/abci"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
+ defaultlane "github.com/skip-mev/pob/lanes/base"
+ "github.com/skip-mev/pob/lanes/free"
+ "github.com/skip-mev/pob/lanes/mev"
testutils "github.com/skip-mev/pob/testutils"
"github.com/stretchr/testify/suite"
)
@@ -54,9 +55,9 @@ func (s *ProposalsTestSuite) SetupTest() {
func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Run("can prepare a proposal with no transactions", func() {
// Set up the default lane with no transactions
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("1"), nil)
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("1"), nil)
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{})
s.Require().NoError(err)
@@ -77,10 +78,10 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(err)
// Set up the default lane
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx: true})
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx: true})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 10000000000})
s.Require().NotNil(resp)
s.Require().NoError(err)
@@ -114,11 +115,11 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(err)
// Set up the default lane with both transactions passing
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx1: true, tx2: true})
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx1: true, tx2: true})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx1))
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx2))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 10000000000})
s.Require().NotNil(resp)
s.Require().NoError(err)
@@ -152,11 +153,11 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(err)
// Set up the default lane with both transactions passing
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx1: true, tx2: false})
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx1: true, tx2: false})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx1))
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx2))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 10000000000})
s.Require().NotNil(resp)
s.Require().NoError(err)
@@ -167,10 +168,10 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
})
s.Run("can build a proposal an empty proposal with multiple lanes", func() {
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), nil)
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.5"), nil)
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), nil)
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.5"), nil)
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{})
s.Require().NoError(err)
@@ -192,15 +193,15 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(err)
// Set up the TOB lane with the bid tx and the bundled tx
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
tx: true,
bundleTxs[0]: true,
})
- s.Require().NoError(tobLane.Insert(sdk.Context{}, tx))
+ s.Require().NoError(mevLane.Insert(sdk.Context{}, tx))
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.5"), nil)
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.5"), nil)
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 10000000000})
s.Require().NoError(err)
@@ -224,21 +225,21 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(err)
// Set up the TOB lane with the bid tx and the bundled tx
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
tx: true,
bundleTxs[0]: true,
})
- s.Require().NoError(tobLane.Insert(sdk.Context{}, tx))
+ s.Require().NoError(mevLane.Insert(sdk.Context{}, tx))
// Set up the default lane with the bid tx and the bundled tx
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
tx: true,
bundleTxs[0]: true,
})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
s.Require().NoError(defaultLane.Insert(sdk.Context{}, bundleTxs[0]))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 10000000000})
s.Require().NoError(err)
@@ -262,14 +263,14 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(err)
// Set up the TOB lane with the bid tx and the bundled tx
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
tx: false,
bundleTxs[0]: true,
})
- s.Require().NoError(tobLane.Insert(sdk.Context{}, tx))
+ s.Require().NoError(mevLane.Insert(sdk.Context{}, tx))
// Set up the default lane with the bid tx and the bundled tx
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
// Even though this passes it should not include it in the proposal because it is in the ignore list
tx: true,
bundleTxs[0]: true,
@@ -277,7 +278,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
s.Require().NoError(defaultLane.Insert(sdk.Context{}, bundleTxs[0]))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, defaultLane}).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 10000000000})
s.Require().NoError(err)
@@ -301,14 +302,14 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(err)
// Set up the TOB lane with the bid tx and the bundled tx
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), map[sdk.Tx]bool{
tx: true,
bundleTxs[0]: true,
})
- s.Require().NoError(tobLane.Insert(sdk.Context{}, tx))
+ s.Require().NoError(mevLane.Insert(sdk.Context{}, tx))
// Set up the default lane with the bid tx and the bundled tx
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
// Even though this passes it should not include it in the proposal because it is in the ignore list
tx: true,
bundleTxs[0]: true,
@@ -316,7 +317,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
s.Require().NoError(defaultLane.Insert(sdk.Context{}, bundleTxs[0]))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, defaultLane}).PrepareProposalHandler()
proposal := s.getTxBytes(tx, bundleTxs[0])
size := int64(len(proposal[0]) - 1)
@@ -329,7 +330,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
})
s.Run("can build a proposal with single tx from middle lane", func() {
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), nil)
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), nil)
freeTx, err := testutils.CreateFreeTx(
s.encodingConfig.TxConfig,
@@ -342,7 +343,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
)
s.Require().NoError(err)
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
freeTx: true,
})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, freeTx))
@@ -352,7 +353,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
})
s.Require().NoError(freeLane.Insert(sdk.Context{}, freeTx))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, freeLane, defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, freeLane, defaultLane}).PrepareProposalHandler()
proposal := s.getTxBytes(freeTx)
@@ -399,16 +400,16 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
)
s.Require().NoError(err)
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{
tx: true,
bundleTxs[0]: true,
bundleTxs[1]: true,
bundleTxs[2]: true,
bundleTxs[3]: true,
})
- tobLane.Insert(sdk.Context{}, tx)
+ mevLane.Insert(sdk.Context{}, tx)
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
normalTx: true,
})
defaultLane.Insert(sdk.Context{}, normalTx)
@@ -418,7 +419,7 @@ func (s *ProposalsTestSuite) TestPrepareProposal() {
})
freeLane.Insert(sdk.Context{}, freeTx)
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, freeLane, defaultLane}).PrepareProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, freeLane, defaultLane}).PrepareProposalHandler()
proposal := s.getTxBytes(tx, bundleTxs[0], bundleTxs[1], bundleTxs[2], bundleTxs[3], freeTx, normalTx)
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 1000000000})
@@ -444,7 +445,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
)
s.Require().NoError(err)
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
tx: true,
})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
@@ -452,7 +453,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
proposalHandler := abci.NewProposalHandler(
log.NewTestLogger(s.T()),
s.encodingConfig.TxConfig.TxDecoder(),
- []blockbuster.Lane{panicLane, defaultLane},
+ []block.Lane{panicLane, defaultLane},
).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 1000000})
@@ -477,7 +478,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
)
s.Require().NoError(err)
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
tx: true,
})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
@@ -485,7 +486,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
proposalHandler := abci.NewProposalHandler(
log.NewTestLogger(s.T()),
s.encodingConfig.TxConfig.TxDecoder(),
- []blockbuster.Lane{defaultLane, panicLane},
+ []block.Lane{defaultLane, panicLane},
).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 1000000})
@@ -511,7 +512,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
)
s.Require().NoError(err)
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
tx: true,
})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
@@ -519,7 +520,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
proposalHandler := abci.NewProposalHandler(
log.NewTestLogger(s.T()),
s.encodingConfig.TxConfig.TxDecoder(),
- []blockbuster.Lane{panicLane, panicLane2, defaultLane},
+ []block.Lane{panicLane, panicLane2, defaultLane},
).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 1000000})
@@ -545,7 +546,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
)
s.Require().NoError(err)
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{
tx: true,
})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
@@ -553,7 +554,7 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
proposalHandler := abci.NewProposalHandler(
log.NewTestLogger(s.T()),
s.encodingConfig.TxConfig.TxDecoder(),
- []blockbuster.Lane{defaultLane, panicLane, panicLane2},
+ []block.Lane{defaultLane, panicLane, panicLane2},
).PrepareProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestPrepareProposal{MaxTxBytes: 1000000})
@@ -568,11 +569,11 @@ func (s *ProposalsTestSuite) TestPrepareProposalEdgeCases() {
func (s *ProposalsTestSuite) TestProcessProposal() {
s.Run("can process a valid empty proposal", func() {
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
freeLane := s.setUpFreeLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{})
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{})
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, freeLane, defaultLane}).ProcessProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, freeLane, defaultLane}).ProcessProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestProcessProposal{Txs: nil})
s.Require().NoError(err)
@@ -581,11 +582,11 @@ func (s *ProposalsTestSuite) TestProcessProposal() {
})
s.Run("rejects a proposal with bad txs", func() {
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
freeLane := s.setUpFreeLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{})
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.0"), map[sdk.Tx]bool{})
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, freeLane, defaultLane}).ProcessProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, freeLane, defaultLane}).ProcessProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestProcessProposal{Txs: [][]byte{{0x01, 0x02, 0x03}}})
s.Require().Error(err)
@@ -593,7 +594,7 @@ func (s *ProposalsTestSuite) TestProcessProposal() {
})
s.Run("rejects a proposal when a lane panics", func() {
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.25"), map[sdk.Tx]bool{})
panicLane := s.setUpPanicLane(math.LegacyMustNewDecFromStr("0.0"))
txbz, err := testutils.CreateRandomTxBz(
@@ -605,7 +606,7 @@ func (s *ProposalsTestSuite) TestProcessProposal() {
)
s.Require().NoError(err)
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, panicLane}).ProcessProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, panicLane}).ProcessProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestProcessProposal{Txs: [][]byte{txbz}})
s.Require().Error(err)
s.Require().Equal(&cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}, resp)
@@ -635,10 +636,10 @@ func (s *ProposalsTestSuite) TestProcessProposal() {
s.Require().NoError(err)
// Set up the default lane
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx: true})
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("1"), map[sdk.Tx]bool{tx: true})
s.Require().NoError(defaultLane.Insert(sdk.Context{}, tx))
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{defaultLane}).ProcessProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{defaultLane}).ProcessProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestProcessProposal{Txs: s.getTxBytes(tx, tx2)})
s.Require().NotNil(resp)
s.Require().Error(err)
@@ -676,14 +677,14 @@ func (s *ProposalsTestSuite) TestProcessProposal() {
s.Require().NoError(err)
// Set up the default lane
- defaultLane := s.setUpDefaultLane(math.LegacyMustNewDecFromStr("0.5"), nil)
- defaultLane.SetProcessLaneHandler(blockbuster.NoOpProcessLaneHandler())
+ defaultLane := s.setUpStandardLane(math.LegacyMustNewDecFromStr("0.5"), nil)
+ defaultLane.SetProcessLaneHandler(block.NoOpProcessLaneHandler())
// Set up the TOB lane
- tobLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), nil)
- tobLane.SetProcessLaneHandler(blockbuster.NoOpProcessLaneHandler())
+ mevLane := s.setUpTOBLane(math.LegacyMustNewDecFromStr("0.5"), nil)
+ mevLane.SetProcessLaneHandler(block.NoOpProcessLaneHandler())
- proposalHandler := s.setUpProposalHandlers([]blockbuster.Lane{tobLane, defaultLane}).ProcessProposalHandler()
+ proposalHandler := s.setUpProposalHandlers([]block.Lane{mevLane, defaultLane}).ProcessProposalHandler()
resp, err := proposalHandler(s.ctx, &cometabci.RequestProcessProposal{Txs: s.getTxBytes(bidTx, bundle[0], bundle[1], normalTx, normalTx2)})
s.Require().NotNil(resp)
s.Require().Error(err)
@@ -723,8 +724,8 @@ func (s *ProposalsTestSuite) setUpAnteHandler(expectedExecution map[sdk.Tx]bool)
return anteHandler
}
-func (s *ProposalsTestSuite) setUpDefaultLane(maxBlockSpace math.LegacyDec, expectedExecution map[sdk.Tx]bool) *base.DefaultLane {
- cfg := blockbuster.LaneConfig{
+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(),
@@ -732,11 +733,11 @@ func (s *ProposalsTestSuite) setUpDefaultLane(maxBlockSpace math.LegacyDec, expe
MaxBlockSpace: maxBlockSpace,
}
- return base.NewDefaultLane(cfg)
+ return defaultlane.NewDefaultLane(cfg)
}
-func (s *ProposalsTestSuite) setUpTOBLane(maxBlockSpace math.LegacyDec, expectedExecution map[sdk.Tx]bool) *auction.TOBLane {
- cfg := blockbuster.LaneConfig{
+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(),
@@ -744,11 +745,11 @@ func (s *ProposalsTestSuite) setUpTOBLane(maxBlockSpace math.LegacyDec, expected
MaxBlockSpace: maxBlockSpace,
}
- return auction.NewTOBLane(cfg, auction.NewDefaultAuctionFactory(cfg.TxDecoder))
+ return mev.NewMEVLane(cfg, mev.NewDefaultAuctionFactory(cfg.TxDecoder))
}
func (s *ProposalsTestSuite) setUpFreeLane(maxBlockSpace math.LegacyDec, expectedExecution map[sdk.Tx]bool) *free.FreeLane {
- cfg := blockbuster.LaneConfig{
+ cfg := base.LaneConfig{
Logger: log.NewTestLogger(s.T()),
TxEncoder: s.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: s.encodingConfig.TxConfig.TxDecoder(),
@@ -756,32 +757,32 @@ func (s *ProposalsTestSuite) setUpFreeLane(maxBlockSpace math.LegacyDec, expecte
MaxBlockSpace: maxBlockSpace,
}
- return free.NewFreeLane(cfg, blockbuster.DefaultTxPriority(), free.DefaultMatchHandler())
+ return free.NewFreeLane(cfg, base.DefaultTxPriority(), free.DefaultMatchHandler())
}
-func (s *ProposalsTestSuite) setUpPanicLane(maxBlockSpace math.LegacyDec) *blockbuster.LaneConstructor {
- cfg := blockbuster.LaneConfig{
+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,
}
- lane := blockbuster.NewLaneConstructor(
+ lane := base.NewBaseLane(
cfg,
"panic",
- blockbuster.NewConstructorMempool[string](blockbuster.DefaultTxPriority(), cfg.TxEncoder, 0),
- blockbuster.DefaultMatchHandler(),
+ base.NewMempool[string](base.DefaultTxPriority(), cfg.TxEncoder, 0),
+ base.DefaultMatchHandler(),
)
- lane.SetPrepareLaneHandler(blockbuster.PanicPrepareLaneHandler())
- lane.SetProcessLaneHandler(blockbuster.PanicProcessLaneHandler())
+ lane.SetPrepareLaneHandler(block.PanicPrepareLaneHandler())
+ lane.SetProcessLaneHandler(block.PanicProcessLaneHandler())
return lane
}
-func (s *ProposalsTestSuite) setUpProposalHandlers(lanes []blockbuster.Lane) *abci.ProposalHandler {
- mempool := blockbuster.NewMempool(log.NewTestLogger(s.T()), true, lanes...)
+func (s *ProposalsTestSuite) setUpProposalHandlers(lanes []block.Lane) *abci.ProposalHandler {
+ mempool := block.NewLanedMempool(log.NewTestLogger(s.T()), true, lanes...)
return abci.NewProposalHandler(
log.NewTestLogger(s.T()),
diff --git a/api/pob/abci/v1/auction.pulsar.go b/api/pob/abci/v1/auction.pulsar.go
index fb2e665..eadfe00 100644
--- a/api/pob/abci/v1/auction.pulsar.go
+++ b/api/pob/abci/v1/auction.pulsar.go
@@ -1411,4 +1411,4 @@ func file_pob_abci_v1_auction_proto_init() {
file_pob_abci_v1_auction_proto_rawDesc = nil
file_pob_abci_v1_auction_proto_goTypes = nil
file_pob_abci_v1_auction_proto_depIdxs = nil
-}
\ No newline at end of file
+}
diff --git a/blockbuster/lane_abci.go b/block/base/abci.go
similarity index 79%
rename from blockbuster/lane_abci.go
rename to block/base/abci.go
index a70b102..4eb138a 100644
--- a/blockbuster/lane_abci.go
+++ b/block/base/abci.go
@@ -1,20 +1,21 @@
-package blockbuster
+package base
import (
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/utils"
)
// PrepareLane will prepare a partial proposal for the lane. It will select transactions from the
// lane respecting the selection logic of the prepareLaneHandler. It will then update the partial
// proposal with the selected transactions. If the proposal is unable to be updated, we return an
// error. The proposal will only be modified if it passes all of the invarient checks.
-func (l *LaneConstructor) PrepareLane(
+func (l *BaseLane) PrepareLane(
ctx sdk.Context,
- proposal BlockProposal,
+ proposal block.BlockProposal,
maxTxBytes int64,
- next PrepareLanesHandler,
-) (BlockProposal, error) {
+ next block.PrepareLanesHandler,
+) (block.BlockProposal, error) {
txs, txsToRemove, err := l.prepareLaneHandler(ctx, proposal, maxTxBytes)
if err != nil {
return proposal, err
@@ -39,7 +40,7 @@ func (l *LaneConstructor) PrepareLane(
// CheckOrder checks that the ordering logic of the lane is respected given the set of transactions
// in the block proposal. If the ordering logic is not respected, we return an error.
-func (l *LaneConstructor) CheckOrder(ctx sdk.Context, txs []sdk.Tx) error {
+func (l *BaseLane) CheckOrder(ctx sdk.Context, txs []sdk.Tx) error {
return l.checkOrderHandler(ctx, txs)
}
@@ -47,7 +48,7 @@ func (l *LaneConstructor) CheckOrder(ctx sdk.Context, txs []sdk.Tx) error {
// the verification logic of the lane (processLaneHandler). If the transactions are valid, we
// return the transactions that do not belong to this lane to the next lane. If the transactions
// are invalid, we return an error.
-func (l *LaneConstructor) ProcessLane(ctx sdk.Context, txs []sdk.Tx, next ProcessLanesHandler) (sdk.Context, error) {
+func (l *BaseLane) ProcessLane(ctx sdk.Context, txs []sdk.Tx, next block.ProcessLanesHandler) (sdk.Context, error) {
remainingTxs, err := l.processLaneHandler(ctx, txs)
if err != nil {
return ctx, err
@@ -58,7 +59,7 @@ func (l *LaneConstructor) ProcessLane(ctx sdk.Context, txs []sdk.Tx, next Proces
// AnteVerifyTx verifies that the transaction is valid respecting the ante verification logic of
// of the antehandler chain.
-func (l *LaneConstructor) AnteVerifyTx(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
+func (l *BaseLane) AnteVerifyTx(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
if l.cfg.AnteHandler != nil {
return l.cfg.AnteHandler(ctx, tx, simulate)
}
diff --git a/block/base/config.go b/block/base/config.go
new file mode 100644
index 0000000..e9a404f
--- /dev/null
+++ b/block/base/config.go
@@ -0,0 +1,79 @@
+package base
+
+import (
+ "fmt"
+
+ "cosmossdk.io/log"
+ "cosmossdk.io/math"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/skip-mev/pob/block"
+)
+
+// LaneConfig defines the basic configurations needed for a lane.
+type LaneConfig struct {
+ Logger log.Logger
+ TxEncoder sdk.TxEncoder
+ TxDecoder sdk.TxDecoder
+ AnteHandler sdk.AnteHandler
+
+ // 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
+ // lane (up to maxTxBytes as provided by the request). This is useful for the default lane.
+ MaxBlockSpace math.LegacyDec
+
+ // IgnoreList defines the list of lanes to ignore when processing transactions. This
+ // is useful for when you want lanes to exist after the default lane. For example,
+ // say there are two lanes: default and free. The free lane should be 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).
+ IgnoreList []block.Lane
+
+ // MaxTxs sets the maximum number of transactions allowed in the mempool with
+ // the semantics:
+ // - if MaxTx == 0, there is no cap on the number of transactions in the mempool
+ // - if MaxTx > 0, the mempool will cap the number of transactions it stores,
+ // and will prioritize transactions by their priority and sender-nonce
+ // (sequence number) when evicting transactions.
+ // - if MaxTx < 0, `Insert` is a no-op.
+ MaxTxs int
+}
+
+// NewLaneConfig returns a new LaneConfig. This will be embedded in a lane.
+func NewLaneConfig(
+ logger log.Logger,
+ txEncoder sdk.TxEncoder,
+ txDecoder sdk.TxDecoder,
+ anteHandler sdk.AnteHandler,
+ maxBlockSpace math.LegacyDec,
+) LaneConfig {
+ return LaneConfig{
+ Logger: logger,
+ TxEncoder: txEncoder,
+ TxDecoder: txDecoder,
+ AnteHandler: anteHandler,
+ MaxBlockSpace: maxBlockSpace,
+ }
+}
+
+// ValidateBasic validates the lane configuration.
+func (c *LaneConfig) ValidateBasic() error {
+ if c.Logger == nil {
+ return fmt.Errorf("logger cannot be nil")
+ }
+
+ if c.TxEncoder == nil {
+ return fmt.Errorf("tx encoder cannot be nil")
+ }
+
+ if c.TxDecoder == nil {
+ return fmt.Errorf("tx decoder 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")
+ }
+
+ return nil
+}
diff --git a/blockbuster/lane_handlers.go b/block/base/handlers.go
similarity index 90%
rename from blockbuster/lane_handlers.go
rename to block/base/handlers.go
index 0a87a5d..3782d36 100644
--- a/blockbuster/lane_handlers.go
+++ b/block/base/handlers.go
@@ -1,18 +1,19 @@
-package blockbuster
+package base
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/utils"
)
// DefaultPrepareLaneHandler returns a default implementation of the PrepareLaneHandler. It
// selects all transactions in the mempool that are valid and not already in the partial
// proposal. It will continue to reap transactions until the maximum block space for this
// lane has been reached. Additionally, any transactions that are invalid will be returned.
-func (l *LaneConstructor) DefaultPrepareLaneHandler() PrepareLaneHandler {
- return func(ctx sdk.Context, proposal BlockProposal, maxTxBytes int64) ([][]byte, []sdk.Tx, error) {
+func (l *BaseLane) DefaultPrepareLaneHandler() block.PrepareLaneHandler {
+ return func(ctx sdk.Context, proposal block.BlockProposal, maxTxBytes int64) ([][]byte, []sdk.Tx, error) {
var (
totalSize int64
txs [][]byte
@@ -95,7 +96,7 @@ func (l *LaneConstructor) DefaultPrepareLaneHandler() PrepareLaneHandler {
// fails to verify, the entire proposal is rejected. If the handler comes across a transaction
// that does not match the lane's matcher, it will return the remaining transactions in the
// proposal.
-func (l *LaneConstructor) DefaultProcessLaneHandler() ProcessLaneHandler {
+func (l *BaseLane) DefaultProcessLaneHandler() block.ProcessLaneHandler {
return func(ctx sdk.Context, txs []sdk.Tx) ([]sdk.Tx, error) {
var err error
@@ -122,7 +123,7 @@ func (l *LaneConstructor) DefaultProcessLaneHandler() ProcessLaneHandler {
// lane.
// 2. Transactions that belong to other lanes cannot be interleaved with transactions that
// belong to this lane.
-func (l *LaneConstructor) DefaultCheckOrderHandler() CheckOrderHandler {
+func (l *BaseLane) DefaultCheckOrderHandler() block.CheckOrderHandler {
return func(ctx sdk.Context, txs []sdk.Tx) error {
seenOtherLaneTx := false
@@ -148,7 +149,7 @@ func (l *LaneConstructor) DefaultCheckOrderHandler() CheckOrderHandler {
// DefaultMatchHandler returns a default implementation of the MatchHandler. It matches all
// transactions.
-func DefaultMatchHandler() MatchHandler {
+func DefaultMatchHandler() block.MatchHandler {
return func(ctx sdk.Context, tx sdk.Tx) bool {
return true
}
diff --git a/blockbuster/lane_constructor.go b/block/base/lane.go
similarity index 78%
rename from blockbuster/lane_constructor.go
rename to block/base/lane.go
index 7107814..dc58cf4 100644
--- a/blockbuster/lane_constructor.go
+++ b/block/base/lane.go
@@ -1,4 +1,4 @@
-package blockbuster
+package base
import (
"fmt"
@@ -6,16 +6,17 @@ import (
"cosmossdk.io/log"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
+ "github.com/skip-mev/pob/block"
)
-var _ Lane = (*LaneConstructor)(nil)
+var _ block.Lane = (*BaseLane)(nil)
-// LaneConstructor is a generic implementation of a lane. It is meant to be used
+// BaseLane is a generic implementation of a lane. It is meant to be used
// as a base for other lanes to be built on top of. It provides a default
// implementation of the MatchHandler, PrepareLaneHandler, ProcessLaneHandler,
// and CheckOrderHandler. To extend this lane, you must either utilize the default
-// handlers or construct your own that you pass into the constructor/setters.
-type LaneConstructor struct {
+// handlers or construct your own that you pass into the base/setters.
+type BaseLane struct { //nolint
// cfg stores functionality required to encode/decode transactions, maintains how
// many transactions are allowed in this lane's mempool, and the amount of block
// space this lane is allowed to consume.
@@ -26,37 +27,37 @@ type LaneConstructor struct {
// LaneMempool is the mempool that is responsible for storing transactions
// that are waiting to be processed.
- LaneMempool
+ block.LaneMempool
// matchHandler is the function that determines whether or not a transaction
// should be processed by this lane.
- matchHandler MatchHandler
+ matchHandler block.MatchHandler
// prepareLaneHandler is the function that is called when a new proposal is being
// requested and the lane needs to submit transactions it wants included in the block.
- prepareLaneHandler PrepareLaneHandler
+ prepareLaneHandler block.PrepareLaneHandler
// checkOrderHandler is the function that is called when a new proposal is being
// verified and the lane needs to verify that the transactions included in the proposal
// respect the ordering rules of the lane and does not interleave transactions from other lanes.
- checkOrderHandler CheckOrderHandler
+ checkOrderHandler block.CheckOrderHandler
// processLaneHandler is the function that is called when a new proposal is being
// verified and the lane needs to verify that the transactions included in the proposal
// are valid respecting the verification logic of the lane.
- processLaneHandler ProcessLaneHandler
+ processLaneHandler block.ProcessLaneHandler
}
-// NewLaneConstructor returns a new lane constructor. When creating this lane, the type
+// NewBaseLane returns a new lane base. When creating this lane, the type
// of the lane must be specified. The type of the lane is directly associated with the
// type of the mempool that is used to store transactions that are waiting to be processed.
-func NewLaneConstructor(
+func NewBaseLane(
cfg LaneConfig,
laneName string,
- laneMempool LaneMempool,
- matchHandlerFn MatchHandler,
-) *LaneConstructor {
- lane := &LaneConstructor{
+ laneMempool block.LaneMempool,
+ matchHandlerFn block.MatchHandler,
+) *BaseLane {
+ lane := &BaseLane{
cfg: cfg,
laneName: laneName,
LaneMempool: laneMempool,
@@ -72,7 +73,7 @@ func NewLaneConstructor(
// ValidateBasic ensures that the lane was constructed properly. In the case that
// the lane was not constructed with proper handlers, default handlers are set.
-func (l *LaneConstructor) ValidateBasic() error {
+func (l *BaseLane) ValidateBasic() error {
if err := l.cfg.ValidateBasic(); err != nil {
return err
}
@@ -107,7 +108,7 @@ func (l *LaneConstructor) ValidateBasic() error {
// SetPrepareLaneHandler sets the prepare lane handler for the lane. This handler
// is called when a new proposal is being requested and the lane needs to submit
// transactions it wants included in the block.
-func (l *LaneConstructor) SetPrepareLaneHandler(prepareLaneHandler PrepareLaneHandler) {
+func (l *BaseLane) SetPrepareLaneHandler(prepareLaneHandler block.PrepareLaneHandler) {
if prepareLaneHandler == nil {
panic("prepare lane handler cannot be nil")
}
@@ -119,7 +120,7 @@ func (l *LaneConstructor) SetPrepareLaneHandler(prepareLaneHandler PrepareLaneHa
// is called when a new proposal is being verified and the lane needs to verify
// that the transactions included in the proposal are valid respecting the verification
// logic of the lane.
-func (l *LaneConstructor) SetProcessLaneHandler(processLaneHandler ProcessLaneHandler) {
+func (l *BaseLane) SetProcessLaneHandler(processLaneHandler block.ProcessLaneHandler) {
if processLaneHandler == nil {
panic("process lane handler cannot be nil")
}
@@ -131,7 +132,7 @@ func (l *LaneConstructor) SetProcessLaneHandler(processLaneHandler ProcessLaneHa
// is called when a new proposal is being verified and the lane needs to verify
// that the transactions included in the proposal respect the ordering rules of
// the lane and does not include transactions from other lanes.
-func (l *LaneConstructor) SetCheckOrderHandler(checkOrderHandler CheckOrderHandler) {
+func (l *BaseLane) SetCheckOrderHandler(checkOrderHandler block.CheckOrderHandler) {
if checkOrderHandler == nil {
panic("check order handler cannot be nil")
}
@@ -143,14 +144,14 @@ func (l *LaneConstructor) SetCheckOrderHandler(checkOrderHandler CheckOrderHandl
// function first determines if the transaction matches the lane and then checks
// if the transaction is on the ignore list. If the transaction is on the ignore
// list, it returns false.
-func (l *LaneConstructor) Match(ctx sdk.Context, tx sdk.Tx) bool {
+func (l *BaseLane) Match(ctx sdk.Context, tx sdk.Tx) bool {
return l.matchHandler(ctx, tx) && !l.CheckIgnoreList(ctx, tx)
}
// CheckIgnoreList returns true if the transaction is on the ignore list. The ignore
// list is utilized to prevent transactions that should be considered in other lanes
// from being considered from this lane.
-func (l *LaneConstructor) CheckIgnoreList(ctx sdk.Context, tx sdk.Tx) bool {
+func (l *BaseLane) CheckIgnoreList(ctx sdk.Context, tx sdk.Tx) bool {
for _, lane := range l.cfg.IgnoreList {
if lane.Match(ctx, tx) {
return true
@@ -161,38 +162,38 @@ func (l *LaneConstructor) CheckIgnoreList(ctx sdk.Context, tx sdk.Tx) bool {
}
// Name returns the name of the lane.
-func (l *LaneConstructor) Name() string {
+func (l *BaseLane) Name() string {
return l.laneName
}
// SetIgnoreList sets the ignore list for the lane. The ignore list is a list
// of lanes that the lane should ignore when processing transactions.
-func (l *LaneConstructor) SetIgnoreList(lanes []Lane) {
+func (l *BaseLane) SetIgnoreList(lanes []block.Lane) {
l.cfg.IgnoreList = lanes
}
// SetAnteHandler sets the ante handler for the lane.
-func (l *LaneConstructor) SetAnteHandler(anteHandler sdk.AnteHandler) {
+func (l *BaseLane) SetAnteHandler(anteHandler sdk.AnteHandler) {
l.cfg.AnteHandler = anteHandler
}
// Logger returns the logger for the lane.
-func (l *LaneConstructor) Logger() log.Logger {
+func (l *BaseLane) Logger() log.Logger {
return l.cfg.Logger
}
// TxDecoder returns the tx decoder for the lane.
-func (l *LaneConstructor) TxDecoder() sdk.TxDecoder {
+func (l *BaseLane) TxDecoder() sdk.TxDecoder {
return l.cfg.TxDecoder
}
// TxEncoder returns the tx encoder for the lane.
-func (l *LaneConstructor) TxEncoder() sdk.TxEncoder {
+func (l *BaseLane) TxEncoder() sdk.TxEncoder {
return l.cfg.TxEncoder
}
// GetMaxBlockSpace returns the maximum amount of block space that the lane is
// allowed to consume as a percentage of the total block space.
-func (l *LaneConstructor) GetMaxBlockSpace() math.LegacyDec {
+func (l *BaseLane) GetMaxBlockSpace() math.LegacyDec {
return l.cfg.MaxBlockSpace
}
diff --git a/blockbuster/lane_mempool.go b/block/base/mempool.go
similarity index 81%
rename from blockbuster/lane_mempool.go
rename to block/base/mempool.go
index e102ee8..22bcf05 100644
--- a/blockbuster/lane_mempool.go
+++ b/block/base/mempool.go
@@ -1,4 +1,4 @@
-package blockbuster
+package base
import (
"context"
@@ -7,16 +7,16 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block/utils"
)
type (
- // ConstructorMempool defines a mempool that orders transactions based on the
+ // Mempool defines a mempool that orders transactions based on the
// txPriority. The mempool is a wrapper on top of the SDK's Priority Nonce mempool.
// It include's additional helper functions that allow users to determine if a
// transaction is already in the mempool and to compare the priority of two
// transactions.
- ConstructorMempool[C comparable] struct {
+ Mempool[C comparable] struct {
// index defines an index of transactions.
index sdkmempool.Mempool
@@ -79,9 +79,9 @@ func DefaultTxPriority() TxPriority[string] {
}
}
-// NewConstructorMempool returns a new ConstructorMempool.
-func NewConstructorMempool[C comparable](txPriority TxPriority[C], txEncoder sdk.TxEncoder, maxTx int) *ConstructorMempool[C] {
- return &ConstructorMempool[C]{
+// NewMempool returns a new Mempool.
+func NewMempool[C comparable](txPriority TxPriority[C], txEncoder sdk.TxEncoder, maxTx int) *Mempool[C] {
+ return &Mempool[C]{
index: NewPriorityMempool(
PriorityNonceMempoolConfig[C]{
TxPriority: txPriority,
@@ -95,7 +95,7 @@ func NewConstructorMempool[C comparable](txPriority TxPriority[C], txEncoder sdk
}
// Insert inserts a transaction into the mempool.
-func (cm *ConstructorMempool[C]) Insert(ctx context.Context, tx sdk.Tx) error {
+func (cm *Mempool[C]) Insert(ctx context.Context, tx sdk.Tx) error {
if err := cm.index.Insert(ctx, tx); err != nil {
return fmt.Errorf("failed to insert tx into auction index: %w", err)
}
@@ -112,7 +112,7 @@ func (cm *ConstructorMempool[C]) Insert(ctx context.Context, tx sdk.Tx) error {
}
// Remove removes a transaction from the mempool.
-func (cm *ConstructorMempool[C]) Remove(tx sdk.Tx) error {
+func (cm *Mempool[C]) Remove(tx sdk.Tx) error {
if err := cm.index.Remove(tx); err != nil && !errors.Is(err, sdkmempool.ErrTxNotFound) {
return fmt.Errorf("failed to remove transaction from the mempool: %w", err)
}
@@ -131,17 +131,17 @@ func (cm *ConstructorMempool[C]) Remove(tx sdk.Tx) error {
// remove a transaction from the mempool while iterating over the transactions,
// the iterator will not be aware of the removal and will continue to iterate
// over the removed transaction. Be sure to reset the iterator if you remove a transaction.
-func (cm *ConstructorMempool[C]) Select(ctx context.Context, txs [][]byte) sdkmempool.Iterator {
+func (cm *Mempool[C]) Select(ctx context.Context, txs [][]byte) sdkmempool.Iterator {
return cm.index.Select(ctx, txs)
}
// CountTx returns the number of transactions in the mempool.
-func (cm *ConstructorMempool[C]) CountTx() int {
+func (cm *Mempool[C]) CountTx() int {
return cm.index.CountTx()
}
// Contains returns true if the transaction is contained in the mempool.
-func (cm *ConstructorMempool[C]) Contains(tx sdk.Tx) bool {
+func (cm *Mempool[C]) Contains(tx sdk.Tx) bool {
_, txHashStr, err := utils.GetTxHashStr(cm.txEncoder, tx)
if err != nil {
return false
@@ -152,7 +152,7 @@ func (cm *ConstructorMempool[C]) Contains(tx sdk.Tx) bool {
}
// Compare determines the relative priority of two transactions belonging in the same lane.
-func (cm *ConstructorMempool[C]) Compare(ctx sdk.Context, this sdk.Tx, other sdk.Tx) int {
+func (cm *Mempool[C]) Compare(ctx sdk.Context, this sdk.Tx, other sdk.Tx) int {
firstPriority := cm.txPriority.GetTxPriority(ctx, this)
secondPriority := cm.txPriority.GetTxPriority(ctx, other)
return cm.txPriority.Compare(firstPriority, secondPriority)
diff --git a/blockbuster/priority_nonce.go b/block/base/priority_nonce.go
similarity index 94%
rename from blockbuster/priority_nonce.go
rename to block/base/priority_nonce.go
index b561d50..1b32019 100644
--- a/blockbuster/priority_nonce.go
+++ b/block/base/priority_nonce.go
@@ -1,4 +1,16 @@
-package blockbuster
+package base
+
+// ------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------ //
+// NOTE: THIS IS A COPY OF THE PRIORITY NONCE MEMPOOL FROM COSMOS-SDK. IT HAS BEEN
+// MODIFIED FOR OUR USE CASE. THIS CODE WILL BE DEPRECATED ONCE THE COSMOS-SDK
+// CUTS A FINAL v0.50.0 RELEASE.
+// ------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------ //
+// ------------------------------------------------------------------------------ //
import (
"context"
diff --git a/blockbuster/lane_interface.go b/block/lane.go
similarity index 99%
rename from blockbuster/lane_interface.go
rename to block/lane.go
index 59ee35e..0731948 100644
--- a/blockbuster/lane_interface.go
+++ b/block/lane.go
@@ -1,4 +1,4 @@
-package blockbuster
+package block
import (
"cosmossdk.io/log"
diff --git a/blockbuster/mempool.go b/block/mempool.go
similarity index 83%
rename from blockbuster/mempool.go
rename to block/mempool.go
index 938d2b6..4029c09 100644
--- a/blockbuster/mempool.go
+++ b/block/mempool.go
@@ -1,4 +1,4 @@
-package blockbuster
+package block
import (
"context"
@@ -11,10 +11,10 @@ import (
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
)
-var _ Mempool = (*BBMempool)(nil)
+var _ Mempool = (*LanedMempool)(nil)
type (
- // Mempool defines the Blockbuster mempool interface.
+ // Mempool defines the Block SDK mempool interface.
Mempool interface {
sdkmempool.Mempool
@@ -26,14 +26,11 @@ type (
// GetTxDistribution returns the number of transactions in each lane.
GetTxDistribution() map[string]int
-
- // GetLane returns the lane with the given name.
- GetLane(name string) (Lane, error)
}
- // BBMempool defines the Blockbuster mempool implementation. It contains a registry
+ // LanedMempool defines the Block SDK mempool implementation. It contains a registry
// of lanes, which allows for customizable block proposal construction.
- BBMempool struct {
+ LanedMempool struct {
logger log.Logger
// registry contains the lanes in the mempool. The lanes are ordered
@@ -43,7 +40,7 @@ type (
}
)
-// NewMempool returns a new Blockbuster mempool. The blockbuster mempool is
+// NewLanedMempool returns a new Block SDK LanedMempool. The laned mempool is
// comprised of 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
@@ -54,8 +51,8 @@ type (
// 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 NewMempool(logger log.Logger, mutex bool, lanes ...Lane) *BBMempool {
- mempool := &BBMempool{
+func NewLanedMempool(logger log.Logger, mutex bool, lanes ...Lane) *LanedMempool {
+ mempool := &LanedMempool{
logger: logger,
registry: lanes,
}
@@ -79,7 +76,7 @@ func NewMempool(logger log.Logger, mutex bool, lanes ...Lane) *BBMempool {
// CountTx returns the total number of transactions in the mempool. This will
// be the sum of the number of transactions in each lane.
-func (m *BBMempool) CountTx() int {
+func (m *LanedMempool) CountTx() int {
var total int
for _, lane := range m.registry {
total += lane.CountTx()
@@ -89,7 +86,7 @@ func (m *BBMempool) CountTx() int {
}
// GetTxDistribution returns the number of transactions in each lane.
-func (m *BBMempool) GetTxDistribution() map[string]int {
+func (m *LanedMempool) GetTxDistribution() map[string]int {
counts := make(map[string]int, len(m.registry))
for _, lane := range m.registry {
@@ -101,7 +98,7 @@ func (m *BBMempool) GetTxDistribution() map[string]int {
// Insert will insert a transaction into the mempool. It inserts the transaction
// into the first lane that it matches.
-func (m *BBMempool) Insert(ctx context.Context, tx sdk.Tx) (err error) {
+func (m *LanedMempool) Insert(ctx context.Context, tx sdk.Tx) (err error) {
defer func() {
if r := recover(); r != nil {
m.logger.Error("panic in Insert", "err", r)
@@ -136,12 +133,12 @@ func (m *BBMempool) Insert(ctx context.Context, tx sdk.Tx) (err error) {
// - Determine if it even makes sense to return an iterator. What does that even
// mean in the context where you have multiple lanes?
// - Perhaps consider implementing and returning a no-op iterator?
-func (m *BBMempool) Select(_ context.Context, _ [][]byte) sdkmempool.Iterator {
+func (m *LanedMempool) Select(_ context.Context, _ [][]byte) sdkmempool.Iterator {
return nil
}
// Remove removes a transaction from all of the lanes it is currently in.
-func (m *BBMempool) Remove(tx sdk.Tx) (err error) {
+func (m *LanedMempool) Remove(tx sdk.Tx) (err error) {
defer func() {
if r := recover(); r != nil {
m.logger.Error("panic in Remove", "err", r)
@@ -179,7 +176,7 @@ func (m *BBMempool) Remove(tx sdk.Tx) (err error) {
}
// Contains returns true if the transaction is contained in any of the lanes.
-func (m *BBMempool) Contains(tx sdk.Tx) (contains bool) {
+func (m *LanedMempool) Contains(tx sdk.Tx) (contains bool) {
defer func() {
if r := recover(); r != nil {
m.logger.Error("panic in Contains", "err", r)
@@ -197,7 +194,7 @@ func (m *BBMempool) Contains(tx sdk.Tx) (contains bool) {
}
// Registry returns the mempool's lane registry.
-func (m *BBMempool) Registry() []Lane {
+func (m *LanedMempool) Registry() []Lane {
return m.registry
}
@@ -205,7 +202,7 @@ func (m *BBMempool) Registry() []Lane {
// 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 *BBMempool) ValidateBasic() error {
+func (m *LanedMempool) ValidateBasic() error {
sum := math.LegacyZeroDec()
seenZeroMaxBlockSpace := false
@@ -230,14 +227,3 @@ func (m *BBMempool) ValidateBasic() error {
return nil
}
-
-// GetLane returns the lane with the given name.
-func (m *BBMempool) GetLane(name string) (Lane, error) {
- for _, lane := range m.registry {
- if lane.Name() == name {
- return lane, nil
- }
- }
-
- return nil, fmt.Errorf("lane %s not found", name)
-}
diff --git a/blockbuster/mempool_test.go b/block/mempool_test.go
similarity index 81%
rename from blockbuster/mempool_test.go
rename to block/mempool_test.go
index 84e470c..242b27a 100644
--- a/blockbuster/mempool_test.go
+++ b/block/mempool_test.go
@@ -1,4 +1,4 @@
-package blockbuster_test
+package block_test
import (
"math/rand"
@@ -10,10 +10,11 @@ import (
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/lanes/auction"
- "github.com/skip-mev/pob/blockbuster/lanes/base"
- "github.com/skip-mev/pob/blockbuster/lanes/free"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
+ defaultlane "github.com/skip-mev/pob/lanes/base"
+ "github.com/skip-mev/pob/lanes/free"
+ "github.com/skip-mev/pob/lanes/mev"
testutils "github.com/skip-mev/pob/testutils"
buildertypes "github.com/skip-mev/pob/x/builder/types"
"github.com/stretchr/testify/suite"
@@ -27,13 +28,13 @@ type BlockBusterTestSuite struct {
encodingConfig testutils.EncodingConfig
// Define all of the lanes utilized in the test suite
- tobLane *auction.TOBLane
- baseLane *base.DefaultLane
+ mevLane *mev.MEVLane
+ baseLane *defaultlane.DefaultLane
freeLane *free.FreeLane
gasTokenDenom string
- lanes []blockbuster.Lane
- mempool blockbuster.Mempool
+ lanes []block.Lane
+ mempool block.Mempool
// account set up
accounts []testutils.Account
@@ -57,20 +58,20 @@ func (suite *BlockBusterTestSuite) SetupTest() {
//
// TOB lane set up
suite.gasTokenDenom = "stake"
- tobConfig := blockbuster.LaneConfig{
+ mevConfig := base.LaneConfig{
Logger: log.NewNopLogger(),
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: nil,
MaxBlockSpace: math.LegacyZeroDec(),
}
- suite.tobLane = auction.NewTOBLane(
- tobConfig,
- auction.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
+ suite.mevLane = mev.NewMEVLane(
+ mevConfig,
+ mev.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
)
// Free lane set up
- freeConfig := blockbuster.LaneConfig{
+ freeConfig := base.LaneConfig{
Logger: log.NewNopLogger(),
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
@@ -79,25 +80,25 @@ func (suite *BlockBusterTestSuite) SetupTest() {
}
suite.freeLane = free.NewFreeLane(
freeConfig,
- blockbuster.DefaultTxPriority(),
+ base.DefaultTxPriority(),
free.DefaultMatchHandler(),
)
// Base lane set up
- baseConfig := blockbuster.LaneConfig{
+ baseConfig := base.LaneConfig{
Logger: log.NewNopLogger(),
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: nil,
MaxBlockSpace: math.LegacyZeroDec(),
}
- suite.baseLane = base.NewDefaultLane(
+ suite.baseLane = defaultlane.NewDefaultLane(
baseConfig,
)
// Mempool set up
- suite.lanes = []blockbuster.Lane{suite.tobLane, suite.freeLane, suite.baseLane}
- suite.mempool = blockbuster.NewMempool(log.NewTestLogger(suite.T()), true, suite.lanes...)
+ suite.lanes = []block.Lane{suite.mevLane, suite.freeLane, suite.baseLane}
+ suite.mempool = block.NewLanedMempool(log.NewTestLogger(suite.T()), true, suite.lanes...)
// Accounts set up
suite.accounts = testutils.RandomAccounts(suite.random, 10)
@@ -113,15 +114,15 @@ func (suite *BlockBusterTestSuite) TestInsert() {
insertDistribution map[string]int
}{
{
- "insert 1 tob tx",
+ "insert 1 mev tx",
map[string]int{
- suite.tobLane.Name(): 1,
+ suite.mevLane.Name(): 1,
},
},
{
- "insert 10 tob txs",
+ "insert 10 mev txs",
map[string]int{
- suite.tobLane.Name(): 10,
+ suite.mevLane.Name(): 10,
},
},
{
@@ -131,24 +132,24 @@ func (suite *BlockBusterTestSuite) TestInsert() {
},
},
{
- "insert 10 base txs and 10 tob txs",
+ "insert 10 base txs and 10 mev txs",
map[string]int{
suite.baseLane.Name(): 10,
- suite.tobLane.Name(): 10,
+ suite.mevLane.Name(): 10,
},
},
{
- "insert 100 base txs and 100 tob txs",
+ "insert 100 base txs and 100 mev txs",
map[string]int{
suite.baseLane.Name(): 100,
- suite.tobLane.Name(): 100,
+ suite.mevLane.Name(): 100,
},
},
{
- "insert 100 base txs, 100 tob txs, and 100 free txs",
+ "insert 100 base txs, 100 mev txs, and 100 free txs",
map[string]int{
suite.baseLane.Name(): 100,
- suite.tobLane.Name(): 100,
+ suite.mevLane.Name(): 100,
suite.freeLane.Name(): 100,
},
},
@@ -166,9 +167,9 @@ func (suite *BlockBusterTestSuite) TestInsert() {
},
},
{
- "insert 10 tob txs and 10 free txs",
+ "insert 10 mev txs and 10 free txs",
map[string]int{
- suite.tobLane.Name(): 10,
+ suite.mevLane.Name(): 10,
suite.freeLane.Name(): 10,
},
},
@@ -182,7 +183,7 @@ func (suite *BlockBusterTestSuite) TestInsert() {
suite.fillBaseLane(tc.insertDistribution[suite.baseLane.Name()])
// Fill the TOB lane with numTobTxs transactions
- suite.fillTOBLane(tc.insertDistribution[suite.tobLane.Name()])
+ suite.fillTOBLane(tc.insertDistribution[suite.mevLane.Name()])
// Fill the Free lane with numFreeTxs transactions
suite.fillFreeLane(tc.insertDistribution[suite.freeLane.Name()])
@@ -196,7 +197,7 @@ func (suite *BlockBusterTestSuite) TestInsert() {
suite.Require().Equal(sum, suite.mempool.CountTx())
// Validate the lanes
- suite.Require().Equal(tc.insertDistribution[suite.tobLane.Name()], suite.tobLane.CountTx())
+ suite.Require().Equal(tc.insertDistribution[suite.mevLane.Name()], suite.mevLane.CountTx())
suite.Require().Equal(tc.insertDistribution[suite.baseLane.Name()], suite.baseLane.CountTx())
suite.Require().Equal(tc.insertDistribution[suite.freeLane.Name()], suite.freeLane.CountTx())
@@ -204,7 +205,7 @@ func (suite *BlockBusterTestSuite) TestInsert() {
laneCounts := suite.mempool.GetTxDistribution()
// Ensure that the lane counts are correct
- suite.Require().Equal(tc.insertDistribution[suite.tobLane.Name()], laneCounts[suite.tobLane.Name()])
+ suite.Require().Equal(tc.insertDistribution[suite.mevLane.Name()], laneCounts[suite.mevLane.Name()])
suite.Require().Equal(tc.insertDistribution[suite.baseLane.Name()], laneCounts[suite.baseLane.Name()])
suite.Require().Equal(tc.insertDistribution[suite.freeLane.Name()], laneCounts[suite.freeLane.Name()])
})
@@ -218,12 +219,12 @@ func (suite *BlockBusterTestSuite) TestRemove() {
numBaseTxs int
}{
{
- "insert 1 tob tx",
+ "insert 1 mev tx",
1,
0,
},
{
- "insert 10 tob txs",
+ "insert 10 mev txs",
10,
0,
},
@@ -233,12 +234,12 @@ func (suite *BlockBusterTestSuite) TestRemove() {
1,
},
{
- "insert 10 base txs and 10 tob txs",
+ "insert 10 base txs and 10 mev txs",
10,
10,
},
{
- "insert 100 base txs and 100 tob txs",
+ "insert 100 base txs and 100 mev txs",
100,
100,
},
@@ -255,7 +256,7 @@ func (suite *BlockBusterTestSuite) TestRemove() {
suite.fillTOBLane(tc.numTobTxs)
// Remove all transactions from the lanes
- tobCount := tc.numTobTxs
+ mevCount := tc.numTobTxs
baseCount := tc.numBaseTxs
for iterator := suite.baseLane.Select(suite.ctx, nil); iterator != nil; {
tx := iterator.Tx()
@@ -277,10 +278,10 @@ func (suite *BlockBusterTestSuite) TestRemove() {
}
suite.Require().Equal(0, suite.baseLane.CountTx())
- suite.Require().Equal(tobCount, suite.tobLane.CountTx())
+ suite.Require().Equal(mevCount, suite.mevLane.CountTx())
// Remove all transactions from the lanes
- for iterator := suite.tobLane.Select(suite.ctx, nil); iterator != nil; {
+ for iterator := suite.mevLane.Select(suite.ctx, nil); iterator != nil; {
tx := iterator.Tx()
// Remove the transaction from the mempool
@@ -290,16 +291,16 @@ func (suite *BlockBusterTestSuite) TestRemove() {
suite.Require().Equal(false, suite.mempool.Contains(tx))
// Ensure the number of transactions in the lane is correct
- tobCount--
- suite.Require().Equal(suite.tobLane.CountTx(), tobCount)
+ mevCount--
+ suite.Require().Equal(suite.mevLane.CountTx(), mevCount)
distribution := suite.mempool.GetTxDistribution()
- suite.Require().Equal(distribution[suite.tobLane.Name()], tobCount)
+ suite.Require().Equal(distribution[suite.mevLane.Name()], mevCount)
- iterator = suite.tobLane.Select(suite.ctx, nil)
+ iterator = suite.mevLane.Select(suite.ctx, nil)
}
- suite.Require().Equal(0, suite.tobLane.CountTx())
+ suite.Require().Equal(0, suite.mevLane.CountTx())
suite.Require().Equal(0, suite.baseLane.CountTx())
suite.Require().Equal(0, suite.mempool.CountTx())
@@ -307,7 +308,7 @@ func (suite *BlockBusterTestSuite) TestRemove() {
distribution := suite.mempool.GetTxDistribution()
// Ensure that the lane counts are correct
- suite.Require().Equal(distribution[suite.tobLane.Name()], 0)
+ suite.Require().Equal(distribution[suite.mevLane.Name()], 0)
suite.Require().Equal(distribution[suite.baseLane.Name()], 0)
})
}
diff --git a/blockbuster/proposals.go b/block/proposals.go
similarity index 98%
rename from blockbuster/proposals.go
rename to block/proposals.go
index 95da151..f2d77ea 100644
--- a/blockbuster/proposals.go
+++ b/block/proposals.go
@@ -1,4 +1,4 @@
-package blockbuster
+package block
import (
"crypto/sha256"
@@ -7,7 +7,7 @@ import (
"cosmossdk.io/log"
"cosmossdk.io/math"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block/utils"
)
var _ BlockProposal = (*Proposal)(nil)
@@ -30,7 +30,7 @@ type (
// and updating proposals. BlockProposals are iteratively updated as each lane prepares its
// partial proposal. Each lane must call UpdateProposal with its partial proposal in PrepareLane. BlockProposals
// can also include vote extensions, which are included at the top of the proposal.
- BlockProposal interface {
+ BlockProposal interface { //nolint
// UpdateProposal updates the proposal with the given transactions. There are a
// few invarients that are checked:
// 1. The total size of the proposal must be less than the maximum number of bytes allowed.
diff --git a/blockbuster/types.go b/block/types.go
similarity index 60%
rename from blockbuster/types.go
rename to block/types.go
index d816863..8a1d2ed 100644
--- a/blockbuster/types.go
+++ b/block/types.go
@@ -1,10 +1,6 @@
-package blockbuster
+package block
import (
- "fmt"
-
- "cosmossdk.io/log"
- "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)
@@ -44,77 +40,8 @@ type (
// function. You can think of it like an AnteHandler, but for processing proposals in the
// context of lanes instead of modules.
ProcessLanesHandler func(ctx sdk.Context, txs []sdk.Tx) (sdk.Context, error)
-
- // LaneConfig defines the basic functionality needed for a lane.
- LaneConfig struct {
- Logger log.Logger
- TxEncoder sdk.TxEncoder
- TxDecoder sdk.TxDecoder
- AnteHandler sdk.AnteHandler
-
- // 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
- // lane (up to maxTxBytes as provided by the request). This is useful for the default lane.
- MaxBlockSpace math.LegacyDec
-
- // IgnoreList defines the list of lanes to ignore when processing transactions. This
- // is useful for when you want lanes to exist after the default lane. For example,
- // say there are two lanes: default and free. The free lane should be 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).
- IgnoreList []Lane
-
- // MaxTxs sets the maximum number of transactions allowed in the mempool with
- // the semantics:
- // - if MaxTx == 0, there is no cap on the number of transactions in the mempool
- // - if MaxTx > 0, the mempool will cap the number of transactions it stores,
- // and will prioritize transactions by their priority and sender-nonce
- // (sequence number) when evicting transactions.
- // - if MaxTx < 0, `Insert` is a no-op.
- MaxTxs int
- }
)
-// NewLaneConfig returns a new LaneConfig. This will be embedded in a lane.
-func NewBaseLaneConfig(
- logger log.Logger,
- txEncoder sdk.TxEncoder,
- txDecoder sdk.TxDecoder,
- anteHandler sdk.AnteHandler,
- maxBlockSpace math.LegacyDec,
-) LaneConfig {
- return LaneConfig{
- Logger: logger,
- TxEncoder: txEncoder,
- TxDecoder: txDecoder,
- AnteHandler: anteHandler,
- MaxBlockSpace: maxBlockSpace,
- }
-}
-
-// ValidateBasic validates the lane configuration.
-func (c *LaneConfig) ValidateBasic() error {
- if c.Logger == nil {
- return fmt.Errorf("logger cannot be nil")
- }
-
- if c.TxEncoder == nil {
- return fmt.Errorf("tx encoder cannot be nil")
- }
-
- if c.TxDecoder == nil {
- return fmt.Errorf("tx decoder 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")
- }
-
- return nil
-}
-
// NoOpPrepareLanesHandler returns a no-op prepare lanes handler.
// This should only be used for testing.
func NoOpPrepareLanesHandler() PrepareLanesHandler {
diff --git a/blockbuster/utils/ante.go b/block/utils/ante.go
similarity index 100%
rename from blockbuster/utils/ante.go
rename to block/utils/ante.go
diff --git a/blockbuster/utils/mocks/lane.go b/block/utils/mocks/lane.go
similarity index 80%
rename from blockbuster/utils/mocks/lane.go
rename to block/utils/mocks/lane.go
index 16faa82..3473e56 100644
--- a/blockbuster/utils/mocks/lane.go
+++ b/block/utils/mocks/lane.go
@@ -5,7 +5,7 @@ package mocks
import (
context "context"
- blockbuster "github.com/skip-mev/pob/blockbuster"
+ block "github.com/skip-mev/pob/block"
log "cosmossdk.io/log"
@@ -152,23 +152,23 @@ func (_m *Lane) Name() string {
}
// PrepareLane provides a mock function with given fields: ctx, proposal, maxTxBytes, next
-func (_m *Lane) PrepareLane(ctx types.Context, proposal blockbuster.BlockProposal, maxTxBytes int64, next blockbuster.PrepareLanesHandler) (blockbuster.BlockProposal, error) {
+func (_m *Lane) PrepareLane(ctx types.Context, proposal block.BlockProposal, maxTxBytes int64, next block.PrepareLanesHandler) (block.BlockProposal, error) {
ret := _m.Called(ctx, proposal, maxTxBytes, next)
- var r0 blockbuster.BlockProposal
+ var r0 block.BlockProposal
var r1 error
- if rf, ok := ret.Get(0).(func(types.Context, blockbuster.BlockProposal, int64, blockbuster.PrepareLanesHandler) (blockbuster.BlockProposal, error)); ok {
+ if rf, ok := ret.Get(0).(func(types.Context, block.BlockProposal, int64, block.PrepareLanesHandler) (block.BlockProposal, error)); ok {
return rf(ctx, proposal, maxTxBytes, next)
}
- if rf, ok := ret.Get(0).(func(types.Context, blockbuster.BlockProposal, int64, blockbuster.PrepareLanesHandler) blockbuster.BlockProposal); ok {
+ if rf, ok := ret.Get(0).(func(types.Context, block.BlockProposal, int64, block.PrepareLanesHandler) block.BlockProposal); ok {
r0 = rf(ctx, proposal, maxTxBytes, next)
} else {
if ret.Get(0) != nil {
- r0 = ret.Get(0).(blockbuster.BlockProposal)
+ r0 = ret.Get(0).(block.BlockProposal)
}
}
- if rf, ok := ret.Get(1).(func(types.Context, blockbuster.BlockProposal, int64, blockbuster.PrepareLanesHandler) error); ok {
+ if rf, ok := ret.Get(1).(func(types.Context, block.BlockProposal, int64, block.PrepareLanesHandler) error); ok {
r1 = rf(ctx, proposal, maxTxBytes, next)
} else {
r1 = ret.Error(1)
@@ -178,21 +178,21 @@ func (_m *Lane) PrepareLane(ctx types.Context, proposal blockbuster.BlockProposa
}
// ProcessLane provides a mock function with given fields: ctx, proposalTxs, next
-func (_m *Lane) ProcessLane(ctx types.Context, proposalTxs []types.Tx, next blockbuster.ProcessLanesHandler) (types.Context, error) {
+func (_m *Lane) ProcessLane(ctx types.Context, proposalTxs []types.Tx, next block.ProcessLanesHandler) (types.Context, error) {
ret := _m.Called(ctx, proposalTxs, next)
var r0 types.Context
var r1 error
- if rf, ok := ret.Get(0).(func(types.Context, []types.Tx, blockbuster.ProcessLanesHandler) (types.Context, error)); ok {
+ if rf, ok := ret.Get(0).(func(types.Context, []types.Tx, block.ProcessLanesHandler) (types.Context, error)); ok {
return rf(ctx, proposalTxs, next)
}
- if rf, ok := ret.Get(0).(func(types.Context, []types.Tx, blockbuster.ProcessLanesHandler) types.Context); ok {
+ if rf, ok := ret.Get(0).(func(types.Context, []types.Tx, block.ProcessLanesHandler) types.Context); ok {
r0 = rf(ctx, proposalTxs, next)
} else {
r0 = ret.Get(0).(types.Context)
}
- if rf, ok := ret.Get(1).(func(types.Context, []types.Tx, blockbuster.ProcessLanesHandler) error); ok {
+ if rf, ok := ret.Get(1).(func(types.Context, []types.Tx, block.ProcessLanesHandler) error); ok {
r1 = rf(ctx, proposalTxs, next)
} else {
r1 = ret.Error(1)
@@ -237,7 +237,7 @@ func (_m *Lane) SetAnteHandler(antehander types.AnteHandler) {
}
// SetIgnoreList provides a mock function with given fields: ignoreList
-func (_m *Lane) SetIgnoreList(ignoreList []blockbuster.Lane) {
+func (_m *Lane) SetIgnoreList(ignoreList []block.Lane) {
_m.Called(ignoreList)
}
diff --git a/blockbuster/utils/mocks/lane_mempool.go b/block/utils/mocks/lane_mempool.go
similarity index 100%
rename from blockbuster/utils/mocks/lane_mempool.go
rename to block/utils/mocks/lane_mempool.go
diff --git a/blockbuster/utils/utils.go b/block/utils/utils.go
similarity index 100%
rename from blockbuster/utils/utils.go
rename to block/utils/utils.go
diff --git a/blockbuster/utils/utils_test.go b/block/utils/utils_test.go
similarity index 96%
rename from blockbuster/utils/utils_test.go
rename to block/utils/utils_test.go
index e0b47e3..eb33706 100644
--- a/blockbuster/utils/utils_test.go
+++ b/block/utils/utils_test.go
@@ -4,7 +4,7 @@ import (
"testing"
"cosmossdk.io/math"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block/utils"
)
func TestGetMaxTxBytesForLane(t *testing.T) {
diff --git a/blockbuster/README.md b/blockbuster/README.md
deleted file mode 100644
index ff80dcf..0000000
--- a/blockbuster/README.md
+++ /dev/null
@@ -1,355 +0,0 @@
-# BlockBuster
-
-> π BlockBuster is an app-side mempool + set of proposal handlers that allows
-developers to configure modular lanes of transactions in their blocks with
-distinct validation/ordering logic. **BlockBuster is the ultimate highway
-system for transactions.**
-
-## High Level Overview
-
-**`BlockBuster`** is a framework for creating modular, application specific
-mempools by **separating transactions into βlanesβ with custom transaction handling.**
-
-You can think of BlockBuster as a **transaction highway system**, where each
-lane on the highway serves a specific purpose and has its own set of rules and
-traffic flow.
-
-Similarly, **BlockBuster** redefines block-space into **`lanes`** - where each
-`lane` has its own set of rules and transaction flow management systems.
-
-* A lane is what we might traditionally consider to be a standard mempool
-where transaction ***validation***, ***ordering*** and ***prioritization*** for
-contained transactions are shared.
-* Lanes implement a **standard interface** that allows each individual lane to
-propose and validate a portion of a block.
-* Lanes are ordered with each other, configurable by developers. All lanes
-together define the desired block structure of a chain.
-
-## BlockBuster Use Cases
-
-A mempool with separate `lanes` can be used for:
-
-1. **MEV mitigation**: a top of block lane could be designed to create an
-in-protocol top-of-block auction (as we are doing with POB) to recapture MEV
-in a transparent and governable way.
-2. **Free/reduced fee txs**: transactions with certain properties (e.g.
-from trusted accounts or performing encouraged actions) could leverage a
-free lane to reward behavior.
-3. **Dedicated oracle space** Oracles could be included before other kinds
-of transactions to ensure that price updates occur first, and are not able
-to be sandwiched or manipulated.
-4. **Orderflow auctions**: an OFA lane could be constructed such that order
-flow providers can have their submitted transactions bundled with specific
-backrunners, to guarantee MEV rewards are attributed back to users.
-Imagine MEV-share but in protocol.
-5. **Enhanced and customizable privacy**: privacy-enhancing features could
-be introduced, such as threshold encrypted lanes, to protect user data and
- maintain privacy for specific use cases.
-6. **Fee market improvements**: one or many fee markets - such as EIP-1559 -
-could be easily adopted for different lanes (potentially custom for certain
-dApps). Each smart contract/exchange could have its own fee market or auction
-for transaction ordering.
-7. **Congestion management**: segmentation of transactions to lanes can help
-mitigate network congestion by capping usage of certain applications and
-tailoring fee markets.
-
-## BlockBuster Design
-
-BlockBuster is a mempool composed of sub-mempools called **lanes**. All
-lanes together define the transaction highway system and BlockBuster mempool.
-When instantiating the BlockBuster mempool, developers will define all of the
-desired lanes and their configurations (including lane ordering).
-
-Utilizing BlockBuster is a simple three step process:
-
-* Determine the lanes desired. Currently, POB supports three different
-implementations of lanes: top of block lane, free lane, and a default lane.
- 1. Top of block lane allows the top of every block to be auctioned off
- and constructed using logic defined by the `x/builder` module.
- 2. Free lane allows base app to not charge certain types of transactions
- any fees. For example, delegations and/or re-delegations might be charged no
- fees. What qualifies as a free transaction is determined
- [here](https://github.com/skip-mev/pob/blob/main/blockbuster/lanes/free/factory.go).
- 3. Default lane accepts all other transactions and is considered to be
- analogous to how mempools and proposals are constructed today.
-* Instantiate the mempool in base app.
-
-```go
-mempool := blockbuster.NewMempool(lanes...)
-app.App.SetMempool(mempool)
-```
-
-* Instantiate the BlockBuster proposal handlers in base app.
-
-```go
-proposalHandlers := abci.NewProposalHandler(
- app.Logger(),
- app.txConfig.TxDecoder(),
- mempool, // BlockBuster mempool
-)
-app.App.SetPrepareProposal(proposalHandlers.PrepareProposalHandler())
-app.App.SetProcessProposal(proposalHandlers.ProcessProposalHandler())
-```
-
-***Note: BlockBuster should configure a `DefaultLane` that accepts transactions
-that do not belong to any other lane.***
-
-Transactions are inserted into the first lane that the transaction matches to.
-This means that a given transaction should really only belong to one lane
-(but this isnβt enforced).
-
-### Proposals
-
-The ordering of lanes when initializing BlockBuster in base app will determine
-the ordering of how proposals are built. For example, say that we instantiate
-three lanes:
-
-1. Top of block lane
-2. Free lane
-3. Default lane
-
-#### Preparing Proposals
-
-When the current proposer starts building a block, it will first populate the
-proposal with transactions from the top of block lane, followed by free and
-default lane. Each lane proposes its own set of transactions using the laneβs
-`PrepareLane` (analogous to `PrepareProposal`). Each lane has a limit on the
-relative percentage of total block space that the lane can consume.
-For example, the free lane might be configured to only make up 10% of any
-block. This is defined on each laneβs `Config` when it is instantiated.
-
-In the case when any lane fails to propose its portion of the block, it will
-be skipped and the next lane in the set of lanes will propose its portion of
-the block. Failures of partial block proposals are independent of one another.
-
-#### Processing Proposals
-
-Block proposals are validated iteratively following the exact ordering of lanes
-defined on base app. Transactions included in block proposals must respect the
-ordering of lanes. Any proposal that includes transactions that are out of
-order relative to the ordering of lanes will be rejected. Following the
-example defined above, if a proposal contains the following transactions:
-
-1. Default transaction (belonging to the default lane)
-2. Top of block transaction (belonging to the top of block lane)
-3. Free transaction (belonging to the free lane)
-
-It will be rejected because it does not respect the lane ordering.
-
-The BlockBuster `ProcessProposalHandler` processes the proposal by verifying
-all transactions in the proposal according to each lane's verification logic
-in a greedy fashion. If a lane's portion of the proposal is invalid, we
-reject the proposal. After a lane's portion of the proposal is verified, we
-pass the remaining transactions to the next lane in the chain.
-
-#### Coming Soon
-
-BlockBuster will have its own dedicated gRPC service for searchers, wallets,
-and users that allows them to query what lane their transaction might belong
-in, what fees they might have to pay for a given transaction, and the general
-state of the BlockBuster mempool.
-
-### Lanes
-
-Each lane will define its own:
-
-1. Unique prioritization/ordering mechanism i.e. how will transactions from a
-given lane be ordered in a block / mempool.
-2. Inclusion function to determine what types of transactions belong in the lane.
-3. Unique block building/verification mechanism.
-
-The general interface that each lane must implement can be found [here](https://github.com/skip-mev/pob/blob/main/blockbuster/lane.go):
-
-```go
-// Lane defines an interface used for block construction
-Lane interface {
- sdkmempool.Mempool
-
- // Name returns the name of the lane.
- Name() string
-
- // Match determines if a transaction belongs to this lane.
- Match(ctx sdk.Context, tx sdk.Tx) bool
-
- // VerifyTx verifies the transaction belonging to this lane.
- VerifyTx(ctx sdk.Context, tx sdk.Tx) error
-
- // Contains returns true if the mempool/lane contains the given transaction.
- Contains(tx sdk.Tx) bool
-
- // PrepareLane builds a portion of the block. It inputs the maxTxBytes that
- // can be included in the proposal for the given lane, the partial proposal,
- // and a function to call the next lane in the chain. The next lane in the
- // chain will be called with the updated proposal and context.
- PrepareLane(
- ctx sdk.Context,
- proposal BlockProposal,
- maxTxBytes int64,
- next PrepareLanesHandler
- ) (BlockProposal, error)
-
- // ProcessLaneBasic validates that transactions belonging to this lane
- // are not misplaced in the block proposal.
- ProcessLaneBasic(ctx sdk.Context, txs []sdk.Tx) error
-
- // ProcessLane verifies this lane's portion of a proposed block. It inputs
- // the transactions that may belong to this lane and a function to call the
- // next lane in the chain. The next lane in the chain will be called with
- // the updated context and filtered down transactions.
- ProcessLane(
- ctx sdk.Context,
- proposalTxs []sdk.Tx,
- next ProcessLanesHandler,
- ) (sdk.Context, error)
-
- // SetAnteHandler sets the lane's antehandler.
- SetAnteHandler(antehander sdk.AnteHandler)
-
- // Logger returns the lane's logger.
- Logger() log.Logger
-
- // GetMaxBlockSpace returns the max block space for the lane as a relative percentage.
- GetMaxBlockSpace() math.LegacyDec
-}
-```
-
-### 1. Intra-lane Transaction Ordering
-
-**Note: Lanes must implement the `sdk.Mempool` interface.**
-
-Transactions within a lane are ordered in a proposal respecting the ordering
-defined on the laneβs mempool. Developers can define their own custom ordering
-by implementing a custom `TxPriority` struct that allows the laneβs mempool to
-determine the priority of a transaction `GetTxPriority` and relatively order
-two transactions given the priority `Compare`. The top of block lane includes
-an custom `TxPriority` that orders transactions in the mempool based on their
-bid.
-
-```go
-func TxPriority(config Factory) blockbuster.TxPriority[string] {
- return blockbuster.TxPriority[string]{
- GetTxPriority: func(goCtx context.Context, tx sdk.Tx) string {
- bidInfo, err := config.GetAuctionBidInfo(tx)
- if err != nil {
- panic(err)
- }
-
- return bidInfo.Bid.String()
- },
- Compare: func(a, b string) int {
- aCoins, _ := sdk.ParseCoinsNormalized(a)
- bCoins, _ := sdk.ParseCoinsNormalized(b)
-
- switch {
- case aCoins == nil && bCoins == nil:
- return 0
-
- case aCoins == nil:
- return -1
-
- case bCoins == nil:
- return 1
-
- default:
- switch {
- case aCoins.IsAllGT(bCoins):
- return 1
-
- case aCoins.IsAllLT(bCoins):
- return -1
-
- default:
- return 0
- }
- }
- },
- MinValue: "",
- }
-}
-
-// NewMempool returns a new auction mempool.
-func NewMempool(txEncoder sdk.TxEncoder, maxTx int, config Factory) *TOBMempool {
- return &TOBMempool{
- index: blockbuster.NewPriorityMempool(
- blockbuster.PriorityNonceMempoolConfig[string]{
- TxPriority: TxPriority(config),
- MaxTx: maxTx,
- },
- ),
- txEncoder: txEncoder,
- txIndex: make(map[string]struct{}),
- Factory: config,
- }
-}
-```
-
-### 2. [Optional] Transaction Information Retrieval
-
-Each lane can define a factory that configures the necessary set of interfaces
-required for transaction processing, ordering, and validation. Lanes are
-designed such that any given chain can adopt upstream `POB` lanes as long as
-developers implement the specified interface(s) associated with transaction
-information retrieval for that lane.
-
-***A standard cosmos chain or EVM chain can then implement their own versions
-of these interfaces and automatically utilize the lane with no changes upstream!***
-
-For example, the free lane defines an `Factory` that includes a single
-`IsFreeTx` function that allows developers to configure what is a free
-transaction. The default implementation categorizes free transactions as any
-transaction that includes a delegate type message.
-
-```go
-// IsFreeTx defines a default function that checks if a transaction is free. In
-// this case, any transaction that is a delegation/redelegation transaction is free.
-func (config *DefaultFreeFactory) IsFreeTx(tx sdk.Tx) bool {
- for _, msg := range tx.GetMsgs() {
- switch msg.(type) {
- case *types.MsgDelegate:
- return true
- case *types.MsgBeginRedelegate:
- return true
- case *types.MsgCancelUnbondingDelegation:
- return true
- }
- }
-
- return false
-}
-```
-
-### 3. Lane Inclusion Functionality
-
-Lanes must implement a `Match` interface which determines whether a transaction
-should be considered for a given lane. Developerβs are encouraged to utilize the
- same interfaces defined in the `Factory` to match transactions to lanes. For
- example, developers might configure a top of block auction lane to accept
- transactions if they contain a single `MsgAuctionBid` message in the transaction.
-
-### 4.1. [Optional] Transaction Validation
-
-Transactions will be verified the laneβs `VerifyTx` function. This logic can be
-completely arbitrary. For example, the default lane verifies transactions
-using base appβs `AnteHandler` while the top of block lane verifies transactions
-by extracting all bundled transactions included in the bid transaction and then
-verifying the transaction iteratively given the bundle.
-
-### 4.2. Block Building/Verification Logic
-
-Each lane will implement block building and verification logic - analogous to
-`Prepare` and `Process` proposal - that is unique to itself.
-
-* `PrepareLane` will be in charge of building a partial block given the
-transactions in the lane.
-* `ProcessLaneBasic` ensures that transactions that should be included in the
-current lane are not interleaved with other lanes i.e. transactions in
-proposals are ordered respecting the ordering of lanes.
-* `ProcessLane` will be in charge of verifying the laneβs partial block.
-
-### Inheritance
-
-Lanes can inherit the underlying implementation of other lanes and overwrite
-any part of the implementation with their own custom functionality. We
-recommend that userβs extend the functionality of the `Base` lane when first
-exploring the code base.
-
diff --git a/go.work.sum b/go.work.sum
index 8109fb3..1b6fa7d 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -1,14 +1,214 @@
+4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs=
+4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU=
+cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=
+github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA=
+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
+github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0=
+github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
+github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
+github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
+github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
+github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg=
+github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
+github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
+github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
+github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI=
+github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
+github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
+github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
+github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
+github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
+github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
+github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo=
+github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s=
+github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U=
+github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
+github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
+github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
+github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ=
+github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo=
+github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
+github.com/cloudflare/circl v1.3.1/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw=
github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8=
github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ=
+github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cosmos/cosmos-db v0.0.0-20221226095112-f3c38ecb5e32 h1:zlCp9n3uwQieELltZWHRmwPmPaZ8+XoL2Sj+A2YJlr8=
+github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc=
+github.com/daixiang0/gci v0.10.1/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI=
+github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c=
+github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY=
+github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
+github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0=
+github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY=
+github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
+github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
+github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
+github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
+github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
+github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI=
+github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/getsentry/sentry-go v0.17.0 h1:UustVWnOoDFHBS7IJUB2QK/nB5pap748ZEp0swnQJak=
+github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
+github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
+github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
+github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
+github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw=
+github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=
+github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=
+github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=
+github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
+github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
+github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
+github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
+github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
+github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
+github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
+github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ=
+github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs=
+github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
+github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
+github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc=
+github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs=
+github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
+github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
+github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
+github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=
+github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
+github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
+github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
+github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
+github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
+github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
+github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
+github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
+github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
+github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
+github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg=
+github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=
+github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes=
+github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA=
+github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0=
+github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
+github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY=
+github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM=
+github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
+github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc=
+github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
+github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
+github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
+github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
+github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY=
+github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g=
+github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
+github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
+github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
+github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
+github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
+github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE=
+github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
+github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
+github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
+github.com/quasilyte/go-ruleguard v0.3.19/go.mod h1:lHSn69Scl48I7Gt9cX3VrbsZYvYiBYszZOZW4A+oTEw=
+github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=
+github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
+github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
+github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50=
+github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ=
+github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
+github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
+github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
+github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw=
+github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY=
+github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
+github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag=
+github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4=
+github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo=
+github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
+github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
+github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I=
+github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
+github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk=
+github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg=
+github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
+github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8=
+github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg=
+github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
+github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
+github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
+github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
+github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
+github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
+github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
+github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=
+github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA=
+gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
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/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
+go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
+golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
+gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA=
+mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ=
+mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
+mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
+mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is=
diff --git a/lanes/base/README.md b/lanes/base/README.md
new file mode 100644
index 0000000..4f80073
--- /dev/null
+++ b/lanes/base/README.md
@@ -0,0 +1,111 @@
+# ποΈ Default Lane Setup
+
+## π¦ Dependencies
+
+The Block SDK is built on top of the Cosmos SDK. The Block SDK is currently
+compatible with Cosmos SDK versions greater than or equal to `v0.47.0`.
+
+## π₯ Installation
+
+To install the Block SDK, run the following command:
+
+```bash
+$ go install github.com/skip-mev/block-sdk
+```
+
+## π Usage
+
+1. First determine the set of lanes that you want to use in your application. The
+available lanes can be found in our
+[Lane App Store](https://docs.skip.money/chains/lanes/existing-lanes/default).
+This guide only sets up the `default lane`
+2. In your base application, you will need to create a `LanedMempool` composed
+of the `lanes` you want to use.
+3. Next, order the lanes by priority. The first lane is the highest priority lane
+and the last lane is the lowest priority lane. **It is recommended that the last
+lane is the default lane.**
+4. You will also need to create a `PrepareProposalHandler` and a
+`ProcessProposalHandler` that will be responsible for preparing and processing
+proposals respectively. Configure the order of the lanes in the
+`PrepareProposalHandler` and `ProcessProposalHandler` to match the order of the
+lanes in the `LanedMempool`.
+5. Configure your `app.go` to include the following:
+
+```golang
+import (
+ "github.com/skip-mev/block-sdk/abci"
+ "github.com/skip-mev/block-sdk/block/base"
+ defaultlane "github.com/skip-mev/block-sdk/lanes/base"
+)
+
+...
+
+func NewApp() {
+ ...
+ // 1. Create the lanes.
+ //
+ // NOTE: The lanes are ordered by priority. The first lane is the highest priority
+ // lane and the last lane is the lowest priority lane. Top of block lane allows
+ // transactions to bid for inclusion at the top of the next block.
+ //
+ // For more information on how to utilize the LaneConfig please
+ // visit the README in docs.skip.money/chains/lanes/build-your-own-lane#-lane-config.
+ //
+ // Default lane accepts all transactions.
+ defaultConfig := base.LaneConfig{
+ Logger: app.Logger(),
+ TxEncoder: app.txConfig.TxEncoder(),
+ TxDecoder: app.txConfig.TxDecoder(),
+ MaxBlockSpace: math.LegacyZeroDec(),
+ MaxTxs: 0,
+ }
+ defaultLane := defaultlane.NewDefaultLane(defaultConfig)
+
+ // 2. Set up the relative priority of lanes
+ lanes := []block.Lane{
+ defaultLane,
+ }
+ mempool := block.NewLanedMempool(app.Logger(), true, lanes...)
+ app.App.SetMempool(mempool)
+
+ ...
+
+ // 3. Set up the ante handler.
+ anteDecorators := []sdk.AnteDecorator{
+ ante.NewSetUpContextDecorator(),
+ ...
+ utils.NewIgnoreDecorator(
+ ante.NewDeductFeeDecorator(
+ options.BaseOptions.AccountKeeper,
+ options.BaseOptions.BankKeeper,
+ options.BaseOptions.FeegrantKeeper,
+ options.BaseOptions.TxFeeChecker,
+ ),
+ options.FreeLane,
+ ),
+ ...
+ }
+
+ anteHandler := sdk.ChainAnteDecorators(anteDecorators...)
+
+ // Set the lane ante handlers on the lanes.
+ //
+ // NOTE: This step is very important. Without the antehandlers, lanes will not
+ // be able to verify transactions.
+ for _, lane := range lanes {
+ lane.SetAnteHandler(anteHandler)
+ }
+ app.App.SetAnteHandler(anteHandler)
+
+ // 4. Set the abci handlers on base app
+ proposalHandler := abci.NewProposalHandler(
+ app.Logger(),
+ app.TxConfig().TxDecoder(),
+ lanes,
+ )
+ app.App.SetPrepareProposal(proposalHandler.PrepareProposalHandler())
+ app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
+
+ ...
+}
+```
diff --git a/blockbuster/lanes/base/abci_test.go b/lanes/base/abci_test.go
similarity index 89%
rename from blockbuster/lanes/base/abci_test.go
rename to lanes/base/abci_test.go
index d5c054d..317df3b 100644
--- a/blockbuster/lanes/base/abci_test.go
+++ b/lanes/base/abci_test.go
@@ -8,9 +8,10 @@ import (
"cosmossdk.io/log"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/lanes/base"
- "github.com/skip-mev/pob/blockbuster/utils/mocks"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
+ "github.com/skip-mev/pob/block/utils/mocks"
+ defaultlane "github.com/skip-mev/pob/lanes/base"
testutils "github.com/skip-mev/pob/testutils"
)
@@ -41,7 +42,7 @@ func (s *BaseTestSuite) TestPrepareLane() {
// Create a proposal
maxTxBytes := int64(len(txBz) - 1)
- proposal, err := lane.PrepareLane(sdk.Context{}, blockbuster.NewProposal(maxTxBytes), maxTxBytes, blockbuster.NoOpPrepareLanesHandler())
+ proposal, err := lane.PrepareLane(sdk.Context{}, block.NewProposal(maxTxBytes), maxTxBytes, block.NoOpPrepareLanesHandler())
s.Require().NoError(err)
// Ensure the proposal is empty
@@ -75,7 +76,7 @@ func (s *BaseTestSuite) TestPrepareLane() {
// Create a proposal
maxTxBytes := int64(len(txBz))
- proposal, err := lane.PrepareLane(sdk.Context{}, blockbuster.NewProposal(maxTxBytes), maxTxBytes, blockbuster.NoOpPrepareLanesHandler())
+ proposal, err := lane.PrepareLane(sdk.Context{}, block.NewProposal(maxTxBytes), maxTxBytes, block.NoOpPrepareLanesHandler())
s.Require().Error(err)
// Ensure the proposal is empty
@@ -109,7 +110,7 @@ func (s *BaseTestSuite) TestPrepareLane() {
// Create a proposal
maxTxBytes := int64(len(txBz))
- proposal, err := lane.PrepareLane(sdk.Context{}, blockbuster.NewProposal(maxTxBytes), maxTxBytes, blockbuster.NoOpPrepareLanesHandler())
+ proposal, err := lane.PrepareLane(sdk.Context{}, block.NewProposal(maxTxBytes), maxTxBytes, block.NoOpPrepareLanesHandler())
s.Require().NoError(err)
// Ensure the proposal is not empty and contains the transaction
@@ -144,7 +145,7 @@ func (s *BaseTestSuite) TestPrepareLane() {
s.Require().NoError(err)
maxTxBytes := int64(len(txBz))
- proposal, err := lane.PrepareLane(sdk.Context{}, blockbuster.NewProposal(maxTxBytes), maxTxBytes, blockbuster.NoOpPrepareLanesHandler())
+ proposal, err := lane.PrepareLane(sdk.Context{}, block.NewProposal(maxTxBytes), maxTxBytes, block.NoOpPrepareLanesHandler())
s.Require().NoError(err)
// Ensure the proposal is empty
@@ -196,7 +197,7 @@ func (s *BaseTestSuite) TestPrepareLane() {
s.Require().NoError(err)
maxTxBytes := int64(len(txBz1)) + int64(len(txBz2))
- proposal, err := lane.PrepareLane(sdk.Context{}, blockbuster.NewProposal(maxTxBytes), maxTxBytes, blockbuster.NoOpPrepareLanesHandler())
+ proposal, err := lane.PrepareLane(sdk.Context{}, block.NewProposal(maxTxBytes), maxTxBytes, block.NoOpPrepareLanesHandler())
s.Require().NoError(err)
// Ensure the proposal is ordered correctly
@@ -245,7 +246,7 @@ func (s *BaseTestSuite) TestPrepareLane() {
s.Require().NoError(err)
maxTxBytes := int64(len(txBz1)) + int64(len(txBz2))
- proposal, err := lane.PrepareLane(sdk.Context{}, blockbuster.NewProposal(maxTxBytes), maxTxBytes, blockbuster.NoOpPrepareLanesHandler())
+ proposal, err := lane.PrepareLane(sdk.Context{}, block.NewProposal(maxTxBytes), maxTxBytes, block.NoOpPrepareLanesHandler())
s.Require().NoError(err)
// Ensure the proposal is ordered correctly
@@ -294,7 +295,7 @@ func (s *BaseTestSuite) TestPrepareLane() {
s.Require().NoError(err)
maxTxBytes := int64(len(txBz1)) + int64(len(txBz2)) - 1
- proposal, err := lane.PrepareLane(sdk.Context{}, blockbuster.NewProposal(maxTxBytes), maxTxBytes, blockbuster.NoOpPrepareLanesHandler())
+ proposal, err := lane.PrepareLane(sdk.Context{}, block.NewProposal(maxTxBytes), maxTxBytes, block.NoOpPrepareLanesHandler())
s.Require().NoError(err)
// Ensure the proposal is ordered correctly
@@ -323,7 +324,7 @@ func (s *BaseTestSuite) TestProcessLane() {
tx1: true,
})
- _, err = lane.ProcessLane(sdk.Context{}, proposal, blockbuster.NoOpProcessLanesHandler())
+ _, err = lane.ProcessLane(sdk.Context{}, proposal, block.NoOpProcessLanesHandler())
s.Require().NoError(err)
})
@@ -345,7 +346,7 @@ func (s *BaseTestSuite) TestProcessLane() {
tx1: false,
})
- _, err = lane.ProcessLane(sdk.Context{}, proposal, blockbuster.NoOpProcessLanesHandler())
+ _, err = lane.ProcessLane(sdk.Context{}, proposal, block.NoOpProcessLanesHandler())
s.Require().Error(err)
})
@@ -389,7 +390,7 @@ func (s *BaseTestSuite) TestProcessLane() {
tx3: true,
})
- _, err = lane.ProcessLane(sdk.Context{}, proposal, blockbuster.NoOpProcessLanesHandler())
+ _, err = lane.ProcessLane(sdk.Context{}, proposal, block.NoOpProcessLanesHandler())
s.Require().Error(err)
})
}
@@ -487,7 +488,7 @@ func (s *BaseTestSuite) TestCheckOrder() {
mocklane.On("Match", sdk.Context{}, tx2).Return(false)
lane := s.initLane(math.LegacyMustNewDecFromStr("1"), nil)
- lane.SetIgnoreList([]blockbuster.Lane{mocklane})
+ lane.SetIgnoreList([]block.Lane{mocklane})
proposal := []sdk.Tx{
tx1,
@@ -501,8 +502,8 @@ func (s *BaseTestSuite) TestCheckOrder() {
func (s *BaseTestSuite) initLane(
maxBlockSpace math.LegacyDec,
expectedExecution map[sdk.Tx]bool,
-) *base.DefaultLane {
- config := blockbuster.NewBaseLaneConfig(
+) *defaultlane.DefaultLane {
+ config := base.NewLaneConfig(
log.NewTestLogger(s.T()),
s.encodingConfig.TxConfig.TxEncoder(),
s.encodingConfig.TxConfig.TxDecoder(),
@@ -510,7 +511,7 @@ func (s *BaseTestSuite) initLane(
maxBlockSpace,
)
- return base.NewDefaultLane(config)
+ return defaultlane.NewDefaultLane(config)
}
func (s *BaseTestSuite) setUpAnteHandler(expectedExecution map[sdk.Tx]bool) sdk.AnteHandler {
diff --git a/blockbuster/lanes/base/base_test.go b/lanes/base/base_test.go
similarity index 100%
rename from blockbuster/lanes/base/base_test.go
rename to lanes/base/base_test.go
diff --git a/blockbuster/lanes/base/lane.go b/lanes/base/lane.go
similarity index 57%
rename from blockbuster/lanes/base/lane.go
rename to lanes/base/lane.go
index cb997ae..9842592 100644
--- a/blockbuster/lanes/base/lane.go
+++ b/lanes/base/lane.go
@@ -1,7 +1,8 @@
package base
import (
- "github.com/skip-mev/pob/blockbuster"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
)
const (
@@ -9,32 +10,32 @@ const (
LaneName = "default"
)
-var _ blockbuster.Lane = (*DefaultLane)(nil)
+var _ block.Lane = (*DefaultLane)(nil)
// DefaultLane defines a default lane implementation. The default lane orders
// transactions by the transaction fees. The default lane accepts any transaction
-// that is should not be ignored (as defined by the IgnoreList in the LaneConfig).
+// that should not be ignored (as defined by the IgnoreList in the LaneConfig).
// The default lane builds and verifies blocks in a similar fashion to how the
// CometBFT/Tendermint consensus engine builds and verifies blocks pre SDK version
// 0.47.0.
type DefaultLane struct {
- *blockbuster.LaneConstructor
+ *base.BaseLane
}
// NewDefaultLane returns a new default lane.
-func NewDefaultLane(cfg blockbuster.LaneConfig) *DefaultLane {
- lane := blockbuster.NewLaneConstructor(
+func NewDefaultLane(cfg base.LaneConfig) *DefaultLane {
+ lane := base.NewBaseLane(
cfg,
LaneName,
- blockbuster.NewConstructorMempool[string](
- blockbuster.DefaultTxPriority(),
+ base.NewMempool[string](
+ base.DefaultTxPriority(),
cfg.TxEncoder,
cfg.MaxTxs,
),
- blockbuster.DefaultMatchHandler(),
+ base.DefaultMatchHandler(),
)
return &DefaultLane{
- LaneConstructor: lane,
+ BaseLane: lane,
}
}
diff --git a/blockbuster/lanes/base/mempool_test.go b/lanes/base/mempool_test.go
similarity index 90%
rename from blockbuster/lanes/base/mempool_test.go
rename to lanes/base/mempool_test.go
index 4f12e73..b8a5047 100644
--- a/blockbuster/lanes/base/mempool_test.go
+++ b/lanes/base/mempool_test.go
@@ -3,12 +3,12 @@ package base_test
import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
+ "github.com/skip-mev/pob/block/base"
testutils "github.com/skip-mev/pob/testutils"
)
func (s *BaseTestSuite) TestGetTxPriority() {
- txPriority := blockbuster.DefaultTxPriority()
+ txPriority := base.DefaultTxPriority()
s.Run("should be able to get the priority off a normal transaction with fees", func() {
tx, err := testutils.CreateRandomTx(
@@ -56,7 +56,7 @@ func (s *BaseTestSuite) TestGetTxPriority() {
}
func (s *BaseTestSuite) TestCompareTxPriority() {
- txPriority := blockbuster.DefaultTxPriority()
+ txPriority := base.DefaultTxPriority()
s.Run("should return 0 when both priorities are nil", func() {
a := sdk.NewCoin(s.gasTokenDenom, math.NewInt(0)).String()
@@ -84,7 +84,7 @@ func (s *BaseTestSuite) TestCompareTxPriority() {
}
func (s *BaseTestSuite) TestInsert() {
- mempool := blockbuster.NewConstructorMempool[string](blockbuster.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
+ mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
s.Run("should be able to insert a transaction", func() {
tx, err := testutils.CreateRandomTx(
@@ -136,7 +136,7 @@ func (s *BaseTestSuite) TestInsert() {
}
func (s *BaseTestSuite) TestRemove() {
- mempool := blockbuster.NewConstructorMempool[string](blockbuster.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
+ mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
s.Run("should be able to remove a transaction", func() {
tx, err := testutils.CreateRandomTx(
@@ -174,7 +174,7 @@ func (s *BaseTestSuite) TestRemove() {
func (s *BaseTestSuite) TestSelect() {
s.Run("should be able to select transactions in the correct order", func() {
- mempool := blockbuster.NewConstructorMempool[string](blockbuster.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
+ mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
tx1, err := testutils.CreateRandomTx(
s.encodingConfig.TxConfig,
@@ -213,7 +213,7 @@ func (s *BaseTestSuite) TestSelect() {
})
s.Run("should be able to select a single transaction", func() {
- mempool := blockbuster.NewConstructorMempool[string](blockbuster.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
+ mempool := base.NewMempool[string](base.DefaultTxPriority(), s.encodingConfig.TxConfig.TxEncoder(), 3)
tx1, err := testutils.CreateRandomTx(
s.encodingConfig.TxConfig,
diff --git a/lanes/build-your-own/README.md b/lanes/build-your-own/README.md
new file mode 100644
index 0000000..f025adf
--- /dev/null
+++ b/lanes/build-your-own/README.md
@@ -0,0 +1,463 @@
+# ποΈ Build-Your-Own Lane Setup
+
+## π¦ Dependencies
+
+The Block SDK is built on top of the Cosmos SDK. The Block SDK is currently
+compatible with Cosmos SDK versions greater than or equal to `v0.47.0`.
+
+## π₯ Installation
+
+To install the Block SDK, run the following command:
+
+```bash
+$ go install github.com/skip-mev/block-sdk
+```
+
+## π€ How to use it [30 min]
+
+There are **five** required components to building a custom lane using the base lane:
+
+1. `Mempool` - The lane's mempool is responsible for storing transactions that
+have been verified and are waiting to be included in proposals.
+2. `MatchHandler` - This is responsible for determining whether a transaction
+should belong to this lane.
+3. [**OPTIONAL**] `PrepareLaneHandler` - Allows developers to define their own
+handler to customize the how transactions are verified and ordered before they
+are included into a proposal.
+4. [**OPTIONAL**] `CheckOrderHandler` - Allows developers to define their own
+handler that will run any custom checks on whether transactions included in
+block proposals are in the correct order (respecting the ordering rules of the
+lane and the ordering rules of the other lanes).
+5. [**OPTIONAL**] `ProcessLaneHandler` - Allows developers to define their own
+handler for processing transactions that are included in block proposals.
+6. `Configuration` - Configure high-level options for your lane.
+
+### 1. ποΈ Mempool
+
+This is the data structure that is responsible for storing transactions as they
+are being verified and are waiting to be included in proposals.
+`block/base/mempool.go` provides an out-of-the-box implementation that should be
+used as a starting point for building out the mempool and should cover most use
+cases. To utilize the mempool, you must implement a `TxPriority[C]` struct that
+does the following:
+
+* Implements a `GetTxPriority` method that returns the priority (as defined
+ by the type `[C]`) of a given transaction.
+* Implements a `Compare` method that returns the relative priority of two
+ transactions. If the first transaction has a higher priority, the method
+ should return -1, if the second transaction has a higher priority the method
+ should return 1, otherwise the method should return 0.
+* Implements a `MinValue` method that returns the minimum priority value
+ that a transaction can have.
+
+The default implementation can be found in `block/base/mempool.go`.
+
+> Scenario
+What if we wanted to prioritize transactions by the amount they have staked on
+a chain?
+
+We could do the following:
+
+```golang
+// CustomTxPriority returns a TxPriority that prioritizes transactions by the
+// amount they have staked on chain. This means that transactions with a higher
+// amount staked will be prioritized over transactions with a lower amount staked.
+func (p *CustomTxPriority) CustomTxPriority() TxPriority[string] {
+ return TxPriority[string]{
+ GetTxPriority: func(ctx context.Context, tx sdk.Tx) string {
+ // Get the signer of the transaction.
+ signer := p.getTransactionSigner(tx)
+
+ // Get the total amount staked by the signer on chain.
+ // This is abstracted away in the example, but you can
+ // implement this using the staking keeper.
+ totalStake, err := p.getTotalStake(ctx, signer)
+ if err != nil {
+ return ""
+ }
+
+ return totalStake.String()
+ },
+ Compare: func(a, b string) int {
+ aCoins, _ := sdk.ParseCoinsNormalized(a)
+ bCoins, _ := sdk.ParseCoinsNormalized(b)
+
+ switch {
+ case aCoins == nil && bCoins == nil:
+ return 0
+
+ case aCoins == nil:
+ return -1
+
+ case bCoins == nil:
+ return 1
+
+ default:
+ switch {
+ case aCoins.IsAllGT(bCoins):
+ return 1
+
+ case aCoins.IsAllLT(bCoins):
+ return -1
+
+ default:
+ return 0
+ }
+ }
+ },
+ MinValue: "",
+ }
+}
+```
+
+#### Using a Custom TxPriority
+
+To utilize this new priority configuration in a lane, all you have to then do
+is pass in the `TxPriority[C]` to the `NewMempool` function.
+
+```golang
+// Create the lane config
+laneCfg := NewLaneConfig(
+ ...
+ MaxTxs: 100,
+ ...
+)
+
+// Pseudocode for creating the custom tx priority
+priorityCfg := NewPriorityConfig(
+ stakingKeeper,
+ accountKeeper,
+ ...
+)
+
+
+// define your mempool that orders transactions by on-chain stake
+mempool := base.NewMempool[string](
+ priorityCfg.CustomTxPriority(), // pass in the custom tx priority
+ laneCfg.TxEncoder,
+ laneCfg.MaxTxs,
+)
+
+// Initialize your lane with the mempool
+lane := base.NewBaseLane(
+ laneCfg,
+ LaneName,
+ mempool,
+ base.DefaultMatchHandler(),
+)
+```
+
+### 2. π€ MatchHandler
+
+`MatchHandler` is utilized to determine if a transaction should be included in
+the lane. **This function can be a stateless or stateful check on the
+transaction!** The default implementation can be found in `block/base/handlers.go`.
+
+The match handler can be as custom as desired. Following the example above, if
+we wanted to make a lane that only accepts transactions if they have a large
+amount staked, we could do the following:
+
+```golang
+// CustomMatchHandler returns a custom implementation of the MatchHandler. It
+// matches transactions that have a large amount staked. These transactions
+// will then be charged no fees at execution time.
+//
+// NOTE: This is a stateful check on the transaction. The details of how to
+// implement this are abstracted away in the example, but you can implement
+// this using the staking keeper.
+func (h *Handler) CustomMatchHandler() block.MatchHandler {
+ return func(ctx sdk.Context, tx sdk.Tx) bool {
+ if !h.IsStakingTx(tx) {
+ return false
+ }
+
+ signer, err := getTxSigner(tx)
+ if err != nil {
+ return false
+ }
+
+ stakedAmount, err := h.GetStakedAmount(signer)
+ if err != nil {
+ return false
+ }
+
+ // The transaction can only be considered for inclusion if the amount
+ // staked is greater than some predetermined threshold.
+ return stakeAmount.GT(h.Threshold)
+ }
+}
+```
+
+#### Using a Custom MatchHandler
+
+If we wanted to create the lane using the custom match handler along with the
+custom mempool, we could do the following:
+
+```golang
+// Pseudocode for creating the custom match handler
+handler := NewHandler(
+ stakingKeeper,
+ accountKeeper,
+ ...
+)
+
+// define your mempool that orders transactions by on chain stake
+mempool := base.NewMempool[string](
+ priorityCfg.CustomTxPriority(),
+ cfg.TxEncoder,
+ cfg.MaxTxs,
+)
+
+// Initialize your lane with the mempool
+lane := base.NewBaseLane(
+ cfg,
+ LaneName,
+ mempool,
+ handler.CustomMatchHandler(),
+)
+```
+
+### [OPTIONAL] Steps 3-5
+
+The remaining steps walk through the process of creating custom block
+building/verification logic. The default implementation found in
+`block/base/handlers.go` should fit most use cases. Please reference that file
+for more details on the default implementation and whether it fits your use case.
+
+Implementing custom block building/verification logic is a bit more involved
+than the previous steps and is a all or nothing approach. This means that if
+you implement any of the handlers, you must implement all of them in most cases.
+ If you do not implement all of them, the lane may have unintended behavior.
+
+### 3. π οΈ PrepareLaneHandler
+
+The `PrepareLaneHandler` is an optional field you can set on the base lane.
+This handler is responsible for the transaction selection logic when a new proposal
+is requested.
+
+The handler should return the following for a given lane:
+
+1. The transactions to be included in the block proposal.
+2. The transactions to be removed from the lane's mempool.
+3. An error if the lane is unable to prepare a block proposal.
+
+```golang
+// PrepareLaneHandler is responsible for preparing transactions to be included
+// in the block from a given lane. Given a lane, this function should return
+// the transactions to include in the block, the transactions that must be
+// removed from the lane, and an error if one occurred.
+PrepareLaneHandler func(ctx sdk.Context,proposal BlockProposal,maxTxBytes int64)
+ (txsToInclude [][]byte, txsToRemove []sdk.Tx, err error)
+```
+
+The default implementation is simple. It will continue to select transactions
+from its mempool under the following criteria:
+
+1. The transactions is not already included in the block proposal.
+2. The transaction is valid and passes the AnteHandler check.
+3. The transaction is not too large to be included in the block.
+
+If a more involved selection process is required, you can implement your own
+`PrepareLaneHandler` and and set it after creating the base lane.
+
+```golang
+// Pseudocode for creating the custom prepare lane handler
+// This assumes that the CustomLane inherits from the base
+// lane.
+customLane := NewCustomLane(
+ cfg,
+ mempool,
+ handler.CustomMatchHandler(),
+)
+
+// Set the custom PrepareLaneHandler on the lane
+customLane.SetPrepareLaneHandler(customlane.PrepareLaneHandler())
+```
+
+### 4. β
CheckOrderHandler
+
+The `CheckOrderHandler` is an optional field you can set on the base lane.
+This handler is responsible for verifying the ordering of the transactions in
+the block proposal that belong to the lane.
+
+```golang
+// CheckOrderHandler is responsible for checking the order of transactions that
+// belong to a given lane. This handler should be used to verify that the
+// ordering of transactions passed into the function respect the ordering logic
+// of the lane (if any transactions from the lane are included). This function
+// should also ensure that transactions that belong to this lane are contiguous
+// and do not have any transactions from other lanes in between them.
+CheckOrderHandler func(ctx sdk.Context, txs []sdk.Tx) error
+```
+
+The default implementation is simple and utilizes the same `TxPriority` struct
+that the mempool uses to determine if transactions are in order. The criteria
+for determining if transactions are in order is as follows:
+
+1. The transactions are in order according to the `TxPriority` struct. i.e.
+any two transactions (that match to the lane) `tx1` and `tx2` where `tx1` has a
+higher priority than `tx2` should be ordered before `tx2`.
+2. The transactions are contiguous. i.e. there are no transactions from other
+lanes in between the transactions that belong to this lane. i.e. if `tx1` and
+`tx2` belong to the lane, there should be no transactions from other lanes in
+between `tx1` and `tx2`.
+
+If a more involved ordering process is required, you can implement your own
+`CheckOrderHandler` and and set it after creating the base lane.
+
+```golang
+// Pseudocode for creating the custom check order handler
+// This assumes that the CustomLane inherits from the base
+// lane.
+customLane := NewCustomLane(
+ cfg,
+ mempool,
+ handler.CustomMatchHandler(),
+)
+
+// Set the custom CheckOrderHandler on the lane
+customLane.SetCheckOrderHandler(customlane.CheckOrderHandler())
+```
+
+### 5. π ProcessLaneHandler
+
+The `ProcessLaneHandler` is an optional field you can set on the base lane.
+This handler is responsible for verifying the transactions in the block proposal
+that belong to the lane. This handler is executed after the `CheckOrderHandler`
+so the transactions passed into this function SHOULD already be in order
+respecting the ordering rules of the lane and respecting the ordering rules of
+mempool relative to the lanes it has. This means that if the first transaction
+does not belong to the lane, the remaining transactions should not belong to
+the lane either.
+
+```golang
+// ProcessLaneHandler is responsible for processing transactions that are
+// included in a block and belong to a given lane. ProcessLaneHandler is
+// executed after CheckOrderHandler so the transactions passed into this
+// function SHOULD already be in order respecting the ordering rules of the
+// lane and respecting the ordering rules of mempool relative to the lanes it has.
+ProcessLaneHandler func(ctx sdk.Context, txs []sdk.Tx) ([]sdk.Tx, error)
+```
+
+Given the invarients above, the default implementation is simple. It will
+continue to verify transactions in the block proposal under the following criteria:
+
+1. If a transaction matches to this lane, verify it and continue. If it is not
+valid, return an error.
+2. If a transaction does not match to this lane, return the remaining
+transactions to the next lane to process.
+
+Similar to the setup of handlers above, if a more involved verification process
+is required, you can implement your own `ProcessLaneHandler` and and set it
+after creating the base lane.
+
+```golang
+// Pseudocode for creating the custom check order handler
+// This assumes that the CustomLane inherits from the base
+// lane.
+customLane := NewCustomLane(
+ cfg,
+ mempool,
+ handler.CustomMatchHandler(),
+)
+
+// Set the custom ProcessLaneHandler on the lane
+customLane.SetProcessLaneHandler(customlane.ProcessLaneHandler())
+```
+
+### 6. π Lane Configuration
+
+Once you have created your custom lane, you can configure it in the application
+by doing the following:
+
+1. Create a custom `LaneConfig` struct that defines the configuration of the lane.
+2. Instantiate the lane with the custom `LaneConfig` struct alongside any other
+dependencies (mempool, match handler, etc.).
+3. Instantiate a new `LanedMempool` with the custom lane.
+4. Set the `LanedMempool` on the `BaseApp` instance.
+5. Set up the proposal handlers of the Block SDK to use your lane.
+6. That's it! You're done!
+
+The lane config (`LaneConfig`) is a simple configuration object that defines
+the desired amount of block space the lane should utilize when building a
+proposal, an antehandler that is used to verify transactions as they are
+added/verified to/in a proposal, and more. By default, we recommend that user's
+pass in all of the base apps configurations (txDecoder, logger, etc.). A sample
+`LaneConfig` might look like the following:
+
+```golang
+config := block.LaneConfig{
+ Logger: app.Logger(),
+ TxDecoder: app.TxDecoder(),
+ TxEncoder: app.TxEncoder(),
+ AnteHandler: app.AnteHandler(),
+ MaxTxs: 0,
+ MaxBlockSpace: math.LegacyZeroDec(),
+ IgnoreList: []block.Lane{},
+}
+```
+
+The three most important parameters to set are the `AnteHandler`, `MaxTxs`, and `MaxBlockSpace`.
+
+#### **AnteHandler**
+
+With the default implementation, the `AnteHandler` is responsible for verifying
+transactions as they are being considered for a new proposal or are being
+processed in a proposed block. We recommend user's utilize the same antehandler
+chain that is used in the base app. If developers want a certain `AnteDecorator`
+to be ignored if it qualifies for a given lane, they can do so by using the
+`NewIgnoreDecorator` defined in `block/utils/ante.go`.
+
+For example, a free lane might want to ignore the `DeductFeeDecorator` so that
+its transactions are not charged any fees. Where ever the `AnteHandler` is
+defined, we could add the following to ignore the `DeductFeeDecorator`:
+
+```golang
+anteDecorators := []sdk.AnteDecorator{
+ ante.NewSetUpContextDecorator(),
+ ...,
+ utils.NewIgnoreDecorator(
+ ante.NewDeductFeeDecorator(
+ options.BaseOptions.AccountKeeper,
+ options.BaseOptions.BankKeeper,
+ options.BaseOptions.FeegrantKeeper,
+ options.BaseOptions.TxFeeChecker,
+ ),
+ options.FreeLane,
+ ),
+ ...,
+}
+```
+
+Anytime a transaction that qualifies for the free lane is being processed, the
+`DeductFeeDecorator` will be ignored and no fees will be deducted!
+
+#### **MaxTxs**
+
+This sets the maximum number of transactions allowed in the mempool with the semantics:
+
+* if `MaxTxs` == 0, there is no cap on the number of transactions in the mempool
+* if `MaxTxs` > 0, the mempool will cap the number of transactions it stores,
+and will prioritize transactions by their priority and sender-nonce
+(sequence number) when evicting transactions.
+* if `MaxTxs` < 0, `Insert` is a no-op.
+
+#### **MaxBlockSpace**
+
+MaxBlockSpace is the maximum amount of block space that the lane will attempt
+to fill when building a proposal. This parameter may be useful lanes that
+should be limited (such as a free or onboarding lane) in space usage.
+Setting this to 0 will allow the lane to fill the block with as many
+transactions as possible.
+
+If a block proposal request has a `MaxTxBytes` of 1000 and the lane has a
+`MaxBlockSpace` of 0.5, the lane will attempt to fill the block with 500 bytes.
+
+#### **[OPTIONAL] IgnoreList**
+
+`IgnoreList` defines the list of lanes to ignore when processing transactions.
+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).
diff --git a/lanes/free/README.md b/lanes/free/README.md
new file mode 100644
index 0000000..4c51d6c
--- /dev/null
+++ b/lanes/free/README.md
@@ -0,0 +1,129 @@
+# ποΈ Free Lane Setup
+
+## π¦ Dependencies
+
+The Block SDK is built on top of the Cosmos SDK. The Block SDK is currently
+compatible with Cosmos SDK versions greater than or equal to `v0.47.0`.
+
+## π₯ Installation
+
+To install the Block SDK, run the following command:
+
+```bash
+$ go install github.com/skip-mev/block-sdk
+```
+
+## π Usage
+
+1. First determine the set of lanes that you want to use in your application. The
+available lanes can be found in our
+[Lane App Store](https://docs.skip.money/chains/lanes/existing-lanes/default).
+In your base application, you will need to create a `LanedMempool` composed of the
+lanes you want to use. *The free lane should not exist on its own. At minimum, it
+is recommended that the free lane is paired with the default lane.*
+2. Next, order the lanes by priority. The first lane is the highest priority lane
+and the last lane is the lowest priority lane.
+3. Set up your `FeeDeductorDecorator` to ignore the free lane where ever you
+initialize your `AnteHandler`. This will ensure that the free lane is not
+subject to deducting transaction fees.
+4. You will also need to create a `PrepareProposalHandler` and a
+`ProcessProposalHandler` that will be responsible for preparing and processing
+proposals respectively. Configure the order of the lanes in the
+`PrepareProposalHandler` and `ProcessProposalHandler` to match the order of the
+lanes in the `LanedMempool`.
+
+NOTE: This example walks through setting up the Free and Default lanes.
+
+```golang
+import (
+ "github.com/skip-mev/block-sdk/abci"
+ "github.com/skip-mev/block-sdk/block/base"
+ defaultlane "github.com/skip-mev/block-sdk/lanes/base"
+ freelane "github.com/skip-mev/block-sdk/lanes/free"
+)
+
+...
+
+func NewApp() {
+ ...
+ // 1. Create the lanes.
+ //
+ // NOTE: The lanes are ordered by priority. The first lane is the highest priority
+ // lane and the last lane is the lowest priority lane. Top of block lane allows
+ // transactions to bid for inclusion at the top of the next block.
+ //
+ // For more information on how to utilize the LaneConfig please
+ // visit the README in docs.skip.money/chains/lanes/build-your-own-lane#-lane-config.
+ //
+ // Set up the configuration of the free lane and instantiate it.
+ freeConfig := base.LaneConfig{
+ Logger: app.Logger(),
+ TxEncoder: app.txConfig.TxEncoder(),
+ TxDecoder: app.txConfig.TxDecoder(),
+ MaxBlockSpace: math.LegacyZeroDec(),
+ MaxTxs: 0,
+ }
+ freeLane := freelane.NewFreeLane(freeConfig, base.DefaultTxPriority(), freelane.DefaultMatchHandler())
+
+ // Default lane accepts all transactions.
+ defaultConfig := base.LaneConfig{
+ Logger: app.Logger(),
+ TxEncoder: app.txConfig.TxEncoder(),
+ TxDecoder: app.txConfig.TxDecoder(),
+ MaxBlockSpace: math.LegacyZeroDec(),
+ MaxTxs: 0,
+ }
+ defaultLane := defaultlane.NewDefaultLane(defaultConfig)
+
+ // 2. Set up the relative priority of lanes
+ lanes := []block.Lane{
+ freeLane,
+ defaultLane,
+ }
+ mempool := block.NewLanedMempool(app.Logger(), true, lanes...)
+ app.App.SetMempool(mempool)
+
+ ...
+
+ // 3. Set up the ante handler.
+ //
+ // This will allow any transaction that matches the to the free lane to
+ // be processed without paying any fees.
+ anteDecorators := []sdk.AnteDecorator{
+ ante.NewSetUpContextDecorator(),
+ ...
+ utils.NewIgnoreDecorator(
+ ante.NewDeductFeeDecorator(
+ options.BaseOptions.AccountKeeper,
+ options.BaseOptions.BankKeeper,
+ options.BaseOptions.FeegrantKeeper,
+ options.BaseOptions.TxFeeChecker,
+ ),
+ options.FreeLane,
+ ),
+ ...
+ }
+
+ anteHandler := sdk.ChainAnteDecorators(anteDecorators...)
+
+ // Set the lane ante handlers on the lanes.
+ //
+ // NOTE: This step is very important. Without the antehandlers, lanes will not
+ // be able to verify transactions.
+ for _, lane := range lanes {
+ lane.SetAnteHandler(anteHandler)
+ }
+ app.App.SetAnteHandler(anteHandler)
+
+ // 4. Set the abci handlers on base app
+ proposalHandler := abci.NewProposalHandler(
+ app.Logger(),
+ app.TxConfig().TxDecoder(),
+ lanes,
+ )
+ app.App.SetPrepareProposal(proposalHandler.PrepareProposalHandler())
+ app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
+
+ ...
+}
+```
diff --git a/blockbuster/lanes/free/lane.go b/lanes/free/lane.go
similarity index 74%
rename from blockbuster/lanes/free/lane.go
rename to lanes/free/lane.go
index 2c4c424..10dcfaa 100644
--- a/blockbuster/lanes/free/lane.go
+++ b/lanes/free/lane.go
@@ -3,7 +3,8 @@ package free
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
- "github.com/skip-mev/pob/blockbuster"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
)
const (
@@ -11,24 +12,24 @@ const (
LaneName = "free"
)
-var _ blockbuster.Lane = (*FreeLane)(nil)
+var _ block.Lane = (*FreeLane)(nil)
// FreeLane defines the lane that is responsible for processing free transactions.
// By default, transactions that are staking related are considered free.
type FreeLane struct { //nolint
- *blockbuster.LaneConstructor
+ *base.BaseLane
}
// NewFreeLane returns a new free lane.
func NewFreeLane(
- cfg blockbuster.LaneConfig,
- txPriority blockbuster.TxPriority[string],
- matchFn blockbuster.MatchHandler,
+ cfg base.LaneConfig,
+ txPriority base.TxPriority[string],
+ matchFn block.MatchHandler,
) *FreeLane {
- lane := blockbuster.NewLaneConstructor(
+ lane := base.NewBaseLane(
cfg,
LaneName,
- blockbuster.NewConstructorMempool[string](
+ base.NewMempool[string](
txPriority,
cfg.TxEncoder,
cfg.MaxTxs,
@@ -37,14 +38,14 @@ func NewFreeLane(
)
return &FreeLane{
- LaneConstructor: lane,
+ BaseLane: lane,
}
}
// DefaultMatchHandler returns the default match handler for the free lane. The
// default implementation matches transactions that are staking related. In particular,
// any transaction that is a MsgDelegate, MsgBeginRedelegate, or MsgCancelUnbondingDelegation.
-func DefaultMatchHandler() blockbuster.MatchHandler {
+func DefaultMatchHandler() block.MatchHandler {
return func(ctx sdk.Context, tx sdk.Tx) bool {
for _, msg := range tx.GetMsgs() {
switch msg.(type) {
diff --git a/lanes/mev/README.md b/lanes/mev/README.md
new file mode 100644
index 0000000..17258b8
--- /dev/null
+++ b/lanes/mev/README.md
@@ -0,0 +1,258 @@
+# ποΈ MEV Lane Setup
+
+## π¦ Dependencies
+
+The Block SDK is built on top of the Cosmos SDK. The Block SDK is currently
+compatible with Cosmos SDK versions greater than or equal to `v0.47.0`.
+
+## π₯ Installation
+
+To install the Block SDK, run the following command:
+
+```bash
+$ go install github.com/skip-mev/block-sdk
+```
+
+## π Usage
+
+1. This guide assumes you have already set up the [Block SDK (and the default lane)](https://docs.skip.money/chains/overview)
+2. You will need to instantiate the `x/builder` module into your application. This
+module is responsible for processing auction transactions and distributing revenue
+to the auction house. The `x/builder` module is also responsible for ensuring the
+validity of auction transactions. *The `x/builder` module should not exist on its
+own. **This is the most intensive part of the set up process.**
+3. Next, add the MEV lane into the `lane` object on your `app.go`. The first
+lane is the highest priority lane and the last lane is the lowest priority lane.
+Since the MEV lane is meant to auction off the top of the block, **it should be
+the highest priority lane**. The default lane should follow.
+4. You will also need to create a `PrepareProposalHandler` and a
+`ProcessProposalHandler` that will be responsible for preparing and processing
+proposals respectively. Configure the order of the lanes in the
+`PrepareProposalHandler` and `ProcessProposalHandler` to match the order of the
+lanes in the `LanedMempool`.
+
+NOTE: This example walks through setting up the MEV and Default lanes.
+
+1. Import the necessary dependencies into your application. This includes the
+ Block SDK proposal handlers + mempool, keeper, builder types, and builder
+ module. This tutorial will go into more detail into each of the dependencies.
+
+ ```go
+ import (
+ ...
+ "github.com/skip-mev/pob/block-sdk"
+ "github.com/skip-mev/pob/block-sdk/abci"
+ "github.com/skip-mev/pob/block-sdk/lanes/mev"
+ "github.com/skip-mev/pob/block-sdk/lanes/base"
+ buildermodule "github.com/skip-mev/block-sdk/x/builder"
+ builderkeeper "github.com/skip-mev/block-sdk/x/builder/keeper"
+ buildertypes "github.com/skip-mev/block-sdk/x/builder/types"
+ builderante "github.com/skip-mev/block-sdk/x/builder/ante"
+ ...
+ )
+ ```
+
+2. Add your module to the the `AppModuleBasic` manager. This manager is in
+ charge of setting up basic, non-dependent module elements such as codec
+ registration and genesis verification. This will register the special
+ `MsgAuctionBid` message. When users want to bid for top of block execution,
+ they will submit a transaction - which we call an auction transaction - that
+ includes a single `MsgAuctionBid`. We prevent any other messages from being
+ included in auction transaction to prevent malicious behavior - such as front
+ running or sandwiching.
+
+ ```go
+ var (
+ ModuleBasics = module.NewBasicManager(
+ ...
+ buildermodule.AppModuleBasic{},
+ )
+ ...
+ )
+ ```
+
+3. The builder `Keeper` is MEV lane's gateway to processing special `MsgAuctionBid`
+ messages that allow users to participate in the top of block auction, distribute
+ revenue to the auction house, and ensure the validity of auction transactions.
+
+ a. First add the keeper to the app's struct definition. We also want to add
+ MEV lane's custom checkTx handler to the app's struct definition. This will
+ allow us to override the default checkTx handler to process bid transactions
+ before they are inserted into the `LanedMempool`. NOTE: The custom handler
+ is required as otherwise the auction can be held hostage by a malicious
+ users.
+
+ ```go
+ type App struct {
+ ...
+ // BuilderKeeper is the keeper that handles processing auction transactions
+ BuilderKeeper builderkeeper.Keeper
+
+ // Custom checkTx handler
+ checkTxHandler mev.CheckTx
+ }
+ ```
+
+ b. Add the builder module to the list of module account permissions. This will
+ instantiate the builder module account on genesis.
+
+ ```go
+ maccPerms = map[string][]string{
+ builder.ModuleName: nil,
+ ...
+ }
+ ```
+
+ c. Instantiate the Block SDK's `LanedMempool` with the application's
+ desired lanes.
+
+ ```go
+ // 1. Create the lanes.
+ //
+ // NOTE: The lanes are ordered by priority. The first lane is the
+ // highest priority
+ // lane and the last lane is the lowest priority lane. Top of block
+ // lane allows transactions to bid for inclusion at the top of the next block.
+ //
+ // For more information on how to utilize the LaneConfig please
+ // visit the README in docs.skip.money/chains/lanes/build-your-own-lane#-lane-config.
+ //
+ // MEV lane hosts an auction at the top of the block.
+ mevConfig := base.LaneConfig{
+ Logger: app.Logger(),
+ TxEncoder: app.txConfig.TxEncoder(),
+ TxDecoder: app.txConfig.TxDecoder(),
+ MaxBlockSpace: math.LegacyZeroDec(),
+ MaxTxs: 0,
+ }
+ mevLane := mev.NewMEVLane(
+ mevConfig,
+ mev.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
+ )
+
+ // 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,
+ }
+ defaultLane := base.NewStandardLane(defaultConfig)
+
+ // 2. Set up the relateive priority of lanes
+ lanes := []block.Lane{
+ mevLane,
+ defaultLane,
+ }
+ mempool := block.NewLanedMempool(app.Logger(), true, lanes...)
+ app.App.SetMempool(mempool)
+ ```
+
+ d. Add the `x/builder` module's `AuctionDecorator` to the ante-handler
+ chain. The `AuctionDecorator` is an AnteHandler decorator that enforces
+ various chain configurable MEV rules.
+
+ ```go
+ anteDecorators := []sdk.AnteDecorator{
+ ante.NewSetUpContextDecorator(),
+ ...
+ builderante.NewBuilderDecorator(
+ options.BuilderKeeper,
+ options.TxEncoder,
+ options.TOBLane,
+ options.Mempool,
+ ),
+ }
+
+ anteHandler := sdk.ChainAnteDecorators(anteDecorators...)
+ app.SetAnteHandler(anteHandler)
+
+ // Set the antehandlers on the lanes.
+ //
+ // NOTE: This step is required as otherwise the lanes will not be able to
+ // process auction transactions.
+ for _, lane := range lanes {
+ lane.SetAnteHandler(anteHandler)
+ }
+ app.App.SetAnteHandler(anteHandler)
+ ```
+
+ e. Instantiate the builder keeper, store keys, and module manager. Note, be
+ sure to do this after all the required keeper dependencies have been instantiated.
+
+ ```go
+ keys := storetypes.NewKVStoreKeys(
+ buildertypes.StoreKey,
+ ...
+ )
+
+ ...
+ app.BuilderKeeper := builderkeeper.NewKeeper(
+ appCodec,
+ keys[buildertypes.StoreKey],
+ app.AccountKeeper,
+ app.BankKeeper,
+ app.DistrKeeper,
+ app.StakingKeeper,
+ authtypes.NewModuleAddress(govv1.ModuleName).String(),
+ )
+
+
+ app.ModuleManager = module.NewManager(
+ builder.NewAppModule(appCodec, app.BuilderKeeper),
+ ...
+ )
+ ```
+
+ f. Configure the proposal/checkTx handlers on base app.
+
+ ```go
+ // Create the proposal handler that will be used to build and validate blocks.
+ proposalHandler := abci.NewProposalHandler(
+ app.Logger(),
+ app.txConfig.TxDecoder(),
+ lanes,
+ )
+ app.App.SetPrepareProposal(proposalHandler.PrepareProposalHandler())
+ app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
+
+ // Set the custom CheckTx handler on BaseApp.
+ checkTxHandler := mev.NewCheckTxHandler(
+ app.App,
+ app.txConfig.TxDecoder(),
+ mevLane,
+ anteHandler,
+ )
+ app.SetCheckTx(checkTxHandler.CheckTx())
+
+ // CheckTx will check the transaction with the provided checkTxHandler.
+ // We override the default handler so that we can verify transactions
+ // before they are inserted into the mempool. With the CheckTx, we can
+ // verify the bid transaction and all of the bundled transactions
+ // before inserting the bid transaction into the mempool.
+ func (app *TestApp) CheckTx(req *cometabci.RequestCheckTx)
+ (*cometabci.ResponseCheckTx, error) {
+ return app.checkTxHandler(req)
+ }
+
+ // SetCheckTx sets the checkTxHandler for the app.
+ func (app *TestApp) SetCheckTx(handler mev.CheckTx) {
+ app.checkTxHandler = handler
+ }
+ ```
+
+ g. Finally, update the app's `InitGenesis` order.
+
+ ```go
+ genesisModuleOrder := []string{
+ buildertypes.ModuleName,
+ ...,
+ }
+ ```
+
+## Params
+
+Note, before building or upgrading the application, make sure to initialize the
+escrow address in the parameters of the module. The default parameters
+initialize the escrow address to be the module account address.
diff --git a/blockbuster/lanes/auction/abci.go b/lanes/mev/abci.go
similarity index 93%
rename from blockbuster/lanes/auction/abci.go
rename to lanes/mev/abci.go
index 0773c82..137da8c 100644
--- a/blockbuster/lanes/auction/abci.go
+++ b/lanes/mev/abci.go
@@ -1,12 +1,12 @@
-package auction
+package mev
import (
"bytes"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/utils"
"github.com/skip-mev/pob/x/builder/types"
)
@@ -14,8 +14,8 @@ import (
// and whose bundled transactions are valid and include them in the proposal. It
// will return no transactions if no valid bids are found. If any of the bids are invalid,
// it will return them and will only remove the bids and not the bundled transactions.
-func (l *TOBLane) PrepareLaneHandler() blockbuster.PrepareLaneHandler {
- return func(ctx sdk.Context, proposal blockbuster.BlockProposal, maxTxBytes int64) ([][]byte, []sdk.Tx, error) {
+func (l *MEVLane) PrepareLaneHandler() block.PrepareLaneHandler {
+ return func(ctx sdk.Context, proposal block.BlockProposal, maxTxBytes int64) ([][]byte, []sdk.Tx, error) {
// Define all of the info we need to select transactions for the partial proposal.
var (
txs [][]byte
@@ -128,7 +128,7 @@ func (l *TOBLane) PrepareLaneHandler() blockbuster.PrepareLaneHandler {
txs = append(txs, bundledTxBz...)
// Write the cache context to the original context when we know we have a
- // valid top of block bundle.
+ // valid bundle.
write()
break selectBidTxLoop
@@ -146,8 +146,8 @@ func (l *TOBLane) PrepareLaneHandler() blockbuster.PrepareLaneHandler {
}
// ProcessLaneHandler will ensure that block proposals that include transactions from
-// the top-of-block auction lane are valid.
-func (l *TOBLane) ProcessLaneHandler() blockbuster.ProcessLaneHandler {
+// the mev lane are valid.
+func (l *MEVLane) ProcessLaneHandler() block.ProcessLaneHandler {
return func(ctx sdk.Context, txs []sdk.Tx) ([]sdk.Tx, error) {
if len(txs) == 0 {
return txs, nil
@@ -178,7 +178,7 @@ func (l *TOBLane) ProcessLaneHandler() blockbuster.ProcessLaneHandler {
// - there are no other bid transactions in the proposal
// - transactions from other lanes are not interleaved with transactions from the bid
// transaction.
-func (l *TOBLane) CheckOrderHandler() blockbuster.CheckOrderHandler {
+func (l *MEVLane) CheckOrderHandler() block.CheckOrderHandler {
return func(ctx sdk.Context, txs []sdk.Tx) error {
if len(txs) == 0 {
return nil
@@ -241,7 +241,7 @@ func (l *TOBLane) CheckOrderHandler() blockbuster.CheckOrderHandler {
// VerifyTx will verify that the bid transaction and all of its bundled
// transactions are valid. It will return an error if any of the transactions
// are invalid.
-func (l *TOBLane) VerifyTx(ctx sdk.Context, bidTx sdk.Tx, bidInfo *types.BidInfo) (err error) {
+func (l *MEVLane) VerifyTx(ctx sdk.Context, bidTx sdk.Tx, bidInfo *types.BidInfo) (err error) {
if bidInfo == nil {
return fmt.Errorf("bid info is nil")
}
diff --git a/blockbuster/lanes/auction/check_tx.go b/lanes/mev/check_tx.go
similarity index 94%
rename from blockbuster/lanes/auction/check_tx.go
rename to lanes/mev/check_tx.go
index 089ee99..dbe890b 100644
--- a/blockbuster/lanes/auction/check_tx.go
+++ b/lanes/mev/check_tx.go
@@ -1,4 +1,4 @@
-package auction
+package mev
import (
"fmt"
@@ -26,9 +26,9 @@ type (
// bid transactions.
txDecoder sdk.TxDecoder
- // TOBLane is utilized to retrieve the bid info of a transaction and to
+ // MEVLane is utilized to retrieve the bid info of a transaction and to
// insert a bid transaction into the application-side mempool.
- tobLane TOBLaneI
+ mevLane MEVLaneI
// anteHandler is utilized to verify the bid transaction against the latest
// committed state.
@@ -63,17 +63,17 @@ type (
}
)
-// NewCheckTxHandler is a constructor for CheckTxHandler.
+// NewCheckTxHandler constructs a new CheckTxHandler instance.
func NewCheckTxHandler(
baseApp BaseApp,
txDecoder sdk.TxDecoder,
- tobLane TOBLaneI,
+ mevLane MEVLaneI,
anteHandler sdk.AnteHandler,
) *CheckTxHandler {
return &CheckTxHandler{
baseApp: baseApp,
txDecoder: txDecoder,
- tobLane: tobLane,
+ mevLane: mevLane,
anteHandler: anteHandler,
}
}
@@ -121,7 +121,7 @@ func (handler *CheckTxHandler) CheckTx() CheckTx {
}
// Attempt to get the bid info of the transaction.
- bidInfo, err := handler.tobLane.GetAuctionBidInfo(tx)
+ bidInfo, err := handler.mevLane.GetAuctionBidInfo(tx)
if err != nil {
handler.baseApp.Logger().Info(
"failed to get auction bid info",
@@ -173,7 +173,7 @@ func (handler *CheckTxHandler) CheckTx() CheckTx {
}
// If the bid transaction is valid, we know we can insert it into the mempool for consideration in the next block.
- if err := handler.tobLane.Insert(ctx, tx); err != nil {
+ if err := handler.mevLane.Insert(ctx, tx); err != nil {
handler.baseApp.Logger().Info(
"invalid bid tx; failed to insert bid transaction into mempool",
"err", err,
@@ -212,13 +212,13 @@ func (handler *CheckTxHandler) ValidateBidTx(ctx sdk.Context, bidTx sdk.Tx, bidI
// Verify all of the bundled transactions.
for _, tx := range bidInfo.Transactions {
- bundledTx, err := handler.tobLane.WrapBundleTransaction(tx)
+ bundledTx, err := handler.mevLane.WrapBundleTransaction(tx)
if err != nil {
return gasInfo, fmt.Errorf("invalid bid tx; failed to decode bundled tx: %w", err)
}
// bid txs cannot be included in bundled txs
- bidInfo, _ := handler.tobLane.GetAuctionBidInfo(bundledTx)
+ bidInfo, _ := handler.mevLane.GetAuctionBidInfo(bundledTx)
if bidInfo != nil {
return gasInfo, fmt.Errorf("invalid bid tx; bundled tx cannot be a bid tx")
}
diff --git a/blockbuster/lanes/auction/factory.go b/lanes/mev/factory.go
similarity index 95%
rename from blockbuster/lanes/auction/factory.go
rename to lanes/mev/factory.go
index 6032aa9..d0bca0c 100644
--- a/blockbuster/lanes/auction/factory.go
+++ b/lanes/mev/factory.go
@@ -1,11 +1,11 @@
-package auction
+package mev
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/signing"
- "github.com/skip-mev/pob/blockbuster"
+ "github.com/skip-mev/pob/block"
"github.com/skip-mev/pob/x/builder/types"
)
@@ -24,7 +24,7 @@ type (
GetAuctionBidInfo(tx sdk.Tx) (*types.BidInfo, error)
// MatchHandler defines a function that checks if a transaction matches the auction lane.
- MatchHandler() blockbuster.MatchHandler
+ MatchHandler() block.MatchHandler
}
// DefaultAuctionFactory defines a default implmentation for the auction factory interface for processing auction transactions.
@@ -95,7 +95,7 @@ func (config *DefaultAuctionFactory) GetAuctionBidInfo(tx sdk.Tx) (*types.BidInf
}, nil
}
-func (config *DefaultAuctionFactory) MatchHandler() blockbuster.MatchHandler {
+func (config *DefaultAuctionFactory) MatchHandler() block.MatchHandler {
return func(ctx sdk.Context, tx sdk.Tx) bool {
bidInfo, err := config.GetAuctionBidInfo(tx)
return bidInfo != nil && err == nil
diff --git a/blockbuster/lanes/auction/factory_test.go b/lanes/mev/factory_test.go
similarity index 96%
rename from blockbuster/lanes/auction/factory_test.go
rename to lanes/mev/factory_test.go
index 53c6ec1..b68587e 100644
--- a/blockbuster/lanes/auction/factory_test.go
+++ b/lanes/mev/factory_test.go
@@ -1,4 +1,4 @@
-package auction_test
+package mev_test
import (
"crypto/rand"
@@ -8,7 +8,7 @@ import (
testutils "github.com/skip-mev/pob/testutils"
)
-func (suite *IntegrationTestSuite) TestIsAuctionTx() {
+func (suite *MEVTestSuite) TestIsAuctionTx() {
testCases := []struct {
name string
createTx func() sdk.Tx
@@ -92,7 +92,7 @@ func (suite *IntegrationTestSuite) TestIsAuctionTx() {
}
}
-func (suite *IntegrationTestSuite) TestGetTransactionSigners() {
+func (suite *MEVTestSuite) TestGetTransactionSigners() {
testCases := []struct {
name string
createTx func() sdk.Tx
@@ -176,7 +176,7 @@ func (suite *IntegrationTestSuite) TestGetTransactionSigners() {
}
}
-func (suite *IntegrationTestSuite) TestWrapBundleTransaction() {
+func (suite *MEVTestSuite) TestWrapBundleTransaction() {
testCases := []struct {
name string
createBundleTx func() (sdk.Tx, []byte)
@@ -229,7 +229,7 @@ func (suite *IntegrationTestSuite) TestWrapBundleTransaction() {
}
}
-func (suite *IntegrationTestSuite) TestGetBidder() {
+func (suite *MEVTestSuite) TestGetBidder() {
testCases := []struct {
name string
createTx func() sdk.Tx
@@ -304,7 +304,7 @@ func (suite *IntegrationTestSuite) TestGetBidder() {
}
}
-func (suite *IntegrationTestSuite) TestGetBid() {
+func (suite *MEVTestSuite) TestGetBid() {
testCases := []struct {
name string
createTx func() sdk.Tx
@@ -379,7 +379,7 @@ func (suite *IntegrationTestSuite) TestGetBid() {
}
}
-func (suite *IntegrationTestSuite) TestGetBundledTransactions() {
+func (suite *MEVTestSuite) TestGetBundledTransactions() {
testCases := []struct {
name string
createTx func() (sdk.Tx, [][]byte)
@@ -450,7 +450,7 @@ func (suite *IntegrationTestSuite) TestGetBundledTransactions() {
}
}
-func (suite *IntegrationTestSuite) TestGetTimeout() {
+func (suite *MEVTestSuite) TestGetTimeout() {
testCases := []struct {
name string
createTx func() sdk.Tx
diff --git a/blockbuster/lanes/auction/lane.go b/lanes/mev/lane.go
similarity index 51%
rename from blockbuster/lanes/auction/lane.go
rename to lanes/mev/lane.go
index 14d7066..d3da91b 100644
--- a/blockbuster/lanes/auction/lane.go
+++ b/lanes/mev/lane.go
@@ -1,37 +1,37 @@
-package auction
+package mev
import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
)
const (
- // LaneName defines the name of the top-of-block auction lane.
- LaneName = "top-of-block"
+ // LaneName defines the name of the mev lane.
+ LaneName = "mev"
)
-var _ TOBLaneI = (*TOBLane)(nil)
+var _ MEVLaneI = (*MEVLane)(nil)
-// TOBLane defines a top-of-block auction lane. The top of block auction lane
+// MEVLane defines a MEV (Maximal Extracted Value) auction lane. The MEV auction lane
// hosts transactions that want to bid for inclusion at the top of the next block.
-// The top of block auction lane stores bid transactions that are sorted by
-// their bid price. The highest valid bid transaction is selected for inclusion in the
-// next block. The bundled transactions of the selected bid transaction are also
-// included in the next block.
+// The MEV auction lane stores bid transactions that are sorted by their bid price.
+// The highest valid bid transaction is selected for inclusion in the next block.
+// The bundled transactions of the selected bid transaction are also included in the
+// next block.
type (
- // TOBLaneI defines the interface for the top-of-block auction lane. This interface
+ // MEVLaneI defines the interface for the mev auction lane. This interface
// is utilized by both the x/builder module and the checkTx handler.
- TOBLaneI interface {
- blockbuster.Lane
+ MEVLaneI interface { //nolint
+ block.Lane
Factory
GetTopAuctionTx(ctx context.Context) sdk.Tx
}
- TOBLane struct {
- // LaneConfig defines the base lane configuration.
- *blockbuster.LaneConstructor
+ MEVLane struct { //nolint
+ *base.BaseLane
// Factory defines the API/functionality which is responsible for determining
// if a transaction is a bid transaction and how to extract relevant
@@ -40,16 +40,16 @@ type (
}
)
-// NewTOBLane returns a new TOB lane.
-func NewTOBLane(
- cfg blockbuster.LaneConfig,
+// NewMEVLane returns a new TOB lane.
+func NewMEVLane(
+ cfg base.LaneConfig,
factory Factory,
-) *TOBLane {
- lane := &TOBLane{
- LaneConstructor: blockbuster.NewLaneConstructor(
+) *MEVLane {
+ lane := &MEVLane{
+ BaseLane: base.NewBaseLane(
cfg,
LaneName,
- blockbuster.NewConstructorMempool[string](
+ base.NewMempool[string](
TxPriority(factory),
cfg.TxEncoder,
cfg.MaxTxs,
diff --git a/blockbuster/lanes/auction/mempool.go b/lanes/mev/mempool.go
similarity index 73%
rename from blockbuster/lanes/auction/mempool.go
rename to lanes/mev/mempool.go
index 68a3b81..68946df 100644
--- a/blockbuster/lanes/auction/mempool.go
+++ b/lanes/mev/mempool.go
@@ -1,16 +1,16 @@
-package auction
+package mev
import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster"
+ "github.com/skip-mev/pob/block/base"
)
-// TxPriority returns a TxPriority over auction bid transactions only. It
-// is to be used in the auction index only.
-func TxPriority(config Factory) blockbuster.TxPriority[string] {
- return blockbuster.TxPriority[string]{
+// TxPriority returns a TxPriority over mev lane transactions only. It
+// is to be used in the mev index only.
+func TxPriority(config Factory) base.TxPriority[string] {
+ return base.TxPriority[string]{
GetTxPriority: func(goCtx context.Context, tx sdk.Tx) string {
bidInfo, err := config.GetAuctionBidInfo(tx)
if err != nil {
@@ -52,7 +52,7 @@ func TxPriority(config Factory) blockbuster.TxPriority[string] {
// GetTopAuctionTx returns the highest bidding transaction in the auction mempool.
// This is primarily a helper function for the x/builder module.
-func (l *TOBLane) GetTopAuctionTx(ctx context.Context) sdk.Tx {
+func (l *MEVLane) GetTopAuctionTx(ctx context.Context) sdk.Tx {
iterator := l.Select(ctx, nil)
if iterator == nil {
return nil
diff --git a/blockbuster/lanes/auction/auction_test.go b/lanes/mev/mev_test.go
similarity index 73%
rename from blockbuster/lanes/auction/auction_test.go
rename to lanes/mev/mev_test.go
index ffe71ae..e1c9e65 100644
--- a/blockbuster/lanes/auction/auction_test.go
+++ b/lanes/mev/mev_test.go
@@ -1,4 +1,4 @@
-package auction_test
+package mev_test
import (
"math/rand"
@@ -8,16 +8,16 @@ import (
"cosmossdk.io/log"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/skip-mev/pob/blockbuster/lanes/auction"
+ "github.com/skip-mev/pob/lanes/mev"
testutils "github.com/skip-mev/pob/testutils"
"github.com/stretchr/testify/suite"
)
-type IntegrationTestSuite struct {
+type MEVTestSuite struct {
suite.Suite
encCfg testutils.EncodingConfig
- config auction.Factory
+ config mev.Factory
ctx sdk.Context
random *rand.Rand
accounts []testutils.Account
@@ -25,13 +25,13 @@ type IntegrationTestSuite struct {
}
func TestMempoolTestSuite(t *testing.T) {
- suite.Run(t, new(IntegrationTestSuite))
+ suite.Run(t, new(MEVTestSuite))
}
-func (suite *IntegrationTestSuite) SetupTest() {
+func (suite *MEVTestSuite) SetupTest() {
// Mempool setup
suite.encCfg = testutils.CreateTestEncodingConfig()
- suite.config = auction.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder())
+ suite.config = mev.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder())
suite.ctx = sdk.NewContext(nil, cmtproto.Header{}, false, log.NewTestLogger(suite.T()))
// Init accounts
diff --git a/blockbuster/lanes/auction/utils.go b/lanes/mev/utils.go
similarity index 98%
rename from blockbuster/lanes/auction/utils.go
rename to lanes/mev/utils.go
index 6d85330..4406c56 100644
--- a/blockbuster/lanes/auction/utils.go
+++ b/lanes/mev/utils.go
@@ -1,4 +1,4 @@
-package auction
+package mev
import (
"errors"
diff --git a/blockbuster/lanes/auction/utils_test.go b/lanes/mev/utils_test.go
similarity index 79%
rename from blockbuster/lanes/auction/utils_test.go
rename to lanes/mev/utils_test.go
index 2db4b74..7ae1dae 100644
--- a/blockbuster/lanes/auction/utils_test.go
+++ b/lanes/mev/utils_test.go
@@ -1,10 +1,10 @@
-package auction_test
+package mev_test
import (
"testing"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
- "github.com/skip-mev/pob/blockbuster/lanes/auction"
+ "github.com/skip-mev/pob/lanes/mev"
testutils "github.com/skip-mev/pob/testutils"
buildertypes "github.com/skip-mev/pob/x/builder/types"
"github.com/stretchr/testify/require"
@@ -16,7 +16,7 @@ func TestGetMsgAuctionBidFromTx_Valid(t *testing.T) {
txBuilder := encCfg.TxConfig.NewTxBuilder()
txBuilder.SetMsgs(&buildertypes.MsgAuctionBid{})
- msg, err := auction.GetMsgAuctionBidFromTx(txBuilder.GetTx())
+ msg, err := mev.GetMsgAuctionBidFromTx(txBuilder.GetTx())
require.NoError(t, err)
require.NotNil(t, msg)
}
@@ -31,7 +31,7 @@ func TestGetMsgAuctionBidFromTx_MultiMsgBid(t *testing.T) {
&banktypes.MsgSend{},
)
- msg, err := auction.GetMsgAuctionBidFromTx(txBuilder.GetTx())
+ msg, err := mev.GetMsgAuctionBidFromTx(txBuilder.GetTx())
require.Error(t, err)
require.Nil(t, msg)
}
@@ -42,7 +42,7 @@ func TestGetMsgAuctionBidFromTx_NoBid(t *testing.T) {
txBuilder := encCfg.TxConfig.NewTxBuilder()
txBuilder.SetMsgs(&banktypes.MsgSend{})
- msg, err := auction.GetMsgAuctionBidFromTx(txBuilder.GetTx())
+ msg, err := mev.GetMsgAuctionBidFromTx(txBuilder.GetTx())
require.NoError(t, err)
require.Nil(t, msg)
}
diff --git a/blockbuster/lanes/terminator/lane.go b/lanes/terminator/lane.go
similarity index 86%
rename from blockbuster/lanes/terminator/lane.go
rename to lanes/terminator/lane.go
index 35e1453..3fce765 100644
--- a/blockbuster/lanes/terminator/lane.go
+++ b/lanes/terminator/lane.go
@@ -7,7 +7,7 @@ import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
- "github.com/skip-mev/pob/blockbuster"
+ "github.com/skip-mev/pob/block"
)
const (
@@ -36,10 +36,10 @@ const (
// snd \ \ \ /
type Terminator struct{}
-var _ blockbuster.Lane = (*Terminator)(nil)
+var _ block.Lane = (*Terminator)(nil)
// PrepareLane is a no-op
-func (t Terminator) PrepareLane(_ sdk.Context, proposal blockbuster.BlockProposal, _ int64, _ blockbuster.PrepareLanesHandler) (blockbuster.BlockProposal, error) {
+func (t Terminator) PrepareLane(_ sdk.Context, proposal block.BlockProposal, _ int64, _ block.PrepareLanesHandler) (block.BlockProposal, error) {
return proposal, nil
}
@@ -49,7 +49,7 @@ func (t Terminator) CheckOrder(sdk.Context, []sdk.Tx) error {
}
// ProcessLane is a no-op
-func (t Terminator) ProcessLane(ctx sdk.Context, _ []sdk.Tx, _ blockbuster.ProcessLanesHandler) (sdk.Context, error) {
+func (t Terminator) ProcessLane(ctx sdk.Context, _ []sdk.Tx, _ block.ProcessLanesHandler) (sdk.Context, error) {
return ctx, nil
}
@@ -72,7 +72,7 @@ func (t Terminator) Name() string {
func (t Terminator) SetAnteHandler(sdk.AnteHandler) {}
// SetIgnoreList is a no-op
-func (t Terminator) SetIgnoreList([]blockbuster.Lane) {}
+func (t Terminator) SetIgnoreList([]block.Lane) {}
// Match is a no-op
func (t Terminator) Match(sdk.Context, sdk.Tx) bool {
diff --git a/tests/app/ante.go b/tests/app/ante.go
index 7fdbf91..53d0e5c 100644
--- a/tests/app/ante.go
+++ b/tests/app/ante.go
@@ -3,20 +3,20 @@ package app
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/utils"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/utils"
builderante "github.com/skip-mev/pob/x/builder/ante"
builderkeeper "github.com/skip-mev/pob/x/builder/keeper"
)
type POBHandlerOptions struct {
BaseOptions ante.HandlerOptions
- Mempool blockbuster.Mempool
- TOBLane builderante.TOBLane
+ Mempool block.Mempool
+ MEVLane builderante.MEVLane
TxDecoder sdk.TxDecoder
TxEncoder sdk.TxEncoder
BuilderKeeper builderkeeper.Keeper
- FreeLane blockbuster.Lane
+ FreeLane block.Lane
}
// NewPOBAnteHandler wraps all of the default Cosmos SDK AnteDecorators with the POB AnteHandler.
@@ -54,7 +54,7 @@ func NewPOBAnteHandler(options POBHandlerOptions) sdk.AnteHandler {
ante.NewSigGasConsumeDecorator(options.BaseOptions.AccountKeeper, options.BaseOptions.SigGasConsumer),
ante.NewSigVerificationDecorator(options.BaseOptions.AccountKeeper, options.BaseOptions.SignModeHandler),
ante.NewIncrementSequenceDecorator(options.BaseOptions.AccountKeeper),
- builderante.NewBuilderDecorator(options.BuilderKeeper, options.TxEncoder, options.TOBLane, options.Mempool),
+ builderante.NewBuilderDecorator(options.BuilderKeeper, options.TxEncoder, options.MEVLane, options.Mempool),
}
return sdk.ChainAnteDecorators(anteDecorators...)
diff --git a/tests/app/app.go b/tests/app/app.go
index 8ebc49a..8185791 100644
--- a/tests/app/app.go
+++ b/tests/app/app.go
@@ -61,11 +61,12 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/abci"
- "github.com/skip-mev/pob/blockbuster/lanes/auction"
- "github.com/skip-mev/pob/blockbuster/lanes/base"
- "github.com/skip-mev/pob/blockbuster/lanes/free"
+ "github.com/skip-mev/pob/abci"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
+ defaultlane "github.com/skip-mev/pob/lanes/base"
+ "github.com/skip-mev/pob/lanes/free"
+ "github.com/skip-mev/pob/lanes/mev"
buildermodule "github.com/skip-mev/pob/x/builder"
builderkeeper "github.com/skip-mev/pob/x/builder/keeper"
)
@@ -139,7 +140,7 @@ type TestApp struct {
FeeGrantKeeper feegrantkeeper.Keeper
// custom checkTx handler
- checkTxHandler auction.CheckTx
+ checkTxHandler mev.CheckTx
}
func init() {
@@ -261,21 +262,21 @@ func New(
//
// NOTE: The lanes are ordered by priority. The first lane is the highest priority
// lane and the last lane is the lowest priority lane.
- // Top of block lane allows transactions to bid for inclusion at the top of the next block.
- tobConfig := blockbuster.LaneConfig{
+ // 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.
}
- tobLane := auction.NewTOBLane(
- tobConfig,
- auction.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
+ mevLane := mev.NewMEVLane(
+ mevConfig,
+ mev.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
)
// Free lane allows transactions to be included in the next block for free.
- freeConfig := blockbuster.LaneConfig{
+ freeConfig := base.LaneConfig{
Logger: app.Logger(),
TxEncoder: app.txConfig.TxEncoder(),
TxDecoder: app.txConfig.TxDecoder(),
@@ -284,27 +285,27 @@ func New(
}
freeLane := free.NewFreeLane(
freeConfig,
- blockbuster.DefaultTxPriority(),
+ base.DefaultTxPriority(),
free.DefaultMatchHandler(),
)
// Default lane accepts all other transactions.
- defaultConfig := blockbuster.LaneConfig{
+ defaultConfig := base.LaneConfig{
Logger: app.Logger(),
TxEncoder: app.txConfig.TxEncoder(),
TxDecoder: app.txConfig.TxDecoder(),
MaxBlockSpace: math.LegacyZeroDec(),
MaxTxs: 0,
}
- defaultLane := base.NewDefaultLane(defaultConfig)
+ defaultLane := defaultlane.NewDefaultLane(defaultConfig)
// Set the lanes into the mempool.
- lanes := []blockbuster.Lane{
- tobLane,
+ lanes := []block.Lane{
+ mevLane,
freeLane,
defaultLane,
}
- mempool := blockbuster.NewMempool(app.Logger(), true, lanes...)
+ mempool := block.NewLanedMempool(app.Logger(), true, lanes...)
app.App.SetMempool(mempool)
// Create a global ante handler that will be called on each transaction when
@@ -322,7 +323,7 @@ func New(
TxDecoder: app.txConfig.TxDecoder(),
TxEncoder: app.txConfig.TxEncoder(),
FreeLane: freeLane,
- TOBLane: tobLane,
+ MEVLane: mevLane,
Mempool: mempool,
}
anteHandler := NewPOBAnteHandler(options)
@@ -343,10 +344,10 @@ func New(
app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
// Set the custom CheckTx handler on BaseApp.
- checkTxHandler := auction.NewCheckTxHandler(
+ checkTxHandler := mev.NewCheckTxHandler(
app.App,
app.txConfig.TxDecoder(),
- tobLane,
+ mevLane,
anteHandler,
)
app.SetCheckTx(checkTxHandler.CheckTx())
@@ -392,7 +393,7 @@ func (app *TestApp) CheckTx(req *cometabci.RequestCheckTx) (*cometabci.ResponseC
}
// SetCheckTx sets the checkTxHandler for the app.
-func (app *TestApp) SetCheckTx(handler auction.CheckTx) {
+func (app *TestApp) SetCheckTx(handler mev.CheckTx) {
app.checkTxHandler = handler
}
diff --git a/tests/integration/pob_suite.go b/tests/integration/pob_suite.go
index 4f406c0..dde0672 100644
--- a/tests/integration/pob_suite.go
+++ b/tests/integration/pob_suite.go
@@ -1003,7 +1003,7 @@ func (s *POBIntegrationTestSuite) TestLanes() {
params := QueryBuilderParams(s.T(), s.chain)
- s.Run("block with tob, free, and normal tx", func() {
+ s.Run("block with mev, free, and normal tx", func() {
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
// create free-tx, bid-tx, and normal-tx\
@@ -1071,7 +1071,7 @@ func (s *POBIntegrationTestSuite) TestLanes() {
require.Equal(s.T(), user2BalanceBefore, user2BalanceAfter+delegation.Amount.Int64())
})
- s.Run("failing top of block transaction, free, and normal tx", func() {
+ s.Run("failing MEV transaction, free, and normal tx", func() {
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\
@@ -1151,7 +1151,7 @@ func (s *POBIntegrationTestSuite) TestLanes() {
require.Equal(s.T(), user2BalanceBefore, user2BalanceAfter+delegation.Amount.Int64())
})
- s.Run("top of block transaction that includes transactions from the free lane", func() {
+ s.Run("MEV transaction that includes transactions from the free lane", func() {
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
delegateTx := Tx{
@@ -1212,7 +1212,7 @@ func (s *POBIntegrationTestSuite) TestLanes() {
VerifyBlock(s.T(), block, 0, TxHash(txs[0]), bundledTx)
})
- s.Run("top of block transaction that includes transaction from free lane + other free lane txs + normal txs", func() {
+ s.Run("MEV transaction that includes transaction from free lane + other free lane txs + normal txs", func() {
user2BalanceBefore := QueryAccountBalance(s.T(), s.chain.(*cosmos.CosmosChain), s.user2.FormattedAddress(), s.denom)
// create free-txs signed by user2 / 3
diff --git a/x/builder/ante/ante.go b/x/builder/ante/ante.go
index 4c0a496..ae62909 100644
--- a/x/builder/ante/ante.go
+++ b/x/builder/ante/ante.go
@@ -14,9 +14,9 @@ import (
var _ sdk.AnteDecorator = BuilderDecorator{}
type (
- // TOBLane is an interface that defines the methods required to interact with the top of block
+ // MEVLane is an interface that defines the methods required to interact with the MEV
// lane.
- TOBLane interface {
+ MEVLane interface {
GetAuctionBidInfo(tx sdk.Tx) (*types.BidInfo, error)
GetTopAuctionTx(ctx context.Context) sdk.Tx
}
@@ -30,12 +30,12 @@ type (
BuilderDecorator struct {
builderKeeper keeper.Keeper
txEncoder sdk.TxEncoder
- lane TOBLane
+ lane MEVLane
mempool Mempool
}
)
-func NewBuilderDecorator(ak keeper.Keeper, txEncoder sdk.TxEncoder, lane TOBLane, mempool Mempool) BuilderDecorator {
+func NewBuilderDecorator(ak keeper.Keeper, txEncoder sdk.TxEncoder, lane MEVLane, mempool Mempool) BuilderDecorator {
return BuilderDecorator{
builderKeeper: ak,
txEncoder: txEncoder,
diff --git a/x/builder/ante/ante_test.go b/x/builder/ante/ante_test.go
index 5608d0b..6c25a43 100644
--- a/x/builder/ante/ante_test.go
+++ b/x/builder/ante/ante_test.go
@@ -11,9 +11,10 @@ import (
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
- "github.com/skip-mev/pob/blockbuster"
- "github.com/skip-mev/pob/blockbuster/lanes/auction"
- "github.com/skip-mev/pob/blockbuster/lanes/base"
+ "github.com/skip-mev/pob/block"
+ "github.com/skip-mev/pob/block/base"
+ defaultlane "github.com/skip-mev/pob/lanes/base"
+ "github.com/skip-mev/pob/lanes/mev"
testutils "github.com/skip-mev/pob/testutils"
"github.com/skip-mev/pob/x/builder/ante"
"github.com/skip-mev/pob/x/builder/keeper"
@@ -39,10 +40,10 @@ type AnteTestSuite struct {
authorityAccount sdk.AccAddress
// mempool and lane set up
- mempool blockbuster.Mempool
- tobLane *auction.TOBLane
- baseLane *base.DefaultLane
- lanes []blockbuster.Lane
+ mempool block.Mempool
+ mevLane *mev.MEVLane
+ baseLane *defaultlane.DefaultLane
+ lanes []block.Lane
// Account set up
balance sdk.Coin
@@ -83,32 +84,32 @@ func (suite *AnteTestSuite) SetupTest() {
// Lanes configuration
//
// TOB lane set up
- tobConfig := blockbuster.LaneConfig{
+ mevConfig := base.LaneConfig{
Logger: suite.ctx.Logger(),
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: suite.anteHandler,
MaxBlockSpace: math.LegacyZeroDec(),
}
- suite.tobLane = auction.NewTOBLane(
- tobConfig,
- auction.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
+ suite.mevLane = mev.NewMEVLane(
+ mevConfig,
+ mev.NewDefaultAuctionFactory(suite.encodingConfig.TxConfig.TxDecoder()),
)
// Base lane set up
- baseConfig := blockbuster.LaneConfig{
+ baseConfig := base.LaneConfig{
Logger: suite.ctx.Logger(),
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: suite.anteHandler,
MaxBlockSpace: math.LegacyZeroDec(),
- IgnoreList: []blockbuster.Lane{suite.tobLane},
+ IgnoreList: []block.Lane{suite.mevLane},
}
- suite.baseLane = base.NewDefaultLane(baseConfig)
+ suite.baseLane = defaultlane.NewDefaultLane(baseConfig)
// Mempool set up
- suite.lanes = []blockbuster.Lane{suite.tobLane, suite.baseLane}
- suite.mempool = blockbuster.NewMempool(log.NewTestLogger(suite.T()), true, suite.lanes...)
+ suite.lanes = []block.Lane{suite.mevLane, suite.baseLane}
+ suite.mempool = block.NewLanedMempool(log.NewTestLogger(suite.T()), true, suite.lanes...)
}
func (suite *AnteTestSuite) anteHandler(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
@@ -180,7 +181,7 @@ func (suite *AnteTestSuite) TestAnteHandler() {
false,
},
{
- "valid auction bid tx",
+ "valid mev bid tx",
func() {
balance = sdk.NewCoin("stake", math.NewInt(10000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
@@ -189,14 +190,14 @@ func (suite *AnteTestSuite) TestAnteHandler() {
true,
},
{
- "invalid auction bid tx with no timeout",
+ "invalid mev bid tx with no timeout",
func() {
timeout = 0
},
false,
},
{
- "auction tx is the top bidding tx",
+ "mev tx is the top bidding tx",
func() {
timeout = 1000
balance = sdk.NewCoin("stake", math.NewInt(10000))
@@ -211,7 +212,7 @@ func (suite *AnteTestSuite) TestAnteHandler() {
true,
},
{
- "invalid frontrunning auction bid tx",
+ "invalid frontrunning mev bid tx",
func() {
randomAccount := testutils.RandomAccounts(suite.random, 2)
bidder := randomAccount[0]
@@ -223,7 +224,7 @@ func (suite *AnteTestSuite) TestAnteHandler() {
false,
},
{
- "valid frontrunning auction bid tx",
+ "valid frontrunning mev bid tx",
func() {
randomAccount := testutils.RandomAccounts(suite.random, 2)
bidder := randomAccount[0]
@@ -235,7 +236,7 @@ func (suite *AnteTestSuite) TestAnteHandler() {
true,
},
{
- "invalid sandwiching auction bid tx",
+ "invalid sandwiching mev bid tx",
func() {
randomAccount := testutils.RandomAccounts(suite.random, 2)
bidder := randomAccount[0]
@@ -247,7 +248,7 @@ func (suite *AnteTestSuite) TestAnteHandler() {
false,
},
{
- "invalid auction bid tx with many signers",
+ "invalid mev bid tx with many signers",
func() {
signers = testutils.RandomAccounts(suite.random, 10)
frontRunningProtection = true
@@ -263,7 +264,7 @@ func (suite *AnteTestSuite) TestAnteHandler() {
suite.ctx = suite.ctx.WithBlockHeight(1)
- // Set the auction params
+ // Set the mev params
err := suite.builderKeeper.SetParams(suite.ctx, buildertypes.Params{
MaxBundleSize: maxBundleSize,
ReserveFee: reserveFee,
@@ -278,24 +279,24 @@ func (suite *AnteTestSuite) TestAnteHandler() {
suite.Require().NoError(err)
distribution := suite.mempool.GetTxDistribution()
- suite.Require().Equal(0, distribution[auction.LaneName])
- suite.Require().Equal(0, distribution[base.LaneName])
+ suite.Require().Equal(0, distribution[mev.LaneName])
+ suite.Require().Equal(0, distribution[defaultlane.LaneName])
suite.Require().NoError(suite.mempool.Insert(suite.ctx, topAuctionTx))
distribution = suite.mempool.GetTxDistribution()
- suite.Require().Equal(1, distribution[auction.LaneName])
- suite.Require().Equal(0, distribution[base.LaneName])
+ suite.Require().Equal(1, distribution[mev.LaneName])
+ suite.Require().Equal(0, distribution[defaultlane.LaneName])
}
- // Create the actual auction tx and insert into the mempool
- auctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, bidder, bid, 0, timeout, signers)
+ // Create the actual mev tx and insert into the mempool
+ mevTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, bidder, bid, 0, timeout, signers)
suite.Require().NoError(err)
// Execute the ante handler
suite.balance = balance
- suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxEncoder(), suite.tobLane, suite.mempool)
- _, err = suite.anteHandler(suite.ctx, auctionTx, false)
+ suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxEncoder(), suite.mevLane, suite.mempool)
+ _, err = suite.anteHandler(suite.ctx, mevTx, false)
if tc.pass {
suite.Require().NoError(err)
} else {