diff --git a/CHANGELOG.md b/CHANGELOG.md index 782fd7da76ac..11ffada70624 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/feegrant) [\#11813](https://github.com/cosmos/cosmos-sdk/pull/11813) Fix pagination total count in `AllowancesByGranter` query. * (errors) [\#12002](https://github.com/cosmos/cosmos-sdk/pull/12002) Removed 'redacted' error message from defaultErrEncoder. * (ante) [#12017](https://github.com/cosmos/cosmos-sdk/pull/12017) Index ante events for failed tx (backport #12013). +* [#12153](https://github.com/cosmos/cosmos-sdk/pull/12153) Add a new `NewSimulationManagerFromAppModules` constructor, to simplify simulation wiring. ### Bug Fixes diff --git a/simapp/app.go b/simapp/app.go index 2890c18c4fd0..fa00c5c65b65 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -529,28 +529,9 @@ func NewSimApp( // NOTE: this is not required apps that don't use the simulator for fuzz testing // transactions overrideModules := map[string]module.AppModuleSimulation{ - authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AuthKeeper, app.AccountsKeeper, authsims.RandomGenesisAccounts, nil), - } - app.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules) - - // create, start, and load the unordered tx manager - utxDataDir := filepath.Join(homePath, "data") - app.UnorderedTxManager = unorderedtx.NewManager(utxDataDir) - app.UnorderedTxManager.Start() - - if err := app.UnorderedTxManager.OnInit(); err != nil { - panic(fmt.Errorf("failed to initialize unordered tx manager: %w", err)) - } - - // register custom snapshot extensions (if any) - if manager := app.SnapshotManager(); manager != nil { - err := manager.RegisterExtensions( - unorderedtx.NewSnapshotter(app.UnorderedTxManager), - ) - if err != nil { - panic(fmt.Errorf("failed to register snapshot extension: %w", err)) - } + authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts), } + app.sm = module.NewSimulationManagerFromAppModules(app.mm.Modules, overrideModules) app.sm.RegisterStoreDecoders() diff --git a/types/module/simulation.go b/types/module/simulation.go index 57e31171b5bd..93045a651138 100644 --- a/types/module/simulation.go +++ b/types/module/simulation.go @@ -92,7 +92,38 @@ func NewSimulationManagerFromAppModules(modules map[string]appmodule.AppModule, return NewSimulationManager(simModules...) } -// Deprecated: Use GetProposalMsgs instead. +// NewSimulationManagerFromAppModules creates a new SimulationManager object. +// +// First it sets any SimulationModule provided by overrideModules, and ignores any AppModule +// with the same moduleName. +// Then it attempts to cast every provided AppModule into an AppModuleSimulation. +// If the cast succeeds, its included, otherwise it is excluded. +func NewSimulationManagerFromAppModules(modules map[string]AppModule, overrideModules map[string]AppModuleSimulation) *SimulationManager { + simModules := []AppModuleSimulation{} + appModuleNamesSorted := make([]string, 0, len(modules)) + for moduleName := range modules { + appModuleNamesSorted = append(appModuleNamesSorted, moduleName) + } + + sort.Strings(appModuleNamesSorted) + + for _, moduleName := range appModuleNamesSorted { + // for every module, see if we override it. If so, use override. + // Else, if we can cast the app module into a simulation module add it. + // otherwise no simulation module. + if simModule, ok := overrideModules[moduleName]; ok { + simModules = append(simModules, simModule) + } else { + appModule := modules[moduleName] + if simModule, ok := appModule.(AppModuleSimulation); ok { + simModules = append(simModules, simModule) + } + // cannot cast, so we continue + } + } + return NewSimulationManager(simModules...) +} + // GetProposalContents returns each module's proposal content generator function // with their default operation weight and key. func (sm *SimulationManager) GetProposalContents(simState SimulationState) []simulation.WeightedProposalContent {