github.com/cosmos/cosmos-sdk@v0.50.10/x/genutil/client/cli/migrate.go (about) 1 package cli 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "sort" 7 "strings" 8 "time" 9 10 "github.com/spf13/cobra" 11 "golang.org/x/exp/maps" 12 13 "github.com/cosmos/cosmos-sdk/client" 14 "github.com/cosmos/cosmos-sdk/client/flags" 15 "github.com/cosmos/cosmos-sdk/version" 16 v043 "github.com/cosmos/cosmos-sdk/x/genutil/migrations/v043" 17 v046 "github.com/cosmos/cosmos-sdk/x/genutil/migrations/v046" 18 v047 "github.com/cosmos/cosmos-sdk/x/genutil/migrations/v047" 19 "github.com/cosmos/cosmos-sdk/x/genutil/types" 20 ) 21 22 const flagGenesisTime = "genesis-time" 23 24 // MigrationMap is a map of SDK versions to their respective genesis migration functions. 25 var MigrationMap = types.MigrationMap{ 26 "v0.43": v043.Migrate, // NOTE: v0.43, v0.44 and v0.45 are genesis compatible. 27 "v0.46": v046.Migrate, 28 "v0.47": v047.Migrate, 29 } 30 31 // MigrateGenesisCmd returns a command to execute genesis state migration. 32 // Applications should pass their own migration map to this function. 33 // When the application migration includes a SDK migration, the Cosmos SDK migration function should as well be called. 34 func MigrateGenesisCmd(migrations types.MigrationMap) *cobra.Command { 35 cmd := &cobra.Command{ 36 Use: "migrate [target-version] [genesis-file]", 37 Short: "Migrate genesis to a specified target version", 38 Long: "Migrate the source genesis into the target version and print to STDOUT", 39 Example: fmt.Sprintf("%s migrate v0.47 /path/to/genesis.json --chain-id=cosmoshub-3 --genesis-time=2019-04-22T17:00:00Z", version.AppName), 40 Args: cobra.ExactArgs(2), 41 RunE: func(cmd *cobra.Command, args []string) error { 42 return MigrateHandler(cmd, args, migrations) 43 }, 44 } 45 46 cmd.Flags().String(flagGenesisTime, "", "Override genesis_time with this flag") 47 cmd.Flags().String(flags.FlagChainID, "", "Override chain_id with this flag") 48 cmd.Flags().String(flags.FlagOutputDocument, "", "Exported state is written to the given file instead of STDOUT") 49 50 return cmd 51 } 52 53 // MigrateHandler handles the migration command with a migration map as input, 54 // returning an error upon failure. 55 func MigrateHandler(cmd *cobra.Command, args []string, migrations types.MigrationMap) error { 56 clientCtx := client.GetClientContextFromCmd(cmd) 57 58 target := args[0] 59 migrationFunc, ok := migrations[target] 60 if !ok || migrationFunc == nil { 61 versions := maps.Keys(migrations) 62 sort.Strings(versions) 63 return fmt.Errorf("unknown migration function for version: %s (supported versions %s)", target, strings.Join(versions, ", ")) 64 } 65 66 importGenesis := args[1] 67 appGenesis, err := types.AppGenesisFromFile(importGenesis) 68 if err != nil { 69 return err 70 } 71 72 if err := appGenesis.ValidateAndComplete(); err != nil { 73 return fmt.Errorf("make sure that you have correctly migrated all CometBFT consensus params. Refer the UPGRADING.md (%s): %w", chainUpgradeGuide, err) 74 } 75 76 // Since some default values are valid values, we just print to 77 // make sure the user didn't forget to update these values. 78 if appGenesis.Consensus.Params.Evidence.MaxBytes == 0 { 79 fmt.Printf("Warning: consensus.params.evidence.max_bytes is set to 0. If this is"+ 80 " deliberate, feel free to ignore this warning. If not, please have a look at the chain"+ 81 " upgrade guide at %s.\n", chainUpgradeGuide) 82 } 83 84 var initialState types.AppMap 85 if err := json.Unmarshal(appGenesis.AppState, &initialState); err != nil { 86 return fmt.Errorf("failed to JSON unmarshal initial genesis state: %w", err) 87 } 88 89 newGenState, err := migrationFunc(initialState, clientCtx) 90 if err != nil { 91 return fmt.Errorf("failed to migrate genesis state: %w", err) 92 } 93 94 appGenesis.AppState, err = json.Marshal(newGenState) 95 if err != nil { 96 return fmt.Errorf("failed to JSON marshal migrated genesis state: %w", err) 97 } 98 99 genesisTime, _ := cmd.Flags().GetString(flagGenesisTime) 100 if genesisTime != "" { 101 var t time.Time 102 103 err := t.UnmarshalText([]byte(genesisTime)) 104 if err != nil { 105 return fmt.Errorf("failed to unmarshal genesis time: %w", err) 106 } 107 108 appGenesis.GenesisTime = t 109 } 110 111 chainID, _ := cmd.Flags().GetString(flags.FlagChainID) 112 if chainID != "" { 113 appGenesis.ChainID = chainID 114 } 115 116 bz, err := json.Marshal(appGenesis) 117 if err != nil { 118 return fmt.Errorf("failed to marshal app genesis: %w", err) 119 } 120 121 outputDocument, _ := cmd.Flags().GetString(flags.FlagOutputDocument) 122 if outputDocument == "" { 123 cmd.Println(string(bz)) 124 return nil 125 } 126 127 if err = appGenesis.SaveAs(outputDocument); err != nil { 128 return err 129 } 130 131 return nil 132 }