forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge PR cosmos#4471: Migrate genesis cmd
- Loading branch information
1 parent
4e86810
commit 00f753d
Showing
12 changed files
with
1,353 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#4409 Implement a command that migrates exported state from one version to the next. | ||
The `migrate` command currently supports migrating from v0.34 to v0.36 by implementing | ||
necessary types for both versions. |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package cli | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/tendermint/tendermint/types" | ||
|
||
"github.com/cosmos/cosmos-sdk/codec" | ||
"github.com/cosmos/cosmos-sdk/server" | ||
"github.com/cosmos/cosmos-sdk/version" | ||
extypes "github.com/cosmos/cosmos-sdk/x/genutil" | ||
"github.com/cosmos/cosmos-sdk/x/genutil/legacy/v036" | ||
) | ||
|
||
var migrationMap = extypes.MigrationMap{ | ||
"v0.36": v036.Migrate, | ||
} | ||
|
||
const ( | ||
flagGenesisTime = "genesis-time" | ||
flagChainId = "chain-id" | ||
) | ||
|
||
func MigrateGenesisCmd(_ *server.Context, cdc *codec.Codec) *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "migrate [target-version] [genesis-file]", | ||
Short: "Migrate genesis to a specified target version", | ||
Long: fmt.Sprintf(`Migrate the source genesis into the target version and print to STDOUT. | ||
Example: | ||
$ %s migrate v0.36 /path/to/genesis.json --chain-id=cosmoshub-3 --genesis-time=2019-04-22T17:00:00Z | ||
`, version.ServerName), | ||
Args: cobra.ExactArgs(2), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
target := args[0] | ||
importGenesis := args[1] | ||
|
||
genDoc, err := types.GenesisDocFromFile(importGenesis) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var initialState extypes.AppMap | ||
cdc.MustUnmarshalJSON(genDoc.AppState, &initialState) | ||
|
||
if migrationMap[target] == nil { | ||
return fmt.Errorf("unknown migration function version: %s", target) | ||
} | ||
|
||
newGenState := migrationMap[target](initialState, cdc) | ||
genDoc.AppState = cdc.MustMarshalJSON(newGenState) | ||
|
||
genesisTime := cmd.Flag(flagGenesisTime).Value.String() | ||
if genesisTime != "" { | ||
var t time.Time | ||
|
||
err := t.UnmarshalText([]byte(genesisTime)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
genDoc.GenesisTime = t | ||
} | ||
|
||
chainId := cmd.Flag(flagChainId).Value.String() | ||
if chainId != "" { | ||
genDoc.ChainID = chainId | ||
} | ||
|
||
out, err := cdc.MarshalJSONIndent(genDoc, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(string(out)) | ||
return nil | ||
|
||
}, | ||
} | ||
|
||
cmd.Flags().String(flagGenesisTime, "", "Override genesis_time with this flag") | ||
cmd.Flags().String(flagChainId, "", "Override chain_id with this flag") | ||
|
||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package cli | ||
|
||
import ( | ||
"io/ioutil" | ||
"path" | ||
"testing" | ||
|
||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"github.com/stretchr/testify/require" | ||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" | ||
"github.com/tendermint/tendermint/libs/cli" | ||
"github.com/tendermint/tendermint/libs/log" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/server" | ||
"github.com/cosmos/cosmos-sdk/tests" | ||
) | ||
|
||
func setupCmd(genesisTime string, chainId string) *cobra.Command { | ||
c := &cobra.Command{ | ||
Use: "c", | ||
Args: cobra.ArbitraryArgs, | ||
Run: func(_ *cobra.Command, args []string) {}, | ||
} | ||
|
||
c.Flags().String(flagGenesisTime, genesisTime, "") | ||
c.Flags().String(flagChainId, chainId, "") | ||
|
||
return c | ||
} | ||
|
||
func TestMigrateGenesis(t *testing.T) { | ||
home, cleanup := tests.NewTestCaseDir(t) | ||
viper.Set(cli.HomeFlag, home) | ||
viper.Set(client.FlagName, "moniker") | ||
logger := log.NewNopLogger() | ||
cfg, err := tcmd.ParseConfig() | ||
require.Nil(t, err) | ||
ctx := server.NewContext(cfg, logger) | ||
cdc := makeCodec() | ||
|
||
genesisPath := path.Join(home, "genesis.json") | ||
target := "v0.36" | ||
|
||
defer cleanup() | ||
|
||
// Reject if we dont' have the right parameters or genesis does not exists | ||
require.Error(t, MigrateGenesisCmd(ctx, cdc).RunE(nil, []string{target, genesisPath})) | ||
|
||
// Noop migration with minimal genesis | ||
emptyGenesis := []byte(`{"chain_id":"test","app_state":{}}`) | ||
err = ioutil.WriteFile(genesisPath, emptyGenesis, 0644) | ||
require.Nil(t, err) | ||
cmd := setupCmd("", "test2") | ||
require.NoError(t, MigrateGenesisCmd(ctx, cdc).RunE(cmd, []string{target, genesisPath})) | ||
// Every migration function shuold tests its own module separately | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package v036 | ||
|
||
import ( | ||
"github.com/cosmos/cosmos-sdk/codec" | ||
"github.com/cosmos/cosmos-sdk/x/genutil" | ||
v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v034" | ||
v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" | ||
) | ||
|
||
// Migrate migrates exported state from v0.34 to a v0.36 genesis state. | ||
func Migrate(appState genutil.AppMap, cdc *codec.Codec) genutil.AppMap { | ||
v034Codec := codec.New() | ||
codec.RegisterCrypto(v034Codec) | ||
v036Codec := codec.New() | ||
codec.RegisterCrypto(v036Codec) | ||
|
||
if appState[v034gov.ModuleName] != nil { | ||
var govState v034gov.GenesisState | ||
v034gov.RegisterCodec(v034Codec) | ||
v034Codec.MustUnmarshalJSON(appState[v034gov.ModuleName], &govState) | ||
v036gov.RegisterCodec(v036Codec) | ||
delete(appState, v034gov.ModuleName) // Drop old key, in case it changed name | ||
appState[v036gov.ModuleName] = v036Codec.MustMarshalJSON(v036gov.MigrateGovernance(govState)) | ||
} | ||
return appState | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package v036 | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"github.com/tendermint/go-amino" | ||
|
||
"github.com/cosmos/cosmos-sdk/x/genutil" | ||
) | ||
|
||
var basic034Gov = []byte(` | ||
{ | ||
"starting_proposal_id": "2", | ||
"deposits": [ | ||
{ | ||
"proposal_id": "1", | ||
"deposit": { | ||
"depositor": "cosmos1grgelyng2v6v3t8z87wu3sxgt9m5s03xvslewd", | ||
"proposal_id": "1", | ||
"amount": [ | ||
{ | ||
"denom": "uatom", | ||
"amount": "512000000" | ||
} | ||
] | ||
} | ||
} | ||
], | ||
"votes" : [ | ||
{ | ||
"proposal_id": "1", | ||
"vote": { | ||
"voter": "cosmos1lktjhnzkpkz3ehrg8psvmwhafg56kfss5597tg", | ||
"proposal_id": "1", | ||
"option": "Yes" | ||
} | ||
} | ||
], | ||
"proposals": [ | ||
{ | ||
"proposal_content": { | ||
"type": "gov/TextProposal", | ||
"value": { | ||
"title": "test", | ||
"description": "test" | ||
} | ||
}, | ||
"proposal_id": "1", | ||
"proposal_status": "Passed", | ||
"final_tally_result": { | ||
"yes": "1", | ||
"abstain": "0", | ||
"no": "0", | ||
"no_with_veto": "0" | ||
}, | ||
"submit_time": "2019-05-03T21:08:25.443199036Z", | ||
"deposit_end_time": "2019-05-17T21:08:25.443199036Z", | ||
"total_deposit": [ | ||
{ | ||
"denom": "uatom", | ||
"amount": "512000000" | ||
} | ||
], | ||
"voting_start_time": "2019-05-04T16:02:33.24680295Z", | ||
"voting_end_time": "2019-05-18T16:02:33.24680295Z" | ||
} | ||
], | ||
"deposit_params": { | ||
"min_deposit": [ | ||
{ | ||
"denom": "uatom", | ||
"amount": "512000000" | ||
} | ||
], | ||
"max_deposit_period": "1209600000000000" | ||
}, | ||
"voting_params": { | ||
"voting_period": "1209600000000000" | ||
}, | ||
"tally_params": { | ||
"quorum": "0.400000000000000000", | ||
"threshold": "0.500000000000000000", | ||
"veto": "0.334000000000000000" | ||
} | ||
} | ||
`) | ||
|
||
func TestDummyGenesis(t *testing.T) { | ||
genesisDummy := genutil.AppMap{ | ||
"foo": {}, | ||
"bar": []byte(`{"custom": "module"}`), | ||
} | ||
cdc := amino.NewCodec() | ||
migratedDummy := Migrate(genesisDummy, cdc) | ||
|
||
// We should not touch custom modules in the map | ||
require.Equal(t, genesisDummy["foo"], migratedDummy["foo"]) | ||
require.Equal(t, genesisDummy["bar"], migratedDummy["bar"]) | ||
} | ||
|
||
func TestGovGenesis(t *testing.T) { | ||
genesis := genutil.AppMap{ | ||
"gov": basic034Gov, | ||
} | ||
cdc := amino.NewCodec() | ||
|
||
require.NotPanics(t, func() { Migrate(genesis, cdc) }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package genutil | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"github.com/cosmos/cosmos-sdk/codec" | ||
) | ||
|
||
type ( | ||
// AppMap map modules names with their json raw representation | ||
AppMap map[string]json.RawMessage | ||
// MigrationCallback converts a genesis map from the previous version to the targeted one | ||
MigrationCallback func(AppMap, *codec.Codec) AppMap | ||
// MigrationMap defines a mapping from a version to a MigrationCallback | ||
MigrationMap map[string]MigrationCallback | ||
) |
Oops, something went wrong.