feat: Add x/gov v043->v046 migrations (#11036)
## Description Closes: #10869 depends on: - [x] #11029 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
This commit is contained in:
parent
63a248ef03
commit
dbc19b3c54
@ -60,6 +60,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* [\#11019](https://github.com/cosmos/cosmos-sdk/pull/11019) Add `MsgCreatePermanentLockedAccount` and CLI method for creating permanent locked account
|
||||
* [\#10947](https://github.com/cosmos/cosmos-sdk/pull/10947) Add `AllowancesByGranter` query to the feegrant module
|
||||
* [\#10407](https://github.com/cosmos/cosmos-sdk/pull/10407) Add validation to `x/upgrade` module's `BeginBlock` to check accidental binary downgrades
|
||||
* (gov) [\#11036](https://github.com/cosmos/cosmos-sdk/pull/11036) Add in-place migrations for 0.43->0.46. Add a `migrate v0.46` CLI command for v0.43->0.46 JSON genesis migration.
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
v040 "github.com/cosmos/cosmos-sdk/x/genutil/migrations/v040"
|
||||
v043 "github.com/cosmos/cosmos-sdk/x/genutil/migrations/v043"
|
||||
v046 "github.com/cosmos/cosmos-sdk/x/genutil/migrations/v046"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
)
|
||||
|
||||
@ -26,7 +27,8 @@ const flagGenesisTime = "genesis-time"
|
||||
// Ref: https://github.com/cosmos/cosmos-sdk/issues/5041
|
||||
var migrationMap = types.MigrationMap{
|
||||
"v0.42": v040.Migrate, // NOTE: v0.40, v0.41 and v0.42 are genesis compatible.
|
||||
"v0.43": v043.Migrate,
|
||||
"v0.43": v043.Migrate, // NOTE: v0.43, v0.44 and v0.45 are genesis compatible.
|
||||
"v0.46": v046.Migrate,
|
||||
}
|
||||
|
||||
// GetMigrationCallback returns a MigrationCallback for a given version.
|
||||
|
||||
32
x/genutil/migrations/v046/migrate.go
Normal file
32
x/genutil/migrations/v046/migrate.go
Normal file
@ -0,0 +1,32 @@
|
||||
package v046
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
v043gov "github.com/cosmos/cosmos-sdk/x/gov/migrations/v043"
|
||||
v046gov "github.com/cosmos/cosmos-sdk/x/gov/migrations/v046"
|
||||
gov "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||
)
|
||||
|
||||
// Migrate migrates exported state from v0.43 to a v0.46 genesis state.
|
||||
func Migrate(appState types.AppMap, clientCtx client.Context) types.AppMap {
|
||||
// Migrate x/gov.
|
||||
if appState[v043gov.ModuleName] != nil {
|
||||
// unmarshal relative source genesis application state
|
||||
var oldGovState gov.GenesisState
|
||||
clientCtx.Codec.MustUnmarshalJSON(appState[v043gov.ModuleName], &oldGovState)
|
||||
|
||||
// delete deprecated x/gov genesis state
|
||||
delete(appState, v043gov.ModuleName)
|
||||
|
||||
// Migrate relative source genesis application state and marshal it into
|
||||
// the respective key.
|
||||
newGovState, err := v046gov.MigrateJSON(&oldGovState)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
appState[v046gov.ModuleName] = clientCtx.Codec.MustMarshalJSON(newGovState)
|
||||
}
|
||||
|
||||
return appState
|
||||
}
|
||||
@ -2,6 +2,7 @@ package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v046 "github.com/cosmos/cosmos-sdk/x/bank/migrations/v046"
|
||||
v043 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v043"
|
||||
)
|
||||
|
||||
@ -19,3 +20,8 @@ func NewMigrator(keeper Keeper) Migrator {
|
||||
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
|
||||
return v043.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc)
|
||||
}
|
||||
|
||||
// Migrate2to3 migrates from version 2 to 3.
|
||||
func (m Migrator) Migrate2to3(ctx sdk.Context) error {
|
||||
return v046.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc)
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package v043_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -122,7 +121,5 @@ func TestMigrateJSON(t *testing.T) {
|
||||
}
|
||||
}`
|
||||
|
||||
fmt.Println(string(indentedBz))
|
||||
|
||||
require.Equal(t, expected, string(indentedBz))
|
||||
}
|
||||
|
||||
@ -75,6 +75,7 @@ func migrateStoreWeightedVotes(store sdk.KVStore, cdc codec.BinaryCodec) error {
|
||||
// migration includes:
|
||||
//
|
||||
// - Change addresses to be length-prefixed.
|
||||
// - Change all legacy votes to ADR-037 weighted votes.
|
||||
func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error {
|
||||
store := ctx.KVStore(storeKey)
|
||||
migratePrefixProposalAddress(store, types.DepositsKeyPrefix)
|
||||
|
||||
@ -3,7 +3,9 @@ package v046
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta2"
|
||||
)
|
||||
@ -117,3 +119,109 @@ func ConvertToLegacyDeposit(deposit *v1beta2.Deposit) v1beta1.Deposit {
|
||||
Amount: types.NewCoins(deposit.Amount...),
|
||||
}
|
||||
}
|
||||
|
||||
func convertToNewDeposits(oldDeps v1beta1.Deposits) v1beta2.Deposits {
|
||||
newDeps := make([]*v1beta2.Deposit, len(oldDeps))
|
||||
for i, oldDep := range oldDeps {
|
||||
newDeps[i] = &v1beta2.Deposit{
|
||||
ProposalId: oldDep.ProposalId,
|
||||
Depositor: oldDep.Depositor,
|
||||
Amount: oldDep.Amount,
|
||||
}
|
||||
}
|
||||
|
||||
return newDeps
|
||||
}
|
||||
|
||||
func convertToNewVotes(oldVotes v1beta1.Votes) (v1beta2.Votes, error) {
|
||||
newVotes := make([]*v1beta2.Vote, len(oldVotes))
|
||||
for i, oldVote := range oldVotes {
|
||||
var newWVOs []*v1beta2.WeightedVoteOption
|
||||
|
||||
// We deprecated Vote.Option in v043. However, it might still be set.
|
||||
// - if only Options is set, or both Option & Options are set, we read from Options,
|
||||
// - if Options is not set, and Option is set, we read from Option,
|
||||
// - if none are set, we throw error.
|
||||
if oldVote.Options != nil {
|
||||
newWVOs = make([]*v1beta2.WeightedVoteOption, len(oldVote.Options))
|
||||
for j, oldWVO := range oldVote.Options {
|
||||
newWVOs[j] = v1beta2.NewWeightedVoteOption(v1beta2.VoteOption(oldWVO.Option), oldWVO.Weight)
|
||||
}
|
||||
} else if oldVote.Option != v1beta1.OptionEmpty {
|
||||
newWVOs = v1beta2.NewNonSplitVoteOption(v1beta2.VoteOption(oldVote.Option))
|
||||
} else {
|
||||
return nil, fmt.Errorf("vote does not have neither Options nor Option")
|
||||
}
|
||||
|
||||
newVotes[i] = &v1beta2.Vote{
|
||||
ProposalId: oldVote.ProposalId,
|
||||
Voter: oldVote.Voter,
|
||||
Options: newWVOs,
|
||||
}
|
||||
}
|
||||
|
||||
return newVotes, nil
|
||||
}
|
||||
|
||||
func convertToNewDepParams(oldDepParams v1beta1.DepositParams) v1beta2.DepositParams {
|
||||
return v1beta2.DepositParams{
|
||||
MinDeposit: oldDepParams.MinDeposit,
|
||||
MaxDepositPeriod: &oldDepParams.MaxDepositPeriod,
|
||||
}
|
||||
}
|
||||
|
||||
func convertToNewVotingParams(oldVoteParams v1beta1.VotingParams) v1beta2.VotingParams {
|
||||
return v1beta2.VotingParams{
|
||||
VotingPeriod: &oldVoteParams.VotingPeriod,
|
||||
}
|
||||
}
|
||||
|
||||
func convertToNewTallyParams(oldTallyParams v1beta1.TallyParams) v1beta2.TallyParams {
|
||||
return v1beta2.TallyParams{
|
||||
Quorum: oldTallyParams.Quorum.String(),
|
||||
Threshold: oldTallyParams.Threshold.String(),
|
||||
VetoThreshold: oldTallyParams.VetoThreshold.String(),
|
||||
}
|
||||
}
|
||||
|
||||
func convertToNewProposal(oldProp v1beta1.Proposal) (v1beta2.Proposal, error) {
|
||||
msg, err := v1beta2.NewLegacyContent(oldProp.GetContent(), authtypes.NewModuleAddress(ModuleName).String())
|
||||
if err != nil {
|
||||
return v1beta2.Proposal{}, err
|
||||
}
|
||||
msgAny, err := codectypes.NewAnyWithValue(msg)
|
||||
if err != nil {
|
||||
return v1beta2.Proposal{}, err
|
||||
}
|
||||
|
||||
return v1beta2.Proposal{
|
||||
ProposalId: oldProp.ProposalId,
|
||||
Messages: []*codectypes.Any{msgAny},
|
||||
Status: v1beta2.ProposalStatus(oldProp.Status),
|
||||
FinalTallyResult: &v1beta2.TallyResult{
|
||||
Yes: oldProp.FinalTallyResult.Yes.String(),
|
||||
No: oldProp.FinalTallyResult.No.String(),
|
||||
Abstain: oldProp.FinalTallyResult.Abstain.String(),
|
||||
NoWithVeto: oldProp.FinalTallyResult.NoWithVeto.String(),
|
||||
},
|
||||
SubmitTime: &oldProp.SubmitTime,
|
||||
DepositEndTime: &oldProp.DepositEndTime,
|
||||
TotalDeposit: oldProp.TotalDeposit,
|
||||
VotingStartTime: &oldProp.VotingStartTime,
|
||||
VotingEndTime: &oldProp.VotingEndTime,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertToNewProposals(oldProps v1beta1.Proposals) (v1beta2.Proposals, error) {
|
||||
newProps := make([]*v1beta2.Proposal, len(oldProps))
|
||||
for i, oldProp := range oldProps {
|
||||
p, err := convertToNewProposal(oldProp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newProps[i] = &p
|
||||
}
|
||||
|
||||
return newProps, nil
|
||||
}
|
||||
34
x/gov/migrations/v046/json.go
Normal file
34
x/gov/migrations/v046/json.go
Normal file
@ -0,0 +1,34 @@
|
||||
package v046
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta2"
|
||||
)
|
||||
|
||||
// MigrateJSON accepts exported v0.43 x/gov genesis state and migrates it to
|
||||
// v0.46 x/gov genesis state. The migration includes:
|
||||
//
|
||||
// - Updating everything to v1beta2.
|
||||
// - Migrating proposals to be Msg-based.
|
||||
func MigrateJSON(oldState *v1beta1.GenesisState) (*v1beta2.GenesisState, error) {
|
||||
newProps, err := convertToNewProposals(oldState.Proposals)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newVotes, err := convertToNewVotes(oldState.Votes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
depParams, votingParms, tallyParams := convertToNewDepParams(oldState.DepositParams), convertToNewVotingParams(oldState.VotingParams), convertToNewTallyParams(oldState.TallyParams)
|
||||
|
||||
return &v1beta2.GenesisState{
|
||||
StartingProposalId: oldState.StartingProposalId,
|
||||
Deposits: convertToNewDeposits(oldState.Deposits),
|
||||
Votes: newVotes,
|
||||
Proposals: newProps,
|
||||
DepositParams: &depParams,
|
||||
VotingParams: &votingParms,
|
||||
TallyParams: &tallyParams,
|
||||
}, nil
|
||||
}
|
||||
154
x/gov/migrations/v046/json_test.go
Normal file
154
x/gov/migrations/v046/json_test.go
Normal file
@ -0,0 +1,154 @@
|
||||
package v046_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
v046 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v046"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta2"
|
||||
)
|
||||
|
||||
func TestMigrateJSON(t *testing.T) {
|
||||
encodingConfig := simapp.MakeTestEncodingConfig()
|
||||
clientCtx := client.Context{}.
|
||||
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
|
||||
WithTxConfig(encodingConfig.TxConfig).
|
||||
WithCodec(encodingConfig.Codec)
|
||||
|
||||
voter, err := sdk.AccAddressFromBech32("cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh")
|
||||
require.NoError(t, err)
|
||||
|
||||
govGenState := v1beta1.DefaultGenesisState()
|
||||
propTime := time.Unix(1e9, 0)
|
||||
contentAny, err := codectypes.NewAnyWithValue(v1beta1.NewTextProposal("my title", "my desc").(proto.Message))
|
||||
require.NoError(t, err)
|
||||
govGenState.Proposals = v1beta1.Proposals{
|
||||
v1beta1.Proposal{
|
||||
ProposalId: 1,
|
||||
Content: contentAny,
|
||||
SubmitTime: propTime,
|
||||
DepositEndTime: propTime,
|
||||
VotingStartTime: propTime,
|
||||
VotingEndTime: propTime,
|
||||
Status: v1beta1.StatusDepositPeriod,
|
||||
FinalTallyResult: v1beta1.EmptyTallyResult(),
|
||||
TotalDeposit: sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(123))),
|
||||
},
|
||||
}
|
||||
govGenState.Votes = v1beta1.Votes{
|
||||
v1beta1.Vote{ProposalId: 1, Voter: voter.String(), Option: v1beta1.OptionAbstain},
|
||||
v1beta1.Vote{ProposalId: 2, Voter: voter.String(), Options: v1beta1.NewNonSplitVoteOption(v1beta1.OptionNo)},
|
||||
}
|
||||
|
||||
migrated, err := v046.MigrateJSON(govGenState)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure the migrated proposal's Msg signer is the gov acct.
|
||||
require.Equal(t,
|
||||
authtypes.NewModuleAddress(types.ModuleName).String(),
|
||||
migrated.Proposals[0].Messages[0].GetCachedValue().(*v1beta2.MsgExecLegacyContent).Authority,
|
||||
)
|
||||
|
||||
bz, err := clientCtx.Codec.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, "", "\t")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Make sure about:
|
||||
// - Proposals use MsgExecLegacyContent
|
||||
expected := `{
|
||||
"deposit_params": {
|
||||
"max_deposit_period": "172800s",
|
||||
"min_deposit": [
|
||||
{
|
||||
"amount": "10000000",
|
||||
"denom": "stake"
|
||||
}
|
||||
]
|
||||
},
|
||||
"deposits": [],
|
||||
"proposals": [
|
||||
{
|
||||
"deposit_end_time": "2001-09-09T01:46:40Z",
|
||||
"final_tally_result": {
|
||||
"abstain": "0",
|
||||
"no": "0",
|
||||
"no_with_veto": "0",
|
||||
"yes": "0"
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"@type": "/cosmos.gov.v1beta2.MsgExecLegacyContent",
|
||||
"authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn",
|
||||
"content": {
|
||||
"@type": "/cosmos.gov.v1beta1.TextProposal",
|
||||
"description": "my desc",
|
||||
"title": "my title"
|
||||
}
|
||||
}
|
||||
],
|
||||
"metadata": null,
|
||||
"proposal_id": "1",
|
||||
"status": "PROPOSAL_STATUS_DEPOSIT_PERIOD",
|
||||
"submit_time": "2001-09-09T01:46:40Z",
|
||||
"total_deposit": [
|
||||
{
|
||||
"amount": "123",
|
||||
"denom": "stake"
|
||||
}
|
||||
],
|
||||
"voting_end_time": "2001-09-09T01:46:40Z",
|
||||
"voting_start_time": "2001-09-09T01:46:40Z"
|
||||
}
|
||||
],
|
||||
"starting_proposal_id": "1",
|
||||
"tally_params": {
|
||||
"quorum": "0.334000000000000000",
|
||||
"threshold": "0.500000000000000000",
|
||||
"veto_threshold": "0.334000000000000000"
|
||||
},
|
||||
"votes": [
|
||||
{
|
||||
"options": [
|
||||
{
|
||||
"option": "VOTE_OPTION_ABSTAIN",
|
||||
"weight": "1.000000000000000000"
|
||||
}
|
||||
],
|
||||
"proposal_id": "1",
|
||||
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
|
||||
},
|
||||
{
|
||||
"options": [
|
||||
{
|
||||
"option": "VOTE_OPTION_NO",
|
||||
"weight": "1.000000000000000000"
|
||||
}
|
||||
],
|
||||
"proposal_id": "2",
|
||||
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
|
||||
}
|
||||
],
|
||||
"voting_params": {
|
||||
"voting_period": "172800s"
|
||||
}
|
||||
}`
|
||||
|
||||
require.Equal(t, expected, string(indentedBz))
|
||||
}
|
||||
6
x/gov/migrations/v046/keys.go
Normal file
6
x/gov/migrations/v046/keys.go
Normal file
@ -0,0 +1,6 @@
|
||||
package v046
|
||||
|
||||
const (
|
||||
// ModuleName is the name of the module
|
||||
ModuleName = "gov"
|
||||
)
|
||||
51
x/gov/migrations/v046/store.go
Normal file
51
x/gov/migrations/v046/store.go
Normal file
@ -0,0 +1,51 @@
|
||||
package v046
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/store/prefix"
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v040 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v040"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||
)
|
||||
|
||||
// migrateProposals migrates all legacy proposals into MsgExecLegacyContent
|
||||
// proposals.
|
||||
func migrateProposals(store sdk.KVStore, cdc codec.BinaryCodec) error {
|
||||
propStore := prefix.NewStore(store, v040.ProposalsKeyPrefix)
|
||||
|
||||
iter := propStore.Iterator(nil, nil)
|
||||
defer iter.Close()
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
var oldProp v1beta1.Proposal
|
||||
err := cdc.Unmarshal(iter.Value(), &oldProp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newProp, err := convertToNewProposal(oldProp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bz, err := cdc.Marshal(&newProp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set new value on store.
|
||||
propStore.Set(iter.Key(), bz)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MigrateStore performs in-place store migrations from v0.43 to v0.46. The
|
||||
// migration includes:
|
||||
//
|
||||
// - Migrate proposals to be Msg-based.
|
||||
func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec) error {
|
||||
store := ctx.KVStore(storeKey)
|
||||
|
||||
return migrateProposals(store, cdc)
|
||||
}
|
||||
76
x/gov/migrations/v046/store_test.go
Normal file
76
x/gov/migrations/v046/store_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
package v046_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
v040gov "github.com/cosmos/cosmos-sdk/x/gov/migrations/v040"
|
||||
v046gov "github.com/cosmos/cosmos-sdk/x/gov/migrations/v046"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta2"
|
||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||
)
|
||||
|
||||
func TestMigrateStore(t *testing.T) {
|
||||
cdc := simapp.MakeTestEncodingConfig().Codec
|
||||
govKey := sdk.NewKVStoreKey("gov")
|
||||
ctx := testutil.DefaultContext(govKey, sdk.NewTransientStoreKey("transient_test"))
|
||||
store := ctx.KVStore(govKey)
|
||||
|
||||
propTime := time.Unix(1e9, 0)
|
||||
|
||||
// Create 2 proposals
|
||||
prop1, err := v1beta1.NewProposal(v1beta1.NewTextProposal("my title 1", "my desc 1"), 1, propTime, propTime)
|
||||
require.NoError(t, err)
|
||||
prop1Bz, err := cdc.Marshal(&prop1)
|
||||
require.NoError(t, err)
|
||||
prop2, err := v1beta1.NewProposal(upgradetypes.NewSoftwareUpgradeProposal("my title 2", "my desc 2", upgradetypes.Plan{
|
||||
Name: "my plan 2",
|
||||
}), 2, propTime, propTime)
|
||||
require.NoError(t, err)
|
||||
prop2Bz, err := cdc.Marshal(&prop2)
|
||||
require.NoError(t, err)
|
||||
|
||||
store.Set(v040gov.ProposalKey(prop1.ProposalId), prop1Bz)
|
||||
store.Set(v040gov.ProposalKey(prop2.ProposalId), prop2Bz)
|
||||
|
||||
// Run migrations.
|
||||
err = v046gov.MigrateStore(ctx, govKey, cdc)
|
||||
require.NoError(t, err)
|
||||
|
||||
var newProp1 v1beta2.Proposal
|
||||
err = cdc.Unmarshal(store.Get(v040gov.ProposalKey(prop1.ProposalId)), &newProp1)
|
||||
require.NoError(t, err)
|
||||
compareProps(t, prop1, newProp1)
|
||||
|
||||
var newProp2 v1beta2.Proposal
|
||||
err = cdc.Unmarshal(store.Get(v040gov.ProposalKey(prop2.ProposalId)), &newProp2)
|
||||
require.NoError(t, err)
|
||||
compareProps(t, prop2, newProp2)
|
||||
}
|
||||
|
||||
func compareProps(t *testing.T, oldProp v1beta1.Proposal, newProp v1beta2.Proposal) {
|
||||
require.Equal(t, oldProp.ProposalId, newProp.ProposalId)
|
||||
require.Equal(t, oldProp.TotalDeposit.String(), sdk.Coins(newProp.TotalDeposit).String())
|
||||
require.Equal(t, oldProp.Status.String(), newProp.Status.String())
|
||||
require.Equal(t, oldProp.FinalTallyResult.Yes.String(), newProp.FinalTallyResult.Yes)
|
||||
require.Equal(t, oldProp.FinalTallyResult.No.String(), newProp.FinalTallyResult.No)
|
||||
require.Equal(t, oldProp.FinalTallyResult.NoWithVeto.String(), newProp.FinalTallyResult.NoWithVeto)
|
||||
require.Equal(t, oldProp.FinalTallyResult.Abstain.String(), newProp.FinalTallyResult.Abstain)
|
||||
|
||||
newContent := newProp.Messages[0].GetCachedValue().(*v1beta2.MsgExecLegacyContent).Content.GetCachedValue().(v1beta1.Content)
|
||||
require.Equal(t, oldProp.Content.GetCachedValue().(v1beta1.Content), newContent)
|
||||
|
||||
// Compare UNIX times, as a simple Equal gives difference between Local and
|
||||
// UTC times.
|
||||
// ref: https://github.com/golang/go/issues/19486#issuecomment-292968278
|
||||
require.Equal(t, oldProp.SubmitTime.Unix(), newProp.SubmitTime.Unix())
|
||||
require.Equal(t, oldProp.DepositEndTime.Unix(), newProp.DepositEndTime.Unix())
|
||||
require.Equal(t, oldProp.VotingStartTime.Unix(), newProp.VotingStartTime.Unix())
|
||||
require.Equal(t, oldProp.VotingEndTime.Unix(), newProp.VotingEndTime.Unix())
|
||||
}
|
||||
@ -169,6 +169,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// InitGenesis performs genesis initialization for the gov module. It returns
|
||||
@ -188,7 +192,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
|
||||
}
|
||||
|
||||
// ConsensusVersion implements AppModule/ConsensusVersion.
|
||||
func (AppModule) ConsensusVersion() uint64 { return 2 }
|
||||
func (AppModule) ConsensusVersion() uint64 { return 3 }
|
||||
|
||||
// BeginBlock performs a no-op.
|
||||
func (AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user