diff --git a/x/ccv/provider/keeper/keeper.go b/x/ccv/provider/keeper/keeper.go index 87d349563e..751384fded 100644 --- a/x/ccv/provider/keeper/keeper.go +++ b/x/ccv/provider/keeper/keeper.go @@ -1155,14 +1155,10 @@ func (k Keeper) SetTopN( func (k Keeper) GetTopN( ctx sdk.Context, chainID string, -) (uint32, bool) { +) uint32 { store := ctx.KVStore(k.storeKey) buf := store.Get(types.TopNKey(chainID)) - if buf == nil { - return 0, false - } else { - } - return binary.BigEndian.Uint32(buf), true + return binary.BigEndian.Uint32(buf) } // IsTopN returns true if chain with `chainID` is a Top N chain (i.e., enforces at least one validator to validate chain `chainID`) diff --git a/x/ccv/provider/keeper/keeper_test.go b/x/ccv/provider/keeper/keeper_test.go index 9c9d421fd9..950cf5b0eb 100644 --- a/x/ccv/provider/keeper/keeper_test.go +++ b/x/ccv/provider/keeper/keeper_test.go @@ -628,3 +628,22 @@ func TestGetAllProposedConsumerChainIDs(t *testing.T) { } } } + +// TestTopN tests `SetTopN`, `GetTopN`, `IsTopN`, and `IsOptIn` methods +func TestTopN(t *testing.T) { + providerKeeper, ctx, ctrl, _ := testkeeper.GetProviderKeeperAndCtx(t, testkeeper.NewInMemKeeperParams(t)) + defer ctrl.Finish() + + providerKeeper.SetTopN(ctx, "TopNChainID1", 50) + require.Equal(t, uint32(50), providerKeeper.GetTopN(ctx, "TopNChainID1")) + require.True(t, providerKeeper.IsTopN(ctx, "TopNChainID1")) + require.False(t, providerKeeper.IsOptIn(ctx, "TopNChainID1")) + + providerKeeper.SetTopN(ctx, "TopNChainID2", 100) + require.Equal(t, uint32(100), providerKeeper.GetTopN(ctx, "TopNChainID2")) + + providerKeeper.SetTopN(ctx, "OptInChain", 0) + require.Equal(t, uint32(0), providerKeeper.GetTopN(ctx, "OptInChain")) + require.False(t, providerKeeper.IsTopN(ctx, "OptInChain")) + require.True(t, providerKeeper.IsOptIn(ctx, "OptInChain")) +} diff --git a/x/ccv/provider/keeper/proposal.go b/x/ccv/provider/keeper/proposal.go index 28b9964c84..c1205b921a 100644 --- a/x/ccv/provider/keeper/proposal.go +++ b/x/ccv/provider/keeper/proposal.go @@ -36,13 +36,6 @@ func (k Keeper) HandleConsumerAdditionProposal(ctx sdk.Context, p *types.Consume return err } - // you should not be able - if _, found := k.GetTopN(ctx, p.ChainId); found { - return errorsmod.Wrap(types.ErrDuplicateConsumerChain, - fmt.Sprint("cannot add a chain ")) - } - k.SetTopN(ctx, p.ChainId, p.Top_N) - k.SetPendingConsumerAdditionProp(ctx, p) k.Logger(ctx).Info("consumer addition proposal enqueued", @@ -372,6 +365,7 @@ func (k Keeper) BeginBlockInit(ctx sdk.Context) { ctx.Logger().Info("consumer client could not be created: %w", err) continue } + k.SetTopN(ctx, prop.ChainId, prop.Top_N) // The cached context is created with a new EventManager so we merge the event // into the original context ctx.EventManager().EmitEvents(cachedCtx.EventManager().Events())