github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/genutil/client/cli/migrate.go (about)

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"time"
     7  
     8  	"github.com/fibonacci-chain/fbc/libs/tendermint/types"
     9  	"github.com/pkg/errors"
    10  	"github.com/spf13/cobra"
    11  
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    13  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server"
    14  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    16  	extypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/genutil"
    17  	v036 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/genutil/legacy/v0_36"
    18  	v038 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/genutil/legacy/v0_38"
    19  	v039 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/genutil/legacy/v0_39"
    20  )
    21  
    22  const (
    23  	flagGenesisTime = "genesis-time"
    24  	flagChainID     = "chain-id"
    25  )
    26  
    27  // Allow applications to extend and modify the migration process.
    28  //
    29  // Ref: https://github.com/cosmos/cosmos-sdk/issues/5041
    30  var migrationMap = extypes.MigrationMap{
    31  	"v0.36": v036.Migrate,
    32  	"v0.38": v038.Migrate, // NOTE: v0.37 and v0.38 are genesis compatible
    33  	"v0.39": v039.Migrate,
    34  }
    35  
    36  // GetMigrationCallback returns a MigrationCallback for a given version.
    37  func GetMigrationCallback(version string) extypes.MigrationCallback {
    38  	return migrationMap[version]
    39  }
    40  
    41  // GetMigrationVersions get all migration version in a sorted slice.
    42  func GetMigrationVersions() []string {
    43  	versions := make([]string, len(migrationMap))
    44  
    45  	var i int
    46  	for version := range migrationMap {
    47  		versions[i] = version
    48  		i++
    49  	}
    50  
    51  	sort.Strings(versions)
    52  	return versions
    53  }
    54  
    55  // MigrateGenesisCmd returns a command to execute genesis state migration.
    56  // nolint: funlen
    57  func MigrateGenesisCmd(_ *server.Context, cdc *codec.Codec) *cobra.Command {
    58  	cmd := &cobra.Command{
    59  		Use:   "migrate [target-version] [genesis-file]",
    60  		Short: "Migrate genesis to a specified target version",
    61  		Long: fmt.Sprintf(`Migrate the source genesis into the target version and print to STDOUT.
    62  
    63  Example:
    64  $ %s migrate v0.36 /path/to/genesis.json --chain-id=cosmoshub-3 --genesis-time=2019-04-22T17:00:00Z
    65  `, version.ServerName),
    66  		Args: cobra.ExactArgs(2),
    67  		RunE: func(cmd *cobra.Command, args []string) error {
    68  			var err error
    69  
    70  			target := args[0]
    71  			importGenesis := args[1]
    72  
    73  			genDoc, err := types.GenesisDocFromFile(importGenesis)
    74  			if err != nil {
    75  				return errors.Wrapf(err, "failed to read genesis document from file %s", importGenesis)
    76  			}
    77  
    78  			var initialState extypes.AppMap
    79  			if err := cdc.UnmarshalJSON(genDoc.AppState, &initialState); err != nil {
    80  				return errors.Wrap(err, "failed to JSON unmarshal initial genesis state")
    81  			}
    82  
    83  			migrationFunc := GetMigrationCallback(target)
    84  			if migrationFunc == nil {
    85  				return fmt.Errorf("unknown migration function for version: %s", target)
    86  			}
    87  
    88  			// TODO: handler error from migrationFunc call
    89  			newGenState := migrationFunc(initialState)
    90  
    91  			genDoc.AppState, err = cdc.MarshalJSON(newGenState)
    92  			if err != nil {
    93  				return errors.Wrap(err, "failed to JSON marshal migrated genesis state")
    94  			}
    95  
    96  			genesisTime := cmd.Flag(flagGenesisTime).Value.String()
    97  			if genesisTime != "" {
    98  				var t time.Time
    99  
   100  				err := t.UnmarshalText([]byte(genesisTime))
   101  				if err != nil {
   102  					return errors.Wrap(err, "failed to unmarshal genesis time")
   103  				}
   104  
   105  				genDoc.GenesisTime = t
   106  			}
   107  
   108  			chainID := cmd.Flag(flagChainID).Value.String()
   109  			if chainID != "" {
   110  				genDoc.ChainID = chainID
   111  			}
   112  
   113  			bz, err := cdc.MarshalJSONIndent(genDoc, "", "  ")
   114  			if err != nil {
   115  				return errors.Wrap(err, "failed to marshal genesis doc")
   116  			}
   117  
   118  			sortedBz, err := sdk.SortJSON(bz)
   119  			if err != nil {
   120  				return errors.Wrap(err, "failed to sort JSON genesis doc")
   121  			}
   122  
   123  			cmd.Println(string(sortedBz))
   124  			return nil
   125  		},
   126  	}
   127  
   128  	cmd.Flags().String(flagGenesisTime, "", "override genesis_time with this flag")
   129  	cmd.Flags().String(flagChainID, "", "override chain_id with this flag")
   130  
   131  	return cmd
   132  }