github.com/Finschia/finschia-sdk@v0.48.1/x/genutil/client/cli/migrate.go (about)

     1  package cli
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"sort"
     7  	"time"
     8  
     9  	ocjson "github.com/Finschia/ostracon/libs/json"
    10  	"github.com/pkg/errors"
    11  	"github.com/spf13/cobra"
    12  
    13  	"github.com/Finschia/finschia-sdk/client"
    14  	"github.com/Finschia/finschia-sdk/client/flags"
    15  	sdk "github.com/Finschia/finschia-sdk/types"
    16  	"github.com/Finschia/finschia-sdk/version"
    17  	"github.com/Finschia/finschia-sdk/x/genutil/types"
    18  )
    19  
    20  const flagGenesisTime = "genesis-time"
    21  
    22  // Allow applications to extend and modify the migration process.
    23  //
    24  // Ref: https://github.com/cosmos/cosmos-sdk/issues/5041
    25  var migrationMap = types.MigrationMap{}
    26  
    27  // GetMigrationCallback returns a MigrationCallback for a given version.
    28  func GetMigrationCallback(version string) types.MigrationCallback {
    29  	return migrationMap[version]
    30  }
    31  
    32  // GetMigrationVersions get all migration version in a sorted slice.
    33  func GetMigrationVersions() []string {
    34  	versions := make([]string, len(migrationMap))
    35  
    36  	var i int
    37  
    38  	for version := range migrationMap {
    39  		versions[i] = version
    40  		i++
    41  	}
    42  
    43  	sort.Strings(versions)
    44  
    45  	return versions
    46  }
    47  
    48  // MigrateGenesisCmd returns a command to execute genesis state migration.
    49  func MigrateGenesisCmd() *cobra.Command {
    50  	cmd := &cobra.Command{
    51  		Use:   "migrate [target-version] [genesis-file]",
    52  		Short: "Migrate genesis to a specified target version",
    53  		Long: fmt.Sprintf(`Migrate the source genesis into the target version and print to STDOUT.
    54  
    55  Example:
    56  $ %s migrate v0.43 /path/to/genesis.json --chain-id=test-chain-1 --genesis-time=2021-11-08T14:00:00Z
    57  `, version.AppName),
    58  		Args: cobra.ExactArgs(2),
    59  		RunE: func(cmd *cobra.Command, args []string) error {
    60  			clientCtx := client.GetClientContextFromCmd(cmd)
    61  
    62  			var err error
    63  
    64  			target := args[0]
    65  			importGenesis := args[1]
    66  
    67  			genDoc, err := validateGenDoc(importGenesis)
    68  			if err != nil {
    69  				return err
    70  			}
    71  
    72  			// Since some default values are valid values, we just print to
    73  			// make sure the user didn't forget to update these values.
    74  			if genDoc.ConsensusParams.Evidence.MaxBytes == 0 {
    75  				fmt.Printf("Warning: consensus_params.evidence.max_bytes is set to 0. If this is"+
    76  					" deliberate, feel free to ignore this warning. If not, please have a look at the chain"+
    77  					" upgrade guide at %s.\n", chainUpgradeGuide)
    78  			}
    79  
    80  			var initialState types.AppMap
    81  			if err := json.Unmarshal(genDoc.AppState, &initialState); err != nil {
    82  				return errors.Wrap(err, "failed to JSON unmarshal initial genesis state")
    83  			}
    84  
    85  			migrationFunc := GetMigrationCallback(target)
    86  			if migrationFunc == nil {
    87  				return fmt.Errorf("unknown migration function for version: %s", target)
    88  			}
    89  
    90  			// TODO: handler error from migrationFunc call
    91  			newGenState := migrationFunc(initialState, clientCtx)
    92  
    93  			genDoc.AppState, err = json.Marshal(newGenState)
    94  			if err != nil {
    95  				return errors.Wrap(err, "failed to JSON marshal migrated genesis state")
    96  			}
    97  
    98  			genesisTime, _ := cmd.Flags().GetString(flagGenesisTime)
    99  			if genesisTime != "" {
   100  				var t time.Time
   101  
   102  				err := t.UnmarshalText([]byte(genesisTime))
   103  				if err != nil {
   104  					return errors.Wrap(err, "failed to unmarshal genesis time")
   105  				}
   106  
   107  				genDoc.GenesisTime = t
   108  			}
   109  
   110  			chainID, _ := cmd.Flags().GetString(flags.FlagChainID)
   111  			if chainID != "" {
   112  				genDoc.ChainID = chainID
   113  			}
   114  
   115  			bz, err := ocjson.Marshal(genDoc)
   116  			if err != nil {
   117  				return errors.Wrap(err, "failed to marshal genesis doc")
   118  			}
   119  
   120  			sortedBz, err := sdk.SortJSON(bz)
   121  			if err != nil {
   122  				return errors.Wrap(err, "failed to sort JSON genesis doc")
   123  			}
   124  
   125  			cmd.Println(string(sortedBz))
   126  			return nil
   127  		},
   128  	}
   129  
   130  	cmd.Flags().String(flagGenesisTime, "", "override genesis_time with this flag")
   131  	cmd.Flags().String(flags.FlagChainID, "", "override chain_id with this flag")
   132  
   133  	return cmd
   134  }