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(x/genutil): add better error messages for genesis validation #21701

Merged
merged 7 commits into from
Sep 13, 2024
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i

### Improvements

* (genutil) [#21701](https://github.com/cosmos/cosmos-sdk/pull/21701) Improved error messages for genesis validation.

### Bug Fixes

* (baseapp) [#21256](https://github.com/cosmos/cosmos-sdk/pull/21256) Halt height will not commit the block indicated, meaning that if halt-height is set to 10, only blocks until 9 (included) will be committed. This is to go back to the original behavior before a change was introduced in v0.50.0.
Expand Down
22 changes: 20 additions & 2 deletions x/genutil/client/cli/validate_genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package cli

import (
"encoding/json"
"errors"
"fmt"
"io"
"strings"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -32,7 +35,7 @@ func ValidateGenesisCmd(genMM genesisMM) *cobra.Command {

appGenesis, err := types.AppGenesisFromFile(genesis)
if err != nil {
return err
return enrichUnmarshalError(err)
}

if err := appGenesis.ValidateAndComplete(); err != nil {
Expand All @@ -41,12 +44,19 @@ func ValidateGenesisCmd(genMM genesisMM) *cobra.Command {

var genState map[string]json.RawMessage
if err = json.Unmarshal(appGenesis.AppState, &genState); err != nil {
if strings.Contains(err.Error(), "unexpected end of JSON input") {
return fmt.Errorf("app_state is missing in the genesis file: %s", err.Error())
}
return fmt.Errorf("error unmarshalling genesis doc %s: %w", genesis, err)
}

if genMM != nil {
if err = genMM.ValidateGenesis(genState); err != nil {
return fmt.Errorf("error validating genesis file %s: %w", genesis, err)
errStr := fmt.Sprintf("error validating genesis file %s: %s", genesis, err.Error())
if errors.Is(err, io.EOF) {
errStr = fmt.Sprintf("%s: section is missing in the app_state", errStr)
}
return fmt.Errorf("%s", errStr)
}
}

Expand All @@ -55,3 +65,11 @@ func ValidateGenesisCmd(genMM genesisMM) *cobra.Command {
},
}
}

func enrichUnmarshalError(err error) error {
var syntaxErr *json.SyntaxError
if errors.As(err, &syntaxErr) {
return fmt.Errorf("error at offset %d: %s", syntaxErr.Offset, syntaxErr.Error())
}
return err
}
46 changes: 38 additions & 8 deletions x/genutil/client/cli/validate_genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ import (

"github.com/stretchr/testify/require"

appmodulev2 "cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/x/staking"

"github.com/cosmos/cosmos-sdk/client"
codectestutil "github.com/cosmos/cosmos-sdk/codec/testutil"
"github.com/cosmos/cosmos-sdk/testutil"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/cosmos/cosmos-sdk/types/module"
testutilmod "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
)

Expand All @@ -32,15 +39,37 @@ var v037Exported = `{
}`

func TestValidateGenesis(t *testing.T) {
cdc := testutilmod.MakeTestEncodingConfig(codectestutil.CodecOptions{}, genutil.AppModule{}).Codec
testCases := []struct {
name string
genesis string
expErr bool
name string
genesis string
expErrStr string
genMM *module.Manager
}{
{
"invalid json",
`{"app_state": {x,}}`,
"error at offset 16: invalid character",
module.NewManagerFromMap(nil),
},
{
"invalid: missing module config in app_state",
func() string {
bz, err := os.ReadFile("../../types/testdata/app_genesis.json")
require.NoError(t, err)

return string(bz)
}(),
"section is missing in the app_state",
module.NewManagerFromMap(map[string]appmodulev2.AppModule{
"custommod": staking.NewAppModule(cdc, nil, nil, nil),
}),
},
{
"exported 0.37 genesis file",
v037Exported,
true,
"make sure that you have correctly migrated all CometBFT consensus params",
module.NewManagerFromMap(nil),
},
{
"valid 0.50 genesis file",
Expand All @@ -50,7 +79,8 @@ func TestValidateGenesis(t *testing.T) {

return string(bz)
}(),
false,
"",
module.NewManagerFromMap(nil),
},
}

Expand All @@ -59,9 +89,9 @@ func TestValidateGenesis(t *testing.T) {

t.Run(tc.name, func(t *testing.T) {
genesisFile := testutil.WriteToNewTempFile(t, tc.genesis)
_, err := clitestutil.ExecTestCLICmd(client.Context{}, cli.ValidateGenesisCmd(nil), []string{genesisFile.Name()})
if tc.expErr {
require.Contains(t, err.Error(), "make sure that you have correctly migrated all CometBFT consensus params")
_, err := clitestutil.ExecTestCLICmd(client.Context{}, cli.ValidateGenesisCmd(tc.genMM), []string{genesisFile.Name()})
if tc.expErrStr != "" {
require.Contains(t, err.Error(), tc.expErrStr)
} else {
require.NoError(t, err)
}
Expand Down
Loading