chore(v0.50.0): Migrating codebase to latest SDK version (#215)

This commit is contained in:
David Terpay 2023-07-26 17:42:57 -04:00 committed by GitHub
parent b13f5e999d
commit 5dd05d1afb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 2293 additions and 1209 deletions

View File

@ -70,7 +70,20 @@ $(BUILD_TARGETS): $(BUILD_DIR)/
$(BUILD_DIR)/:
mkdir -p $(BUILD_DIR)/
.PHONY: build-test-app
# build-and-start-app builds a POB simulation application binary in the build folder
# and initializes a single validator configuration. If desired, users can suppliment
# other addresses using "genesis add-genesis-account address 10000000000000000000000000stake".
# This will allow users to bootstrap their wallet with a balance.
build-and-start-app: build-test-app
./build/testappd init validator1 --chain-id chain-id-0
./build/testappd keys add validator1
./build/testappd genesis add-genesis-account validator1 10000000000000000000000000stake
./build/testappd genesis add-genesis-account cosmos1see0htr47uapjvcvh0hu6385rp8lw3em24hysg 10000000000000000000000000stake
./build/testappd genesis gentx validator1 1000000000stake --chain-id chain-id-0
./build/testappd genesis collect-gentxs
./build/testappd start --api.enable true --api.enabled-unsafe-cors true --log_level info
.PHONY: build-test-app build-and-start-app
###############################################################################
## Docker ##
@ -92,7 +105,7 @@ test-e2e: $(TEST_E2E_DEPS)
@go test ./tests/e2e/... -mod=readonly -timeout 30m -race -v -tags='$(TEST_E2E_TAGS)'
test:
@go test -v ./...
@go test -v -race $(shell go list ./... | grep -v tests/)
.PHONY: test test-e2e
@ -100,7 +113,7 @@ test:
### Protobuf ###
###############################################################################
protoVer=0.11.6
protoVer=0.13.5
protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer)
protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName)

View File

@ -5,10 +5,11 @@ import (
"testing"
"time"
sdklogger "cosmossdk.io/log"
"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
comettypes "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
@ -64,8 +65,14 @@ func (suite *ABCITestSuite) SetupTest() {
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.WithBlockHeight(1)
suite.logger = log.NewNopLogger()
suite.ctx = testCtx.Ctx.WithBlockHeight(10)
suite.logger = log.NewTestLogger(suite.T())
suite.ctx = suite.ctx.WithConsensusParams(cmtproto.ConsensusParams{
Abci: &cmtproto.ABCIParams{
VoteExtensionsEnableHeight: 1,
},
})
// Lanes configuration
//
@ -75,7 +82,7 @@ func (suite *ABCITestSuite) SetupTest() {
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: suite.anteHandler,
MaxBlockSpace: sdk.ZeroDec(),
MaxBlockSpace: math.LegacyZeroDec(),
}
suite.tobLane = auction.NewTOBLane(
config,
@ -119,7 +126,7 @@ func (suite *ABCITestSuite) SetupTest() {
// Accounts set up
suite.accounts = testutils.RandomAccounts(suite.random, 10)
suite.balance = sdk.NewCoin("foo", sdk.NewInt(1000000000000000000))
suite.balance = sdk.NewCoin("stake", math.NewInt(1000000000000000000))
suite.nonces = make(map[string]uint64)
for _, acc := range suite.accounts {
suite.nonces[acc.Address.String()] = 0
@ -127,7 +134,10 @@ func (suite *ABCITestSuite) SetupTest() {
// Proposal handler set up
suite.proposalHandler = abci.NewProposalHandler(
[]blockbuster.Lane{suite.baseLane}, // only the base lane is used for proposal handling
[]blockbuster.Lane{
suite.tobLane,
suite.baseLane,
},
suite.tobLane,
suite.logger,
suite.encodingConfig.TxConfig.TxEncoder(),
@ -135,7 +145,7 @@ func (suite *ABCITestSuite) SetupTest() {
abci.NoOpValidateVoteExtensionsFn(),
)
suite.voteExtensionHandler = abci.NewVoteExtensionHandler(
sdklogger.NewTestLogger(suite.T()),
log.NewTestLogger(suite.T()),
suite.tobLane,
suite.encodingConfig.TxConfig.TxDecoder(),
suite.encodingConfig.TxConfig.TxEncoder(),
@ -143,8 +153,7 @@ func (suite *ABCITestSuite) SetupTest() {
}
func (suite *ABCITestSuite) anteHandler(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
signer := tx.GetMsgs()[0].GetSigners()[0]
suite.bankKeeper.EXPECT().GetBalance(ctx, signer, suite.balance.Denom).AnyTimes().Return(suite.balance)
suite.bankKeeper.EXPECT().GetBalance(ctx, gomock.Any(), suite.balance.Denom).AnyTimes().Return(suite.balance)
next := func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) {
return ctx, nil
@ -183,8 +192,8 @@ func (suite *ABCITestSuite) fillTOBLane(numTxs int, numBundledTxs int) {
// create a randomized auction transaction
nonce := suite.nonces[acc.Address.String()]
bidAmount := sdk.NewInt(int64(suite.random.Intn(1000) + 1))
bid := sdk.NewCoin("foo", bidAmount)
bidAmount := math.NewInt(int64(suite.random.Intn(1000) + 1))
bid := sdk.NewCoin("stake", bidAmount)
signers := []testutils.Account{}
for j := 0; j < numBundledTxs; j++ {

View File

@ -1,6 +1,7 @@
package abci_test
import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
testutils "github.com/skip-mev/pob/testutils"
buildertypes "github.com/skip-mev/pob/x/builder/types"
@ -29,7 +30,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("stake", math.NewInt(100)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -53,7 +54,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz1, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -63,7 +64,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz2, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("stake", math.NewInt(100)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -89,7 +90,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz1, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -99,7 +100,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz2, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("stake", math.NewInt(100)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -128,7 +129,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz1, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -138,7 +139,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz2, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("stake", math.NewInt(100)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -176,7 +177,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz1, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(1001)),
sdk.NewCoin("stake", math.NewInt(1001)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -186,7 +187,7 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
bidTxBz2, err := testutils.CreateAuctionTxWithSignerBz(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("stake", math.NewInt(100)),
0,
1,
[]testutils.Account{suite.accounts[0]},
@ -244,8 +245,8 @@ func (suite *ABCITestSuite) TestGetBidsFromVoteExtensions() {
func (suite *ABCITestSuite) TestBuildTOB() {
params := buildertypes.Params{
MaxBundleSize: 4,
ReserveFee: sdk.NewCoin("foo", sdk.NewInt(100)),
MinBidIncrement: sdk.NewCoin("foo", sdk.NewInt(100)),
ReserveFee: sdk.NewCoin("stake", math.NewInt(100)),
MinBidIncrement: sdk.NewCoin("stake", math.NewInt(100)),
FrontRunningProtection: true,
}
suite.builderKeeper.SetParams(suite.ctx, params)
@ -268,9 +269,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[0]},
)
suite.Require().NoError(err)
@ -285,9 +286,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(1)),
sdk.NewCoin("stake", math.NewInt(1)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[0]},
)
suite.Require().NoError(err)
@ -302,9 +303,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(1000)),
sdk.NewCoin("stake", math.NewInt(1000)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[0], suite.accounts[1]},
)
suite.Require().NoError(err)
@ -319,9 +320,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{
suite.accounts[0],
suite.accounts[0],
@ -343,9 +344,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[0]},
)
suite.Require().NoError(err)
@ -360,9 +361,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx1, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[0]},
)
suite.Require().NoError(err)
@ -370,9 +371,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx2, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[1],
sdk.NewCoin("foo", sdk.NewInt(102)),
sdk.NewCoin("stake", math.NewInt(102)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[1]},
)
suite.Require().NoError(err)
@ -387,9 +388,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx1, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(1000)),
sdk.NewCoin("stake", math.NewInt(1000)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[0], suite.accounts[1]},
)
suite.Require().NoError(err)
@ -397,9 +398,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx2, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[1],
sdk.NewCoin("foo", sdk.NewInt(200)),
sdk.NewCoin("stake", math.NewInt(200)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[1]},
)
suite.Require().NoError(err)
@ -414,9 +415,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx1, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{
suite.accounts[0],
suite.accounts[0],
@ -431,9 +432,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx2, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[1],
sdk.NewCoin("foo", sdk.NewInt(102)),
sdk.NewCoin("stake", math.NewInt(102)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[1]},
)
suite.Require().NoError(err)
@ -448,9 +449,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx1, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(101)),
sdk.NewCoin("stake", math.NewInt(101)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[0]},
)
suite.Require().NoError(err)
@ -458,9 +459,9 @@ func (suite *ABCITestSuite) TestBuildTOB() {
bidTx2, err := testutils.CreateAuctionTxWithSigners(
suite.encodingConfig.TxConfig,
suite.accounts[1],
sdk.NewCoin("foo", sdk.NewInt(102)),
sdk.NewCoin("stake", math.NewInt(102)),
0,
1,
uint64(suite.ctx.BlockHeight())+2,
[]testutils.Account{suite.accounts[1]},
)
suite.Require().NoError(err)

View File

@ -88,12 +88,13 @@ func (h *ProposalHandler) VerifyTOB(ctx sdk.Context, proposalTxs [][]byte) (*Auc
// verify that the included vote extensions are valid in accordance with the
// the preferences of the application
if err := h.validateVoteExtensionsFn(ctx, ctx.BlockHeight(), lastCommitInfo); err != nil {
cacheCtx, _ := ctx.CacheContext()
if err := h.validateVoteExtensionsFn(cacheCtx, cacheCtx.BlockHeight(), lastCommitInfo); err != nil {
return nil, fmt.Errorf("failed to validate vote extensions: %w", err)
}
// Build the top of block proposal from the auction info.
expectedTOB := h.BuildTOB(ctx, lastCommitInfo, auctionInfo.MaxTxBytes)
expectedTOB := h.BuildTOB(cacheCtx, lastCommitInfo, auctionInfo.MaxTxBytes)
// Verify that the top of block txs matches the top of block proposal txs.
actualTOBTxs := proposalTxs[NumInjectedTxs : auctionInfo.NumTxs+NumInjectedTxs]
@ -151,15 +152,6 @@ func (h *ProposalHandler) buildTOB(ctx sdk.Context, bidTx sdk.Tx, maxBytes int64
return proposal, err
}
maxBytesForLane := utils.GetMaxTxBytesForLane(
proposal.GetMaxTxBytes(),
proposal.GetTotalTxBytes(),
h.tobLane.GetMaxBlockSpace(),
)
if int64(len(txBz)) > maxBytesForLane {
return proposal, fmt.Errorf("bid transaction is too large; got %d, max %d", len(txBz), maxBytes)
}
// Ensure that the bid transaction is valid
if err := h.tobLane.VerifyTx(ctx, bidTx); err != nil {
return proposal, err

View File

@ -1,8 +1,9 @@
package abci
import (
"cosmossdk.io/log"
"cosmossdk.io/math"
cometabci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
"github.com/skip-mev/pob/blockbuster"
@ -36,13 +37,9 @@ type (
// of the top of block lane.
VerifyTx(ctx sdk.Context, tx sdk.Tx) error
// ProcessLaneBasic is utilized to verify the rest of the proposal according to
// the preferences of the top of block lane.
ProcessLaneBasic(txs []sdk.Tx) error
// GetMaxBlockSpace returns the maximum block space that can be used by the top of
// block lane as a percentage of the total block space.
GetMaxBlockSpace() sdk.Dec
GetMaxBlockSpace() math.LegacyDec
// Logger returns the logger for the top of block lane.
Logger() log.Logger
@ -82,11 +79,13 @@ func NewProposalHandler(
tobLane TOBLaneProposal,
logger log.Logger,
txEncoder sdk.TxEncoder,
txDecoder sdk.TxDecoder,
validateVeFN ValidateVoteExtensionsFn,
) *ProposalHandler {
return &ProposalHandler{
prepareLanesHandler: abci.ChainPrepareLanes(lanes...),
// We prepare lanes skipping the first lane because the first lane is the top of block lane.
prepareLanesHandler: abci.ChainPrepareLanes(lanes[1:]...),
processLanesHandler: abci.ChainProcessLanes(lanes...),
tobLane: tobLane,
logger: logger,
@ -97,82 +96,136 @@ func NewProposalHandler(
}
// PrepareProposalHandler returns the PrepareProposal ABCI handler that performs
// top-of-block auctioning and general block proposal construction.
// top-of-block auctioning and general block proposal construction. This handler
// will first attempt to construct the top of the block by utilizing the vote
// extensions from the previous height. If the vote extensions are not available,
// then no top of block auction is performed. After this, the rest of the proposal
// will be constructed by selecting transactions from each lane according to each
// lane's selection logic.
func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
return func(ctx sdk.Context, req cometabci.RequestPrepareProposal) cometabci.ResponsePrepareProposal {
// Build the top of block portion of the proposal given the vote extensions
// from the previous block.
topOfBlock := h.BuildTOB(ctx, req.LocalLastCommit, req.MaxTxBytes)
return func(ctx sdk.Context, req *cometabci.RequestPrepareProposal) (*cometabci.ResponsePrepareProposal, error) {
partialProposal := blockbuster.NewProposal(req.MaxTxBytes)
voteExtensionsEnabled := h.VoteExtensionsEnabled(ctx)
// If information is unable to be marshaled, we return an empty proposal. This will
// cause another proposal to be generated after it is rejected in ProcessProposal.
lastCommitInfo, err := req.LocalLastCommit.Marshal()
if err != nil {
h.logger.Error("failed to marshal last commit info", "err", err)
return cometabci.ResponsePrepareProposal{Txs: nil}
h.logger.Info(
"preparing proposal",
"height", req.Height,
"vote_extensions_enabled", voteExtensionsEnabled,
)
if voteExtensionsEnabled {
// Build the top of block portion of the proposal given the vote extensions
// from the previous height.
partialProposal = h.BuildTOB(ctx, req.LocalLastCommit, req.MaxTxBytes)
h.logger.Info(
"built top of block",
"num_txs", partialProposal.GetNumTxs(),
"size", partialProposal.GetTotalTxBytes(),
)
// If information is unable to be marshaled, we return an empty proposal. This will
// cause another proposal to be generated after it is rejected in ProcessProposal.
lastCommitInfo, err := req.LocalLastCommit.Marshal()
if err != nil {
h.logger.Error("failed to marshal last commit info", "err", err)
return &cometabci.ResponsePrepareProposal{Txs: nil}, err
}
auctionInfo := &AuctionInfo{
ExtendedCommitInfo: lastCommitInfo,
MaxTxBytes: req.MaxTxBytes,
NumTxs: uint64(partialProposal.GetNumTxs()),
}
// Add the auction info and top of block transactions into the proposal.
auctionInfoBz, err := auctionInfo.Marshal()
if err != nil {
h.logger.Error("failed to marshal auction info", "err", err)
return &cometabci.ResponsePrepareProposal{Txs: nil}, err
}
partialProposal.AddVoteExtension(auctionInfoBz)
}
auctionInfo := &AuctionInfo{
ExtendedCommitInfo: lastCommitInfo,
MaxTxBytes: req.MaxTxBytes,
NumTxs: uint64(topOfBlock.GetNumTxs()),
}
// Add the auction info and top of block transactions into the proposal.
auctionInfoBz, err := auctionInfo.Marshal()
if err != nil {
h.logger.Error("failed to marshal auction info", "err", err)
return cometabci.ResponsePrepareProposal{Txs: nil}
}
topOfBlock.AddVoteExtension(auctionInfoBz)
// Prepare the proposal by selecting transactions from each lane according to
// each lane's selection logic.
proposal, err := h.prepareLanesHandler(ctx, topOfBlock)
finalProposal, err := h.prepareLanesHandler(ctx, partialProposal)
if err != nil {
h.logger.Error("failed to prepare proposal", "err", err)
return cometabci.ResponsePrepareProposal{Txs: nil}
return &cometabci.ResponsePrepareProposal{Txs: nil}, err
}
return cometabci.ResponsePrepareProposal{Txs: proposal.GetProposal()}
h.logger.Info(
"prepared proposal",
"num_txs", finalProposal.GetNumTxs(),
"size", finalProposal.GetTotalTxBytes(),
)
return &cometabci.ResponsePrepareProposal{Txs: finalProposal.GetProposal()}, err
}
}
// ProcessProposalHandler returns the ProcessProposal ABCI handler that performs
// block proposal verification.
// block proposal verification. This handler will first attempt to verify the top
// of block transactions by utilizing the vote extensions from the previous height.
// If the vote extensions are not available, then no top of block verification is done.
// After this, the rest of the proposal will be verified according to each lane's
// verification logic.
func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
return func(ctx sdk.Context, req cometabci.RequestProcessProposal) cometabci.ResponseProcessProposal {
proposal := req.Txs
return func(ctx sdk.Context, req *cometabci.RequestProcessProposal) (*cometabci.ResponseProcessProposal, error) {
txs := req.Txs
voteExtensionsEnabled := h.VoteExtensionsEnabled(ctx)
// Verify that the same top of block transactions can be built from the vote
// extensions included in the proposal.
auctionInfo, err := h.VerifyTOB(ctx, proposal)
if err != nil {
h.logger.Error("failed to verify top of block transactions", "err", err)
return cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}
h.logger.Info(
"processing proposal",
"height", req.Height,
"vote_extensions_enabled", voteExtensionsEnabled,
"num_txs", len(req.Txs),
)
// If vote extensions have been enabled, verify that the same top of block transactions can be
// built from the vote extensions included in the proposal. Otherwise verify that the proposal
// is valid according to each lane's verification logic.
if voteExtensionsEnabled {
auctionInfo, err := h.VerifyTOB(ctx, txs)
if err != nil {
h.logger.Error("failed to verify top of block transactions", "err", err)
return &cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}, err
}
h.logger.Info(
"verified top of block",
"num_txs", auctionInfo.NumTxs,
)
txs = req.Txs[NumInjectedTxs:]
}
// Decode the transactions in the proposal.
decodedTxs, err := utils.GetDecodedTxs(h.txDecoder, proposal[NumInjectedTxs:])
decodedTxs, err := utils.GetDecodedTxs(h.txDecoder, txs)
if err != nil {
h.logger.Error("failed to decode transactions", "err", err)
return cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}
}
// Do a basic check of the rest of the proposal to make sure no auction transactions
// are included.
if err := h.tobLane.ProcessLaneBasic(decodedTxs); err != nil {
h.logger.Error("failed to process proposal", "err", err)
return cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}
return &cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}, err
}
// Verify that the rest of the proposal is valid according to each lane's verification logic.
if _, err = h.processLanesHandler(ctx, decodedTxs[auctionInfo.NumTxs:]); err != nil {
if _, err = h.processLanesHandler(ctx, decodedTxs); err != nil {
h.logger.Error("failed to process proposal", "err", err)
return cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}
return &cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}, err
}
return cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_ACCEPT}
return &cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_ACCEPT}, nil
}
}
// VoteExtensionsEnabled determines if vote extensions are enabled for the current block.
func (h *ProposalHandler) VoteExtensionsEnabled(ctx sdk.Context) bool {
cp := ctx.ConsensusParams()
if cp.Abci == nil || cp.Abci.VoteExtensionsEnableHeight == 0 {
return false
}
// We do a > here because the vote extensions are enabled at block height H
// but will only be used at block height H+1.
return ctx.BlockHeight() > cp.Abci.VoteExtensionsEnableHeight
}

View File

@ -1,8 +1,9 @@
package abci_test
import (
"cosmossdk.io/log"
"cosmossdk.io/math"
comettypes "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/abci"
"github.com/skip-mev/pob/blockbuster"
@ -13,8 +14,6 @@ import (
buildertypes "github.com/skip-mev/pob/x/builder/types"
)
// TODO:
// - Add tests that can that trigger a panic for the tob of block lane
func (suite *ABCITestSuite) TestPrepareProposal() {
var (
// the modified transactions cannot exceed this size
@ -28,7 +27,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
// auction configuration
maxBundleSize uint32 = 10
reserveFee = sdk.NewCoin("foo", sdk.NewInt(1000))
reserveFee = sdk.NewCoin("stake", math.NewInt(1000))
frontRunningProtection = true
)
@ -42,7 +41,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
"single valid tob transaction in the mempool",
func() {
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -64,7 +63,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
"single invalid tob transaction in the mempool",
func() {
bidder := suite.accounts[0]
bid := reserveFee.Sub(sdk.NewCoin("foo", sdk.NewInt(1))) // bid is less than the reserve fee
bid := reserveFee.Sub(sdk.NewCoin("stake", math.NewInt(1))) // bid is less than the reserve fee
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -108,7 +107,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -138,7 +137,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create an invalid tob transaction (frontrunning)
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000000000))
bid := sdk.NewCoin("stake", math.NewInt(1000000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder, bidder, suite.accounts[1]}
@ -147,7 +146,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
// Create a valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -170,7 +169,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -179,7 +178,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
// Create a valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -190,6 +189,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
auctionTxs = []sdk.Tx{bidTx, bidTx2}
winningBidTx = bidTx
insertBundledTxs = false
frontRunningProtection = false
},
3,
map[string]int{
@ -198,13 +198,13 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
},
},
{
"multiple tob transactions where the first is valid and bundle is inserted into mempool",
"single tob transactions where the first is valid and bundle is inserted into mempool",
func() {
frontRunningProtection = false
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], suite.accounts[1], bidder, suite.accounts[3], suite.accounts[4]}
@ -227,7 +227,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], suite.accounts[1], bidder, suite.accounts[3], suite.accounts[4]}
@ -269,7 +269,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
suite.Require().NoError(suite.mempool.Insert(suite.ctx, tx))
}
// Insert all of the bundled transactions into the TOB lane if desired
// Insert all of the bundled transactions into the mempool if desired
if insertBundledTxs {
for _, tx := range auctionTxs {
bidInfo, err := suite.tobLane.GetAuctionBidInfo(tx)
@ -294,7 +294,10 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxEncoder(), suite.tobLane, suite.mempool)
suite.proposalHandler = abci.NewProposalHandler(
[]blockbuster.Lane{suite.baseLane},
[]blockbuster.Lane{
suite.tobLane,
suite.baseLane,
},
suite.tobLane,
suite.logger,
suite.encodingConfig.TxConfig.TxEncoder(),
@ -303,10 +306,10 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
)
handler := suite.proposalHandler.PrepareProposalHandler()
req := suite.createPrepareProposalRequest(maxTxBytes)
res := handler(suite.ctx, req)
res, _ := handler(suite.ctx, &req)
// -------------------- Check Invariants -------------------- //
// The first slot in the proposal must be the auction info
// The first slot in the proposal must be the auction info (if vote extensions are enabled)
auctionInfo := abci.AuctionInfo{}
err := auctionInfo.Unmarshal(res.Txs[abci.AuctionInfoIndex])
suite.Require().NoError(err)
@ -342,7 +345,6 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
bidInfo, err := suite.tobLane.GetAuctionBidInfo(tx)
suite.Require().NoError(err)
suite.Require().Nil(bidInfo)
}
// 4. All of the transactions must be unique
@ -358,13 +360,41 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
}
}
// TODO:
// - Add tests that ensure that the top of block lane does not propose more transactions than it is allowed to
func (suite *ABCITestSuite) TestPrepareProposalPreVoteExtensions() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
bidTx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, bidder, bid, nonce, timeout, signers)
suite.Require().NoError(err)
// Insert the bid transaction into the mempool
suite.Require().NoError(suite.mempool.Insert(suite.ctx, bidTx))
account := suite.accounts[5]
nonce = suite.nonces[account.Address.String()]
timeout = uint64(100)
numberMsgs := uint64(3)
normalTx, err := testutils.CreateRandomTx(suite.encodingConfig.TxConfig, account, nonce, numberMsgs, timeout)
suite.Require().NoError(err)
// Insert the normal transaction into the mempool
suite.Require().NoError(suite.mempool.Insert(suite.ctx, normalTx))
handler := suite.proposalHandler.PrepareProposalHandler()
req := suite.createPrepareProposalRequest(1000000000000)
suite.ctx = suite.ctx.WithBlockHeight(0)
res, _ := handler(suite.ctx, &req)
suite.Require().Equal(1, len(res.Txs))
}
func (suite *ABCITestSuite) TestProcessProposal() {
var (
// auction configuration
maxBundleSize uint32 = 10
reserveFee = sdk.NewCoin("foo", sdk.NewInt(1000))
reserveFee = sdk.NewCoin("stake", math.NewInt(1000))
frontRunningProtection = true
maxTxBytes int64 = 1000000000000000000
@ -417,7 +447,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -440,7 +470,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -469,7 +499,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -495,7 +525,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[1], bidder}
@ -520,7 +550,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder, suite.accounts[1]} // front-running
@ -545,7 +575,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder, bidder}
@ -554,7 +584,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
// Create another valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000000))
bid = sdk.NewCoin("stake", math.NewInt(1000000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -580,7 +610,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder, bidder}
@ -589,7 +619,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
// Create another valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000000))
bid = sdk.NewCoin("stake", math.NewInt(1000000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -615,7 +645,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder, bidder}
@ -624,7 +654,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
// Create another valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000000))
bid = sdk.NewCoin("stake", math.NewInt(1000000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -654,7 +684,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -682,7 +712,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -716,7 +746,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], suite.accounts[1], bidder, suite.accounts[3], suite.accounts[4]}
@ -762,8 +792,11 @@ func (suite *ABCITestSuite) TestProcessProposal() {
// reset the proposal handler with the new mempool
suite.proposalHandler = abci.NewProposalHandler(
[]blockbuster.Lane{suite.baseLane},
suite.tobLane, log.NewNopLogger(),
[]blockbuster.Lane{
suite.tobLane,
suite.baseLane,
},
suite.tobLane, log.NewTestLogger(suite.T()),
suite.encodingConfig.TxConfig.TxEncoder(),
suite.encodingConfig.TxConfig.TxDecoder(),
abci.NoOpValidateVoteExtensionsFn(),
@ -772,7 +805,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
tc.createTxs()
handler := suite.proposalHandler.ProcessProposalHandler()
res := handler(suite.ctx, comettypes.RequestProcessProposal{
res, _ := handler(suite.ctx, &comettypes.RequestProcessProposal{
Txs: proposal,
})

View File

@ -1,9 +1,3 @@
/*
NOTE: These types are TEMPORARY and will be removed once the Cosmos SDK v0.48
alpha/RC tag is released. These types are simply used to prototype and develop
against.
*/
//nolint
package abci
import (
@ -11,53 +5,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
const (
ResponseVerifyVoteExtension_UNKNOWN ResponseVerifyVoteExtension_VerifyStatus = 0
ResponseVerifyVoteExtension_ACCEPT ResponseVerifyVoteExtension_VerifyStatus = 1
// Rejecting the vote extension will reject the entire precommit by the sender.
// Incorrectly implementing this thus has liveness implications as it may affect
// CometBFT's ability to receive 2/3+ valid votes to finalize the block.
// Honest nodes should never be rejected.
ResponseVerifyVoteExtension_REJECT ResponseVerifyVoteExtension_VerifyStatus = 2
)
type (
RequestExtendVote struct {
// the hash of the block that this vote may be referring to
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
// the height of the extended vote
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
}
ResponseExtendVote struct {
VoteExtension []byte `protobuf:"bytes,1,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
}
RequestVerifyVoteExtension struct {
// the hash of the block that this received vote corresponds to
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
// the validator that signed the vote extension
ValidatorAddress []byte `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"`
Height int64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"`
VoteExtension []byte `protobuf:"bytes,4,opt,name=vote_extension,json=voteExtension,proto3" json:"vote_extension,omitempty"`
}
ResponseVerifyVoteExtension_VerifyStatus int32
ResponseVerifyVoteExtension struct {
Status ResponseVerifyVoteExtension_VerifyStatus `protobuf:"varint,1,opt,name=status,proto3,enum=tendermint.abci.ResponseVerifyVoteExtension_VerifyStatus" json:"status,omitempty"`
}
)
type (
// ExtendVoteHandler defines a function type alias for extending a pre-commit vote.
ExtendVoteHandler func(sdk.Context, *RequestExtendVote) (*ResponseExtendVote, error)
// VerifyVoteExtensionHandler defines a function type alias for verifying a
// pre-commit vote extension.
VerifyVoteExtensionHandler func(sdk.Context, *RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error)
)
// ValidateVoteExtensionsFn defines the function for validating vote extensions. This
// function is not explicitly used to validate the oracle data but rather that
// the signed vote extensions included in the proposal are valid and provide

View File

@ -5,9 +5,11 @@ import (
"encoding/hex"
"cosmossdk.io/log"
cometabci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
"github.com/skip-mev/pob/blockbuster/lanes/auction"
"github.com/skip-mev/pob/blockbuster/utils"
)
type (
@ -66,32 +68,51 @@ func NewVoteExtensionHandler(logger log.Logger, lane TOBLaneVE, txDecoder sdk.Tx
// ExtendVoteHandler returns the ExtendVoteHandler ABCI handler that extracts
// the top bidding valid auction transaction from a validator's local mempool and
// returns it in its vote extension.
func (h *VoteExtensionHandler) ExtendVoteHandler() ExtendVoteHandler {
return func(ctx sdk.Context, req *RequestExtendVote) (*ResponseExtendVote, error) {
func (h *VoteExtensionHandler) ExtendVoteHandler() sdk.ExtendVoteHandler {
return func(ctx sdk.Context, req *cometabci.RequestExtendVote) (*cometabci.ResponseExtendVote, error) {
// Iterate through auction bids until we find a valid one
auctionIterator := h.tobLane.Select(ctx, nil)
txsToRemove := make(map[sdk.Tx]struct{}, 0)
defer func() {
if err := utils.RemoveTxsFromLane(txsToRemove, h.tobLane); err != nil {
h.logger.Info(
"failed to remove transactions from lane",
"err", err,
)
}
}()
for ; auctionIterator != nil; auctionIterator = auctionIterator.Next() {
bidTx := auctionIterator.Tx()
// Verify the bid tx can be encoded and included in vote extension
if bidBz, err := h.txEncoder(bidTx); err == nil {
// Validate the auction transaction against a cache state
cacheCtx, _ := ctx.CacheContext()
bidTxBz, hash, err := utils.GetTxHashStr(h.txEncoder, bidTx)
if err != nil {
h.logger.Info(
"failed to get hash of auction bid tx",
"err", err,
)
txsToRemove[bidTx] = struct{}{}
if err := h.tobLane.VerifyTx(cacheCtx, bidTx); err == nil {
hash := sha256.Sum256(bidBz)
hashStr := hex.EncodeToString(hash[:])
h.logger.Info(
"extending vote with auction transaction",
"tx_hash", hashStr,
"height", ctx.BlockHeight(),
)
return &ResponseExtendVote{VoteExtension: bidBz}, nil
}
continue
}
// Validate the auction transaction against a cache state
cacheCtx, _ := ctx.CacheContext()
if err := h.tobLane.VerifyTx(cacheCtx, bidTx); err != nil {
h.logger.Info(
"failed to verify auction bid tx",
"tx_hash", hash,
"err", err,
)
txsToRemove[bidTx] = struct{}{}
continue
}
h.logger.Info("extending vote with auction transaction", "tx_hash", hash)
return &cometabci.ResponseExtendVote{VoteExtension: bidTxBz}, nil
}
h.logger.Info(
@ -99,23 +120,23 @@ func (h *VoteExtensionHandler) ExtendVoteHandler() ExtendVoteHandler {
"height", ctx.BlockHeight(),
)
return &ResponseExtendVote{VoteExtension: []byte{}}, nil
return &cometabci.ResponseExtendVote{VoteExtension: []byte{}}, nil
}
}
// VerifyVoteExtensionHandler returns the VerifyVoteExtensionHandler ABCI handler
// that verifies the vote extension included in RequestVerifyVoteExtension.
// In particular, it verifies that the vote extension is a valid auction transaction.
func (h *VoteExtensionHandler) VerifyVoteExtensionHandler() VerifyVoteExtensionHandler {
return func(ctx sdk.Context, req *RequestVerifyVoteExtension) (*ResponseVerifyVoteExtension, error) {
func (h *VoteExtensionHandler) VerifyVoteExtensionHandler() sdk.VerifyVoteExtensionHandler {
return func(ctx sdk.Context, req *cometabci.RequestVerifyVoteExtension) (*cometabci.ResponseVerifyVoteExtension, error) {
txBz := req.VoteExtension
if len(txBz) == 0 {
h.logger.Info(
"verifyed vote extension with no auction transaction",
"verified vote extension with no auction transaction",
"height", ctx.BlockHeight(),
)
return &ResponseVerifyVoteExtension{Status: ResponseVerifyVoteExtension_ACCEPT}, nil
return &cometabci.ResponseVerifyVoteExtension{Status: cometabci.ResponseVerifyVoteExtension_ACCEPT}, nil
}
// Reset the cache if necessary
@ -133,7 +154,7 @@ func (h *VoteExtensionHandler) VerifyVoteExtensionHandler() VerifyVoteExtensionH
"height", ctx.BlockHeight(),
)
return &ResponseVerifyVoteExtension{Status: ResponseVerifyVoteExtension_REJECT}, err
return &cometabci.ResponseVerifyVoteExtension{Status: cometabci.ResponseVerifyVoteExtension_REJECT}, err
}
h.logger.Info(
@ -142,7 +163,7 @@ func (h *VoteExtensionHandler) VerifyVoteExtensionHandler() VerifyVoteExtensionH
"height", ctx.BlockHeight(),
)
return &ResponseVerifyVoteExtension{Status: ResponseVerifyVoteExtension_ACCEPT}, nil
return &cometabci.ResponseVerifyVoteExtension{Status: cometabci.ResponseVerifyVoteExtension_ACCEPT}, nil
}
// Decode the vote extension which should be a valid auction transaction
@ -156,7 +177,7 @@ func (h *VoteExtensionHandler) VerifyVoteExtensionHandler() VerifyVoteExtensionH
)
h.cache[hash] = err
return &ResponseVerifyVoteExtension{Status: ResponseVerifyVoteExtension_REJECT}, err
return &cometabci.ResponseVerifyVoteExtension{Status: cometabci.ResponseVerifyVoteExtension_REJECT}, err
}
// Verify the auction transaction and cache the result
@ -168,8 +189,17 @@ func (h *VoteExtensionHandler) VerifyVoteExtensionHandler() VerifyVoteExtensionH
"err", err,
)
if err := h.tobLane.Remove(bidTx); err != nil {
h.logger.Info(
"failed to remove auction transaction from lane",
"tx_hash", hash,
"height", ctx.BlockHeight(),
"err", err,
)
}
h.cache[hash] = err
return &ResponseVerifyVoteExtension{Status: ResponseVerifyVoteExtension_REJECT}, err
return &cometabci.ResponseVerifyVoteExtension{Status: cometabci.ResponseVerifyVoteExtension_REJECT}, err
}
h.cache[hash] = nil
@ -180,7 +210,7 @@ func (h *VoteExtensionHandler) VerifyVoteExtensionHandler() VerifyVoteExtensionH
"height", ctx.BlockHeight(),
)
return &ResponseVerifyVoteExtension{Status: ResponseVerifyVoteExtension_ACCEPT}, nil
return &cometabci.ResponseVerifyVoteExtension{Status: cometabci.ResponseVerifyVoteExtension_ACCEPT}, nil
}
}

View File

@ -2,6 +2,8 @@ package abci_test
import (
"cosmossdk.io/log"
"cosmossdk.io/math"
cometabci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/abci"
testutils "github.com/skip-mev/pob/testutils"
@ -11,7 +13,7 @@ import (
func (suite *ABCITestSuite) TestExtendVoteExtensionHandler() {
params := types.Params{
MaxBundleSize: 5,
ReserveFee: sdk.NewCoin("foo", sdk.NewInt(10)),
ReserveFee: sdk.NewCoin("stake", math.NewInt(10)),
FrontRunningProtection: true,
}
@ -43,7 +45,7 @@ func (suite *ABCITestSuite) TestExtendVoteExtensionHandler() {
"mempool with invalid auction transaction (invalid bid)",
func() []byte {
bidder := suite.accounts[0]
bid := params.ReserveFee.Sub(sdk.NewCoin("foo", sdk.NewInt(1)))
bid := params.ReserveFee.Sub(sdk.NewCoin("stake", math.NewInt(1)))
signers := []testutils.Account{bidder}
timeout := 1
@ -59,7 +61,7 @@ func (suite *ABCITestSuite) TestExtendVoteExtensionHandler() {
{
"mempool contains only invalid auction bids (bid is too low)",
func() []byte {
params.ReserveFee = sdk.NewCoin("foo", sdk.NewInt(10000000000000000))
params.ReserveFee = sdk.NewCoin("stake", math.NewInt(10000000000000000))
err := suite.builderKeeper.SetParams(suite.ctx, params)
suite.Require().NoError(err)
@ -88,7 +90,7 @@ func (suite *ABCITestSuite) TestExtendVoteExtensionHandler() {
{
"top bid is invalid but next best is valid",
func() []byte {
params.ReserveFee = sdk.NewCoin("foo", sdk.NewInt(10))
params.ReserveFee = sdk.NewCoin("stake", math.NewInt(10))
bidder := suite.accounts[0]
bid := params.ReserveFee.Add(params.ReserveFee)
@ -143,7 +145,7 @@ func (suite *ABCITestSuite) TestExtendVoteExtensionHandler() {
func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
params := types.Params{
MaxBundleSize: 5,
ReserveFee: sdk.NewCoin("foo", sdk.NewInt(100)),
ReserveFee: sdk.NewCoin("stake", math.NewInt(100)),
FrontRunningProtection: true,
}
@ -152,13 +154,13 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
testCases := []struct {
name string
req func() *abci.RequestVerifyVoteExtension
req func() *cometabci.RequestVerifyVoteExtension
expectedErr bool
}{
{
"invalid vote extension bytes",
func() *abci.RequestVerifyVoteExtension {
return &abci.RequestVerifyVoteExtension{
func() *cometabci.RequestVerifyVoteExtension {
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: []byte("invalid vote extension"),
}
},
@ -166,8 +168,8 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"empty vote extension bytes",
func() *abci.RequestVerifyVoteExtension {
return &abci.RequestVerifyVoteExtension{
func() *cometabci.RequestVerifyVoteExtension {
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: []byte{},
}
},
@ -175,8 +177,8 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"nil vote extension bytes",
func() *abci.RequestVerifyVoteExtension {
return &abci.RequestVerifyVoteExtension{
func() *cometabci.RequestVerifyVoteExtension {
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: nil,
}
},
@ -184,14 +186,14 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"invalid extension with bid tx with bad timeout",
func() *abci.RequestVerifyVoteExtension {
func() *cometabci.RequestVerifyVoteExtension {
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10))
bid := sdk.NewCoin("stake", math.NewInt(10))
signers := []testutils.Account{bidder}
timeout := 0
bz := suite.createAuctionTxBz(bidder, bid, signers, timeout)
return &abci.RequestVerifyVoteExtension{
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: bz,
}
},
@ -199,14 +201,14 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"invalid vote extension with bid tx with bad bid",
func() *abci.RequestVerifyVoteExtension {
func() *cometabci.RequestVerifyVoteExtension {
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(0))
bid := sdk.NewCoin("stake", math.NewInt(0))
signers := []testutils.Account{bidder}
timeout := 10
bz := suite.createAuctionTxBz(bidder, bid, signers, timeout)
return &abci.RequestVerifyVoteExtension{
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: bz,
}
},
@ -214,14 +216,14 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"valid vote extension",
func() *abci.RequestVerifyVoteExtension {
func() *cometabci.RequestVerifyVoteExtension {
bidder := suite.accounts[0]
bid := params.ReserveFee
signers := []testutils.Account{bidder}
timeout := 10
bz := suite.createAuctionTxBz(bidder, bid, signers, timeout)
return &abci.RequestVerifyVoteExtension{
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: bz,
}
},
@ -229,7 +231,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"invalid vote extension with front running bid tx",
func() *abci.RequestVerifyVoteExtension {
func() *cometabci.RequestVerifyVoteExtension {
bidder := suite.accounts[0]
bid := params.ReserveFee
timeout := 10
@ -238,7 +240,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
signers := []testutils.Account{bidder, bundlee}
bz := suite.createAuctionTxBz(bidder, bid, signers, timeout)
return &abci.RequestVerifyVoteExtension{
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: bz,
}
},
@ -246,7 +248,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"invalid vote extension with too many bundle txs",
func() *abci.RequestVerifyVoteExtension {
func() *cometabci.RequestVerifyVoteExtension {
// disable front running protection
params.FrontRunningProtection = false
err := suite.builderKeeper.SetParams(suite.ctx, params)
@ -258,7 +260,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
timeout := 10
bz := suite.createAuctionTxBz(bidder, bid, signers, timeout)
return &abci.RequestVerifyVoteExtension{
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: bz,
}
},
@ -266,7 +268,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"invalid vote extension with a failing bundle tx",
func() *abci.RequestVerifyVoteExtension {
func() *cometabci.RequestVerifyVoteExtension {
bidder := suite.accounts[0]
bid := params.ReserveFee
@ -282,7 +284,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
bz, err := suite.encodingConfig.TxConfig.TxEncoder()(bidTx)
suite.Require().NoError(err)
return &abci.RequestVerifyVoteExtension{
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: bz,
}
},
@ -290,7 +292,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
},
{
"valid vote extension + no comparison to local mempool",
func() *abci.RequestVerifyVoteExtension {
func() *cometabci.RequestVerifyVoteExtension {
bidder := suite.accounts[0]
bid := params.ReserveFee
signers := []testutils.Account{bidder}
@ -309,7 +311,7 @@ func (suite *ABCITestSuite) TestVerifyVoteExtensionHandler() {
tx := suite.tobLane.GetTopAuctionTx(suite.ctx)
suite.Require().NotNil(tx)
return &abci.RequestVerifyVoteExtension{
return &cometabci.RequestVerifyVoteExtension{
VoteExtension: bz,
}
},

View File

@ -1,8 +1,8 @@
package abci
import (
"cosmossdk.io/log"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/blockbuster"
"github.com/skip-mev/pob/blockbuster/lanes/terminator"
@ -36,19 +36,19 @@ func NewProposalHandler(logger log.Logger, txDecoder sdk.TxDecoder, mempool bloc
// the default lane will not have a boundary on the number of bytes that can be included in the proposal and
// will include all valid transactions in the proposal (up to MaxTxBytes).
func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
return func(ctx sdk.Context, req abci.RequestPrepareProposal) (resp abci.ResponsePrepareProposal) {
return func(ctx sdk.Context, req *abci.RequestPrepareProposal) (resp *abci.ResponsePrepareProposal, err error) {
// In the case where there is a panic, we recover here and return an empty proposal.
defer func() {
if err := recover(); err != nil {
h.logger.Error("failed to prepare proposal", "err", err)
resp = abci.ResponsePrepareProposal{Txs: make([][]byte, 0)}
resp = &abci.ResponsePrepareProposal{Txs: make([][]byte, 0)}
}
}()
proposal, err := h.prepareLanesHandler(ctx, blockbuster.NewProposal(req.MaxTxBytes))
if err != nil {
h.logger.Error("failed to prepare proposal", "err", err)
return abci.ResponsePrepareProposal{Txs: make([][]byte, 0)}
return &abci.ResponsePrepareProposal{Txs: make([][]byte, 0)}, err
}
h.logger.Info(
@ -57,9 +57,9 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
"total_tx_bytes", proposal.GetTotalTxBytes(),
)
return abci.ResponsePrepareProposal{
return &abci.ResponsePrepareProposal{
Txs: proposal.GetProposal(),
}
}, nil
}
}
@ -68,37 +68,37 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler {
// If a lane's portion of the proposal is invalid, we reject the proposal. After a lane's portion
// of the proposal is verified, we pass the remaining transactions to the next lane in the chain.
func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler {
return func(ctx sdk.Context, req abci.RequestProcessProposal) (resp abci.ResponseProcessProposal) {
return func(ctx sdk.Context, req *abci.RequestProcessProposal) (resp *abci.ResponseProcessProposal, err error) {
// In the case where any of the lanes panic, we recover here and return a reject status.
defer func() {
if err := recover(); err != nil {
h.logger.Error("failed to process proposal", "err", err)
resp = abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
resp = &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
}
}()
txs := req.Txs
if len(txs) == 0 {
h.logger.Info("accepted empty proposal")
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil
}
// Decode the transactions from the proposal.
decodedTxs, err := utils.GetDecodedTxs(h.txDecoder, txs)
if err != nil {
h.logger.Error("failed to decode transactions", "err", err)
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, err
}
// Verify the proposal using the verification logic from each lane.
if _, err := h.processLanesHandler(ctx, decodedTxs); err != nil {
h.logger.Error("failed to validate the proposal", "err", err)
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, err
}
h.logger.Info("validated proposal", "num_txs", len(txs))
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil
}
}
@ -197,7 +197,9 @@ func ChainProcessLanes(chain ...blockbuster.Lane) blockbuster.ProcessLanesHandle
}
chain[0].Logger().Info("processing lane", "lane", chain[0].Name())
if err := chain[0].ProcessLaneBasic(proposalTxs); err != nil {
chain[0].Logger().Error("failed to process lane", "lane", chain[0].Name(), "err", err)
return ctx, err
}

View File

@ -5,8 +5,9 @@ import (
"testing"
"time"
"github.com/cometbft/cometbft/libs/log"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
@ -69,17 +70,17 @@ func (suite *ABCITestSuite) SetupTest() {
// General config for transactions and randomness for the test suite
suite.encodingConfig = testutils.CreateTestEncodingConfig()
suite.random = rand.New(rand.NewSource(time.Now().Unix()))
key := sdk.NewKVStoreKey(buildertypes.StoreKey)
key := storetypes.NewKVStoreKey(buildertypes.StoreKey)
testCtx := testutil.DefaultContextWithDB(suite.T(), key, storetypes.NewTransientStoreKey("transient_test"))
suite.ctx = testCtx.Ctx.WithBlockHeight(1)
// Lanes configuration
config := blockbuster.BaseLaneConfig{
Logger: log.NewNopLogger(),
Logger: log.NewTestLogger(suite.T()),
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: suite.anteHandler,
MaxBlockSpace: sdk.ZeroDec(), // It can be as big as it wants (up to maxTxBytes)
MaxBlockSpace: math.LegacyZeroDec(), // It can be as big as it wants (up to maxTxBytes)
}
// Top of block lane set up
@ -142,13 +143,12 @@ func (suite *ABCITestSuite) SetupTest() {
suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxEncoder(), suite.tobLane, suite.mempool)
// Proposal handler set up
suite.proposalHandler = abci.NewProposalHandler(log.NewNopLogger(), suite.encodingConfig.TxConfig.TxDecoder(), suite.mempool)
suite.proposalHandler = abci.NewProposalHandler(log.NewTestLogger(suite.T()), suite.encodingConfig.TxConfig.TxDecoder(), suite.mempool)
}
func (suite *ABCITestSuite) anteHandler(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
signer := tx.GetMsgs()[0].GetSigners()[0]
suite.bankKeeper.EXPECT().GetBalance(ctx, signer, "foo").AnyTimes().Return(
sdk.NewCoin("foo", sdk.NewInt(100000000000000)),
suite.bankKeeper.EXPECT().GetBalance(ctx, gomock.Any(), "stake").AnyTimes().Return(
sdk.NewCoin("stake", math.NewInt(100000000000000)),
)
next := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
@ -195,8 +195,8 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
// auction configuration
maxBundleSize uint32 = 10
reserveFee = sdk.NewCoin("foo", sdk.NewInt(1000))
minBidIncrement = sdk.NewCoin("foo", sdk.NewInt(100))
reserveFee = sdk.NewCoin("stake", math.NewInt(1000))
minBidIncrement = sdk.NewCoin("stake", math.NewInt(100))
frontRunningProtection = true
)
@ -226,7 +226,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create a tob tx
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -264,7 +264,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create a tob tx
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -288,7 +288,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
freeSize := int64(len(freeTxBytes))
maxTxBytes = tobSize + freeSize
suite.tobConfig.MaxBlockSpace = sdk.NewDecWithPrec(1, 1)
suite.tobConfig.MaxBlockSpace = math.LegacyMustNewDecFromStr("0.1")
txs = []sdk.Tx{freeTx}
auctionTxs = []sdk.Tx{bidTx}
@ -307,7 +307,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create a tob tx
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2]}
@ -331,8 +331,8 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
freeSize := int64(len(freeTxBytes))
maxTxBytes = tobSize*2 + freeSize - 1
suite.tobConfig.MaxBlockSpace = sdk.ZeroDec()
suite.freeConfig.MaxBlockSpace = sdk.MustNewDecFromStr("0.1")
suite.tobConfig.MaxBlockSpace = math.LegacyZeroDec()
suite.freeConfig.MaxBlockSpace = math.LegacyMustNewDecFromStr("0.1")
txs = []sdk.Tx{freeTx}
auctionTxs = []sdk.Tx{bidTx}
@ -351,7 +351,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create a tob tx
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -389,13 +389,13 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
maxTxBytes = tobSize*2 + freeSize + normalSize + 1
// Tob can take up as much space as it wants
suite.tobConfig.MaxBlockSpace = sdk.ZeroDec()
suite.tobConfig.MaxBlockSpace = math.LegacyZeroDec()
// Free can take up less space than the tx
suite.freeConfig.MaxBlockSpace = sdk.MustNewDecFromStr("0.01")
suite.freeConfig.MaxBlockSpace = math.LegacyMustNewDecFromStr("0.01")
// Default can take up as much space as it wants
suite.baseConfig.MaxBlockSpace = sdk.ZeroDec()
suite.baseConfig.MaxBlockSpace = math.LegacyZeroDec()
txs = []sdk.Tx{freeTx, normalTx}
auctionTxs = []sdk.Tx{bidTx}
@ -413,12 +413,12 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
"single valid tob transaction in the mempool",
func() {
// reset the configs
suite.tobConfig.MaxBlockSpace = sdk.ZeroDec()
suite.freeConfig.MaxBlockSpace = sdk.ZeroDec()
suite.baseConfig.MaxBlockSpace = sdk.ZeroDec()
suite.tobConfig.MaxBlockSpace = math.LegacyZeroDec()
suite.freeConfig.MaxBlockSpace = math.LegacyZeroDec()
suite.baseConfig.MaxBlockSpace = math.LegacyZeroDec()
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -442,7 +442,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
"single invalid tob transaction in the mempool",
func() {
bidder := suite.accounts[0]
bid := reserveFee.Sub(sdk.NewCoin("foo", sdk.NewInt(1))) // bid is less than the reserve fee
bid := reserveFee.Sub(sdk.NewCoin("stake", math.NewInt(1))) // bid is less than the reserve fee
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -488,7 +488,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create a valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -519,7 +519,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create an invalid tob transaction (frontrunning)
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000000000))
bid := sdk.NewCoin("stake", math.NewInt(1000000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder, bidder, suite.accounts[1]}
@ -528,7 +528,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
// Create a valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -552,7 +552,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -561,7 +561,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
// Create a valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -587,7 +587,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], suite.accounts[1], bidder, suite.accounts[3], suite.accounts[4]}
@ -611,7 +611,7 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
func() {
// Create a tob tx
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -691,11 +691,12 @@ func (suite *ABCITestSuite) TestPrepareProposal() {
}
// Create a new proposal handler
suite.proposalHandler = abci.NewProposalHandler(log.NewNopLogger(), suite.encodingConfig.TxConfig.TxDecoder(), suite.mempool)
suite.proposalHandler = abci.NewProposalHandler(log.NewTestLogger(suite.T()), suite.encodingConfig.TxConfig.TxDecoder(), suite.mempool)
handler := suite.proposalHandler.PrepareProposalHandler()
res := handler(suite.ctx, abcitypes.RequestPrepareProposal{
res, err := handler(suite.ctx, &abcitypes.RequestPrepareProposal{
MaxTxBytes: maxTxBytes,
})
suite.Require().NoError(err)
// -------------------- Check Invariants -------------------- //
// 1. the number of transactions in the response must be equal to the number of expected transactions
@ -795,7 +796,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
// auction configuration
maxBundleSize uint32 = 10
reserveFee = sdk.NewCoin("foo", sdk.NewInt(1000))
reserveFee = sdk.NewCoin("stake", math.NewInt(1000))
frontRunningProtection = true
)
@ -830,7 +831,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
"single tob tx without bundled txs in proposal",
func() {
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{bidder}
@ -847,7 +848,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
"single tob tx with bundled txs in proposal",
func() {
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[1], bidder}
@ -865,7 +866,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], suite.accounts[1], bidder, suite.accounts[3], suite.accounts[4]}
@ -883,7 +884,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -892,7 +893,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
// Create a valid tob transaction
bidder = suite.accounts[1]
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
nonce = suite.nonces[bidder.Address.String()]
timeout = uint64(100)
signers = []testutils.Account{bidder}
@ -912,7 +913,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
// Create an valid tob transaction
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(10000000))
bid := sdk.NewCoin("stake", math.NewInt(10000000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -945,7 +946,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a tob tx
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -976,7 +977,7 @@ func (suite *ABCITestSuite) TestProcessProposal() {
func() {
// Create a tob tx
bidder := suite.accounts[0]
bid := sdk.NewCoin("foo", sdk.NewInt(1000))
bid := sdk.NewCoin("stake", math.NewInt(1000))
nonce := suite.nonces[bidder.Address.String()]
timeout := uint64(100)
signers := []testutils.Account{suite.accounts[2], bidder}
@ -1042,12 +1043,18 @@ func (suite *ABCITestSuite) TestProcessProposal() {
suite.builderDecorator = ante.NewBuilderDecorator(suite.builderKeeper, suite.encodingConfig.TxConfig.TxEncoder(), suite.tobLane, suite.mempool)
handler := suite.proposalHandler.ProcessProposalHandler()
res := handler(suite.ctx, abcitypes.RequestProcessProposal{
res, err := handler(suite.ctx, &abcitypes.RequestProcessProposal{
Txs: proposalTxs,
})
// Check if the response is valid
suite.Require().Equal(tc.response, res.Status)
if res.Status == abcitypes.ResponseProcessProposal_ACCEPT {
suite.Require().NoError(err)
} else {
suite.Require().Error(err)
}
})
}
}

View File

@ -4,9 +4,10 @@ import (
"context"
"fmt"
log "cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
cometabci "github.com/cometbft/cometbft/abci/types"
log "github.com/cometbft/cometbft/libs/log"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/skip-mev/pob/x/builder/types"
@ -33,14 +34,11 @@ type (
// anteHandler is utilized to verify the bid transaction against the latest
// committed state.
anteHandler sdk.AnteHandler
// chainID is the chain ID of the blockchain.
chainID string
}
// CheckTx is baseapp's CheckTx method that checks the validity of a
// transaction.
CheckTx func(cometabci.RequestCheckTx) cometabci.ResponseCheckTx
CheckTx func(req *cometabci.RequestCheckTx) (*cometabci.ResponseCheckTx, error)
// TOBLane is the interface that defines all of the dependencies that
// are required to interact with the top of block lane.
@ -60,11 +58,11 @@ type (
// as well as retrieve the latest committed state.
BaseApp interface {
// CommitMultiStore is utilized to retrieve the latest committed state.
CommitMultiStore() sdk.CommitMultiStore
CommitMultiStore() storetypes.CommitMultiStore
// CheckTx is baseapp's CheckTx method that checks the validity of a
// transaction.
CheckTx(cometabci.RequestCheckTx) cometabci.ResponseCheckTx
CheckTx(req *cometabci.RequestCheckTx) (*cometabci.ResponseCheckTx, error)
// Logger is utilized to log errors.
Logger() log.Logger
@ -73,7 +71,10 @@ type (
LastBlockHeight() int64
// GetConsensusParams is utilized to retrieve the consensus params.
GetConsensusParams(ctx sdk.Context) *tmproto.ConsensusParams
GetConsensusParams(ctx sdk.Context) cmtproto.ConsensusParams
// ChainID is utilized to retrieve the chain ID.
ChainID() string
}
)
@ -83,14 +84,12 @@ func NewCheckTxHandler(
txDecoder sdk.TxDecoder,
tobLane TOBLane,
anteHandler sdk.AnteHandler,
chainID string,
) *CheckTxHandler {
return &CheckTxHandler{
baseApp: baseApp,
txDecoder: txDecoder,
tobLane: tobLane,
anteHandler: anteHandler,
chainID: chainID,
}
}
@ -101,27 +100,69 @@ func NewCheckTxHandler(
// otherwise the auction can be griefed. No state changes are applied to the state
// during this process.
func (handler *CheckTxHandler) CheckTx() CheckTx {
return func(req cometabci.RequestCheckTx) (resp cometabci.ResponseCheckTx) {
return func(req *cometabci.RequestCheckTx) (resp *cometabci.ResponseCheckTx, err error) {
defer func() {
if err := recover(); err != nil {
resp = sdkerrors.ResponseCheckTxWithEvents(fmt.Errorf("panic in check tx handler: %s", err), 0, 0, nil, false)
if rec := recover(); rec != nil {
handler.baseApp.Logger().Error(
"panic in check tx handler",
"err", rec,
)
err = fmt.Errorf("panic in check tx handler: %s", rec)
resp = sdkerrors.ResponseCheckTxWithEvents(
err,
0,
0,
nil,
false,
)
}
}()
tx, err := handler.txDecoder(req.Tx)
if err != nil {
return sdkerrors.ResponseCheckTxWithEvents(fmt.Errorf("failed to decode tx: %w", err), 0, 0, nil, false)
handler.baseApp.Logger().Info(
"failed to decode tx",
"err", err,
)
return sdkerrors.ResponseCheckTxWithEvents(
fmt.Errorf("failed to decode tx: %w", err),
0,
0,
nil,
false,
), err
}
// Attempt to get the bid info of the transaction.
bidInfo, err := handler.tobLane.GetAuctionBidInfo(tx)
if err != nil {
return sdkerrors.ResponseCheckTxWithEvents(fmt.Errorf("failed to get auction bid info: %w", err), 0, 0, nil, false)
handler.baseApp.Logger().Info(
"failed to get auction bid info",
"err", err,
)
return sdkerrors.ResponseCheckTxWithEvents(
fmt.Errorf("failed to get auction bid info: %w", err),
0,
0,
nil,
false,
), err
}
// If this is not a bid transaction, we just execute it normally.
if bidInfo == nil {
return handler.baseApp.CheckTx(req)
resp, err := handler.baseApp.CheckTx(req)
if err != nil {
handler.baseApp.Logger().Info(
"failed to execute check tx",
"err", err,
)
}
return resp, err
}
// We attempt to get the latest committed state in order to verify transactions
@ -132,19 +173,41 @@ func (handler *CheckTxHandler) CheckTx() CheckTx {
// Verify the bid transaction.
gasInfo, err := handler.ValidateBidTx(ctx, tx, bidInfo)
if err != nil {
return sdkerrors.ResponseCheckTxWithEvents(fmt.Errorf("invalid bid tx: %w", err), gasInfo.GasWanted, gasInfo.GasUsed, nil, false)
handler.baseApp.Logger().Info(
"invalid bid tx",
"err", err,
)
return sdkerrors.ResponseCheckTxWithEvents(
fmt.Errorf("invalid bid tx: %w", err),
gasInfo.GasWanted,
gasInfo.GasUsed,
nil,
false,
), err
}
// If the bid transaction is valid, we know we can insert it into the mempool for consideration in the next block.
if err := handler.tobLane.Insert(ctx, tx); err != nil {
return sdkerrors.ResponseCheckTxWithEvents(fmt.Errorf("invalid bid tx; failed to insert bid transaction into mempool: %w", err), gasInfo.GasWanted, gasInfo.GasUsed, nil, false)
handler.baseApp.Logger().Info(
"invalid bid tx; failed to insert bid transaction into mempool",
"err", err,
)
return sdkerrors.ResponseCheckTxWithEvents(
fmt.Errorf("invalid bid tx; failed to insert bid transaction into mempool: %w", err),
gasInfo.GasWanted,
gasInfo.GasUsed,
nil,
false,
), err
}
return cometabci.ResponseCheckTx{
return &cometabci.ResponseCheckTx{
Code: cometabci.CodeTypeOK,
GasWanted: int64(gasInfo.GasWanted),
GasUsed: int64(gasInfo.GasUsed),
}
}, nil
}
}
@ -185,14 +248,14 @@ func (handler *CheckTxHandler) ValidateBidTx(ctx sdk.Context, bidTx sdk.Tx, bidI
// GetContextForBidTx is returns the latest committed state and sets the context given
// the checkTx request.
func (handler *CheckTxHandler) GetContextForBidTx(req cometabci.RequestCheckTx) sdk.Context {
func (handler *CheckTxHandler) GetContextForBidTx(req *cometabci.RequestCheckTx) sdk.Context {
// Retrieve the commit multi-store which is used to retrieve the latest committed state.
ms := handler.baseApp.CommitMultiStore().CacheMultiStore()
// Create a new context based off of the latest committed state.
header := tmproto.Header{
header := cmtproto.Header{
Height: handler.baseApp.LastBlockHeight(),
ChainID: handler.chainID, // TODO: Replace with actual chain ID. This is currently not exposed by the app.
ChainID: handler.baseApp.ChainID(),
}
ctx, _ := sdk.NewContext(ms, header, true, handler.baseApp.Logger()).CacheContext()

View File

@ -3,7 +3,8 @@ package blockbuster
import (
"fmt"
"github.com/cometbft/cometbft/libs/log"
"cosmossdk.io/log"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
)
@ -30,7 +31,7 @@ type (
// used by this lane. NOTE: If this is set to zero, then there is no limit
// on the number of transactions that can be included in the block for this
// lane (up to maxTxBytes as provided by the request). This is useful for the default lane.
MaxBlockSpace sdk.Dec
MaxBlockSpace math.LegacyDec
// IgnoreList defines the list of lanes to ignore when processing transactions. This
// is useful for when you want lanes to exist after the default lane. For example,
@ -79,12 +80,18 @@ type (
Logger() log.Logger
// GetMaxBlockSpace returns the max block space for the lane as a relative percentage.
GetMaxBlockSpace() sdk.Dec
GetMaxBlockSpace() math.LegacyDec
}
)
// NewLaneConfig returns a new LaneConfig. This will be embedded in a lane.
func NewBaseLaneConfig(logger log.Logger, txEncoder sdk.TxEncoder, txDecoder sdk.TxDecoder, anteHandler sdk.AnteHandler, maxBlockSpace sdk.Dec) BaseLaneConfig {
func NewBaseLaneConfig(
logger log.Logger,
txEncoder sdk.TxEncoder,
txDecoder sdk.TxDecoder,
anteHandler sdk.AnteHandler,
maxBlockSpace math.LegacyDec,
) BaseLaneConfig {
return BaseLaneConfig{
Logger: logger,
TxEncoder: txEncoder,
@ -108,7 +115,7 @@ func (c *BaseLaneConfig) ValidateBasic() error {
return fmt.Errorf("tx decoder cannot be nil")
}
if c.MaxBlockSpace.IsNil() || c.MaxBlockSpace.IsNegative() || c.MaxBlockSpace.GT(sdk.OneDec()) {
if c.MaxBlockSpace.IsNil() || c.MaxBlockSpace.IsNegative() || c.MaxBlockSpace.GT(math.LegacyOneDec()) {
return fmt.Errorf("max block space must be set to a value between 0 and 1")
}

View File

@ -34,12 +34,19 @@ selectBidTxLoop:
bidTxBz, hash, err := utils.GetTxHashStr(l.Cfg.TxEncoder, tmpBidTx)
if err != nil {
l.Logger().Info("failed to get hash of auction bid tx", "err", err)
txsToRemove[tmpBidTx] = struct{}{}
continue selectBidTxLoop
}
// if the transaction is already in the (partial) block proposal, we skip it.
if proposal.Contains(bidTxBz) {
l.Logger().Info(
"failed to select auction bid tx for lane; tx is already in proposal",
"tx_hash", hash,
)
continue selectBidTxLoop
}
@ -52,6 +59,7 @@ selectBidTxLoop:
"tx_hash", hash,
"err", err,
)
txsToRemove[tmpBidTx] = struct{}{}
continue selectBidTxLoop
}
@ -60,6 +68,12 @@ selectBidTxLoop:
// its bundled transactions.
bidInfo, err := l.GetAuctionBidInfo(tmpBidTx)
if bidInfo == nil || err != nil {
l.Logger().Info(
"failed to get auction bid info",
"tx_hash", hash,
"err", err,
)
// Some transactions in the bundle may be malformed or invalid, so we
// remove the bid transaction and try the next top bid.
txsToRemove[tmpBidTx] = struct{}{}
@ -71,18 +85,35 @@ selectBidTxLoop:
for index, rawRefTx := range bidInfo.Transactions {
sdkTx, err := l.WrapBundleTransaction(rawRefTx)
if err != nil {
l.Logger().Info(
"failed to wrap bundled tx",
"tx_hash", hash,
"err", err,
)
txsToRemove[tmpBidTx] = struct{}{}
continue selectBidTxLoop
}
sdkTxBz, _, err := utils.GetTxHashStr(l.Cfg.TxEncoder, sdkTx)
if err != nil {
l.Logger().Info(
"failed to get hash of bundled tx",
"tx_hash", hash,
"err", err,
)
txsToRemove[tmpBidTx] = struct{}{}
continue selectBidTxLoop
}
// if the transaction is already in the (partial) block proposal, we skip it.
if proposal.Contains(sdkTxBz) {
l.Logger().Info(
"failed to select auction bid tx for lane; tx is already in proposal",
"tx_hash", hash,
)
continue selectBidTxLoop
}
@ -105,7 +136,7 @@ selectBidTxLoop:
break selectBidTxLoop
}
l.Cfg.Logger.Info(
l.Logger().Info(
"failed to select auction bid tx for lane; tx size is too large",
"tx_size", bidTxSize,
"max_size", maxTxBytes,
@ -114,6 +145,12 @@ selectBidTxLoop:
// Remove all transactions that were invalid during the creation of the partial proposal.
if err := utils.RemoveTxsFromLane(txsToRemove, l.Mempool); err != nil {
l.Logger().Error(
"failed to remove transactions from lane",
"lane", l.Name(),
"err", err,
)
return proposal, err
}
@ -130,8 +167,11 @@ selectBidTxLoop:
// ProcessLane will ensure that block proposals that include transactions from
// the top-of-block auction lane are valid.
func (l *TOBLane) ProcessLane(ctx sdk.Context, txs []sdk.Tx, next blockbuster.ProcessLanesHandler) (sdk.Context, error) {
bidTx := txs[0]
if len(txs) == 0 {
return next(ctx, txs)
}
bidTx := txs[0]
if !l.Match(bidTx) {
return next(ctx, txs)
}
@ -154,6 +194,10 @@ func (l *TOBLane) ProcessLane(ctx sdk.Context, txs []sdk.Tx, next blockbuster.Pr
// they were included in the bid transaction.
// - there are no other bid transactions in the proposal
func (l *TOBLane) ProcessLaneBasic(txs []sdk.Tx) error {
if len(txs) == 0 {
return nil
}
bidTx := txs[0]
// If there is a bid transaction, it must be the first transaction in the block proposal.

View File

@ -5,7 +5,7 @@ import (
"testing"
"time"
"github.com/cometbft/cometbft/libs/log"
"cosmossdk.io/log"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/blockbuster/lanes/auction"
@ -34,7 +34,7 @@ func (suite *IntegrationTestSuite) SetupTest() {
suite.encCfg = testutils.CreateTestEncodingConfig()
suite.config = auction.NewDefaultAuctionFactory(suite.encCfg.TxConfig.TxDecoder())
suite.mempool = auction.NewMempool(suite.encCfg.TxConfig.TxEncoder(), 0, suite.config)
suite.ctx = sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger())
suite.ctx = sdk.NewContext(nil, cmtproto.Header{}, false, log.NewTestLogger(suite.T()))
// Init accounts
suite.random = rand.New(rand.NewSource(time.Now().Unix()))

View File

@ -95,7 +95,7 @@ func (config *DefaultAuctionFactory) GetAuctionBidInfo(tx sdk.Tx) (*types.BidInf
// a bundle. In the default case, each bundle transaction will be an sdk.Tx and the
// signers are the signers of each sdk.Msg in the transaction.
func (config *DefaultAuctionFactory) getBundleSigners(bundle [][]byte) ([]map[string]struct{}, error) {
signers := make([]map[string]struct{}, 0)
bundleSigners := make([]map[string]struct{}, 0)
for _, tx := range bundle {
sdkTx, err := config.txDecoder(tx)
@ -109,12 +109,18 @@ func (config *DefaultAuctionFactory) getBundleSigners(bundle [][]byte) ([]map[st
}
txSigners := make(map[string]struct{})
for _, signer := range sigTx.GetSigners() {
txSigners[signer.String()] = struct{}{}
signers, err := sigTx.GetSigners()
if err != nil {
return nil, err
}
signers = append(signers, txSigners)
for _, signer := range signers {
txSigners[sdk.AccAddress(signer).String()] = struct{}{}
}
bundleSigners = append(bundleSigners, txSigners)
}
return signers, nil
return bundleSigners, nil
}

View File

@ -3,6 +3,7 @@ package auction_test
import (
"crypto/rand"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
testutils "github.com/skip-mev/pob/testutils"
)
@ -27,7 +28,7 @@ func (suite *IntegrationTestSuite) TestIsAuctionTx() {
{
"malformed auction bid tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
msgs := testutils.CreateRandomMsgs(suite.accounts[0].Address, 2)
@ -43,7 +44,7 @@ func (suite *IntegrationTestSuite) TestIsAuctionTx() {
{
"valid auction bid tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
msgs := []sdk.Msg{msgAuctionBid}
@ -58,10 +59,10 @@ func (suite *IntegrationTestSuite) TestIsAuctionTx() {
{
"tx with multiple MsgAuctionBid messages",
func() sdk.Tx {
bid1, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
bid1, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
bid2, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 1, 2)
bid2, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 1, 2)
suite.Require().NoError(err)
msgs := []sdk.Msg{bid1, bid2}
@ -104,7 +105,7 @@ func (suite *IntegrationTestSuite) TestGetTransactionSigners() {
tx, err := testutils.CreateAuctionTxWithSigners(
suite.encCfg.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("stake", math.NewInt(100)),
1,
0,
suite.accounts[0:1],
@ -137,7 +138,7 @@ func (suite *IntegrationTestSuite) TestGetTransactionSigners() {
tx, err := testutils.CreateAuctionTxWithSigners(
suite.encCfg.TxConfig,
suite.accounts[0],
sdk.NewCoin("foo", sdk.NewInt(100)),
sdk.NewCoin("stake", math.NewInt(100)),
1,
0,
suite.accounts[0:3],
@ -251,7 +252,7 @@ func (suite *IntegrationTestSuite) TestGetBidder() {
{
"valid auction tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
msgs := []sdk.Msg{msgAuctionBid}
@ -267,7 +268,7 @@ func (suite *IntegrationTestSuite) TestGetBidder() {
{
"invalid auction tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]
@ -326,7 +327,7 @@ func (suite *IntegrationTestSuite) TestGetBid() {
{
"valid auction tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
msgs := []sdk.Msg{msgAuctionBid}
@ -335,14 +336,14 @@ func (suite *IntegrationTestSuite) TestGetBid() {
suite.Require().NoError(err)
return tx
},
sdk.NewInt64Coin("foo", 100),
sdk.NewInt64Coin("stake", 100),
false,
true,
},
{
"invalid auction tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]
@ -399,7 +400,7 @@ func (suite *IntegrationTestSuite) TestGetBundledTransactions() {
{
"valid auction tx",
func() (sdk.Tx, [][]byte) {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
msgs := []sdk.Msg{msgAuctionBid}
@ -414,7 +415,7 @@ func (suite *IntegrationTestSuite) TestGetBundledTransactions() {
{
"invalid auction tx",
func() (sdk.Tx, [][]byte) {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]
@ -472,7 +473,7 @@ func (suite *IntegrationTestSuite) TestGetTimeout() {
{
"valid auction tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
msgs := []sdk.Msg{msgAuctionBid}
@ -488,7 +489,7 @@ func (suite *IntegrationTestSuite) TestGetTimeout() {
{
"invalid auction tx",
func() sdk.Tx {
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("foo", 100), 0, 2)
msgAuctionBid, err := testutils.CreateMsgAuctionBid(suite.encCfg.TxConfig, suite.accounts[0], sdk.NewInt64Coin("stake", 100), 0, 2)
suite.Require().NoError(err)
randomMsg := testutils.CreateRandomMsgs(suite.accounts[0].Address, 1)[0]

View File

@ -5,13 +5,13 @@ import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/skip-mev/pob/blockbuster/lanes/auction"
pobcodec "github.com/skip-mev/pob/codec"
testutils "github.com/skip-mev/pob/testutils"
buildertypes "github.com/skip-mev/pob/x/builder/types"
"github.com/stretchr/testify/require"
)
func TestGetMsgAuctionBidFromTx_Valid(t *testing.T) {
encCfg := pobcodec.CreateEncodingConfig()
encCfg := testutils.CreateTestEncodingConfig()
txBuilder := encCfg.TxConfig.NewTxBuilder()
txBuilder.SetMsgs(&buildertypes.MsgAuctionBid{})
@ -22,7 +22,7 @@ func TestGetMsgAuctionBidFromTx_Valid(t *testing.T) {
}
func TestGetMsgAuctionBidFromTx_MultiMsgBid(t *testing.T) {
encCfg := pobcodec.CreateEncodingConfig()
encCfg := testutils.CreateTestEncodingConfig()
txBuilder := encCfg.TxConfig.NewTxBuilder()
txBuilder.SetMsgs(
@ -37,7 +37,7 @@ func TestGetMsgAuctionBidFromTx_MultiMsgBid(t *testing.T) {
}
func TestGetMsgAuctionBidFromTx_NoBid(t *testing.T) {
encCfg := pobcodec.CreateEncodingConfig()
encCfg := testutils.CreateTestEncodingConfig()
txBuilder := encCfg.TxConfig.NewTxBuilder()
txBuilder.SetMsgs(&banktypes.MsgSend{})

View File

@ -31,12 +31,20 @@ func (l *DefaultLane) PrepareLane(
txBytes, hash, err := utils.GetTxHashStr(l.Cfg.TxEncoder, tx)
if err != nil {
l.Logger().Info("failed to get hash of tx", "err", err)
txsToRemove[tx] = struct{}{}
continue
}
// if the transaction is already in the (partial) block proposal, we skip it.
if proposal.Contains(txBytes) {
l.Logger().Info(
"failed to select tx for lane; tx is already in proposal",
"tx_hash", hash,
"lane", l.Name(),
)
continue
}
@ -53,6 +61,7 @@ func (l *DefaultLane) PrepareLane(
"tx_hash", hash,
"err", err,
)
txsToRemove[tx] = struct{}{}
continue
}
@ -63,6 +72,11 @@ func (l *DefaultLane) PrepareLane(
// Remove all transactions that were invalid during the creation of the partial proposal.
if err := utils.RemoveTxsFromLane(txsToRemove, l.Mempool); err != nil {
l.Logger().Error(
"failed to remove transactions from lane",
"err", err,
)
return proposal, err
}

View File

@ -1,7 +1,8 @@
package base
import (
"github.com/cometbft/cometbft/libs/log"
"cosmossdk.io/log"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/blockbuster"
)
@ -25,6 +26,9 @@ type DefaultLane struct {
// LaneConfig defines the base lane configuration.
Cfg blockbuster.BaseLaneConfig
// Name defines the name of the lane.
laneName string
}
// NewDefaultLane returns a new default lane.
@ -33,10 +37,19 @@ func NewDefaultLane(cfg blockbuster.BaseLaneConfig) *DefaultLane {
panic(err)
}
return &DefaultLane{
Mempool: NewDefaultMempool(cfg.TxEncoder),
Cfg: cfg,
lane := &DefaultLane{
Mempool: NewDefaultMempool(cfg.TxEncoder),
Cfg: cfg,
laneName: LaneName,
}
return lane
}
// WithName returns a lane option that sets the lane's name.
func (l *DefaultLane) WithName(name string) *DefaultLane {
l.laneName = name
return l
}
// Match returns true if the transaction belongs to this lane. Since
@ -54,7 +67,7 @@ func (l *DefaultLane) Match(tx sdk.Tx) bool {
// Name returns the name of the lane.
func (l *DefaultLane) Name() string {
return LaneName
return l.laneName
}
// Logger returns the lane's logger.
@ -68,7 +81,7 @@ func (l *DefaultLane) SetAnteHandler(anteHandler sdk.AnteHandler) {
}
// GetMaxBlockSpace returns the maximum block space for the lane as a relative percentage.
func (l *DefaultLane) GetMaxBlockSpace() sdk.Dec {
func (l *DefaultLane) GetMaxBlockSpace() math.LegacyDec {
return l.Cfg.MaxBlockSpace
}

View File

@ -26,7 +26,7 @@ func NewFreeLane(cfg blockbuster.BaseLaneConfig, factory Factory) *Lane {
}
return &Lane{
DefaultLane: base.NewDefaultLane(cfg),
DefaultLane: base.NewDefaultLane(cfg).WithName(LaneName),
Factory: factory,
}
}

View File

@ -4,7 +4,8 @@ import (
"context"
"fmt"
"github.com/cometbft/cometbft/libs/log"
"cosmossdk.io/log"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
"github.com/skip-mev/pob/blockbuster"
@ -98,6 +99,6 @@ func (t Terminator) Logger() log.Logger {
}
// GetMaxBlockSpace is a no-op
func (t Terminator) GetMaxBlockSpace() sdk.Dec {
return sdk.ZeroDec()
func (t Terminator) GetMaxBlockSpace() math.LegacyDec {
return math.LegacyZeroDec()
}

View File

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
)
@ -142,7 +143,7 @@ func (m *BBMempool) Registry() []Lane {
// ValidateBasic validates the mempools configuration.
func (m *BBMempool) ValidateBasic() error {
sum := sdk.ZeroDec()
sum := math.LegacyZeroDec()
seenZeroMaxBlockSpace := false
for _, lane := range m.registry {
@ -157,10 +158,10 @@ func (m *BBMempool) ValidateBasic() error {
switch {
// Ensure that the sum of the lane max block space percentages is less than
// or equal to 1.
case sum.GT(sdk.OneDec()):
case sum.GT(math.LegacyOneDec()):
return fmt.Errorf("sum of lane max block space percentages must be less than or equal to 1, got %s", sum)
// Ensure that there is no unused block space.
case sum.LT(sdk.OneDec()) && !seenZeroMaxBlockSpace:
case sum.LT(math.LegacyOneDec()) && !seenZeroMaxBlockSpace:
return fmt.Errorf("sum of total block space percentages will be less than 1")
}

View File

@ -5,8 +5,9 @@ import (
"testing"
"time"
"github.com/cometbft/cometbft/libs/log"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/blockbuster"
@ -47,7 +48,7 @@ func (suite *BlockBusterTestSuite) SetupTest() {
// General config for transactions and randomness for the test suite
suite.encodingConfig = testutils.CreateTestEncodingConfig()
suite.random = rand.New(rand.NewSource(time.Now().Unix()))
key := sdk.NewKVStoreKey(buildertypes.StoreKey)
key := storetypes.NewKVStoreKey(buildertypes.StoreKey)
testCtx := testutil.DefaultContextWithDB(suite.T(), key, storetypes.NewTransientStoreKey("transient_test"))
suite.ctx = testCtx.Ctx.WithBlockHeight(1)
@ -59,7 +60,7 @@ func (suite *BlockBusterTestSuite) SetupTest() {
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: nil,
MaxBlockSpace: sdk.ZeroDec(),
MaxBlockSpace: math.LegacyZeroDec(),
}
// Top of block lane set up
@ -331,8 +332,8 @@ func (suite *BlockBusterTestSuite) fillTOBLane(numTxs int) {
// create a randomized auction transaction
nonce := suite.nonces[acc.Address.String()]
bidAmount := sdk.NewInt(int64(suite.random.Intn(1000) + 1))
bid := sdk.NewCoin("foo", bidAmount)
bidAmount := math.NewInt(int64(suite.random.Intn(1000) + 1))
bid := sdk.NewCoin("stake", bidAmount)
tx, err := testutils.CreateAuctionTxWithSigners(suite.encodingConfig.TxConfig, acc, bid, nonce, 1000, nil)
suite.Require().NoError(err)
@ -351,7 +352,7 @@ func (suite *BlockBusterTestSuite) fillFreeLane(numTxs int) {
// create a few random msgs and construct the tx
nonce := suite.nonces[acc.Address.String()]
tx, err := testutils.CreateFreeTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, "val1", sdk.NewCoin("foo", sdk.NewInt(100)))
tx, err := testutils.CreateFreeTx(suite.encodingConfig.TxConfig, acc, nonce, 1000, "val1", sdk.NewCoin("stake", math.NewInt(100)))
suite.Require().NoError(err)
// insert the tx into the lane and update the account

View File

@ -5,8 +5,8 @@ import (
"encoding/hex"
"fmt"
"github.com/cometbft/cometbft/libs/log"
sdk "github.com/cosmos/cosmos-sdk/types"
"cosmossdk.io/log"
"cosmossdk.io/math"
"github.com/skip-mev/pob/blockbuster/utils"
)
@ -20,7 +20,7 @@ type (
Logger() log.Logger
// GetMaxBlockSpace returns the maximum block space for the lane as a relative percentage.
GetMaxBlockSpace() sdk.Dec
GetMaxBlockSpace() math.LegacyDec
// Name returns the name of the lane.
Name() string

View File

@ -5,6 +5,7 @@ import (
"encoding/hex"
"fmt"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool"
)
@ -51,7 +52,7 @@ func RemoveTxsFromLane(txs map[sdk.Tx]struct{}, mempool sdkmempool.Mempool) erro
// GetMaxTxBytesForLane returns the maximum number of bytes that can be included in the proposal
// for the given lane.
func GetMaxTxBytesForLane(maxTxBytes, totalTxBytes int64, ratio sdk.Dec) int64 {
func GetMaxTxBytesForLane(maxTxBytes, totalTxBytes int64, ratio math.LegacyDec) int64 {
// In the case where the ratio is zero, we return the max tx bytes remaining. Note, the only
// lane that should have a ratio of zero is the default lane. This means the default lane
// will have no limit on the number of transactions it can include in a block and is only

View File

@ -3,7 +3,7 @@ package utils_test
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"cosmossdk.io/math"
"github.com/skip-mev/pob/blockbuster/utils"
)
@ -12,56 +12,56 @@ func TestGetMaxTxBytesForLane(t *testing.T) {
name string
maxTxBytes int64
totalTxBytes int64
ratio sdk.Dec
ratio math.LegacyDec
expected int64
}{
{
"ratio is zero",
100,
50,
sdk.ZeroDec(),
math.LegacyZeroDec(),
50,
},
{
"ratio is zero",
100,
100,
sdk.ZeroDec(),
math.LegacyZeroDec(),
0,
},
{
"ratio is zero",
100,
150,
sdk.ZeroDec(),
math.LegacyZeroDec(),
0,
},
{
"ratio is 1",
100,
50,
sdk.OneDec(),
math.LegacyOneDec(),
100,
},
{
"ratio is 10%",
100,
50,
sdk.MustNewDecFromStr("0.1"),
math.LegacyMustNewDecFromStr("0.1"),
10,
},
{
"ratio is 25%",
100,
50,
sdk.MustNewDecFromStr("0.25"),
math.LegacyMustNewDecFromStr("0.25"),
25,
},
{
"ratio is 50%",
101,
50,
sdk.MustNewDecFromStr("0.5"),
math.LegacyMustNewDecFromStr("0.5"),
50,
},
}

View File

@ -1,29 +0,0 @@
package codec
import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
)
// EncodingConfig defines an encoding configuration.
type EncodingConfig struct {
InterfaceRegistry types.InterfaceRegistry
Codec codec.Codec
TxConfig client.TxConfig
Amino *codec.LegacyAmino
}
func CreateEncodingConfig() EncodingConfig {
cdc := codec.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry()
codec := codec.NewProtoCodec(interfaceRegistry)
return EncodingConfig{
InterfaceRegistry: interfaceRegistry,
Codec: codec,
TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes),
Amino: cdc,
}
}

103
go.mod
View File

@ -3,16 +3,23 @@ module github.com/skip-mev/pob
go 1.20
require (
cosmossdk.io/api v0.3.1
cosmossdk.io/core v0.6.1
cosmossdk.io/api v0.7.0
cosmossdk.io/client/v2 v2.0.0-20230724130706-5442197d6bcd
cosmossdk.io/core v0.9.0
cosmossdk.io/depinject v1.0.0-alpha.3
cosmossdk.io/errors v1.0.0
cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca
cosmossdk.io/math v1.0.1
github.com/cometbft/cometbft v0.37.2
github.com/cometbft/cometbft-db v0.8.0
cosmossdk.io/store v1.0.0-alpha.1
cosmossdk.io/tools/confix v0.0.0-20230724130706-5442197d6bcd
cosmossdk.io/x/circuit v0.0.0-20230724130706-5442197d6bcd
cosmossdk.io/x/feegrant v0.0.0-20230724130706-5442197d6bcd
cosmossdk.io/x/tx v0.9.1
cosmossdk.io/x/upgrade v0.0.0-20230724130706-5442197d6bcd
github.com/cometbft/cometbft v0.38.0-rc3
github.com/cosmos/cosmos-db v1.0.0
github.com/cosmos/cosmos-proto v1.0.0-beta.3
github.com/cosmos/cosmos-sdk v0.47.4
github.com/cosmos/cosmos-sdk v0.50.0-beta.0
github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/gogoproto v1.4.10
github.com/golang/mock v1.6.0
@ -22,6 +29,7 @@ require (
github.com/huandu/skiplist v1.2.0
github.com/ory/dockertest/v3 v3.10.0
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.4
google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529
@ -35,52 +43,60 @@ require (
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v1.1.0 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
cosmossdk.io/tools/rosetta v0.2.1 // indirect
cosmossdk.io/collections v0.3.0 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/aws/aws-sdk-go v1.44.203 // indirect
github.com/aws/aws-sdk-go v1.44.224 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect
github.com/bits-and-blooms/bitset v1.8.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/cockroachdb/apd/v2 v2.0.2 // indirect
github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect
github.com/confio/ics23/go v0.9.0 // indirect
github.com/cockroachdb/errors v1.10.0 // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v0.0.0-20230711190327-88bbab59ff4f // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6 // indirect
github.com/cometbft/cometbft-db v0.8.0 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v0.20.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.12.1 // indirect
github.com/cosmos/rosetta-sdk-go v0.10.0 // indirect
github.com/creachadair/taskgroup v0.3.2 // indirect
github.com/cosmos/iavl v1.0.0-beta.2 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.0 // indirect
github.com/creachadair/atomicfile v0.3.1 // indirect
github.com/creachadair/tomledit v0.0.24 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/docker/cli v20.10.17+incompatible // indirect
github.com/docker/docker v20.10.19+incompatible // indirect
github.com/docker/cli v23.0.1+incompatible // indirect
github.com/docker/docker v23.0.1+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.5.0 // indirect
github.com/emicklei/dot v1.5.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/felixge/httpsnoop v1.0.2 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/getsentry/sentry-go v0.22.0 // indirect
github.com/go-kit/kit v0.12.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@ -97,60 +113,65 @@ require (
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/gtank/merlin v0.1.1 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-getter v1.7.1 // indirect
github.com/hashicorp/go-hclog v1.5.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-metrics v0.5.1 // indirect
github.com/hashicorp/go-plugin v1.4.10 // indirect
github.com/hashicorp/go-safetemp v1.0.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/improbable-eng/grpc-web v0.15.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.16.3 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.7 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/linxGnu/grocksdb v1.7.16 // indirect
github.com/linxGnu/grocksdb v1.8.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
github.com/minio/highwayhash v1.0.2 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/rakyll/statik v0.1.7 // indirect
github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.11.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rs/cors v1.8.2 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/rs/cors v1.8.3 // indirect
github.com/rs/zerolog v1.29.1 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
@ -160,14 +181,15 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/zondax/hid v0.9.1 // indirect
github.com/zondax/ledger-go v0.14.0 // indirect
github.com/zondax/ledger-go v0.14.1 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
@ -180,8 +202,9 @@ require (
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.0 // indirect
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v0.5.5 // indirect
pgregory.net/rapid v1.0.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)

249
go.sum
View File

@ -187,10 +187,14 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/api v0.3.1 h1:NNiOclKRR0AOlO4KIqeaG6PS6kswOMhHD0ir0SscNXE=
cosmossdk.io/api v0.3.1/go.mod h1:DfHfMkiNA2Uhy8fj0JJlOCYOBp4eWUUJ1te5zBGNyIw=
cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s=
cosmossdk.io/core v0.6.1/go.mod h1:g3MMBCBXtxbDWBURDVnJE7XML4BG5qENhs0gzkcpuFA=
cosmossdk.io/api v0.7.0 h1:QsEMIWuv9xWDbF2HZnW4Lpu1/SejCztPu0LQx7t6MN4=
cosmossdk.io/api v0.7.0/go.mod h1:kJFAEMLN57y0viszHDPLMmieF0471o5QAwwApa+270M=
cosmossdk.io/client/v2 v2.0.0-20230724130706-5442197d6bcd h1:Xg/hp/Ml1YPCCxTklzgEIwhy80o7cEd7mvrIx0YS+H0=
cosmossdk.io/client/v2 v2.0.0-20230724130706-5442197d6bcd/go.mod h1:cRYwwVgXhMpKrh6/oao3u+SW5Nb7RHQCGcF+jTsmcQQ=
cosmossdk.io/collections v0.3.0 h1:v0eEqLBxebAV+t+Ahwf9tSJOu95HVLINwROXx2TTZ08=
cosmossdk.io/collections v0.3.0/go.mod h1:CHE1+niUElL9ikCpevRZcp0yqQ4TU0TrEEGirN0mvIg=
cosmossdk.io/core v0.9.0 h1:30ScAOHDIUOCg1DKAwqkho9wuQJnu7GUrMcg0XLioic=
cosmossdk.io/core v0.9.0/go.mod h1:NFgl5r41Q36+RixTvyrfsS6qQ65agCbZ1FTpnN7/G1Y=
cosmossdk.io/depinject v1.0.0-alpha.3 h1:6evFIgj//Y3w09bqOUOzEpFj5tsxBqdc5CfkO7z+zfw=
cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3sMUnEtt8HPWU=
cosmossdk.io/errors v1.0.0 h1:nxF07lmlBbB8NKQhtJ+sJm6ef5uV1XkvPXG2bUntb04=
@ -199,20 +203,30 @@ cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca h1:msenprh2BLLRwNT7zN56TbB
cosmossdk.io/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c=
cosmossdk.io/math v1.0.1 h1:Qx3ifyOPaMLNH/89WeZFH268yCvU4xEcnPLu3sJqPPg=
cosmossdk.io/math v1.0.1/go.mod h1:Ygz4wBHrgc7g0N+8+MrnTfS9LLn9aaTGa9hKopuym5k=
cosmossdk.io/tools/rosetta v0.2.1 h1:ddOMatOH+pbxWbrGJKRAawdBkPYLfKXutK9IETnjYxw=
cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw=
cosmossdk.io/store v1.0.0-alpha.1 h1:/151XxAgm0tiKuYrtJzMG61lf6enpPuP+D/hIN8cRjQ=
cosmossdk.io/store v1.0.0-alpha.1/go.mod h1:ejgU9GhRGMNBduVnDwC3RyhOmu4uKlNQlTiJgPmbDkI=
cosmossdk.io/tools/confix v0.0.0-20230724130706-5442197d6bcd h1:kGqp1WfBw0FHvtYN3FkU9dTkpOKVOkLG+MddoAh/7QA=
cosmossdk.io/tools/confix v0.0.0-20230724130706-5442197d6bcd/go.mod h1:0hR2RA/sxP6yO6nffc6JW9/8S5AHzRvdkivxpvrkWuw=
cosmossdk.io/x/circuit v0.0.0-20230724130706-5442197d6bcd h1:eN2ZRy3Aw89NESga/RvLR7/QzYHr1Ip0mCsi+ATo1+4=
cosmossdk.io/x/circuit v0.0.0-20230724130706-5442197d6bcd/go.mod h1:9j92Murx9xkeeQZl+nkI6iVT+h9/GHg/MqMzHqHLKhc=
cosmossdk.io/x/feegrant v0.0.0-20230724130706-5442197d6bcd h1:of8W41/xzf9Yr68UMMxnodw5Nzo405psYZEie+IacGM=
cosmossdk.io/x/feegrant v0.0.0-20230724130706-5442197d6bcd/go.mod h1:AhfsRnEMElAAnZfrFuIrFpzqbc6o45Dkbkea8XzT/bU=
cosmossdk.io/x/tx v0.9.1 h1:9pmmXA9Vs4qdouOFnzhsdsff2mif0f0kylMq5xTGhRI=
cosmossdk.io/x/tx v0.9.1/go.mod h1:/YFGTXG6+kyihd8YbfuJiXHV4R/mIMm2uvVzo80CIhA=
cosmossdk.io/x/upgrade v0.0.0-20230724130706-5442197d6bcd h1:bxUrk7NTpXxe9CPjz2kUS0tfHfnPoQTV+XCMcVFk9rM=
cosmossdk.io/x/upgrade v0.0.0-20230724130706-5442197d6bcd/go.mod h1:V3F7GY3iFACMLYYwm154Tke2bbCJyCSEyYeaPRNc5BY=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
@ -238,16 +252,15 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U=
github.com/aws/aws-sdk-go v1.44.203/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ=
github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -257,11 +270,13 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s=
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c=
github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ=
github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
@ -303,15 +318,22 @@ github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b80
github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw=
github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU=
github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
github.com/cockroachdb/pebble v0.0.0-20230711190327-88bbab59ff4f h1:V7Cg5eC+VAHz4rusEB1/kSEQ1mbhHJfV0RICDcTBFLw=
github.com/cockroachdb/pebble v0.0.0-20230711190327-88bbab59ff4f/go.mod h1:FN5O47SBEz5+kO9fG8UTR64g2WS1u5ZFCgTvxGjoSks=
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6 h1:DJK8W/iB+s/qkTtmXSrHA49lp5O3OsR7E6z4byOLy34=
github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coinbase/rosetta-sdk-go/types v1.0.0 h1:jpVIwLcPoOeCR6o1tU+Xv7r5bMONNbHU7MuEHboiFuA=
github.com/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c=
github.com/cometbft/cometbft v0.37.2 h1:XB0yyHGT0lwmJlFmM4+rsRnczPlHoAKFX6K8Zgc2/Jc=
github.com/cometbft/cometbft v0.37.2/go.mod h1:Y2MMMN//O5K4YKd8ze4r9jmk4Y7h0ajqILXbH5JQFVs=
github.com/cometbft/cometbft v0.38.0-rc3 h1:Ly3eVPWoFu0y68PmZwLljucPdEBtfigZtqm+OV1W6dE=
github.com/cometbft/cometbft v0.38.0-rc3/go.mod h1:5Jz0Z8YsHSf0ZaAqGvi/ifioSdVFPtEGrm8Y9T/993k=
github.com/cometbft/cometbft-db v0.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo=
github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3HfVHrY4PG8x5c0=
github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4=
github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
@ -324,11 +346,12 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk=
github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis=
github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E=
github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U=
github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o=
github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I=
github.com/cosmos/cosmos-sdk v0.47.4 h1:FVUpEprm58nMmBX4xkRdMDaIG5Nr4yy92HZAfGAw9bg=
github.com/cosmos/cosmos-sdk v0.47.4/go.mod h1:R5n+uM7vguVPFap4pgkdvQCT1nVo/OtPwrlAU40rvok=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/cosmos-sdk v0.50.0-beta.0 h1:cPblupyMlA4qvnvuuQEjYQPq1uqSXBgQmsiGREQ5hd0=
github.com/cosmos/cosmos-sdk v0.50.0-beta.0/go.mod h1:MF/wnXyreoL0g8YdRZhUD4apPdgebMc29LgMJB+dh6M=
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw=
github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE=
@ -336,22 +359,24 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ
github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU=
github.com/cosmos/gogoproto v1.4.10 h1:QH/yT8X+c0F4ZDacDv3z+xE3WU1P1Z3wQoLMBRJoKuI=
github.com/cosmos/gogoproto v1.4.10/go.mod h1:3aAZzeRWpAwr+SS/LLkICX2/kDFyaYVzckBDzygIxek=
github.com/cosmos/iavl v0.20.0 h1:fTVznVlepH0KK8NyKq8w+U7c2L6jofa27aFX6YGlm38=
github.com/cosmos/iavl v0.20.0/go.mod h1:WO7FyvaZJoH65+HFOsDir7xU9FWk2w9cHXNW1XHcl7A=
github.com/cosmos/iavl v1.0.0-beta.2 h1:XOsIM80Yyml/KifCXEYOy9tWCXwMAbLa91n6pReW07Y=
github.com/cosmos/iavl v1.0.0-beta.2/go.mod h1:EA97dJ07TBktRlG/iGzK6g1eCXNj1q3MGoFYkVzrwHE=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo=
github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA=
github.com/cosmos/ledger-cosmos-go v0.12.1 h1:sMBxza5p/rNK/06nBSNmsI/WDqI0pVJFVNihy1Y984w=
github.com/cosmos/ledger-cosmos-go v0.12.1/go.mod h1:dhO6kj+Y+AHIOgAe4L9HL/6NDdyyth4q238I9yFpD2g=
github.com/cosmos/rosetta-sdk-go v0.10.0 h1:E5RhTruuoA7KTIXUcMicL76cffyeoyvNybzUGSKFTcM=
github.com/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4=
github.com/cosmos/ledger-cosmos-go v0.13.0 h1:ex0CvCxToSR7j5WjrghPu2Bu9sSXKikjnVvUryNnx4s=
github.com/cosmos/ledger-cosmos-go v0.13.0/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM=
github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk=
github.com/creachadair/atomicfile v0.3.1 h1:yQORkHjSYySh/tv5th1dkKcn02NEW5JleB84sjt+W4Q=
github.com/creachadair/atomicfile v0.3.1/go.mod h1:mwfrkRxFKwpNAflYZzytbSwxvbK6fdGRRlp0KEQc0qU=
github.com/creachadair/tomledit v0.0.24 h1:5Xjr25R2esu1rKCbQEmjZYlrhFkDspoAbAKb6QKQDhQ=
github.com/creachadair/tomledit v0.0.24/go.mod h1:9qHbShRWQzSCcn617cMzg4eab1vbLCOjOshAWSzWr8U=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0=
github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
@ -360,9 +385,9 @@ github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnG
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o=
@ -374,10 +399,10 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y=
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64=
github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/cli v23.0.1+incompatible h1:LRyWITpGzl2C9e9uGxzisptnxAn1zfZKXy13Ul2Q5oM=
github.com/docker/cli v23.0.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v23.0.1+incompatible h1:vjgvJZxprTTE1A37nm+CLNAdwu6xZekyoiVlUZEINcY=
github.com/docker/docker v23.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
@ -393,6 +418,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/emicklei/dot v1.5.0 h1:tc9eKdCBTgoR68vJ6OcgMtI0SdrGDwLPPVaPA6XhX50=
github.com/emicklei/dot v1.5.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -405,6 +432,9 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@ -417,11 +447,14 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/getsentry/sentry-go v0.22.0 h1:XNX9zKbv7baSEI65l+H1GEJgSeIC1c7EN5kluWaP6dM=
github.com/getsentry/sentry-go v0.22.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -430,20 +463,21 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4=
github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
@ -453,11 +487,12 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0=
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0=
@ -598,19 +633,14 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -620,11 +650,17 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY=
github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-metrics v0.5.1 h1:rfPwUqFU6uZXNvGl4hzjY8LEBsqFVU4si1H9/Hqck/U=
github.com/hashicorp/go-metrics v0.5.1/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk=
github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
@ -648,6 +684,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU=
github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@ -656,6 +694,8 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr
github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw=
github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
@ -695,8 +735,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
@ -704,19 +744,21 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8=
github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4=
github.com/linxGnu/grocksdb v1.8.0 h1:H4L/LhP7GOMf1j17oQAElHgVlbEje2h14A8Tz9cM2BE=
github.com/linxGnu/grocksdb v1.8.0/go.mod h1:09CeBborffXhXdNpEcOeZrLKEnRtrZFEpFdPNI9Zjjg=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
@ -724,6 +766,7 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
@ -740,9 +783,6 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94=
github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@ -759,8 +799,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -784,18 +824,22 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce h1:/pEpMk55wH0X+E5zedGEMOdLuWmV8P4+4W3+LZaM6kg=
github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q=
github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
@ -822,14 +866,16 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU=
github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761 h1:W04oB3d0J01W5jgYRGKsV8LCM6g9EkCvPkZcmFuy0OE=
github.com/petermattis/goid v0.0.0-20230518223814-80aa455d8761/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -845,34 +891,32 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc=
github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk=
github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
@ -880,10 +924,12 @@ github.com/regen-network/gocuke v0.6.2 h1:pHviZ0kKAq2U2hN2q3smKNxct6hS0mGByFMHGn
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo=
github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
@ -946,9 +992,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
@ -965,8 +1011,8 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
@ -991,8 +1037,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo=
github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
github.com/zondax/ledger-go v0.14.0 h1:dlMC7aO8Wss1CxBq2I96kZ69Nh1ligzbs8UWOtq/AsA=
github.com/zondax/ledger-go v0.14.0/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320=
github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c=
github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
@ -1012,11 +1058,15 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@ -1025,7 +1075,6 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
@ -1045,8 +1094,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc h1:mCRnTeVUjcrhlRmO0VK8a6k6Rrf6TF9htwo2pJVSjIU=
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb h1:xIApU0ow1zwMa2uL1VDNeQlNVFTWMQxZUZCMDy0Q4Us=
golang.org/x/exp v0.0.0-20230711153332-06a737ee72cb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -1073,8 +1122,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1179,7 +1228,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1324,13 +1374,13 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@ -1650,9 +1700,8 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@ -1663,8 +1712,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k=
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA=
pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
pgregory.net/rapid v1.0.0 h1:iQaM2w5PZ6xvt6x7hbd7tiDS+nk7YPp5uCaEba+T/F4=
pgregory.net/rapid v1.0.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -4,6 +4,7 @@ package pob.builder.v1;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "amino/amino.proto";
import "cosmos_proto/cosmos.proto";
option go_package = "github.com/skip-mev/pob/x/builder/types";
@ -38,7 +39,9 @@ message Params {
// proposer_fee defines the portion of the winning bid that goes to the block
// proposer that proposed the block.
string proposer_fee = 6 [
(gogoproto.nullable) = false,
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec"
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
}

View File

@ -1,16 +1,24 @@
package app
//nolint:revive
import (
_ "embed"
"io"
"os"
"path/filepath"
"cosmossdk.io/log"
"cosmossdk.io/math"
dbm "github.com/cosmos/cosmos-db"
"cosmossdk.io/depinject"
dbm "github.com/cometbft/cometbft-db"
storetypes "cosmossdk.io/store/types"
circuitkeeper "cosmossdk.io/x/circuit/keeper"
"cosmossdk.io/x/upgrade"
upgradekeeper "cosmossdk.io/x/upgrade/keeper"
feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
feegrantmodule "cosmossdk.io/x/feegrant/module"
cometabci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
tmtypes "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
@ -20,31 +28,22 @@ import (
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/store/streaming"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/x/capability"
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
consensus "github.com/cosmos/cosmos-sdk/x/consensus"
"github.com/cosmos/cosmos-sdk/x/consensus"
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
"github.com/cosmos/cosmos-sdk/x/crisis"
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/evidence"
evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/gov"
@ -54,7 +53,6 @@ import (
groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
"github.com/cosmos/cosmos-sdk/x/mint"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
"github.com/cosmos/cosmos-sdk/x/params"
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
@ -63,9 +61,8 @@ import (
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/x/upgrade"
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
veabci "github.com/skip-mev/pob/abci"
"github.com/skip-mev/pob/blockbuster"
"github.com/skip-mev/pob/blockbuster/abci"
"github.com/skip-mev/pob/blockbuster/lanes/auction"
@ -92,29 +89,24 @@ var (
auth.AppModuleBasic{},
genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
bank.AppModuleBasic{},
capability.AppModuleBasic{},
staking.AppModuleBasic{},
mint.AppModuleBasic{},
distr.AppModuleBasic{},
gov.NewAppModuleBasic(
[]govclient.ProposalHandler{
paramsclient.ProposalHandler,
upgradeclient.LegacyProposalHandler,
upgradeclient.LegacyCancelProposalHandler,
},
),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
slashing.AppModuleBasic{},
feegrantmodule.AppModuleBasic{},
upgrade.AppModuleBasic{},
evidence.AppModuleBasic{},
authzmodule.AppModuleBasic{},
groupmodule.AppModuleBasic{},
vesting.AppModuleBasic{},
nftmodule.AppModuleBasic{},
consensus.AppModuleBasic{},
buildermodule.AppModuleBasic{},
feegrantmodule.AppModuleBasic{},
)
)
@ -125,7 +117,6 @@ var (
type TestApp struct {
*runtime.App
legacyAmino *codec.LegacyAmino
appCodec codec.Codec
txConfig client.TxConfig
@ -134,7 +125,6 @@ type TestApp struct {
// keepers
AccountKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.Keeper
CapabilityKeeper *capabilitykeeper.Keeper
StakingKeeper *stakingkeeper.Keeper
SlashingKeeper slashingkeeper.Keeper
MintKeeper mintkeeper.Keeper
@ -144,11 +134,11 @@ type TestApp struct {
UpgradeKeeper *upgradekeeper.Keeper
ParamsKeeper paramskeeper.Keeper
AuthzKeeper authzkeeper.Keeper
EvidenceKeeper evidencekeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
GroupKeeper groupkeeper.Keeper
ConsensusParamsKeeper consensuskeeper.Keeper
CircuitBreakerKeeper circuitkeeper.Keeper
BuilderKeeper builderkeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
// custom checkTx handler
checkTxHandler abci.CheckTx
@ -182,6 +172,8 @@ func New(
// supply the application options
appOpts,
logger,
// ADVANCED CONFIGURATION
//
@ -216,7 +208,6 @@ func New(
&app.interfaceRegistry,
&app.AccountKeeper,
&app.BankKeeper,
&app.CapabilityKeeper,
&app.StakingKeeper,
&app.SlashingKeeper,
&app.MintKeeper,
@ -226,11 +217,11 @@ func New(
&app.UpgradeKeeper,
&app.ParamsKeeper,
&app.AuthzKeeper,
&app.EvidenceKeeper,
&app.FeeGrantKeeper,
&app.GroupKeeper,
&app.BuilderKeeper,
&app.ConsensusParamsKeeper,
&app.FeeGrantKeeper,
&app.CircuitBreakerKeeper,
); err != nil {
panic(err)
}
@ -261,35 +252,42 @@ func New(
// }
// baseAppOptions = append(baseAppOptions, prepareOpt)
app.App = appBuilder.Build(logger, db, traceStore, baseAppOptions...)
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
// ---------------------------------------------------------------------------- //
// ------------------------- Begin Custom Code -------------------------------- //
// ---------------------------------------------------------------------------- //
// Set POB's mempool into the app.
config := blockbuster.BaseLaneConfig{
Logger: app.Logger(),
TxEncoder: app.txConfig.TxEncoder(),
TxDecoder: app.txConfig.TxDecoder(),
MaxBlockSpace: sdk.ZeroDec(),
}
// Create the lanes.
//
// NOTE: The lanes are ordered by priority. The first lane is the highest priority
// lane and the last lane is the lowest priority lane.
// Top of block lane allows transactions to bid for inclusion at the top of the next block.
tobConfig := blockbuster.BaseLaneConfig{
Logger: app.Logger(),
TxEncoder: app.txConfig.TxEncoder(),
TxDecoder: app.txConfig.TxDecoder(),
MaxBlockSpace: math.LegacyZeroDec(),
}
tobLane := auction.NewTOBLane(
config,
tobConfig,
0,
auction.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
)
// Free lane allows transactions to be included in the next block for free.
freeConfig := blockbuster.BaseLaneConfig{
Logger: app.Logger(),
TxEncoder: app.txConfig.TxEncoder(),
TxDecoder: app.txConfig.TxDecoder(),
MaxBlockSpace: math.LegacyZeroDec(),
IgnoreList: []blockbuster.Lane{
tobLane,
},
}
freeLane := free.NewFreeLane(
config,
freeConfig,
free.NewDefaultFreeFactory(app.txConfig.TxDecoder()),
)
@ -298,19 +296,20 @@ func New(
Logger: app.Logger(),
TxEncoder: app.txConfig.TxEncoder(),
TxDecoder: app.txConfig.TxDecoder(),
MaxBlockSpace: sdk.ZeroDec(),
MaxBlockSpace: math.LegacyZeroDec(),
IgnoreList: []blockbuster.Lane{
tobLane,
freeLane,
},
}
defaultLane := base.NewDefaultLane(defaultConfig)
// Set the lanes into the mempool.
lanes := []blockbuster.Lane{
tobLane,
freeLane,
defaultLane,
}
mempool := blockbuster.NewMempool(lanes...)
app.App.SetMempool(mempool)
@ -338,24 +337,36 @@ func New(
for _, lane := range lanes {
lane.SetAnteHandler(anteHandler)
}
// Set the proposal handlers on the BaseApp along with the custom antehandler.
proposalHandlers := abci.NewProposalHandler(
app.Logger(),
app.txConfig.TxDecoder(),
mempool,
)
app.App.SetPrepareProposal(proposalHandlers.PrepareProposalHandler())
app.App.SetProcessProposal(proposalHandlers.ProcessProposalHandler())
app.App.SetAnteHandler(anteHandler)
// Set the proposal handlers on base app
proposalHandler := veabci.NewProposalHandler(
lanes,
tobLane,
app.Logger(),
app.txConfig.TxEncoder(),
app.txConfig.TxDecoder(),
veabci.NoOpValidateVoteExtensionsFn(),
)
app.App.SetPrepareProposal(proposalHandler.PrepareProposalHandler())
app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
// Set the vote extension handler on the app.
voteExtensionHandler := veabci.NewVoteExtensionHandler(
app.Logger(),
tobLane,
app.txConfig.TxDecoder(),
app.txConfig.TxEncoder(),
)
app.App.SetExtendVoteHandler(voteExtensionHandler.ExtendVoteHandler())
app.App.SetVerifyVoteExtensionHandler(voteExtensionHandler.VerifyVoteExtensionHandler())
// Set the custom CheckTx handler on BaseApp.
checkTxHandler := abci.NewCheckTxHandler(
app.App,
app.txConfig.TxDecoder(),
tobLane,
anteHandler,
ChainID,
)
app.SetCheckTx(checkTxHandler.CheckTx())
@ -363,12 +374,6 @@ func New(
// ------------------------- End Custom Code ---------------------------------- //
// ---------------------------------------------------------------------------- //
// load state streaming if enabled
if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
logger.Error("failed to load state streaming", "err", err)
os.Exit(1)
}
/**** Module Options ****/
app.ModuleManager.RegisterInvariants(app.CrisisKeeper)
@ -401,7 +406,7 @@ func New(
// handler so that we can verify bid transactions before they are inserted into the mempool.
// With the POB CheckTx, we can verify the bid transaction and all of the bundled transactions
// before inserting the bid transaction into the mempool.
func (app *TestApp) CheckTx(req cometabci.RequestCheckTx) cometabci.ResponseCheckTx {
func (app *TestApp) CheckTx(req *cometabci.RequestCheckTx) (*cometabci.ResponseCheckTx, error) {
return app.checkTxHandler(req)
}
@ -410,6 +415,31 @@ func (app *TestApp) SetCheckTx(handler abci.CheckTx) {
app.checkTxHandler = handler
}
// TODO: remove this once we have a proper config file
func (app *TestApp) InitChain(req *cometabci.RequestInitChain) (*cometabci.ResponseInitChain, error) {
req.ConsensusParams.Abci.VoteExtensionsEnableHeight = 2
resp, err := app.App.InitChain(req)
if resp == nil {
resp = &cometabci.ResponseInitChain{}
}
resp.ConsensusParams = &tmtypes.ConsensusParams{
Abci: &tmtypes.ABCIParams{
VoteExtensionsEnableHeight: 2,
},
}
return resp, err
}
// TODO: remove this once we have a proper config file
func (app *TestApp) FinalizeBlock(req *cometabci.RequestFinalizeBlock) (*cometabci.ResponseFinalizeBlock, error) {
resp, err := app.App.FinalizeBlock(req)
if resp != nil {
resp.ConsensusParamUpdates = nil
}
return resp, err
}
// Name returns the name of the App
func (app *TestApp) Name() string { return app.BaseApp.Name() }
@ -451,17 +481,6 @@ func (app *TestApp) GetKey(storeKey string) *storetypes.KVStoreKey {
return kvStoreKey
}
func (app *TestApp) kvStoreKeys() map[string]*storetypes.KVStoreKey {
keys := make(map[string]*storetypes.KVStoreKey)
for _, k := range app.GetStoreKeys() {
if kv, ok := k.(*storetypes.KVStoreKey); ok {
keys[kv.Name()] = kv
}
}
return keys
}
// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.

View File

@ -3,16 +3,17 @@ package app
import (
"time"
"google.golang.org/protobuf/types/known/durationpb"
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
@ -24,46 +25,54 @@ import (
txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
"cosmossdk.io/depinject"
_ "cosmossdk.io/x/circuit" // import for side-effects
_ "cosmossdk.io/x/upgrade" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/authz/module" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/bank" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/crisis" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/gov"
_ "github.com/cosmos/cosmos-sdk/x/group/module" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/mint" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/params" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/slashing" // import for side-effects
_ "github.com/cosmos/cosmos-sdk/x/staking" // import for side-effects
_ "github.com/skip-mev/pob/x/builder" // import for side-effects
"cosmossdk.io/core/appconfig"
circuittypes "cosmossdk.io/x/circuit/types"
"cosmossdk.io/x/feegrant"
upgradetypes "cosmossdk.io/x/upgrade/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/types/module"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
"github.com/cosmos/cosmos-sdk/x/feegrant"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/group"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
buildermodulev1 "github.com/skip-mev/pob/api/pob/builder/module/v1"
buildertypes "github.com/skip-mev/pob/x/builder/types"
"google.golang.org/protobuf/types/known/durationpb"
)
var (
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
// NOTE: Capability module must occur first so that it can initialize any capabilities
// so that other modules that want to create or claim capabilities afterwards in InitChain
// can do so safely.
genesisModuleOrder = []string{
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
feegrant.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
vestingtypes.ModuleName, consensustypes.ModuleName, buildertypes.ModuleName,
}
// module account permissions
moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
{Account: authtypes.FeeCollectorName},
@ -87,58 +96,35 @@ var (
}
// application configuration (used by depinject)
AppConfig = appconfig.Compose(&appv1alpha1.Config{
AppConfig = depinject.Configs(appconfig.Compose(&appv1alpha1.Config{
Modules: []*appv1alpha1.ModuleConfig{
{
Name: "runtime",
Name: runtime.ModuleName,
Config: appconfig.WrapAny(&runtimev1alpha1.Module{
AppName: "TestApp",
// During begin block slashing happens after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool, so as to keep the
// CanWithdrawInvariant invariant.
// NOTE: staking module is required if HistoricalEntries param > 0
// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)
BeginBlockers: []string{
upgradetypes.ModuleName,
capabilitytypes.ModuleName,
minttypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
evidencetypes.ModuleName,
stakingtypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
govtypes.ModuleName,
crisistypes.ModuleName,
genutiltypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
group.ModuleName,
paramstypes.ModuleName,
vestingtypes.ModuleName,
buildertypes.ModuleName,
consensustypes.ModuleName,
feegrant.ModuleName,
},
EndBlockers: []string{
crisistypes.ModuleName,
govtypes.ModuleName,
stakingtypes.ModuleName,
capabilitytypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
minttypes.ModuleName,
genutiltypes.ModuleName,
evidencetypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
group.ModuleName,
paramstypes.ModuleName,
consensustypes.ModuleName,
upgradetypes.ModuleName,
vestingtypes.ModuleName,
buildertypes.ModuleName,
feegrant.ModuleName,
},
OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
{
@ -146,12 +132,34 @@ var (
KvStoreKey: "acc",
},
},
InitGenesis: genesisModuleOrder,
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
InitGenesis: []string{
authtypes.ModuleName,
banktypes.ModuleName,
distrtypes.ModuleName,
stakingtypes.ModuleName,
slashingtypes.ModuleName,
govtypes.ModuleName,
minttypes.ModuleName,
crisistypes.ModuleName,
genutiltypes.ModuleName,
authz.ModuleName,
group.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
vestingtypes.ModuleName,
consensustypes.ModuleName,
circuittypes.ModuleName,
buildertypes.ModuleName,
feegrant.ModuleName,
},
// When ExportGenesis is not specified, the export genesis module order
// is equal to the init genesis order
// ExportGenesis: genesisModuleOrder,
// ExportGenesis: []string{},
// Uncomment if you want to set a custom migration order here.
// OrderMigrations: nil,
// OrderMigrations: []string{},
}),
},
{
@ -168,6 +176,10 @@ var (
Name: vestingtypes.ModuleName,
Config: appconfig.WrapAny(&vestingmodulev1.Module{}),
},
{
Name: feegrant.ModuleName,
Config: appconfig.WrapAny(&feegrantmodulev1.Module{}),
},
{
Name: banktypes.ModuleName,
Config: appconfig.WrapAny(&bankmodulev1.Module{
@ -206,16 +218,6 @@ var (
Name: distrtypes.ModuleName,
Config: appconfig.WrapAny(&distrmodulev1.Module{}),
},
{
Name: capabilitytypes.ModuleName,
Config: appconfig.WrapAny(&capabilitymodulev1.Module{
SealKeeper: true,
}),
},
{
Name: evidencetypes.ModuleName,
Config: appconfig.WrapAny(&evidencemodulev1.Module{}),
},
{
Name: minttypes.ModuleName,
Config: appconfig.WrapAny(&mintmodulev1.Module{}),
@ -227,10 +229,6 @@ var (
MaxMetadataLen: 255,
}),
},
{
Name: feegrant.ModuleName,
Config: appconfig.WrapAny(&feegrantmodulev1.Module{}),
},
{
Name: govtypes.ModuleName,
Config: appconfig.WrapAny(&govmodulev1.Module{}),
@ -243,10 +241,25 @@ var (
Name: consensustypes.ModuleName,
Config: appconfig.WrapAny(&consensusmodulev1.Module{}),
},
{
Name: circuittypes.ModuleName,
Config: appconfig.WrapAny(&circuitmodulev1.Module{}),
},
{
Name: buildertypes.ModuleName,
Config: appconfig.WrapAny(&buildermodulev1.Module{}),
},
},
})
}),
depinject.Supply(
// supply custom module basics
map[string]module.AppModuleBasic{
genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
govtypes.ModuleName: gov.NewAppModuleBasic(
[]govclient.ProposalHandler{
paramsclient.ProposalHandler,
},
),
},
))
)

View File

@ -5,7 +5,9 @@ import (
"fmt"
"log"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
storetypes "cosmossdk.io/store/types"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -16,19 +18,23 @@ import (
// ExportAppStateAndValidators exports the state of the application for a genesis
// file.
func (app *TestApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs []string, modulesToExport []string) (servertypes.ExportedApp, error) {
func (app *TestApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs, modulesToExport []string) (servertypes.ExportedApp, error) {
// as if they could withdraw from the start of the next block
ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
ctx := app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
// We export at last height + 1, because that's the height at which
// Tendermint will start InitChain.
// CometBFT will start InitChain.
height := app.LastBlockHeight() + 1
if forZeroHeight {
height = 0
app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs)
}
genState := app.ModuleManager.ExportGenesisForModules(ctx, app.appCodec, modulesToExport)
genState, err := app.ModuleManager.ExportGenesisForModules(ctx, app.appCodec, modulesToExport)
if err != nil {
return servertypes.ExportedApp{}, err
}
appState, err := json.MarshalIndent(genState, "", " ")
if err != nil {
return servertypes.ExportedApp{}, err
@ -46,7 +52,7 @@ func (app *TestApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedA
// prepare for fresh start at zero height
// NOTE zero height genesis is a temporary feature which will be deprecated
//
// in favour of export at a block height
// in favor of export at a block height
func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
applyAllowedAddrs := false
@ -71,13 +77,20 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
/* Handle fee distribution state. */
// withdraw all validator commission
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
return false
})
if err != nil {
panic(err)
}
// withdraw all delegator rewards
dels := app.StakingKeeper.GetAllDelegations(ctx)
dels, err := app.StakingKeeper.GetAllDelegations(ctx)
if err != nil {
panic(err)
}
for _, delegation := range dels {
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
if err != nil {
@ -102,10 +115,18 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
// reinitialize all validators
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
feePool := app.DistrKeeper.GetFeePool(ctx)
scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
if err != nil {
panic(err)
}
feePool, err := app.DistrKeeper.FeePool.Get(ctx)
if err != nil {
panic(err)
}
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
app.DistrKeeper.SetFeePool(ctx, feePool)
if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil {
panic(err)
}
if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()); err != nil {
panic(err)
@ -142,7 +163,10 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
for i := range red.Entries {
red.Entries[i].CreationHeight = 0
}
app.StakingKeeper.SetRedelegation(ctx, red)
err = app.StakingKeeper.SetRedelegation(ctx, red)
if err != nil {
panic(err)
}
return false
})
@ -151,20 +175,23 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
for i := range ubd.Entries {
ubd.Entries[i].CreationHeight = 0
}
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
err = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
if err != nil {
panic(err)
}
return false
})
// Iterate through validators by power descending, reset bond heights, and
// update bond intra-tx counters.
store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey))
iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
counter := int16(0)
for ; iter.Valid(); iter.Next() {
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
validator, found := app.StakingKeeper.GetValidator(ctx, addr)
if !found {
validator, err := app.StakingKeeper.GetValidator(ctx, addr)
if err != nil {
panic("expected validator, not found")
}
@ -182,7 +209,7 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
return
}
_, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
_, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
if err != nil {
log.Fatal(err)
}

50
tests/app/helpers.go Normal file
View File

@ -0,0 +1,50 @@
package app
import (
"fmt"
"os"
"cosmossdk.io/log"
dbm "github.com/cosmos/cosmos-db"
pruningtypes "cosmossdk.io/store/pruning/types"
bam "github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client/flags"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/testutil/network"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/cosmos/cosmos-sdk/types/module/testutil"
)
// NewTestNetworkFixture returns a new simapp AppConstructor for network simulation tests
func NewTestNetworkFixture() network.TestFixture {
dir, err := os.MkdirTemp("", "simapp")
if err != nil {
panic(fmt.Sprintf("failed creating temporary directory: %v", err))
}
defer os.RemoveAll(dir)
app := New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(dir))
appCtr := func(val network.ValidatorI) servertypes.Application {
return New(
val.GetCtx().Logger, dbm.NewMemDB(), nil, true,
simtestutil.NewAppOptionsWithFlagHome(val.GetCtx().Config.RootDir),
bam.SetPruning(pruningtypes.NewPruningOptionsFromString(val.GetAppConfig().Pruning)),
bam.SetMinGasPrices(val.GetAppConfig().MinGasPrices),
bam.SetChainID(val.GetCtx().Viper.GetString(flags.FlagChainID)),
)
}
return network.TestFixture{
AppConstructor: appCtr,
GenesisState: app.DefaultGenesis(),
EncodingConfig: testutil.TestEncodingConfig{
InterfaceRegistry: app.InterfaceRegistry(),
Codec: app.AppCodec(),
TxConfig: app.TxConfig(),
Amino: app.LegacyAmino(),
},
}
}

View File

@ -5,9 +5,17 @@ import (
"io"
"os"
dbm "github.com/cometbft/cometbft-db"
tmcfg "github.com/cometbft/cometbft/config"
"github.com/cometbft/cometbft/libs/log"
cmtcfg "github.com/cometbft/cometbft/config"
dbm "github.com/cosmos/cosmos-db"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"cosmossdk.io/client/v2/autocli"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
confixcmd "cosmossdk.io/tools/confix/cmd"
"github.com/skip-mev/pob/tests/app"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/config"
"github.com/cosmos/cosmos-sdk/client/debug"
@ -15,49 +23,64 @@ import (
"github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/pruning"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/client/snapshot"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server"
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config"
"github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/crisis"
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
"github.com/skip-mev/pob/tests/app"
"github.com/skip-mev/pob/tests/app/params"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
// NewRootCmd creates a new root command for simd. It is called once in the main function.
func NewRootCmd() *cobra.Command {
// we "pre"-instantiate the application for getting the injected/configured encoding configuration
testApp := app.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(app.DefaultNodeHome))
encodingConfig := params.EncodingConfig{
InterfaceRegistry: testApp.InterfaceRegistry(),
Codec: testApp.AppCodec(),
TxConfig: testApp.TxConfig(),
Amino: testApp.LegacyAmino(),
var (
interfaceRegistry codectypes.InterfaceRegistry
appCodec codec.Codec
txConfig client.TxConfig
legacyAmino *codec.LegacyAmino
autoCliOpts autocli.AppOptions
moduleBasicManager module.BasicManager
)
if err := depinject.Inject(depinject.Configs(app.AppConfig, depinject.Supply(log.NewNopLogger())),
&interfaceRegistry,
&appCodec,
&txConfig,
&legacyAmino,
&autoCliOpts,
&moduleBasicManager,
); err != nil {
panic(err)
}
initClientCtx := client.Context{}.
WithCodec(encodingConfig.Codec).
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
WithTxConfig(encodingConfig.TxConfig).
WithLegacyAmino(encodingConfig.Amino).
WithCodec(appCodec).
WithInterfaceRegistry(interfaceRegistry).
WithLegacyAmino(legacyAmino).
WithInput(os.Stdin).
WithAccountRetriever(types.AccountRetriever{}).
WithHomeDir(app.DefaultNodeHome).
WithViper("")
WithViper("") // In simapp, we don't use any prefix for env variables.
rootCmd := &cobra.Command{
Use: "testappd",
Short: "POB testing application",
Short: "POB's simulation app",
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
// set the default command outputs
cmd.SetOut(cmd.OutOrStdout())
cmd.SetErr(cmd.ErrOrStderr())
initClientCtx = initClientCtx.WithCmdContext(cmd.Context())
initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
if err != nil {
return err
@ -68,26 +91,45 @@ func NewRootCmd() *cobra.Command {
return err
}
// This needs to go after ReadFromClientConfig, as that function
// sets the RPC client needed for SIGN_MODE_TEXTUAL.
enabledSignModes := append([]signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT}, tx.DefaultSignModes...)
txConfigOpts := tx.ConfigOptions{
EnabledSignModes: enabledSignModes,
TextualCoinMetadataQueryFn: txmodule.NewGRPCCoinMetadataQueryFn(initClientCtx),
}
txConfigWithTextual, err := tx.NewTxConfigWithOptions(
codec.NewProtoCodec(interfaceRegistry),
txConfigOpts,
)
if err != nil {
return err
}
initClientCtx = initClientCtx.WithTxConfig(txConfigWithTextual)
if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
return err
}
customAppTemplate, customAppConfig := initAppConfig()
customTMConfig := initTendermintConfig()
customCMTConfig := initCometBFTConfig()
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig)
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customCMTConfig)
},
}
initRootCmd(rootCmd, encodingConfig)
initRootCmd(rootCmd, txConfig, interfaceRegistry, appCodec, moduleBasicManager)
if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
panic(err)
}
return rootCmd
}
// initTendermintConfig helps to override default Tendermint Config values.
// return tmcfg.DefaultConfig if no custom configuration is required for the application.
func initTendermintConfig() *tmcfg.Config {
cfg := tmcfg.DefaultConfig()
// initCometBFTConfig helps to override default CometBFT Config values.
// return cmtcfg.DefaultConfig if no custom configuration is required for the application.
func initCometBFTConfig() *cmtcfg.Config {
cfg := cmtcfg.DefaultConfig()
// these values put a higher strain on node memory
// cfg.P2P.MaxNumInboundPeers = 100
@ -130,7 +172,7 @@ func initAppConfig() (string, interface{}) {
// - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
// own app.toml to override, or use this default value.
//
// In testapp, we set the min gas prices to 0.
// In simapp, we set the min gas prices to 0.
srvCfg.MinGasPrices = "0stake"
// srvCfg.BaseConfig.IAVLDisableFastNode = true // disable fastnode by default
@ -153,15 +195,23 @@ lru_size = 0`
return customAppTemplate, customAppConfig
}
func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
func initRootCmd(
rootCmd *cobra.Command,
txConfig client.TxConfig,
_ codectypes.InterfaceRegistry,
_ codec.Codec,
basicManager module.BasicManager,
) {
cfg := sdk.GetConfig()
cfg.Seal()
rootCmd.AddCommand(
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
genutilcli.InitCmd(basicManager, app.DefaultNodeHome),
NewTestnetCmd(basicManager, banktypes.GenesisBalancesIterator{}),
debug.Cmd(),
config.Cmd(),
pruning.PruningCmd(newApp),
confixcmd.ConfigCommand(),
pruning.Cmd(newApp, app.DefaultNodeHome),
snapshot.Cmd(newApp),
)
server.AddCommands(rootCmd, app.DefaultNodeHome, newApp, appExport, addModuleInitFlags)
@ -169,7 +219,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
// add keybase, auxiliary RPC, query, genesis, and tx child commands
rootCmd.AddCommand(
rpc.StatusCommand(),
genesisCommand(encodingConfig),
genesisCommand(txConfig, basicManager),
queryCommand(),
txCommand(),
keys.Commands(app.DefaultNodeHome),
@ -180,13 +230,13 @@ func addModuleInitFlags(startCmd *cobra.Command) {
crisis.AddModuleInitFlags(startCmd)
}
func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command {
cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, app.ModuleBasics, app.DefaultNodeHome)
// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter
func genesisCommand(txConfig client.TxConfig, basicManager module.BasicManager, cmds ...*cobra.Command) *cobra.Command {
cmd := genutilcli.Commands(txConfig, basicManager, app.DefaultNodeHome)
for _, subCmd := range cmds {
cmd.AddCommand(subCmd)
}
return cmd
}
@ -201,15 +251,13 @@ func queryCommand() *cobra.Command {
}
cmd.AddCommand(
authcmd.GetAccountCmd(),
rpc.ValidatorCommand(),
rpc.BlockCommand(),
server.QueryBlockCmd(),
authcmd.QueryTxsByEventsCmd(),
server.QueryBlocksCmd(),
authcmd.QueryTxCmd(),
)
app.ModuleBasics.AddQueryCommands(cmd)
return cmd
}
@ -234,29 +282,26 @@ func txCommand() *cobra.Command {
authcmd.GetAuxToFeeCommand(),
)
app.ModuleBasics.AddTxCommands(cmd)
return cmd
}
// newApp creates the application
func newApp(
logger log.Logger,
db dbm.DB,
traceStore io.Writer,
appOpts servertypes.AppOptions,
) servertypes.Application {
baseAppOpts := server.DefaultBaseappOptions(appOpts)
baseappOptions := server.DefaultBaseappOptions(appOpts)
return app.New(
logger,
db,
traceStore,
true,
logger, db, traceStore, true,
appOpts,
baseAppOpts...,
baseappOptions...,
)
}
// appExport creates a new simapp (optionally at a given height) and exports state.
func appExport(
logger log.Logger,
db dbm.DB,
@ -267,8 +312,6 @@ func appExport(
appOpts servertypes.AppOptions,
modulesToExport []string,
) (servertypes.ExportedApp, error) {
var testApp *app.TestApp
// this check is necessary as we use the flag in x/upgrade.
// we can exit more gracefully by checking the flag here.
homePath, ok := appOpts.Get(flags.FlagHome).(string)
@ -285,15 +328,16 @@ func appExport(
viperAppOpts.Set(server.FlagInvCheckPeriod, 1)
appOpts = viperAppOpts
var simApp *app.TestApp
if height != -1 {
testApp = app.New(logger, db, traceStore, false, appOpts)
simApp = app.New(logger, db, traceStore, false, appOpts)
if err := testApp.LoadHeight(height); err != nil {
if err := simApp.LoadHeight(height); err != nil {
return servertypes.ExportedApp{}, err
}
} else {
testApp = app.New(logger, db, traceStore, true, appOpts)
simApp = app.New(logger, db, traceStore, true, appOpts)
}
return testApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
}

View File

@ -0,0 +1,522 @@
package cmd
import (
"bufio"
"encoding/json"
"fmt"
"net"
"os"
"path/filepath"
cmtconfig "github.com/cometbft/cometbft/config"
cmttime "github.com/cometbft/cometbft/types/time"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"cosmossdk.io/math"
"cosmossdk.io/math/unsafe"
"github.com/skip-mev/pob/tests/app"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/server"
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
var (
flagNodeDirPrefix = "node-dir-prefix"
flagNumValidators = "v"
flagOutputDir = "output-dir"
flagNodeDaemonHome = "node-daemon-home"
flagStartingIPAddress = "starting-ip-address"
flagEnableLogging = "enable-logging"
flagGRPCAddress = "grpc.address"
flagRPCAddress = "rpc.address"
flagAPIAddress = "api.address"
flagPrintMnemonic = "print-mnemonic"
)
type initArgs struct {
algo string
chainID string
keyringBackend string
minGasPrices string
nodeDaemonHome string
nodeDirPrefix string
numValidators int
outputDir string
startingIPAddress string
}
type startArgs struct {
algo string
apiAddress string
chainID string
enableLogging bool
grpcAddress string
minGasPrices string
numValidators int
outputDir string
printMnemonic bool
rpcAddress string
}
func addTestnetFlagsToCmd(cmd *cobra.Command) {
cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
cmd.Flags().StringP(flagOutputDir, "o", "./.testnets", "Directory to store initialization data for the testnet")
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
cmd.Flags().String(flags.FlagKeyType, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for")
// support old flags name for backwards compatibility
cmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
if name == "algo" {
name = flags.FlagKeyType
}
return pflag.NormalizedName(name)
})
}
// NewTestnetCmd creates a root testnet command with subcommands to run an in-process testnet or initialize
// validator configuration files for running a multi-validator testnet in a separate process
func NewTestnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command {
testnetCmd := &cobra.Command{
Use: "testnet",
Short: "subcommands for starting or configuring local testnets",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
testnetCmd.AddCommand(testnetStartCmd())
testnetCmd.AddCommand(testnetInitFilesCmd(mbm, genBalIterator))
return testnetCmd
}
// testnetInitFilesCmd returns a cmd to initialize all files for CometBFT testnet and application
func testnetInitFilesCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command {
cmd := &cobra.Command{
Use: "init-files",
Short: "Initialize config directories & files for a multi-validator testnet running locally via separate processes (e.g. Docker Compose or similar)",
Long: `init-files will setup "v" number of directories and populate each with
necessary files (private validator, genesis, config, etc.) for running "v" validator nodes.
Booting up a network with these validator folders is intended to be used with Docker Compose,
or a similar setup where each node has a manually configurable IP address.
Note, strict routability for addresses is turned off in the config file.
Example:
simd testnet init-files --v 4 --output-dir ./.testnets --starting-ip-address 192.168.10.2
`,
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}
serverCtx := server.GetServerContextFromCmd(cmd)
config := serverCtx.Config
args := initArgs{}
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
args.keyringBackend, _ = cmd.Flags().GetString(flags.FlagKeyringBackend)
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices)
args.nodeDirPrefix, _ = cmd.Flags().GetString(flagNodeDirPrefix)
args.nodeDaemonHome, _ = cmd.Flags().GetString(flagNodeDaemonHome)
args.startingIPAddress, _ = cmd.Flags().GetString(flagStartingIPAddress)
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType)
return initTestnetFiles(clientCtx, cmd, config, mbm, genBalIterator, args)
},
}
addTestnetFlagsToCmd(cmd)
cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)")
cmd.Flags().String(flagNodeDaemonHome, "simd", "Home directory of the node's daemon configuration")
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
return cmd
}
// testnetStartCmd returns a cmd to start multi validator in-process testnet
func testnetStartCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "start",
Short: "Launch an in-process multi-validator testnet",
Long: `testnet will launch an in-process multi-validator testnet,
and generate "v" directories, populated with necessary validator configuration files
(private validator, genesis, config, etc.).
Example:
simd testnet --v 4 --output-dir ./.testnets
`,
RunE: func(cmd *cobra.Command, _ []string) error {
args := startArgs{}
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices)
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType)
args.enableLogging, _ = cmd.Flags().GetBool(flagEnableLogging)
args.rpcAddress, _ = cmd.Flags().GetString(flagRPCAddress)
args.apiAddress, _ = cmd.Flags().GetString(flagAPIAddress)
args.grpcAddress, _ = cmd.Flags().GetString(flagGRPCAddress)
args.printMnemonic, _ = cmd.Flags().GetBool(flagPrintMnemonic)
return startTestnet(cmd, args)
},
}
addTestnetFlagsToCmd(cmd)
cmd.Flags().Bool(flagEnableLogging, false, "Enable INFO logging of CometBFT validator nodes")
cmd.Flags().String(flagRPCAddress, "tcp://0.0.0.0:26657", "the RPC address to listen on")
cmd.Flags().String(flagAPIAddress, "tcp://0.0.0.0:1317", "the address to listen on for REST API")
cmd.Flags().String(flagGRPCAddress, "0.0.0.0:9090", "the gRPC server address to listen on")
cmd.Flags().Bool(flagPrintMnemonic, true, "print mnemonic of first validator to stdout for manual testing")
return cmd
}
const nodeDirPerm = 0o755
// initTestnetFiles initializes testnet files for a testnet to be run in a separate process
func initTestnetFiles(
clientCtx client.Context,
cmd *cobra.Command,
nodeConfig *cmtconfig.Config,
mbm module.BasicManager,
genBalIterator banktypes.GenesisBalancesIterator,
args initArgs,
) error {
if args.chainID == "" {
args.chainID = "chain-" + unsafe.Str(6)
}
nodeIDs := make([]string, args.numValidators)
valPubKeys := make([]cryptotypes.PubKey, args.numValidators)
simappConfig := srvconfig.DefaultConfig()
simappConfig.MinGasPrices = args.minGasPrices
simappConfig.API.Enable = true
simappConfig.Telemetry.Enabled = true
simappConfig.Telemetry.PrometheusRetentionTime = 60
simappConfig.Telemetry.EnableHostnameLabel = false
simappConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", args.chainID}}
var (
genAccounts []authtypes.GenesisAccount
genBalances []banktypes.Balance
genFiles []string
)
inBuf := bufio.NewReader(cmd.InOrStdin())
// generate private keys, node IDs, and initial transactions
for i := 0; i < args.numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", args.nodeDirPrefix, i)
nodeDir := filepath.Join(args.outputDir, nodeDirName, args.nodeDaemonHome)
gentxsDir := filepath.Join(args.outputDir, "gentxs")
nodeConfig.SetRoot(nodeDir)
nodeConfig.Moniker = nodeDirName
nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
ip, err := getIP(i, args.startingIPAddress)
if err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig)
if err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
genFiles = append(genFiles, nodeConfig.GenesisFile())
kb, err := keyring.New(sdk.KeyringServiceName(), args.keyringBackend, nodeDir, inBuf, clientCtx.Codec)
if err != nil {
return err
}
keyringAlgos, _ := kb.SupportedAlgorithms()
algo, err := keyring.NewSigningAlgoFromString(args.algo, keyringAlgos)
if err != nil {
return err
}
addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "", true, algo)
if err != nil {
_ = os.RemoveAll(args.outputDir)
return err
}
info := map[string]string{"secret": secret}
cliPrint, err := json.Marshal(info)
if err != nil {
return err
}
// save private key seed words
if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil {
return err
}
accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction)
accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction)
coins := sdk.Coins{
sdk.NewCoin("testtoken", accTokens),
sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens),
}
genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()})
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))
valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction)
createValMsg, err := stakingtypes.NewMsgCreateValidator(
sdk.ValAddress(addr),
valPubKeys[i],
sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()),
math.OneInt(),
)
if err != nil {
return err
}
txBuilder := clientCtx.TxConfig.NewTxBuilder()
if err := txBuilder.SetMsgs(createValMsg); err != nil {
return err
}
txBuilder.SetMemo(memo)
txFactory := tx.Factory{}
txFactory = txFactory.
WithChainID(args.chainID).
WithMemo(memo).
WithKeybase(kb).
WithTxConfig(clientCtx.TxConfig)
if err := tx.Sign(cmd.Context(), txFactory, nodeDirName, txBuilder, true); err != nil {
return err
}
txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
if err != nil {
return err
}
if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil {
return err
}
srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), simappConfig)
}
if err := initGenFiles(clientCtx, mbm, args.chainID, genAccounts, genBalances, genFiles, args.numValidators); err != nil {
return err
}
err := collectGenFiles(
clientCtx, nodeConfig, args.chainID, nodeIDs, valPubKeys, args.numValidators,
args.outputDir, args.nodeDirPrefix, args.nodeDaemonHome, genBalIterator,
)
if err != nil {
return err
}
cmd.PrintErrf("Successfully initialized %d node directories\n", args.numValidators)
return nil
}
func initGenFiles(
clientCtx client.Context, mbm module.BasicManager, chainID string,
genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance,
genFiles []string, numValidators int,
) error {
appGenState := mbm.DefaultGenesis(clientCtx.Codec)
// set the accounts in the genesis state
var authGenState authtypes.GenesisState
clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState)
accounts, err := authtypes.PackAccounts(genAccounts)
if err != nil {
return err
}
authGenState.Accounts = accounts
appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState)
// set the balances in the genesis state
var bankGenState banktypes.GenesisState
clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState)
bankGenState.Balances = banktypes.SanitizeGenesisBalances(genBalances)
for _, bal := range bankGenState.Balances {
bankGenState.Supply = bankGenState.Supply.Add(bal.Coins...)
}
appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState)
appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ")
if err != nil {
return err
}
appGenesis := genutiltypes.NewAppGenesisWithVersion(chainID, appGenStateJSON)
// generate empty genesis files for each validator and save
for i := 0; i < numValidators; i++ {
if err := appGenesis.SaveAs(genFiles[i]); err != nil {
return err
}
}
return nil
}
func collectGenFiles(
clientCtx client.Context, nodeConfig *cmtconfig.Config, chainID string,
nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int,
outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator,
) error {
var appState json.RawMessage
genTime := cmttime.Now()
for i := 0; i < numValidators; i++ {
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
gentxsDir := filepath.Join(outputDir, "gentxs")
nodeConfig.Moniker = nodeDirName
nodeConfig.SetRoot(nodeDir)
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey)
appGenesis, err := genutiltypes.AppGenesisFromFile(nodeConfig.GenesisFile())
if err != nil {
return err
}
nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, appGenesis, genBalIterator, genutiltypes.DefaultMessageValidator)
if err != nil {
return err
}
if appState == nil {
// set the canonical application state (they should not differ)
appState = nodeAppState
}
genFile := nodeConfig.GenesisFile()
// overwrite each validator's genesis file to have a canonical genesis time
if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
return err
}
}
return nil
}
func getIP(i int, startingIPAddr string) (ip string, err error) {
if len(startingIPAddr) == 0 {
ip, err = server.ExternalIP()
if err != nil {
return "", err
}
return ip, nil
}
return calculateIP(startingIPAddr, i)
}
func calculateIP(ip string, i int) (string, error) {
ipv4 := net.ParseIP(ip).To4()
if ipv4 == nil {
return "", fmt.Errorf("%v: non ipv4 address", ip)
}
for j := 0; j < i; j++ {
ipv4[3]++
}
return ipv4.String(), nil
}
func writeFile(name, dir string, contents []byte) error {
file := filepath.Join(dir, name)
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("could not create directory %q: %w", dir, err)
}
return os.WriteFile(file, contents, 0o600)
}
// startTestnet starts an in-process testnet
func startTestnet(cmd *cobra.Command, args startArgs) error {
networkConfig := network.DefaultConfig(app.NewTestNetworkFixture)
// Default networkConfig.ChainID is random, and we should only override it if chainID provided
// is non-empty
if args.chainID != "" {
networkConfig.ChainID = args.chainID
}
networkConfig.SigningAlgo = args.algo
networkConfig.MinGasPrices = args.minGasPrices
networkConfig.NumValidators = args.numValidators
networkConfig.EnableLogging = args.enableLogging
networkConfig.RPCAddress = args.rpcAddress
networkConfig.APIAddress = args.apiAddress
networkConfig.GRPCAddress = args.grpcAddress
networkConfig.PrintMnemonic = args.printMnemonic
networkLogger := network.NewCLILogger(cmd)
baseDir := fmt.Sprintf("%s/%s", args.outputDir, networkConfig.ChainID)
if _, err := os.Stat(baseDir); !os.IsNotExist(err) {
return fmt.Errorf(
"testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
networkConfig.ChainID, baseDir)
}
testnet, err := network.New(networkLogger, baseDir, networkConfig)
if err != nil {
return err
}
if _, err := testnet.WaitForHeight(1); err != nil {
return err
}
cmd.Println("press the Enter Key to terminate")
if _, err := fmt.Scanln(); err != nil { // wait for Enter Key
return err
}
testnet.Cleanup()
return nil
}

View File

@ -3,21 +3,16 @@ package main
import (
"os"
"github.com/cosmos/cosmos-sdk/server"
"cosmossdk.io/log"
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
"github.com/skip-mev/pob/tests/app"
"github.com/skip-mev/pob/tests/app/testappd/cmd"
cmd "github.com/skip-mev/pob/tests/app/testappd/cmd"
)
func main() {
rootCmd := cmd.NewRootCmd()
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
switch e := err.(type) {
case server.ErrorCode:
os.Exit(e.Code)
default:
os.Exit(1)
}
log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)
os.Exit(1)
}
}

View File

@ -4,8 +4,8 @@ import (
"fmt"
"os"
dbm "github.com/cometbft/cometbft-db"
"github.com/cometbft/cometbft/libs/log"
"cosmossdk.io/log"
dbm "github.com/cosmos/cosmos-db"
"github.com/cosmos/cosmos-sdk/codec"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
"github.com/skip-mev/pob/tests/app"
@ -40,7 +40,11 @@ type chain struct {
}
func newChain() (*chain, error) {
tmpDir, err := os.MkdirTemp("", "pob-e2e-testnet-")
pwd, err := os.Getwd()
if err != nil {
return nil, err
}
tmpDir, err := os.MkdirTemp(pwd, ".pob-e2e-testnet-")
if err != nil {
return nil, err
}

View File

@ -11,6 +11,7 @@ import (
"testing"
"time"
"cosmossdk.io/math"
cometcfg "github.com/cometbft/cometbft/config"
cometjson "github.com/cometbft/cometbft/libs/json"
rpchttp "github.com/cometbft/cometbft/rpc/client/http"
@ -31,9 +32,9 @@ import (
var (
numValidators = 4
minGasPrice = sdk.NewDecCoinFromDec(app.BondDenom, sdk.MustNewDecFromStr("0.02")).String()
minGasPrice = sdk.NewDecCoinFromDec(app.BondDenom, math.LegacyMustNewDecFromStr("0.02")).String()
initBalanceStr = sdk.NewInt64Coin(app.BondDenom, 1000000000000000000).String()
stakeAmount, _ = sdk.NewIntFromString("100000000000")
stakeAmount = math.NewInt(100000000000)
stakeAmountCoin = sdk.NewCoin(app.BondDenom, stakeAmount)
)
@ -116,15 +117,12 @@ func (s *IntegrationTestSuite) initNodes() {
val0ConfigDir := s.chain.validators[0].configDir()
// Define the builder module parameters
escrowAddress, err := sdk.AccAddressFromBech32("cosmos14j5j2lsx7629590jvpk3vj0xe9w8203jf4yknk")
s.Require().Nil(err, "Unexpected error decoding escrow address")
params := types.Params{
MaxBundleSize: 5,
EscrowAccountAddress: escrowAddress,
ReserveFee: sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000)),
MinBidIncrement: sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000)),
ProposerFee: sdk.NewDecWithPrec(1, 2),
EscrowAccountAddress: sdk.MustAccAddressFromBech32("cosmos14j5j2lsx7629590jvpk3vj0xe9w8203jf4yknk").Bytes(),
ReserveFee: sdk.NewCoin(app.BondDenom, math.NewInt(1000000)),
MinBidIncrement: sdk.NewCoin(app.BondDenom, math.NewInt(1000000)),
ProposerFee: math.LegacyMustNewDecFromStr("0.1"),
FrontRunningProtection: true,
}
@ -162,7 +160,7 @@ func (s *IntegrationTestSuite) initGenesis() {
votingPeriod := 5 * time.Second
govGenState.Params.VotingPeriod = &votingPeriod
govGenState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(100)))
govGenState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(100)))
bz, err := cdc.MarshalJSON(&govGenState)
s.Require().NoError(err)
@ -223,6 +221,9 @@ func (s *IntegrationTestSuite) initValidatorConfigs() {
valConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
valConfig.StateSync.Enable = false
valConfig.LogLevel = "info"
valConfig.BaseConfig.Genesis = filepath.Join("config", "genesis.json")
valConfig.RootDir = filepath.Join("root", ".simapp")
valConfig.Consensus.TimeoutCommit = 2 * time.Second
var peers []string

View File

@ -3,6 +3,7 @@
package e2e
import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/tests/app"
)
@ -28,7 +29,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
accounts := s.createTestAccounts(numAccounts, initBalance)
// basic send amount
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
// auction parameters
params := s.queryBuilderParams()
@ -39,7 +40,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
// standard tx params
gasLimit := uint64(5000000)
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
testCases := []struct {
name string
@ -56,15 +57,17 @@ func (s *IntegrationTestSuite) TestValidBids() {
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
// Ensure that the block was correctly created and executed in the order expected
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
@ -72,7 +75,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
bundleHashes[0]: true,
bundleHashes[1]: true,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
@ -91,15 +94,17 @@ func (s *IntegrationTestSuite) TestValidBids() {
bundle[i] = s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, uint64(i), 1000, gasLimit, fees)
}
// Wait for a block to ensure all transactions are included in the same block
s.waitForABlock()
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
s.broadcastTx(bidTx, 0)
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.displayExpectedBundle("gud auction bid", bidTx, bundle)
s.broadcastTx(bidTx, 0)
// broadcast the bid so that it can be included in a vote extension of a coming block
s.waitForABlock()
// Execute a few other messages to be included in the block after the bid and bundle
normalTxs := make([][]byte, 3)
@ -128,7 +133,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
expectedExecution[hash] = true
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
@ -147,32 +152,33 @@ func (s *IntegrationTestSuite) TestValidBids() {
bundle[i] = s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, uint64(i), 1000, gasLimit, fees)
}
// Wait for a block to ensure all transactions are included in the same block
s.waitForABlock()
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
s.broadcastTx(bidTx, 0)
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.displayExpectedBundle("gud auction bid 1", bidTx, bundle)
// Create another bid transaction that includes the bundle and is valid from the same account
// to verify that user can bid with the same account multiple times in the same block
bid2 := bid.Add(minBidIncrement)
bidTx2 := s.createAuctionBidTx(accounts[1], bid2, bundle, 0, height+1, gasLimit, fees)
s.broadcastTx(bidTx2, 0)
bidTx2 := s.createAuctionBidTx(accounts[1], bid2, bundle, 0, height+3, gasLimit, fees)
s.displayExpectedBundle("gud auction bid 2", bidTx2, bundle)
// Create a third bid
bid3 := bid2.Add(minBidIncrement)
bidTx3 := s.createAuctionBidTx(accounts[1], bid3, bundle, 0, height+1, gasLimit, fees)
s.broadcastTx(bidTx3, 0)
bidTx3 := s.createAuctionBidTx(accounts[1], bid3, bundle, 0, height+3, gasLimit, fees)
s.displayExpectedBundle("gud auction bid 3", bidTx3, bundle)
// Wait for a block to be created
// Wait for a block to ensure all transactions are included in the same block
s.waitForABlock()
s.broadcastTx(bidTx, 0)
s.broadcastTx(bidTx2, 0)
s.broadcastTx(bidTx3, 0)
// Wait for a block to be created
s.waitForNBlocks(2)
// Ensure that the block was correctly created and executed in the order expected
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
@ -180,14 +186,13 @@ func (s *IntegrationTestSuite) TestValidBids() {
expectedExecution := map[string]bool{
bundleHashes[0]: false,
bundleHashes2[0]: false,
bundleHashes3[0]: true,
}
for _, hash := range bundleHashes3[1:] {
for _, hash := range bundleHashes3 {
expectedExecution[hash] = true
}
s.verifyTopOfBlockAuction(height+1, bundleHashes3, expectedExecution)
s.verifyTopOfBlockAuction(height+3, bundleHashes3, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid3)
@ -212,17 +217,21 @@ func (s *IntegrationTestSuite) TestValidBids() {
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+3, gasLimit, fees)
s.displayExpectedBundle("gud auction bid", bidTx, bundle)
// Broadcast the bid transaction
s.broadcastTx(bidTx, 0)
// Wait for a block to broadcast other transactions so that the normal txs can be included in the
// mempool before they are included in a proposal with the vote extensions
s.waitForABlock()
// Broadcast all of the transactions in the bundle to the mempool
for _, tx := range bundle {
s.broadcastTx(tx, 0)
}
// Broadcast the bid transaction
s.broadcastTx(bidTx, 0)
// Broadcast some other transactions to the mempool
normalTxs := make([][]byte, 10)
for i := 0; i < 10; i++ {
@ -247,7 +256,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
expectedExecution[hash] = true
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
@ -272,9 +281,13 @@ func (s *IntegrationTestSuite) TestValidBids() {
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
// Wait for a block to broadcast other transactions so that the normal txs can be included in the
// mempool before they are included in a proposal with the vote extensions
s.waitForABlock()
// Execute a few other messages to be included in the block after the bid and bundle
normalTxs := make([][]byte, 3)
normalTxs[0] = s.createMsgSendTx(accounts[1], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees)
@ -306,7 +319,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
expectedExecution[hash] = true
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
@ -338,7 +351,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
accounts := s.createTestAccounts(numAccounts, initBalance)
// basic send amount
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
// auction parameters
params := s.queryBuilderParams()
@ -349,7 +362,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
// standard tx params
gasLimit := uint64(5000000)
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
testCases := []struct {
name string
@ -378,7 +391,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
// Createa a second bid transaction that includes the bundle and is valid
bid2 := reserveFee.Add(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
bid2 := reserveFee.Add(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, bundle2, 0, height+5, gasLimit, fees)
// Wait for a block to ensure all transactions are included in the same block
@ -413,7 +426,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
}
// Pass in nil since we don't know the order of transactions that ill be executed
s.verifyTopOfBlockAuction(height+2, nil, expectedExecution)
s.verifyTopOfBlockAuction(height+3, nil, expectedExecution)
// Ensure that the escrow account has the correct balance (both bids should have been extracted by this point)
expectedEscrowFee := s.calculateProposerEscrowSplit(bid).Add(s.calculateProposerEscrowSplit(bid2))
@ -443,18 +456,18 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+2, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("gud auction bid 1", bidTx, bundle)
// Create another bid transaction that includes the bundle and is valid from a different account
bid2 := bid.Add(minBidIncrement)
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, bundle2, 0, height+1, gasLimit, fees)
s.broadcastTx(bidTx2, 0)
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, bundle2, 0, height+5, gasLimit, fees)
s.broadcastTx(bidTx2, 1)
s.displayExpectedBundle("gud auction bid 2", bidTx2, bundle2)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(3)
// Ensure that the block was correctly created and executed in the order expected
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
@ -467,10 +480,10 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
expectedExecution[hash] = true
}
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(3)
// Ensure that the block was correctly created and executed in the order expected
expectedExecution = map[string]bool{
@ -481,7 +494,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
expectedExecution[hash] = true
}
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+4, bundleHashes, expectedExecution)
// Ensure that the escrow account has the correct balance (both bids should have been extracted by this point)
expectedEscrowFee := s.calculateProposerEscrowSplit(bid).Add(s.calculateProposerEscrowSplit(bid2))
@ -499,21 +512,23 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bid 1", bidTx, bundle)
// Create a second bid transaction that includes the bundle and is valid (but smaller than the min bid increment)
badBid := reserveFee.Add(sdk.NewInt64Coin(app.BondDenom, 10))
bidTx2 := s.createAuctionBidTx(accounts[0], badBid, bundle, 0, height+1, gasLimit, fees)
bidTx2 := s.createAuctionBidTx(accounts[0], badBid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx2, 0)
s.displayExpectedBundle("bid 2", bidTx2, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
// Ensure only the first bid was executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
@ -523,7 +538,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
bundleHashes[1]: true,
bundleHashes2[0]: false,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
@ -531,7 +546,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
// Wait another block to make sure the second bid is not executed
s.waitForABlock()
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
s.verifyTopOfBlockAuction(height+4, bundleHashes2, expectedExecution)
},
},
{
@ -545,21 +560,23 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
s.createMsgSendTx(accounts[2], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bid 1", bidTx, bundle)
// Create a second bid transaction that includes the bundle and is valid (but smaller than the min bid increment)
badBid := reserveFee.Add(sdk.NewInt64Coin(app.BondDenom, 10))
bidTx2 := s.createAuctionBidTx(accounts[1], badBid, bundle, 0, height+1, gasLimit, fees)
bidTx2 := s.createAuctionBidTx(accounts[1], badBid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx2, 0)
s.displayExpectedBundle("bid 2", bidTx2, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
// Ensure only the first bid was executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
@ -569,7 +586,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
bundleHashes[1]: true,
bundleHashes2[0]: false,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
@ -577,99 +594,55 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
// Wait another block to make sure the second bid is not executed
s.waitForABlock()
s.verifyTopOfBlockAuction(height+4, bundleHashes2, expectedExecution)
},
},
{
name: "Multiple transactions with increasing bids but first bid has same bundle so it should fail in later block (different accounts)",
test: func() {
// Get escrow account balance
escrowBalance := s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom)
// Create a bundle with a single transaction
bundle := [][]byte{
s.createMsgSendTx(accounts[2], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bid 1", bidTx, bundle)
// Create a second bid transaction that includes the bundle and is valid
bid2 := reserveFee.Add(minBidIncrement)
bidTx2 := s.createAuctionBidTx(accounts[0], bid2, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx2, 1)
s.displayExpectedBundle("bid 2", bidTx2, bundle)
// Wait for a block to be created
s.waitForNBlocks(2)
// Ensure only the second bid was executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
expectedExecution := map[string]bool{
bundleHashes[0]: false,
bundleHashes2[0]: true,
bundleHashes2[1]: true,
}
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
},
},
{
name: "Multiple transactions with increasing bids but first bid has same bundle so it should fail in later block (same account)",
test: func() {
// Get escrow account balance
escrowBalance := s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom)
// Create a bundle with a single transaction
bundle := [][]byte{
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
}
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+2, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bid 1", bidTx, bundle)
// Create a second bid transaction that includes the bundle and is valid
bid2 := reserveFee.Add(minBidIncrement)
bidTx2 := s.createAuctionBidTx(accounts[0], bid2, bundle, 0, height+1, gasLimit, fees)
s.broadcastTx(bidTx2, 0)
s.displayExpectedBundle("bid 2", bidTx2, bundle)
// Wait for a block to be created
s.waitForABlock()
// Ensure only the second bid was executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
expectedExecution := map[string]bool{
bundleHashes[0]: false,
bundleHashes2[0]: true,
bundleHashes2[1]: true,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid2)
s.Require().Equal(expectedEscrowFee.Add(escrowBalance), s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom))
// Wait for a block to be created and ensure that the first bid was not executed
s.waitForABlock()
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
name: "Multiple transactions with increasing bids but first bid has same bundle so it should fail in later block (different account)",
test: func() {
// Get escrow account balance
escrowBalance := s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom)
// Create a bundle with a single transaction
bundle := [][]byte{
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
}
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+2, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bid 1", bidTx, bundle)
// Create a second bid transaction that includes the bundle and is valid
bid2 := reserveFee.Add(minBidIncrement)
bidTx2 := s.createAuctionBidTx(accounts[1], bid2, bundle, 0, height+1, gasLimit, fees)
s.broadcastTx(bidTx2, 0)
s.displayExpectedBundle("bid 2", bidTx2, bundle)
// Wait for a block to be created
s.waitForABlock()
// Ensure only the second bid was executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
expectedExecution := map[string]bool{
bundleHashes[0]: false,
bundleHashes2[0]: true,
bundleHashes2[1]: true,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid2)
s.Require().Equal(expectedEscrowFee.Add(escrowBalance), s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom))
// Wait for a block to be created and ensure that the first bid was not executed
s.waitForABlock()
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
s.waitForNBlocks(2)
s.verifyTopOfBlockAuction(height+4, bundleHashes, expectedExecution)
},
},
{
@ -688,21 +661,23 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
s.createMsgSendTx(accounts[1], accounts[0].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes the bundle and is valid
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[2], bid, firstBundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[2], bid, firstBundle, 0, height+2, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bid 1", bidTx, firstBundle)
// Create a second bid transaction that includes the bundle and is valid
bid2 := reserveFee.Add(minBidIncrement)
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, secondBundle, 0, height+1, gasLimit, fees)
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, secondBundle, 0, height+2, gasLimit, fees)
s.broadcastTx(bidTx2, 0)
s.displayExpectedBundle("bid 2", bidTx2, secondBundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
// Ensure only the second bid was executed
bundleHashes := s.bundleToTxHashes(bidTx, firstBundle)
@ -713,15 +688,15 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
bundleHashes2[0]: true,
bundleHashes2[1]: true,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
// Ensure that the escrow account has the correct balance
expectedEscrowFee := s.calculateProposerEscrowSplit(bid2)
s.Require().Equal(expectedEscrowFee.Add(escrowBalance), s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom))
// Wait for a block to be created and ensure that the second bid is executed
// Wait for a block to be created and ensure that the second bid is not executed
s.waitForABlock()
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+4, bundleHashes, expectedExecution)
},
},
}
@ -742,7 +717,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
accounts := s.createTestAccounts(numAccounts, initBalance)
// basic send amount
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
// auction parameters
params := s.queryBuilderParams()
@ -752,7 +727,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
// standard tx params
gasLimit := uint64(5000000)
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
testCases := []struct {
name string
@ -772,10 +747,12 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
// Create a bid transaction that includes the bundle
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bad auction bid", bidTx, bundle)
s.waitForNBlocks(2)
// Ensure that the block was built correctly and that the bid was not executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
expectedExecution := map[string]bool{
@ -783,7 +760,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
bundleHashes[1]: false,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
@ -794,15 +771,18 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
}
// Wait for a block to ensure all transactions are included in the same block
s.waitForABlock()
// Create a bid transaction that includes the bundle that is attempting to bid more than their balance
bid := sdk.NewCoin(app.BondDenom, sdk.NewInt(999999999999999999))
bid := sdk.NewCoin(app.BondDenom, math.NewInt(999999999999999999))
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("bad auction bid", bidTx, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
expectedExecution := map[string]bool{
@ -811,7 +791,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
}
// Ensure that the block was built correctly and that the bid was not executed
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
@ -824,15 +804,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
s.createMsgSendTx(accounts[2], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes the bundle
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("front-running auction bid", bidTx, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
expectedExecution := map[string]bool{
@ -843,7 +825,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
}
// Ensure that the block was built correctly and that the bid was not executed
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
@ -854,15 +836,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1000, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes the bundle
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
expectedExecution := map[string]bool{
@ -871,7 +855,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
}
// Ensure that the block was built correctly and that the bid was not executed
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
@ -882,15 +866,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
}
s.waitForABlock()
// Create a bid transaction that includes a bid that is smaller than the reserve fee
bid := reserveFee.Sub(sdk.NewInt64Coin(app.BondDenom, 1))
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
// Ensure that no transactions were executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
@ -899,7 +885,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
bundleHashes[1]: false,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
@ -911,15 +897,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
bundle = append(bundle, s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, uint64(i+1), 1000, gasLimit, fees))
}
s.waitForABlock()
// Create a bid transaction that includes the bundle
bid := reserveFee
height := s.queryCurrentHeight()
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+2, gasLimit, fees)
s.broadcastTx(bidTx, 0)
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
// Ensure that no transactions were executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
@ -928,7 +916,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
for _, hash := range bundleHashes {
expectedExecution[hash] = false
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
@ -947,7 +935,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
// Wait for a block to be created
s.waitForABlock()
s.waitForNBlocks(2)
// Ensure that no transactions were executed
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
@ -956,7 +944,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
bundleHashes[1]: false,
}
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
},
},
{
@ -977,14 +965,16 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
// Wait for a block to ensure all transactions are included in the same block
s.waitForABlock()
// Broadcast the bid transaction
s.broadcastTx(bidTx, 0)
s.waitForABlock()
// Broadcast all of the transactions in the bundle
for _, tx := range bundle {
s.broadcastTx(tx, 0)
}
// Broadcast the bid transaction
s.broadcastTx(bidTx, 0)
// Wait for a block to be created
s.waitForABlock()
@ -998,7 +988,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
expectedExecution[bundleHashes[0]] = false
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
s.verifyTopOfBlockAuction(height+3, bundleHashes, expectedExecution)
},
},
}
@ -1025,13 +1015,13 @@ func (s *IntegrationTestSuite) TestFreeLane() {
numAccounts := 4
accounts := s.createTestAccounts(numAccounts, initBalance)
defaultSendAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
defaultStakeAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
defaultSendAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
defaultStakeAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
defaultSendAmountCoins := sdk.NewCoins(defaultSendAmount)
// standard tx params
gasLimit := uint64(5000000)
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
testCases := []struct {
name string
@ -1146,8 +1136,8 @@ func (s *IntegrationTestSuite) TestLanes() {
numAccounts := 4
accounts := s.createTestAccounts(numAccounts, initBalance)
defaultSendAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
defaultStakeAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
defaultSendAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
defaultStakeAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
defaultSendAmountCoins := sdk.NewCoins(defaultSendAmount)
// auction parameters
@ -1156,7 +1146,7 @@ func (s *IntegrationTestSuite) TestLanes() {
// standard tx params
gasLimit := uint64(5000000)
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
testCases := []struct {
name string
@ -1182,11 +1172,13 @@ func (s *IntegrationTestSuite) TestLanes() {
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
s.waitForABlock()
s.broadcastTx(bidTx, 0)
// Broadcast the transactions
s.waitForABlock()
s.broadcastTx(freeTx, 0)
s.broadcastTx(normalTx, 0)
s.broadcastTx(bidTx, 0)
// Wait for a block to be created
s.waitForABlock()
@ -1234,11 +1226,14 @@ func (s *IntegrationTestSuite) TestLanes() {
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
s.waitForABlock()
s.broadcastTx(bidTx, 0)
// Broadcast the transactions
s.waitForABlock()
s.broadcastTx(freeTx, 0)
s.broadcastTx(normalTx, 0)
s.broadcastTx(bidTx, 0)
// Wait for a block to be created
s.waitForABlock()
@ -1282,11 +1277,13 @@ func (s *IntegrationTestSuite) TestLanes() {
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
s.waitForABlock()
s.broadcastTx(bidTx, 0)
// Broadcast the transactions
s.waitForABlock()
s.broadcastTx(freeTx, 0)
s.broadcastTx(normalTx, 0)
s.broadcastTx(bidTx, 0)
// Wait for a block to be created
s.waitForABlock()
@ -1316,7 +1313,7 @@ func (s *IntegrationTestSuite) TestLanes() {
// basic free transaction
validators := s.queryValidators()
validator := validators[0]
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(0)))) // Free transaction with no fees
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(0)))) // Free transaction with no fees
// Create a bid transaction that includes the bundle and is invalid (out of sequence number)
bundle := [][]byte{
@ -1328,10 +1325,12 @@ func (s *IntegrationTestSuite) TestLanes() {
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+5, gasLimit, fees)
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
s.waitForABlock()
s.broadcastTx(bidTx, 0)
// Broadcast the transactions
s.waitForABlock()
s.broadcastTx(freeTx, 0)
s.broadcastTx(bidTx, 0)
// Wait for a block to be created
s.waitForABlock()
@ -1359,10 +1358,10 @@ func (s *IntegrationTestSuite) TestLanes() {
// basic free transaction
validators := s.queryValidators()
validator := validators[0]
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(0)))) // Free transaction with no fees
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(0)))) // Free transaction with no fees
// Another free transaction that should be included in the block
freeTx2 := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 1, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(0)))) // Free transaction with no fees
freeTx2 := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 1, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(0)))) // Free transaction with no fees
// Create a bid transaction that includes the bundle and is invalid (out of sequence number)
bundle := [][]byte{
@ -1376,9 +1375,11 @@ func (s *IntegrationTestSuite) TestLanes() {
normalTx := s.createMsgSendTx(accounts[3], accounts[2].Address.String(), defaultSendAmountCoins, 0, 1000, gasLimit, fees)
// Broadcast the transactions (including the ones in the bundle)
s.waitForABlock()
s.broadcastTx(bidTx, 0)
// Broadcast the transactions (including the ones in the bundle)
s.waitForABlock()
s.broadcastTx(freeTx, 0)
s.broadcastTx(bundle[1], 0)
s.broadcastTx(freeTx2, 0)

View File

@ -7,8 +7,8 @@ import (
"strings"
"time"
"cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client/flags"
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
@ -49,7 +49,7 @@ func (s *IntegrationTestSuite) execMsgSendTx(valIdx int, to sdk.AccAddress, amou
amount.String(), // amount
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.chain.validators[valIdx].keyInfo.Name),
fmt.Sprintf("--%s=%s", flags.FlagChainID, s.chain.id),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000000)).String()),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoin(app.BondDenom, math.NewInt(1000000000)).String()),
"--keyring-backend=test",
"--broadcast-mode=sync",
"-y",
@ -127,41 +127,53 @@ func (s *IntegrationTestSuite) createTx(account TestAccount, msgs []sdk.Msg, seq
baseAccount := s.queryAccount(account.Address)
sequenceNumber := baseAccount.Sequence + sequenceOffset
// Set the messages, fees, and timeout.
txBuilder.SetMsgs(msgs...)
txBuilder.SetGasLimit(5000000)
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000))))
s.Require().NoError(txBuilder.SetMsgs(msgs...))
txBuilder.SetFeeAmount(fees)
txBuilder.SetGasLimit(gasLimit)
txBuilder.SetTimeoutHeight(height)
sigV2 := signing.SignatureV2{
signerData := authsigning.SignerData{
ChainID: app.ChainID,
AccountNumber: baseAccount.AccountNumber,
Sequence: sequenceNumber,
PubKey: account.PrivateKey.PubKey(),
}
sig := signing.SignatureV2{
PubKey: account.PrivateKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: txConfig.SignModeHandler().DefaultMode(),
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: sequenceNumber,
}
s.Require().NoError(txBuilder.SetSignatures(sigV2))
s.Require().NoError(txBuilder.SetSignatures(sig))
signerData := authsigning.SignerData{
ChainID: s.chain.id,
AccountNumber: baseAccount.AccountNumber,
Sequence: sequenceNumber,
}
sigV2, err := clienttx.SignWithPrivKey(
txConfig.SignModeHandler().DefaultMode(),
bytesToSign, err := authsigning.GetSignBytesAdapter(
context.Background(),
encodingConfig.TxConfig.SignModeHandler(),
signing.SignMode_SIGN_MODE_DIRECT,
signerData,
txBuilder,
account.PrivateKey,
txConfig,
sequenceNumber,
txBuilder.GetTx(),
)
s.Require().NoError(err)
s.Require().NoError(txBuilder.SetSignatures(sigV2))
bz, err := txConfig.TxEncoder()(txBuilder.GetTx())
sigBytes, err := account.PrivateKey.Sign(bytesToSign)
s.Require().NoError(err)
sig = signing.SignatureV2{
PubKey: account.PrivateKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: sigBytes,
},
Sequence: sequenceNumber,
}
s.Require().NoError(txBuilder.SetSignatures(sig))
signedTx := txBuilder.GetTx()
bz, err := encodingConfig.TxConfig.TxEncoder()(signedTx)
s.Require().NoError(err)
return bz

View File

@ -10,7 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
tmclient "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
cmtclient "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
sdk "github.com/cosmos/cosmos-sdk/types"
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
@ -116,6 +116,18 @@ func (s *IntegrationTestSuite) waitForABlock() {
)
}
// waitForNBlocks will wait until the current block height has increased by n blocks.
func (s *IntegrationTestSuite) waitForNBlocks(n int) {
height := s.queryCurrentHeight()
s.Require().Eventually(
func() bool {
return s.queryCurrentHeight() >= height+uint64(n)
},
10*time.Second,
50*time.Millisecond,
)
}
// bundleToTxHashes converts a bundle to a slice of transaction hashes.
func (s *IntegrationTestSuite) bundleToTxHashes(bidTx []byte, bundle [][]byte) []string {
hashes := make([]string, len(bundle)+1)
@ -163,7 +175,7 @@ func (s *IntegrationTestSuite) verifyTopOfBlockAuction(height uint64, bundle []s
// Check that the block contains the expected transactions in the expected order
// iff the bid transaction was expected to execute.
if len(bundle) > 0 && expectedExecution[bundle[0]] {
if len(bundle) > 0 && len(expectedExecution) > 0 && expectedExecution[bundle[0]] && len(txs) > 0 {
if expectedExecution[bundle[0]] {
hashBz := sha256.Sum256(txs[0])
hash := hex.EncodeToString(hashBz[:])
@ -259,12 +271,12 @@ func (s *IntegrationTestSuite) broadcastTx(tx []byte, valIdx int) {
gRPCURI,
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
s.Require().NoError(err)
client := txtypes.NewServiceClient(grpcConn)
req := &txtypes.BroadcastTxRequest{TxBytes: tx, Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC}
_, err = client.BroadcastTx(context.Background(), req)
s.Require().NoError(err)
client.BroadcastTx(context.Background(), req)
}
// queryTx queries a transaction by its hash and returns whether there was an
@ -335,9 +347,9 @@ func (s *IntegrationTestSuite) queryAccount(address sdk.AccAddress) *authtypes.B
// queryCurrentHeight returns the current block height.
func (s *IntegrationTestSuite) queryCurrentHeight() uint64 {
queryClient := tmclient.NewServiceClient(s.createClientContext())
queryClient := cmtclient.NewServiceClient(s.createClientContext())
req := &tmclient.GetLatestBlockRequest{}
req := &cmtclient.GetLatestBlockRequest{}
resp, err := queryClient.GetLatestBlock(context.Background(), req)
s.Require().NoError(err)
@ -346,13 +358,35 @@ func (s *IntegrationTestSuite) queryCurrentHeight() uint64 {
// queryBlockTxs returns the txs of the block at the given height.
func (s *IntegrationTestSuite) queryBlockTxs(height uint64) [][]byte {
queryClient := tmclient.NewServiceClient(s.createClientContext())
queryClient := cmtclient.NewServiceClient(s.createClientContext())
req := &tmclient.GetBlockByHeightRequest{Height: int64(height)}
req := &cmtclient.GetBlockByHeightRequest{Height: int64(height)}
resp, err := queryClient.GetBlockByHeight(context.Background(), req)
s.Require().NoError(err)
return resp.GetSdkBlock().Data.Txs
txs := resp.GetSdkBlock().Data.Txs
// The first transaction is the vote extension.
s.Require().Greater(len(txs), 0)
return txs[1:]
}
// queryTx returns information about a transaction.
func (s *IntegrationTestSuite) queryTx(txHash string) *txtypes.GetTxResponse {
queryClient := txtypes.NewServiceClient(s.createClientContext())
req := &txtypes.GetTxRequest{Hash: txHash}
resp, err := queryClient.GetTx(context.Background(), req)
s.Require().NoError(err)
return resp
}
// queryTxExecutionHeight returns the block height at which a transaction was executed.
func (s *IntegrationTestSuite) queryTxExecutionHeight(txHash string) uint64 {
txResp := s.queryTx(txHash)
return uint64(txResp.TxResponse.Height)
}
// queryValidators returns the validators of the network.

View File

@ -1,12 +1,14 @@
package e2e
import (
"context"
"encoding/json"
"fmt"
"os"
"path"
"path/filepath"
"cosmossdk.io/math"
cometcfg "github.com/cometbft/cometbft/config"
"github.com/cometbft/cometbft/p2p"
"github.com/cometbft/cometbft/privval"
@ -18,9 +20,10 @@ import (
"github.com/cosmos/cosmos-sdk/server"
sdk "github.com/cosmos/cosmos-sdk/types"
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutilstypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/skip-mev/pob/tests/app"
)
@ -74,7 +77,16 @@ func (v *validator) init() error {
genDoc.Validators = nil
genDoc.AppState = appState
if err = genutil.ExportGenesisFile(genDoc, config.GenesisFile()); err != nil {
if err := genDoc.SaveAs(config.GenesisFile()); err != nil {
return err
}
genAppState, err := genutilstypes.AppGenesisFromFile(config.GenesisFile())
if err != nil {
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
}
if err = genutil.ExportGenesisFile(genAppState, config.GenesisFile()); err != nil {
return fmt.Errorf("failed to export app genesis state: %w", err)
}
@ -167,15 +179,15 @@ func (v *validator) createKey(name string) error {
func (v *validator) buildCreateValidatorMsg(amount sdk.Coin) (sdk.Msg, error) {
description := stakingtypes.NewDescription(v.moniker, "", "", "", "")
commissionRates := stakingtypes.CommissionRates{
Rate: sdk.MustNewDecFromStr("0.1"),
MaxRate: sdk.MustNewDecFromStr("0.2"),
MaxChangeRate: sdk.MustNewDecFromStr("0.01"),
Rate: math.LegacyMustNewDecFromStr("0.1"),
MaxRate: math.LegacyMustNewDecFromStr("0.2"),
MaxChangeRate: math.LegacyMustNewDecFromStr("0.01"),
}
// get the initial validator min self delegation
minSelfDelegation, _ := sdk.NewIntFromString("1")
minSelfDelegation := math.NewInt(1)
valPubKey, err := cryptocodec.FromTmPubKeyInterface(v.consensusKey.PubKey)
valPubKey, err := cryptocodec.FromCmtPubKeyInterface(v.consensusKey.PubKey)
if err != nil {
return nil, err
}
@ -205,10 +217,16 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
txBuilder.SetFeeAmount(sdk.NewCoins())
txBuilder.SetGasLimit(200_000)
pubKey, err := v.keyInfo.GetPubKey()
if err != nil {
return nil, err
}
signerData := authsigning.SignerData{
ChainID: v.chain.id,
AccountNumber: 0,
Sequence: 0,
PubKey: pubKey,
}
// For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on
@ -219,14 +237,14 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
// Note: This line is not needed for SIGN_MODE_LEGACY_AMINO, but putting it
// also doesn't affect its generated sign bytes, so for code's simplicity
// sake, we put it here.
pubKey, err := v.keyInfo.GetPubKey()
if err != nil {
return nil, err
}
sig := txsigning.SignatureV2{
sig := signing.SignatureV2{
PubKey: pubKey,
Data: &txsigning.SingleSignatureData{
SignMode: txsigning.SignMode_SIGN_MODE_DIRECT,
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: 0,
@ -236,8 +254,10 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
return nil, err
}
bytesToSign, err := encodingConfig.TxConfig.SignModeHandler().GetSignBytes(
txsigning.SignMode_SIGN_MODE_DIRECT,
bytesToSign, err := authsigning.GetSignBytesAdapter(
context.Background(),
encodingConfig.TxConfig.SignModeHandler(),
signing.SignMode_SIGN_MODE_DIRECT,
signerData,
txBuilder.GetTx(),
)
@ -250,10 +270,10 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
return nil, err
}
sig = txsigning.SignatureV2{
sig = signing.SignatureV2{
PubKey: pubKey,
Data: &txsigning.SingleSignatureData{
SignMode: txsigning.SignMode_SIGN_MODE_DIRECT,
Data: &signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: sigBytes,
},
Sequence: 0,

View File

@ -1,6 +1,7 @@
package test
import (
"context"
"reflect"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -58,7 +59,7 @@ func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder {
return m.recorder
}
func (m *MockBankKeeper) GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin {
func (m *MockBankKeeper) GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetBalance", ctx, addr, denom)
ret0 := ret[0].(sdk.Coin)
@ -70,7 +71,7 @@ func (mr *MockBankKeeperMockRecorder) GetBalance(ctx, addr, denom interface{}) *
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalance", reflect.TypeOf((*MockBankKeeper)(nil).GetBalance), ctx, addr, denom)
}
func (m *MockBankKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error {
func (m *MockBankKeeper) SendCoins(ctx context.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error {
m.ctrl.T.Helper()
m.ctrl.Call(m, "SendCoins", ctx, fromAddr, toAddr, amt)
return nil
@ -100,11 +101,11 @@ func (m *MockDistributionKeeper) EXPECT() *MockDistributionKeeperRecorder {
return m.recorder
}
func (m *MockDistributionKeeper) GetPreviousProposerConsAddr(ctx sdk.Context) sdk.ConsAddress {
func (m *MockDistributionKeeper) GetPreviousProposerConsAddr(ctx context.Context) (sdk.ConsAddress, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetPreviousProposerConsAddr", ctx)
ret0 := ret[0].(sdk.ConsAddress)
return ret0
return ret0, nil
}
func (mr *MockDistributionKeeperRecorder) GetPreviousProposerConsAddr(ctx any) *gomock.Call {
@ -131,14 +132,14 @@ func (m *MockStakingKeeper) EXPECT() *MockStakingKeeperRecorder {
return m.recorder
}
func (m *MockStakingKeeper) ValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) stakingtypes.ValidatorI {
func (m *MockStakingKeeper) GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.Validator, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ValidatorByConsAddr", ctx, consAddr)
ret0 := ret[0].(stakingtypes.ValidatorI)
return ret0
ret := m.ctrl.Call(m, "GetValidatorByConsAddr", ctx, consAddr)
ret0 := ret[0].(stakingtypes.Validator)
return ret0, nil
}
func (mr *MockStakingKeeperRecorder) ValidatorByConsAddr(ctx, consAddr any) *gomock.Call {
func (mr *MockStakingKeeperRecorder) GetValidatorByConsAddr(ctx, consAddr any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidatorByConsAddr", reflect.TypeOf((*MockStakingKeeper)(nil).ValidatorByConsAddr), ctx, consAddr)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorByConsAddr", reflect.TypeOf((*MockStakingKeeper)(nil).GetValidatorByConsAddr), ctx, consAddr)
}

View File

@ -3,8 +3,10 @@ package test
import (
"math/rand"
txsigning "cosmossdk.io/x/tx/signing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
addresscodec "github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
@ -16,6 +18,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/tx"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/cosmos/gogoproto/proto"
buildertypes "github.com/skip-mev/pob/x/builder/types"
)
@ -27,21 +30,29 @@ type EncodingConfig struct {
}
func CreateTestEncodingConfig() EncodingConfig {
cdc := codec.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry()
interfaceRegistry, err := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
SigningOptions: txsigning.Options{
AddressCodec: addresscodec.NewBech32Codec("cosmos"),
ValidatorAddressCodec: addresscodec.NewBech32Codec("cosmos"),
},
})
if err != nil {
panic(err)
}
banktypes.RegisterInterfaces(interfaceRegistry)
cryptocodec.RegisterInterfaces(interfaceRegistry)
buildertypes.RegisterInterfaces(interfaceRegistry)
stakingtypes.RegisterInterfaces(interfaceRegistry)
codec := codec.NewProtoCodec(interfaceRegistry)
protoCodec := codec.NewProtoCodec(interfaceRegistry)
return EncodingConfig{
InterfaceRegistry: interfaceRegistry,
Codec: codec,
TxConfig: tx.NewTxConfig(codec, tx.DefaultSignModes),
Amino: cdc,
Codec: protoCodec,
TxConfig: tx.NewTxConfig(protoCodec, tx.DefaultSignModes),
Amino: codec.NewLegacyAmino(),
}
}
@ -82,7 +93,7 @@ func CreateTx(txCfg client.TxConfig, account Account, nonce, timeout uint64, msg
sigV2 := signing.SignatureV2{
PubKey: account.PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: txCfg.SignModeHandler().DefaultMode(),
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce,
@ -125,7 +136,7 @@ func CreateRandomTx(txCfg client.TxConfig, account Account, nonce, numberMsgs, t
sigV2 := signing.SignatureV2{
PubKey: account.PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: txCfg.SignModeHandler().DefaultMode(),
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce,
@ -163,7 +174,7 @@ func CreateTxWithSigners(txCfg client.TxConfig, nonce, timeout uint64, signers [
sigV2 := signing.SignatureV2{
PubKey: signers[0].PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: txCfg.SignModeHandler().DefaultMode(),
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce,
@ -208,7 +219,7 @@ func CreateAuctionTxWithSigners(txCfg client.TxConfig, bidder Account, bid sdk.C
sigV2 := signing.SignatureV2{
PubKey: bidder.PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: txCfg.SignModeHandler().DefaultMode(),
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce,
@ -271,7 +282,7 @@ func CreateMsgAuctionBid(txCfg client.TxConfig, bidder Account, bid sdk.Coin, no
sigV2 := signing.SignatureV2{
PubKey: bidder.PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: txCfg.SignModeHandler().DefaultMode(),
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
},
Sequence: nonce + uint64(i),

View File

@ -123,7 +123,11 @@ func (bd BuilderDecorator) ValidateTimeout(ctx sdk.Context, timeout int64) error
}
if timeout < currentBlockHeight {
return fmt.Errorf("timeout height cannot be less than the current block height")
return fmt.Errorf(
"timeout height cannot be less than the current block height (timeout: %d, current block height: %d)",
timeout,
currentBlockHeight,
)
}
return nil

View File

@ -5,7 +5,8 @@ import (
"testing"
"time"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
@ -86,7 +87,7 @@ func (suite *AnteTestSuite) SetupTest() {
TxEncoder: suite.encodingConfig.TxConfig.TxEncoder(),
TxDecoder: suite.encodingConfig.TxConfig.TxDecoder(),
AnteHandler: suite.anteHandler,
MaxBlockSpace: sdk.ZeroDec(),
MaxBlockSpace: math.LegacyZeroDec(),
}
suite.tobLane = auction.NewTOBLane(
config,
@ -103,8 +104,7 @@ func (suite *AnteTestSuite) SetupTest() {
}
func (suite *AnteTestSuite) anteHandler(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
signer := tx.GetMsgs()[0].GetSigners()[0]
suite.bankKeeper.EXPECT().GetBalance(ctx, signer, suite.balance.Denom).AnyTimes().Return(suite.balance)
suite.bankKeeper.EXPECT().GetBalance(ctx, gomock.Any(), suite.balance.Denom).AnyTimes().Return(suite.balance)
next := func(ctx sdk.Context, tx sdk.Tx, _ bool) (sdk.Context, error) {
return ctx, nil
@ -117,20 +117,20 @@ func (suite *AnteTestSuite) TestAnteHandler() {
var (
// Bid set up
bidder = testutils.RandomAccounts(suite.random, 1)[0]
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
balance = sdk.NewCoin("foo", sdk.NewInt(10000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
balance = sdk.NewCoin("stake", math.NewInt(10000))
signers = []testutils.Account{bidder}
// Top bidding auction tx set up
topBidder = testutils.RandomAccounts(suite.random, 1)[0]
topBid = sdk.NewCoin("foo", sdk.NewInt(100))
topBid = sdk.NewCoin("stake", math.NewInt(100))
insertTopBid = true
timeout = uint64(1000)
// Auction setup
maxBundleSize uint32 = 5
reserveFee = sdk.NewCoin("foo", sdk.NewInt(100))
minBidIncrement = sdk.NewCoin("foo", sdk.NewInt(100))
reserveFee = sdk.NewCoin("stake", math.NewInt(100))
minBidIncrement = sdk.NewCoin("stake", math.NewInt(100))
frontRunningProtection = true
)
@ -150,7 +150,7 @@ func (suite *AnteTestSuite) TestAnteHandler() {
"smaller bid than winning bid, invalid auction tx",
func() {
insertTopBid = true
topBid = sdk.NewCoin("foo", sdk.NewInt(100000))
topBid = sdk.NewCoin("stake", math.NewInt(100000))
},
false,
},
@ -158,25 +158,25 @@ func (suite *AnteTestSuite) TestAnteHandler() {
"bidder has insufficient balance, invalid auction tx",
func() {
insertTopBid = false
balance = sdk.NewCoin("foo", sdk.NewInt(10))
balance = sdk.NewCoin("stake", math.NewInt(10))
},
false,
},
{
"bid is smaller than reserve fee, invalid auction tx",
func() {
balance = sdk.NewCoin("foo", sdk.NewInt(10000))
bid = sdk.NewCoin("foo", sdk.NewInt(101))
reserveFee = sdk.NewCoin("foo", sdk.NewInt(1000))
balance = sdk.NewCoin("stake", math.NewInt(10000))
bid = sdk.NewCoin("stake", math.NewInt(101))
reserveFee = sdk.NewCoin("stake", math.NewInt(1000))
},
false,
},
{
"valid auction bid tx",
func() {
balance = sdk.NewCoin("foo", sdk.NewInt(10000))
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
reserveFee = sdk.NewCoin("foo", sdk.NewInt(100))
balance = sdk.NewCoin("stake", math.NewInt(10000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
reserveFee = sdk.NewCoin("stake", math.NewInt(100))
},
true,
},
@ -191,9 +191,9 @@ func (suite *AnteTestSuite) TestAnteHandler() {
"auction tx is the top bidding tx",
func() {
timeout = 1000
balance = sdk.NewCoin("foo", sdk.NewInt(10000))
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
reserveFee = sdk.NewCoin("foo", sdk.NewInt(100))
balance = sdk.NewCoin("stake", math.NewInt(10000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
reserveFee = sdk.NewCoin("stake", math.NewInt(100))
insertTopBid = true
topBidder = bidder

View File

@ -4,6 +4,7 @@ import (
"math/rand"
"time"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
testutils "github.com/skip-mev/pob/testutils"
"github.com/skip-mev/pob/x/builder/keeper"
@ -14,13 +15,13 @@ func (suite *KeeperTestSuite) TestValidateBidInfo() {
var (
// Tx building variables
accounts = []testutils.Account{} // tracks the order of signers in the bundle
balance = sdk.NewCoin("foo", sdk.NewInt(10000))
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
balance = sdk.NewCoin("stake", math.NewInt(10000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
// Auction params
maxBundleSize uint32 = 10
reserveFee = sdk.NewCoin("foo", sdk.NewInt(1000))
minBidIncrement = sdk.NewCoin("foo", sdk.NewInt(1000))
reserveFee = sdk.NewCoin("stake", math.NewInt(1000))
minBidIncrement = sdk.NewCoin("stake", math.NewInt(1000))
escrowAddress = sdk.AccAddress([]byte("escrow"))
frontRunningProtection = true
@ -46,8 +47,8 @@ func (suite *KeeperTestSuite) TestValidateBidInfo() {
{
"insufficient balance",
func() {
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
balance = sdk.NewCoin("foo", sdk.NewInt(100))
bid = sdk.NewCoin("stake", math.NewInt(1000))
balance = sdk.NewCoin("stake", math.NewInt(100))
},
false,
},
@ -55,8 +56,8 @@ func (suite *KeeperTestSuite) TestValidateBidInfo() {
"too many transactions in the bundle",
func() {
// reset the balance and bid to their original values
bid = sdk.NewCoin("foo", sdk.NewInt(1000))
balance = sdk.NewCoin("foo", sdk.NewInt(10000))
bid = sdk.NewCoin("stake", math.NewInt(1000))
balance = sdk.NewCoin("stake", math.NewInt(10000))
accounts = testutils.RandomAccounts(rnd, int(maxBundleSize+1))
},
false,
@ -119,33 +120,33 @@ func (suite *KeeperTestSuite) TestValidateBidInfo() {
"invalid bundle that does not outbid the highest bid",
func() {
accounts = []testutils.Account{bidder, bidder, bidder}
highestBid = sdk.NewCoin("foo", sdk.NewInt(500))
bid = sdk.NewCoin("foo", sdk.NewInt(500))
highestBid = sdk.NewCoin("stake", math.NewInt(500))
bid = sdk.NewCoin("stake", math.NewInt(500))
},
false,
},
{
"valid bundle that outbids the highest bid",
func() {
highestBid = sdk.NewCoin("foo", sdk.NewInt(500))
bid = sdk.NewCoin("foo", sdk.NewInt(1500))
highestBid = sdk.NewCoin("stake", math.NewInt(500))
bid = sdk.NewCoin("stake", math.NewInt(1500))
},
true,
},
{
"attempting to bid with a different denom",
func() {
highestBid = sdk.NewCoin("foo", sdk.NewInt(500))
bid = sdk.NewCoin("foo2", sdk.NewInt(1500))
highestBid = sdk.NewCoin("stake", math.NewInt(500))
bid = sdk.NewCoin("stake2", math.NewInt(1500))
},
false,
},
{
"min bid increment is different from bid denom", // THIS SHOULD NEVER HAPPEN
func() {
highestBid = sdk.NewCoin("foo", sdk.NewInt(500))
bid = sdk.NewCoin("foo", sdk.NewInt(1500))
minBidIncrement = sdk.NewCoin("foo2", sdk.NewInt(1000))
highestBid = sdk.NewCoin("stake", math.NewInt(500))
bid = sdk.NewCoin("stake", math.NewInt(1500))
minBidIncrement = sdk.NewCoin("stake2", math.NewInt(1000))
},
false,
},

View File

@ -3,10 +3,11 @@ package keeper
import (
"fmt"
"github.com/cometbft/cometbft/libs/log"
"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"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/rewards"
"github.com/skip-mev/pob/x/builder/types"
@ -161,10 +162,10 @@ func (k Keeper) GetMinBidIncrement(ctx sdk.Context) (sdk.Coin, error) {
}
// GetProposerFee returns the proposer fee for the builder module.
func (k Keeper) GetProposerFee(ctx sdk.Context) (sdk.Dec, error) {
func (k Keeper) GetProposerFee(ctx sdk.Context) (math.LegacyDec, error) {
params, err := k.GetParams(ctx)
if err != nil {
return sdk.ZeroDec(), err
return math.LegacyZeroDec(), err
}
return params.ProposerFee, nil

View File

@ -3,7 +3,7 @@ package keeper_test
import (
"testing"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"

View File

@ -51,7 +51,12 @@ func (m MsgServer) AuctionBid(goCtx context.Context, msg *types.MsgAuctionBid) (
return nil, err
}
} else {
rewardsAddress := m.rewardsAddressProvider.GetRewardsAddress(ctx)
rewardsAddress, err := m.rewardsAddressProvider.GetRewardsAddress(ctx)
if err != nil {
// In the case where the rewards address provider returns an error, the
// escrow account will receive the entire bid.
rewardsAddress = escrowAddress
}
// determine the amount of the bid that goes to the (previous) proposer
bid := sdk.NewDecCoinsFromCoins(msg.Bid)

View File

@ -4,6 +4,7 @@ import (
"math/rand"
"time"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
testutils "github.com/skip-mev/pob/testutils"
@ -32,7 +33,7 @@ func (suite *KeeperTestSuite) TestMsgAuctionBid() {
{
name: "invalid bidder address",
msg: &types.MsgAuctionBid{
Bidder: "foo",
Bidder: "stake",
},
malleate: func() {},
expectErr: true,
@ -54,12 +55,12 @@ func (suite *KeeperTestSuite) TestMsgAuctionBid() {
name: "valid bundle with no proposer fee",
msg: &types.MsgAuctionBid{
Bidder: bidder.Address.String(),
Bid: sdk.NewInt64Coin("foo", 1024),
Bid: sdk.NewInt64Coin("stake", 1024),
Transactions: [][]byte{{0xFF}, {0xFF}},
},
malleate: func() {
params := types.DefaultParams()
params.ProposerFee = sdk.ZeroDec()
params.ProposerFee = math.LegacyZeroDec()
params.EscrowAccountAddress = escrow.Address
suite.builderKeeper.SetParams(suite.ctx, params)
@ -68,7 +69,7 @@ func (suite *KeeperTestSuite) TestMsgAuctionBid() {
suite.ctx,
bidder.Address,
escrow.Address,
sdk.NewCoins(sdk.NewInt64Coin("foo", 1024)),
sdk.NewCoins(sdk.NewInt64Coin("stake", 1024)),
).
Return(nil).
AnyTimes()
@ -79,30 +80,30 @@ func (suite *KeeperTestSuite) TestMsgAuctionBid() {
name: "valid bundle with proposer fee",
msg: &types.MsgAuctionBid{
Bidder: bidder.Address.String(),
Bid: sdk.NewInt64Coin("foo", 3416),
Bid: sdk.NewInt64Coin("stake", 3416),
Transactions: [][]byte{{0xFF}, {0xFF}},
},
malleate: func() {
params := types.DefaultParams()
params.ProposerFee = sdk.MustNewDecFromStr("0.30")
params.ProposerFee = math.LegacyMustNewDecFromStr("0.30")
params.EscrowAccountAddress = escrow.Address
suite.builderKeeper.SetParams(suite.ctx, params)
suite.distrKeeper.EXPECT().
GetPreviousProposerConsAddr(suite.ctx).
Return(proposerCons.ConsKey.PubKey().Address().Bytes())
Return(proposerCons.ConsKey.PubKey().Address().Bytes(), nil)
suite.stakingKeeper.EXPECT().
ValidatorByConsAddr(suite.ctx, sdk.ConsAddress(proposerCons.ConsKey.PubKey().Address().Bytes())).
Return(proposer).
GetValidatorByConsAddr(suite.ctx, sdk.ConsAddress(proposerCons.ConsKey.PubKey().Address().Bytes())).
Return(proposer, nil).
AnyTimes()
suite.bankKeeper.EXPECT().
SendCoins(suite.ctx, bidder.Address, proposerOperator.Address, sdk.NewCoins(sdk.NewInt64Coin("foo", 1024))).
SendCoins(suite.ctx, bidder.Address, proposerOperator.Address, sdk.NewCoins(sdk.NewInt64Coin("stake", 1024))).
Return(nil)
suite.bankKeeper.EXPECT().
SendCoins(suite.ctx, bidder.Address, escrow.Address, sdk.NewCoins(sdk.NewInt64Coin("foo", 2392))).
SendCoins(suite.ctx, bidder.Address, escrow.Address, sdk.NewCoins(sdk.NewInt64Coin("stake", 2392))).
Return(nil)
},
expectErr: false,
@ -139,7 +140,7 @@ func (suite *KeeperTestSuite) TestMsgUpdateParams() {
msg: &types.MsgUpdateParams{
Authority: suite.authorityAccount.String(),
Params: types.Params{
ProposerFee: sdk.MustNewDecFromStr("1.1"),
ProposerFee: math.LegacyMustNewDecFromStr("1.1"),
},
},
passBasic: false,
@ -150,7 +151,7 @@ func (suite *KeeperTestSuite) TestMsgUpdateParams() {
msg: &types.MsgUpdateParams{
Authority: suite.authorityAccount.String(),
Params: types.Params{
ProposerFee: sdk.MustNewDecFromStr("0.1"),
ProposerFee: math.LegacyMustNewDecFromStr("0.1"),
},
},
passBasic: false,
@ -161,11 +162,11 @@ func (suite *KeeperTestSuite) TestMsgUpdateParams() {
msg: &types.MsgUpdateParams{
Authority: account.Address.String(),
Params: types.Params{
ProposerFee: sdk.MustNewDecFromStr("0.1"),
ProposerFee: math.LegacyMustNewDecFromStr("0.1"),
MaxBundleSize: 2,
EscrowAccountAddress: suite.authorityAccount,
MinBidIncrement: sdk.NewInt64Coin("foo", 100),
ReserveFee: sdk.NewInt64Coin("foo", 100),
MinBidIncrement: sdk.NewInt64Coin("stake", 100),
ReserveFee: sdk.NewInt64Coin("stake", 100),
},
},
passBasic: true,

View File

@ -7,11 +7,11 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/depinject"
storetypes "cosmossdk.io/store/types"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

View File

@ -1,10 +1,14 @@
package rewards
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/x/builder/types"
)
var _ types.RewardsAddressProvider = (*FixedAddressRewardsAddressProvider)(nil)
// FixedAddressRewardsAddressProvider provides a portion of
// auction profits to a fixed address (i.e. the proposer portion).
// This is useful for chains that do not have a distribution module.
@ -15,12 +19,16 @@ type FixedAddressRewardsAddressProvider struct {
// NewFixedAddressRewardsAddressProvider creates a reward provider for a fixed address.
func NewFixedAddressRewardsAddressProvider(
rewardsAddress sdk.AccAddress,
) types.RewardsAddressProvider {
) *FixedAddressRewardsAddressProvider {
return &FixedAddressRewardsAddressProvider{
rewardsAddress: rewardsAddress,
}
}
func (p *FixedAddressRewardsAddressProvider) GetRewardsAddress(_ sdk.Context) sdk.AccAddress {
return p.rewardsAddress
func (p *FixedAddressRewardsAddressProvider) GetRewardsAddress(_ sdk.Context) (sdk.AccAddress, error) {
if p.rewardsAddress.Empty() {
return nil, fmt.Errorf("rewards address is empty")
}
return p.rewardsAddress, nil
}

View File

@ -6,6 +6,8 @@ import (
"github.com/skip-mev/pob/x/builder/types"
)
var _ types.RewardsAddressProvider = (*ProposerRewardsAddressProvider)(nil)
// ProposerRewardsAddressProvider provides a portion of
// auction profits to the block proposer.
type ProposerRewardsAddressProvider struct {
@ -17,16 +19,23 @@ type ProposerRewardsAddressProvider struct {
func NewProposerRewardsAddressProvider(
distrKeeper types.DistributionKeeper,
stakingKeeper types.StakingKeeper,
) types.RewardsAddressProvider {
) *ProposerRewardsAddressProvider {
return &ProposerRewardsAddressProvider{
distrKeeper: distrKeeper,
stakingKeeper: stakingKeeper,
}
}
func (p *ProposerRewardsAddressProvider) GetRewardsAddress(ctx sdk.Context) sdk.AccAddress {
prevPropConsAddr := p.distrKeeper.GetPreviousProposerConsAddr(ctx)
prevProposer := p.stakingKeeper.ValidatorByConsAddr(ctx, prevPropConsAddr)
func (p *ProposerRewardsAddressProvider) GetRewardsAddress(ctx sdk.Context) (sdk.AccAddress, error) {
prevPropConsAddr, err := p.distrKeeper.GetPreviousProposerConsAddr(ctx)
if err != nil {
return nil, err
}
return sdk.AccAddress(prevProposer.GetOperator())
prevProposer, err := p.stakingKeeper.GetValidatorByConsAddr(ctx, prevPropConsAddr)
if err != nil {
return nil, err
}
return sdk.AccAddress(prevProposer.GetOperator()), nil
}

View File

@ -7,27 +7,17 @@ import (
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)
ModuleCdc = codec.NewLegacyAmino()
)
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

View File

@ -1,6 +1,8 @@
package types
import (
context "context"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
@ -12,22 +14,22 @@ type AccountKeeper interface {
// 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
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
SendCoins(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error
GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin
}
// DistributionKeeper defines the expected API contract for the x/distribution
// module.
type DistributionKeeper interface {
GetPreviousProposerConsAddr(ctx sdk.Context) sdk.ConsAddress
GetPreviousProposerConsAddr(ctx context.Context) (sdk.ConsAddress, error)
}
// StakingKeeper defines the expected API contract for the x/staking module.
type StakingKeeper interface {
ValidatorByConsAddr(sdk.Context, sdk.ConsAddress) stakingtypes.ValidatorI
GetValidatorByConsAddr(context.Context, sdk.ConsAddress) (stakingtypes.Validator, error)
}
// RewardsAddressProvider is an interface that provides an address where auction profits are sent.
// RewardsAddressProvider is an interface that provides an address where proposer/subset of auction profits are sent.
type RewardsAddressProvider interface {
GetRewardsAddress(context sdk.Context) sdk.AccAddress
GetRewardsAddress(context sdk.Context) (sdk.AccAddress, error)
}

View File

@ -4,8 +4,9 @@
package types
import (
cosmossdk_io_math "cosmossdk.io/math"
fmt "fmt"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/cosmos-proto"
types "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/cosmos-sdk/types/tx/amino"
_ "github.com/cosmos/gogoproto/gogoproto"
@ -89,7 +90,7 @@ type Params struct {
FrontRunningProtection bool `protobuf:"varint,5,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,6,opt,name=proposer_fee,json=proposerFee,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"proposer_fee"`
ProposerFee cosmossdk_io_math.LegacyDec `protobuf:"bytes,6,opt,name=proposer_fee,json=proposerFee,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"proposer_fee"`
}
func (m *Params) Reset() { *m = Params{} }
@ -168,37 +169,39 @@ func init() {
func init() { proto.RegisterFile("pob/builder/v1/genesis.proto", fileDescriptor_287f1bdff5ccfc33) }
var fileDescriptor_287f1bdff5ccfc33 = []byte{
// 474 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xc1, 0x6e, 0xd4, 0x3c,
0x14, 0x85, 0x27, 0x7f, 0xfb, 0x8f, 0xa8, 0x67, 0x4a, 0xd5, 0xa8, 0x1a, 0x85, 0x82, 0xd2, 0xa8,
0x8b, 0x32, 0xaa, 0x54, 0x5b, 0x03, 0x2c, 0x10, 0xbb, 0x09, 0xa5, 0x88, 0xdd, 0x90, 0xee, 0xd8,
0x44, 0x4e, 0x72, 0x1b, 0xac, 0xd6, 0x76, 0x64, 0x3b, 0x61, 0xe8, 0x23, 0xb0, 0xe2, 0x31, 0x58,
0xa1, 0x3e, 0x46, 0x97, 0x5d, 0x22, 0x16, 0x15, 0x9a, 0x59, 0xf4, 0x35, 0x50, 0xec, 0xb4, 0x94,
0x25, 0x9b, 0x24, 0xf2, 0x77, 0x7d, 0xce, 0x3d, 0xb9, 0x17, 0x3d, 0xa9, 0x64, 0x46, 0xb2, 0x9a,
0x9d, 0x15, 0xa0, 0x48, 0x33, 0x21, 0x25, 0x08, 0xd0, 0x4c, 0xe3, 0x4a, 0x49, 0x23, 0xfd, 0x87,
0x95, 0xcc, 0x70, 0x47, 0x71, 0x33, 0xd9, 0xde, 0x2a, 0x65, 0x29, 0x2d, 0x22, 0xed, 0x97, 0xab,
0xda, 0x0e, 0x73, 0xa9, 0xb9, 0xd4, 0x24, 0xa3, 0x1a, 0x48, 0x33, 0xc9, 0xc0, 0xd0, 0x09, 0xc9,
0x25, 0x13, 0x1d, 0xdf, 0xa4, 0x9c, 0x09, 0x49, 0xec, 0xd3, 0x1d, 0xed, 0x1e, 0xa2, 0xe1, 0x5b,
0xe7, 0x74, 0x6c, 0xa8, 0x01, 0xff, 0x05, 0xea, 0x57, 0x54, 0x51, 0xae, 0x03, 0x2f, 0xf2, 0xc6,
0x83, 0x67, 0x23, 0xfc, 0xb7, 0x33, 0x9e, 0x59, 0x1a, 0xaf, 0x5e, 0x5e, 0xef, 0xf4, 0x92, 0xae,
0x76, 0xf7, 0xfb, 0x0a, 0xea, 0x3b, 0xe0, 0xef, 0xa1, 0x0d, 0x4e, 0xe7, 0x69, 0x56, 0x8b, 0xe2,
0x0c, 0x52, 0xcd, 0xce, 0xc1, 0x2a, 0xad, 0x27, 0xeb, 0x9c, 0xce, 0x63, 0x7b, 0x7a, 0xcc, 0xce,
0x5b, 0xa3, 0x11, 0xe8, 0x5c, 0xc9, 0x4f, 0x29, 0xcd, 0x73, 0x59, 0x0b, 0x93, 0xd2, 0xa2, 0x50,
0xa0, 0x75, 0xf0, 0x5f, 0xe4, 0x8d, 0x87, 0xc9, 0x96, 0xa3, 0x53, 0x07, 0xa7, 0x8e, 0xf9, 0x6f,
0xd0, 0x40, 0x81, 0x06, 0xd5, 0x40, 0x7a, 0x02, 0x10, 0xac, 0xd8, 0x1e, 0x1f, 0x61, 0x97, 0x1b,
0xb7, 0xb9, 0x71, 0x97, 0x1b, 0xbf, 0x96, 0x4c, 0xc4, 0x6b, 0x6d, 0x9b, 0xdf, 0x6e, 0x2e, 0xf6,
0xbd, 0x04, 0x75, 0x17, 0x8f, 0x00, 0xfc, 0x19, 0xda, 0xe4, 0x4c, 0xa4, 0x19, 0x2b, 0x52, 0x26,
0x72, 0x05, 0x1c, 0x84, 0x09, 0x56, 0xff, 0x41, 0x6c, 0x83, 0x33, 0x11, 0xb3, 0xe2, 0xdd, 0xed,
0x65, 0xff, 0x25, 0x0a, 0x4e, 0x94, 0x14, 0x26, 0x55, 0xb5, 0x10, 0x4c, 0x94, 0x69, 0xfb, 0x7b,
0x21, 0x37, 0x4c, 0x8a, 0xe0, 0xff, 0xc8, 0x1b, 0x3f, 0x48, 0x46, 0x96, 0x27, 0x0e, 0xcf, 0xee,
0xa8, 0xff, 0x1e, 0x0d, 0x2b, 0x25, 0x2b, 0xa9, 0x41, 0xd9, 0x4c, 0xfd, 0xc8, 0x1b, 0xaf, 0xc5,
0xb8, 0xf5, 0xfa, 0x79, 0xbd, 0xb3, 0x57, 0x32, 0xf3, 0xb1, 0xce, 0x70, 0x2e, 0x39, 0xe9, 0xa6,
0xeb, 0x5e, 0x07, 0xba, 0x38, 0x25, 0xe6, 0x73, 0x05, 0x1a, 0x1f, 0x42, 0x9e, 0x0c, 0x6e, 0x35,
0x8e, 0x00, 0x5e, 0x45, 0x5f, 0x6e, 0x2e, 0xf6, 0x1f, 0xdf, 0xab, 0x9b, 0xdf, 0x6d, 0x56, 0x37,
0xbe, 0xe9, 0xe5, 0x22, 0xf4, 0xae, 0x16, 0xa1, 0xf7, 0x6b, 0x11, 0x7a, 0x5f, 0x97, 0x61, 0xef,
0x6a, 0x19, 0xf6, 0x7e, 0x2c, 0xc3, 0xde, 0x87, 0xa7, 0xf7, 0x0c, 0xf5, 0x29, 0xab, 0x0e, 0x38,
0x34, 0xa4, 0xdd, 0xcd, 0x3f, 0x1a, 0xd6, 0x35, 0xeb, 0xdb, 0x05, 0x7a, 0xfe, 0x3b, 0x00, 0x00,
0xff, 0xff, 0x3d, 0xb6, 0x59, 0xc6, 0xb9, 0x02, 0x00, 0x00,
// 499 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0x86, 0x63, 0x5a, 0x22, 0xba, 0x49, 0xa9, 0x6a, 0x55, 0x91, 0x5b, 0x90, 0x1b, 0xf5, 0x00,
0x51, 0xa5, 0xec, 0x2a, 0x80, 0x10, 0xe2, 0x96, 0x10, 0x8a, 0x90, 0x38, 0x44, 0xee, 0x09, 0x2e,
0xd6, 0x7a, 0x3d, 0x75, 0x57, 0xe9, 0xee, 0x5a, 0xbb, 0x1b, 0x93, 0xf6, 0x11, 0x38, 0xf1, 0x18,
0x1c, 0x7b, 0x40, 0x3c, 0x43, 0x8f, 0x15, 0x27, 0xc4, 0xa1, 0x42, 0xc9, 0xa1, 0xaf, 0x81, 0xec,
0x75, 0x8b, 0x38, 0xf6, 0x62, 0xd9, 0xf3, 0xcd, 0xfc, 0xf3, 0xcf, 0x78, 0xd0, 0xe3, 0x5c, 0x25,
0x24, 0x99, 0xf1, 0x93, 0x14, 0x34, 0x29, 0x06, 0x24, 0x03, 0x09, 0x86, 0x1b, 0x9c, 0x6b, 0x65,
0x95, 0xff, 0x30, 0x57, 0x09, 0xae, 0x29, 0x2e, 0x06, 0x3b, 0x5b, 0x99, 0xca, 0x54, 0x85, 0x48,
0xf9, 0xe6, 0xb2, 0x76, 0x42, 0xa6, 0x8c, 0x50, 0x86, 0x24, 0xd4, 0x00, 0x29, 0x06, 0x09, 0x58,
0x3a, 0x20, 0x4c, 0x71, 0x59, 0xf3, 0x4d, 0x2a, 0xb8, 0x54, 0xa4, 0x7a, 0xd6, 0xa1, 0x6d, 0x57,
0x12, 0x3b, 0x2d, 0xf7, 0xe1, 0xd0, 0xde, 0x18, 0xb5, 0xdf, 0x39, 0x13, 0x87, 0x96, 0x5a, 0xf0,
0x5f, 0xa0, 0x66, 0x4e, 0x35, 0x15, 0x26, 0xf0, 0xba, 0x5e, 0xaf, 0xf5, 0xac, 0x83, 0xff, 0x37,
0x85, 0x27, 0x15, 0x1d, 0xad, 0x5e, 0x5c, 0xed, 0x36, 0xa2, 0x3a, 0x77, 0xef, 0xc7, 0x0a, 0x6a,
0x3a, 0xe0, 0x3f, 0x41, 0x1b, 0x82, 0xce, 0xe3, 0x64, 0x26, 0xd3, 0x13, 0x88, 0x0d, 0x3f, 0x83,
0x4a, 0x69, 0x3d, 0x5a, 0x17, 0x74, 0x3e, 0xaa, 0xa2, 0x87, 0xfc, 0xac, 0x6c, 0xd4, 0x01, 0xc3,
0xb4, 0xfa, 0x1c, 0x53, 0xc6, 0xd4, 0x4c, 0xda, 0x98, 0xa6, 0xa9, 0x06, 0x63, 0x82, 0x7b, 0x5d,
0xaf, 0xd7, 0x8e, 0xb6, 0x1c, 0x1d, 0x3a, 0x38, 0x74, 0xcc, 0x7f, 0x8b, 0x5a, 0x1a, 0x0c, 0xe8,
0x02, 0xe2, 0x23, 0x80, 0x60, 0xa5, 0xf2, 0xb8, 0x8d, 0xeb, 0x91, 0xca, 0x95, 0xe0, 0x7a, 0x25,
0xf8, 0x8d, 0xe2, 0x72, 0xb4, 0x56, 0xda, 0xfc, 0x76, 0x7d, 0xbe, 0xef, 0x45, 0xa8, 0x2e, 0x3c,
0x00, 0xf0, 0x27, 0x68, 0x53, 0x70, 0x19, 0x27, 0x3c, 0x8d, 0xb9, 0x64, 0x1a, 0x04, 0x48, 0x1b,
0xac, 0xde, 0x41, 0x6c, 0x43, 0x70, 0x39, 0xe2, 0xe9, 0xfb, 0x9b, 0x62, 0xff, 0x15, 0x0a, 0x8e,
0xb4, 0x92, 0x36, 0xd6, 0x33, 0x29, 0xb9, 0xcc, 0xaa, 0x5d, 0x03, 0xb3, 0x5c, 0xc9, 0xe0, 0x7e,
0xd7, 0xeb, 0x3d, 0x88, 0x3a, 0x15, 0x8f, 0x1c, 0x9e, 0xdc, 0x52, 0xff, 0x23, 0x6a, 0xe7, 0x5a,
0xe5, 0xca, 0x80, 0xae, 0x66, 0x6a, 0x76, 0xbd, 0xde, 0xda, 0xe8, 0x65, 0xd9, 0xeb, 0xf7, 0xd5,
0xee, 0x23, 0xe7, 0xc6, 0xa4, 0x53, 0xcc, 0x15, 0x11, 0xd4, 0x1e, 0xe3, 0x0f, 0x90, 0x51, 0x76,
0x3a, 0x06, 0xf6, 0xf3, 0x7b, 0x1f, 0xd5, 0x66, 0xc7, 0xc0, 0x9c, 0xb1, 0xd6, 0x8d, 0xd6, 0x01,
0xc0, 0xeb, 0xee, 0x97, 0xeb, 0xf3, 0xfd, 0x5a, 0xa1, 0x6f, 0xd2, 0x29, 0x99, 0xdf, 0x1e, 0x5f,
0xfd, 0x1b, 0x87, 0x17, 0x8b, 0xd0, 0xbb, 0x5c, 0x84, 0xde, 0x9f, 0x45, 0xe8, 0x7d, 0x5d, 0x86,
0x8d, 0xcb, 0x65, 0xd8, 0xf8, 0xb5, 0x0c, 0x1b, 0x9f, 0x9e, 0x66, 0xdc, 0x1e, 0xcf, 0x12, 0xcc,
0x94, 0x20, 0x66, 0xca, 0xf3, 0xbe, 0x80, 0x82, 0x94, 0xe7, 0xfb, 0x4f, 0xc3, 0x9e, 0xe6, 0x60,
0x92, 0x66, 0x75, 0x48, 0xcf, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xb6, 0x7e, 0x29, 0xdc,
0x02, 0x00, 0x00,
}
func (m *GenesisState) Marshal() (dAtA []byte, err error) {

View File

@ -3,6 +3,7 @@ package types_test
import (
"testing"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/skip-mev/pob/x/builder/types"
)
@ -36,7 +37,7 @@ func TestMsgAuctionBid(t *testing.T) {
description: "invalid message with empty transactions",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoin("test", sdk.NewInt(100)),
Bid: sdk.NewCoin("test", math.NewInt(100)),
Transactions: [][]byte{},
},
expectPass: false,
@ -45,7 +46,7 @@ func TestMsgAuctionBid(t *testing.T) {
description: "valid message",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoin("test", sdk.NewInt(100)),
Bid: sdk.NewCoin("test", math.NewInt(100)),
Transactions: [][]byte{[]byte("test")},
},
expectPass: true,
@ -54,7 +55,7 @@ func TestMsgAuctionBid(t *testing.T) {
description: "valid message with multiple transactions",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoin("test", sdk.NewInt(100)),
Bid: sdk.NewCoin("test", math.NewInt(100)),
Transactions: [][]byte{[]byte("test"), []byte("test2")},
},
expectPass: true,
@ -63,7 +64,7 @@ func TestMsgAuctionBid(t *testing.T) {
description: "invalid message with empty transaction in transactions",
msg: types.MsgAuctionBid{
Bidder: sdk.AccAddress([]byte("test")).String(),
Bid: sdk.NewCoin("test", sdk.NewInt(100)),
Bid: sdk.NewCoin("test", math.NewInt(100)),
Transactions: [][]byte{[]byte("test"), []byte("")},
},
expectPass: false,
@ -101,15 +102,28 @@ func TestMsgUpdateParams(t *testing.T) {
},
expectPass: false,
},
{
description: "invalid message with invalid params (invalid escrow address)",
msg: types.MsgUpdateParams{
Authority: sdk.AccAddress([]byte("test")).String(),
Params: types.Params{
EscrowAccountAddress: nil,
ReserveFee: sdk.NewCoin("test", math.NewInt(100)),
MinBidIncrement: sdk.NewCoin("test", math.NewInt(100)),
ProposerFee: math.LegacyNewDecFromInt(math.NewInt(1)),
},
},
expectPass: false,
},
{
description: "valid message",
msg: types.MsgUpdateParams{
Authority: sdk.AccAddress([]byte("test")).String(),
Params: types.Params{
ProposerFee: sdk.NewDec(1),
ProposerFee: math.LegacyNewDecFromInt(math.NewInt(1)),
EscrowAccountAddress: sdk.AccAddress([]byte("test")),
ReserveFee: sdk.NewCoin("test", sdk.NewInt(100)),
MinBidIncrement: sdk.NewCoin("test", sdk.NewInt(100)),
ReserveFee: sdk.NewCoin("test", math.NewInt(100)),
MinBidIncrement: sdk.NewCoin("test", math.NewInt(100)),
},
},
expectPass: true,
@ -119,10 +133,10 @@ func TestMsgUpdateParams(t *testing.T) {
msg: types.MsgUpdateParams{
Authority: sdk.AccAddress([]byte("test")).String(),
Params: types.Params{
ProposerFee: sdk.NewDec(1),
ProposerFee: math.LegacyNewDecFromInt(math.NewInt(1)),
EscrowAccountAddress: sdk.AccAddress([]byte("test")),
ReserveFee: sdk.NewCoin("test", sdk.NewInt(100)),
MinBidIncrement: sdk.NewCoin("test2", sdk.NewInt(100)),
ReserveFee: sdk.NewCoin("test", math.NewInt(100)),
MinBidIncrement: sdk.NewCoin("test2", math.NewInt(100)),
},
},
expectPass: false,
@ -132,7 +146,7 @@ func TestMsgUpdateParams(t *testing.T) {
msg: types.MsgUpdateParams{
Authority: sdk.AccAddress([]byte("test")).String(),
Params: types.Params{
ProposerFee: sdk.NewDec(1),
ProposerFee: math.LegacyNewDecFromInt(math.NewInt(1)),
EscrowAccountAddress: sdk.AccAddress([]byte("test")),
},
},
@ -143,10 +157,10 @@ func TestMsgUpdateParams(t *testing.T) {
msg: types.MsgUpdateParams{
Authority: sdk.AccAddress([]byte("test")).String(),
Params: types.Params{
ProposerFee: sdk.NewDec(1),
ProposerFee: math.LegacyNewDecFromInt(math.NewInt(1)),
EscrowAccountAddress: sdk.AccAddress([]byte("test")),
ReserveFee: sdk.NewCoin("test", sdk.NewInt(100)),
MinBidIncrement: sdk.NewCoin("test", sdk.NewInt(0)),
ReserveFee: sdk.NewCoin("test", math.NewInt(100)),
MinBidIncrement: sdk.NewCoin("test", math.NewInt(0)),
},
},
expectPass: false,

View File

@ -11,10 +11,10 @@ import (
var (
DefaultMaxBundleSize uint32 = 2
DefaultEscrowAccountAddress = authtypes.NewModuleAddress(ModuleName)
DefaultReserveFee = sdk.NewCoin("stake", sdk.NewInt(1))
DefaultMinBidIncrement = sdk.NewCoin("stake", sdk.NewInt(1))
DefaultReserveFee = sdk.NewCoin("stake", math.NewInt(1))
DefaultMinBidIncrement = sdk.NewCoin("stake", math.NewInt(1))
DefaultFrontRunningProtection = true
DefaultProposerFee = sdk.ZeroDec()
DefaultProposerFee = math.LegacyNewDec(0)
)
// NewParams returns a new Params instance with the provided values.
@ -23,7 +23,7 @@ func NewParams(
escrowAccountAddress []byte,
reserveFee, minBidIncrement sdk.Coin,
frontRunningProtection bool,
proposerFee sdk.Dec,
proposerFee math.LegacyDec,
) Params {
return Params{
MaxBundleSize: maxBundleSize,
@ -49,15 +49,20 @@ func DefaultParams() Params {
// Validate performs basic validation on the parameters.
func (p Params) Validate() error {
if p.EscrowAccountAddress == nil {
return fmt.Errorf("escrow account address cannot be nil")
}
if err := validateFee(p.ReserveFee); err != nil {
return fmt.Errorf("invalid reserve fee (%s)", err)
}
if err := validateFee(p.MinBidIncrement); err != nil {
return fmt.Errorf("invalid minimum bid increment (%s)", err)
}
// Minimum bid increment must always be greater than 0.
if p.MinBidIncrement.IsLTE(sdk.NewCoin(p.MinBidIncrement.Denom, sdk.ZeroInt())) {
if p.MinBidIncrement.IsLTE(sdk.NewCoin(p.MinBidIncrement.Denom, math.ZeroInt())) {
return fmt.Errorf("minimum bid increment cannot be zero")
}
@ -81,7 +86,7 @@ func validateFee(fee sdk.Coin) error {
return fee.Validate()
}
func validateProposerFee(v sdk.Dec) error {
func validateProposerFee(v math.LegacyDec) error {
if v.IsNil() {
return fmt.Errorf("proposer fee cannot be nil: %s", v)
}