chore: remove params dep from crisis, gov and mint (#17837)

This commit is contained in:
Marko 2023-09-22 11:35:20 +02:00 committed by GitHub
parent 076ab3bf89
commit d5c78a637e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 44 additions and 1809 deletions

View File

@ -426,6 +426,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/bank) [#17818](https://github.com/cosmos/cosmos-sdk/pull/17818) Remove params requirement from `NewAppModule`
* (x/slashing & x/auth) [#17820](https://github.com/cosmos/cosmos-sdk/pull/17820) Remove params requirement from `NewAppModule`
* (x/distribution & x/staking) [#17834](https://github.com/cosmos/cosmos-sdk/pull/17834) Remove params requirement from `NewAppModule`
* (x/mint & x/gov & x/crisis) [#17837](https://github.com/cosmos/cosmos-sdk/pull/17837) Remove params requirement from `NewAppModule`
### Client Breaking Changes

View File

@ -386,10 +386,10 @@ func NewSimApp(
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)),
crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)),
gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.interfaceRegistry),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),

View File

@ -127,7 +127,7 @@ func initFixture(tb testing.TB) *fixture {
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper)
stakingModule := staking.NewAppModule(cdc, stakingKeeper, accountKeeper, bankKeeper)
distrModule := distribution.NewAppModule(cdc, distrKeeper, accountKeeper, bankKeeper, stakingKeeper)
govModule := gov.NewAppModule(cdc, govKeeper, accountKeeper, bankKeeper, nil)
govModule := gov.NewAppModule(cdc, govKeeper, accountKeeper, bankKeeper)
integrationApp := integration.NewIntegrationApp(newCtx, logger, keys, cdc, map[string]appmodule.AppModule{
authtypes.ModuleName: authModule,

View File

@ -55,7 +55,7 @@ func Example() {
// here bankkeeper and staking keeper is nil because we are not testing them
// subspace is nil because we don't test params (which is legacy anyway)
mintKeeper := mintkeeper.NewKeeper(encodingCfg.Codec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), nil, accountKeeper, nil, authtypes.FeeCollectorName, authority)
mintModule := mint.NewAppModule(encodingCfg.Codec, mintKeeper, accountKeeper, nil, nil)
mintModule := mint.NewAppModule(encodingCfg.Codec, mintKeeper, accountKeeper, nil)
// create the application and register all the modules from the previous step
integrationApp := integration.NewIntegrationApp(

View File

@ -1,18 +0,0 @@
package exported
import (
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)
type (
ParamSet = paramtypes.ParamSet
// Subspace defines an interface that implements the legacy x/params Subspace
// type.
//
// NOTE: This is used solely for migration of x/params managed parameters.
Subspace interface {
Get(ctx sdk.Context, key []byte, ptr interface{})
}
)

View File

@ -2,21 +2,17 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/crisis/exported"
v2 "github.com/cosmos/cosmos-sdk/x/crisis/migrations/v2"
)
// Migrator is a struct for handling in-place state migrations.
type Migrator struct {
keeper *Keeper
legacySubspace exported.Subspace
keeper *Keeper
}
// NewMigrator returns a new Migrator.
func NewMigrator(k *Keeper, ss exported.Subspace) Migrator {
func NewMigrator(k *Keeper) Migrator {
return Migrator{
keeper: k,
legacySubspace: ss,
keeper: k,
}
}
@ -25,5 +21,5 @@ func NewMigrator(k *Keeper, ss exported.Subspace) Migrator {
// and managed by the x/params modules and stores them directly into the x/crisis
// module state.
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
return v2.MigrateStore(ctx, m.keeper.storeService, m.legacySubspace, m.keeper.cdc)
return nil
}

View File

@ -1,40 +0,0 @@
package v2
import (
storetypes "cosmossdk.io/core/store"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/crisis/exported"
)
const (
ModuleName = "crisis"
)
var (
ConstantFee = []byte("ConstantFee")
ConstantFeeKey = []byte{0x01}
)
// MigrateStore migrates the x/crisis module state from the consensus version 1 to
// version 2. Specifically, it takes the `ConstantFee` parameter that is currently stored
// and managed by the x/params module and stores it directly into the x/crisis
// module state.
func MigrateStore(ctx sdk.Context, storeService storetypes.KVStoreService, legacySubspace exported.Subspace, cdc codec.BinaryCodec) error {
store := storeService.OpenKVStore(ctx)
var currConstantFee sdk.Coin
legacySubspace.Get(ctx, ConstantFee, &currConstantFee)
if !currConstantFee.IsValid() {
return errors.ErrInvalidCoins.Wrap("constant fee")
}
bz, err := cdc.Marshal(&currConstantFee)
if err != nil {
return err
}
return store.Set(ConstantFeeKey, bz)
}

View File

@ -1,47 +0,0 @@
package v2_test
import (
"testing"
"github.com/stretchr/testify/require"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/crisis"
v2 "github.com/cosmos/cosmos-sdk/x/crisis/migrations/v2"
"github.com/cosmos/cosmos-sdk/x/crisis/types"
)
type mockSubspace struct {
constantFee sdk.Coin
}
func newMockSubspace(fee sdk.Coin) mockSubspace {
return mockSubspace{constantFee: fee}
}
func (ms mockSubspace) Get(ctx sdk.Context, key []byte, ptr interface{}) {
*ptr.(*sdk.Coin) = ms.constantFee
}
func TestMigrate(t *testing.T) {
cdc := moduletestutil.MakeTestEncodingConfig(crisis.AppModuleBasic{}).Codec
storeKey := storetypes.NewKVStoreKey(v2.ModuleName)
storeService := runtime.NewKVStoreService(storeKey)
tKey := storetypes.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(storeKey, tKey)
store := ctx.KVStore(storeKey)
legacySubspace := newMockSubspace(types.DefaultGenesisState().ConstantFee)
require.NoError(t, v2.MigrateStore(ctx, storeService, legacySubspace, cdc))
var res sdk.Coin
bz := store.Get(v2.ConstantFeeKey)
require.NoError(t, cdc.Unmarshal(bz, &res))
require.NotNil(t, res)
require.Equal(t, legacySubspace.constantFee, res)
}

View File

@ -26,7 +26,6 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/crisis/client/cli"
"github.com/cosmos/cosmos-sdk/x/crisis/exported"
"github.com/cosmos/cosmos-sdk/x/crisis/keeper"
"github.com/cosmos/cosmos-sdk/x/crisis/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
@ -101,9 +100,6 @@ type AppModule struct {
// executed.
keeper *keeper.Keeper
// legacySubspace is used solely for migration of x/params managed parameters
legacySubspace exported.Subspace
skipGenesisInvariants bool
}
@ -111,11 +107,10 @@ type AppModule struct {
// we will call keeper.AssertInvariants during InitGenesis (it may take a significant time)
// - which doesn't impact the chain security unless 66+% of validators have a wrongly
// modified genesis file.
func NewAppModule(keeper *keeper.Keeper, skipGenesisInvariants bool, ss exported.Subspace) AppModule {
func NewAppModule(keeper *keeper.Keeper, skipGenesisInvariants bool) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{},
keeper: keeper,
legacySubspace: ss,
skipGenesisInvariants: skipGenesisInvariants,
}
@ -136,7 +131,7 @@ func AddModuleInitFlags(startCmd *cobra.Command) {
func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
m := keeper.NewMigrator(am.keeper, am.legacySubspace)
m := keeper.NewMigrator(am.keeper)
if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err))
}
@ -192,9 +187,6 @@ type ModuleInputs struct {
BankKeeper types.SupplyKeeper
AddressCodec address.Codec
// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace exported.Subspace `optional:"true"`
}
type ModuleOutputs struct {
@ -236,7 +228,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
skipGenesisInvariants = cast.ToBool(in.AppOpts.Get(FlagSkipGenesisInvariants))
}
m := NewAppModule(k, skipGenesisInvariants, in.LegacySubspace)
m := NewAppModule(k, skipGenesisInvariants)
return ModuleOutputs{CrisisKeeper: k, Module: m}
}

View File

@ -1,18 +0,0 @@
package exported
import (
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)
type (
ParamSet = paramtypes.ParamSet
// Subspace defines an interface that implements the legacy x/params Subspace
// type.
//
// NOTE: This is used solely for migration of x/params managed parameters.
ParamSubspace interface {
Get(ctx sdk.Context, key []byte, ptr interface{})
}
)

View File

@ -2,40 +2,34 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/exported"
v2 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v2"
v3 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v3"
v4 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v4"
v5 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v5"
)
// Migrator is a struct for handling in-place store migrations.
type Migrator struct {
keeper *Keeper
legacySubspace exported.ParamSubspace
keeper *Keeper
}
// NewMigrator returns a new Migrator.
func NewMigrator(keeper *Keeper, legacySubspace exported.ParamSubspace) Migrator {
func NewMigrator(keeper *Keeper) Migrator {
return Migrator{
keeper: keeper,
legacySubspace: legacySubspace,
keeper: keeper,
}
}
// Migrate1to2 migrates from version 1 to 2.
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
return v2.MigrateStore(ctx, m.keeper.storeService, m.keeper.cdc)
return nil
}
// Migrate2to3 migrates from version 2 to 3.
func (m Migrator) Migrate2to3(ctx sdk.Context) error {
return v3.MigrateStore(ctx, m.keeper.storeService, m.keeper.cdc)
return nil
}
// Migrate3to4 migrates from version 3 to 4.
func (m Migrator) Migrate3to4(ctx sdk.Context) error {
return v4.MigrateStore(ctx, m.keeper.storeService, m.legacySubspace, m.keeper.cdc)
return nil
}
// Migrate4to5 migrates from version 4 to 5.

View File

@ -1,164 +0,0 @@
package v1
// Package v1 (v0.40) is copy-pasted from:
// https://github.com/cosmos/cosmos-sdk/blob/v0.41.0/x/gov/types/keys.go
import (
"encoding/binary"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/kv"
)
const (
// ModuleName is the name of the module
ModuleName = "gov"
// StoreKey is the store key string for gov
StoreKey = ModuleName
// RouterKey is the message route for gov
RouterKey = ModuleName
// QuerierRoute is the querier route for gov
QuerierRoute = ModuleName
addrLen = 20
)
// Keys for governance store
// Items are stored with the following key: values
//
// - 0x00<proposalID_Bytes>: Proposal
//
// - 0x01<endTime_Bytes><proposalID_Bytes>: activeProposalID
//
// - 0x02<endTime_Bytes><proposalID_Bytes>: inactiveProposalID
//
// - 0x03: nextProposalID
//
// - 0x10<proposalID_Bytes><depositorAddr_Bytes>: Deposit
//
// - 0x20<proposalID_Bytes><voterAddr_Bytes>: Voter
var (
ProposalsKeyPrefix = []byte{0x00}
ActiveProposalQueuePrefix = []byte{0x01}
InactiveProposalQueuePrefix = []byte{0x02}
ProposalIDKey = []byte{0x03}
DepositsKeyPrefix = []byte{0x10}
VotesKeyPrefix = []byte{0x20}
)
var lenTime = len(sdk.FormatTimeBytes(time.Now()))
// GetProposalIDBytes returns the byte representation of the proposalID
func GetProposalIDBytes(proposalID uint64) (proposalIDBz []byte) {
proposalIDBz = make([]byte, 8)
binary.BigEndian.PutUint64(proposalIDBz, proposalID)
return
}
// GetProposalIDFromBytes returns proposalID in uint64 format from a byte array
func GetProposalIDFromBytes(bz []byte) (proposalID uint64) {
return binary.BigEndian.Uint64(bz)
}
// ProposalKey gets a specific proposal from the store
func ProposalKey(proposalID uint64) []byte {
return append(ProposalsKeyPrefix, GetProposalIDBytes(proposalID)...)
}
// ActiveProposalByTimeKey gets the active proposal queue key by endTime
func ActiveProposalByTimeKey(endTime time.Time) []byte {
return append(ActiveProposalQueuePrefix, sdk.FormatTimeBytes(endTime)...)
}
// ActiveProposalQueueKey returns the key for a proposalID in the activeProposalQueue
func ActiveProposalQueueKey(proposalID uint64, endTime time.Time) []byte {
return append(ActiveProposalByTimeKey(endTime), GetProposalIDBytes(proposalID)...)
}
// InactiveProposalByTimeKey gets the inactive proposal queue key by endTime
func InactiveProposalByTimeKey(endTime time.Time) []byte {
return append(InactiveProposalQueuePrefix, sdk.FormatTimeBytes(endTime)...)
}
// InactiveProposalQueueKey returns the key for a proposalID in the inactiveProposalQueue
func InactiveProposalQueueKey(proposalID uint64, endTime time.Time) []byte {
return append(InactiveProposalByTimeKey(endTime), GetProposalIDBytes(proposalID)...)
}
// DepositsKey gets the first part of the deposits key based on the proposalID
func DepositsKey(proposalID uint64) []byte {
return append(DepositsKeyPrefix, GetProposalIDBytes(proposalID)...)
}
// DepositKey key of a specific deposit from the store
func DepositKey(proposalID uint64, depositorAddr sdk.AccAddress) []byte {
return append(DepositsKey(proposalID), depositorAddr.Bytes()...)
}
// VotesKey gets the first part of the votes key based on the proposalID
func VotesKey(proposalID uint64) []byte {
return append(VotesKeyPrefix, GetProposalIDBytes(proposalID)...)
}
// VoteKey key of a specific vote from the store
func VoteKey(proposalID uint64, voterAddr sdk.AccAddress) []byte {
return append(VotesKey(proposalID), voterAddr.Bytes()...)
}
// Split keys function; used for iterators
// SplitProposalKey split the proposal key and returns the proposal id
func SplitProposalKey(key []byte) (proposalID uint64) {
kv.AssertKeyLength(key[1:], 8)
return GetProposalIDFromBytes(key[1:])
}
// SplitActiveProposalQueueKey split the active proposal key and returns the proposal id and endTime
func SplitActiveProposalQueueKey(key []byte) (proposalID uint64, endTime time.Time) {
return splitKeyWithTime(key)
}
// SplitInactiveProposalQueueKey split the inactive proposal key and returns the proposal id and endTime
func SplitInactiveProposalQueueKey(key []byte) (proposalID uint64, endTime time.Time) {
return splitKeyWithTime(key)
}
// SplitKeyDeposit split the deposits key and returns the proposal id and depositor address
func SplitKeyDeposit(key []byte) (proposalID uint64, depositorAddr sdk.AccAddress) {
return splitKeyWithAddress(key)
}
// SplitKeyVote split the votes key and returns the proposal id and voter address
func SplitKeyVote(key []byte) (proposalID uint64, voterAddr sdk.AccAddress) {
return splitKeyWithAddress(key)
}
// private functions
func splitKeyWithTime(key []byte) (proposalID uint64, endTime time.Time) {
kv.AssertKeyLength(key[1:], 8+lenTime)
endTime, err := sdk.ParseTimeBytes(key[1 : 1+lenTime])
if err != nil {
panic(err)
}
proposalID = GetProposalIDFromBytes(key[1+lenTime:])
return
}
func splitKeyWithAddress(key []byte) (proposalID uint64, addr sdk.AccAddress) {
kv.AssertKeyLength(key[1:], 8+addrLen)
kv.AssertKeyAtLeastLength(key, 10)
proposalID = GetProposalIDFromBytes(key[1:9])
addr = sdk.AccAddress(key[9:])
return
}

View File

@ -1,31 +0,0 @@
package v2
import (
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
// migrateJSONWeightedVotes migrates the ADR-037 weighted votes.
func migrateJSONWeightedVotes(oldVotes v1beta1.Votes) v1beta1.Votes {
newVotes := make(v1beta1.Votes, len(oldVotes))
for i, oldVote := range oldVotes {
newVotes[i] = migrateVote(oldVote)
}
return newVotes
}
// MigrateJSON accepts exported v1 (v0.40) x/gov genesis state and migrates it to
// v2 (v0.43) x/gov genesis state. The migration includes:
//
// - Gov weighted votes.
func MigrateJSON(oldState *v1beta1.GenesisState) *v1beta1.GenesisState {
return &v1beta1.GenesisState{
StartingProposalId: oldState.StartingProposalId,
Deposits: oldState.Deposits,
Votes: migrateJSONWeightedVotes(oldState.Votes),
Proposals: oldState.Proposals,
DepositParams: oldState.DepositParams,
VotingParams: oldState.VotingParams,
TallyParams: oldState.TallyParams,
}
}

View File

@ -1,125 +0,0 @@
package v2_test
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
v2 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v2"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
func TestMigrateJSON(t *testing.T) {
encodingConfig := moduletestutil.MakeTestEncodingConfig()
clientCtx := client.Context{}.
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
WithTxConfig(encodingConfig.TxConfig).
WithCodec(encodingConfig.Codec)
voter, err := sdk.AccAddressFromBech32("cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh")
require.NoError(t, err)
govGenState := &v1beta1.GenesisState{
Votes: v1beta1.Votes{
v1beta1.Vote{ProposalId: 1, Voter: voter.String(), Option: v1beta1.OptionAbstain},
v1beta1.Vote{ProposalId: 2, Voter: voter.String(), Option: v1beta1.OptionEmpty},
v1beta1.Vote{ProposalId: 3, Voter: voter.String(), Option: v1beta1.OptionNo},
v1beta1.Vote{ProposalId: 4, Voter: voter.String(), Option: v1beta1.OptionNoWithVeto},
v1beta1.Vote{ProposalId: 5, Voter: voter.String(), Option: v1beta1.OptionYes},
},
}
migrated := v2.MigrateJSON(govGenState)
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:
// - Votes are all ADR-037 weighted votes with weight 1.
expected := `{
"deposit_params": {
"max_deposit_period": "0s",
"min_deposit": []
},
"deposits": [],
"proposals": [],
"starting_proposal_id": "0",
"tally_params": {
"quorum": "0",
"threshold": "0",
"veto_threshold": "0"
},
"votes": [
{
"option": "VOTE_OPTION_UNSPECIFIED",
"options": [
{
"option": "VOTE_OPTION_ABSTAIN",
"weight": "1.000000000000000000"
}
],
"proposal_id": "1",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"option": "VOTE_OPTION_UNSPECIFIED",
"options": [
{
"option": "VOTE_OPTION_UNSPECIFIED",
"weight": "1.000000000000000000"
}
],
"proposal_id": "2",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"option": "VOTE_OPTION_UNSPECIFIED",
"options": [
{
"option": "VOTE_OPTION_NO",
"weight": "1.000000000000000000"
}
],
"proposal_id": "3",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"option": "VOTE_OPTION_UNSPECIFIED",
"options": [
{
"option": "VOTE_OPTION_NO_WITH_VETO",
"weight": "1.000000000000000000"
}
],
"proposal_id": "4",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"option": "VOTE_OPTION_UNSPECIFIED",
"options": [
{
"option": "VOTE_OPTION_YES",
"weight": "1.000000000000000000"
}
],
"proposal_id": "5",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
}
],
"voting_params": {
"voting_period": "0s"
}
}`
require.Equal(t, expected, string(indentedBz))
}

View File

@ -1,6 +0,0 @@
package v2
const (
// ModuleName is the name of the module
ModuleName = "gov"
)

View File

@ -1,102 +0,0 @@
package v2
import (
"fmt"
corestoretypes "cosmossdk.io/core/store"
"cosmossdk.io/store/prefix"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
"github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
const proposalIDLen = 8
// migratePrefixProposalAddress is a helper function that migrates all keys of format:
// <prefix_bytes><proposal_id (8 bytes)><address_bytes>
// into format:
// <prefix_bytes><proposal_id (8 bytes)><address_len (1 byte)><address_bytes>
func migratePrefixProposalAddress(store corestoretypes.KVStore, prefixBz []byte) error {
oldStore := prefix.NewStore(runtime.KVStoreAdapter(store), prefixBz)
oldStoreIter := oldStore.Iterator(nil, nil)
defer oldStoreIter.Close()
for ; oldStoreIter.Valid(); oldStoreIter.Next() {
proposalID := oldStoreIter.Key()[:proposalIDLen]
addr := oldStoreIter.Key()[proposalIDLen:]
newStoreKey := append(append(prefixBz, proposalID...), address.MustLengthPrefix(addr)...)
// Set new key on store. Values don't change.
err := store.Set(newStoreKey, oldStoreIter.Value())
if err != nil {
return err
}
oldStore.Delete(oldStoreIter.Key())
}
return nil
}
// migrateStoreWeightedVotes migrates a legacy vote to an ADR-037 weighted vote.
// Important: the `oldVote` has its `Option` field set, whereas the new weighted
// vote has its `Options` field set.
func migrateVote(oldVote v1beta1.Vote) v1beta1.Vote {
return v1beta1.Vote{
ProposalId: oldVote.ProposalId,
Voter: oldVote.Voter,
Options: v1beta1.NewNonSplitVoteOption(oldVote.Option),
}
}
// migrateStoreWeightedVotes migrates in-place all legacy votes to ADR-037 weighted votes.
func migrateStoreWeightedVotes(store corestoretypes.KVStore, cdc codec.BinaryCodec) error {
iterator := storetypes.KVStorePrefixIterator(runtime.KVStoreAdapter(store), types.VotesKeyPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var oldVote v1beta1.Vote
err := cdc.Unmarshal(iterator.Value(), &oldVote)
if err != nil {
return err
}
newVote := migrateVote(oldVote)
fmt.Println("migrateStoreWeightedVotes newVote=", newVote)
bz, err := cdc.Marshal(&newVote)
if err != nil {
return err
}
err = store.Set(iterator.Key(), bz)
if err != nil {
return err
}
}
return nil
}
// MigrateStore performs in-place store migrations from v1 (v0.40) to v2 (v0.43). The
// migration includes:
//
// - Change addresses to be length-prefixed.
// - Change all legacy votes to ADR-037 weighted votes.
func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec) error {
store := storeService.OpenKVStore(ctx)
err := migratePrefixProposalAddress(store, types.DepositsKeyPrefix)
if err != nil {
return err
}
err = migratePrefixProposalAddress(store, types.VotesKeyPrefix)
if err != nil {
return err
}
return migrateStoreWeightedVotes(store, cdc)
}

View File

@ -1,117 +0,0 @@
package v2_test
import (
"bytes"
"testing"
"time"
"github.com/stretchr/testify/require"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
v1 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v1"
v2 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v2"
"github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
func TestMigrateStore(t *testing.T) {
cdc := moduletestutil.MakeTestEncodingConfig().Codec
govKey := storetypes.NewKVStoreKey("gov")
ctx := testutil.DefaultContext(govKey, storetypes.NewTransientStoreKey("transient_test"))
store := ctx.KVStore(govKey)
_, _, addr1 := testdata.KeyTestPubAddr()
proposalID := uint64(6)
now := time.Now()
// Use dummy value for keys where we don't test values.
dummyValue := []byte("foo")
// Use real values for votes, as we're testing weighted votes.
oldVote := v1beta1.Vote{ProposalId: 1, Voter: "foobar", Option: v1beta1.OptionNoWithVeto}
oldVoteValue := cdc.MustMarshal(&oldVote)
newVote := v1beta1.Vote{ProposalId: 1, Voter: "foobar", Options: v1beta1.WeightedVoteOptions{{Option: v1beta1.OptionNoWithVeto, Weight: math.LegacyNewDec(1)}}}
newVoteValue := cdc.MustMarshal(&newVote)
testCases := []struct {
name string
oldKey, oldValue, newKey, newValue []byte
}{
{
"ProposalKey",
v1.ProposalKey(proposalID), dummyValue,
append(types.ProposalsKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...), dummyValue,
},
{
"ActiveProposalQueue",
v1.ActiveProposalQueueKey(proposalID, now), dummyValue,
activeProposalQueueKey(proposalID, now), dummyValue,
},
{
"InactiveProposalQueue",
v1.InactiveProposalQueueKey(proposalID, now), dummyValue,
inactiveProposalQueueKey(proposalID, now), dummyValue,
},
{
"ProposalIDKey",
v1.ProposalIDKey, dummyValue,
types.ProposalIDKey, dummyValue,
},
{
"DepositKey",
v1.DepositKey(proposalID, addr1), dummyValue,
depositKey(proposalID, addr1), dummyValue,
},
{
"VotesKeyPrefix",
v1.VoteKey(proposalID, addr1), oldVoteValue,
voteKey(proposalID, addr1), newVoteValue,
},
}
// Set all the old keys to the store
for _, tc := range testCases {
store.Set(tc.oldKey, tc.oldValue)
}
// Run migratio
storeService := runtime.NewKVStoreService(govKey)
err := v2.MigrateStore(ctx, storeService, cdc)
require.NoError(t, err)
// Make sure the new keys are set and old keys are deleted.
for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
if !bytes.Equal(tc.oldKey, tc.newKey) {
require.Nil(t, store.Get(tc.oldKey))
}
require.Equal(t, tc.newValue, store.Get(tc.newKey))
})
}
}
// TODO(tip): remove all the functions below once we delete the migrations
func depositKey(proposalID uint64, depositorAddr sdk.AccAddress) []byte {
return append(append(types.DepositsKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...), address.MustLengthPrefix(depositorAddr.Bytes())...)
}
func voteKey(proposalID uint64, addr sdk.AccAddress) []byte {
return append(append(types.VotesKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...), address.MustLengthPrefix(addr.Bytes())...)
}
func activeProposalQueueKey(proposalID uint64, endTime time.Time) []byte {
return append(append(types.ActiveProposalQueuePrefix, sdk.FormatTimeBytes(endTime)...), sdk.Uint64ToBigEndian(proposalID)...)
}
// InactiveProposalQueueKey returns the key for a proposalID in the inactiveProposalQueue
func inactiveProposalQueueKey(proposalID uint64, endTime time.Time) []byte {
return append(append(types.InactiveProposalQueuePrefix, sdk.FormatTimeBytes(endTime)...), sdk.Uint64ToBigEndian(proposalID)...)
}

View File

@ -8,11 +8,15 @@ import (
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
const (
// ModuleName is the name of the module
ModuleName = "gov"
)
// ConvertToLegacyProposal takes a new proposal and attempts to convert it to the
// legacy proposal format. This conversion is best effort. New proposal types that
// don't have a legacy message will return a "nil" content.
@ -131,113 +135,3 @@ func ConvertToLegacyDeposit(deposit *v1.Deposit) v1beta1.Deposit {
Amount: types.NewCoins(deposit.Amount...),
}
}
func convertToNewDeposits(oldDeps v1beta1.Deposits) v1.Deposits {
newDeps := make([]*v1.Deposit, len(oldDeps))
for i, oldDep := range oldDeps {
newDeps[i] = &v1.Deposit{
ProposalId: oldDep.ProposalId,
Depositor: oldDep.Depositor,
Amount: oldDep.Amount,
}
}
return newDeps
}
func convertToNewVotes(oldVotes v1beta1.Votes) (v1.Votes, error) {
newVotes := make([]*v1.Vote, len(oldVotes))
for i, oldVote := range oldVotes {
var newWVOs []*v1.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.
switch {
case oldVote.Options != nil:
newWVOs = make([]*v1.WeightedVoteOption, len(oldVote.Options))
for j, oldWVO := range oldVote.Options {
newWVOs[j] = v1.NewWeightedVoteOption(v1.VoteOption(oldWVO.Option), oldWVO.Weight)
}
case oldVote.Option != v1beta1.OptionEmpty:
newWVOs = v1.NewNonSplitVoteOption(v1.VoteOption(oldVote.Option))
default:
return nil, fmt.Errorf("vote does not have neither InterfaceRegistryOptions nor Option")
}
newVotes[i] = &v1.Vote{
ProposalId: oldVote.ProposalId,
Voter: oldVote.Voter,
Options: newWVOs,
}
}
return newVotes, nil
}
func convertToNewDepParams(oldDepParams v1beta1.DepositParams) v1.DepositParams {
return v1.DepositParams{
MinDeposit: oldDepParams.MinDeposit,
MaxDepositPeriod: &oldDepParams.MaxDepositPeriod,
}
}
func convertToNewVotingParams(oldVoteParams v1beta1.VotingParams) v1.VotingParams {
return v1.VotingParams{
VotingPeriod: &oldVoteParams.VotingPeriod,
}
}
func convertToNewTallyParams(oldTallyParams v1beta1.TallyParams) v1.TallyParams {
return v1.TallyParams{
Quorum: oldTallyParams.Quorum.String(),
Threshold: oldTallyParams.Threshold.String(),
VetoThreshold: oldTallyParams.VetoThreshold.String(),
}
}
func convertToNewProposal(oldProp v1beta1.Proposal) (v1.Proposal, error) {
msg, err := v1.NewLegacyContent(oldProp.GetContent(), authtypes.NewModuleAddress(ModuleName).String())
if err != nil {
return v1.Proposal{}, err
}
msgAny, err := codectypes.NewAnyWithValue(msg)
if err != nil {
return v1.Proposal{}, err
}
return v1.Proposal{
Id: oldProp.ProposalId,
Messages: []*codectypes.Any{msgAny},
Status: v1.ProposalStatus(oldProp.Status),
FinalTallyResult: &v1.TallyResult{
YesCount: oldProp.FinalTallyResult.Yes.String(),
NoCount: oldProp.FinalTallyResult.No.String(),
AbstainCount: oldProp.FinalTallyResult.Abstain.String(),
NoWithVetoCount: oldProp.FinalTallyResult.NoWithVeto.String(),
},
SubmitTime: &oldProp.SubmitTime,
DepositEndTime: &oldProp.DepositEndTime,
TotalDeposit: oldProp.TotalDeposit,
VotingStartTime: &oldProp.VotingStartTime,
VotingEndTime: &oldProp.VotingEndTime,
Title: oldProp.GetContent().GetTitle(),
Summary: oldProp.GetContent().GetDescription(),
}, nil
}
func convertToNewProposals(oldProps v1beta1.Proposals) (v1.Proposals, error) {
newProps := make([]*v1.Proposal, len(oldProps))
for i, oldProp := range oldProps {
p, err := convertToNewProposal(oldProp)
if err != nil {
return nil, err
}
newProps[i] = &p
}
return newProps, nil
}

View File

@ -1,34 +0,0 @@
package v3
import (
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
// MigrateJSON accepts exported v2 (v0.43) x/gov genesis state and migrates it to
// v3 (V0.46) x/gov genesis state. The migration includes:
//
// - Updating everything to v1.
// - Migrating proposals to be Msg-based.
func MigrateJSON(oldState *v1beta1.GenesisState) (*v1.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 &v1.GenesisState{
StartingProposalId: oldState.StartingProposalId,
Deposits: convertToNewDeposits(oldState.Deposits),
Votes: newVotes,
Proposals: newProps,
DepositParams: &depParams,
VotingParams: &votingParms,
TallyParams: &tallyParams,
}, nil
}

View File

@ -1,165 +0,0 @@
package v3_test
import (
"encoding/json"
"testing"
"time"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"
sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/gov"
v3 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v3"
"github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
var voter = sdk.MustAccAddressFromBech32("cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh")
func TestMigrateJSON(t *testing.T) {
encodingConfig := moduletestutil.MakeTestEncodingConfig(gov.AppModuleBasic{})
clientCtx := client.Context{}.
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
WithTxConfig(encodingConfig.TxConfig).
WithCodec(encodingConfig.Codec)
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", sdkmath.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 := v3.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().(*v1.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 := `{
"constitution": "",
"deposit_params": {
"max_deposit_period": "172800s",
"min_deposit": [
{
"amount": "10000000",
"denom": "stake"
}
]
},
"deposits": [],
"params": null,
"proposals": [
{
"deposit_end_time": "2001-09-09T01:46:40Z",
"expedited": false,
"failed_reason": "",
"final_tally_result": {
"abstain_count": "0",
"no_count": "0",
"no_with_veto_count": "0",
"yes_count": "0"
},
"id": "1",
"messages": [
{
"@type": "/cosmos.gov.v1.MsgExecLegacyContent",
"authority": "cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn",
"content": {
"@type": "/cosmos.gov.v1beta1.TextProposal",
"description": "my desc",
"title": "my title"
}
}
],
"metadata": "",
"proposer": "",
"status": "PROPOSAL_STATUS_DEPOSIT_PERIOD",
"submit_time": "2001-09-09T01:46:40Z",
"summary": "my desc",
"title": "my title",
"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": [
{
"metadata": "",
"options": [
{
"option": "VOTE_OPTION_ABSTAIN",
"weight": "1.000000000000000000"
}
],
"proposal_id": "1",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
},
{
"metadata": "",
"options": [
{
"option": "VOTE_OPTION_NO",
"weight": "1.000000000000000000"
}
],
"proposal_id": "2",
"voter": "cosmos1fl48vsnmsdzcv85q5d2q4z5ajdha8yu34mf0eh"
}
],
"voting_params": {
"voting_period": "172800s"
}
}`
require.Equal(t, expected, string(indentedBz))
}

View File

@ -1,6 +0,0 @@
package v3
const (
// ModuleName is the name of the module
ModuleName = "gov"
)

View File

@ -1,98 +0,0 @@
package v3
import (
corestoretypes "cosmossdk.io/core/store"
"cosmossdk.io/store/prefix"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
sdk "github.com/cosmos/cosmos-sdk/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v1"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
// migrateProposals migrates all legacy proposals into MsgExecLegacyContent
// proposals.
func migrateProposals(store storetypes.KVStore, cdc codec.BinaryCodec) error {
propStore := prefix.NewStore(store, v1.ProposalsKeyPrefix)
iter := propStore.Iterator(nil, nil)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
var oldProp govv1beta1.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
}
// migrateVotes migrates all v1beta1 weighted votes (with sdk.Dec as weight)
// to v1 weighted votes (with string as weight)
func migrateVotes(store storetypes.KVStore, cdc codec.BinaryCodec) error {
votesStore := prefix.NewStore(store, v1.VotesKeyPrefix)
iter := votesStore.Iterator(nil, nil)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
var oldVote govv1beta1.Vote
err := cdc.Unmarshal(iter.Value(), &oldVote)
if err != nil {
return err
}
newVote := govv1.Vote{
ProposalId: oldVote.ProposalId,
Voter: oldVote.Voter,
}
newOptions := make([]*govv1.WeightedVoteOption, len(oldVote.Options))
for i, o := range oldVote.Options {
newOptions[i] = &govv1.WeightedVoteOption{
Option: govv1.VoteOption(o.Option),
Weight: o.Weight.String(), // Convert to decimal string
}
}
newVote.Options = newOptions
bz, err := cdc.Marshal(&newVote)
if err != nil {
return err
}
// Set new value on store.
votesStore.Set(iter.Key(), bz)
}
return nil
}
// MigrateStore performs in-place store migrations from v2 (v0.43) to v3 (v0.46). The
// migration includes:
//
// - Migrate proposals to be Msg-based.
func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec) error {
store := storeService.OpenKVStore(ctx)
if err := migrateVotes(runtime.KVStoreAdapter(store), cdc); err != nil {
return err
}
return migrateProposals(runtime.KVStoreAdapter(store), cdc)
}

View File

@ -1,98 +0,0 @@
package v3_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/gov"
v1gov "github.com/cosmos/cosmos-sdk/x/gov/migrations/v1"
v3gov "github.com/cosmos/cosmos-sdk/x/gov/migrations/v3"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
func TestMigrateStore(t *testing.T) {
cdc := moduletestutil.MakeTestEncodingConfig(gov.AppModuleBasic{}).Codec
govKey := storetypes.NewKVStoreKey("gov")
ctx := testutil.DefaultContext(govKey, storetypes.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(v1beta1.NewTextProposal("my title 2", "my desc 2"), 2, propTime, propTime)
require.NoError(t, err)
require.NoError(t, err)
prop2Bz, err := cdc.Marshal(&prop2)
require.NoError(t, err)
store.Set(v1gov.ProposalKey(prop1.ProposalId), prop1Bz)
store.Set(v1gov.ProposalKey(prop2.ProposalId), prop2Bz)
// Vote on prop 1
options := []v1beta1.WeightedVoteOption{
{Option: v1beta1.OptionNo, Weight: math.LegacyMustNewDecFromStr("0.3")},
{Option: v1beta1.OptionYes, Weight: math.LegacyMustNewDecFromStr("0.7")},
}
vote1 := v1beta1.Vote{ProposalId: 1, Voter: voter.String(), Options: options}
vote1Bz := cdc.MustMarshal(&vote1)
store.Set(v1gov.VoteKey(1, voter), vote1Bz)
// Run migrations.
storeService := runtime.NewKVStoreService(govKey)
err = v3gov.MigrateStore(ctx, storeService, cdc)
require.NoError(t, err)
var newProp1 v1.Proposal
err = cdc.Unmarshal(store.Get(v1gov.ProposalKey(prop1.ProposalId)), &newProp1)
require.NoError(t, err)
compareProps(t, prop1, newProp1)
var newProp2 v1.Proposal
err = cdc.Unmarshal(store.Get(v1gov.ProposalKey(prop2.ProposalId)), &newProp2)
require.NoError(t, err)
compareProps(t, prop2, newProp2)
var newVote1 v1.Vote
err = cdc.Unmarshal(store.Get(v1gov.VoteKey(prop1.ProposalId, voter)), &newVote1)
require.NoError(t, err)
// Without the votes migration, we would have 300000000000000000 in state,
// because of how sdk.Dec stores itself in state.
require.Equal(t, "0.300000000000000000", newVote1.Options[0].Weight)
require.Equal(t, "0.700000000000000000", newVote1.Options[1].Weight)
}
func compareProps(t *testing.T, oldProp v1beta1.Proposal, newProp v1.Proposal) {
t.Helper()
require.Equal(t, oldProp.ProposalId, newProp.Id)
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.YesCount)
require.Equal(t, oldProp.FinalTallyResult.No.String(), newProp.FinalTallyResult.NoCount)
require.Equal(t, oldProp.FinalTallyResult.NoWithVeto.String(), newProp.FinalTallyResult.NoWithVetoCount)
require.Equal(t, oldProp.FinalTallyResult.Abstain.String(), newProp.FinalTallyResult.AbstainCount)
newContent := newProp.Messages[0].GetCachedValue().(*v1.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())
}

View File

@ -1,41 +0,0 @@
package v4
import (
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
)
// MigrateJSON accepts exported v3 (v0.46) x/gov genesis state and migrates it to
// v4 (v0.47) x/gov genesis state. The migration includes:
//
// Params migrations from x/params to gov
// Addition of the new min initial deposit ratio parameter that is set to 0 by default.
// Proposals in voting period are tracked in a separate index.
func MigrateJSON(oldState *v1.GenesisState) (*v1.GenesisState, error) {
defaultParams := v1.DefaultParams()
params := v1.NewParams(
oldState.DepositParams.MinDeposit,
defaultParams.ExpeditedMinDeposit,
*oldState.DepositParams.MaxDepositPeriod,
*oldState.VotingParams.VotingPeriod,
*defaultParams.ExpeditedVotingPeriod,
oldState.TallyParams.Quorum,
oldState.TallyParams.Threshold,
defaultParams.ExpeditedThreshold,
oldState.TallyParams.VetoThreshold,
defaultParams.MinInitialDepositRatio,
defaultParams.ProposalCancelRatio,
defaultParams.ProposalCancelDest,
defaultParams.BurnProposalDepositPrevote,
defaultParams.BurnVoteQuorum,
defaultParams.BurnVoteVeto,
)
return &v1.GenesisState{
StartingProposalId: oldState.StartingProposalId,
Deposits: oldState.Deposits,
Votes: oldState.Votes,
Proposals: oldState.Proposals,
Params: &params,
}, nil
}

View File

@ -1,98 +0,0 @@
package v4_test
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/gov"
v4 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v4"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
)
func TestMigrateJSON(t *testing.T) {
encodingConfig := moduletestutil.MakeTestEncodingConfig(gov.AppModuleBasic{})
clientCtx := client.Context{}.
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
WithTxConfig(encodingConfig.TxConfig).
WithCodec(encodingConfig.Codec)
govGenState := v1.DefaultGenesisState()
oldGovState := &v1.GenesisState{
StartingProposalId: govGenState.StartingProposalId,
Deposits: govGenState.Deposits,
Votes: govGenState.Votes,
Proposals: govGenState.Proposals,
DepositParams: &v1.DepositParams{
MinDeposit: govGenState.Params.MinDeposit,
MaxDepositPeriod: govGenState.Params.MaxDepositPeriod,
},
VotingParams: &v1.VotingParams{
VotingPeriod: govGenState.Params.VotingPeriod,
},
TallyParams: &v1.TallyParams{
Quorum: govGenState.Params.Quorum,
Threshold: govGenState.Params.Threshold,
VetoThreshold: govGenState.Params.VetoThreshold,
},
}
migrated, err := v4.MigrateJSON(oldGovState)
require.NoError(t, err)
require.Equal(t, migrated, govGenState)
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 := `{
"constitution": "",
"deposit_params": null,
"deposits": [],
"params": {
"burn_proposal_deposit_prevote": false,
"burn_vote_quorum": false,
"burn_vote_veto": true,
"expedited_min_deposit": [
{
"amount": "50000000",
"denom": "stake"
}
],
"expedited_threshold": "0.667000000000000000",
"expedited_voting_period": "86400s",
"max_deposit_period": "172800s",
"min_deposit": [
{
"amount": "10000000",
"denom": "stake"
}
],
"min_initial_deposit_ratio": "0.000000000000000000",
"proposal_cancel_dest": "",
"proposal_cancel_ratio": "0.500000000000000000",
"quorum": "0.334000000000000000",
"threshold": "0.500000000000000000",
"veto_threshold": "0.334000000000000000",
"voting_period": "172800s"
},
"proposals": [],
"starting_proposal_id": "1",
"tally_params": null,
"votes": [],
"voting_params": null
}`
require.Equal(t, expected, string(indentedBz))
}

View File

@ -1,28 +0,0 @@
package v4
import "encoding/binary"
const (
// ModuleName is the name of the module
ModuleName = "gov"
)
var (
// ParamsKey is the key of x/gov params
ParamsKey = []byte{0x30}
// - 0x04<proposalID_Bytes>: ProposalContents
VotingPeriodProposalKeyPrefix = []byte{0x04}
)
// VotingPeriodProposalKey gets if a proposal is in voting period.
func VotingPeriodProposalKey(proposalID uint64) []byte {
return append(VotingPeriodProposalKeyPrefix, GetProposalIDBytes(proposalID)...)
}
// GetProposalIDBytes returns the byte representation of the proposalID
func GetProposalIDBytes(proposalID uint64) (proposalIDBz []byte) {
proposalIDBz = make([]byte, 8)
binary.BigEndian.PutUint64(proposalIDBz, proposalID)
return
}

View File

@ -1,138 +0,0 @@
package v4
import (
"fmt"
"sort"
corestoretypes "cosmossdk.io/core/store"
"cosmossdk.io/store/prefix"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/runtime"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/exported"
v1 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
)
func migrateParams(ctx sdk.Context, store storetypes.KVStore, legacySubspace exported.ParamSubspace, cdc codec.BinaryCodec) error {
dp := govv1.DepositParams{}
vp := govv1.VotingParams{}
tp := govv1.TallyParams{}
legacySubspace.Get(ctx, govv1.ParamStoreKeyDepositParams, &dp)
legacySubspace.Get(ctx, govv1.ParamStoreKeyVotingParams, &vp)
legacySubspace.Get(ctx, govv1.ParamStoreKeyTallyParams, &tp)
defaultParams := govv1.DefaultParams()
params := govv1.NewParams(
dp.MinDeposit,
defaultParams.ExpeditedMinDeposit,
*dp.MaxDepositPeriod,
*vp.VotingPeriod,
*defaultParams.ExpeditedVotingPeriod,
tp.Quorum,
tp.Threshold,
defaultParams.ExpeditedThreshold,
tp.VetoThreshold,
defaultParams.MinInitialDepositRatio,
defaultParams.ProposalCancelRatio,
defaultParams.ProposalCancelDest,
defaultParams.BurnProposalDepositPrevote,
defaultParams.BurnVoteQuorum,
defaultParams.BurnVoteVeto,
)
bz, err := cdc.Marshal(&params)
if err != nil {
return err
}
store.Set(ParamsKey, bz)
return nil
}
func migrateProposalVotingPeriod(ctx sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec) error {
propStore := prefix.NewStore(store, v1.ProposalsKeyPrefix)
iter := propStore.Iterator(nil, nil)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
var prop govv1.Proposal
err := cdc.Unmarshal(iter.Value(), &prop)
if err != nil {
return err
}
if prop.Status == govv1.StatusVotingPeriod {
store.Set(VotingPeriodProposalKey(prop.Id), []byte{1})
}
}
return nil
}
// MigrateStore performs in-place store migrations from v3 (v0.46) to v4 (v0.47). The
// migration includes:
//
// Params migrations from x/params to gov
// Addition of the new min initial deposit ratio parameter that is set to 0 by default.
// Proposals in voting period are tracked in a separate index.
func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, legacySubspace exported.ParamSubspace, cdc codec.BinaryCodec) error {
store := runtime.KVStoreAdapter(storeService.OpenKVStore(ctx))
if err := migrateProposalVotingPeriod(ctx, store, cdc); err != nil {
return err
}
return migrateParams(ctx, store, legacySubspace, cdc)
}
// AddProposerAddressToProposal will add proposer to proposal and set to the store. This function is optional.
func AddProposerAddressToProposal(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec, proposals map[uint64]string) error {
proposalIDs := make([]uint64, 0, len(proposals))
for proposalID := range proposals {
proposalIDs = append(proposalIDs, proposalID)
}
// sort the proposalIDs
sort.Slice(proposalIDs, func(i, j int) bool { return proposalIDs[i] < proposalIDs[j] })
store := runtime.KVStoreAdapter(storeService.OpenKVStore(ctx))
for _, proposalID := range proposalIDs {
if len(proposals[proposalID]) == 0 {
return fmt.Errorf("found missing proposer for proposal ID: %d", proposalID)
}
if _, err := sdk.AccAddressFromBech32(proposals[proposalID]); err != nil {
return fmt.Errorf("invalid proposer address : %s", proposals[proposalID])
}
bz := store.Get(append(types.ProposalsKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...))
var proposal govv1.Proposal
if err := cdc.Unmarshal(bz, &proposal); err != nil {
panic(err)
}
// Check if proposal is active
if proposal.Status != govv1.ProposalStatus_PROPOSAL_STATUS_VOTING_PERIOD &&
proposal.Status != govv1.ProposalStatus_PROPOSAL_STATUS_DEPOSIT_PERIOD {
return fmt.Errorf("invalid proposal : %s, proposal not active", proposals[proposalID])
}
proposal.Proposer = proposals[proposalID]
// set the new proposal with proposer
bz, err := cdc.Marshal(&proposal)
if err != nil {
panic(err)
}
store.Set(append(types.ProposalsKeyPrefix, sdk.Uint64ToBigEndian(proposalID)...), bz)
}
return nil
}

View File

@ -1,138 +0,0 @@
package v4_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/bank"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/gov"
v1gov "github.com/cosmos/cosmos-sdk/x/gov/migrations/v1"
v4 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v4"
"github.com/cosmos/cosmos-sdk/x/gov/types"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
"github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)
var (
_, _, addr = testdata.KeyTestPubAddr()
govAcct = authtypes.NewModuleAddress(types.ModuleName)
TestProposal = getTestProposal()
)
type mockSubspace struct {
dp v1.DepositParams
vp v1.VotingParams
tp v1.TallyParams
}
func newMockSubspace(p v1.Params) mockSubspace {
return mockSubspace{
dp: v1.DepositParams{
MinDeposit: p.MinDeposit,
MaxDepositPeriod: p.MaxDepositPeriod,
},
vp: v1.VotingParams{
VotingPeriod: p.VotingPeriod,
},
tp: v1.TallyParams{
Quorum: p.Quorum,
Threshold: p.Threshold,
VetoThreshold: p.VetoThreshold,
},
}
}
func (ms mockSubspace) Get(ctx sdk.Context, key []byte, ptr interface{}) {
switch string(key) {
case string(v1.ParamStoreKeyDepositParams):
*ptr.(*v1.DepositParams) = ms.dp
case string(v1.ParamStoreKeyVotingParams):
*ptr.(*v1.VotingParams) = ms.vp
case string(v1.ParamStoreKeyTallyParams):
*ptr.(*v1.TallyParams) = ms.tp
}
}
func TestMigrateStore(t *testing.T) {
cdc := moduletestutil.MakeTestEncodingConfig(gov.AppModuleBasic{}, bank.AppModuleBasic{}).Codec
govKey := storetypes.NewKVStoreKey("gov")
ctx := testutil.DefaultContext(govKey, storetypes.NewTransientStoreKey("transient_test"))
store := ctx.KVStore(govKey)
legacySubspace := newMockSubspace(v1.DefaultParams())
propTime := time.Unix(1e9, 0)
// Create 2 proposals
prop1Content, err := v1.NewLegacyContent(v1beta1.NewTextProposal("Test", "description"), authtypes.NewModuleAddress("gov").String())
require.NoError(t, err)
proposal1, err := v1.NewProposal([]sdk.Msg{prop1Content}, 1, propTime, propTime, "some metadata for the legacy content", "Test", "description", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false)
require.NoError(t, err)
prop1Bz, err := cdc.Marshal(&proposal1)
require.NoError(t, err)
store.Set(v1gov.ProposalKey(proposal1.Id), prop1Bz)
proposal2, err := v1.NewProposal(getTestProposal(), 2, propTime, propTime, "some metadata for the legacy content", "Test", "description", sdk.AccAddress("cosmos1ghekyjucln7y67ntx7cf27m9dpuxxemn4c8g4r"), false)
proposal2.Status = v1.StatusVotingPeriod
require.NoError(t, err)
prop2Bz, err := cdc.Marshal(&proposal2)
require.NoError(t, err)
store.Set(v1gov.ProposalKey(proposal2.Id), prop2Bz)
// Run migrations.
storeService := runtime.NewKVStoreService(govKey)
err = v4.MigrateStore(ctx, storeService, legacySubspace, cdc)
require.NoError(t, err)
// Check params
var params v1.Params
bz := store.Get(v4.ParamsKey)
require.NoError(t, cdc.Unmarshal(bz, &params))
require.NotNil(t, params)
require.Equal(t, legacySubspace.dp.MinDeposit, params.MinDeposit)
require.Equal(t, legacySubspace.dp.MaxDepositPeriod, params.MaxDepositPeriod)
require.Equal(t, legacySubspace.vp.VotingPeriod, params.VotingPeriod)
require.Equal(t, legacySubspace.tp.Quorum, params.Quorum)
require.Equal(t, legacySubspace.tp.Threshold, params.Threshold)
require.Equal(t, legacySubspace.tp.VetoThreshold, params.VetoThreshold)
require.Equal(t, math.LegacyZeroDec().String(), params.MinInitialDepositRatio)
// Check proposals' status
var migratedProp1 v1.Proposal
bz = store.Get(v1gov.ProposalKey(proposal1.Id))
require.NoError(t, cdc.Unmarshal(bz, &migratedProp1))
require.Equal(t, v1.StatusDepositPeriod, migratedProp1.Status)
var migratedProp2 v1.Proposal
bz = store.Get(v1gov.ProposalKey(proposal2.Id))
require.NoError(t, cdc.Unmarshal(bz, &migratedProp2))
require.Equal(t, v1.StatusVotingPeriod, migratedProp2.Status)
// Check if proposal 2 is in the new store but not proposal 1
require.Nil(t, store.Get(v4.VotingPeriodProposalKey(proposal1.Id)))
require.Equal(t, []byte{0x1}, store.Get(v4.VotingPeriodProposalKey(proposal2.Id)))
}
func getTestProposal() []sdk.Msg {
legacyProposalMsg, err := v1.NewLegacyContent(v1beta1.NewTextProposal("Title", "description"), authtypes.NewModuleAddress(types.ModuleName).String())
if err != nil {
panic(err)
}
return []sdk.Msg{
banktypes.NewMsgSend(govAcct, addr, sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(1000)))),
legacyProposalMsg,
}
}

View File

@ -5,17 +5,19 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
v4 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v4"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
)
// ParamsKey is the key of x/gov params
var ParamsKey = []byte{0x30}
// MigrateStore performs in-place store migrations from v4 (v0.47) to v5 (v0.50). The
// migration includes:
//
// Addition of the new proposal expedited parameters that are set to 0 by default.
func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, cdc codec.BinaryCodec) error {
store := storeService.OpenKVStore(ctx)
paramsBz, err := store.Get(v4.ParamsKey)
paramsBz, err := store.Get(ParamsKey)
if err != nil {
return err
}
@ -38,5 +40,5 @@ func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, c
return err
}
return store.Set(v4.ParamsKey, bz)
return store.Set(ParamsKey, bz)
}

View File

@ -13,7 +13,6 @@ import (
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/cosmos/cosmos-sdk/x/gov"
v4 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v4"
v5 "github.com/cosmos/cosmos-sdk/x/gov/migrations/v5"
v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
)
@ -25,7 +24,7 @@ func TestMigrateStore(t *testing.T) {
store := ctx.KVStore(govKey)
var params v1.Params
bz := store.Get(v4.ParamsKey)
bz := store.Get(v5.ParamsKey)
require.NoError(t, cdc.Unmarshal(bz, &params))
require.NotNil(t, params)
require.Equal(t, "", params.ExpeditedThreshold)
@ -37,7 +36,7 @@ func TestMigrateStore(t *testing.T) {
require.NoError(t, err)
// Check params
bz = store.Get(v4.ParamsKey)
bz = store.Get(v5.ParamsKey)
require.NoError(t, cdc.Unmarshal(bz, &params))
require.NotNil(t, params)
require.Equal(t, v1.DefaultParams().ExpeditedMinDeposit, params.ExpeditedMinDeposit)

View File

@ -134,22 +134,18 @@ type AppModule struct {
keeper *keeper.Keeper
accountKeeper govtypes.AccountKeeper
bankKeeper govtypes.BankKeeper
// legacySubspace is used solely for migration of x/params managed parameters
legacySubspace govtypes.ParamSubspace
}
// NewAppModule creates a new AppModule object
func NewAppModule(
cdc codec.Codec, keeper *keeper.Keeper,
ak govtypes.AccountKeeper, bk govtypes.BankKeeper, ss govtypes.ParamSubspace,
ak govtypes.AccountKeeper, bk govtypes.BankKeeper,
) AppModule {
return AppModule{
AppModuleBasic: AppModuleBasic{cdc: cdc, ac: ak.AddressCodec()},
keeper: keeper,
accountKeeper: ak,
bankKeeper: bk,
legacySubspace: ss,
}
}
@ -166,6 +162,10 @@ func init() {
appmodule.Invoke(InvokeAddRoutes, InvokeSetHooks))
}
func ProvideKeyTable() paramtypes.KeyTable {
return v1.ParamKeyTable() //nolint:staticcheck // we still need this for upgrades
}
type ModuleInputs struct {
depinject.In
@ -179,9 +179,6 @@ type ModuleInputs struct {
BankKeeper govtypes.BankKeeper
StakingKeeper govtypes.StakingKeeper
DistributionKeeper govtypes.DistributionKeeper
// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace govtypes.ParamSubspace `optional:"true"`
}
type ModuleOutputs struct {
@ -215,16 +212,12 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
defaultConfig,
authority.String(),
)
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.LegacySubspace)
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper)
hr := v1beta1.HandlerRoute{Handler: v1beta1.ProposalHandler, RouteKey: govtypes.RouterKey}
return ModuleOutputs{Module: m, Keeper: k, HandlerRoute: hr}
}
func ProvideKeyTable() paramtypes.KeyTable {
return v1.ParamKeyTable() //nolint:staticcheck // we still need this for upgrades
}
func InvokeAddRoutes(keeper *keeper.Keeper, routes []v1beta1.HandlerRoute) {
if keeper == nil || routes == nil {
return
@ -282,7 +275,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
v1beta1.RegisterQueryServer(cfg.QueryServer(), legacyQueryServer)
v1.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServer(am.keeper))
m := keeper.NewMigrator(am.keeper, am.legacySubspace)
m := keeper.NewMigrator(am.keeper)
if err := cfg.RegisterMigration(govtypes.ModuleName, 1, m.Migrate1to2); err != nil {
panic(fmt.Sprintf("failed to migrate x/gov from version 1 to 2: %v", err))
}

View File

@ -10,12 +10,6 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// ParamSubspace defines the expected Subspace interface for parameters (noalias)
type ParamSubspace interface {
Get(ctx sdk.Context, key []byte, ptr interface{})
Set(ctx sdk.Context, key []byte, param interface{})
}
// StakingKeeper expected staking keeper (Validator and Delegator sets) (noalias)
type StakingKeeper interface {
ValidatorAddressCodec() addresscodec.Codec

View File

@ -1,18 +0,0 @@
package exported
import (
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)
type (
ParamSet = paramtypes.ParamSet
// Subspace defines an interface that implements the legacy x/params Subspace
// type.
//
// NOTE: This is used solely for migration of x/params managed parameters.
Subspace interface {
GetParamSet(ctx sdk.Context, ps ParamSet)
}
)

View File

@ -2,21 +2,17 @@ package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/mint/exported"
v2 "github.com/cosmos/cosmos-sdk/x/mint/migrations/v2"
)
// Migrator is a struct for handling in-place state migrations.
type Migrator struct {
keeper Keeper
legacySubspace exported.Subspace
keeper Keeper
}
// NewMigrator returns Migrator instance for the state migration.
func NewMigrator(k Keeper, ss exported.Subspace) Migrator {
func NewMigrator(k Keeper) Migrator {
return Migrator{
keeper: k,
legacySubspace: ss,
keeper: k,
}
}
@ -25,5 +21,5 @@ func NewMigrator(k Keeper, ss exported.Subspace) Migrator {
// and managed by the x/params modules and stores them directly into the x/mint
// module state.
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
return v2.Migrate(ctx, m.keeper.storeService.OpenKVStore(ctx), m.legacySubspace, m.keeper.cdc)
return nil
}

View File

@ -1,37 +0,0 @@
package v2
import (
storetypes "cosmossdk.io/core/store"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/mint/exported"
"github.com/cosmos/cosmos-sdk/x/mint/types"
)
const (
ModuleName = "mint"
)
var ParamsKey = []byte{0x01}
// Migrate migrates the x/mint module state from the consensus version 1 to
// version 2. Specifically, it takes the parameters that are currently stored
// and managed by the x/params modules and stores them directly into the x/mint
// module state.
func Migrate(
ctx sdk.Context,
store storetypes.KVStore,
legacySubspace exported.Subspace,
cdc codec.BinaryCodec,
) error {
var currParams types.Params
legacySubspace.GetParamSet(ctx, &currParams)
if err := currParams.Validate(); err != nil {
return err
}
bz := cdc.MustMarshal(&currParams)
return store.Set(ParamsKey, bz)
}

View File

@ -1,50 +0,0 @@
package v2_test
import (
"testing"
"github.com/stretchr/testify/require"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/mint/exported"
v2 "github.com/cosmos/cosmos-sdk/x/mint/migrations/v2"
"github.com/cosmos/cosmos-sdk/x/mint/types"
)
type mockSubspace struct {
ps types.Params
}
func newMockSubspace(ps types.Params) mockSubspace {
return mockSubspace{ps: ps}
}
func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps exported.ParamSet) {
*ps.(*types.Params) = ms.ps
}
func TestMigrate(t *testing.T) {
encCfg := moduletestutil.MakeTestEncodingConfig(mint.AppModuleBasic{})
cdc := encCfg.Codec
storeKey := storetypes.NewKVStoreKey(v2.ModuleName)
tKey := storetypes.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(storeKey, tKey)
kvStoreService := runtime.NewKVStoreService(storeKey)
store := kvStoreService.OpenKVStore(ctx)
legacySubspace := newMockSubspace(types.DefaultParams())
require.NoError(t, v2.Migrate(ctx, store, legacySubspace, cdc))
var res types.Params
bz, err := store.Get(v2.ParamsKey)
require.NoError(t, err)
require.NoError(t, cdc.Unmarshal(bz, &res))
require.Equal(t, legacySubspace.ps, res)
}

View File

@ -19,7 +19,6 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/mint/exported"
"github.com/cosmos/cosmos-sdk/x/mint/keeper"
"github.com/cosmos/cosmos-sdk/x/mint/simulation"
"github.com/cosmos/cosmos-sdk/x/mint/types"
@ -88,9 +87,6 @@ type AppModule struct {
keeper keeper.Keeper
authKeeper types.AccountKeeper
// legacySubspace is used solely for migration of x/params managed parameters
legacySubspace exported.Subspace
// inflationCalculator is used to calculate the inflation rate during BeginBlock.
// If inflationCalculator is nil, the default inflation calculation logic is used.
inflationCalculator types.InflationCalculationFn
@ -103,7 +99,6 @@ func NewAppModule(
keeper keeper.Keeper,
ak types.AccountKeeper,
ic types.InflationCalculationFn,
ss exported.Subspace,
) AppModule {
if ic == nil {
ic = types.DefaultInflationCalculationFn
@ -114,7 +109,6 @@ func NewAppModule(
keeper: keeper,
authKeeper: ak,
inflationCalculator: ic,
legacySubspace: ss,
}
}
@ -130,7 +124,7 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper))
types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServerImpl(am.keeper))
m := keeper.NewMigrator(am.keeper, am.legacySubspace)
m := keeper.NewMigrator(am.keeper)
if err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2); err != nil {
panic(fmt.Sprintf("failed to migrate x/%s from version 1 to 2: %v", types.ModuleName, err))
@ -202,9 +196,6 @@ type ModuleInputs struct {
Cdc codec.Codec
InflationCalculationFn types.InflationCalculationFn `optional:"true"`
// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace exported.Subspace `optional:"true"`
AccountKeeper types.AccountKeeper
BankKeeper types.BankKeeper
StakingKeeper types.StakingKeeper
@ -245,7 +236,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
)
// when no inflation calculation function is provided it will use the default types.DefaultInflationCalculationFn
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.InflationCalculationFn, in.LegacySubspace)
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.InflationCalculationFn)
return ModuleOutputs{MintKeeper: k, Module: m}
}