diff --git a/server/export.go b/server/export.go index 150add98e78d..2d5e83a8e20a 100644 --- a/server/export.go +++ b/server/export.go @@ -21,6 +21,7 @@ const ( FlagHeight = "height" FlagForZeroHeight = "for-zero-height" FlagJailAllowedAddrs = "jail-allowed-addrs" + FlagModulesToExport = "modules-to-export" ) // ExportCmd dumps app state to JSON. @@ -67,8 +68,9 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com height, _ := cmd.Flags().GetInt64(FlagHeight) forZeroHeight, _ := cmd.Flags().GetBool(FlagForZeroHeight) jailAllowedAddrs, _ := cmd.Flags().GetStringSlice(FlagJailAllowedAddrs) + modulesToExport, _ := cmd.Flags().GetStringSlice(FlagModulesToExport) - exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper) + exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper, modulesToExport) if err != nil { return fmt.Errorf("error exporting state: %v", err) } @@ -114,6 +116,7 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com cmd.Flags().Int64(FlagHeight, -1, "Export state from a particular height (-1 means latest height)") cmd.Flags().Bool(FlagForZeroHeight, false, "Export state to start at height zero (perform preproccessing)") cmd.Flags().StringSlice(FlagJailAllowedAddrs, []string{}, "Comma-separated list of operator addresses of jailed validators to unjail") + cmd.Flags().StringSlice(FlagModulesToExport, []string{}, "Comma-separated list of modules to export. If empty, will export all modules") return cmd } diff --git a/server/export_test.go b/server/export_test.go index 364a8475dd33..fa59b9b72c37 100644 --- a/server/export_test.go +++ b/server/export_test.go @@ -149,7 +149,7 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t app.Commit() cmd := server.ExportCmd( - func(_ log.Logger, _ dbm.DB, _ io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOptons types.AppOptions) (types.ExportedApp, error) { + func(_ log.Logger, _ dbm.DB, _ io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOptons types.AppOptions, modulesToExport []string) (types.ExportedApp, error) { encCfg := simapp.MakeTestEncodingConfig() var simApp *simapp.SimApp @@ -163,7 +163,7 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t simApp = simapp.NewSimApp(logger, db, nil, true, map[int64]bool{}, "", 0, encCfg, appOptons) } - return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) + return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) }, tempDir) ctx := context.Background() diff --git a/server/types/app.go b/server/types/app.go index 467f627c605f..a72fc759c975 100644 --- a/server/types/app.go +++ b/server/types/app.go @@ -75,5 +75,5 @@ type ( // AppExporter is a function that dumps all app state to // JSON-serializable structure and returns the current validator set. - AppExporter func(log.Logger, dbm.DB, io.Writer, int64, bool, []string, AppOptions) (ExportedApp, error) + AppExporter func(log.Logger, dbm.DB, io.Writer, int64, bool, []string, AppOptions, []string) (ExportedApp, error) ) diff --git a/simapp/app_test.go b/simapp/app_test.go index 435a7786cbe2..b1a8f3a251e5 100644 --- a/simapp/app_test.go +++ b/simapp/app_test.go @@ -64,7 +64,7 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) { // Making a new app object with the db, so that initchain hasn't been called app2 := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0, encCfg, EmptyAppOptions{}) - _, err = app2.ExportAppStateAndValidators(false, []string{}) + _, err = app2.ExportAppStateAndValidators(false, []string{}, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } diff --git a/simapp/export.go b/simapp/export.go index eb213aee2496..40c11bb69426 100644 --- a/simapp/export.go +++ b/simapp/export.go @@ -16,7 +16,7 @@ import ( // ExportAppStateAndValidators exports the state of the application for a genesis // file. func (app *SimApp) ExportAppStateAndValidators( - forZeroHeight bool, jailAllowedAddrs []string, + forZeroHeight bool, jailAllowedAddrs []string, modulesToExport []string, ) (servertypes.ExportedApp, error) { // as if they could withdraw from the start of the next block ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) @@ -29,7 +29,7 @@ func (app *SimApp) ExportAppStateAndValidators( app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) } - genState := app.mm.ExportGenesis(ctx, app.appCodec) + genState := app.mm.ExportGenesis(ctx, app.appCodec, modulesToExport) appState, err := json.MarshalIndent(genState, "", " ") if err != nil { return servertypes.ExportedApp{}, err diff --git a/simapp/sim_test.go b/simapp/sim_test.go index bab40cfbf6cd..94259d720321 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -132,7 +132,7 @@ func TestAppImportExport(t *testing.T) { fmt.Printf("exporting genesis...\n") - exported, err := app.ExportAppStateAndValidators(false, []string{}) + exported, err := app.ExportAppStateAndValidators(false, []string{}, []string{}) require.NoError(t, err) fmt.Printf("importing genesis...\n") @@ -233,7 +233,7 @@ func TestAppSimulationAfterImport(t *testing.T) { fmt.Printf("exporting genesis...\n") - exported, err := app.ExportAppStateAndValidators(true, []string{}) + exported, err := app.ExportAppStateAndValidators(true, []string{}, []string{}) require.NoError(t, err) fmt.Printf("importing genesis...\n") diff --git a/simapp/simd/cmd/root.go b/simapp/simd/cmd/root.go index 878b397d94a7..a10d7db612bd 100644 --- a/simapp/simd/cmd/root.go +++ b/simapp/simd/cmd/root.go @@ -283,7 +283,7 @@ func (a appCreator) newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, a // and exports state. func (a appCreator) appExport( logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, - appOpts servertypes.AppOptions) (servertypes.ExportedApp, error) { + appOpts servertypes.AppOptions, modulesToExport []string) (servertypes.ExportedApp, error) { var simApp *simapp.SimApp homePath, ok := appOpts.Get(flags.FlagHome).(string) @@ -301,5 +301,5 @@ func (a appCreator) appExport( simApp = simapp.NewSimApp(logger, db, traceStore, true, map[int64]bool{}, homePath, uint(1), a.encCfg, appOpts) } - return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) + return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport) } diff --git a/simapp/types.go b/simapp/types.go index 0e190af1bc93..559e88b51125 100644 --- a/simapp/types.go +++ b/simapp/types.go @@ -33,7 +33,7 @@ type App interface { // Exports the state of the application for a genesis file. ExportAppStateAndValidators( - forZeroHeight bool, jailAllowedAddrs []string, + forZeroHeight bool, jailAllowedAddrs []string, modulesToExport []string, ) (types.ExportedApp, error) // All the registered module account addreses. diff --git a/simapp/utils.go b/simapp/utils.go index a1614198b3dd..1a23fde190a4 100644 --- a/simapp/utils.go +++ b/simapp/utils.go @@ -79,7 +79,7 @@ func CheckExportSimulation( ) error { if config.ExportStatePath != "" { fmt.Println("exporting app state...") - exported, err := app.ExportAppStateAndValidators(false, nil) + exported, err := app.ExportAppStateAndValidators(false, nil, nil) if err != nil { return err } diff --git a/types/module/module.go b/types/module/module.go index 2c4205f5e1f8..08c40c58babe 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -338,10 +338,16 @@ func (m *Manager) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, genesisData } // ExportGenesis performs export genesis functionality for modules -func (m *Manager) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) map[string]json.RawMessage { +func (m *Manager) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string) map[string]json.RawMessage { genesisData := make(map[string]json.RawMessage) - for _, moduleName := range m.OrderExportGenesis { - genesisData[moduleName] = m.Modules[moduleName].ExportGenesis(ctx, cdc) + if len(modulesToExport) == 0 { + for _, moduleName := range m.OrderExportGenesis { + genesisData[moduleName] = m.Modules[moduleName].ExportGenesis(ctx, cdc) + } + } else { + for _, moduleName := range modulesToExport { + genesisData[moduleName] = m.Modules[moduleName].ExportGenesis(ctx, cdc) + } } return genesisData diff --git a/types/module/module_test.go b/types/module/module_test.go index 97d3a4b80726..82ca0deb45fe 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -239,7 +239,7 @@ func TestManager_ExportGenesis(t *testing.T) { want := map[string]json.RawMessage{ "module1": json.RawMessage(`{"key1": "value1"}`), "module2": json.RawMessage(`{"key2": "value2"}`)} - require.Equal(t, want, mm.ExportGenesis(ctx, cdc)) + require.Equal(t, want, mm.ExportGenesis(ctx, cdc, []string{})) } func TestManager_BeginBlock(t *testing.T) {