Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add x/gov v043->v046 migrations #11036

Merged
merged 15 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion x/genutil/client/cli/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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.
Expand Down
32 changes: 32 additions & 0 deletions x/genutil/migrations/v046/migrate.go
Original file line number Diff line number Diff line change
@@ -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.45 to a v0.46 genesis state.
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
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
}
6 changes: 6 additions & 0 deletions x/gov/keeper/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we use 1, 2, and 3 version numbers - do they relate to anything. Might it be more intuitive to specify SDK version migrations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided in adr-041 to use uint here. I guess the idea back then was to prepare when modules will have their own go.mods. It might be that this ConsensusVersion == the major version in go.mod. Or not. Anyways, I think it's better for modules to have independent consensus versions than be tied up to SDK versions.

(note the v04* migration folders could probably be renamed though).

func (m Migrator) Migrate2to3(ctx sdk.Context) error {
return v046.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc)
}
3 changes: 0 additions & 3 deletions x/gov/migrations/v043/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package v043_test

import (
"encoding/json"
"fmt"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -122,7 +121,5 @@ func TestMigrateJSON(t *testing.T) {
}
}`

fmt.Println(string(indentedBz))

require.Equal(t, expected, string(indentedBz))
}
1 change: 1 addition & 0 deletions x/gov/migrations/v043/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -117,3 +119,99 @@ 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 {
newVotes := make([]*v1beta2.Vote, len(oldVotes))
for i, oldVote := range oldVotes {
// All oldVotes don't have the Option field anymore, as they have been
// migrated in the v043 package.
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
newWVOs := make([]*v1beta2.WeightedVoteOption, len(oldVote.Options))
for j, oldWVO := range oldVote.Options {
newWVOs[j] = v1beta2.NewWeightedVoteOption(v1beta2.VoteOption(oldVote.Option), oldWVO.Weight)
}

newVotes[i] = &v1beta2.Vote{
ProposalId: oldVote.ProposalId,
Voter: oldVote.Voter,
Options: newWVOs,
}
}

return newVotes
}

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
}
30 changes: 30 additions & 0 deletions x/gov/migrations/v046/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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
}

depParams, votingParms, tallyParams := convertToNewDepParams(oldState.DepositParams), convertToNewVotingParams(oldState.VotingParams), convertToNewTallyParams(oldState.TallyParams)

return &v1beta2.GenesisState{
StartingProposalId: oldState.StartingProposalId,
Deposits: convertToNewDeposits(oldState.Deposits),
Votes: convertToNewVotes(oldState.Votes),
Proposals: newProps,
DepositParams: &depParams,
VotingParams: &votingParms,
TallyParams: &tallyParams,
}, nil
}
138 changes: 138 additions & 0 deletions x/gov/migrations/v046/json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
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},
}

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": [],
"proposal_id": "1",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
}
],
"voting_params": {
"voting_period": "172800s"
}
}`

require.Equal(t, expected, string(indentedBz))
}
6 changes: 6 additions & 0 deletions x/gov/migrations/v046/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package v046

const (
// ModuleName is the name of the module
ModuleName = "gov"
)
Loading