diff --git a/app/consumer/genesis.go b/app/consumer/genesis.go index 39b6edc149..dd2c53bb41 100644 --- a/app/consumer/genesis.go +++ b/app/consumer/genesis.go @@ -4,6 +4,9 @@ import ( "encoding/json" "fmt" "os" + "path/filepath" + "sort" + "strings" cmtjson "github.com/cometbft/cometbft/libs/json" "github.com/cosmos/cosmos-sdk/client" @@ -33,14 +36,29 @@ type ( TransformationMap map[string]TransformationCallback ) +// Migration of consumer genesis content as it is exported from a provider version v2 +// to a version readable by current consumer (version v3). func migrateFromV2(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) { oldConsumerGenesis := consumerTypes.GenesisState{} - oldConsumerGenesis.Validate() err := cmtjson.Unmarshal(jsonRaw, &oldConsumerGenesis) if err != nil { - return nil, err + return nil, fmt.Errorf("reading consumer genesis data failed: %s", err) } + // some sanity checks for v2 transformation + if len(oldConsumerGenesis.Provider.InitialValSet) > 0 { + return nil, fmt.Errorf("invalid source version. Unexpected element 'provider.initial_val_set'") + } + + if oldConsumerGenesis.Provider.ClientState != nil { + return nil, fmt.Errorf("invalid source version. Unexpected element 'provider.client_state'") + } + + if oldConsumerGenesis.Provider.ConsensusState != nil { + return nil, fmt.Errorf("invalid source version. Unexpected element 'provider.consensus_state'") + } + + // Note: version 2 of provider genesis data fills up deprecated fields newGenesis := types.ConsumerGenesisState{ Params: oldConsumerGenesis.Params, Provider: types.ProviderInfo{ @@ -54,6 +72,7 @@ func migrateFromV2(jsonRaw []byte, ctx client.Context) (json.RawMessage, error) return newJson, nil } +// Mapping of provider module version to related transformation function var transformationMap = TransformationMap{ "v2": migrateFromV2, } @@ -65,12 +84,11 @@ func TransformConsumerGenesis(cmd *cobra.Command, args []string, transformationM sourceVersion := args[0] sourceFile := args[1] - jsonRaw, err := os.ReadFile(sourceFile) + jsonRaw, err := os.ReadFile(filepath.Clean(sourceFile)) if err != nil { return err } - // TODO: content validation would be good transform, exists := transformationMap[sourceVersion] if !exists { return fmt.Errorf("error transforming consumer genesis content: Unsupported versions %s", sourceVersion) @@ -84,7 +102,7 @@ func TransformConsumerGenesis(cmd *cobra.Command, args []string, transformationM bz, err := cmtjson.Marshal(newConsumerGenesis) if err != nil { - return err + return fmt.Errorf("failed exporting new consumer genesis to JSON: %s", err) } sortedBz, err := sdk.SortJSON(bz) @@ -96,19 +114,33 @@ func TransformConsumerGenesis(cmd *cobra.Command, args []string, transformationM return nil } +// List of provider versions supported by consumer genesis transformations +func getSupportedTransformationVersions() []string { + var keys []string + for k, _ := range transformationMap { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + // NewDefaultGenesisState generates the default state for the application. func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState { return ModuleBasics.DefaultGenesis(cdc) } +// GetConsumerGenesisTransformCmd transforms Consumer Genesis JSON content exported from a specific +// provider version to a JSON format supported by this consumer version. +// Note: Provider module version can be received by querying 'module_versions' on the upgrade module. func GetConsumerGenesisTransformCmd() *cobra.Command { cmd := &cobra.Command{ Use: "transform [source-version] [genesis-file]", - Short: "Transform consumer genesis section from a specified provider version", - Long: fmt.Sprintf(`Transform the consumer genesis into the target version and print to STDOUT. + Short: "Transform CCV consumer genesis from a specified provider version", + Long: fmt.Sprintf(`Transform the consumer genesis file from a specified provider version to a version supported by this consumer. Result is printed to STDOUT. +Supported provider versions: %s Example: -$ %s transform v2.0.0 /path/to/consumer_genesis.json `, version.AppName), +$ %s transform v2 /path/to/consumer_genesis.json `, strings.Join(getSupportedTransformationVersions(), ", "), version.AppName), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { //return ModuleBasics.ValidateGenesis(cmd, args, migrationMap)