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