From 6855d0f9223387f8ee4f9c947dd9d4b3317b0ffe Mon Sep 17 00:00:00 2001 From: Julien Robert Date: Sat, 12 Aug 2023 19:17:26 +0200 Subject: [PATCH] fix(types): check mm endblocker assertion for core api and abci (#17371) --- CHANGELOG.md | 2 ++ docs/docs/building-modules/01-module-manager.md | 6 +++--- types/module/module.go | 14 +++++++++----- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aad2c4790e9..d5ee39f97e6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking Changes +* (types) `module.EndBlockAppModule` has been replaced by Core API `appmodule.HasBeginBlocker`. +* (types) `module.BeginBlockAppModule` has been replaced by Core API `appmodule.HasEndBlocker` or `module.HasABCIEndBlock` when needing validator updates. * (types) [#17358](https://github.com/cosmos/cosmos-sdk/pull/17358) Remove deprecated `sdk.Handler`, use `baseapp.MsgServiceHandler` instead. * (x/slashing) [17044](https://github.com/cosmos/cosmos-sdk/pull/17044) Use collections for `AddrPubkeyRelation`: * remove from `types`: `AddrPubkeyRelationKey` diff --git a/docs/docs/building-modules/01-module-manager.md b/docs/docs/building-modules/01-module-manager.md index b1e88d59639d..bfe977b0b6b5 100644 --- a/docs/docs/building-modules/01-module-manager.md +++ b/docs/docs/building-modules/01-module-manager.md @@ -266,9 +266,9 @@ The module manager is used throughout the application whenever an action on a co * `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. * `RunMigrationBeginBlock(ctx sdk.Context) (bool, error)`: At the beginning of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./05-beginblock-endblock.md) function of the upgrade module implementing the `HasBeginBlocker` interface. The function returns a boolean value indicating whether the migration was executed or not and an error if fails. -* `BeginBlock(ctx context.Context) error`: At the beginning of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./05-beginblock-endblock.md) function of each non-upgrade modules implementing the `HasBeginBlocker` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from non-upgrade modules. -* `EndBlock(ctx context.Context) error`: At the end of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./05-beginblock-endblock.md) function of each modules implementing the `HasEndBlocker` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/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`](../core/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./05-beginblock-endblock.md) function of each modules implementing the `HasEndBlocker` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/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). +* `BeginBlock(ctx context.Context) error`: At the beginning of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./05-beginblock-endblock.md) function of each non-upgrade modules implementing the `appmodule.HasBeginBlocker` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from non-upgrade modules. +* `EndBlock(ctx context.Context) error`: At the end of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./05-beginblock-endblock.md) function of each modules implementing the `appmodule.HasEndBlocker` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/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`](../core/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./05-beginblock-endblock.md) function of each modules implementing the `module.HasABCIEndblock` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/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). * `Precommit(ctx context.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately before the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `Precommit` function of each modules implementing the `HasPrecommit` interface, in the order defined in `OrderPrecommiters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the newly committed block's [`finalizeblockstate`](../core/00-baseapp.md#state-updates). * `PrepareCheckState(ctx context.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `PrepareCheckState` function of each module implementing the `HasPrepareCheckState` interface, in the order defined in `OrderPrepareCheckStaters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the next block's [`checkState`](../core/00-baseapp.md#state-updates). Writes to this state will be present in the [`checkState`](../core/00-baseapp.md#state-updates) of the next block, and therefore this method can be used to prepare the `checkState` for the next block. diff --git a/types/module/module.go b/types/module/module.go index f985d0d73792..2eacd3b80455 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -373,8 +373,12 @@ func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames, func(moduleName string) bool { module := m.Modules[moduleName] - _, hasEndBlock := module.(HasABCIEndblock) - return !hasEndBlock + if _, hasEndBlock := module.(appmodule.HasEndBlocker); hasEndBlock { + return !hasEndBlock + } + + _, hasABCIEndBlock := module.(HasABCIEndblock) + return !hasABCIEndBlock }) m.OrderEndBlockers = moduleNames } @@ -565,9 +569,9 @@ func (m *Manager) checkModulesExists(moduleName []string) error { return nil } -// assertNoForgottenModules checks that we didn't forget any modules in the -// SetOrder* functions. -// `pass` is a closure which allows one to omit modules from `moduleNames`. If you provide non-nil `pass` and it returns true, the module would not be subject of the assertion. +// assertNoForgottenModules checks that we didn't forget any modules in the SetOrder* functions. +// `pass` is a closure which allows one to omit modules from `moduleNames`. +// If you provide non-nil `pass` and it returns true, the module would not be subject of the assertion. func (m *Manager) assertNoForgottenModules(setOrderFnName string, moduleNames []string, pass func(moduleName string) bool) { ms := make(map[string]bool) for _, m := range moduleNames {