[ENG-653]: Rename to builder module (#41)

This commit is contained in:
David Terpay
2023-04-03 18:53:38 +00:00
committed by GitHub
parent 36c7509d57
commit 61fcd5efdc
33 changed files with 311 additions and 313 deletions
+108
View File
@@ -0,0 +1,108 @@
package ante
import (
"bytes"
"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/mempool"
"github.com/skip-mev/pob/x/builder/keeper"
)
var _ sdk.AnteDecorator = BuilderDecorator{}
type BuilderDecorator struct {
builderKeeper keeper.Keeper
txDecoder sdk.TxDecoder
txEncoder sdk.TxEncoder
mempool *mempool.AuctionMempool
}
func NewBuilderDecorator(ak keeper.Keeper, txDecoder sdk.TxDecoder, txEncoder sdk.TxEncoder, mempool *mempool.AuctionMempool) BuilderDecorator {
return BuilderDecorator{
builderKeeper: ak,
txDecoder: txDecoder,
txEncoder: txEncoder,
mempool: mempool,
}
}
// AnteHandle validates that the auction bid is valid if one exists. If valid it will deduct the entrance fee from the
// bidder's account.
func (ad BuilderDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
auctionMsg, err := mempool.GetMsgAuctionBidFromTx(tx)
if err != nil {
return ctx, err
}
// Validate the auction bid if one exists.
if auctionMsg != nil {
bidder, err := sdk.AccAddressFromBech32(auctionMsg.Bidder)
if err != nil {
return ctx, errors.Wrapf(err, "invalid bidder address (%s)", auctionMsg.Bidder)
}
transactions := make([]sdk.Tx, len(auctionMsg.Transactions))
for i, tx := range auctionMsg.Transactions {
decodedTx, err := ad.txDecoder(tx)
if err != nil {
return ctx, errors.Wrapf(err, "failed to decode transaction (%s)", tx)
}
transactions[i] = decodedTx
}
topBid := sdk.NewCoins()
// If the current transaction is the highest bidding transaction, then the highest bid is empty.
isTopBidTx, err := ad.IsTopBidTx(ctx, tx)
if err != nil {
return ctx, errors.Wrap(err, "failed to check if current transaction is highest bidding transaction")
}
if !isTopBidTx {
// Set the top bid to the highest bidding transaction.
topBid, err = ad.GetTopAuctionBid(ctx)
if err != nil {
return ctx, errors.Wrap(err, "failed to get highest auction bid")
}
}
if err := ad.builderKeeper.ValidateAuctionMsg(ctx, bidder, auctionMsg.Bid, topBid, transactions); err != nil {
return ctx, errors.Wrap(err, "failed to validate auction bid")
}
}
return next(ctx, tx, simulate)
}
// GetTopAuctionBid returns the highest auction bid if one exists.
func (ad BuilderDecorator) GetTopAuctionBid(ctx sdk.Context) (sdk.Coins, error) {
auctionTx := ad.mempool.GetTopAuctionTx(ctx)
if auctionTx == nil {
return sdk.NewCoins(), nil
}
return auctionTx.(*mempool.WrappedBidTx).GetBid(), nil
}
// IsTopBidTx returns true if the transaction inputted is the highest bidding auction transaction in the mempool.
func (ad BuilderDecorator) IsTopBidTx(ctx sdk.Context, tx sdk.Tx) (bool, error) {
auctionTx := ad.mempool.GetTopAuctionTx(ctx)
if auctionTx == nil {
return false, nil
}
topBidTx := mempool.UnwrapBidTx(auctionTx)
topBidBz, err := ad.txEncoder(topBidTx)
if err != nil {
return false, err
}
currentTxBz, err := ad.txEncoder(tx)
if err != nil {
return false, err
}
return bytes.Equal(topBidBz, currentTxBz), nil
}
+263
View File
@@ -0,0 +1,263 @@
package ante_test
import (
"math/rand"
"testing"
"time"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
"github.com/skip-mev/pob/mempool"
testutils "github.com/skip-mev/pob/testutils"
"github.com/skip-mev/pob/x/builder/ante"
"github.com/skip-mev/pob/x/builder/keeper"
buildertypes "github.com/skip-mev/pob/x/builder/types"
"github.com/stretchr/testify/suite"
)
type AnteTestSuite struct {
suite.Suite
ctx sdk.Context
// mempool setup
encodingConfig testutils.EncodingConfig
random *rand.Rand
// builder setup
builderKeeper keeper.Keeper
bankKeeper *testutils.MockBankKeeper
accountKeeper *testutils.MockAccountKeeper
distrKeeper *testutils.MockDistributionKeeper
stakingKeeper *testutils.MockStakingKeeper
builderDecorator ante.BuilderDecorator
key *storetypes.KVStoreKey
authorityAccount sdk.AccAddress
}
func TestAnteTestSuite(t *testing.T) {
suite.Run(t, new(AnteTestSuite))
}
func (suite *AnteTestSuite) SetupTest() {
// General config
suite.encodingConfig = testutils.CreateTestEncodingConfig()
suite.random = rand.New(rand.NewSource(time.Now().Unix()))
suite.key = storetypes.NewKVStoreKey(buildertypes.StoreKey)
testCtx := testutil.DefaultContextWithDB(suite.T(), suite.key, storetypes.NewTransientStoreKey("transient_test"))
suite.ctx = testCtx.Ctx
// Keepers set up
ctrl := gomock.NewController(suite.T())
suite.accountKeeper = testutils.NewMockAccountKeeper(ctrl)
suite.accountKeeper.EXPECT().GetModuleAddress(buildertypes.ModuleName).Return(sdk.AccAddress{}).AnyTimes()
suite.bankKeeper = testutils.NewMockBankKeeper(ctrl)
suite.distrKeeper = testutils.NewMockDistributionKeeper(ctrl)
suite.stakingKeeper = testutils.NewMockStakingKeeper(ctrl)
suite.authorityAccount = sdk.AccAddress([]byte("authority"))
suite.builderKeeper = keeper.NewKeeper(
suite.encodingConfig.Codec,
suite.key,
suite.accountKeeper,
suite.bankKeeper,
suite.distrKeeper,
suite.stakingKeeper,
suite.authorityAccount.String(),
)
err := suite.builderKeeper.SetParams(suite.ctx, buildertypes.DefaultParams())
suite.Require().NoError(err)
}
func (suite *AnteTestSuite) executeAnteHandler(tx sdk.Tx, balance sdk.Coins) (sdk.Context, error) {
signer := tx.GetMsgs()[0].GetSigners()[0]
suite.bankKeeper.EXPECT().GetAllBalances(suite.ctx, signer).AnyTimes().Return(balance)
next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
return ctx, nil
}
return suite.builderDecorator.AnteHandle(suite.ctx, tx, false, next)
}
func (suite *AnteTestSuite) TestAnteHandler() {
var (
// Bid set up
bidder = testutils.RandomAccounts(suite.random, 1)[0]
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000)))
signers = []testutils.Account{bidder}
// Top bidding auction tx set up
topBidder = testutils.RandomAccounts(suite.random, 1)[0]
topBid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
insertTopBid = true
// Auction setup
maxBundleSize uint32 = 5
reserveFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
minBuyInFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
minBidIncrement = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
frontRunningProtection = true
)
cases := []struct {
name string
malleate func()
pass bool
}{
{
"empty mempool, valid bid",
func() {
insertTopBid = false
},
true,
},
{
"smaller bid than winning bid, invalid auction tx",
func() {
insertTopBid = true
topBid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100000)))
},
false,
},
{
"bidder has insufficient balance, invalid auction tx",
func() {
insertTopBid = false
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10)))
},
false,
},
{
"bid is smaller than reserve fee, invalid auction tx",
func() {
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(101)))
reserveFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
},
false,
},
{
"bid is greater than reserve fee but has insufficient balance to pay the buy in fee",
func() {
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(101)))
reserveFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
minBuyInFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
},
false,
},
{
"valid auction bid tx",
func() {
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
reserveFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
minBuyInFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
},
true,
},
{
"auction tx is the top bidding tx",
func() {
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
reserveFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
minBuyInFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(100)))
insertTopBid = true
topBidder = bidder
topBid = bid
signers = []testutils.Account{}
},
true,
},
{
"invalid frontrunning auction bid tx",
func() {
randomAccount := testutils.RandomAccounts(suite.random, 2)
bidder := randomAccount[0]
otherUser := randomAccount[1]
insertTopBid = false
signers = []testutils.Account{bidder, otherUser}
},
false,
},
{
"valid frontrunning auction bid tx",
func() {
randomAccount := testutils.RandomAccounts(suite.random, 2)
bidder := randomAccount[0]
otherUser := randomAccount[1]
signers = []testutils.Account{bidder, otherUser}
frontRunningProtection = false
},
true,
},
{
"invalid sandwiching auction bid tx",
func() {
randomAccount := testutils.RandomAccounts(suite.random, 2)
bidder := randomAccount[0]
otherUser := randomAccount[1]
signers = []testutils.Account{bidder, otherUser, bidder}
frontRunningProtection = true
},
false,
},
{
"invalid auction bid tx with many signers",
func() {
signers = testutils.RandomAccounts(suite.random, 10)
frontRunningProtection = true
},
false,
},
}
for _, tc := range cases {
suite.Run(tc.name, func() {
suite.SetupTest()
tc.malleate()
// Set the auction params
err := suite.builderKeeper.SetParams(suite.ctx, buildertypes.Params{
MaxBundleSize: maxBundleSize,
ReserveFee: reserveFee,
MinBuyInFee: minBuyInFee,
MinBidIncrement: minBidIncrement,
FrontRunningProtection: frontRunningProtection,
})
suite.Require().NoError(err)
// Insert the top bid into the mempool
mempool := mempool.NewAuctionMempool(suite.encodingConfig.TxConfig.TxDecoder(), 0)
if insertTopBid {
topAuctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, topBidder, topBid, 0, []testutils.Account{})
suite.Require().NoError(err)
suite.Require().Equal(0, mempool.CountTx())
suite.Require().Equal(0, mempool.CountAuctionTx())
suite.Require().NoError(mempool.Insert(suite.ctx, topAuctionTx))
suite.Require().Equal(1, mempool.CountTx())
suite.Require().Equal(1, mempool.CountAuctionTx())
}
// Create the actual auction tx and insert into the mempool
auctionTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, bidder, bid, 0, signers)
suite.Require().NoError(err)
// Execute the ante handler
suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxDecoder(), suite.encodingConfig.TxConfig.TxEncoder(), mempool)
_, err = suite.executeAnteHandler(auctionTx, balance)
if tc.pass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}
+156
View File
@@ -0,0 +1,156 @@
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// ValidateAuctionMsg validates that the MsgAuctionBid can be included in the auction.
func (k Keeper) ValidateAuctionMsg(ctx sdk.Context, bidder sdk.AccAddress, bid, highestBid sdk.Coins, transactions []sdk.Tx) error {
// Validate the bundle size.
maxBundleSize, err := k.GetMaxBundleSize(ctx)
if err != nil {
return err
}
if uint32(len(transactions)) > maxBundleSize {
return fmt.Errorf("bundle size (%d) exceeds max bundle size (%d)", len(transactions), maxBundleSize)
}
// Validate the bid amount.
if err := k.ValidateAuctionBid(ctx, bidder, bid, highestBid); err != nil {
return err
}
// Validate the bundle of transactions if front-running protection is enabled.
protectionEnabled, err := k.FrontRunningProtectionEnabled(ctx)
if err != nil {
return err
}
if protectionEnabled {
if err := k.ValidateAuctionBundle(bidder, transactions); err != nil {
return err
}
}
return nil
}
// ValidateAuctionBid validates that the bidder has sufficient funds to participate in the auction and that the bid amount
// is sufficiently high enough.
func (k Keeper) ValidateAuctionBid(ctx sdk.Context, bidder sdk.AccAddress, bid, highestBid sdk.Coins) error {
// Ensure the bid is greater than the highest bid + min bid increment.
minBidIncrement, err := k.GetMinBidIncrement(ctx)
if err != nil {
return err
}
minBid := highestBid.Add(minBidIncrement...)
if !bid.IsAllGTE(minBid) {
return fmt.Errorf("bid amount (%s) is less than the highest bid (%s) + min bid increment (%s)", bid, highestBid, minBidIncrement)
}
// Get the bid floor.
reserveFee, err := k.GetReserveFee(ctx)
if err != nil {
return err
}
if !bid.IsAllGTE(reserveFee) {
return fmt.Errorf("bid amount (%s) is less than the reserve fee (%s)", bid, reserveFee)
}
// Get the pay-to-play fee.
minBuyInFee, err := k.GetMinBuyInFee(ctx)
if err != nil {
return err
}
// Ensure the bidder has enough funds to cover all the inclusion fees.
minBalance := bid.Add(minBuyInFee...)
balances := k.bankKeeper.GetAllBalances(ctx, bidder)
if !balances.IsAllGTE(minBalance) {
return fmt.Errorf("insufficient funds to bid %s (reserve fee + bid) with balance %s", minBalance, balances)
}
return nil
}
// ValidateAuctionBundle validates the ordering of the referenced transactions. Bundles are valid if
// 1. all of the transactions are signed by the signer.
// 2. some subset of contiguous transactions starting from the first tx are signed by the same signer, and all other tranasctions
// are signed by the bidder.
//
// example:
// 1. valid: [tx1, tx2, tx3] where tx1 is signed by the signer 1 and tx2 and tx3 are signed by the bidder.
// 2. valid: [tx1, tx2, tx3, tx4] where tx1 - tx4 are signed by the bidder.
// 3. invalid: [tx1, tx2, tx3] where tx1 and tx3 are signed by the bidder and tx2 is signed by some other signer. (possible sandwich attack)
// 4. invalid: [tx1, tx2, tx3] where tx1 is signed by the bidder, and tx2 - tx3 are signed by some other signer. (possible front-running attack)
func (k Keeper) ValidateAuctionBundle(bidder sdk.AccAddress, transactions []sdk.Tx) error {
if len(transactions) <= 1 {
return nil
}
// prevSigners is used to track whether the signers of the current transaction overlap.
prevSigners, err := k.getTxSigners(transactions[0])
if err != nil {
return err
}
seenBidder := prevSigners[bidder.String()]
// Check that all subsequent transactions are signed by either
// 1. the same party as the first transaction
// 2. the same party for some arbitrary number of txs and then are all remaining txs are signed by the bidder.
for _, refTx := range transactions[1:] {
txSigners, err := k.getTxSigners(refTx)
if err != nil {
return err
}
// Filter the signers to only those that signed the current transaction.
filterSigners(prevSigners, txSigners)
// If there are no overlapping signers from the previous tx and the bidder address has not been seen, then the bundle can still be valid
// as long as all subsequent transactions are signed by the bidder.
if len(prevSigners) == 0 {
if seenBidder {
return fmt.Errorf("bundle contains transactions signed by multiple parties; possible front-running or sandwich attack")
}
seenBidder = true
prevSigners = map[string]bool{bidder.String(): true}
filterSigners(prevSigners, txSigners)
if len(prevSigners) == 0 {
return fmt.Errorf("bundle contains transactions signed by multiple parties; possible front-running or sandwich attack")
}
}
}
return nil
}
// getTxSigners returns the signers of a transaction.
func (k Keeper) getTxSigners(tx sdk.Tx) (map[string]bool, error) {
signers := make(map[string]bool, 0)
for _, msg := range tx.GetMsgs() {
for _, signer := range msg.GetSigners() {
// TODO: check for multi-sig accounts
// https://github.com/skip-mev/pob/issues/14
signers[signer.String()] = true
}
}
return signers, nil
}
// filterSigners removes any signers from the currentSigners map that are not in the txSigners map.
func filterSigners(currentSigners, txSigners map[string]bool) {
for signer := range currentSigners {
if _, ok := txSigners[signer]; !ok {
delete(currentSigners, signer)
}
}
}
+302
View File
@@ -0,0 +1,302 @@
package keeper_test
import (
"math/rand"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
testutils "github.com/skip-mev/pob/testutils"
"github.com/skip-mev/pob/x/builder/keeper"
buildertypes "github.com/skip-mev/pob/x/builder/types"
)
func (suite *KeeperTestSuite) TestValidateAuctionMsg() {
var (
// Tx building variables
accounts = []testutils.Account{} // tracks the order of signers in the bundle
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
// Auction params
maxBundleSize uint32 = 10
reserveFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
minBuyInFee = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
minBidIncrement = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
escrowAddress = sdk.AccAddress([]byte("escrow"))
frontRunningProtection = true
// mempool variables
highestBid = sdk.NewCoins()
)
rnd := rand.New(rand.NewSource(time.Now().Unix()))
bidder := testutils.RandomAccounts(rnd, 1)[0]
cases := []struct {
name string
malleate func()
pass bool
}{
{
"insufficient bid amount",
func() {
bid = sdk.NewCoins()
},
false,
},
{
"insufficient balance",
func() {
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
balance = sdk.NewCoins()
},
false,
},
{
"bid amount equals the balance (not accounting for the reserve fee)",
func() {
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(2000)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(2000)))
},
false,
},
{
"too many transactions in the bundle",
func() {
// reset the balance and bid to their original values
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1000)))
balance = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000)))
accounts = testutils.RandomAccounts(rnd, int(maxBundleSize+1))
},
false,
},
{
"frontrunning bundle",
func() {
randomAccount := testutils.RandomAccounts(rnd, 1)[0]
accounts = []testutils.Account{bidder, randomAccount}
},
false,
},
{
"sandwiching bundle",
func() {
randomAccount := testutils.RandomAccounts(rnd, 1)[0]
accounts = []testutils.Account{bidder, randomAccount, bidder}
},
false,
},
{
"valid bundle",
func() {
randomAccount := testutils.RandomAccounts(rnd, 1)[0]
accounts = []testutils.Account{randomAccount, randomAccount, bidder, bidder, bidder}
},
true,
},
{
"valid bundle with only bidder txs",
func() {
accounts = []testutils.Account{bidder, bidder, bidder, bidder}
},
true,
},
{
"valid bundle with only random txs from single same user",
func() {
randomAccount := testutils.RandomAccounts(rnd, 1)[0]
accounts = []testutils.Account{randomAccount, randomAccount, randomAccount, randomAccount}
},
true,
},
{
"invalid bundle with random accounts",
func() {
accounts = testutils.RandomAccounts(rnd, 2)
},
false,
},
{
"disabled front-running protection",
func() {
accounts = testutils.RandomAccounts(rnd, 10)
frontRunningProtection = false
},
true,
},
{
"invalid bundle that does not outbid the highest bid",
func() {
accounts = []testutils.Account{bidder, bidder, bidder}
highestBid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(500)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(500)))
},
false,
},
{
"valid bundle that outbids the highest bid",
func() {
highestBid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(500)))
bid = sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(1500)))
},
true,
},
}
for _, tc := range cases {
suite.Run(tc.name, func() {
suite.SetupTest() // reset
tc.malleate()
// Set up the new builder keeper with mocks customized for this test case
suite.bankKeeper.EXPECT().GetAllBalances(suite.ctx, bidder.Address).Return(balance).AnyTimes()
suite.bankKeeper.EXPECT().SendCoins(suite.ctx, bidder.Address, escrowAddress, reserveFee).Return(nil).AnyTimes()
suite.builderKeeper = keeper.NewKeeper(
suite.encCfg.Codec,
suite.key,
suite.accountKeeper,
suite.bankKeeper,
suite.distrKeeper,
suite.stakingKeeper,
suite.authorityAccount.String(),
)
params := buildertypes.Params{
MaxBundleSize: maxBundleSize,
ReserveFee: reserveFee,
MinBuyInFee: minBuyInFee,
EscrowAccountAddress: escrowAddress.String(),
FrontRunningProtection: frontRunningProtection,
MinBidIncrement: minBidIncrement,
}
suite.builderKeeper.SetParams(suite.ctx, params)
// Create the bundle of transactions ordered by accounts
bundle := make([]sdk.Tx, 0)
for _, acc := range accounts {
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, acc, 0, 1)
suite.Require().NoError(err)
bundle = append(bundle, tx)
}
err := suite.builderKeeper.ValidateAuctionMsg(suite.ctx, bidder.Address, bid, highestBid, bundle)
if tc.pass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestValidateBundle() {
// TODO: Update this to be multi-dimensional to test multi-sig
// https://github.com/skip-mev/pob/issues/14
var accounts []testutils.Account // tracks the order of signers in the bundle
rng := rand.New(rand.NewSource(time.Now().Unix()))
bidder := testutils.RandomAccounts(rng, 1)[0]
cases := []struct {
name string
malleate func()
pass bool
}{
{
"valid empty bundle",
func() {
accounts = make([]testutils.Account, 0)
},
true,
},
{
"valid single tx bundle",
func() {
accounts = []testutils.Account{bidder}
},
true,
},
{
"valid multi-tx bundle by same account",
func() {
accounts = []testutils.Account{bidder, bidder, bidder, bidder}
},
true,
},
{
"valid single-tx bundle by a different account",
func() {
randomAccount := testutils.RandomAccounts(rng, 1)[0]
accounts = []testutils.Account{randomAccount}
},
true,
},
{
"valid multi-tx bundle by a different accounts",
func() {
randomAccount := testutils.RandomAccounts(rng, 1)[0]
accounts = []testutils.Account{randomAccount, bidder}
},
true,
},
{
"invalid frontrunning bundle",
func() {
randomAccount := testutils.RandomAccounts(rng, 1)[0]
accounts = []testutils.Account{bidder, randomAccount}
},
false,
},
{
"invalid sandwiching bundle",
func() {
randomAccount := testutils.RandomAccounts(rng, 1)[0]
accounts = []testutils.Account{bidder, randomAccount, bidder}
},
false,
},
{
"invalid multi account bundle",
func() {
accounts = testutils.RandomAccounts(rng, 3)
},
false,
},
{
"invalid multi account bundle without bidder",
func() {
randomAccount1 := testutils.RandomAccounts(rng, 1)[0]
randomAccount2 := testutils.RandomAccounts(rng, 1)[0]
accounts = []testutils.Account{randomAccount1, randomAccount2}
},
false,
},
}
for _, tc := range cases {
suite.Run(tc.name, func() {
suite.SetupTest() // reset
// Malleate the test case
tc.malleate()
// Create the bundle of transactions ordered by accounts
bundle := make([]sdk.Tx, 0)
for _, acc := range accounts {
// Create a random tx
tx, err := testutils.CreateRandomTx(suite.encCfg.TxConfig, acc, 0, 1)
suite.Require().NoError(err)
bundle = append(bundle, tx)
}
// Validate the bundle
err := suite.builderKeeper.ValidateAuctionBundle(bidder.Address, bundle)
if tc.pass {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}
+25
View File
@@ -0,0 +1,25 @@
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/x/builder/types"
)
// InitGenesis initializes the builder module's state from a given genesis state.
func (k Keeper) InitGenesis(ctx sdk.Context, gs types.GenesisState) {
// Set the builder module's parameters.
if err := k.SetParams(ctx, gs.Params); err != nil {
panic(err)
}
}
// ExportGenesis returns a GenesisState for a given context.
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
// Get the builder module's parameters.
params, err := k.GetParams(ctx)
if err != nil {
panic(err)
}
return types.NewGenesisState(params)
}
+32
View File
@@ -0,0 +1,32 @@
package keeper
import (
"context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/x/builder/types"
)
var _ types.QueryServer = QueryServer{}
// QueryServer defines the builder module's gRPC querier service.
type QueryServer struct {
keeper Keeper
}
// NewQueryServer creates a new gRPC query server for the builder module.
func NewQueryServer(keeper Keeper) *QueryServer {
return &QueryServer{keeper: keeper}
}
// Params queries all parameters of the builder module.
func (q QueryServer) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
params, err := q.keeper.GetParams(ctx)
if err != nil {
return nil, err
}
return &types.QueryParamsResponse{Params: params}, nil
}
+172
View File
@@ -0,0 +1,172 @@
package keeper
import (
"fmt"
"github.com/cometbft/cometbft/libs/log"
"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/x/builder/types"
)
type Keeper struct {
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
bankKeeper types.BankKeeper
distrKeeper types.DistributionKeeper
stakingKeeper types.StakingKeeper
// The address that is capable of executing a MsgUpdateParams message.
// Typically this will be the governance module's address.
authority string
}
func NewKeeper(
cdc codec.BinaryCodec,
storeKey storetypes.StoreKey,
accountKeeper types.AccountKeeper,
bankKeeper types.BankKeeper,
distrKeeper types.DistributionKeeper,
stakingKeeper types.StakingKeeper,
authority string,
) Keeper {
// Ensure that the authority address is valid.
if _, err := sdk.AccAddressFromBech32(authority); err != nil {
panic(err)
}
// Ensure that the builder module account exists.
if accountKeeper.GetModuleAddress(types.ModuleName) == nil {
panic("builder module account has not been set")
}
return Keeper{
cdc: cdc,
storeKey: storeKey,
bankKeeper: bankKeeper,
distrKeeper: distrKeeper,
stakingKeeper: stakingKeeper,
authority: authority,
}
}
// Logger returns a builder module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+types.ModuleName)
}
// GetAuthority returns the address that is capable of executing a MsgUpdateParams message.
func (k Keeper) GetAuthority() string {
return k.authority
}
// GetParams returns the builder module's parameters.
func (k Keeper) GetParams(ctx sdk.Context) (types.Params, error) {
store := ctx.KVStore(k.storeKey)
key := types.KeyParams
bz := store.Get(key)
if len(bz) == 0 {
return types.Params{}, fmt.Errorf("no params found for the builder module")
}
params := types.Params{}
if err := params.Unmarshal(bz); err != nil {
return types.Params{}, err
}
return params, nil
}
// SetParams sets the builder module's parameters.
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error {
store := ctx.KVStore(k.storeKey)
bz, err := params.Marshal()
if err != nil {
return err
}
store.Set(types.KeyParams, bz)
return nil
}
// GetMaxBundleSize returns the maximum number of transactions that can be included in a bundle.
func (k Keeper) GetMaxBundleSize(ctx sdk.Context) (uint32, error) {
params, err := k.GetParams(ctx)
if err != nil {
return 0, err
}
return params.MaxBundleSize, nil
}
// GetEscrowAccount returns the builder module's escrow account.
func (k Keeper) GetEscrowAccount(ctx sdk.Context) (sdk.AccAddress, error) {
params, err := k.GetParams(ctx)
if err != nil {
return nil, err
}
account, err := sdk.AccAddressFromBech32(params.EscrowAccountAddress)
if err != nil {
return nil, err
}
return account, nil
}
// GetReserveFee returns the reserve fee of the builder module.
func (k Keeper) GetReserveFee(ctx sdk.Context) (sdk.Coins, error) {
params, err := k.GetParams(ctx)
if err != nil {
return sdk.NewCoins(), err
}
return params.ReserveFee, nil
}
// GetMinBuyInFee returns the fee that the bidder must pay to enter the builder.
func (k Keeper) GetMinBuyInFee(ctx sdk.Context) (sdk.Coins, error) {
params, err := k.GetParams(ctx)
if err != nil {
return sdk.NewCoins(), err
}
return params.MinBuyInFee, nil
}
// GetMinBidIncrement returns the minimum bid increment for the builder.
func (k Keeper) GetMinBidIncrement(ctx sdk.Context) (sdk.Coins, error) {
params, err := k.GetParams(ctx)
if err != nil {
return sdk.NewCoins(), err
}
return params.MinBidIncrement, nil
}
// GetProposerFee returns the proposer fee for the builder module.
func (k Keeper) GetProposerFee(ctx sdk.Context) (sdk.Dec, error) {
params, err := k.GetParams(ctx)
if err != nil {
return sdk.ZeroDec(), err
}
return params.ProposerFee, nil
}
// FrontRunningProtectionEnabled returns true if front-running protection is enabled.
func (k Keeper) FrontRunningProtectionEnabled(ctx sdk.Context) (bool, error) {
params, err := k.GetParams(ctx)
if err != nil {
return false, err
}
return params.FrontRunningProtection, nil
}
+69
View File
@@ -0,0 +1,69 @@
package keeper_test
import (
"testing"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
"github.com/skip-mev/pob/mempool"
testutils "github.com/skip-mev/pob/testutils"
"github.com/skip-mev/pob/x/builder/keeper"
"github.com/skip-mev/pob/x/builder/types"
"github.com/stretchr/testify/suite"
)
type KeeperTestSuite struct {
suite.Suite
builderKeeper keeper.Keeper
bankKeeper *testutils.MockBankKeeper
accountKeeper *testutils.MockAccountKeeper
distrKeeper *testutils.MockDistributionKeeper
stakingKeeper *testutils.MockStakingKeeper
encCfg testutils.EncodingConfig
ctx sdk.Context
msgServer types.MsgServer
key *storetypes.KVStoreKey
authorityAccount sdk.AccAddress
mempool *mempool.AuctionMempool
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
func (suite *KeeperTestSuite) SetupTest() {
suite.encCfg = testutils.CreateTestEncodingConfig()
suite.key = storetypes.NewKVStoreKey(types.StoreKey)
testCtx := testutil.DefaultContextWithDB(suite.T(), suite.key, storetypes.NewTransientStoreKey("transient_test"))
suite.ctx = testCtx.Ctx
ctrl := gomock.NewController(suite.T())
suite.accountKeeper = testutils.NewMockAccountKeeper(ctrl)
suite.accountKeeper.EXPECT().GetModuleAddress(types.ModuleName).Return(sdk.AccAddress{}).AnyTimes()
suite.bankKeeper = testutils.NewMockBankKeeper(ctrl)
suite.distrKeeper = testutils.NewMockDistributionKeeper(ctrl)
suite.stakingKeeper = testutils.NewMockStakingKeeper(ctrl)
suite.authorityAccount = sdk.AccAddress([]byte("authority"))
suite.builderKeeper = keeper.NewKeeper(
suite.encCfg.Codec,
suite.key,
suite.accountKeeper,
suite.bankKeeper,
suite.distrKeeper,
suite.stakingKeeper,
suite.authorityAccount.String(),
)
err := suite.builderKeeper.SetParams(suite.ctx, types.DefaultParams())
suite.Require().NoError(err)
suite.mempool = mempool.NewAuctionMempool(suite.encCfg.TxConfig.TxDecoder(), 0)
suite.msgServer = keeper.NewMsgServerImpl(suite.builderKeeper)
}
+97
View File
@@ -0,0 +1,97 @@
package keeper
import (
"context"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/x/builder/types"
)
var _ types.MsgServer = MsgServer{}
// MsgServer is the wrapper for the builder module's msg service.
type MsgServer struct {
Keeper
}
// NewMsgServerImpl returns an implementation of the builder MsgServer interface.
func NewMsgServerImpl(keeper Keeper) *MsgServer {
return &MsgServer{Keeper: keeper}
}
func (m MsgServer) AuctionBid(goCtx context.Context, msg *types.MsgAuctionBid) (*types.MsgAuctionBidResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// This should never return an error because the address was validated when
// the message was ingressed.
bidder, err := sdk.AccAddressFromBech32(msg.Bidder)
if err != nil {
return nil, err
}
// Ensure that the number of transactions is less than or equal to the maximum
// allowed.
maxBundleSize, err := m.GetMaxBundleSize(ctx)
if err != nil {
return nil, err
}
if uint32(len(msg.Transactions)) > maxBundleSize {
return nil, fmt.Errorf("the number of transactions in the bid is greater than the maximum allowed; expected <= %d, got %d", maxBundleSize, len(msg.Transactions))
}
proposerFee, err := m.GetProposerFee(ctx)
if err != nil {
return nil, err
}
escrow, err := m.Keeper.GetEscrowAccount(ctx)
if err != nil {
return nil, err
}
if proposerFee.IsZero() {
// send the entire bid to the escrow account when no proposer fee is set
if err := m.bankKeeper.SendCoins(ctx, bidder, escrow, msg.Bid); err != nil {
return nil, err
}
} else {
prevPropConsAddr := m.distrKeeper.GetPreviousProposerConsAddr(ctx)
prevProposer := m.stakingKeeper.ValidatorByConsAddr(ctx, prevPropConsAddr)
// determine the amount of the bid that goes to the (previous) proposer
bid := sdk.NewDecCoinsFromCoins(msg.Bid...)
proposerReward, _ := bid.MulDecTruncate(proposerFee).TruncateDecimal()
if err := m.bankKeeper.SendCoins(ctx, bidder, sdk.AccAddress(prevProposer.GetOperator()), proposerReward); err != nil {
return nil, err
}
// Determine the amount of the remaining bid that goes to the escrow account.
// If a decimal remainder exists, it'll stay with the bidding account.
escrowTotal := bid.Sub(sdk.NewDecCoinsFromCoins(proposerReward...))
escrowReward, _ := escrowTotal.TruncateDecimal()
if err := m.bankKeeper.SendCoins(ctx, bidder, escrow, escrowReward); err != nil {
return nil, err
}
}
return &types.MsgAuctionBidResponse{}, nil
}
func (m MsgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// ensure that the message signer is the authority
if msg.Authority != m.Keeper.GetAuthority() {
return nil, fmt.Errorf("this message can only be executed by the authority; expected %s, got %s", m.Keeper.GetAuthority(), msg.Authority)
}
if err := m.Keeper.SetParams(ctx, msg.Params); err != nil {
return nil, err
}
return &types.MsgUpdateParamsResponse{}, nil
}
+128
View File
@@ -0,0 +1,128 @@
package keeper_test
import (
"math/rand"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
testutils "github.com/skip-mev/pob/testutils"
"github.com/skip-mev/pob/x/builder/types"
)
func (suite *KeeperTestSuite) TestMsgAuctionBid() {
rng := rand.New(rand.NewSource(time.Now().Unix()))
accounts := testutils.RandomAccounts(rng, 4)
bidder := accounts[0]
escrow := accounts[1]
proposerCons := accounts[2]
proposerOperator := accounts[3]
proposer := stakingtypes.Validator{
OperatorAddress: sdk.ValAddress(proposerOperator.Address).String(),
}
testCases := []struct {
name string
msg *types.MsgAuctionBid
malleate func()
expectErr bool
}{
{
name: "invalid bidder address",
msg: &types.MsgAuctionBid{
Bidder: "foo",
},
malleate: func() {},
expectErr: true,
},
{
name: "too many bundled transactions",
msg: &types.MsgAuctionBid{
Bidder: bidder.Address.String(),
Transactions: [][]byte{{0xFF}, {0xFF}, {0xFF}},
},
malleate: func() {
params := types.DefaultParams()
params.MaxBundleSize = 2
suite.builderKeeper.SetParams(suite.ctx, params)
},
expectErr: true,
},
{
name: "valid bundle with no proposer fee",
msg: &types.MsgAuctionBid{
Bidder: bidder.Address.String(),
Bid: sdk.NewCoins(sdk.NewInt64Coin("foo", 1024)),
Transactions: [][]byte{{0xFF}, {0xFF}},
},
malleate: func() {
params := types.DefaultParams()
params.ProposerFee = sdk.ZeroDec()
params.EscrowAccountAddress = escrow.Address.String()
suite.builderKeeper.SetParams(suite.ctx, params)
suite.bankKeeper.EXPECT().
SendCoins(
suite.ctx,
bidder.Address,
escrow.Address,
sdk.NewCoins(sdk.NewInt64Coin("foo", 1024)),
).
Return(nil).
AnyTimes()
},
expectErr: false,
},
{
name: "valid bundle with proposer fee",
msg: &types.MsgAuctionBid{
Bidder: bidder.Address.String(),
Bid: sdk.NewCoins(sdk.NewInt64Coin("foo", 3416)),
Transactions: [][]byte{{0xFF}, {0xFF}},
},
malleate: func() {
params := types.DefaultParams()
params.ProposerFee = sdk.MustNewDecFromStr("0.30")
params.EscrowAccountAddress = escrow.Address.String()
suite.builderKeeper.SetParams(suite.ctx, params)
suite.distrKeeper.EXPECT().
GetPreviousProposerConsAddr(suite.ctx).
Return(proposerCons.ConsKey.PubKey().Address().Bytes())
suite.stakingKeeper.EXPECT().
ValidatorByConsAddr(suite.ctx, sdk.ConsAddress(proposerCons.ConsKey.PubKey().Address().Bytes())).
Return(proposer).
AnyTimes()
suite.bankKeeper.EXPECT().
SendCoins(suite.ctx, bidder.Address, proposerOperator.Address, sdk.NewCoins(sdk.NewInt64Coin("foo", 1024))).
Return(nil)
suite.bankKeeper.EXPECT().
SendCoins(suite.ctx, bidder.Address, escrow.Address, sdk.NewCoins(sdk.NewInt64Coin("foo", 2392))).
Return(nil)
},
expectErr: false,
},
}
for _, tc := range testCases {
suite.Run(tc.name, func() {
tc.malleate()
_, err := suite.msgServer.AuctionBid(suite.ctx, tc.msg)
if tc.expectErr {
suite.Require().Error(err)
} else {
suite.Require().NoError(err)
}
})
}
}
func (suite *KeeperTestSuite) TestMsgUpdateParams() {
suite.T().SkipNow()
}
+123
View File
@@ -0,0 +1,123 @@
package builder
import (
"context"
"encoding/json"
"fmt"
"cosmossdk.io/api/tendermint/abci"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/gorilla/mux"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/skip-mev/pob/x/builder/keeper"
"github.com/skip-mev/pob/x/builder/types"
"github.com/spf13/cobra"
)
var (
_ module.AppModule = AppModule{}
_ module.AppModuleBasic = AppModuleBasic{}
)
// ConsensusVersion defines the current x/builder module consensus version.
const ConsensusVersion = 1
// AppModuleBasic defines the basic application module used by the builder module.
type AppModuleBasic struct {
cdc codec.Codec
}
// Name returns the builder module's name.
func (AppModuleBasic) Name() string {
return types.ModuleName
}
// RegisterLegacyAminoCodec registers the builder module's types on the given LegacyAmino codec.
func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
types.RegisterLegacyAminoCodec(cdc)
}
// RegisterInterfaces registers the builder module's interface types.
func (AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) {
types.RegisterInterfaces(registry)
}
// DefaultGenesis returns default genesis state as raw bytes for the builder module.
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return cdc.MustMarshalJSON(types.DefaultGenesisState())
}
// ValidateGenesis performs genesis state validation for the builder module.
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error {
var genState types.GenesisState
if err := cdc.UnmarshalJSON(bz, &genState); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}
return genState.Validate()
}
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the builder module.
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
panic(err)
}
}
// GetTxCmd returns the root tx command for the builder module.
func (AppModuleBasic) GetTxCmd() *cobra.Command { return nil }
// GetQueryCmd returns no root query command for the builder module.
func (AppModuleBasic) GetQueryCmd() *cobra.Command { return nil }
type AppModule struct {
AppModuleBasic
keeper keeper.Keeper
}
// NewAppModule creates a new AppModule object.
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc},
keeper: keeper,
}
}
// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }
// RegisterServices registers a the gRPC Query and Msg services for the x/builder
// module.
func (am AppModule) RegisterServices(cfc module.Configurator) {
types.RegisterMsgServer(cfc.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
types.RegisterQueryServer(cfc.QueryServer(), keeper.NewQueryServer(am.keeper))
}
func (a AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {}
// RegisterInvariants registers the invariants of the module. If an invariant
// deviates from its predicted value, the InvariantRegistry triggers appropriate
// logic (most often the chain will be halted).
func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {}
// InitGenesis performs the module's genesis initialization for the builder
// module. It returns no validator updates.
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate {
var genState types.GenesisState
cdc.MustUnmarshalJSON(gs, &genState)
am.keeper.InitGenesis(ctx, genState)
return []abci.ValidatorUpdate{}
}
// ExportGenesis returns the builder module's exported genesis state as raw
// JSON bytes.
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
genState := am.keeper.ExportGenesis(ctx)
return cdc.MustMarshalJSON(genState)
}
+53
View File
@@ -0,0 +1,53 @@
package types
import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/legacy"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/msgservice"
authzcodec "github.com/cosmos/cosmos-sdk/x/authz/codec"
govcodec "github.com/cosmos/cosmos-sdk/x/gov/codec"
groupcodec "github.com/cosmos/cosmos-sdk/x/group/codec"
)
var (
amino = codec.NewLegacyAmino()
ModuleCdc = codec.NewAminoCodec(amino)
)
func init() {
RegisterLegacyAminoCodec(amino)
cryptocodec.RegisterCrypto(amino)
sdk.RegisterLegacyAminoCodec(amino)
// Register all Amino interfaces and concrete types on the authz and gov
// Amino codec so that this can later be used to properly serialize MsgGrant,
// MsgExec and MsgSubmitProposal instances.
RegisterLegacyAminoCodec(authzcodec.Amino)
RegisterLegacyAminoCodec(govcodec.Amino)
RegisterLegacyAminoCodec(groupcodec.Amino)
}
// RegisterLegacyAminoCodec registers the necessary x/builder interfaces and
// concrete types on the provided LegacyAmino codec. These types are used for
// Amino JSON serialization.
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
legacy.RegisterAminoMsg(cdc, &MsgAuctionBid{}, "pob/x/builder/MsgAuctionBid")
legacy.RegisterAminoMsg(cdc, &MsgUpdateParams{}, "pob/x/builder/MsgUpdateParams")
cdc.RegisterConcrete(Params{}, "pob/builder/Params", nil)
}
// RegisterInterfaces registers the x/builder interfaces types with the
// interface registry.
func RegisterInterfaces(registry types.InterfaceRegistry) {
registry.RegisterImplementations(
(*sdk.Msg)(nil),
&MsgAuctionBid{},
&MsgUpdateParams{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
+28
View File
@@ -0,0 +1,28 @@
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// BankKeeper defines the expected API contract for the x/auth module.
type AccountKeeper interface {
GetModuleAddress(moduleName string) sdk.AccAddress
}
// BankKeeper defines the expected API contract for the x/bank module.
type BankKeeper interface {
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
}
// DistributionKeeper defines the expected API contract for the x/distribution
// module.
type DistributionKeeper interface {
GetPreviousProposerConsAddr(ctx sdk.Context) sdk.ConsAddress
}
// StakingKeeper defines the expected API contract for the x/staking module.
type StakingKeeper interface {
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI
}
+20
View File
@@ -0,0 +1,20 @@
package types
// NewGenesisState creates a new GenesisState instance.
func NewGenesisState(params Params) *GenesisState {
return &GenesisState{
Params: params,
}
}
// DefaultGenesisState returns the default GenesisState instance.
func DefaultGenesisState() *GenesisState {
return &GenesisState{
Params: DefaultParams(),
}
}
// Validate performs basic validation of the builder module genesis state.
func (gs GenesisState) Validate() error {
return gs.Params.Validate()
}
+837
View File
@@ -0,0 +1,837 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: pob/builder/v1/genesis.proto
package types
import (
fmt "fmt"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/cosmos-sdk/types/tx/amino"
_ "github.com/cosmos/gogoproto/gogoproto"
proto "github.com/cosmos/gogoproto/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// GenesisState defines the genesis state of the x/builder module.
type GenesisState struct {
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (*GenesisState) Descriptor() ([]byte, []int) {
return fileDescriptor_287f1bdff5ccfc33, []int{0}
}
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *GenesisState) XXX_Merge(src proto.Message) {
xxx_messageInfo_GenesisState.Merge(m, src)
}
func (m *GenesisState) XXX_Size() int {
return m.Size()
}
func (m *GenesisState) XXX_DiscardUnknown() {
xxx_messageInfo_GenesisState.DiscardUnknown(m)
}
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
func (m *GenesisState) GetParams() Params {
if m != nil {
return m.Params
}
return Params{}
}
// Params defines the parameters of the x/builder module.
type Params struct {
// max_bundle_size is the maximum number of transactions that can be bundled
// in a single bundle.
MaxBundleSize uint32 `protobuf:"varint,1,opt,name=max_bundle_size,json=maxBundleSize,proto3" json:"max_bundle_size,omitempty"`
// escrow_account_address is the address of the account that will receive a
// portion of the bid proceeds.
EscrowAccountAddress string `protobuf:"bytes,2,opt,name=escrow_account_address,json=escrowAccountAddress,proto3" json:"escrow_account_address,omitempty"`
// reserve_fee specifies the bid floor for the auction.
ReserveFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=reserve_fee,json=reserveFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"reserve_fee"`
// min_buy_in_fee specifies the fee that the bidder must pay to enter the
// auction.
MinBuyInFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=min_buy_in_fee,json=minBuyInFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"min_buy_in_fee"`
// min_bid_increment specifies the minimum amount that the next bid must be
// greater than the previous bid.
MinBidIncrement github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,5,rep,name=min_bid_increment,json=minBidIncrement,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"min_bid_increment"`
// front_running_protection specifies whether front running and sandwich
// attack protection is enabled.
FrontRunningProtection bool `protobuf:"varint,6,opt,name=front_running_protection,json=frontRunningProtection,proto3" json:"front_running_protection,omitempty"`
// proposer_fee defines the portion of the winning bid that goes to the block
// proposer that proposed the block.
ProposerFee github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,7,opt,name=proposer_fee,json=proposerFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"proposer_fee"`
}
func (m *Params) Reset() { *m = Params{} }
func (m *Params) String() string { return proto.CompactTextString(m) }
func (*Params) ProtoMessage() {}
func (*Params) Descriptor() ([]byte, []int) {
return fileDescriptor_287f1bdff5ccfc33, []int{1}
}
func (m *Params) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Params.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Params) XXX_Merge(src proto.Message) {
xxx_messageInfo_Params.Merge(m, src)
}
func (m *Params) XXX_Size() int {
return m.Size()
}
func (m *Params) XXX_DiscardUnknown() {
xxx_messageInfo_Params.DiscardUnknown(m)
}
var xxx_messageInfo_Params proto.InternalMessageInfo
func (m *Params) GetMaxBundleSize() uint32 {
if m != nil {
return m.MaxBundleSize
}
return 0
}
func (m *Params) GetEscrowAccountAddress() string {
if m != nil {
return m.EscrowAccountAddress
}
return ""
}
func (m *Params) GetReserveFee() github_com_cosmos_cosmos_sdk_types.Coins {
if m != nil {
return m.ReserveFee
}
return nil
}
func (m *Params) GetMinBuyInFee() github_com_cosmos_cosmos_sdk_types.Coins {
if m != nil {
return m.MinBuyInFee
}
return nil
}
func (m *Params) GetMinBidIncrement() github_com_cosmos_cosmos_sdk_types.Coins {
if m != nil {
return m.MinBidIncrement
}
return nil
}
func (m *Params) GetFrontRunningProtection() bool {
if m != nil {
return m.FrontRunningProtection
}
return false
}
func init() {
proto.RegisterType((*GenesisState)(nil), "skipmev.pob.builder.v1.GenesisState")
proto.RegisterType((*Params)(nil), "skipmev.pob.builder.v1.Params")
}
func init() { proto.RegisterFile("pob/builder/v1/genesis.proto", fileDescriptor_287f1bdff5ccfc33) }
var fileDescriptor_287f1bdff5ccfc33 = []byte{
// 521 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x93, 0xbf, 0x6e, 0x13, 0x4f,
0x10, 0xc7, 0x7d, 0xbf, 0xf8, 0x67, 0x60, 0x9d, 0x10, 0xe5, 0x14, 0x59, 0x47, 0x40, 0x67, 0x2b,
0x45, 0xb0, 0x22, 0x65, 0x57, 0x0e, 0x20, 0x21, 0x44, 0x63, 0x83, 0x82, 0x22, 0x51, 0x84, 0x4b,
0x47, 0x73, 0xba, 0x3f, 0x13, 0xb3, 0x4a, 0x76, 0xf7, 0xd8, 0xdd, 0x3b, 0xec, 0x88, 0x27, 0xa0,
0xe2, 0x31, 0x10, 0x55, 0x1e, 0x23, 0x65, 0x4a, 0x44, 0x11, 0x90, 0x5d, 0xe4, 0x29, 0x90, 0xd0,
0xee, 0x5e, 0x42, 0x0a, 0x0a, 0x9a, 0x34, 0x77, 0xa7, 0xfd, 0x7e, 0x77, 0x3e, 0x33, 0x73, 0x33,
0xe8, 0x41, 0x21, 0x52, 0x92, 0x96, 0xf4, 0x28, 0x07, 0x49, 0xaa, 0x01, 0x19, 0x03, 0x07, 0x45,
0x15, 0x2e, 0xa4, 0xd0, 0xc2, 0xef, 0xa8, 0x43, 0x5a, 0x30, 0xa8, 0x70, 0x21, 0x52, 0x5c, 0xbb,
0x70, 0x35, 0x58, 0x5b, 0x1d, 0x8b, 0xb1, 0xb0, 0x16, 0x62, 0xbe, 0x9c, 0x7b, 0x2d, 0xcc, 0x84,
0x62, 0x42, 0x91, 0x34, 0x51, 0x40, 0xaa, 0x41, 0x0a, 0x3a, 0x19, 0x90, 0x4c, 0x50, 0x5e, 0xeb,
0x2b, 0x09, 0xa3, 0x5c, 0x10, 0xfb, 0x74, 0x47, 0xeb, 0xaf, 0xd1, 0xe2, 0x2b, 0x47, 0xdc, 0xd7,
0x89, 0x06, 0xff, 0x39, 0x6a, 0x15, 0x89, 0x4c, 0x98, 0x0a, 0xbc, 0x9e, 0xd7, 0x6f, 0x6f, 0x87,
0xf8, 0xef, 0x19, 0xe0, 0x3d, 0xeb, 0x1a, 0x35, 0x4f, 0xcf, 0xbb, 0x8d, 0xa8, 0xbe, 0xb3, 0xfe,
0xab, 0x89, 0x5a, 0x4e, 0xf0, 0x37, 0xd0, 0x32, 0x4b, 0x26, 0x71, 0x5a, 0xf2, 0xfc, 0x08, 0x62,
0x45, 0x8f, 0xc1, 0x46, 0x5c, 0x8a, 0x96, 0x58, 0x32, 0x19, 0xd9, 0xd3, 0x7d, 0x7a, 0x0c, 0xfe,
0x63, 0xd4, 0x01, 0x95, 0x49, 0xf1, 0x21, 0x4e, 0xb2, 0x4c, 0x94, 0x5c, 0xc7, 0x49, 0x9e, 0x4b,
0x50, 0x2a, 0xf8, 0xaf, 0xe7, 0xf5, 0xef, 0x44, 0xab, 0x4e, 0x1d, 0x3a, 0x71, 0xe8, 0x34, 0xff,
0x3d, 0x6a, 0x4b, 0x50, 0x20, 0x2b, 0x88, 0x0f, 0x00, 0x82, 0x85, 0xde, 0x42, 0xbf, 0xbd, 0x7d,
0x0f, 0xbb, 0xfa, 0xb1, 0xa9, 0x1f, 0xd7, 0xf5, 0xe3, 0x17, 0x82, 0xf2, 0xd1, 0x13, 0x93, 0xe6,
0xd7, 0x1f, 0xdd, 0xfe, 0x98, 0xea, 0x77, 0x65, 0x8a, 0x33, 0xc1, 0x48, 0xdd, 0x2c, 0xf7, 0xda,
0x52, 0xf9, 0x21, 0xd1, 0xd3, 0x02, 0x94, 0xbd, 0xa0, 0xbe, 0x5c, 0x9c, 0x6c, 0x7a, 0x11, 0xaa,
0x21, 0x3b, 0x00, 0x7e, 0x89, 0xee, 0x32, 0xca, 0xe3, 0xb4, 0x9c, 0xc6, 0x94, 0x5b, 0x6a, 0xf3,
0x86, 0xa8, 0x6d, 0x46, 0xf9, 0xa8, 0x9c, 0xee, 0x72, 0x83, 0xfd, 0x88, 0x56, 0x2c, 0x96, 0xe6,
0x31, 0xe5, 0x99, 0x04, 0x06, 0x5c, 0x07, 0xff, 0xdf, 0x10, 0x79, 0xd9, 0x90, 0x69, 0xbe, 0x7b,
0x09, 0xf2, 0x9f, 0xa2, 0xe0, 0x40, 0x0a, 0xae, 0x63, 0x59, 0x72, 0x4e, 0xf9, 0x38, 0x36, 0x53,
0x03, 0x99, 0xa6, 0x82, 0x07, 0xad, 0x9e, 0xd7, 0xbf, 0x1d, 0x75, 0xac, 0x1e, 0x39, 0x79, 0xef,
0x4a, 0xf5, 0xdf, 0xa0, 0xc5, 0x42, 0x8a, 0x42, 0x28, 0x90, 0xb6, 0x59, 0xb7, 0xcc, 0xdf, 0x1c,
0x61, 0x93, 0xd7, 0xf7, 0xf3, 0xee, 0xc6, 0x3f, 0xe4, 0xf5, 0x12, 0xb2, 0xa8, 0x7d, 0x19, 0x63,
0x07, 0xe0, 0x59, 0xef, 0xd3, 0xc5, 0xc9, 0xe6, 0xfd, 0x6b, 0xbe, 0xc9, 0xd5, 0xe2, 0xd4, 0xd3,
0x38, 0x3c, 0x9d, 0x85, 0xde, 0xd9, 0x2c, 0xf4, 0x7e, 0xce, 0x42, 0xef, 0xf3, 0x3c, 0x6c, 0x9c,
0xcd, 0xc3, 0xc6, 0xb7, 0x79, 0xd8, 0x78, 0xfb, 0xf0, 0x1a, 0xd0, 0x4c, 0xf4, 0x16, 0x83, 0x8a,
0x98, 0xd5, 0xfb, 0x13, 0xc3, 0x52, 0xd3, 0x96, 0xdd, 0x8b, 0x47, 0xbf, 0x03, 0x00, 0x00, 0xff,
0xff, 0xe5, 0xc0, 0xeb, 0xb3, 0x98, 0x03, 0x00, 0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func (m *Params) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Params) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size := m.ProposerFee.Size()
i -= size
if _, err := m.ProposerFee.MarshalTo(dAtA[i:]); err != nil {
return 0, err
}
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x3a
if m.FrontRunningProtection {
i--
if m.FrontRunningProtection {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x30
}
if len(m.MinBidIncrement) > 0 {
for iNdEx := len(m.MinBidIncrement) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.MinBidIncrement[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x2a
}
}
if len(m.MinBuyInFee) > 0 {
for iNdEx := len(m.MinBuyInFee) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.MinBuyInFee[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x22
}
}
if len(m.ReserveFee) > 0 {
for iNdEx := len(m.ReserveFee) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.ReserveFee[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x1a
}
}
if len(m.EscrowAccountAddress) > 0 {
i -= len(m.EscrowAccountAddress)
copy(dAtA[i:], m.EscrowAccountAddress)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.EscrowAccountAddress)))
i--
dAtA[i] = 0x12
}
if m.MaxBundleSize != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.MaxBundleSize))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *GenesisState) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = m.Params.Size()
n += 1 + l + sovGenesis(uint64(l))
return n
}
func (m *Params) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.MaxBundleSize != 0 {
n += 1 + sovGenesis(uint64(m.MaxBundleSize))
}
l = len(m.EscrowAccountAddress)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
if len(m.ReserveFee) > 0 {
for _, e := range m.ReserveFee {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
if len(m.MinBuyInFee) > 0 {
for _, e := range m.MinBuyInFee {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
if len(m.MinBidIncrement) > 0 {
for _, e := range m.MinBidIncrement {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
if m.FrontRunningProtection {
n += 2
}
l = m.ProposerFee.Size()
n += 1 + l + sovGenesis(uint64(l))
return n
}
func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenesis(x uint64) (n int) {
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *GenesisState) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *Params) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Params: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field MaxBundleSize", wireType)
}
m.MaxBundleSize = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.MaxBundleSize |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field EscrowAccountAddress", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.EscrowAccountAddress = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ReserveFee", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ReserveFee = append(m.ReserveFee, types.Coin{})
if err := m.ReserveFee[len(m.ReserveFee)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MinBuyInFee", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.MinBuyInFee = append(m.MinBuyInFee, types.Coin{})
if err := m.MinBuyInFee[len(m.MinBuyInFee)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field MinBidIncrement", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.MinBidIncrement = append(m.MinBidIncrement, types.Coin{})
if err := m.MinBidIncrement[len(m.MinBidIncrement)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field FrontRunningProtection", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.FrontRunningProtection = bool(v != 0)
case 7:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ProposerFee", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.ProposerFee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGenesis
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthGenesis
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGenesis
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGenesis
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
)
+22
View File
@@ -0,0 +1,22 @@
package types
const (
// ModuleName is the name of the builder module
ModuleName = "builder"
// StoreKey is the default store key for the builder module
StoreKey = ModuleName
// RouterKey is the message route for the builder module
RouterKey = ModuleName
// QuerierRoute is the querier route for the builder module
QuerierRoute = ModuleName
)
const (
prefixParams = iota + 1
)
// KeyParams is the store key for the builder module's parameters.
var KeyParams = []byte{prefixParams}
+74
View File
@@ -0,0 +1,74 @@
package types
import (
fmt "fmt"
"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
_ sdk.Msg = &MsgUpdateParams{}
_ sdk.Msg = &MsgAuctionBid{}
)
// GetSignBytes implements the LegacyMsg interface.
func (m MsgUpdateParams) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
}
// GetSigners returns the expected signers for a MsgUpdateParams message.
func (m MsgUpdateParams) GetSigners() []sdk.AccAddress {
addr, _ := sdk.AccAddressFromBech32(m.Authority)
return []sdk.AccAddress{addr}
}
// ValidateBasic does a sanity check on the provided data.
func (m MsgUpdateParams) ValidateBasic() error {
if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil {
return errors.Wrap(err, "invalid authority address")
}
return m.Params.Validate()
}
// GetSignBytes implements the LegacyMsg interface.
func (m MsgAuctionBid) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&m))
}
// GetSigners returns the expected signers for a MsgAuctionBid message.
func (m MsgAuctionBid) GetSigners() []sdk.AccAddress {
addr, _ := sdk.AccAddressFromBech32(m.Bidder)
return []sdk.AccAddress{addr}
}
// ValidateBasic does a sanity check on the provided data.
func (m MsgAuctionBid) ValidateBasic() error {
if _, err := sdk.AccAddressFromBech32(m.Bidder); err != nil {
return errors.Wrap(err, "invalid bidder address")
}
// Validate the bid.
if m.Bid.IsZero() {
return fmt.Errorf("no bid included")
}
if err := m.Bid.Validate(); err != nil {
return errors.Wrap(err, "invalid bid")
}
// Validate the transactions.
if len(m.Transactions) == 0 {
return fmt.Errorf("no transactions included")
}
for _, tx := range m.Transactions {
if len(tx) == 0 {
return fmt.Errorf("empty transaction included")
}
}
return nil
}
+141
View File
@@ -0,0 +1,141 @@
package types_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/x/builder/types"
)
// TestMsgAuctionBid tests the ValidateBasic method of MsgAuctionBid
func TestMsgAuctionBid(t *testing.T) {
cases := []struct {
description string
msg types.MsgAuctionBid
expectPass bool
}{
{
description: "invalid message with empty bidder",
msg: types.MsgAuctionBid{
Bidder: "",
Bid: sdk.NewCoins(),
Transactions: [][]byte{},
},
expectPass: false,
},
{
description: "invalid message with empty bid",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoins(),
Transactions: [][]byte{},
},
expectPass: false,
},
{
description: "invalid message with empty transactions",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(100))),
Transactions: [][]byte{},
},
expectPass: false,
},
{
description: "valid message",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(100))),
Transactions: [][]byte{[]byte("test")},
},
expectPass: true,
},
{
description: "valid message with multiple transactions",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(100))),
Transactions: [][]byte{[]byte("test"), []byte("test2")},
},
expectPass: true,
},
{
description: "invalid message with empty transaction in transactions",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(100))),
Transactions: [][]byte{[]byte("test"), []byte("")},
},
expectPass: false,
},
}
for _, tc := range cases {
t.Run(tc.description, func(t *testing.T) {
err := tc.msg.ValidateBasic()
if tc.expectPass {
if err != nil {
t.Errorf("expected no error on %s, got %s", tc.description, err)
}
} else {
if err == nil {
t.Errorf("expected error on %s, got none", tc.description)
}
}
})
}
}
// TestMsgUpdateParams tests the ValidateBasic method of MsgUpdateParams
func TestMsgUpdateParams(t *testing.T) {
cases := []struct {
description string
msg types.MsgUpdateParams
expectPass bool
}{
{
description: "invalid message with empty authority address",
msg: types.MsgUpdateParams{
Authority: "",
Params: types.Params{},
},
expectPass: false,
},
{
description: "invalid message with invalid params (invalid escrow address)",
msg: types.MsgUpdateParams{
Authority: sdk.AccAddress([]byte("test")).String(),
Params: types.Params{
EscrowAccountAddress: "test",
},
},
expectPass: false,
},
{
description: "valid message",
msg: types.MsgUpdateParams{
Authority: sdk.AccAddress([]byte("test")).String(),
Params: types.Params{
ProposerFee: sdk.NewDec(1),
EscrowAccountAddress: sdk.AccAddress([]byte("test")).String(),
},
},
expectPass: true,
},
}
for _, tc := range cases {
t.Run(tc.description, func(t *testing.T) {
err := tc.msg.ValidateBasic()
if tc.expectPass {
if err != nil {
t.Errorf("expected no error on %s, got %s", tc.description, err)
}
} else {
if err == nil {
t.Errorf("expected error on %s, got none", tc.description)
}
}
})
}
}
+96
View File
@@ -0,0 +1,96 @@
package types
import (
fmt "fmt"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
DefaultMaxBundleSize uint32 = 2
DefaultEscrowAccountAddress string
DefaultReserveFee = sdk.Coins{}
DefaultMinBuyInFee = sdk.Coins{}
DefaultMinBidIncrement = sdk.Coins{}
DefaultFrontRunningProtection = true
DefaultProposerFee = sdk.ZeroDec()
)
// NewParams returns a new Params instance with the provided values.
func NewParams(
maxBundleSize uint32,
escrowAccountAddress string,
reserveFee, minBuyInFee, minBidIncrement sdk.Coins,
frontRunningProtection bool,
proposerFee sdk.Dec,
) Params {
return Params{
MaxBundleSize: maxBundleSize,
EscrowAccountAddress: escrowAccountAddress,
ReserveFee: reserveFee,
MinBuyInFee: minBuyInFee,
MinBidIncrement: minBidIncrement,
FrontRunningProtection: frontRunningProtection,
ProposerFee: proposerFee,
}
}
// DefaultParams returns the default x/builder parameters.
func DefaultParams() Params {
return NewParams(
DefaultMaxBundleSize,
DefaultEscrowAccountAddress,
DefaultReserveFee,
DefaultMinBuyInFee,
DefaultMinBidIncrement,
DefaultFrontRunningProtection,
DefaultProposerFee,
)
}
// Validate performs basic validation on the parameters.
func (p Params) Validate() error {
if err := validateEscrowAccountAddress(p.EscrowAccountAddress); err != nil {
return err
}
if err := p.ReserveFee.Validate(); err != nil {
return fmt.Errorf("invalid reserve fee (%s)", err)
}
if err := p.MinBuyInFee.Validate(); err != nil {
return fmt.Errorf("invalid minimum buy-in fee (%s)", err)
}
if err := p.MinBidIncrement.Validate(); err != nil {
return fmt.Errorf("invalid minimum bid increment (%s)", err)
}
return validateProposerFee(p.ProposerFee)
}
func validateProposerFee(v sdk.Dec) error {
if v.IsNil() {
return fmt.Errorf("proposer fee cannot be nil: %s", v)
}
if v.IsNegative() {
return fmt.Errorf("proposer fee cannot be negative: %s", v)
}
if v.GT(math.LegacyOneDec()) {
return fmt.Errorf("proposer fee too large: %s", v)
}
return nil
}
// validateEscrowAccountAddress ensures the escrow account address is a valid
// address.
func validateEscrowAccountAddress(account string) error {
// If the escrow account address is set, ensure it is a valid address.
if _, err := sdk.AccAddressFromBech32(account); err != nil {
return fmt.Errorf("invalid escrow account address (%s)", err)
}
return nil
}
+538
View File
@@ -0,0 +1,538 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: pob/builder/v1/query.proto
package types
import (
context "context"
fmt "fmt"
_ "github.com/cosmos/cosmos-sdk/types/query"
_ "github.com/cosmos/gogoproto/gogoproto"
grpc1 "github.com/cosmos/gogoproto/grpc"
proto "github.com/cosmos/gogoproto/proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// QueryParamsRequest is the request type for the Query/Params RPC method.
type QueryParamsRequest struct {
}
func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} }
func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) }
func (*QueryParamsRequest) ProtoMessage() {}
func (*QueryParamsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_fe4920efc6923232, []int{0}
}
func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *QueryParamsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryParamsRequest.Merge(m, src)
}
func (m *QueryParamsRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryParamsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo
// QueryParamsResponse is the response type for the Query/Params RPC method.
type QueryParamsResponse struct {
// params defines the parameters of the module.
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
}
func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} }
func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) }
func (*QueryParamsResponse) ProtoMessage() {}
func (*QueryParamsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_fe4920efc6923232, []int{1}
}
func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *QueryParamsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryParamsResponse.Merge(m, src)
}
func (m *QueryParamsResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryParamsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo
func (m *QueryParamsResponse) GetParams() Params {
if m != nil {
return m.Params
}
return Params{}
}
func init() {
proto.RegisterType((*QueryParamsRequest)(nil), "skipmev.pob.builder.v1.QueryParamsRequest")
proto.RegisterType((*QueryParamsResponse)(nil), "skipmev.pob.builder.v1.QueryParamsResponse")
}
func init() { proto.RegisterFile("pob/builder/v1/query.proto", fileDescriptor_fe4920efc6923232) }
var fileDescriptor_fe4920efc6923232 = []byte{
// 307 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2a, 0xc8, 0x4f, 0xd2,
0x4f, 0x2a, 0xcd, 0xcc, 0x49, 0x49, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa,
0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x2b, 0xce, 0xce, 0x2c, 0xc8, 0x4d, 0x2d, 0xd3,
0x2b, 0xc8, 0x4f, 0xd2, 0x83, 0xaa, 0xd1, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07,
0x2b, 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0xa5, 0x64, 0xd2, 0xf3, 0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x13,
0x0b, 0x32, 0xf5, 0x13, 0xf3, 0xf2, 0xf2, 0x4b, 0x12, 0x4b, 0x32, 0xf3, 0xf3, 0x8a, 0xa1, 0xb2,
0xd2, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0x10, 0xf3, 0xd1, 0x2c, 0x92, 0x92, 0x41, 0x73, 0x44,
0x7a, 0x6a, 0x5e, 0x6a, 0x71, 0x26, 0x54, 0xab, 0x92, 0x08, 0x97, 0x50, 0x20, 0x48, 0x71, 0x40,
0x62, 0x51, 0x62, 0x6e, 0x71, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x52, 0x30, 0x97, 0x30,
0x8a, 0x68, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x90, 0x0d, 0x17, 0x5b, 0x01, 0x58, 0x44, 0x82,
0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x4e, 0x0f, 0xbb, 0x27, 0xf4, 0x20, 0xfa, 0x9c, 0x58, 0x4e,
0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x31, 0x9a, 0xc0, 0xc8, 0xc5, 0x0a, 0x36, 0x55, 0xa8, 0x8d,
0x91, 0x8b, 0x0d, 0xa2, 0x44, 0x48, 0x0b, 0x97, 0x11, 0x98, 0xae, 0x92, 0xd2, 0x26, 0x4a, 0x2d,
0xc4, 0xad, 0x4a, 0xca, 0x1d, 0xcf, 0x37, 0x68, 0x31, 0x36, 0x5d, 0x7e, 0x32, 0x99, 0x49, 0x42,
0x48, 0x4c, 0x1f, 0x2d, 0x10, 0x20, 0x4e, 0x72, 0x72, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23,
0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6,
0x63, 0x39, 0x86, 0x28, 0xf5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d,
0x90, 0xad, 0xba, 0xb9, 0xa9, 0x65, 0x60, 0x43, 0x2a, 0xe0, 0xc6, 0x94, 0x54, 0x16, 0xa4, 0x16,
0x27, 0xb1, 0x81, 0xc3, 0xd1, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x01, 0xac, 0x49, 0x92, 0xec,
0x01, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type QueryClient interface {
// Params queries the parameters of the x/builder module.
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
}
type queryClient struct {
cc grpc1.ClientConn
}
func NewQueryClient(cc grpc1.ClientConn) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) {
out := new(QueryParamsResponse)
err := c.cc.Invoke(ctx, "/skipmev.pob.builder.v1.Query/Params", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// Params queries the parameters of the x/builder module.
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Params not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
}
func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryParamsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).Params(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/skipmev.pob.builder.v1.Query/Params",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "skipmev.pob.builder.v1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Params",
Handler: _Query_Params_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "pob/builder/v1/query.proto",
}
func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
return len(dAtA) - i, nil
}
func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
{
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
return len(dAtA) - i, nil
}
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *QueryParamsRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
return n
}
func (m *QueryParamsResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = m.Params.Size()
n += 1 + l + sovQuery(uint64(l))
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozQuery(x uint64) (n int) {
return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowQuery
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthQuery
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupQuery
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthQuery
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group")
)
+153
View File
@@ -0,0 +1,153 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: pob/builder/v1/query.proto
/*
Package types is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package types
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var _ = metadata.Join
func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryParamsRequest
var metadata runtime.ServerMetadata
msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryParamsRequest
var metadata runtime.ServerMetadata
msg, err := server.Params(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterQueryHandler(ctx, mux, conn)
}
// RegisterQueryHandler registers the http handlers for service Query to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
}
// RegisterQueryHandlerClient registers the http handlers for service Query
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "QueryClient" to call the correct interceptors.
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"pob", "builder", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Query_Params_0 = runtime.ForwardResponseMessage
)
File diff suppressed because it is too large Load Diff
+171
View File
@@ -0,0 +1,171 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: pob/builder/v1/tx.proto
/*
Package types is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package types
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var _ = metadata.Join
var (
filter_Msg_AuctionBid_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Msg_AuctionBid_0(ctx context.Context, marshaler runtime.Marshaler, client MsgClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq MsgAuctionBid
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_AuctionBid_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.AuctionBid(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Msg_AuctionBid_0(ctx context.Context, marshaler runtime.Marshaler, server MsgServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq MsgAuctionBid
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_AuctionBid_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.AuctionBid(ctx, &protoReq)
return msg, metadata, err
}
// RegisterMsgHandlerServer registers the http handlers for service Msg to "mux".
// UnaryRPC :call MsgServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMsgHandlerFromEndpoint instead.
func RegisterMsgHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MsgServer) error {
mux.Handle("POST", pattern_Msg_AuctionBid_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Msg_AuctionBid_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Msg_AuctionBid_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterMsgHandlerFromEndpoint is same as RegisterMsgHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterMsgHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterMsgHandler(ctx, mux, conn)
}
// RegisterMsgHandler registers the http handlers for service Msg to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterMsgHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterMsgHandlerClient(ctx, mux, NewMsgClient(conn))
}
// RegisterMsgHandlerClient registers the http handlers for service Msg
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MsgClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MsgClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "MsgClient" to call the correct interceptors.
func RegisterMsgHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MsgClient) error {
mux.Handle("POST", pattern_Msg_AuctionBid_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Msg_AuctionBid_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Msg_AuctionBid_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Msg_AuctionBid_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"pob", "builder", "v1", "bid"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Msg_AuctionBid_0 = runtime.ForwardResponseMessage
)