Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add --output-document flag to the export CLI command to allow writing genesis state to a file instead of STDOUT #13802

Merged
merged 1 commit into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#13651](https://github.com/cosmos/cosmos-sdk/pull/13651) Update `server/config/config.GetConfig` function.
* [#13781](https://github.com/cosmos/cosmos-sdk/pull/13781) Remove `client/keys.KeysCdc`.
* [#13803](https://github.com/cosmos/cosmos-sdk/pull/13803) Add an error log if iavl set operation failed.
* [#13802](https://github.com/cosmos/cosmos-sdk/pull/13802) Add --output-document flag to the export CLI command to allow writing genesis state to a file.

### State Machine Breaking

Expand Down
19 changes: 18 additions & 1 deletion server/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
FlagForZeroHeight = "for-zero-height"
FlagJailAllowedAddrs = "jail-allowed-addrs"
FlagModulesToExport = "modules-to-export"
FlagOutputDocument = "output-document"
)

// ExportCmd dumps app state to JSON.
Expand Down Expand Up @@ -67,6 +68,7 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com
forZeroHeight, _ := cmd.Flags().GetBool(FlagForZeroHeight)
jailAllowedAddrs, _ := cmd.Flags().GetStringSlice(FlagJailAllowedAddrs)
modulesToExport, _ := cmd.Flags().GetStringSlice(FlagModulesToExport)
outputDocument, _ := cmd.Flags().GetString(FlagOutputDocument)

Check warning

Code scanning / gosec

Returned error is not propagated up the stack.

Returned error is not propagated up the stack.

exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper, modulesToExport)
if err != nil {
Expand Down Expand Up @@ -106,7 +108,21 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com

cmd.SetOut(cmd.OutOrStdout())
cmd.SetErr(cmd.OutOrStderr())
cmd.Println(string(sdk.MustSortJSON(encoded)))
out := sdk.MustSortJSON(encoded)

if outputDocument == "" {
cmd.Println(string(out))
return nil
}

var exportedGenDoc tmtypes.GenesisDoc
if err = tmjson.Unmarshal(out, &exportedGenDoc); err != nil {
return err
}
if err = exportedGenDoc.SaveAs(outputDocument); err != nil {
return err
}

return nil
},
}
Expand All @@ -116,6 +132,7 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com
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")
cmd.Flags().String(FlagOutputDocument, "", "Exported state is written to the given file instead of STDOUT")

return cmd
}
41 changes: 41 additions & 0 deletions tests/e2e/server/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,47 @@ func TestExportCmd_Height(t *testing.T) {
}
}

func TestExportCmd_Output(t *testing.T) {
testCases := []struct {
name string
flags []string
outputDocument string
}{
{
"should export state to the specified file",
[]string{
fmt.Sprintf("--%s=%s", server.FlagOutputDocument, "foobar.json"),
},
"foobar.json",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
tempDir := t.TempDir()
_, ctx, _, cmd := setupApp(t, tempDir)

output := &bytes.Buffer{}
cmd.SetOut(output)
args := append(tc.flags, fmt.Sprintf("--%s=%s", flags.FlagHome, tempDir))
cmd.SetArgs(args)
require.NoError(t, cmd.ExecuteContext(ctx))

var exportedGenDoc tmtypes.GenesisDoc
f, err := os.ReadFile(tc.outputDocument)
if err != nil {
t.Fatalf("error reading exported genesis doc: %s", err)
}
require.NoError(t, tmjson.Unmarshal(f, &exportedGenDoc))

// Cleanup
if err = os.Remove(tc.outputDocument); err != nil {
t.Fatalf("error removing exported genesis doc: %s", err)
}
})
}
}

func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *tmtypes.GenesisDoc, *cobra.Command) {
t.Helper()

Expand Down