From d235bc495286e1dbfa567427714297bb4fab1338 Mon Sep 17 00:00:00 2001 From: Vlad J Date: Mon, 1 Dec 2025 14:51:51 -0500 Subject: [PATCH] refactor!(gov): make distribution keeper optional (#25616) Co-authored-by: Alex | Cosmos Labs --- CHANGELOG.md | 1 + tests/integration/gov/genesis_test.go | 2 +- x/gov/genesis_test.go | 39 --------------------------- x/gov/{ => keeper}/genesis.go | 13 ++++++--- x/gov/keeper/genesis_test.go | 36 +++++++++++++++++++++++++ x/gov/module.go | 4 +-- 6 files changed, 49 insertions(+), 46 deletions(-) delete mode 100644 x/gov/genesis_test.go rename x/gov/{ => keeper}/genesis.go (87%) create mode 100644 x/gov/keeper/genesis_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 8066e3b0ba..09ab1fe0a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (crypto) [#24414](https://github.com/cosmos/cosmos-sdk/pull/24414) Remove sr25519 support, since it was removed in CometBFT v1.x (see: CometBFT [#3646](https://github.com/cometbft/cometbft/pull/3646)). * (x/gov) [#25615](https://github.com/cosmos/cosmos-sdk/pull/25615) Decouple `x/gov` from `x/staking` by making `CalculateVoteResultsAndVotingPowerFn` a required parameter to `keeper.NewKeeper` instead of `StakingKeeper`. `BondedTokens` has been renamed to `ValidatorPower` and `TotalBondedTokens` has been renamed to `TotalValidatorPower` to allow for multiple validator power representations. +* (x/gov) [#25616](https://github.com/cosmos/cosmos-sdk/pull/25616) `DistrKeeper` `x/distribution` is now optional. Genesis validation ensures `distrKeeper` is set if distribution module is used as proposal cancel destination. ### Features diff --git a/tests/integration/gov/genesis_test.go b/tests/integration/gov/genesis_test.go index f3d1784e53..72c8b17534 100644 --- a/tests/integration/gov/genesis_test.go +++ b/tests/integration/gov/genesis_test.go @@ -109,7 +109,7 @@ func TestImportExportQueues(t *testing.T) { distributionGenState := s1.DistrKeeper.ExportGenesis(ctx) // export the state and import it into a new app - govGenState, _ := gov.ExportGenesis(ctx, s1.GovKeeper) + govGenState, _ := keeper.ExportGenesis(ctx, s1.GovKeeper) genesisState := s1.appBuilder.DefaultGenesis() genesisState[authtypes.ModuleName] = s1.cdc.MustMarshalJSON(authGenState) diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go deleted file mode 100644 index 9382b2cdff..0000000000 --- a/x/gov/genesis_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package gov_test - -import ( - "testing" - - "github.com/stretchr/testify/require" - - sdkmath "cosmossdk.io/math" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/gov" - v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" -) - -func TestImportExportQueues_ErrorUnconsistentState(t *testing.T) { - suite := createTestSuite(t) - app := suite.App - ctx := app.NewContext(false) - require.Panics(t, func() { - gov.InitGenesis(ctx, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, &v1.GenesisState{ - Deposits: v1.Deposits{ - { - ProposalId: 1234, - Depositor: "me", - Amount: sdk.Coins{ - sdk.NewCoin( - "stake", - sdkmath.NewInt(1234), - ), - }, - }, - }, - }) - }) - gov.InitGenesis(ctx, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, v1.DefaultGenesisState()) - genState, err := gov.ExportGenesis(ctx, suite.GovKeeper) - require.NoError(t, err) - require.Equal(t, genState, v1.DefaultGenesisState()) -} diff --git a/x/gov/genesis.go b/x/gov/keeper/genesis.go similarity index 87% rename from x/gov/genesis.go rename to x/gov/keeper/genesis.go index 0eeebcd72e..8169bacaed 100644 --- a/x/gov/genesis.go +++ b/x/gov/keeper/genesis.go @@ -1,4 +1,4 @@ -package gov +package keeper import ( "fmt" @@ -6,18 +6,23 @@ import ( "cosmossdk.io/collections" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/gov/keeper" + disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/gov/types" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" ) // InitGenesis - store genesis parameters -func InitGenesis(ctx sdk.Context, ak types.AccountKeeper, bk types.BankKeeper, k *keeper.Keeper, data *v1.GenesisState) { +func InitGenesis(ctx sdk.Context, ak types.AccountKeeper, bk types.BankKeeper, k *Keeper, data *v1.GenesisState) { err := k.ProposalID.Set(ctx, data.StartingProposalId) if err != nil { panic(err) } + distrAddress := ak.GetModuleAddress(disttypes.ModuleName).String() + if data.Params.ProposalCancelDest == distrAddress && distrAddress != "" && k.distrKeeper == nil { + panic(fmt.Sprintf("must set DistrKeeper first if using distribution module (%s) as proposal cancel destination", distrAddress)) + } + err = k.Params.Set(ctx, *data.Params) if err != nil { panic(err) @@ -86,7 +91,7 @@ func InitGenesis(ctx sdk.Context, ak types.AccountKeeper, bk types.BankKeeper, k } // ExportGenesis - output genesis parameters -func ExportGenesis(ctx sdk.Context, k *keeper.Keeper) (*v1.GenesisState, error) { +func ExportGenesis(ctx sdk.Context, k *Keeper) (*v1.GenesisState, error) { startingProposalID, err := k.ProposalID.Peek(ctx) if err != nil { return nil, err diff --git a/x/gov/keeper/genesis_test.go b/x/gov/keeper/genesis_test.go new file mode 100644 index 0000000000..6a21cd0fc4 --- /dev/null +++ b/x/gov/keeper/genesis_test.go @@ -0,0 +1,36 @@ +package keeper_test + +import ( + "go.uber.org/mock/gomock" + + sdkmath "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/gov/keeper" + v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" +) + +func (suite *KeeperTestSuite) TestImportExportQueues_ErrorUnconsistentState() { + suite.reset() + suite.acctKeeper.EXPECT().SetModuleAccount(suite.ctx, gomock.Any()).AnyTimes() + suite.Require().Panics(func() { + keeper.InitGenesis(suite.ctx, suite.acctKeeper, suite.bankKeeper, suite.govKeeper, &v1.GenesisState{ + Deposits: v1.Deposits{ + { + ProposalId: 1234, + Depositor: "me", + Amount: sdk.Coins{ + sdk.NewCoin( + "stake", + sdkmath.NewInt(1234), + ), + }, + }, + }, + }) + }) + keeper.InitGenesis(suite.ctx, suite.acctKeeper, suite.bankKeeper, suite.govKeeper, v1.DefaultGenesisState()) + genState, err := keeper.ExportGenesis(suite.ctx, suite.govKeeper) + suite.Require().NoError(err) + suite.Require().Equal(genState, v1.DefaultGenesisState()) +} diff --git a/x/gov/module.go b/x/gov/module.go index 535cd721ad..fab4e2b5ca 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -176,13 +176,13 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState v1.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - InitGenesis(ctx, am.accountKeeper, am.bankKeeper, am.keeper, &genesisState) + keeper.InitGenesis(ctx, am.accountKeeper, am.bankKeeper, am.keeper, &genesisState) } // ExportGenesis returns the exported genesis state as raw bytes for the gov // module. func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - gs, err := ExportGenesis(ctx, am.keeper) + gs, err := keeper.ExportGenesis(ctx, am.keeper) if err != nil { panic(err) }