diff --git a/testutil/keeper/expectations.go b/testutil/keeper/expectations.go index 34446bd0c3..8a010ce405 100644 --- a/testutil/keeper/expectations.go +++ b/testutil/keeper/expectations.go @@ -57,8 +57,6 @@ func GetMocksForMakeConsumerGenesis(ctx sdk.Context, mocks *MockedKeepers, mocks.MockClientKeeper.EXPECT().GetSelfConsensusState(gomock.Any(), clienttypes.GetSelfHeight(ctx)).Return(&ibctmtypes.ConsensusState{}, nil).Times(1), - - mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1), } } diff --git a/testutil/keeper/unit_test_helpers.go b/testutil/keeper/unit_test_helpers.go index abba1a23c9..ef208cb907 100644 --- a/testutil/keeper/unit_test_helpers.go +++ b/testutil/keeper/unit_test_helpers.go @@ -215,6 +215,7 @@ func SetupForStoppingConsumerChain(t *testing.T, ctx sdk.Context, providerKeeper *providerkeeper.Keeper, mocks MockedKeepers, ) { t.Helper() + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1) expectations := GetMocksForCreateConsumerClient(ctx, &mocks, "chainID", clienttypes.NewHeight(4, 5)) expectations = append(expectations, GetMocksForSetConsumerChain(ctx, &mocks, "chainID")...) diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index 2e8c9b46d4..cab171ac48 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -388,6 +388,19 @@ func (k Keeper) BeginBlockInit(ctx sdk.Context) { continue } + consumerGenesis, found := k.GetConsumerGenesis(cachedCtx, prop.ChainId) + if !found { + // drop the proposal + ctx.Logger().Info("consumer genesis could not be created") + continue + } + + if len(consumerGenesis.Provider.InitialValSet) == 0 { + // drop the proposal + ctx.Logger().Info("consumer genesis initial validator set cannot be empty") + continue + } + // The cached context is created with a new EventManager so we merge the event // into the original context ctx.EventManager().EmitEvents(cachedCtx.EventManager().Events()) diff --git a/x/ccv/provider/keeper/proposal_test.go b/x/ccv/provider/keeper/proposal_test.go index 80b4531b75..310c9556b6 100644 --- a/x/ccv/provider/keeper/proposal_test.go +++ b/x/ccv/provider/keeper/proposal_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "bytes" "encoding/json" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "sort" "testing" "time" @@ -115,6 +116,7 @@ func TestHandleConsumerAdditionProposal(t *testing.T) { if tc.expAppendProp { // Mock calls are only asserted if we expect a client to be created. + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1) gomock.InOrder( testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, tc.prop.ChainId, clienttypes.NewHeight(2, 3))..., ) @@ -158,6 +160,7 @@ func TestCreateConsumerClient(t *testing.T) { description: "No state mutation, new client should be created", setup: func(providerKeeper *providerkeeper.Keeper, ctx sdk.Context, mocks *testkeeper.MockedKeepers) { // Valid client creation is asserted with mock expectations here + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1) gomock.InOrder( testkeeper.GetMocksForCreateConsumerClient(ctx, mocks, "chainID", clienttypes.NewHeight(4, 5))..., ) @@ -796,6 +799,7 @@ func TestMakeConsumerGenesis(t *testing.T) { // ctx = ctx.WithChainID("testchain1") // chainID is obtained from ctx ctx = ctx.WithBlockHeight(5) // RevisionHeight obtained from ctx + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1) gomock.InOrder(testkeeper.GetMocksForMakeConsumerGenesis(ctx, &mocks, 1814400000000000)...) // matches params from jsonString @@ -1021,6 +1025,8 @@ func TestBeginBlockInit(t *testing.T) { // opt in a sample validator so the chain's proposal can successfully execute validator := cryptotestutil.NewCryptoIdentityFromIntSeed(0).SDKStakingValidator() consAddr, _ := validator.GetConsAddr() + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Return([]stakingtypes.Validator{validator}).AnyTimes() + mocks.MockStakingKeeper.EXPECT().GetLastValidatorPower(gomock.Any(), validator.GetOperator()).Return(int64(1)).AnyTimes() providerKeeper.SetOptedIn(ctx, pendingProps[4].ChainId, providertypes.NewProviderConsAddress(consAddr)) providerKeeper.BeginBlockInit(ctx) @@ -1104,6 +1110,7 @@ func TestBeginBlockCCR(t *testing.T) { expectations := []*gomock.Call{} for _, prop := range pendingProps { // A consumer chain is setup corresponding to each prop, making these mocks necessary + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1) expectations = append(expectations, testkeeper.GetMocksForCreateConsumerClient(ctx, &mocks, prop.ChainId, clienttypes.NewHeight(2, 3))...) expectations = append(expectations, testkeeper.GetMocksForSetConsumerChain(ctx, &mocks, prop.ChainId)...) diff --git a/x/ccv/provider/proposal_handler_test.go b/x/ccv/provider/proposal_handler_test.go index 185db25b07..8d5b696b40 100644 --- a/x/ccv/provider/proposal_handler_test.go +++ b/x/ccv/provider/proposal_handler_test.go @@ -96,6 +96,7 @@ func TestProviderProposalHandler(t *testing.T) { // Mock expectations depending on expected outcome switch { case tc.expValidConsumerAddition: + mocks.MockStakingKeeper.EXPECT().GetLastValidators(gomock.Any()).Times(1) gomock.InOrder(testkeeper.GetMocksForCreateConsumerClient( ctx, &mocks, "chainID", clienttypes.NewHeight(2, 3), )...)