diff --git a/CHANGELOG.md b/CHANGELOG.md index aa6a4ec21052..b279fd1d6444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [#16547](https://github.com/cosmos/cosmos-sdk/pull/16547) Ensure a transaction's gas limit cannot exceed the block gas limit. * (x/auth/types) [#16554](https://github.com/cosmos/cosmos-sdk/pull/16554) `ModuleAccount.Validate` now reports a nil `.BaseAccount` instead of panicking. * (baseapp) [#16613](https://github.com/cosmos/cosmos-sdk/pull/16613) Ensure each message in a transaction has a registered handler, otherwise `CheckTx` will fail. +* (baseapp) [#16596](https://github.com/cosmos/cosmos-sdk/pull/16596) Return error during ExtendVote and VerifyVoteExtension if the request height is earlier than `VoteExtensionsEnableHeight`. * (x/consensus) [#16713](https://github.com/cosmos/cosmos-sdk/pull/16713) Add missing ABCI param in MsgUpdateParams. * [#16639](https://github.com/cosmos/cosmos-sdk/pull/16639) Make sure we don't execute blocks beyond the halt height. * (baseapp) [#16700](https://github.com/cosmos/cosmos-sdk/pull/16700) Fix: Consensus Failure in returning no response to malformed transactions diff --git a/UPGRADING.md b/UPGRADING.md index 29244312c368..a7a9c87a1922 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -29,6 +29,21 @@ Additionally, the SDK is starting its abstraction from CometBFT Go types thoroug * The usage of CometBFT have been replaced to use the Cosmos SDK logger interface (`cosmossdk.io/log.Logger`). * The usage of `github.com/cometbft/cometbft/libs/bytes.HexByte` have been replaced by `[]byte`. +#### Enable Vote Extensions + +:::tip This is an optional feature that is disabled by default. + +Once all the code changes required to implement Vote Extensions are in place, +they can be enabled by setting the consensus param `Abci.VoteExtensionsEnableHeight` +to a value greater than zero. + +In a new chain, this can be done in the `genesis.json` file. + +For existing chains this can be done in two ways: + +- During an upgrade the value is set in an upgrade handler. +- A governance proposal that changes the consensus param **after a coordinated upgrade has taken place**. + ### BaseApp All ABCI methods now accept a pointer to the request and response types defined diff --git a/baseapp/abci.go b/baseapp/abci.go index c977f03ed8b6..3ef7fa77c090 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -556,7 +556,9 @@ func (app *BaseApp) ExtendVote(_ context.Context, req *abci.RequestExtendVote) ( // If vote extensions are not enabled, as a safety precaution, we return an // error. cp := app.GetConsensusParams(app.voteExtensionState.ctx) - if cp.Abci != nil && cp.Abci.VoteExtensionsEnableHeight <= 0 { + + extsEnabled := cp.Abci != nil && req.Height >= cp.Abci.VoteExtensionsEnableHeight && cp.Abci.VoteExtensionsEnableHeight != 0 + if !extsEnabled { return nil, fmt.Errorf("vote extensions are not enabled; unexpected call to ExtendVote at height %d", req.Height) } @@ -569,6 +571,7 @@ func (app *BaseApp) ExtendVote(_ context.Context, req *abci.RequestExtendVote) ( WithHeaderInfo(coreheader.Info{ ChainID: app.chainID, Height: req.Height, + Hash: req.Hash, }) // add a deferred recover handler in case extendVote panics @@ -607,7 +610,9 @@ func (app *BaseApp) VerifyVoteExtension(req *abci.RequestVerifyVoteExtension) (r // If vote extensions are not enabled, as a safety precaution, we return an // error. cp := app.GetConsensusParams(app.voteExtensionState.ctx) - if cp.Abci != nil && cp.Abci.VoteExtensionsEnableHeight <= 0 { + + extsEnabled := cp.Abci != nil && req.Height >= cp.Abci.VoteExtensionsEnableHeight && cp.Abci.VoteExtensionsEnableHeight != 0 + if !extsEnabled { return nil, fmt.Errorf("vote extensions are not enabled; unexpected call to VerifyVoteExtension at height %d", req.Height) } diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 3791b57336d3..5487f5c371d6 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -3,6 +3,7 @@ package baseapp_test import ( "bytes" "context" + "encoding/hex" "errors" "fmt" "strconv" @@ -11,13 +12,19 @@ import ( "time" abci "github.com/cometbft/cometbft/abci/types" + "github.com/cometbft/cometbft/crypto/secp256k1" + cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" dbm "github.com/cosmos/cosmos-db" + protoio "github.com/cosmos/gogoproto/io" "github.com/cosmos/gogoproto/jsonpb" + "github.com/cosmos/gogoproto/proto" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" + "cosmossdk.io/math" pruningtypes "cosmossdk.io/store/pruning/types" "cosmossdk.io/store/snapshots" snapshottypes "cosmossdk.io/store/snapshots/types" @@ -25,6 +32,7 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" baseapptestutil "github.com/cosmos/cosmos-sdk/baseapp/testutil" + "github.com/cosmos/cosmos-sdk/baseapp/testutil/mock" "github.com/cosmos/cosmos-sdk/testutil" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -51,12 +59,14 @@ func TestABCI_First_block_Height(t *testing.T) { suite := NewBaseAppSuite(t, baseapp.SetChainID("test-chain-id")) app := suite.baseApp - app.InitChain(&abci.RequestInitChain{ + _, err := app.InitChain(&abci.RequestInitChain{ ChainId: "test-chain-id", ConsensusParams: &cmtproto.ConsensusParams{Block: &cmtproto.BlockParams{MaxGas: 5000000}}, InitialHeight: 1, }) - app.Commit() + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) ctx := app.GetContextForCheckTx(nil) require.Equal(t, int64(1), ctx.BlockHeight()) @@ -85,8 +95,8 @@ func TestABCI_InitChain(t *testing.T) { Data: key, } + // initChain is nil and chain ID is wrong - errors _, err := app.InitChain(&abci.RequestInitChain{ChainId: "wrong-chain-id"}) - // initChain is nil and chain ID is wrong - panics require.Error(t, err) // initChain is nil - nothing happens @@ -110,9 +120,12 @@ func TestABCI_InitChain(t *testing.T) { // The AppHash returned by a new chain is the sha256 hash of "". // $ echo -n '' | sha256sum // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + apphash, err := hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") + require.NoError(t, err) + require.Equal( t, - []byte{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}, + apphash, initChainRes.AppHash, ) @@ -123,12 +136,15 @@ func TestABCI_InitChain(t *testing.T) { chainID = getCheckStateCtx(app).ChainID() require.Equal(t, "test-chain-id", chainID, "ChainID in checkState not set correctly in InitChain") - app.FinalizeBlock(&abci.RequestFinalizeBlock{ + _, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{ Hash: initChainRes.AppHash, Height: 1, }) + require.NoError(t, err) + + _, err = app.Commit() + require.NoError(t, err) - app.Commit() resQ, err = app.Query(context.TODO(), &query) require.NoError(t, err) require.Equal(t, int64(1), app.LastBlockHeight()) @@ -148,8 +164,10 @@ func TestABCI_InitChain(t *testing.T) { require.Equal(t, value, resQ.Value) // commit and ensure we can still query - app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1}) - app.Commit() + _, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: app.LastBlockHeight() + 1}) + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) resQ, err = app.Query(context.TODO(), &query) require.NoError(t, err) @@ -161,12 +179,14 @@ func TestABCI_InitChain_WithInitialHeight(t *testing.T) { db := dbm.NewMemDB() app := baseapp.NewBaseApp(name, log.NewTestLogger(t), db, nil) - app.InitChain( + _, err := app.InitChain( &abci.RequestInitChain{ InitialHeight: 3, }, ) - app.Commit() + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) require.Equal(t, int64(3), app.LastBlockHeight()) } @@ -176,21 +196,172 @@ func TestABCI_FinalizeBlock_WithInitialHeight(t *testing.T) { db := dbm.NewMemDB() app := baseapp.NewBaseApp(name, log.NewTestLogger(t), db, nil) - app.InitChain( + _, err := app.InitChain( &abci.RequestInitChain{ InitialHeight: 3, }, ) + require.NoError(t, err) - _, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 4}) + _, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 4}) require.Error(t, err, "invalid height: 4; expected: 3") - app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 3}) - app.Commit() + _, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 3}) + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) require.Equal(t, int64(3), app.LastBlockHeight()) } +func TestABCI_FinalizeBlock_WithBeginAndEndBlocker(t *testing.T) { + name := t.Name() + db := dbm.NewMemDB() + app := baseapp.NewBaseApp(name, log.NewTestLogger(t), db, nil) + + app.SetBeginBlocker(func(ctx sdk.Context) (sdk.BeginBlock, error) { + return sdk.BeginBlock{ + Events: []abci.Event{ + { + Type: "sometype", + Attributes: []abci.EventAttribute{ + { + Key: "foo", + Value: "bar", + }, + }, + }, + }, + }, nil + }) + + app.SetEndBlocker(func(ctx sdk.Context) (sdk.EndBlock, error) { + return sdk.EndBlock{ + Events: []abci.Event{ + { + Type: "anothertype", + Attributes: []abci.EventAttribute{ + { + Key: "foo", + Value: "bar", + }, + }, + }, + }, + }, nil + }) + + _, err := app.InitChain( + &abci.RequestInitChain{ + InitialHeight: 1, + }, + ) + require.NoError(t, err) + + res, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) + require.NoError(t, err) + + require.Len(t, res.Events, 2) + + require.Equal(t, "sometype", res.Events[0].Type) + require.Equal(t, "foo", res.Events[0].Attributes[0].Key) + require.Equal(t, "bar", res.Events[0].Attributes[0].Value) + require.Equal(t, "mode", res.Events[0].Attributes[1].Key) + require.Equal(t, "BeginBlock", res.Events[0].Attributes[1].Value) + + require.Equal(t, "anothertype", res.Events[1].Type) + require.Equal(t, "foo", res.Events[1].Attributes[0].Key) + require.Equal(t, "bar", res.Events[1].Attributes[0].Value) + require.Equal(t, "mode", res.Events[1].Attributes[1].Key) + require.Equal(t, "EndBlock", res.Events[1].Attributes[1].Value) + + _, err = app.Commit() + require.NoError(t, err) + + require.Equal(t, int64(1), app.LastBlockHeight()) +} + +func TestABCI_ExtendVote(t *testing.T) { + name := t.Name() + db := dbm.NewMemDB() + app := baseapp.NewBaseApp(name, log.NewTestLogger(t), db, nil) + + app.SetExtendVoteHandler(func(ctx sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + voteExt := "foo" + hex.EncodeToString(req.Hash) + strconv.FormatInt(req.Height, 10) + return &abci.ResponseExtendVote{VoteExtension: []byte(voteExt)}, nil + }) + + app.SetVerifyVoteExtensionHandler(func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + // do some kind of verification here + expectedVoteExt := "foo" + hex.EncodeToString(req.Hash) + strconv.FormatInt(req.Height, 10) + if !bytes.Equal(req.VoteExtension, []byte(expectedVoteExt)) { + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil + } + + return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil + }) + + app.SetParamStore(¶mStore{db: dbm.NewMemDB()}) + _, err := app.InitChain( + &abci.RequestInitChain{ + InitialHeight: 1, + ConsensusParams: &cmtproto.ConsensusParams{ + Abci: &cmtproto.ABCIParams{ + VoteExtensionsEnableHeight: 200, + }, + }, + }, + ) + require.NoError(t, err) + + // Votes not enabled yet + _, err = app.ExtendVote(context.Background(), &abci.RequestExtendVote{Height: 123, Hash: []byte("thehash")}) + require.ErrorContains(t, err, "vote extensions are not enabled") + + // First vote on the first enabled height + res, err := app.ExtendVote(context.Background(), &abci.RequestExtendVote{Height: 200, Hash: []byte("thehash")}) + require.NoError(t, err) + require.Len(t, res.VoteExtension, 20) + + res, err = app.ExtendVote(context.Background(), &abci.RequestExtendVote{Height: 1000, Hash: []byte("thehash")}) + require.NoError(t, err) + require.Len(t, res.VoteExtension, 21) + + // Error during vote extension should return an empty vote extension and no error + app.SetExtendVoteHandler(func(ctx sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { + return nil, errors.New("some error") + }) + res, err = app.ExtendVote(context.Background(), &abci.RequestExtendVote{Height: 1000, Hash: []byte("thehash")}) + require.NoError(t, err) + require.Len(t, res.VoteExtension, 0) + + // Verify Vote Extensions + _, err = app.VerifyVoteExtension(&abci.RequestVerifyVoteExtension{Height: 123, VoteExtension: []byte("1234567")}) + require.ErrorContains(t, err, "vote extensions are not enabled") + + // First vote on the first enabled height + vres, err := app.VerifyVoteExtension(&abci.RequestVerifyVoteExtension{Height: 200, Hash: []byte("thehash"), VoteExtension: []byte("foo74686568617368200")}) + require.NoError(t, err) + require.Equal(t, abci.ResponseVerifyVoteExtension_ACCEPT, vres.Status) + + vres, err = app.VerifyVoteExtension(&abci.RequestVerifyVoteExtension{Height: 1000, Hash: []byte("thehash"), VoteExtension: []byte("foo746865686173681000")}) + require.NoError(t, err) + require.Equal(t, abci.ResponseVerifyVoteExtension_ACCEPT, vres.Status) + + // Reject because it's just some random bytes + vres, err = app.VerifyVoteExtension(&abci.RequestVerifyVoteExtension{Height: 201, Hash: []byte("thehash"), VoteExtension: []byte("12345678")}) + require.NoError(t, err) + require.Equal(t, abci.ResponseVerifyVoteExtension_REJECT, vres.Status) + + // Reject because the verification failed (no error) + app.SetVerifyVoteExtensionHandler(func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) { + return nil, errors.New("some error") + }) + vres, err = app.VerifyVoteExtension(&abci.RequestVerifyVoteExtension{Height: 201, Hash: []byte("thehash"), VoteExtension: []byte("12345678")}) + require.NoError(t, err) + require.Equal(t, abci.ResponseVerifyVoteExtension_REJECT, vres.Status) +} + func TestABCI_GRPCQuery(t *testing.T) { grpcQueryOpt := func(bapp *baseapp.BaseApp) { testdata.RegisterQueryServer( @@ -201,9 +372,10 @@ func TestABCI_GRPCQuery(t *testing.T) { suite := NewBaseAppSuite(t, grpcQueryOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) req := testdata.SayHelloRequest{Name: "foo"} reqBz, err := req.Marshal() @@ -217,8 +389,10 @@ func TestABCI_GRPCQuery(t *testing.T) { require.Equal(t, sdkerrors.ErrInvalidHeight.ABCICode(), resQuery.Code, resQuery) require.Contains(t, resQuery.Log, "TestABCI_GRPCQuery is not ready; please wait for first block") - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: suite.baseApp.LastBlockHeight() + 1}) - suite.baseApp.Commit() + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: suite.baseApp.LastBlockHeight() + 1}) + require.NoError(t, err) + _, err = suite.baseApp.Commit() + require.NoError(t, err) reqQuery := abci.RequestQuery{ Data: reqBz, @@ -279,9 +453,10 @@ func TestBaseApp_PrepareCheckState(t *testing.T) { app := baseapp.NewBaseApp(name, logger, db, nil) app.SetParamStore(¶mStore{db: dbm.NewMemDB()}) - app.InitChain(&abci.RequestInitChain{ + _, err := app.InitChain(&abci.RequestInitChain{ ConsensusParams: cp, }) + require.NoError(t, err) wasPrepareCheckStateCalled := false app.SetPrepareCheckStater(func(ctx sdk.Context) { @@ -289,7 +464,8 @@ func TestBaseApp_PrepareCheckState(t *testing.T) { }) app.Seal() - app.Commit() + _, err = app.Commit() + require.NoError(t, err) require.Equal(t, true, wasPrepareCheckStateCalled) } @@ -306,9 +482,10 @@ func TestBaseApp_Precommit(t *testing.T) { app := baseapp.NewBaseApp(name, logger, db, nil) app.SetParamStore(¶mStore{db: dbm.NewMemDB()}) - app.InitChain(&abci.RequestInitChain{ + _, err := app.InitChain(&abci.RequestInitChain{ ConsensusParams: cp, }) + require.NoError(t, err) wasPrecommiterCalled := false app.SetPrecommiter(func(ctx sdk.Context) { @@ -316,7 +493,8 @@ func TestBaseApp_Precommit(t *testing.T) { }) app.Seal() - app.Commit() + _, err = app.Commit() + require.NoError(t, err) require.Equal(t, true, wasPrecommiterCalled) } @@ -331,9 +509,10 @@ func TestABCI_CheckTx(t *testing.T) { baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImpl{t, capKey1, counterKey}) nTxs := int64(5) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) for i := int64(0); i < nTxs; i++ { tx := newTxCounter(t, suite.txConfig, i, 0) // no messages @@ -353,7 +532,7 @@ func TestABCI_CheckTx(t *testing.T) { require.Equal(t, nTxs, storedCounter) // if a block is committed, CheckTx state should be reset - _, err := suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ Height: 1, Hash: []byte("hash"), }) @@ -362,7 +541,8 @@ func TestABCI_CheckTx(t *testing.T) { require.NotNil(t, getCheckStateCtx(suite.baseApp).BlockGasMeter(), "block gas meter should have been set to checkState") require.NotEmpty(t, getCheckStateCtx(suite.baseApp).HeaderHash()) - suite.baseApp.Commit() + _, err = suite.baseApp.Commit() + require.NoError(t, err) checkStateStore = getCheckStateCtx(suite.baseApp).KVStore(capKey1) storedBytes := checkStateStore.Get(counterKey) @@ -374,9 +554,10 @@ func TestABCI_FinalizeBlock_DeliverTx(t *testing.T) { anteOpt := func(bapp *baseapp.BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) } suite := NewBaseAppSuite(t, anteOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) deliverKey := []byte("deliver-key") baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImpl{t, capKey1, deliverKey}) @@ -413,7 +594,8 @@ func TestABCI_FinalizeBlock_DeliverTx(t *testing.T) { require.Equal(t, sdk.MarkEventsToIndex(counterEvent(sdk.EventTypeMessage, counter).ToABCIEvents(), map[string]struct{}{})[0].Attributes[0], events[2].Attributes[0], "msg handler update counter event") } - suite.baseApp.Commit() + _, err = suite.baseApp.Commit() + require.NoError(t, err) } } @@ -422,9 +604,10 @@ func TestABCI_FinalizeBlock_MultiMsg(t *testing.T) { anteOpt := func(bapp *baseapp.BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) } suite := NewBaseAppSuite(t, anteOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) deliverKey := []byte("deliver-key") baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImpl{t, capKey1, deliverKey}) @@ -438,10 +621,11 @@ func TestABCI_FinalizeBlock_MultiMsg(t *testing.T) { txBytes, err := suite.txConfig.TxEncoder()(tx) require.NoError(t, err) - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ Height: 1, Txs: [][]byte{txBytes}, }) + require.NoError(t, err) store := getFinalizeBlockStateCtx(suite.baseApp).KVStore(capKey1) @@ -500,9 +684,10 @@ func TestABCI_Query_SimulateTx(t *testing.T) { } suite := NewBaseAppSuite(t, anteOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImplGasMeterOnly{gasConsumed}) @@ -544,8 +729,10 @@ func TestABCI_Query_SimulateTx(t *testing.T) { require.Equal(t, result.Events, simRes.Result.Events) require.True(t, bytes.Equal(result.Data, simRes.Result.Data)) - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: count}) - suite.baseApp.Commit() + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: count}) + require.NoError(t, err) + _, err = suite.baseApp.Commit() + require.NoError(t, err) } } @@ -559,13 +746,15 @@ func TestABCI_InvalidTransaction(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImplGasMeterOnly{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ Height: 1, }) + require.NoError(t, err) // malformed transaction bytes { @@ -703,15 +892,18 @@ func TestABCI_TxGasLimits(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImplGasMeterOnly{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ Height: 1, }) + require.NoError(t, err) - suite.baseApp.Commit() + _, err = suite.baseApp.Commit() + require.NoError(t, err) testCases := []struct { tx signing.Tx @@ -792,15 +984,17 @@ func TestABCI_MaxBlockGasLimits(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImplGasMeterOnly{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{ Block: &cmtproto.BlockParams{ MaxGas: 100, }, }, }) + require.NoError(t, err) - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) + require.NoError(t, err) testCases := []struct { tx signing.Tx @@ -825,7 +1019,8 @@ func TestABCI_MaxBlockGasLimits(t *testing.T) { tx := tc.tx // reset block gas - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: suite.baseApp.LastBlockHeight() + 1}) + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: suite.baseApp.LastBlockHeight() + 1}) + require.NoError(t, err) // execute the transaction multiple times for j := 0; j < tc.numDelivers; j++ { @@ -890,13 +1085,14 @@ func TestABCI_GasConsumptionBadTx(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImplGasMeterOnly{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{ Block: &cmtproto.BlockParams{ MaxGas: 9, }, }, }) + require.NoError(t, err) tx := newTxCounter(t, suite.txConfig, 5, 0) tx = setFailOnAnte(t, suite.txConfig, tx, true) @@ -928,9 +1124,10 @@ func TestABCI_Query(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImplGasMeterOnly{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) // NOTE: "/store/key1" tells us KVStore // and the final "/key" says to use the data as the @@ -958,7 +1155,7 @@ func TestABCI_Query(t *testing.T) { bz, err := suite.txConfig.TxEncoder()(tx) require.NoError(t, err) - suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ + _, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ Height: 1, Txs: [][]byte{bz}, }) @@ -969,7 +1166,8 @@ func TestABCI_Query(t *testing.T) { require.Equal(t, 0, len(res.Value)) // query returns correct value after Commit - suite.baseApp.Commit() + _, err = suite.baseApp.Commit() + require.NoError(t, err) res, err = suite.baseApp.Query(context.TODO(), &query) require.NoError(t, err) @@ -1071,13 +1269,14 @@ func TestABCI_GetBlockRetentionHeight(t *testing.T) { tc := tc tc.bapp.SetParamStore(¶mStore{db: dbm.NewMemDB()}) - tc.bapp.InitChain(&abci.RequestInitChain{ + _, err = tc.bapp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{ Evidence: &cmtproto.EvidenceParams{ MaxAgeNumBlocks: tc.maxAgeBlocks, }, }, }) + require.NoError(t, err) t.Run(name, func(t *testing.T) { require.Equal(t, tc.expected, tc.bapp.GetBlockRetentionHeight(tc.commitHeight)) @@ -1100,8 +1299,10 @@ func TestPrepareCheckStateCalledWithCheckState(t *testing.T) { wasPrepareCheckStateCalled = true }) - app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) - app.Commit() + _, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) require.Equal(t, true, wasPrepareCheckStateCalled) } @@ -1122,8 +1323,10 @@ func TestPrecommiterCalledWithDeliverState(t *testing.T) { wasPrecommiterCalled = true }) - app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) - app.Commit() + _, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) require.Equal(t, true, wasPrecommiterCalled) } @@ -1139,9 +1342,10 @@ func TestABCI_Proposal_HappyPath(t *testing.T) { baseapptestutil.RegisterKeyValueServer(suite.baseApp.MsgServiceRouter(), MsgKeyValueImpl{}) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), NoopCounterServerImpl{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) tx := newTxCounter(t, suite.txConfig, 0, 1) txBytes, err := suite.txConfig.TxEncoder()(tx) @@ -1183,13 +1387,14 @@ func TestABCI_Proposal_HappyPath(t *testing.T) { require.NoError(t, err) require.Equal(t, abci.ResponseProcessProposal_ACCEPT, resProcessProposal.Status) + // the same txs as in PrepareProposal res, err := suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{ Height: suite.baseApp.LastBlockHeight() + 1, - Txs: [][]byte{txBytes}, + Txs: reqProposalTxBytes[:], }) require.NoError(t, err) - require.Equal(t, 1, pool.CountTx()) + require.Equal(t, 0, pool.CountTx()) require.NotEmpty(t, res.TxResults[0].Events) require.True(t, res.TxResults[0].IsOK(), fmt.Sprintf("%v", res)) @@ -1216,10 +1421,11 @@ func TestABCI_Proposal_Read_State_PrepareProposal(t *testing.T) { suite := NewBaseAppSuite(t, setInitChainerOpt, prepareOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ InitialHeight: 1, ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) reqPrepareProposal := abci.RequestPrepareProposal{ MaxTxBytes: 1000, @@ -1238,10 +1444,6 @@ func TestABCI_Proposal_Read_State_PrepareProposal(t *testing.T) { resProcessProposal, err := suite.baseApp.ProcessProposal(&reqProcessProposal) require.NoError(t, err) require.Equal(t, abci.ResponseProcessProposal_ACCEPT, resProcessProposal.Status) - - // suite.baseApp.BeginBlock(abci.RequestBeginBlock{ - // Header: cmtproto.Header{Height: suite.baseApp.LastBlockHeight() + 1}, - // }) } func TestABCI_Proposals_WithVE(t *testing.T) { @@ -1317,9 +1519,10 @@ func TestABCI_PrepareProposal_ReachedMaxBytes(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt, baseapp.SetMempool(pool)) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), NoopCounterServerImpl{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) for i := 0; i < 100; i++ { tx2 := newTxCounter(t, suite.txConfig, int64(i), int64(i)) @@ -1346,12 +1549,13 @@ func TestABCI_PrepareProposal_BadEncoding(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt, baseapp.SetMempool(pool)) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), NoopCounterServerImpl{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) tx := newTxCounter(t, suite.txConfig, 0, 0) - err := pool.Insert(sdk.Context{}, tx) + err = pool.Insert(sdk.Context{}, tx) require.NoError(t, err) reqPrepareProposal := abci.RequestPrepareProposal{ @@ -1410,9 +1614,10 @@ func TestABCI_PrepareProposal_Failures(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt, baseapp.SetMempool(pool)) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), NoopCounterServerImpl{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) tx := newTxCounter(t, suite.txConfig, 0, 0) txBytes, err := suite.txConfig.TxEncoder()(tx) @@ -1450,9 +1655,10 @@ func TestABCI_PrepareProposal_PanicRecovery(t *testing.T) { } suite := NewBaseAppSuite(t, prepareOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) req := abci.RequestPrepareProposal{ MaxTxBytes: 1000, @@ -1466,6 +1672,119 @@ func TestABCI_PrepareProposal_PanicRecovery(t *testing.T) { }) } +func TestABCI_PrepareProposal_VoteExtensions(t *testing.T) { + // set up mocks + ctrl := gomock.NewController(t) + valStore := mock.NewMockValidatorStore(ctrl) + privkey := secp256k1.GenPrivKey() + pubkey := privkey.PubKey() + addr := sdk.AccAddress(pubkey.Address()) + tmPk := cmtprotocrypto.PublicKey{ + Sum: &cmtprotocrypto.PublicKey_Secp256K1{ + Secp256K1: pubkey.Bytes(), + }, + } + + val1 := mock.NewMockValidator(ctrl) + val1.EXPECT().BondedTokens().Return(math.NewInt(667)) + val1.EXPECT().CmtConsPublicKey().Return(tmPk, nil).AnyTimes() + + consAddr := sdk.ConsAddress(addr.String()) + valStore.EXPECT().GetValidatorByConsAddr(gomock.Any(), consAddr.Bytes()).Return(val1, nil).AnyTimes() + valStore.EXPECT().TotalBondedTokens(gomock.Any()).Return(math.NewInt(1000)).AnyTimes() + + // set up baseapp + prepareOpt := func(bapp *baseapp.BaseApp) { + bapp.SetPrepareProposal(func(ctx sdk.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { + cp := ctx.ConsensusParams() + extsEnabled := cp.Abci != nil && req.Height >= cp.Abci.VoteExtensionsEnableHeight && cp.Abci.VoteExtensionsEnableHeight != 0 + if extsEnabled { + err := baseapp.ValidateVoteExtensions(ctx, valStore, req.Height, bapp.ChainID(), req.LocalLastCommit) + if err != nil { + return nil, err + } + + req.Txs = append(req.Txs, []byte("some-tx-that-does-something-from-votes")) + + } + return &abci.ResponsePrepareProposal{Txs: req.Txs}, nil + }) + } + + suite := NewBaseAppSuite(t, prepareOpt) + + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ + InitialHeight: 1, + ConsensusParams: &cmtproto.ConsensusParams{ + Abci: &cmtproto.ABCIParams{ + VoteExtensionsEnableHeight: 2, + }, + }, + }) + require.NoError(t, err) + + // first test without vote extensions, no new txs should be added + reqPrepareProposal := abci.RequestPrepareProposal{ + MaxTxBytes: 1000, + Height: 1, // this value can't be 0 + } + resPrepareProposal, err := suite.baseApp.PrepareProposal(&reqPrepareProposal) + require.NoError(t, err) + require.Equal(t, 0, len(resPrepareProposal.Txs)) + + // now we try with vote extensions, a new tx should show up + marshalDelimitedFn := func(msg proto.Message) ([]byte, error) { + var buf bytes.Buffer + if err := protoio.NewDelimitedWriter(&buf).WriteMsg(msg); err != nil { + return nil, err + } + + return buf.Bytes(), nil + } + + ext := []byte("something") + cve := cmtproto.CanonicalVoteExtension{ + Extension: ext, + Height: 2, // the vote extension was signed in the previous height + Round: int64(0), + ChainId: suite.baseApp.ChainID(), + } + + bz, err := marshalDelimitedFn(&cve) + require.NoError(t, err) + + extSig, err := privkey.Sign(bz) + require.NoError(t, err) + + reqPrepareProposal = abci.RequestPrepareProposal{ + MaxTxBytes: 1000, + Height: 3, // this value can't be 0 + LocalLastCommit: abci.ExtendedCommitInfo{ + Round: 0, + Votes: []abci.ExtendedVoteInfo{ + { + Validator: abci.Validator{ + Address: consAddr.Bytes(), + // this is being ignored by our validation function + Power: sdk.TokensToConsensusPower(math.NewInt(1000000), sdk.DefaultPowerReduction), + }, + VoteExtension: ext, + ExtensionSignature: extSig, + }, + }, + }, + } + resPrepareProposal, err = suite.baseApp.PrepareProposal(&reqPrepareProposal) + require.NoError(t, err) + require.Equal(t, 1, len(resPrepareProposal.Txs)) + + // now vote extensions but our sole voter doesn't reach majority + val1.EXPECT().BondedTokens().Return(math.NewInt(666)) + resPrepareProposal, err = suite.baseApp.PrepareProposal(&reqPrepareProposal) + require.NoError(t, err) + require.Equal(t, 0, len(resPrepareProposal.Txs)) +} + func TestABCI_ProcessProposal_PanicRecovery(t *testing.T) { processOpt := func(app *baseapp.BaseApp) { app.SetProcessProposal(func(ctx sdk.Context, rpp *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { @@ -1474,9 +1793,10 @@ func TestABCI_ProcessProposal_PanicRecovery(t *testing.T) { } suite := NewBaseAppSuite(t, processOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) require.NotPanics(t, func() { res, err := suite.baseApp.ProcessProposal(&abci.RequestProcessProposal{Height: 1}) @@ -1512,9 +1832,10 @@ func TestABCI_Proposal_Reset_State_Between_Calls(t *testing.T) { suite := NewBaseAppSuite(t, prepareOpt, processOpt) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) reqPrepareProposal := abci.RequestPrepareProposal{ MaxTxBytes: 1000, diff --git a/baseapp/abci_utils.go b/baseapp/abci_utils.go index 5a5298f0112f..d73fb003b46e 100644 --- a/baseapp/abci_utils.go +++ b/baseapp/abci_utils.go @@ -50,7 +50,7 @@ type ( // ValidateVoteExtensions defines a helper function for verifying vote extension // signatures that may be passed or manually injected into a block proposal from -// a proposer in ProcessProposal. It returns an error if any signature is invalid +// a proposer in PrepareProposal. It returns an error if any signature is invalid // or if unexpected vote extensions and/or signatures are found or less than 2/3 // power is received. func ValidateVoteExtensions( @@ -61,7 +61,7 @@ func ValidateVoteExtensions( extCommit abci.ExtendedCommitInfo, ) error { cp := ctx.ConsensusParams() - extsEnabled := cp.Abci != nil && cp.Abci.VoteExtensionsEnableHeight > 0 + extsEnabled := cp.Abci != nil && currentHeight >= cp.Abci.VoteExtensionsEnableHeight && cp.Abci.VoteExtensionsEnableHeight != 0 marshalDelimitedFn := func(msg proto.Message) ([]byte, error) { var buf bytes.Buffer @@ -72,7 +72,7 @@ func ValidateVoteExtensions( return buf.Bytes(), nil } - var sumVP math.Int + sumVP := math.NewInt(0) for _, vote := range extCommit.Votes { if !extsEnabled { if len(vote.VoteExtension) > 0 { diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index d2e07e685a2a..e4579c5b23f4 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -101,9 +101,10 @@ func NewBaseAppSuiteWithSnapshots(t *testing.T, cfg SnapshotsConfig, opts ...fun baseapptestutil.RegisterKeyValueServer(suite.baseApp.MsgServiceRouter(), MsgKeyValueImpl{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err = suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) r := rand.New(rand.NewSource(3920758213583)) keyCounter := 0 @@ -458,9 +459,10 @@ func TestCustomRunTxPanicHandler(t *testing.T) { suite := NewBaseAppSuite(t, anteOpt) baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), NoopCounterServerImpl{}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) suite.baseApp.AddRunTxRecoveryHandler(func(recoveryObj interface{}) error { err, ok := recoveryObj.(error) @@ -497,9 +499,10 @@ func TestBaseAppAnteHandler(t *testing.T) { deliverKey := []byte("deliver-key") baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImpl{t, capKey1, deliverKey}) - suite.baseApp.InitChain(&abci.RequestInitChain{ + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{ ConsensusParams: &cmtproto.ConsensusParams{}, }) + require.NoError(t, err) // execute a tx that will fail ante handler execution // @@ -569,11 +572,15 @@ func TestABCI_CreateQueryContext(t *testing.T) { name := t.Name() app := baseapp.NewBaseApp(name, log.NewTestLogger(t), db, nil) - app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) - app.Commit() + _, err := app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1}) + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) - app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 2}) - app.Commit() + _, err = app.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 2}) + require.NoError(t, err) + _, err = app.Commit() + require.NoError(t, err) testCases := []struct { name string @@ -609,7 +616,9 @@ func TestSetMinGasPrices(t *testing.T) { func TestGetMaximumBlockGas(t *testing.T) { suite := NewBaseAppSuite(t) - suite.baseApp.InitChain(&abci.RequestInitChain{}) + _, err := suite.baseApp.InitChain(&abci.RequestInitChain{}) + require.NoError(t, err) + ctx := suite.baseApp.NewContext(true) suite.baseApp.StoreConsensusParams(ctx, cmtproto.ConsensusParams{Block: &cmtproto.BlockParams{MaxGas: 0}}) diff --git a/baseapp/testutil/mock/mocks.go b/baseapp/testutil/mock/mocks.go new file mode 100644 index 000000000000..437ed68f485b --- /dev/null +++ b/baseapp/testutil/mock/mocks.go @@ -0,0 +1,210 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: baseapp/abci_utils.go + +// Package mock is a generated GoMock package. +package mock + +import ( + reflect "reflect" + + math "cosmossdk.io/math" + crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + baseapp "github.com/cosmos/cosmos-sdk/baseapp" + types "github.com/cosmos/cosmos-sdk/crypto/types" + types0 "github.com/cosmos/cosmos-sdk/types" + gomock "github.com/golang/mock/gomock" +) + +// MockValidator is a mock of Validator interface. +type MockValidator struct { + ctrl *gomock.Controller + recorder *MockValidatorMockRecorder +} + +// MockValidatorMockRecorder is the mock recorder for MockValidator. +type MockValidatorMockRecorder struct { + mock *MockValidator +} + +// NewMockValidator creates a new mock instance. +func NewMockValidator(ctrl *gomock.Controller) *MockValidator { + mock := &MockValidator{ctrl: ctrl} + mock.recorder = &MockValidatorMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockValidator) EXPECT() *MockValidatorMockRecorder { + return m.recorder +} + +// BondedTokens mocks base method. +func (m *MockValidator) BondedTokens() math.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BondedTokens") + ret0, _ := ret[0].(math.Int) + return ret0 +} + +// BondedTokens indicates an expected call of BondedTokens. +func (mr *MockValidatorMockRecorder) BondedTokens() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BondedTokens", reflect.TypeOf((*MockValidator)(nil).BondedTokens)) +} + +// CmtConsPublicKey mocks base method. +func (m *MockValidator) CmtConsPublicKey() (crypto.PublicKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CmtConsPublicKey") + ret0, _ := ret[0].(crypto.PublicKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CmtConsPublicKey indicates an expected call of CmtConsPublicKey. +func (mr *MockValidatorMockRecorder) CmtConsPublicKey() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CmtConsPublicKey", reflect.TypeOf((*MockValidator)(nil).CmtConsPublicKey)) +} + +// MockValidatorStore is a mock of ValidatorStore interface. +type MockValidatorStore struct { + ctrl *gomock.Controller + recorder *MockValidatorStoreMockRecorder +} + +// MockValidatorStoreMockRecorder is the mock recorder for MockValidatorStore. +type MockValidatorStoreMockRecorder struct { + mock *MockValidatorStore +} + +// NewMockValidatorStore creates a new mock instance. +func NewMockValidatorStore(ctrl *gomock.Controller) *MockValidatorStore { + mock := &MockValidatorStore{ctrl: ctrl} + mock.recorder = &MockValidatorStoreMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockValidatorStore) EXPECT() *MockValidatorStoreMockRecorder { + return m.recorder +} + +// GetValidatorByConsAddr mocks base method. +func (m *MockValidatorStore) GetValidatorByConsAddr(arg0 types0.Context, arg1 types.Address) (baseapp.Validator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValidatorByConsAddr", arg0, arg1) + ret0, _ := ret[0].(baseapp.Validator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetValidatorByConsAddr indicates an expected call of GetValidatorByConsAddr. +func (mr *MockValidatorStoreMockRecorder) GetValidatorByConsAddr(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorByConsAddr", reflect.TypeOf((*MockValidatorStore)(nil).GetValidatorByConsAddr), arg0, arg1) +} + +// TotalBondedTokens mocks base method. +func (m *MockValidatorStore) TotalBondedTokens(ctx types0.Context) math.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TotalBondedTokens", ctx) + ret0, _ := ret[0].(math.Int) + return ret0 +} + +// TotalBondedTokens indicates an expected call of TotalBondedTokens. +func (mr *MockValidatorStoreMockRecorder) TotalBondedTokens(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TotalBondedTokens", reflect.TypeOf((*MockValidatorStore)(nil).TotalBondedTokens), ctx) +} + +// MockGasTx is a mock of GasTx interface. +type MockGasTx struct { + ctrl *gomock.Controller + recorder *MockGasTxMockRecorder +} + +// MockGasTxMockRecorder is the mock recorder for MockGasTx. +type MockGasTxMockRecorder struct { + mock *MockGasTx +} + +// NewMockGasTx creates a new mock instance. +func NewMockGasTx(ctrl *gomock.Controller) *MockGasTx { + mock := &MockGasTx{ctrl: ctrl} + mock.recorder = &MockGasTxMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockGasTx) EXPECT() *MockGasTxMockRecorder { + return m.recorder +} + +// GetGas mocks base method. +func (m *MockGasTx) GetGas() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetGas") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// GetGas indicates an expected call of GetGas. +func (mr *MockGasTxMockRecorder) GetGas() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGas", reflect.TypeOf((*MockGasTx)(nil).GetGas)) +} + +// MockProposalTxVerifier is a mock of ProposalTxVerifier interface. +type MockProposalTxVerifier struct { + ctrl *gomock.Controller + recorder *MockProposalTxVerifierMockRecorder +} + +// MockProposalTxVerifierMockRecorder is the mock recorder for MockProposalTxVerifier. +type MockProposalTxVerifierMockRecorder struct { + mock *MockProposalTxVerifier +} + +// NewMockProposalTxVerifier creates a new mock instance. +func NewMockProposalTxVerifier(ctrl *gomock.Controller) *MockProposalTxVerifier { + mock := &MockProposalTxVerifier{ctrl: ctrl} + mock.recorder = &MockProposalTxVerifierMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockProposalTxVerifier) EXPECT() *MockProposalTxVerifierMockRecorder { + return m.recorder +} + +// PrepareProposalVerifyTx mocks base method. +func (m *MockProposalTxVerifier) PrepareProposalVerifyTx(tx types0.Tx) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrepareProposalVerifyTx", tx) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PrepareProposalVerifyTx indicates an expected call of PrepareProposalVerifyTx. +func (mr *MockProposalTxVerifierMockRecorder) PrepareProposalVerifyTx(tx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareProposalVerifyTx", reflect.TypeOf((*MockProposalTxVerifier)(nil).PrepareProposalVerifyTx), tx) +} + +// ProcessProposalVerifyTx mocks base method. +func (m *MockProposalTxVerifier) ProcessProposalVerifyTx(txBz []byte) (types0.Tx, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ProcessProposalVerifyTx", txBz) + ret0, _ := ret[0].(types0.Tx) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ProcessProposalVerifyTx indicates an expected call of ProcessProposalVerifyTx. +func (mr *MockProposalTxVerifierMockRecorder) ProcessProposalVerifyTx(txBz interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProcessProposalVerifyTx", reflect.TypeOf((*MockProposalTxVerifier)(nil).ProcessProposalVerifyTx), txBz) +} diff --git a/scripts/mockgen.sh b/scripts/mockgen.sh index a3786acc50d2..a57691b951f7 100755 --- a/scripts/mockgen.sh +++ b/scripts/mockgen.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash mockgen_cmd="mockgen" +$mockgen_cmd -source=baseapp/abci_utils.go -package mock -destination baseapp/testutil/mock/validator_store.go $mockgen_cmd -source=client/account_retriever.go -package mock -destination testutil/mock/account_retriever.go $mockgen_cmd -package mock -destination store/mock/cosmos_cosmos_db_DB.go github.com/cosmos/cosmos-db DB $mockgen_cmd -source=types/module/module.go -package mock -destination testutil/mock/types_module_module.go