Skip to content

Commit

Permalink
refactor(modules): adopt appmodulev2.Hasgenesis (#19627)
Browse files Browse the repository at this point in the history
Co-authored-by: Julien Robert <julien@rbrt.fr>
  • Loading branch information
tac0turtle and julienrbrt authored Mar 11, 2024
1 parent d4e5206 commit d2e4096
Show file tree
Hide file tree
Showing 72 changed files with 684 additions and 692 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
* (types) [#19652](https://github.com/cosmos/cosmos-sdk/pull/19652)
* Moved`types/module.HasRegisterInterfaces` to `cosmossdk.io/core`.
* Moved `RegisterInterfaces` and `RegisterImplementations` from `InterfaceRegistry` to `cosmossdk.io/core/registry.LegacyRegistry` interface.
* (types) [#19627](https://github.com/cosmos/cosmos-sdk/pull/19627) All genesis interfaces now don't take `codec.JsonCodec`. Every module has the codec already, passing it created an unneeded dependency. Additionally, to reflect this change, the module manager does not take a codec either.

### Client Breaking Changes

Expand Down
6 changes: 3 additions & 3 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,16 @@ Previous module migrations have been removed. It is required to migrate to v0.50

##### Genesis Interface

All genesis interfaces have been migrated to take context.Context instead of sdk.Context.
All genesis interfaces have been migrated to take context.Context instead of sdk.Context. Secondly, the codec is no longer passed in by the framework. The codec is now passed in by the module.

```go
// InitGenesis performs genesis initialization for the authz module.
func (am AppModule) InitGenesis(ctx context.Context, cdc codec.JSONCodec, data json.RawMessage) {
func (am AppModule) InitGenesis(ctx context.Context, data json.RawMessage) error {
}

// ExportGenesis returns the exported genesis state as raw bytes for the authz
// module.
func (am AppModule) ExportGenesis(ctx context.Context, cdc codec.JSONCodec) json.RawMessage {
func (am AppModule) ExportGenesis(ctx context.Context) (json.RawMessage, error) {
}
```

Expand Down
11 changes: 8 additions & 3 deletions core/appmodule/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ package appmodule
import (
"context"
"io"

appmodule "cosmossdk.io/core/appmodule/v2"
)

// HasGenesis is the extension interface that modules should implement to handle
// HasGenesis defines a custom genesis handling API implementation.
type HasGenesis = appmodule.HasGenesis

// HasGenesisAuto is the extension interface that modules should implement to handle
// genesis data and state initialization.
// WARNING: This interface is experimental and may change at any time.
type HasGenesis interface {
AppModule
type HasGenesisAuto interface {
appmodule.AppModule

// DefaultGenesis writes the default genesis for this module to the target.
DefaultGenesis(GenesisTarget) error
Expand Down
8 changes: 4 additions & 4 deletions core/appmodule/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type ResponsePreBlock interface {
// HasPreBlocker is the extension interface that modules should implement to run
// custom logic before BeginBlock.
type HasPreBlocker interface {
AppModule
appmodule.AppModule
// PreBlock is method that will be run before BeginBlock.
PreBlock(context.Context) (ResponsePreBlock, error)
}
Expand Down Expand Up @@ -91,12 +91,12 @@ type HasMsgHandler interface {
// HasPrepareCheckState is an extension interface that contains information about the AppModule
// and PrepareCheckState.
type HasPrepareCheckState interface {
AppModule
appmodule.AppModule
PrepareCheckState(context.Context) error
}

// HasPrecommit is an extension interface that contains information about the AppModule and Precommit.
// HasPrecommit is an extension interface that contains information about the appmodule.AppModule and Precommit.
type HasPrecommit interface {
AppModule
appmodule.AppModule
Precommit(context.Context) error
}
2 changes: 1 addition & 1 deletion core/appmodule/v2/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
// migration of existing modules to the new app module API. It is intended to be replaced by collections
type HasGenesis interface {
AppModule
DefaultGenesis() Message
DefaultGenesis() json.RawMessage
ValidateGenesis(data json.RawMessage) error
InitGenesis(ctx context.Context, data json.RawMessage) error
ExportGenesis(ctx context.Context) (json.RawMessage, error)
Expand Down
8 changes: 5 additions & 3 deletions docs/build/building-modules/01-module-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ There are 2 main application module interfaces:

The above interfaces are mostly embedding smaller interfaces (extension interfaces), that defines specific functionalities:

<!-- TO UPDATE - THIS IS SEVERELY OUTDATED -->

* (legacy) `module.HasName`: Allows the module to provide its own name for legacy purposes.
* (legacy) [`module.HasGenesisBasics`](#modulehasgenesisbasics): The legacy interface for stateless genesis methods.
* (legacy) [`module.HasGenesis`](#modulehasgenesis) for inter-dependent genesis-related module functionalities.
Expand Down Expand Up @@ -270,9 +272,9 @@ The module manager is used throughout the application whenever an action on a co
* `SetOrderMigrations(moduleNames ...string)`: Sets the order of migrations to be run. If not set then migrations will be run with an order defined in `DefaultMigrationsOrder`.
* `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./07-invariants.md) of module implementing the `HasInvariants` interface.
* `RegisterServices(cfg Configurator)`: Registers the services of modules implementing the `HasServices` interface.
* `InitGenesis(ctx context.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./08-genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates.
* `ExportGenesis(ctx context.Context, cdc codec.JSONCodec)`: Calls the [`ExportGenesis`](./08-genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required.
* `ExportGenesisForModules(ctx context.Context, cdc codec.JSONCodec, modulesToExport []string)`: Behaves the same as `ExportGenesis`, except takes a list of modules to export.
* `InitGenesis(ctx context.Context, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./08-genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates.
* `ExportGenesis(ctx context.Context)`: Calls the [`ExportGenesis`](./08-genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required.
* `ExportGenesisForModules(ctx context.Context, modulesToExport []string)`: Behaves the same as `ExportGenesis`, except takes a list of modules to export.
* `BeginBlock(ctx context.Context) error`: At the beginning of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./06-beginblock-endblock.md) function of each modules implementing the `appmodule.HasBeginBlocker` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../../learn/advanced/02-context.md) with an event manager to aggregate [events](../../learn/advanced/08-events.md) emitted from each modules.
* `EndBlock(ctx context.Context) error`: At the end of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-beginblock-endblock.md) function of each modules implementing the `appmodule.HasEndBlocker` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../../learn/advanced/02-context.md) with an event manager to aggregate [events](../../learn/advanced/08-events.md) emitted from all modules. The function returns an `abci` which contains the aforementioned events, as well as validator set updates (if any).
* `EndBlock(context.Context) ([]abci.ValidatorUpdate, error)`: At the end of each block, this function is called from [`BaseApp`](../../learn/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-beginblock-endblock.md) function of each modules implementing the `module.HasABCIEndBlock` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../../learn/advanced/02-context.md) with an event manager to aggregate [events](../../learn/advanced/08-events.md) emitted from all modules. The function returns an `abci` which contains the aforementioned events, as well as validator set updates (if any).
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ replace (
cosmossdk.io/x/staking => ./x/staking
)

replace github.com/cosmos/iavl => github.com/cosmos/iavl v1.0.1 // TODO remove

// Below are the long-lived replace of the Cosmos SDK
replace (
// use cosmos fork of keyring
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ 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.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g=
github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y=
github.com/cosmos/iavl v1.0.0 h1:bw6t0Mv/mVCJvlMTOPHWLs5uUE3BRBfVWCRelOzl+so=
github.com/cosmos/iavl v1.0.0/go.mod h1:CmTGqMnRnucjxbjduneZXT+0vPgNElYvdefjX2q9tYc=
github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw=
github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY=
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=
Expand Down
4 changes: 2 additions & 2 deletions orm/model/ormdb/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type ModuleDB interface {
// func NewAppModule(keeper keeper.Keeper) AppModule {
// return AppModule{HasGenesis: keeper.GenesisHandler()}
// }
GenesisHandler() appmodule.HasGenesis
GenesisHandler() appmodule.HasGenesis // TODO should be appmodule.HasGenesisAuto with core v1

private()
}
Expand Down Expand Up @@ -212,7 +212,7 @@ func (m moduleDB) GetTable(message proto.Message) ormtable.Table {
return m.tablesByName[message.ProtoReflect().Descriptor().FullName()]
}

func (m moduleDB) GenesisHandler() appmodule.HasGenesis {
func (m moduleDB) GenesisHandler() appmodule.HasGenesis { // TODO should be appmodule.HasGenesisAuto with core v1
return appModuleGenesisWrapper{m}
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func (a *App) LoadHeight(height int64) error {

// DefaultGenesis returns a default genesis from the registered AppModule's.
func (a *App) DefaultGenesis() map[string]json.RawMessage {
return a.ModuleManager.DefaultGenesis(a.cdc)
return a.ModuleManager.DefaultGenesis()
}

// GetStoreKeys returns all the stored store keys.
Expand Down
8 changes: 4 additions & 4 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@ func NewSimApp(
// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.
app.ModuleManager = module.NewManager(
genutil.NewAppModule(app.AuthKeeper, app.StakingKeeper, app, txConfig, genutiltypes.DefaultMessageValidator),
accounts.NewAppModule(app.AccountsKeeper),
genutil.NewAppModule(appCodec, app.AuthKeeper, app.StakingKeeper, app, txConfig, genutiltypes.DefaultMessageValidator),
accounts.NewAppModule(appCodec, app.AccountsKeeper),
auth.NewAppModule(appCodec, app.AuthKeeper, authsims.RandomGenesisAccounts),
vesting.NewAppModule(app.AuthKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AuthKeeper),
Expand All @@ -420,7 +420,7 @@ func NewSimApp(
distr.NewAppModule(appCodec, app.DistrKeeper, app.AuthKeeper, app.BankKeeper, app.StakingKeeper, app.PoolKeeper),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AuthKeeper, app.BankKeeper),
upgrade.NewAppModule(app.UpgradeKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
evidence.NewAppModule(appCodec, app.EvidenceKeeper),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry),
nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AuthKeeper, app.BankKeeper, app.interfaceRegistry),
Expand Down Expand Up @@ -698,7 +698,7 @@ func (app *SimApp) AutoCliOpts() autocli.AppOptions {

// DefaultGenesis returns a default genesis from the registered AppModule's.
func (a *SimApp) DefaultGenesis() map[string]json.RawMessage {
return a.ModuleManager.DefaultGenesis(a.appCodec)
return a.ModuleManager.DefaultGenesis()
}

// GetKey returns the KVStoreKey for the provided store key.
Expand Down
4 changes: 2 additions & 2 deletions simapp/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ func TestInitGenesisOnMigration(t *testing.T) {
t.Cleanup(mockCtrl.Finish)
mockModule := mock.NewMockAppModuleWithAllExtensions(mockCtrl)
mockDefaultGenesis := json.RawMessage(`{"key": "value"}`)
mockModule.EXPECT().DefaultGenesis(gomock.Eq(app.appCodec)).Times(1).Return(mockDefaultGenesis)
mockModule.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(app.appCodec), gomock.Eq(mockDefaultGenesis)).Times(1)
mockModule.EXPECT().DefaultGenesis().Times(1).Return(mockDefaultGenesis)
mockModule.EXPECT().InitGenesis(gomock.Eq(ctx), gomock.Eq(mockDefaultGenesis)).Times(1)
mockModule.EXPECT().ConsensusVersion().Times(1).Return(uint64(0))

app.ModuleManager.Modules["mock"] = mockModule
Expand Down
2 changes: 1 addition & 1 deletion simapp/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (app *SimApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAd
app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs)
}

genState, err := app.ModuleManager.ExportGenesisForModules(ctx, app.appCodec, modulesToExport)
genState, err := app.ModuleManager.ExportGenesisForModules(ctx, modulesToExport)
if err != nil {
return servertypes.ExportedApp{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion simapp/simd/cmd/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ func initGenFiles(
genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance,
genFiles []string, numValidators int,
) error {
appGenState := mm.DefaultGenesis(clientCtx.Codec)
appGenState := mm.DefaultGenesis()

// set the accounts in the genesis state
var authGenState authtypes.GenesisState
Expand Down
1 change: 0 additions & 1 deletion store/snapshots/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ func (s *extSnapshotter) RestoreExtension(height uint64, format uint32, payloadR

// GetTempDir returns a writable temporary director for the test to use.
func GetTempDir(tb testing.TB) string {
//return "/tmp/snapshots"
tb.Helper()
// os.MkDir() is used instead of testing.T.TempDir()
// see https://github.com/cosmos/cosmos-sdk/pull/8475 and
Expand Down
4 changes: 2 additions & 2 deletions store/snapshots/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ func (s *Store) Prune(retain uint32) (uint64, error) {
skip[height] = true
continue
}
err = s.Delete(height, uint32(format))
err = s.Delete(height, format)
if err != nil {
return 0, errors.Wrap(err, "failed to prune snapshots")
}
Expand Down Expand Up @@ -382,7 +382,7 @@ func (s *Store) parseMetadataFilename(filename string) (height uint64, format ui
return 0, 0, errors.Wrapf(err, "invalid snapshot metadata filename %s", filename)
}
format = uint32(f)
if filename != filepath.Base(s.pathMetadata(height, uint32(format))) {
if filename != filepath.Base(s.pathMetadata(height, format)) {
return 0, 0, fmt.Errorf("invalid snapshot metadata filename %s", filename)
}
return height, format, nil
Expand Down
23 changes: 11 additions & 12 deletions tests/integration/evidence/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,12 @@ func (suite *GenesisTestSuite) TestInitGenesis() {
tc.malleate()

if tc.expPass {
suite.NotPanics(func() {
evidence.InitGenesis(suite.ctx, suite.keeper, genesisState)
})
err := evidence.InitGenesis(suite.ctx, suite.keeper, genesisState)
suite.NoError(err)
} else {
suite.Panics(func() {
evidence.InitGenesis(suite.ctx, suite.keeper, genesisState)
})
err := evidence.InitGenesis(suite.ctx, suite.keeper, genesisState)
suite.Error(err)

}

tc.posttests()
Expand Down Expand Up @@ -151,13 +150,13 @@ func (suite *GenesisTestSuite) TestExportGenesis() {
tc.malleate()

if tc.expPass {
suite.NotPanics(func() {
evidence.ExportGenesis(suite.ctx, suite.keeper)
})

_, err := evidence.ExportGenesis(suite.ctx, suite.keeper)
suite.Require().NoError(err)

} else {
suite.Panics(func() {
evidence.ExportGenesis(suite.ctx, suite.keeper)
})
_, err := evidence.ExportGenesis(suite.ctx, suite.keeper)
suite.Require().Error(err)
}

tc.posttests()
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/evidence/keeper/infraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func initFixture(tb testing.TB) *fixture {
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper)
stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper)
slashingModule := slashing.NewAppModule(cdc, slashingKeeper, accountKeeper, bankKeeper, stakingKeeper, cdc.InterfaceRegistry())
evidenceModule := evidence.NewAppModule(*evidenceKeeper)
evidenceModule := evidence.NewAppModule(cdc, *evidenceKeeper)

integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc,
encodingCfg.InterfaceRegistry.SigningContext().AddressCodec(),
Expand Down
31 changes: 17 additions & 14 deletions tests/integration/gov/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,23 +204,26 @@ func TestImportExportQueues_ErrorUnconsistentState(t *testing.T) {
suite := createTestSuite(t)
app := suite.app
ctx := app.BaseApp.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),
),
},

params := v1.DefaultParams()
err := 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),
),
},
},
})
},
Params: &params,
})
gov.InitGenesis(ctx, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, v1.DefaultGenesisState())
require.Error(t, err)
err = gov.InitGenesis(ctx, suite.AccountKeeper, suite.BankKeeper, suite.GovKeeper, v1.DefaultGenesisState())
require.NoError(t, err)
genState, err := gov.ExportGenesis(ctx, suite.GovKeeper)
require.NoError(t, err)
require.Equal(t, genState, v1.DefaultGenesisState())
Expand Down
4 changes: 3 additions & 1 deletion testutil/integration/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ func NewIntegrationApp(
bApp.SetInitChainer(func(ctx sdk.Context, _ *cmtabcitypes.RequestInitChain) (*cmtabcitypes.ResponseInitChain, error) {
for _, mod := range modules {
if m, ok := mod.(module.HasGenesis); ok {
m.InitGenesis(ctx, appCodec, m.DefaultGenesis(appCodec))
if err := m.InitGenesis(ctx, m.DefaultGenesis()); err != nil {
return nil, err
}
}
}

Expand Down
Loading

0 comments on commit d2e4096

Please sign in to comment.