diff --git a/Makefile b/Makefile index aff4055..f293ae6 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/abci/abci_test.go b/abci/abci_test.go index 5805280..395d512 100644 --- a/abci/abci_test.go +++ b/abci/abci_test.go @@ -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++ { diff --git a/abci/auction_test.go b/abci/auction_test.go index e5ad50e..9db0270 100644 --- a/abci/auction_test.go +++ b/abci/auction_test.go @@ -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) diff --git a/abci/proposal_auction.go b/abci/proposal_auction.go index db74a48..f807116 100644 --- a/abci/proposal_auction.go +++ b/abci/proposal_auction.go @@ -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 diff --git a/abci/proposals.go b/abci/proposals.go index 136eeda..88bc09e 100644 --- a/abci/proposals.go +++ b/abci/proposals.go @@ -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 +} diff --git a/abci/proposals_test.go b/abci/proposals_test.go index 7d116bf..8f10d86 100644 --- a/abci/proposals_test.go +++ b/abci/proposals_test.go @@ -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, }) diff --git a/abci/types.go b/abci/types.go index a7097a7..f8137b1 100644 --- a/abci/types.go +++ b/abci/types.go @@ -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 diff --git a/abci/vote_extensions.go b/abci/vote_extensions.go index b8c7c13..273830e 100644 --- a/abci/vote_extensions.go +++ b/abci/vote_extensions.go @@ -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 } } diff --git a/abci/vote_extensions_test.go b/abci/vote_extensions_test.go index 2833df9..0eebe0d 100644 --- a/abci/vote_extensions_test.go +++ b/abci/vote_extensions_test.go @@ -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, } }, diff --git a/blockbuster/abci/abci.go b/blockbuster/abci/abci.go index a9f0624..3ddcc7c 100644 --- a/blockbuster/abci/abci.go +++ b/blockbuster/abci/abci.go @@ -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 } diff --git a/blockbuster/abci/abci_test.go b/blockbuster/abci/abci_test.go index 6c03e90..183cc4f 100644 --- a/blockbuster/abci/abci_test.go +++ b/blockbuster/abci/abci_test.go @@ -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) + } }) } } diff --git a/blockbuster/abci/check_tx.go b/blockbuster/abci/check_tx.go index 1ab4e2e..e9deaf9 100644 --- a/blockbuster/abci/check_tx.go +++ b/blockbuster/abci/check_tx.go @@ -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() diff --git a/blockbuster/lane.go b/blockbuster/lane.go index 820db75..e1c2478 100644 --- a/blockbuster/lane.go +++ b/blockbuster/lane.go @@ -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") } diff --git a/blockbuster/lanes/auction/abci.go b/blockbuster/lanes/auction/abci.go index 45d8d2b..83359f3 100644 --- a/blockbuster/lanes/auction/abci.go +++ b/blockbuster/lanes/auction/abci.go @@ -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. diff --git a/blockbuster/lanes/auction/auction_test.go b/blockbuster/lanes/auction/auction_test.go index afa7277..7e2eec4 100644 --- a/blockbuster/lanes/auction/auction_test.go +++ b/blockbuster/lanes/auction/auction_test.go @@ -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())) diff --git a/blockbuster/lanes/auction/factory.go b/blockbuster/lanes/auction/factory.go index f49f566..37c9738 100644 --- a/blockbuster/lanes/auction/factory.go +++ b/blockbuster/lanes/auction/factory.go @@ -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 } diff --git a/blockbuster/lanes/auction/factory_test.go b/blockbuster/lanes/auction/factory_test.go index dfc5bd0..53c6ec1 100644 --- a/blockbuster/lanes/auction/factory_test.go +++ b/blockbuster/lanes/auction/factory_test.go @@ -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] diff --git a/blockbuster/lanes/auction/utils_test.go b/blockbuster/lanes/auction/utils_test.go index 28b7eba..2db4b74 100644 --- a/blockbuster/lanes/auction/utils_test.go +++ b/blockbuster/lanes/auction/utils_test.go @@ -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{}) diff --git a/blockbuster/lanes/base/abci.go b/blockbuster/lanes/base/abci.go index 825be1e..b38f6e1 100644 --- a/blockbuster/lanes/base/abci.go +++ b/blockbuster/lanes/base/abci.go @@ -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 } diff --git a/blockbuster/lanes/base/lane.go b/blockbuster/lanes/base/lane.go index 1129b31..6624253 100644 --- a/blockbuster/lanes/base/lane.go +++ b/blockbuster/lanes/base/lane.go @@ -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 } diff --git a/blockbuster/lanes/free/lane.go b/blockbuster/lanes/free/lane.go index 09b8991..58db1ce 100644 --- a/blockbuster/lanes/free/lane.go +++ b/blockbuster/lanes/free/lane.go @@ -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, } } diff --git a/blockbuster/lanes/terminator/lane.go b/blockbuster/lanes/terminator/lane.go index 8eae9b4..4174917 100644 --- a/blockbuster/lanes/terminator/lane.go +++ b/blockbuster/lanes/terminator/lane.go @@ -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() } diff --git a/blockbuster/mempool.go b/blockbuster/mempool.go index 969cfc9..6c8b412 100644 --- a/blockbuster/mempool.go +++ b/blockbuster/mempool.go @@ -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") } diff --git a/blockbuster/mempool_test.go b/blockbuster/mempool_test.go index 8df8fcc..d794664 100644 --- a/blockbuster/mempool_test.go +++ b/blockbuster/mempool_test.go @@ -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 diff --git a/blockbuster/proposals.go b/blockbuster/proposals.go index 108e907..4ea94a1 100644 --- a/blockbuster/proposals.go +++ b/blockbuster/proposals.go @@ -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 diff --git a/blockbuster/utils/utils.go b/blockbuster/utils/utils.go index 938b840..6edf364 100644 --- a/blockbuster/utils/utils.go +++ b/blockbuster/utils/utils.go @@ -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 diff --git a/blockbuster/utils/utils_test.go b/blockbuster/utils/utils_test.go index f38e1e5..e0b47e3 100644 --- a/blockbuster/utils/utils_test.go +++ b/blockbuster/utils/utils_test.go @@ -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, }, } diff --git a/codec/codec.go b/codec/codec.go deleted file mode 100644 index 5bea048..0000000 --- a/codec/codec.go +++ /dev/null @@ -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, - } -} diff --git a/go.mod b/go.mod index b7ef99e..8e68dcd 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index fa38fa6..e75397d 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/proto/pob/builder/v1/genesis.proto b/proto/pob/builder/v1/genesis.proto index d141795..0909c23 100644 --- a/proto/pob/builder/v1/genesis.proto +++ b/proto/pob/builder/v1/genesis.proto @@ -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 ]; } diff --git a/tests/app/app.go b/tests/app/app.go index 5560479..ab94df1 100644 --- a/tests/app/app.go +++ b/tests/app/app.go @@ -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. diff --git a/tests/app/config.go b/tests/app/config.go index e34db9c..8d181fa 100644 --- a/tests/app/config.go +++ b/tests/app/config.go @@ -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, + }, + ), + }, + )) ) diff --git a/tests/app/export.go b/tests/app/export.go index 7cb309f..13f8b96 100644 --- a/tests/app/export.go +++ b/tests/app/export.go @@ -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) } diff --git a/tests/app/helpers.go b/tests/app/helpers.go new file mode 100644 index 0000000..4681a9c --- /dev/null +++ b/tests/app/helpers.go @@ -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(), + }, + } +} diff --git a/tests/app/testappd/cmd/root.go b/tests/app/testappd/cmd/root.go index a6950a4..5c6de93 100644 --- a/tests/app/testappd/cmd/root.go +++ b/tests/app/testappd/cmd/root.go @@ -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) } diff --git a/tests/app/testappd/cmd/testnet.go b/tests/app/testappd/cmd/testnet.go new file mode 100644 index 0000000..2ca9f82 --- /dev/null +++ b/tests/app/testappd/cmd/testnet.go @@ -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 +} diff --git a/tests/app/testappd/main.go b/tests/app/testappd/main.go index f1cce95..c644f01 100644 --- a/tests/app/testappd/main.go +++ b/tests/app/testappd/main.go @@ -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) } } diff --git a/tests/e2e/chain.go b/tests/e2e/chain.go index 365e228..0ac39a5 100644 --- a/tests/e2e/chain.go +++ b/tests/e2e/chain.go @@ -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 } diff --git a/tests/e2e/e2e_setup_test.go b/tests/e2e/e2e_setup_test.go index 3c54ba7..79159f6 100644 --- a/tests/e2e/e2e_setup_test.go +++ b/tests/e2e/e2e_setup_test.go @@ -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 diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index bce49ef..c819832 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -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) diff --git a/tests/e2e/e2e_tx_test.go b/tests/e2e/e2e_tx_test.go index 069351e..8bcb475 100644 --- a/tests/e2e/e2e_tx_test.go +++ b/tests/e2e/e2e_tx_test.go @@ -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 diff --git a/tests/e2e/e2e_utils_test.go b/tests/e2e/e2e_utils_test.go index 10afcb2..f0a627c 100644 --- a/tests/e2e/e2e_utils_test.go +++ b/tests/e2e/e2e_utils_test.go @@ -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. diff --git a/tests/e2e/validator.go b/tests/e2e/validator.go index cc822ff..00e5e7e 100644 --- a/tests/e2e/validator.go +++ b/tests/e2e/validator.go @@ -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, diff --git a/testutils/mocks.go b/testutils/mocks.go index ee59ca9..515fd40 100644 --- a/testutils/mocks.go +++ b/testutils/mocks.go @@ -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) } diff --git a/testutils/utils.go b/testutils/utils.go index 818f1c6..2a77768 100644 --- a/testutils/utils.go +++ b/testutils/utils.go @@ -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), diff --git a/x/builder/ante/ante.go b/x/builder/ante/ante.go index c9c0def..3d587a0 100644 --- a/x/builder/ante/ante.go +++ b/x/builder/ante/ante.go @@ -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 diff --git a/x/builder/ante/ante_test.go b/x/builder/ante/ante_test.go index 3bccccd..01ed63c 100644 --- a/x/builder/ante/ante_test.go +++ b/x/builder/ante/ante_test.go @@ -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 diff --git a/x/builder/keeper/auction_test.go b/x/builder/keeper/auction_test.go index 90161bc..7779f85 100644 --- a/x/builder/keeper/auction_test.go +++ b/x/builder/keeper/auction_test.go @@ -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, }, diff --git a/x/builder/keeper/keeper.go b/x/builder/keeper/keeper.go index a43c4bf..f175f72 100644 --- a/x/builder/keeper/keeper.go +++ b/x/builder/keeper/keeper.go @@ -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 diff --git a/x/builder/keeper/keeper_test.go b/x/builder/keeper/keeper_test.go index a8d07e9..bd09d89 100644 --- a/x/builder/keeper/keeper_test.go +++ b/x/builder/keeper/keeper_test.go @@ -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" diff --git a/x/builder/keeper/msg_server.go b/x/builder/keeper/msg_server.go index aa97a20..742e61e 100644 --- a/x/builder/keeper/msg_server.go +++ b/x/builder/keeper/msg_server.go @@ -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) diff --git a/x/builder/keeper/msg_server_test.go b/x/builder/keeper/msg_server_test.go index 9d6ba7a..6b2a0ac 100644 --- a/x/builder/keeper/msg_server_test.go +++ b/x/builder/keeper/msg_server_test.go @@ -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, diff --git a/x/builder/module.go b/x/builder/module.go index c7b9e02..4308e8f 100644 --- a/x/builder/module.go +++ b/x/builder/module.go @@ -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" diff --git a/x/builder/rewards/fixed_provider.go b/x/builder/rewards/fixed_provider.go index 83e0c6a..45fc5eb 100644 --- a/x/builder/rewards/fixed_provider.go +++ b/x/builder/rewards/fixed_provider.go @@ -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 } diff --git a/x/builder/rewards/proposer_provider.go b/x/builder/rewards/proposer_provider.go index 4b004e5..a1094b5 100644 --- a/x/builder/rewards/proposer_provider.go +++ b/x/builder/rewards/proposer_provider.go @@ -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 } diff --git a/x/builder/types/codec.go b/x/builder/types/codec.go index fe9f750..892d089 100644 --- a/x/builder/types/codec.go +++ b/x/builder/types/codec.go @@ -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 diff --git a/x/builder/types/expected_keepers.go b/x/builder/types/expected_keepers.go index 229dffb..9001f90 100644 --- a/x/builder/types/expected_keepers.go +++ b/x/builder/types/expected_keepers.go @@ -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) } diff --git a/x/builder/types/genesis.pb.go b/x/builder/types/genesis.pb.go index 72e0aad..44a0774 100644 --- a/x/builder/types/genesis.pb.go +++ b/x/builder/types/genesis.pb.go @@ -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) { diff --git a/x/builder/types/msgs_test.go b/x/builder/types/msgs_test.go index efd33d1..09ea34d 100644 --- a/x/builder/types/msgs_test.go +++ b/x/builder/types/msgs_test.go @@ -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, diff --git a/x/builder/types/params.go b/x/builder/types/params.go index 4c0d0bc..db8cb1a 100644 --- a/x/builder/types/params.go +++ b/x/builder/types/params.go @@ -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) }