From c14a3a7cb2970766be574f2f26639420fa242b4b Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Fri, 9 Oct 2020 21:09:43 +0200 Subject: [PATCH] CLI `migrate` command follow-up: decode & re-encode (#7464) * Migrate staking module * Add gov legacy * Add comments * Add x/distrib * x/crisis * x/mint * Fix test * migrate x/genutil * Fix lint * Fix staking constants * Fix test * Update x/genutil/legacy/v040/migrate.go Co-authored-by: Marie Gauthier * Add migrate script instead of change BondStatus constants * Fix test * Fix another test Co-authored-by: Marie Gauthier Co-authored-by: Cory --- x/auth/legacy/v040/migrate.go | 1 + x/bank/legacy/v040/migrate.go | 1 + x/crisis/legacy/v039/types.go | 13 +++ x/crisis/legacy/v040/migrate.go | 16 +++ x/crisis/legacy/v040/types.go | 5 + x/distribution/legacy/v040/migrate.go | 108 +++++++++++++++++++ x/distribution/legacy/v040/types.go | 6 ++ x/evidence/legacy/v040/migrate.go | 58 +++++----- x/evidence/legacy/v040/migrate_test.go | 2 +- x/genaccounts/legacy/v036/migrate.go | 4 +- x/genutil/legacy/v039/types.go | 12 +++ x/genutil/legacy/v040/migrate.go | 105 +++++++++++++++++- x/genutil/legacy/v040/types.go | 5 + x/gov/legacy/v040/migrate.go | 141 +++++++++++++++++++++++++ x/gov/legacy/v040/types.go | 6 ++ x/mint/legacy/v039/types.go | 31 ++++++ x/mint/legacy/v040/migrate.go | 27 +++++ x/mint/legacy/v040/types.go | 5 + x/slashing/legacy/v040/migrate.go | 2 + x/staking/legacy/v034/types.go | 18 +++- x/staking/legacy/v036/types.go | 4 +- x/staking/legacy/v038/types.go | 22 +++- x/staking/legacy/v040/migrate.go | 137 ++++++++++++++++++++++++ x/staking/legacy/v040/migrate_test.go | 93 ++++++++++++++++ x/staking/legacy/v040/types.go | 5 + 25 files changed, 786 insertions(+), 41 deletions(-) create mode 100644 x/crisis/legacy/v039/types.go create mode 100644 x/crisis/legacy/v040/migrate.go create mode 100644 x/crisis/legacy/v040/types.go create mode 100644 x/distribution/legacy/v040/migrate.go create mode 100644 x/distribution/legacy/v040/types.go create mode 100644 x/genutil/legacy/v039/types.go create mode 100644 x/genutil/legacy/v040/types.go create mode 100644 x/gov/legacy/v040/migrate.go create mode 100644 x/gov/legacy/v040/types.go create mode 100644 x/mint/legacy/v039/types.go create mode 100644 x/mint/legacy/v040/migrate.go create mode 100644 x/mint/legacy/v040/types.go create mode 100644 x/staking/legacy/v040/migrate.go create mode 100644 x/staking/legacy/v040/migrate_test.go create mode 100644 x/staking/legacy/v040/types.go diff --git a/x/auth/legacy/v040/migrate.go b/x/auth/legacy/v040/migrate.go index 4fe663a48d48..3d335804a50d 100644 --- a/x/auth/legacy/v040/migrate.go +++ b/x/auth/legacy/v040/migrate.go @@ -47,6 +47,7 @@ func convertBaseVestingAccount(old *v039auth.BaseVestingAccount) *v040vesting.Ba // it to v0.40 x/auth genesis state. The migration includes: // // - Removing coins from account encoding. +// - Re-encode in v0.40 GenesisState. func Migrate(authGenState v039auth.GenesisState) *v040auth.GenesisState { // Convert v0.39 accounts to v0.40 ones. var v040Accounts = make([]v040auth.GenesisAccount, len(authGenState.Accounts)) diff --git a/x/bank/legacy/v040/migrate.go b/x/bank/legacy/v040/migrate.go index ba617427648e..ab2e596f57c8 100644 --- a/x/bank/legacy/v040/migrate.go +++ b/x/bank/legacy/v040/migrate.go @@ -12,6 +12,7 @@ import ( // // - Moving balances from x/auth to x/bank genesis state. // - Moving supply from x/supply to x/bank genesis state. +// - Re-encode in v0.40 GenesisState. func Migrate( bankGenState v038bank.GenesisState, authGenState v039auth.GenesisState, diff --git a/x/crisis/legacy/v039/types.go b/x/crisis/legacy/v039/types.go new file mode 100644 index 000000000000..44903e349118 --- /dev/null +++ b/x/crisis/legacy/v039/types.go @@ -0,0 +1,13 @@ +package v039 + +import sdk "github.com/cosmos/cosmos-sdk/types" + +const ( + ModuleName = "crisis" +) + +type ( + GenesisState struct { + ConstantFee sdk.Coin `json:"constant_fee" yaml:"constant_fee"` + } +) diff --git a/x/crisis/legacy/v040/migrate.go b/x/crisis/legacy/v040/migrate.go new file mode 100644 index 000000000000..eb97ba9ee645 --- /dev/null +++ b/x/crisis/legacy/v040/migrate.go @@ -0,0 +1,16 @@ +package v040 + +import ( + v039crisis "github.com/cosmos/cosmos-sdk/x/crisis/legacy/v039" + v040crisis "github.com/cosmos/cosmos-sdk/x/crisis/types" +) + +// Migrate accepts exported v0.39 x/crisis genesis state and +// migrates it to v0.40 x/crisis genesis state. The migration includes: +// +// - Re-encode in v0.40 GenesisState. +func Migrate(crisisGenState v039crisis.GenesisState) *v040crisis.GenesisState { + return &v040crisis.GenesisState{ + ConstantFee: crisisGenState.ConstantFee, + } +} diff --git a/x/crisis/legacy/v040/types.go b/x/crisis/legacy/v040/types.go new file mode 100644 index 000000000000..68c25e93eec1 --- /dev/null +++ b/x/crisis/legacy/v040/types.go @@ -0,0 +1,5 @@ +package v040 + +const ( + ModuleName = "crisis" +) diff --git a/x/distribution/legacy/v040/migrate.go b/x/distribution/legacy/v040/migrate.go new file mode 100644 index 000000000000..b0ba30bba861 --- /dev/null +++ b/x/distribution/legacy/v040/migrate.go @@ -0,0 +1,108 @@ +package v040 + +import ( + v038distribution "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v038" + v040distribution "github.com/cosmos/cosmos-sdk/x/distribution/types" +) + +// Migrate accepts exported x/distribution genesis state from v0.38 and migrates it +// to v0.40 x/distribution genesis state. The migration includes: +// +// - Convert addresses from bytes to bech32 strings. +// - Re-encode in v0.40 GenesisState. +func Migrate(oldDistributionState v038distribution.GenesisState) *v040distribution.GenesisState { + newDelegatorWithdrawInfos := make([]v040distribution.DelegatorWithdrawInfo, len(oldDistributionState.DelegatorWithdrawInfos)) + for i, oldDelegatorWithdrawInfo := range oldDistributionState.DelegatorWithdrawInfos { + newDelegatorWithdrawInfos[i] = v040distribution.DelegatorWithdrawInfo{ + DelegatorAddress: oldDelegatorWithdrawInfo.DelegatorAddress.String(), + WithdrawAddress: oldDelegatorWithdrawInfo.WithdrawAddress.String(), + } + } + + newValidatorOutstandingRewards := make([]v040distribution.ValidatorOutstandingRewardsRecord, len(oldDistributionState.OutstandingRewards)) + for i, oldValidatorOutstandingReward := range oldDistributionState.OutstandingRewards { + newValidatorOutstandingRewards[i] = v040distribution.ValidatorOutstandingRewardsRecord{ + ValidatorAddress: oldValidatorOutstandingReward.ValidatorAddress.String(), + OutstandingRewards: oldValidatorOutstandingReward.OutstandingRewards, + } + } + + newValidatorAccumulatedCommissions := make([]v040distribution.ValidatorAccumulatedCommissionRecord, len(oldDistributionState.ValidatorAccumulatedCommissions)) + for i, oldValidatorAccumulatedCommission := range oldDistributionState.ValidatorAccumulatedCommissions { + newValidatorAccumulatedCommissions[i] = v040distribution.ValidatorAccumulatedCommissionRecord{ + ValidatorAddress: oldValidatorAccumulatedCommission.ValidatorAddress.String(), + Accumulated: v040distribution.ValidatorAccumulatedCommission{ + Commission: oldValidatorAccumulatedCommission.Accumulated, + }, + } + } + + newValidatorHistoricalRewards := make([]v040distribution.ValidatorHistoricalRewardsRecord, len(oldDistributionState.ValidatorHistoricalRewards)) + for i, oldValidatorHistoricalReward := range oldDistributionState.ValidatorHistoricalRewards { + newValidatorHistoricalRewards[i] = v040distribution.ValidatorHistoricalRewardsRecord{ + ValidatorAddress: oldValidatorHistoricalReward.ValidatorAddress.String(), + Period: oldValidatorHistoricalReward.Period, + Rewards: v040distribution.ValidatorHistoricalRewards{ + CumulativeRewardRatio: oldValidatorHistoricalReward.Rewards.CumulativeRewardRatio, + ReferenceCount: uint32(oldValidatorHistoricalReward.Rewards.ReferenceCount), + }, + } + } + + newValidatorCurrentRewards := make([]v040distribution.ValidatorCurrentRewardsRecord, len(oldDistributionState.ValidatorCurrentRewards)) + for i, oldValidatorCurrentReward := range oldDistributionState.ValidatorCurrentRewards { + newValidatorCurrentRewards[i] = v040distribution.ValidatorCurrentRewardsRecord{ + ValidatorAddress: oldValidatorCurrentReward.ValidatorAddress.String(), + Rewards: v040distribution.ValidatorCurrentRewards{ + Rewards: oldValidatorCurrentReward.Rewards.Rewards, + Period: oldValidatorCurrentReward.Rewards.Period, + }, + } + } + + newDelegatorStartingInfos := make([]v040distribution.DelegatorStartingInfoRecord, len(oldDistributionState.DelegatorStartingInfos)) + for i, oldDelegatorStartingInfo := range oldDistributionState.DelegatorStartingInfos { + newDelegatorStartingInfos[i] = v040distribution.DelegatorStartingInfoRecord{ + DelegatorAddress: oldDelegatorStartingInfo.DelegatorAddress.String(), + ValidatorAddress: oldDelegatorStartingInfo.ValidatorAddress.String(), + StartingInfo: v040distribution.DelegatorStartingInfo{ + PreviousPeriod: oldDelegatorStartingInfo.StartingInfo.PreviousPeriod, + Stake: oldDelegatorStartingInfo.StartingInfo.Stake, + Height: oldDelegatorStartingInfo.StartingInfo.Height, + }, + } + } + + newValidatorSlashEvents := make([]v040distribution.ValidatorSlashEventRecord, len(oldDistributionState.ValidatorSlashEvents)) + for i, oldValidatorSlashEvent := range oldDistributionState.ValidatorSlashEvents { + newValidatorSlashEvents[i] = v040distribution.ValidatorSlashEventRecord{ + ValidatorAddress: oldValidatorSlashEvent.ValidatorAddress.String(), + Height: oldValidatorSlashEvent.Height, + Period: oldValidatorSlashEvent.Period, + ValidatorSlashEvent: v040distribution.ValidatorSlashEvent{ + ValidatorPeriod: oldValidatorSlashEvent.Event.ValidatorPeriod, + Fraction: oldValidatorSlashEvent.Event.Fraction, + }, + } + } + + return &v040distribution.GenesisState{ + Params: v040distribution.Params{ + CommunityTax: oldDistributionState.Params.CommunityTax, + BaseProposerReward: oldDistributionState.Params.BaseProposerReward, + BonusProposerReward: oldDistributionState.Params.BonusProposerReward, + WithdrawAddrEnabled: oldDistributionState.Params.WithdrawAddrEnabled, + }, + FeePool: v040distribution.FeePool{ + CommunityPool: oldDistributionState.FeePool.CommunityPool, + }, + DelegatorWithdrawInfos: newDelegatorWithdrawInfos, + PreviousProposer: oldDistributionState.PreviousProposer.String(), + OutstandingRewards: newValidatorOutstandingRewards, + ValidatorAccumulatedCommissions: newValidatorAccumulatedCommissions, + ValidatorHistoricalRewards: newValidatorHistoricalRewards, + ValidatorCurrentRewards: newValidatorCurrentRewards, + DelegatorStartingInfos: newDelegatorStartingInfos, + ValidatorSlashEvents: newValidatorSlashEvents, + } +} diff --git a/x/distribution/legacy/v040/types.go b/x/distribution/legacy/v040/types.go new file mode 100644 index 000000000000..aa502303803e --- /dev/null +++ b/x/distribution/legacy/v040/types.go @@ -0,0 +1,6 @@ +package v040 + +// Default parameter values +const ( + ModuleName = "distribution" +) diff --git a/x/evidence/legacy/v040/migrate.go b/x/evidence/legacy/v040/migrate.go index 7785cd12e791..f848130f345c 100644 --- a/x/evidence/legacy/v040/migrate.go +++ b/x/evidence/legacy/v040/migrate.go @@ -1,46 +1,48 @@ package v040 import ( - "github.com/cosmos/cosmos-sdk/client" + "fmt" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" v038evidence "github.com/cosmos/cosmos-sdk/x/evidence/legacy/v038" v040evidence "github.com/cosmos/cosmos-sdk/x/evidence/types" ) +func migrateEvidence(oldEvidence v038evidence.Evidence) *codectypes.Any { + switch oldEvidence := oldEvidence.(type) { + case v038evidence.Equivocation: + { + newEquivocation := &v040evidence.Equivocation{ + Height: oldEvidence.Height, + Time: oldEvidence.Time, + Power: oldEvidence.Power, + ConsensusAddress: oldEvidence.ConsensusAddress.String(), + } + any, err := codectypes.NewAnyWithValue(newEquivocation) + if err != nil { + panic(err) + } + + return any + } + default: + panic(fmt.Errorf("'%T' is not a valid evidence type", oldEvidence)) + } +} + // Migrate accepts exported v0.38 x/evidence genesis state and migrates it to // v0.40 x/evidence genesis state. The migration includes: // // - Removing the `Params` field. // - Converting Equivocations into Anys. -func Migrate(evidenceState v038evidence.GenesisState, _ client.Context) *v040evidence.GenesisState { - var newEquivocations = make([]v040evidence.Equivocation, len(evidenceState.Evidence)) - for i, evidence := range evidenceState.Evidence { - equivocation, ok := evidence.(v038evidence.Equivocation) - if !ok { - // There's only equivocation in 0.38. - continue - } - - newEquivocations[i] = v040evidence.Equivocation{ - Height: equivocation.Height, - Time: equivocation.Time, - Power: equivocation.Power, - ConsensusAddress: equivocation.ConsensusAddress.String(), - } - } - - // Then convert the equivocations into Any. - newEvidence := make([]*codectypes.Any, len(newEquivocations)) - for i := range newEquivocations { - any, err := codectypes.NewAnyWithValue(&newEquivocations[i]) - if err != nil { - panic(err) - } - - newEvidence[i] = any +// - Re-encode in v0.40 GenesisState. +func Migrate(evidenceState v038evidence.GenesisState) *v040evidence.GenesisState { + var newEvidences = make([]*codectypes.Any, len(evidenceState.Evidence)) + for i, oldEvidence := range evidenceState.Evidence { + newEvidences[i] = migrateEvidence(oldEvidence) } return &v040evidence.GenesisState{ - Evidence: newEvidence, + Evidence: newEvidences, } } diff --git a/x/evidence/legacy/v040/migrate_test.go b/x/evidence/legacy/v040/migrate_test.go index dcbe77e487ca..a9c23093f47f 100644 --- a/x/evidence/legacy/v040/migrate_test.go +++ b/x/evidence/legacy/v040/migrate_test.go @@ -31,7 +31,7 @@ func TestMigrate(t *testing.T) { }}, } - migrated := v040evidence.Migrate(evidenceGenState, clientCtx) + migrated := v040evidence.Migrate(evidenceGenState) expected := `{"evidence":[{"@type":"/cosmos.evidence.v1beta1.Equivocation","height":"20","time":"0001-01-01T00:00:00Z","power":"100","consensus_address":"cosmosvalcons1xxkueklal9vejv9unqu80w9vptyepfa99x2a3w"}]}` bz, err := clientCtx.JSONMarshaler.MarshalJSON(migrated) diff --git a/x/genaccounts/legacy/v036/migrate.go b/x/genaccounts/legacy/v036/migrate.go index 8dff3e454781..4da938aeaf79 100644 --- a/x/genaccounts/legacy/v036/migrate.go +++ b/x/genaccounts/legacy/v036/migrate.go @@ -90,10 +90,10 @@ func Migrate( // get staking module accounts coins for _, validator := range vals { switch validator.Status { - case sdk.Bonded: + case v034staking.Bonded: bondedAmt = bondedAmt.Add(validator.Tokens) - case sdk.Unbonding, sdk.Unbonded: + case v034staking.Unbonding, v034staking.Unbonded: notBondedAmt = notBondedAmt.Add(validator.Tokens) default: diff --git a/x/genutil/legacy/v039/types.go b/x/genutil/legacy/v039/types.go new file mode 100644 index 000000000000..12d082d1bc8a --- /dev/null +++ b/x/genutil/legacy/v039/types.go @@ -0,0 +1,12 @@ +package v039 + +import "encoding/json" + +const ( + ModuleName = "genutil" +) + +// GenesisState defines the raw genesis transaction in JSON +type GenesisState struct { + GenTxs []json.RawMessage `json:"gentxs" yaml:"gentxs"` +} diff --git a/x/genutil/legacy/v040/migrate.go b/x/genutil/legacy/v040/migrate.go index 121c24b0c167..c07bcdb74243 100644 --- a/x/genutil/legacy/v040/migrate.go +++ b/x/genutil/legacy/v040/migrate.go @@ -9,13 +9,30 @@ import ( v036supply "github.com/cosmos/cosmos-sdk/x/bank/legacy/v036" v038bank "github.com/cosmos/cosmos-sdk/x/bank/legacy/v038" v040bank "github.com/cosmos/cosmos-sdk/x/bank/legacy/v040" + v039crisis "github.com/cosmos/cosmos-sdk/x/crisis/legacy/v039" + v040crisis "github.com/cosmos/cosmos-sdk/x/crisis/legacy/v040" + v038distribution "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v038" + v040distribution "github.com/cosmos/cosmos-sdk/x/distribution/legacy/v040" v038evidence "github.com/cosmos/cosmos-sdk/x/evidence/legacy/v038" v040evidence "github.com/cosmos/cosmos-sdk/x/evidence/legacy/v040" + v039genutil "github.com/cosmos/cosmos-sdk/x/genutil/legacy/v039" "github.com/cosmos/cosmos-sdk/x/genutil/types" + v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" + v040gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v040" + v039mint "github.com/cosmos/cosmos-sdk/x/mint/legacy/v039" + v040mint "github.com/cosmos/cosmos-sdk/x/mint/legacy/v040" v039slashing "github.com/cosmos/cosmos-sdk/x/slashing/legacy/v039" v040slashing "github.com/cosmos/cosmos-sdk/x/slashing/legacy/v040" + v038staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v038" + v040staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v040" ) +func migrateGenutil(oldGenState v039genutil.GenesisState) *types.GenesisState { + return &types.GenesisState{ + GenTxs: oldGenState.GenTxs, + } +} + // Migrate migrates exported state from v0.39 to a v0.40 genesis state. func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { v039Codec := codec.NewLegacyAmino() @@ -62,6 +79,34 @@ func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { appState[v040auth.ModuleName] = v040Codec.MustMarshalJSON(v040auth.Migrate(authGenState)) } + // Migrate x/crisis. + if appState[v039crisis.ModuleName] != nil { + // unmarshal relative source genesis application state + var crisisGenState v039crisis.GenesisState + v039Codec.MustUnmarshalJSON(appState[v039crisis.ModuleName], &crisisGenState) + + // delete deprecated x/crisis genesis state + delete(appState, v039crisis.ModuleName) + + // Migrate relative source genesis application state and marshal it into + // the respective key. + appState[v040crisis.ModuleName] = v040Codec.MustMarshalJSON(v040crisis.Migrate(crisisGenState)) + } + + // Migrate x/distribution. + if appState[v038distribution.ModuleName] != nil { + // unmarshal relative source genesis application state + var distributionGenState v038distribution.GenesisState + v039Codec.MustUnmarshalJSON(appState[v038distribution.ModuleName], &distributionGenState) + + // delete deprecated x/distribution genesis state + delete(appState, v038distribution.ModuleName) + + // Migrate relative source genesis application state and marshal it into + // the respective key. + appState[v040distribution.ModuleName] = v040Codec.MustMarshalJSON(v040distribution.Migrate(distributionGenState)) + } + // Migrate x/evidence. if appState[v038evidence.ModuleName] != nil { // unmarshal relative source genesis application state @@ -73,7 +118,35 @@ func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { // Migrate relative source genesis application state and marshal it into // the respective key. - appState[v040evidence.ModuleName] = v040Codec.MustMarshalJSON(v040evidence.Migrate(evidenceGenState, clientCtx)) + appState[v040evidence.ModuleName] = v040Codec.MustMarshalJSON(v040evidence.Migrate(evidenceGenState)) + } + + // Migrate x/gov. + if appState[v036gov.ModuleName] != nil { + // unmarshal relative source genesis application state + var govGenState v036gov.GenesisState + v039Codec.MustUnmarshalJSON(appState[v036gov.ModuleName], &govGenState) + + // delete deprecated x/gov genesis state + delete(appState, v036gov.ModuleName) + + // Migrate relative source genesis application state and marshal it into + // the respective key. + appState[v040gov.ModuleName] = v040Codec.MustMarshalJSON(v040gov.Migrate(govGenState)) + } + + // Migrate x/mint. + if appState[v039mint.ModuleName] != nil { + // unmarshal relative source genesis application state + var mintGenState v039mint.GenesisState + v039Codec.MustUnmarshalJSON(appState[v039mint.ModuleName], &mintGenState) + + // delete deprecated x/mint genesis state + delete(appState, v039mint.ModuleName) + + // Migrate relative source genesis application state and marshal it into + // the respective key. + appState[v040mint.ModuleName] = v040Codec.MustMarshalJSON(v040mint.Migrate(mintGenState)) } // Migrate x/slashing. @@ -82,7 +155,7 @@ func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { var slashingGenState v039slashing.GenesisState v039Codec.MustUnmarshalJSON(appState[v039slashing.ModuleName], &slashingGenState) - // delete deprecated x/evidence genesis state + // delete deprecated x/slashing genesis state delete(appState, v039slashing.ModuleName) // Migrate relative source genesis application state and marshal it into @@ -90,5 +163,33 @@ func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap { appState[v040slashing.ModuleName] = v040Codec.MustMarshalJSON(v040slashing.Migrate(slashingGenState)) } + // Migrate x/staking. + if appState[v038staking.ModuleName] != nil { + // unmarshal relative source genesis application state + var stakingGenState v038staking.GenesisState + v039Codec.MustUnmarshalJSON(appState[v038staking.ModuleName], &stakingGenState) + + // delete deprecated x/staking genesis state + delete(appState, v038staking.ModuleName) + + // Migrate relative source genesis application state and marshal it into + // the respective key. + appState[v040staking.ModuleName] = v040Codec.MustMarshalJSON(v040staking.Migrate(stakingGenState)) + } + + // Migrate x/genutil + if appState[v039genutil.ModuleName] != nil { + // unmarshal relative source genesis application state + var genutilGenState v039genutil.GenesisState + v039Codec.MustUnmarshalJSON(appState[v039genutil.ModuleName], &genutilGenState) + + // delete deprecated x/staking genesis state + delete(appState, v039genutil.ModuleName) + + // Migrate relative source genesis application state and marshal it into + // the respective key. + appState[ModuleName] = v040Codec.MustMarshalJSON(migrateGenutil(genutilGenState)) + } + return appState } diff --git a/x/genutil/legacy/v040/types.go b/x/genutil/legacy/v040/types.go new file mode 100644 index 000000000000..f641dbff51e1 --- /dev/null +++ b/x/genutil/legacy/v040/types.go @@ -0,0 +1,5 @@ +package v040 + +const ( + ModuleName = "genutil" +) diff --git a/x/gov/legacy/v040/migrate.go b/x/gov/legacy/v040/migrate.go new file mode 100644 index 000000000000..73ee066dd60b --- /dev/null +++ b/x/gov/legacy/v040/migrate.go @@ -0,0 +1,141 @@ +package v040 + +import ( + "fmt" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + v034gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v034" + v036gov "github.com/cosmos/cosmos-sdk/x/gov/legacy/v036" + v040gov "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +func migrateVoteOption(oldVoteOption v034gov.VoteOption) v040gov.VoteOption { + switch oldVoteOption { + case v034gov.OptionEmpty: + return v040gov.OptionEmpty + + case v034gov.OptionYes: + return v040gov.OptionYes + + case v034gov.OptionAbstain: + return v040gov.OptionAbstain + + case v034gov.OptionNo: + return v040gov.OptionNo + + case v034gov.OptionNoWithVeto: + return v040gov.OptionNoWithVeto + + default: + panic(fmt.Errorf("'%s' is not a valid vote option", oldVoteOption)) + } +} + +func migrateProposalStatus(oldProposalStatus v034gov.ProposalStatus) v040gov.ProposalStatus { + switch oldProposalStatus { + + case v034gov.StatusNil: + return v040gov.StatusNil + + case v034gov.StatusDepositPeriod: + return v040gov.StatusDepositPeriod + + case v034gov.StatusVotingPeriod: + return v040gov.StatusVotingPeriod + + case v034gov.StatusPassed: + return v040gov.StatusPassed + + case v034gov.StatusRejected: + return v040gov.StatusRejected + + case v034gov.StatusFailed: + return v040gov.StatusFailed + + default: + panic(fmt.Errorf("'%s' is not a valid proposal status", oldProposalStatus)) + } +} + +func migrateContent(oldContent v036gov.Content) *codectypes.Any { + switch oldContent := oldContent.(type) { + case *v040gov.TextProposal: + { + // Convert the content into Any. + contentAny, err := codectypes.NewAnyWithValue(oldContent) + if err != nil { + panic(err) + } + + return contentAny + } + default: + panic(fmt.Errorf("'%T' is not a valid proposal content type", oldContent)) + } +} + +// Migrate accepts exported v0.36 x/gov genesis state and migrates it to +// v0.40 x/gov genesis state. The migration includes: +// +// - Convert vote option & proposal status from byte to enum. +// - Migrate proposal content to Any. +// - Convert addresses from bytes to bech32 strings. +// - Re-encode in v0.40 GenesisState. +func Migrate(oldGovState v036gov.GenesisState) *v040gov.GenesisState { + newDeposits := make([]v040gov.Deposit, len(oldGovState.Deposits)) + for i, oldDeposit := range oldGovState.Deposits { + newDeposits[i] = v040gov.Deposit{ + ProposalId: oldDeposit.ProposalID, + Depositor: oldDeposit.Depositor.String(), + Amount: oldDeposit.Amount, + } + } + + newVotes := make([]v040gov.Vote, len(oldGovState.Votes)) + for i, oldVote := range oldGovState.Votes { + newVotes[i] = v040gov.Vote{ + ProposalId: oldVote.ProposalID, + Voter: oldVote.Voter.String(), + Option: migrateVoteOption(oldVote.Option), + } + } + + newProposals := make([]v040gov.Proposal, len(oldGovState.Proposals)) + for i, oldProposal := range oldGovState.Proposals { + newProposals[i] = v040gov.Proposal{ + ProposalId: oldProposal.ProposalID, + Content: migrateContent(oldProposal.Content), + Status: migrateProposalStatus(oldProposal.Status), + FinalTallyResult: v040gov.TallyResult{ + Yes: oldProposal.FinalTallyResult.Yes, + Abstain: oldProposal.FinalTallyResult.Abstain, + No: oldProposal.FinalTallyResult.No, + NoWithVeto: oldProposal.FinalTallyResult.NoWithVeto, + }, + SubmitTime: oldProposal.SubmitTime, + DepositEndTime: oldProposal.DepositEndTime, + TotalDeposit: oldProposal.TotalDeposit, + VotingStartTime: oldProposal.VotingStartTime, + VotingEndTime: oldProposal.VotingEndTime, + } + } + + return &v040gov.GenesisState{ + StartingProposalId: oldGovState.StartingProposalID, + Deposits: newDeposits, + Votes: newVotes, + Proposals: newProposals, + DepositParams: v040gov.DepositParams{ + MinDeposit: oldGovState.DepositParams.MinDeposit, + MaxDepositPeriod: oldGovState.DepositParams.MaxDepositPeriod, + }, + VotingParams: v040gov.VotingParams{ + VotingPeriod: oldGovState.VotingParams.VotingPeriod, + }, + TallyParams: v040gov.TallyParams{ + Quorum: oldGovState.TallyParams.Quorum, + Threshold: oldGovState.TallyParams.Threshold, + VetoThreshold: oldGovState.TallyParams.Veto, + }, + } +} diff --git a/x/gov/legacy/v040/types.go b/x/gov/legacy/v040/types.go new file mode 100644 index 000000000000..27f668b2e1aa --- /dev/null +++ b/x/gov/legacy/v040/types.go @@ -0,0 +1,6 @@ +package v040 + +// Default parameter values +const ( + ModuleName = "gov" +) diff --git a/x/mint/legacy/v039/types.go b/x/mint/legacy/v039/types.go new file mode 100644 index 000000000000..10b351b7fb8f --- /dev/null +++ b/x/mint/legacy/v039/types.go @@ -0,0 +1,31 @@ +package v039 + +import sdk "github.com/cosmos/cosmos-sdk/types" + +const ( + ModuleName = "mint" +) + +type ( + // Minter represents the minting state. + Minter struct { + Inflation sdk.Dec `json:"inflation" yaml:"inflation"` // current annual inflation rate + AnnualProvisions sdk.Dec `json:"annual_provisions" yaml:"annual_provisions"` // current annual expected provisions + } + + // mint parameters + Params struct { + MintDenom string `json:"mint_denom" yaml:"mint_denom"` // type of coin to mint + InflationRateChange sdk.Dec `json:"inflation_rate_change" yaml:"inflation_rate_change"` // maximum annual change in inflation rate + InflationMax sdk.Dec `json:"inflation_max" yaml:"inflation_max"` // maximum inflation rate + InflationMin sdk.Dec `json:"inflation_min" yaml:"inflation_min"` // minimum inflation rate + GoalBonded sdk.Dec `json:"goal_bonded" yaml:"goal_bonded"` // goal of percent bonded atoms + BlocksPerYear uint64 `json:"blocks_per_year" yaml:"blocks_per_year"` // expected blocks per year + } + + // GenesisState - minter state + GenesisState struct { + Minter Minter `json:"minter" yaml:"minter"` // minter object + Params Params `json:"params" yaml:"params"` // inflation params + } +) diff --git a/x/mint/legacy/v040/migrate.go b/x/mint/legacy/v040/migrate.go new file mode 100644 index 000000000000..b417c6828951 --- /dev/null +++ b/x/mint/legacy/v040/migrate.go @@ -0,0 +1,27 @@ +package v040 + +import ( + v039mint "github.com/cosmos/cosmos-sdk/x/mint/legacy/v039" + v040mint "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +// Migrate accepts exported v0.39 x/mint genesis state and +// migrates it to v0.40 x/mint genesis state. The migration includes: +// +// - Re-encode in v0.40 GenesisState. +func Migrate(mintGenState v039mint.GenesisState) *v040mint.GenesisState { + return &v040mint.GenesisState{ + Minter: v040mint.Minter{ + Inflation: mintGenState.Minter.Inflation, + AnnualProvisions: mintGenState.Minter.AnnualProvisions, + }, + Params: v040mint.Params{ + MintDenom: mintGenState.Params.MintDenom, + InflationRateChange: mintGenState.Params.InflationRateChange, + InflationMax: mintGenState.Params.InflationMax, + InflationMin: mintGenState.Params.InflationMin, + GoalBonded: mintGenState.Params.GoalBonded, + BlocksPerYear: mintGenState.Params.BlocksPerYear, + }, + } +} diff --git a/x/mint/legacy/v040/types.go b/x/mint/legacy/v040/types.go new file mode 100644 index 000000000000..d725b48c34fb --- /dev/null +++ b/x/mint/legacy/v040/types.go @@ -0,0 +1,5 @@ +package v040 + +const ( + ModuleName = "mint" +) diff --git a/x/slashing/legacy/v040/migrate.go b/x/slashing/legacy/v040/migrate.go index 4f99af1446b0..ba494dcad14a 100644 --- a/x/slashing/legacy/v040/migrate.go +++ b/x/slashing/legacy/v040/migrate.go @@ -11,6 +11,8 @@ import ( // to v0.40 x/slashing genesis state. The migration includes: // // - Chaning SigningInfos and MissedBlocks from map to array. +// - Convert addresses from bytes to bech32 strings. +// - Re-encode in v0.40 GenesisState. func Migrate(oldGenState v039slashing.GenesisState) *v040slashing.GenesisState { // Note that the two following `for` loop over a map's keys, so are not // deterministic. diff --git a/x/staking/legacy/v034/types.go b/x/staking/legacy/v034/types.go index f062ef2fa121..6e93b7986a52 100644 --- a/x/staking/legacy/v034/types.go +++ b/x/staking/legacy/v034/types.go @@ -15,7 +15,21 @@ const ( ModuleName = "staking" ) +// staking constants +const ( + Unbonded BondStatus = 0x00 + Unbonding BondStatus = 0x01 + Bonded BondStatus = 0x02 + + BondStatusUnbonded = "Unbonded" + BondStatusUnbonding = "Unbonding" + BondStatusBonded = "Bonded" +) + type ( + // BondStatus is the status of a validator + BondStatus byte + Pool struct { NotBondedTokens sdk.Int `json:"not_bonded_tokens"` BondedTokens sdk.Int `json:"bonded_tokens"` @@ -51,7 +65,7 @@ type ( OperatorAddress sdk.ValAddress `json:"operator_address"` // the bech32 address of the validator's operator ConsPubKey string `json:"consensus_pubkey"` // the bech32 consensus public key of the validator Jailed bool `json:"jailed"` // has the validator been jailed from bonded status? - Status sdk.BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded) + Status BondStatus `json:"status"` // validator status (bonded/unbonding/unbonded) Tokens sdk.Int `json:"tokens"` // delegated tokens (incl. self-delegation) DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators Description Description `json:"description"` // description terms for the validator @@ -65,7 +79,7 @@ type ( OperatorAddress sdk.ValAddress `json:"operator_address"` ConsPubKey crypto.PubKey `json:"consensus_pubkey"` Jailed bool `json:"jailed"` - Status sdk.BondStatus `json:"status"` + Status BondStatus `json:"status"` Tokens sdk.Int `json:"tokens"` DelegatorShares sdk.Dec `json:"delegator_shares"` Description Description `json:"description"` diff --git a/x/staking/legacy/v036/types.go b/x/staking/legacy/v036/types.go index 7adc446eb009..6c110bbe57dc 100644 --- a/x/staking/legacy/v036/types.go +++ b/x/staking/legacy/v036/types.go @@ -32,7 +32,7 @@ type ( OperatorAddress sdk.ValAddress `json:"operator_address" yaml:"operator_address"` ConsPubKey crypto.PubKey `json:"consensus_pubkey" yaml:"consensus_pubkey"` Jailed bool `json:"jailed" yaml:"jailed"` - Status sdk.BondStatus `json:"status" yaml:"status"` + Status v034staking.BondStatus `json:"status" yaml:"status"` Tokens sdk.Int `json:"tokens" yaml:"tokens"` DelegatorShares sdk.Dec `json:"delegator_shares" yaml:"delegator_shares"` Description v034staking.Description `json:"description" yaml:"description"` @@ -46,7 +46,7 @@ type ( OperatorAddress sdk.ValAddress `json:"operator_address" yaml:"operator_address"` ConsPubKey string `json:"consensus_pubkey" yaml:"consensus_pubkey"` Jailed bool `json:"jailed" yaml:"jailed"` - Status sdk.BondStatus `json:"status" yaml:"status"` + Status v034staking.BondStatus `json:"status" yaml:"status"` Tokens sdk.Int `json:"tokens" yaml:"tokens"` DelegatorShares sdk.Dec `json:"delegator_shares" yaml:"delegator_shares"` Description v034staking.Description `json:"description" yaml:"description"` diff --git a/x/staking/legacy/v038/types.go b/x/staking/legacy/v038/types.go index def28b31cbf8..aff9a559d457 100644 --- a/x/staking/legacy/v038/types.go +++ b/x/staking/legacy/v038/types.go @@ -30,7 +30,7 @@ type ( OperatorAddress sdk.ValAddress `json:"operator_address" yaml:"operator_address"` ConsPubKey crypto.PubKey `json:"consensus_pubkey" yaml:"consensus_pubkey"` Jailed bool `json:"jailed" yaml:"jailed"` - Status sdk.BondStatus `json:"status" yaml:"status"` + Status v034staking.BondStatus `json:"status" yaml:"status"` Tokens sdk.Int `json:"tokens" yaml:"tokens"` DelegatorShares sdk.Dec `json:"delegator_shares" yaml:"delegator_shares"` Description Description `json:"description" yaml:"description"` @@ -44,7 +44,7 @@ type ( OperatorAddress sdk.ValAddress `json:"operator_address" yaml:"operator_address"` ConsPubKey string `json:"consensus_pubkey" yaml:"consensus_pubkey"` Jailed bool `json:"jailed" yaml:"jailed"` - Status sdk.BondStatus `json:"status" yaml:"status"` + Status v034staking.BondStatus `json:"status" yaml:"status"` Tokens sdk.Int `json:"tokens" yaml:"tokens"` DelegatorShares sdk.Dec `json:"delegator_shares" yaml:"delegator_shares"` Description Description `json:"description" yaml:"description"` @@ -56,8 +56,16 @@ type ( Validators []Validator + Params struct { + UnbondingTime time.Duration `json:"unbonding_time" yaml:"unbonding_time"` // time duration of unbonding + MaxValidators uint16 `json:"max_validators" yaml:"max_validators"` // maximum number of validators (max uint16 = 65535) + MaxEntries uint16 `json:"max_entries" yaml:"max_entries"` // max entries for either unbonding delegation or redelegation (per pair/trio) + HistoricalEntries uint16 `json:"historical_entries" yaml:"historical_entries"` // number of historical entries to persist + BondDenom string `json:"bond_denom" yaml:"bond_denom"` // bondable coin denomination + } + GenesisState struct { - Params v034staking.Params `json:"params"` + Params Params `json:"params"` LastTotalPower sdk.Int `json:"last_total_power"` LastValidatorPowers []v034staking.LastValidatorPower `json:"last_validator_powers"` Validators Validators `json:"validators"` @@ -87,7 +95,13 @@ func NewGenesisState( ) GenesisState { return GenesisState{ - Params: params, + Params: Params{ + UnbondingTime: params.UnbondingTime, + MaxValidators: params.MaxValidators, + MaxEntries: params.MaxEntries, + BondDenom: params.BondDenom, + HistoricalEntries: 0, + }, LastTotalPower: lastTotalPower, LastValidatorPowers: lastValPowers, Validators: validators, diff --git a/x/staking/legacy/v040/migrate.go b/x/staking/legacy/v040/migrate.go new file mode 100644 index 000000000000..4cd55afa504a --- /dev/null +++ b/x/staking/legacy/v040/migrate.go @@ -0,0 +1,137 @@ +package v040 + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v034" + v038staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v038" + v040staking "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +func migrateBondStatus(oldStatus v034staking.BondStatus) sdk.BondStatus { + switch oldStatus { + case v034staking.Unbonded: + return sdk.Unbonded + + case v034staking.Unbonding: + return sdk.Unbonding + + case v034staking.Bonded: + return sdk.Bonded + + default: + panic(fmt.Errorf("invalid bond status %d", oldStatus)) + } +} + +// Migrate accepts exported v0.38 x/staking genesis state and migrates it to +// v0.40 x/staking genesis state. The migration includes: +// +// - Convert addresses from bytes to bech32 strings. +// - Update BondStatus staking constants. +// - Re-encode in v0.40 GenesisState. +func Migrate(stakingState v038staking.GenesisState) *v040staking.GenesisState { + newLastValidatorPowers := make([]v040staking.LastValidatorPower, len(stakingState.LastValidatorPowers)) + for i, oldLastValidatorPower := range stakingState.LastValidatorPowers { + newLastValidatorPowers[i] = v040staking.LastValidatorPower{ + Address: oldLastValidatorPower.Address.String(), + Power: oldLastValidatorPower.Power, + } + } + + newValidators := make([]v040staking.Validator, len(stakingState.Validators)) + for i, oldValidator := range stakingState.Validators { + newValidators[i] = v040staking.Validator{ + OperatorAddress: oldValidator.OperatorAddress.String(), + ConsensusPubkey: sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, oldValidator.ConsPubKey), + Jailed: oldValidator.Jailed, + Status: migrateBondStatus(oldValidator.Status), + Tokens: oldValidator.Tokens, + DelegatorShares: oldValidator.DelegatorShares, + Description: v040staking.Description{ + Moniker: oldValidator.Description.Moniker, + Identity: oldValidator.Description.Identity, + Website: oldValidator.Description.Website, + SecurityContact: oldValidator.Description.SecurityContact, + Details: oldValidator.Description.Details, + }, + UnbondingHeight: oldValidator.UnbondingHeight, + UnbondingTime: oldValidator.UnbondingCompletionTime, + Commission: v040staking.Commission{ + CommissionRates: v040staking.CommissionRates{ + Rate: oldValidator.Commission.Rate, + MaxRate: oldValidator.Commission.MaxRate, + MaxChangeRate: oldValidator.Commission.MaxChangeRate, + }, + UpdateTime: oldValidator.Commission.UpdateTime, + }, + MinSelfDelegation: oldValidator.MinSelfDelegation, + } + } + + newDelegations := make([]v040staking.Delegation, len(stakingState.Delegations)) + for i, oldDelegation := range stakingState.Delegations { + newDelegations[i] = v040staking.Delegation{ + DelegatorAddress: oldDelegation.DelegatorAddress.String(), + ValidatorAddress: oldDelegation.ValidatorAddress.String(), + Shares: oldDelegation.Shares, + } + } + + newUnbondingDelegations := make([]v040staking.UnbondingDelegation, len(stakingState.UnbondingDelegations)) + for i, oldUnbondingDelegation := range stakingState.UnbondingDelegations { + newEntries := make([]v040staking.UnbondingDelegationEntry, len(oldUnbondingDelegation.Entries)) + for j, oldEntry := range oldUnbondingDelegation.Entries { + newEntries[j] = v040staking.UnbondingDelegationEntry{ + CreationHeight: oldEntry.CreationHeight, + CompletionTime: oldEntry.CompletionTime, + InitialBalance: oldEntry.InitialBalance, + Balance: oldEntry.Balance, + } + } + + newUnbondingDelegations[i] = v040staking.UnbondingDelegation{ + DelegatorAddress: oldUnbondingDelegation.DelegatorAddress.String(), + ValidatorAddress: oldUnbondingDelegation.ValidatorAddress.String(), + Entries: newEntries, + } + } + + newRedelegations := make([]v040staking.Redelegation, len(stakingState.Redelegations)) + for i, oldRedelegation := range stakingState.Redelegations { + newEntries := make([]v040staking.RedelegationEntry, len(oldRedelegation.Entries)) + for j, oldEntry := range oldRedelegation.Entries { + newEntries[j] = v040staking.RedelegationEntry{ + CreationHeight: oldEntry.CreationHeight, + CompletionTime: oldEntry.CompletionTime, + InitialBalance: oldEntry.InitialBalance, + SharesDst: oldEntry.SharesDst, + } + } + + newRedelegations[i] = v040staking.Redelegation{ + DelegatorAddress: oldRedelegation.DelegatorAddress.String(), + ValidatorSrcAddress: oldRedelegation.ValidatorSrcAddress.String(), + ValidatorDstAddress: oldRedelegation.ValidatorDstAddress.String(), + Entries: newEntries, + } + } + + return &v040staking.GenesisState{ + Params: v040staking.Params{ + UnbondingTime: stakingState.Params.UnbondingTime, + MaxValidators: uint32(stakingState.Params.MaxValidators), + MaxEntries: uint32(stakingState.Params.MaxEntries), + HistoricalEntries: uint32(stakingState.Params.HistoricalEntries), + BondDenom: stakingState.Params.BondDenom, + }, + LastTotalPower: stakingState.LastTotalPower, + LastValidatorPowers: newLastValidatorPowers, + Validators: newValidators, + Delegations: newDelegations, + UnbondingDelegations: newUnbondingDelegations, + Redelegations: newRedelegations, + Exported: stakingState.Exported, + } +} diff --git a/x/staking/legacy/v040/migrate_test.go b/x/staking/legacy/v040/migrate_test.go new file mode 100644 index 000000000000..1d593a6fc98a --- /dev/null +++ b/x/staking/legacy/v040/migrate_test.go @@ -0,0 +1,93 @@ +package v040_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + "github.com/cosmos/cosmos-sdk/simapp" + v034staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v034" + v038staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v038" + v040staking "github.com/cosmos/cosmos-sdk/x/staking/legacy/v040" +) + +func TestMigrate(t *testing.T) { + encodingConfig := simapp.MakeEncodingConfig() + clientCtx := client.Context{}. + WithInterfaceRegistry(encodingConfig.InterfaceRegistry). + WithTxConfig(encodingConfig.TxConfig). + WithLegacyAmino(encodingConfig.Amino). + WithJSONMarshaler(encodingConfig.Marshaler) + + consPubKey := ed25519.GenPrivKeyFromSecret([]byte("val0")).PubKey() + stakingGenState := v038staking.GenesisState{ + Validators: v038staking.Validators{v038staking.Validator{ + ConsPubKey: consPubKey, + Status: v034staking.Unbonded, + }}, + } + + migrated := v040staking.Migrate(stakingGenState) + + bz, err := clientCtx.JSONMarshaler.MarshalJSON(migrated) + require.NoError(t, err) + + // Indent the JSON bz correctly. + var jsonObj map[string]interface{} + err = json.Unmarshal(bz, &jsonObj) + require.NoError(t, err) + indentedBz, err := json.MarshalIndent(jsonObj, "", " ") + require.NoError(t, err) + + // Make sure about: + // - consensus_pubkey: should be bech32 pubkey + // - validator's status should be 1 (new unbonded) + expected := `{ + "delegations": [], + "exported": false, + "last_total_power": "0", + "last_validator_powers": [], + "params": { + "bond_denom": "", + "historical_entries": 0, + "max_entries": 0, + "max_validators": 0, + "unbonding_time": "0s" + }, + "redelegations": [], + "unbonding_delegations": [], + "validators": [ + { + "commission": { + "commission_rates": { + "max_change_rate": "0", + "max_rate": "0", + "rate": "0" + }, + "update_time": "0001-01-01T00:00:00Z" + }, + "consensus_pubkey": "cosmosvalconspub1zcjduepq9ymett3nlv6fytn7lqxzd3q3ckvd79eqlcf3wkhgamcl4rzghesq83ecpx", + "delegator_shares": "0", + "description": { + "details": "", + "identity": "", + "moniker": "", + "security_contact": "", + "website": "" + }, + "jailed": false, + "min_self_delegation": "0", + "operator_address": "", + "status": 1, + "tokens": "0", + "unbonding_height": "0", + "unbonding_time": "0001-01-01T00:00:00Z" + } + ] +}` + + require.Equal(t, expected, string(indentedBz)) +} diff --git a/x/staking/legacy/v040/types.go b/x/staking/legacy/v040/types.go new file mode 100644 index 000000000000..6ad280e277e5 --- /dev/null +++ b/x/staking/legacy/v040/types.go @@ -0,0 +1,5 @@ +package v040 + +const ( + ModuleName = "staking" +)