Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: top of block auction and block-sdk integration #8058

Merged
merged 20 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
157b9ce
feat: add top of block auction and block-sdk from skip-mev
PaddyMc Apr 16, 2024
90495c6
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 16, 2024
fea6201
fix: update params and remove free lane
PaddyMc Apr 17, 2024
d35fe80
chore: temp replace for osmomath
PaddyMc Apr 17, 2024
1712c49
chore: update bundle size to 5 txns
PaddyMc Apr 17, 2024
e960398
chore: update from USDC.axl to noble USDC
PaddyMc Apr 17, 2024
dd692b0
chore: update mev lane to 10% of block space
PaddyMc Apr 17, 2024
a76fa2d
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 18, 2024
e783d28
chore: remove increase seq ante decorator from test ante handler
PaddyMc Apr 19, 2024
05f91d1
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 19, 2024
6a86b88
chore: remove left over merge tags in CHANGELOG.md
PaddyMc Apr 19, 2024
5d9f985
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 19, 2024
8b7447c
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 22, 2024
51ca508
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 23, 2024
4a15e6b
chore: add changes based on review
PaddyMc Apr 24, 2024
5e2e457
chore: bump block sdk to v1.4.2
PaddyMc Apr 24, 2024
b587b02
chore: update merge conflicts
PaddyMc Apr 25, 2024
7bfed64
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 25, 2024
31d4eff
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 26, 2024
3200923
Merge branch 'main' into feat/top-of-block-auction
PaddyMc Apr 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### State Breaking

* [#7935](https://github.com/osmosis-labs/osmosis/pull/7935) Add block sdk and top of block auction from skip-mev :handshake: .
PaddyMc marked this conversation as resolved.
Show resolved Hide resolved
* [#8053](https://github.com/osmosis-labs/osmosis/pull/8053) Reset validator signing info missed blocks counter
* [#8030](https://github.com/osmosis-labs/osmosis/pull/8030) Delete legacy behavior where lockups could not unbond at very small block heights on a testnet.
* [#7005](https://github.com/osmosis-labs/osmosis/pull/7005) Adding deactivated smart account module.
Expand Down
26 changes: 26 additions & 0 deletions app/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"

"github.com/cosmos/cosmos-sdk/client"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
ante "github.com/cosmos/cosmos-sdk/x/auth/ante"
Expand All @@ -22,10 +23,21 @@ import (
smartaccountante "github.com/osmosis-labs/osmosis/v24/x/smart-account/ante"
smartaccountkeeper "github.com/osmosis-labs/osmosis/v24/x/smart-account/keeper"

auctionkeeper "github.com/skip-mev/block-sdk/x/auction/keeper"

txfeeskeeper "github.com/osmosis-labs/osmosis/v24/x/txfees/keeper"
txfeestypes "github.com/osmosis-labs/osmosis/v24/x/txfees/types"

auctionante "github.com/skip-mev/block-sdk/x/auction/ante"
)

// BlockSDKAnteHandlerParams are the parameters necessary to configure the block-sdk antehandlers
type BlockSDKAnteHandlerParams struct {
mevLane auctionante.MEVLane
auctionKeeper auctionkeeper.Keeper
txConfig client.TxConfig
}

// Link to default ante handler used by cosmos sdk:
// https://github.com/cosmos/cosmos-sdk/blob/v0.43.0/x/auth/ante/ante.go#L41
// N.B. There is a sister file called `ante_no_seq.go` that is used for e2e testing.
Expand All @@ -43,6 +55,7 @@ func NewAnteHandler(
sigGasConsumer ante.SignatureVerificationGasConsumer,
signModeHandler signing.SignModeHandler,
channelKeeper *ibckeeper.Keeper,
blockSDKParams BlockSDKAnteHandlerParams,
) sdk.AnteHandler {
mempoolFeeOptions := txfeestypes.NewMempoolFeeOptions(appOpts)
mempoolFeeDecorator := txfeeskeeper.NewMempoolFeeDecorator(*txFeesKeeper, mempoolFeeOptions)
Expand All @@ -62,6 +75,12 @@ func NewAnteHandler(
ante.NewSigVerificationDecorator(accountKeeper, signModeHandler),
ante.NewIncrementSequenceDecorator(accountKeeper),
ibcante.NewRedundantRelayDecorator(channelKeeper),
// auction module antehandler
auctionante.NewAuctionDecorator(
blockSDKParams.auctionKeeper,
blockSDKParams.txConfig.TxEncoder(),
blockSDKParams.mevLane,
),
)

// authenticatorVerificationDecorator is the new authenticator flow that's embedded into the circuit breaker ante
Expand All @@ -75,6 +94,13 @@ func NewAnteHandler(
// a state change.
deductFeeDecorator,
ante.NewIncrementSequenceDecorator(accountKeeper),
ibcante.NewRedundantRelayDecorator(channelKeeper),
// auction module antehandler
auctionante.NewAuctionDecorator(
blockSDKParams.auctionKeeper,
blockSDKParams.txConfig.TxEncoder(),
blockSDKParams.mevLane,
),
)

return sdk.ChainAnteDecorators(
Expand Down
18 changes: 18 additions & 0 deletions app/ante_no_seq.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"

"github.com/cosmos/cosmos-sdk/client"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
ante "github.com/cosmos/cosmos-sdk/x/auth/ante"
Expand All @@ -21,8 +22,18 @@ import (

txfeeskeeper "github.com/osmosis-labs/osmosis/v24/x/txfees/keeper"
txfeestypes "github.com/osmosis-labs/osmosis/v24/x/txfees/types"
auctionkeeper "github.com/skip-mev/block-sdk/x/auction/keeper"

auctionante "github.com/skip-mev/block-sdk/x/auction/ante"
)

// BlockSDKAnteHandlerParams are the parameters necessary to configure the block-sdk antehandlers
type BlockSDKAnteHandlerParams struct {
mevLane auctionante.MEVLane
auctionKeeper auctionkeeper.Keeper
txConfig client.TxConfig
}

// Link to default ante handler used by cosmos sdk:
// https://github.com/cosmos/cosmos-sdk/blob/v0.43.0/x/auth/ante/ante.go#L41
// N.B. There is a sister file called `ante_eq.go` that is used for production.
Expand All @@ -39,6 +50,7 @@ func NewAnteHandler(
sigGasConsumer ante.SignatureVerificationGasConsumer,
signModeHandler signing.SignModeHandler,
channelKeeper *ibckeeper.Keeper,
blockSDKParams BlockSDKAnteHandlerParams,
PaddyMc marked this conversation as resolved.
Show resolved Hide resolved
) sdk.AnteHandler {
mempoolFeeOptions := txfeestypes.NewMempoolFeeOptions(appOpts)
mempoolFeeDecorator := txfeeskeeper.NewMempoolFeeDecorator(*txFeesKeeper, mempoolFeeOptions)
Expand Down Expand Up @@ -66,5 +78,11 @@ func NewAnteHandler(
ante.NewSigVerificationDecorator(ak, signModeHandler),
// ante.NewIncrementSequenceDecorator(ak),
ibcante.NewRedundantRelayDecorator(channelKeeper),
// auction module antehandler
PaddyMc marked this conversation as resolved.
Show resolved Hide resolved
auctionante.NewAuctionDecorator(
blockSDKParams.auctionKeeper,
blockSDKParams.txConfig.TxEncoder(),
blockSDKParams.mevLane,
),
)
}
83 changes: 83 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"time"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
"github.com/skip-mev/block-sdk/block"
"github.com/skip-mev/block-sdk/block/base"

"github.com/cosmos/cosmos-sdk/x/auth"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
Expand Down Expand Up @@ -117,6 +119,9 @@ import (
v9 "github.com/osmosis-labs/osmosis/v24/app/upgrades/v9"
_ "github.com/osmosis-labs/osmosis/v24/client/docs/statik"
"github.com/osmosis-labs/osmosis/v24/x/mint"

blocksdkabci "github.com/skip-mev/block-sdk/abci"
"github.com/skip-mev/block-sdk/abci/checktx"
)

const appName = "OsmosisApp"
Expand Down Expand Up @@ -177,6 +182,8 @@ type OsmosisApp struct {
sm *module.SimulationManager
configurator module.Configurator
homePath string

checkTxHandler checktx.CheckTx
}

// init sets DefaultNodeHome to default osmosisd install location.
Expand Down Expand Up @@ -393,6 +400,20 @@ func NewOsmosisApp(

app.sm.RegisterStoreDecoders()

// initialize lanes + mempool
mevLane, defaultLane := CreateLanes(app, txConfig)

// create the mempool
lanedMempool, err := block.NewLanedMempool(
app.Logger(),
[]block.Lane{mevLane, defaultLane},
)
if err != nil {
panic(err)
}
// set the mempool
app.SetMempool(lanedMempool)

// initialize stores
app.MountKVStores(app.GetKVStoreKey())
app.MountTransientStores(app.GetTransientStoreKey())
Expand All @@ -410,8 +431,57 @@ func NewOsmosisApp(
ante.DefaultSigVerificationGasConsumer,
encodingConfig.TxConfig.SignModeHandler(),
app.IBCKeeper,
BlockSDKAnteHandlerParams{
mevLane: mevLane,
auctionKeeper: *app.AppKeepers.AuctionKeeper,
txConfig: txConfig,
},
)

// update ante-handlers on lanes
opt := []base.LaneOption{
base.WithAnteHandler(anteHandler),
}
mevLane.WithOptions(opt...)
defaultLane.WithOptions(opt...)

// ABCI handlers
// prepare proposal
proposalHandler := blocksdkabci.NewProposalHandler(
app.Logger(),
txConfig.TxDecoder(),
txConfig.TxEncoder(),
lanedMempool,
)

// we use the block-sdk's PrepareProposal logic to build blocks
app.SetPrepareProposal(proposalHandler.PrepareProposalHandler())

// we use a no-op ProcessProposal, this way, we accept all proposals in avoidance
// of liveness failures due to Prepare / Process inconsistency. In other words,
// this ProcessProposal always returns ACCEPT.
app.SetProcessProposal(baseapp.NoOpProcessProposal())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to be sure, we're no-op'ing process proposal along with block sdk integration correct? If so, what's the reason this is ok? 👀

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do any other chains utilize a noOpProcessPropisal? Just curious from a testing perspective what the overhead of this will need to be if we are the first to do so.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah also from David:

https://github.com/skip-mev/osmosis/pull/2/files#r1548522449

"Note: this is set to no-op because the upstream priority nonce mempool that the block SDK utilizes under the hood does not natively support multi-fee denoms. As such the ordering may not be deterministic between proposal creation and verificaiton. This would require an integration with osmosis prices / slinky to turn on the ProcessProposalHandler."


// check-tx
mevCheckTxHandler := checktx.NewMEVCheckTxHandler(
app,
txConfig.TxDecoder(),
mevLane,
anteHandler,
app.BaseApp.CheckTx,
app.ChainID(),
)

// wrap checkTxHandler with mempool parity handler
parityCheckTx := checktx.NewMempoolParityCheckTx(
app.Logger(),
lanedMempool,
txConfig.TxDecoder(),
mevCheckTxHandler.CheckTx(),
)

app.SetCheckTx(parityCheckTx.CheckTx())

// initialize BaseApp
app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker)
Expand Down Expand Up @@ -732,6 +802,19 @@ func InitOsmosisAppForTestnet(app *OsmosisApp, newValAddr bytes.HexBytes, newVal
return app
}

// 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 BlockSDK CheckTx, we can verify the bid transaction and all of the bundled transactions
// before inserting the bid transaction into the mempool.
func (app *OsmosisApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
return app.checkTxHandler(req)
}

// SetCheckTx sets the checkTxHandler for the app.
func (app *OsmosisApp) SetCheckTx(handler checktx.CheckTx) {
app.checkTxHandler = handler
}

// MakeCodecs returns the application codec and a legacy Amino codec.
func MakeCodecs() (codec.Codec, *codec.LegacyAmino) {
config := MakeEncodingConfig()
Expand Down
20 changes: 20 additions & 0 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ import (
epochskeeper "github.com/osmosis-labs/osmosis/x/epochs/keeper"
epochstypes "github.com/osmosis-labs/osmosis/x/epochs/types"

auctionkeeper "github.com/skip-mev/block-sdk/x/auction/keeper"
auctiontypes "github.com/skip-mev/block-sdk/x/auction/types"

storetypes "github.com/cosmos/cosmos-sdk/store/types"
)

Expand Down Expand Up @@ -184,6 +187,9 @@ type AppKeepers struct {
HooksICS4Wrapper ibchooks.ICS4Middleware
PacketForwardKeeper *packetforwardkeeper.Keeper

// BlockSDK
AuctionKeeper *auctionkeeper.Keeper

// keys to access the substores
keys map[string]*storetypes.KVStoreKey
tkeys map[string]*storetypes.TransientStoreKey
Expand Down Expand Up @@ -532,6 +538,18 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.LockupKeeper,
)

// initialize the auction keeper
auctionKeeper := auctionkeeper.NewKeeper(
appCodec,
appKeepers.keys[auctiontypes.StoreKey],
appKeepers.AccountKeeper,
appKeepers.BankKeeper,
appKeepers.DistrKeeper,
appKeepers.StakingKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rewards go to the gov module address 👀

Copy link
Collaborator Author

@PaddyMc PaddyMc Apr 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment incorrect, it uses a function to send rewards to validators

https://github.com/skip-mev/block-sdk/blob/main/x/auction/rewards/proposer_provider.go#L29-L41

)
appKeepers.AuctionKeeper = &auctionKeeper

appKeepers.ValidatorSetPreferenceKeeper = &validatorSetPreferenceKeeper

appKeepers.SuperfluidKeeper = superfluidkeeper.NewKeeper(
Expand Down Expand Up @@ -783,6 +801,7 @@ func (appKeepers *AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legac
paramsKeeper.Subspace(ibchookstypes.ModuleName)
paramsKeeper.Subspace(smartaccounttypes.ModuleName).WithKeyTable(smartaccounttypes.ParamKeyTable())
paramsKeeper.Subspace(txfeestypes.ModuleName)
paramsKeeper.Subspace(auctiontypes.ModuleName)

return paramsKeeper
}
Expand Down Expand Up @@ -905,6 +924,7 @@ func KVStoreKeys() []string {
icqtypes.StoreKey,
packetforwardtypes.StoreKey,
cosmwasmpooltypes.StoreKey,
auctiontypes.StoreKey,
smartaccounttypes.StoreKey,
}
}
3 changes: 3 additions & 0 deletions app/keepers/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import (

smartaccount "github.com/osmosis-labs/osmosis/v24/x/smart-account"

"github.com/skip-mev/block-sdk/x/auction"

_ "github.com/osmosis-labs/osmosis/v24/client/docs/statik"
clclient "github.com/osmosis-labs/osmosis/v24/x/concentrated-liquidity/client"
concentratedliquidity "github.com/osmosis-labs/osmosis/v24/x/concentrated-liquidity/clmodule"
Expand Down Expand Up @@ -132,5 +134,6 @@ var AppModuleBasics = []module.AppModuleBasic{
packetforward.AppModuleBasic{},
cosmwasmpoolmodule.AppModuleBasic{},
tendermint.AppModuleBasic{},
auction.AppModuleBasic{},
smartaccount.AppModuleBasic{},
}
80 changes: 80 additions & 0 deletions app/lanes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package app

import (
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client"

signerextraction "github.com/skip-mev/block-sdk/adapters/signer_extraction_adapter"
"github.com/skip-mev/block-sdk/block/base"
defaultlane "github.com/skip-mev/block-sdk/lanes/base"
mevlane "github.com/skip-mev/block-sdk/lanes/mev"
)

const (
maxTxPerMEVLane = 500 // this is the maximum # of bids that will be held in the app-side in-memory mempool
maxTxPerDefaultLane = 3000 // all other txs
)

var (
defaultLaneBlockspacePercentage = math.LegacyMustNewDecFromStr("0.90")
mevLaneBlockspacePercentage = math.LegacyMustNewDecFromStr("0.10")
PaddyMc marked this conversation as resolved.
Show resolved Hide resolved
)

// CreateLanes walks through the process of creating the lanes for the block sdk. In this function
// we create three separate lanes - MEV, Free, and Default - and then return them.
func CreateLanes(app *OsmosisApp, txConfig client.TxConfig) (*mevlane.MEVLane, *base.BaseLane) {
// 1. Create the signer extractor. This is used to extract the expected signers from
// a transaction. Each lane can have a different signer extractor if needed.
signerAdapter := signerextraction.NewDefaultAdapter()

// 2. Create the configurations for each lane. These configurations determine how many
// transactions the lane can store, the maximum block space the lane can consume, and
// the signer extractor used to extract the expected signers from a transaction.

PaddyMc marked this conversation as resolved.
Show resolved Hide resolved
// Create a mev configuration that accepts maxTxPerMEVLane transactions and consumes mevLaneBlockspacePercentage of the
// block space.
mevConfig := base.LaneConfig{
Logger: app.Logger(),
TxEncoder: txConfig.TxEncoder(),
TxDecoder: txConfig.TxDecoder(),
MaxBlockSpace: mevLaneBlockspacePercentage,
SignerExtractor: signerAdapter,
MaxTxs: maxTxPerMEVLane,
}

// Create a default configuration that accepts maxTxPerDefaultLane transactions and consumes defaultLaneBlockspacePercentage of the
// block space.
defaultConfig := base.LaneConfig{
Logger: app.Logger(),
TxEncoder: txConfig.TxEncoder(),
TxDecoder: txConfig.TxDecoder(),
MaxBlockSpace: defaultLaneBlockspacePercentage,
SignerExtractor: signerAdapter,
MaxTxs: maxTxPerDefaultLane,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So total 3500 txs per block! Wondering if there were reasons these numbers of txs were chose or were arbitrary numbers

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are just arbitrary numbers that the SKIP team suggested

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its really confusing to me why there is a percentage and a maxTxs number. Our framing should be in terms of block space categories relative to one another rather than a number of transactions.

Copy link
Member

@ValarDragon ValarDragon Apr 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The maxTx is a mempool setting, no? These field names from the block SDK can use some improvement imo

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// 3. Create the match handlers for each lane. These match handlers determine whether or not
// a transaction belongs in the lane.

// Create the final match handler for the mev lane.
factory := mevlane.NewDefaultAuctionFactory(txConfig.TxDecoder(), signerAdapter)
mevMatchHandler := factory.MatchHandler()

// Create the final match handler for the default lane. I.e this will direct all txs that are
// not free nor mev to this lane
defaultMatchHandler := base.DefaultMatchHandler()

// 4. Create the lanes.
mevLane := mevlane.NewMEVLane(
mevConfig,
factory,
mevMatchHandler,
)
PaddyMc marked this conversation as resolved.
Show resolved Hide resolved

defaultLane := defaultlane.NewDefaultLane(
defaultConfig,
defaultMatchHandler,
)

return mevLane, defaultLane
}
Loading