Fix migrate legacy params (#1729)

* Fix migrate legacy params

* Better tests

* Handle upgrade from wasmd 33 chains
This commit is contained in:
Alexander Peters
2023-11-21 08:56:41 +01:00
committed by GitHub
parent 9050b5fa4e
commit dffa3212fc
15 changed files with 1742 additions and 108 deletions

View File

@@ -8,6 +8,7 @@ import (
"path/filepath"
"sort"
"strings"
"sync"
abci "github.com/cometbft/cometbft/abci/types"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
@@ -27,10 +28,12 @@ import (
ibcfee "github.com/cosmos/ibc-go/v8/modules/apps/29-fee"
ibcfeekeeper "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/keeper"
ibcfeetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"
transfer "github.com/cosmos/ibc-go/v8/modules/apps/transfer"
"github.com/cosmos/ibc-go/v8/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/v8/modules/core"
ibcclienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" //nolint:staticcheck
ibcconnectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"
porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types"
ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported"
ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper"
@@ -240,6 +243,7 @@ type WasmApp struct {
// module configurator
configurator module.Configurator
once sync.Once
}
// NewWasmApp returns a reference to an initialized WasmApp.
@@ -920,6 +924,27 @@ func NewWasmApp(
return app
}
func (app *WasmApp) FinalizeBlock(req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) {
// when skipping sdk 47 for sdk 50, the upgrade handler is called too late in BaseApp
// this is a hack to ensure that the migration is executed when needed and not panics
app.once.Do(func() {
ctx := app.NewUncachedContext(false, tmproto.Header{})
if _, err := app.ConsensusParamsKeeper.Params(ctx, &consensusparamtypes.QueryParamsRequest{}); err != nil {
// prevents panic: consensus key is nil: collections: not found: key 'no_key' of type github.com/cosmos/gogoproto/tendermint.types.ConsensusParams
// sdk 47:
// Migrate Tendermint consensus parameters from x/params module to a dedicated x/consensus module.
// see https://github.com/cosmos/cosmos-sdk/blob/v0.47.0/simapp/upgrades.go#L66
baseAppLegacySS := app.GetSubspace(baseapp.Paramspace)
err := baseapp.MigrateParams(sdk.UnwrapSDKContext(ctx), baseAppLegacySS, app.ConsensusParamsKeeper.ParamsStore)
if err != nil {
panic(err)
}
}
})
return app.BaseApp.FinalizeBlock(req)
}
func (app *WasmApp) setAnteHandler(txConfig client.TxConfig, wasmConfig wasmtypes.WasmConfig, txCounterStoreKey *storetypes.KVStoreKey) {
anteHandler, err := NewAnteHandler(
HandlerOptions{
@@ -1174,10 +1199,15 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(slashingtypes.ModuleName)
paramsKeeper.Subspace(govtypes.ModuleName)
paramsKeeper.Subspace(crisistypes.ModuleName)
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibcexported.ModuleName)
paramsKeeper.Subspace(icahosttypes.SubModuleName)
paramsKeeper.Subspace(icacontrollertypes.SubModuleName)
// register the IBC key tables for legacy param subspaces
keyTable := ibcclienttypes.ParamKeyTable()
keyTable.RegisterParamSet(&ibcconnectiontypes.Params{})
paramsKeeper.Subspace(ibcexported.ModuleName).WithKeyTable(keyTable)
paramsKeeper.Subspace(ibctransfertypes.ModuleName).WithKeyTable(ibctransfertypes.ParamKeyTable())
paramsKeeper.Subspace(icacontrollertypes.SubModuleName).WithKeyTable(icacontrollertypes.ParamKeyTable())
paramsKeeper.Subspace(icahosttypes.SubModuleName).WithKeyTable(icahosttypes.ParamKeyTable())
paramsKeeper.Subspace(wasmtypes.ModuleName)
return paramsKeeper
}

View File

@@ -3,35 +3,49 @@ package app
import (
"fmt"
icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"
icahosttypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/host/types"
ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
ibcclienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" //nolint:staticcheck
ibcconnectiontypes "github.com/cosmos/ibc-go/v8/modules/core/03-connection/types"
ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported"
upgradetypes "cosmossdk.io/x/upgrade/types"
"github.com/cosmos/cosmos-sdk/baseapp"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/CosmWasm/wasmd/app/upgrades"
"github.com/CosmWasm/wasmd/app/upgrades/noop"
v050 "github.com/CosmWasm/wasmd/app/upgrades/v050"
v2 "github.com/CosmWasm/wasmd/x/wasm/migrations/v2"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
)
// Upgrades list of chain upgrades
var Upgrades = []upgrades.Upgrade{v050.Upgrade}
// RegisterUpgradeHandlers registers the chain upgrade handlers
func (app WasmApp) RegisterUpgradeHandlers() {
setupLegacyKeyTables(app.ParamsKeeper)
func (app *WasmApp) RegisterUpgradeHandlers() {
setupLegacyKeyTables(&app.ParamsKeeper)
if len(Upgrades) == 0 {
// always have a unique upgrade registered for the current version to test in system tests
Upgrades = append(Upgrades, noop.NewUpgrade(app.Version()))
}
keepers := upgrades.AppKeepers{AccountKeeper: app.AccountKeeper}
keepers := upgrades.AppKeepers{
AccountKeeper: &app.AccountKeeper,
ParamsKeeper: &app.ParamsKeeper,
ConsensusParamsKeeper: &app.ConsensusParamsKeeper,
CapabilityKeeper: app.CapabilityKeeper,
IBCKeeper: app.IBCKeeper,
Codec: app.appCodec,
GetStoreKey: app.GetKey,
}
app.GetStoreKeys()
// register all upgrade handlers
for _, upgrade := range Upgrades {
app.UpgradeKeeper.SetUpgradeHandler(
@@ -62,23 +76,31 @@ func (app WasmApp) RegisterUpgradeHandlers() {
}
}
func setupLegacyKeyTables(k paramskeeper.Keeper) {
// Set param key table for params module migration
func setupLegacyKeyTables(k *paramskeeper.Keeper) {
for _, subspace := range k.GetSubspaces() {
subspace := subspace
var keyTable paramstypes.KeyTable
switch subspace.Name() {
// ibc types
case ibcexported.ModuleName:
keyTable = ibcclienttypes.ParamKeyTable()
keyTable.RegisterParamSet(&ibcconnectiontypes.Params{})
case ibctransfertypes.ModuleName:
keyTable = ibctransfertypes.ParamKeyTable()
case icahosttypes.SubModuleName:
keyTable = icahosttypes.ParamKeyTable()
case icacontrollertypes.SubModuleName:
keyTable = icacontrollertypes.ParamKeyTable()
case authtypes.ModuleName:
keyTable = authtypes.ParamKeyTable() //nolint:staticcheck
case banktypes.ModuleName:
keyTable = banktypes.ParamKeyTable() //nolint:staticcheck
case stakingtypes.ModuleName:
keyTable = stakingtypes.ParamKeyTable() //nolint:staticcheck
case minttypes.ModuleName:
keyTable = minttypes.ParamKeyTable() //nolint:staticcheck
case distrtypes.ModuleName:
keyTable = distrtypes.ParamKeyTable() //nolint:staticcheck
case slashingtypes.ModuleName:
keyTable = slashingtypes.ParamKeyTable() //nolint:staticcheck
case govtypes.ModuleName:
keyTable = govv1.ParamKeyTable() //nolint:staticcheck
case crisistypes.ModuleName:
keyTable = crisistypes.ParamKeyTable() //nolint:staticcheck
// wasm
case wasmtypes.ModuleName:
keyTable = v2.ParamKeyTable() //nolint:staticcheck
default:
continue
}
@@ -87,4 +109,7 @@ func setupLegacyKeyTables(k paramskeeper.Keeper) {
subspace.WithKeyTable(keyTable)
}
}
// sdk 47
k.Subspace(baseapp.Paramspace).
WithKeyTable(paramstypes.ConsensusParamsKeyTable())
}

View File

@@ -3,15 +3,27 @@ package upgrades
import (
"context"
capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper"
ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper"
storetypes "cosmossdk.io/store/types"
upgradetypes "cosmossdk.io/x/upgrade/types"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/types/module"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
)
type AppKeepers struct {
authkeeper.AccountKeeper
AccountKeeper *authkeeper.AccountKeeper
ParamsKeeper *paramskeeper.Keeper
ConsensusParamsKeeper *consensusparamkeeper.Keeper
Codec codec.Codec
GetStoreKey func(storeKey string) *storetypes.KVStoreKey
CapabilityKeeper *capabilitykeeper.Keeper
IBCKeeper *ibckeeper.Keeper
}
type ModuleManager interface {
RunMigrations(ctx context.Context, cfg module.Configurator, fromVM module.VersionMap) (module.VersionMap, error)

View File

@@ -31,6 +31,7 @@ func CreateUpgradeHandler(
configurator module.Configurator,
ak *upgrades.AppKeepers,
) upgradetypes.UpgradeHandler {
// sdk 47 to sdk 50
return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
return mm.RunMigrations(ctx, configurator, fromVM)
}

View File

@@ -0,0 +1,73 @@
package v050
import (
"context"
capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
v6 "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/migrations/v6"
icacontrollertypes "github.com/cosmos/ibc-go/v8/modules/apps/27-interchain-accounts/controller/types"
ibctmmigrations "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint/migrations"
storetypes "cosmossdk.io/store/types"
circuittypes "cosmossdk.io/x/circuit/types"
"cosmossdk.io/x/nft"
upgradetypes "cosmossdk.io/x/upgrade/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
"github.com/cosmos/cosmos-sdk/x/group"
"github.com/CosmWasm/wasmd/app/upgrades"
)
// UpgradeName defines the on-chain upgrade name
const UpgradeName = "v0.50"
var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: storetypes.StoreUpgrades{
Added: []string{
// SDK 46
group.ModuleName,
nft.ModuleName,
// SDK 47
crisistypes.ModuleName,
consensusparamtypes.ModuleName,
// SDK 50
circuittypes.ModuleName,
},
Deleted: []string{},
},
}
func CreateUpgradeHandler(
mm upgrades.ModuleManager,
configurator module.Configurator,
ak *upgrades.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
// ibc v6
// NOTE: The moduleName arg of v6.CreateUpgradeHandler refers to the auth module ScopedKeeper name to which the channel capability should be migrated from.
// This should be the same string value provided upon instantiation of the ScopedKeeper with app.CapabilityKeeper.ScopeToModule()
const moduleName = icacontrollertypes.SubModuleName
if err := v6.MigrateICS27ChannelCapability(sdkCtx, ak.Codec, ak.GetStoreKey(capabilitytypes.ModuleName),
ak.CapabilityKeeper, moduleName); err != nil {
return nil, err
}
// ibc v7
if _, err := ibctmmigrations.PruneExpiredConsensusStates(sdkCtx, ak.Codec, ak.IBCKeeper.ClientKeeper); err != nil {
return nil, err
}
// sdk 47
// consensus params migration is done in app.go FinalizeBlock function to prevent panic
// sdk 50
return mm.RunMigrations(ctx, configurator, fromVM)
}
}

View File

@@ -37,7 +37,7 @@ func NewRootCmd() *cobra.Command {
cfg.Seal()
// we "pre"-instantiate the application for getting the injected/configured encoding configuration
// note, this is not necessary when using app wiring, as depinject can be directly used (see root_v2.go)
tempApp := app.NewWasmApp(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(tempDir()), []wasmkeeper.Option{})
tempApp := app.NewWasmApp(log.NewNopLogger(), dbm.NewMemDB(), nil, false, simtestutil.NewAppOptionsWithFlagHome(tempDir()), []wasmkeeper.Option{})
encodingConfig := params.EncodingConfig{
InterfaceRegistry: tempApp.InterfaceRegistry(),
Codec: tempApp.AppCodec(),

View File

@@ -3,20 +3,24 @@ package keeper_test
import (
"testing"
"github.com/cometbft/cometbft/libs/rand"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
upgradetypes "cosmossdk.io/x/upgrade/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/CosmWasm/wasmd/app"
v2 "github.com/CosmWasm/wasmd/x/wasm/migrations/v2"
"github.com/CosmWasm/wasmd/x/wasm/types"
)
func TestModuleMigrations(t *testing.T) {
wasmApp := app.Setup(t)
myAddress := sdk.AccAddress(rand.Bytes(address.Len))
upgradeHandler := func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { //nolint:unparam
return wasmApp.ModuleManager.RunMigrations(ctx, wasmApp.Configurator(), fromVM)
@@ -30,15 +34,15 @@ func TestModuleMigrations(t *testing.T) {
"with legacy params migrated": {
startVersion: 1,
setup: func(ctx sdk.Context) {
params := types.Params{
CodeUploadAccess: types.AllowNobody,
InstantiateDefaultPermission: types.AccessTypeNobody,
params := v2.Params{
CodeUploadAccess: v2.AccessConfig{Permission: v2.AccessTypeNobody},
InstantiateDefaultPermission: v2.AccessTypeNobody,
}
// upgrade code shipped with v0.40
// https://github.com/CosmWasm/wasmd/blob/v0.40.0/app/upgrades.go#L66
sp, _ := wasmApp.ParamsKeeper.GetSubspace(types.ModuleName)
keyTable := types.ParamKeyTable()
keyTable := v2.ParamKeyTable()
if !sp.HasKeyTable() {
sp.WithKeyTable(keyTable)
}
@@ -50,6 +54,29 @@ func TestModuleMigrations(t *testing.T) {
InstantiateDefaultPermission: types.AccessTypeNobody,
},
},
"with legacy one address type replaced": {
startVersion: 1,
setup: func(ctx sdk.Context) {
params := v2.Params{
CodeUploadAccess: v2.AccessConfig{Permission: v2.AccessTypeOnlyAddress, Address: myAddress.String()},
InstantiateDefaultPermission: v2.AccessTypeNobody,
}
// upgrade code shipped with v0.40
// https://github.com/CosmWasm/wasmd/blob/v0.40.0/app/upgrades.go#L66
sp, _ := wasmApp.ParamsKeeper.GetSubspace(types.ModuleName)
keyTable := v2.ParamKeyTable()
if !sp.HasKeyTable() {
sp.WithKeyTable(keyTable)
}
sp.SetParamSet(ctx, &params)
},
exp: types.Params{
CodeUploadAccess: types.AccessTypeAnyOfAddresses.With(myAddress),
InstantiateDefaultPermission: types.AccessTypeNobody,
},
},
"fresh from genesis": {
startVersion: wasmApp.ModuleManager.GetVersionMap()[types.ModuleName], // latest
setup: func(ctx sdk.Context) {},

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,142 @@
/*
NOTE: Usage of x/params to manage parameters is deprecated in favor of x/gov
controlled execution of MsgUpdateParams messages. These types remains solely
for migration purposes and will be removed in a future release.
*/
package v2
import (
"encoding/json"
"fmt"
"github.com/cosmos/gogoproto/jsonpb"
errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/CosmWasm/wasmd/x/wasm/types"
)
var (
ParamStoreKeyUploadAccess = []byte("uploadAccess")
ParamStoreKeyInstantiateAccess = []byte("instantiateAccess")
)
// Deprecated: Type declaration for parameters
func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
}
// ParamSetPairs returns the parameter set pairs.
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(ParamStoreKeyUploadAccess, &p.CodeUploadAccess, validateAccessConfig),
paramtypes.NewParamSetPair(ParamStoreKeyInstantiateAccess, &p.InstantiateDefaultPermission, validateAccessType),
}
}
func validateAccessConfig(i interface{}) error {
v, ok := i.(AccessConfig)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
return v.ValidateBasic()
}
var AllAccessTypes = []AccessType{
AccessTypeNobody,
AccessTypeOnlyAddress,
AccessTypeAnyOfAddresses,
AccessTypeEverybody,
}
func validateAccessType(i interface{}) error {
a, ok := i.(AccessType)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
if a == AccessTypeUnspecified {
return errorsmod.Wrap(types.ErrEmpty, "type")
}
for _, v := range AllAccessTypes {
if v == a {
return nil
}
}
return errorsmod.Wrapf(types.ErrInvalid, "unknown type: %q", a)
}
func (a AccessConfig) ValidateBasic() error {
switch a.Permission {
case AccessTypeUnspecified:
return errorsmod.Wrap(types.ErrEmpty, "type")
case AccessTypeNobody, AccessTypeEverybody:
return nil
case AccessTypeOnlyAddress:
_, err := sdk.AccAddressFromBech32(a.Address)
return errorsmod.Wrap(err, "only address")
case AccessTypeAnyOfAddresses:
return errorsmod.Wrap(assertValidAddresses(a.Addresses), "addresses")
}
return errorsmod.Wrapf(types.ErrInvalid, "unknown type: %q", a.Permission)
}
func assertValidAddresses(addrs []string) error {
if len(addrs) == 0 {
return types.ErrEmpty
}
idx := make(map[string]struct{}, len(addrs))
for _, a := range addrs {
if _, err := sdk.AccAddressFromBech32(a); err != nil {
return errorsmod.Wrapf(err, "address: %s", a)
}
if _, exists := idx[a]; exists {
return types.ErrDuplicate.Wrapf("address: %s", a)
}
idx[a] = struct{}{}
}
return nil
}
func (a AccessType) String() string {
switch a {
case AccessTypeNobody:
return "Nobody"
case AccessTypeOnlyAddress:
return "OnlyAddress"
case AccessTypeEverybody:
return "Everybody"
case AccessTypeAnyOfAddresses:
return "AnyOfAddresses"
}
return "Unspecified"
}
func (a *AccessType) UnmarshalText(text []byte) error {
for _, v := range AllAccessTypes {
if v.String() == string(text) {
*a = v
return nil
}
}
*a = AccessTypeUnspecified
return nil
}
func (a AccessType) MarshalText() ([]byte, error) {
return []byte(a.String()), nil
}
func (a *AccessType) MarshalJSONPB(_ *jsonpb.Marshaler) ([]byte, error) {
return json.Marshal(a)
}
func (a *AccessType) UnmarshalJSONPB(_ *jsonpb.Unmarshaler, data []byte) error {
return json.Unmarshal(data, a)
}
func (a AccessConfig) Equals(o AccessConfig) bool {
return a.Permission == o.Permission && a.Address == o.Address
}

View File

@@ -0,0 +1,89 @@
package v2
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/codec"
)
func TestAccessTypeMarshalJson(t *testing.T) {
specs := map[string]struct {
src AccessType
exp string
}{
"Unspecified": {src: AccessTypeUnspecified, exp: `"Unspecified"`},
"Nobody": {src: AccessTypeNobody, exp: `"Nobody"`},
"OnlyAddress": {src: AccessTypeOnlyAddress, exp: `"OnlyAddress"`},
"AccessTypeAnyOfAddresses": {src: AccessTypeAnyOfAddresses, exp: `"AnyOfAddresses"`},
"Everybody": {src: AccessTypeEverybody, exp: `"Everybody"`},
"unknown": {src: 999, exp: `"Unspecified"`},
}
for msg, spec := range specs {
t.Run(msg, func(t *testing.T) {
got, err := json.Marshal(spec.src)
require.NoError(t, err)
assert.Equal(t, []byte(spec.exp), got)
})
}
}
func TestAccessTypeUnmarshalJson(t *testing.T) {
specs := map[string]struct {
src string
exp AccessType
}{
"Unspecified": {src: `"Unspecified"`, exp: AccessTypeUnspecified},
"Nobody": {src: `"Nobody"`, exp: AccessTypeNobody},
"OnlyAddress": {src: `"OnlyAddress"`, exp: AccessTypeOnlyAddress},
"AnyOfAddresses": {src: `"AnyOfAddresses"`, exp: AccessTypeAnyOfAddresses},
"Everybody": {src: `"Everybody"`, exp: AccessTypeEverybody},
"unknown": {src: `""`, exp: AccessTypeUnspecified},
}
for msg, spec := range specs {
t.Run(msg, func(t *testing.T) {
var got AccessType
err := json.Unmarshal([]byte(spec.src), &got)
require.NoError(t, err)
assert.Equal(t, spec.exp, got)
})
}
}
func TestParamsUnmarshalJson(t *testing.T) {
specs := map[string]struct {
src string
exp Params
}{
"defaults": {
src: `{"code_upload_access": {"permission": "Everybody"},
"instantiate_default_permission": "Everybody"}`,
exp: Params{
CodeUploadAccess: AccessConfig{Permission: AccessTypeEverybody},
InstantiateDefaultPermission: AccessTypeEverybody,
},
},
"legacy type": {
src: `{"code_upload_access": {"permission": "OnlyAddress", "address": "wasm1lq3q55r9sqwqyrfmlp6xy8ufhayt96lmcttthz", "addresses": [] },
"instantiate_default_permission": "Nobody"}`,
exp: Params{
CodeUploadAccess: AccessConfig{
Permission: AccessTypeOnlyAddress, Address: "wasm1lq3q55r9sqwqyrfmlp6xy8ufhayt96lmcttthz", Addresses: nil,
},
InstantiateDefaultPermission: AccessTypeNobody,
},
},
}
for msg, spec := range specs {
t.Run(msg, func(t *testing.T) {
var val Params
marshaler := codec.NewLegacyAmino()
err := marshaler.UnmarshalJSON([]byte(spec.src), &val)
require.NoError(t, err)
assert.Equal(t, spec.exp, val)
})
}
}

View File

@@ -16,13 +16,8 @@ import (
// module state.
func MigrateStore(ctx sdk.Context, storeService corestoretypes.KVStoreService, legacySubspace exported.Subspace, cdc codec.BinaryCodec) error {
store := storeService.OpenKVStore(ctx)
var currParams types.Params
var currParams Params
legacySubspace.GetParamSet(ctx, &currParams)
if err := currParams.ValidateBasic(); err != nil {
return err
}
bz, err := cdc.Marshal(&currParams)
if err != nil {
return err

View File

@@ -3,6 +3,8 @@ package v2_test
import (
"testing"
"github.com/cometbft/cometbft/libs/rand"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
storetypes "cosmossdk.io/store/types"
@@ -10,38 +12,90 @@ import (
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/CosmWasm/wasmd/x/wasm"
"github.com/CosmWasm/wasmd/x/wasm/exported"
v2 "github.com/CosmWasm/wasmd/x/wasm/migrations/v2"
"github.com/CosmWasm/wasmd/x/wasm/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) {
cdc := moduletestutil.MakeTestEncodingConfig(wasm.AppModuleBasic{}).Codec
storeKey := storetypes.NewKVStoreKey(types.StoreKey)
tKey := storetypes.NewTransientStoreKey("transient_test")
ctx := testutil.DefaultContext(storeKey, tKey)
store := ctx.KVStore(storeKey)
cfg := moduletestutil.MakeTestEncodingConfig(wasm.AppModuleBasic{})
cdc := cfg.Codec
var (
wasmStoreKey = storetypes.NewKVStoreKey(types.StoreKey)
paramsStoreKey = storetypes.NewKVStoreKey(paramstypes.StoreKey)
paramsTStoreKey = storetypes.NewTransientStoreKey(paramstypes.TStoreKey)
myAddress = sdk.AccAddress(rand.Bytes(address.Len))
)
specs := map[string]struct {
src v2.Params
}{
"one address": {
src: v2.Params{
CodeUploadAccess: v2.AccessConfig{
Permission: v2.AccessTypeOnlyAddress,
Address: myAddress.String(),
},
InstantiateDefaultPermission: v2.AccessTypeNobody,
},
},
"multiple addresses": {
src: v2.Params{
CodeUploadAccess: v2.AccessConfig{
Permission: v2.AccessTypeAnyOfAddresses,
Addresses: []string{myAddress.String(), sdk.AccAddress(rand.Bytes(address.Len)).String()},
},
InstantiateDefaultPermission: v2.AccessTypeEverybody,
},
},
"everybody": {
src: v2.Params{
CodeUploadAccess: v2.AccessConfig{
Permission: v2.AccessTypeEverybody,
},
InstantiateDefaultPermission: v2.AccessTypeEverybody,
},
},
"nobody": {
src: v2.Params{
CodeUploadAccess: v2.AccessConfig{
Permission: v2.AccessTypeNobody,
},
InstantiateDefaultPermission: v2.AccessTypeNobody,
},
},
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
paramsKeeper := paramskeeper.NewKeeper(cdc, cfg.Amino, paramsStoreKey, paramsTStoreKey)
ctx := testutil.DefaultContextWithKeys(
map[string]*storetypes.KVStoreKey{
paramstypes.StoreKey: paramsStoreKey,
types.StoreKey: wasmStoreKey,
},
map[string]*storetypes.TransientStoreKey{
paramstypes.TStoreKey: paramsTStoreKey,
},
nil,
)
legacySubspace := newMockSubspace(types.DefaultParams())
require.NoError(t, v2.MigrateStore(ctx, runtime.NewKVStoreService(storeKey), legacySubspace, cdc))
// register legacy parameters
params := spec.src
subspace := paramsKeeper.Subspace(types.ModuleName)
subspace.WithKeyTable(v2.ParamKeyTable())
subspace.SetParamSet(ctx, &params)
var res types.Params
bz := store.Get(types.ParamsKey)
require.NoError(t, cdc.Unmarshal(bz, &res))
require.Equal(t, legacySubspace.ps, res)
// when
require.NoError(t, v2.MigrateStore(ctx, runtime.NewKVStoreService(wasmStoreKey), subspace, cdc))
var res v2.Params
bz := ctx.KVStore(wasmStoreKey).Get(types.ParamsKey)
require.NoError(t, cdc.Unmarshal(bz, &res))
assert.Equal(t, params, res)
})
}
}

View File

@@ -27,19 +27,20 @@ import (
"github.com/CosmWasm/wasmd/x/wasm/exported"
"github.com/CosmWasm/wasmd/x/wasm/keeper"
"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
v2 "github.com/CosmWasm/wasmd/x/wasm/migrations/v2"
"github.com/CosmWasm/wasmd/x/wasm/types"
)
type mockSubspace struct {
ps types.Params
ps v2.Params
}
func newMockSubspace(ps types.Params) mockSubspace {
func newMockSubspace(ps v2.Params) mockSubspace {
return mockSubspace{ps: ps}
}
func (ms mockSubspace) GetParamSet(ctx sdk.Context, ps exported.ParamSet) {
*ps.(*types.Params) = ms.ps
*ps.(*v2.Params) = ms.ps
}
type testData struct {
@@ -57,6 +58,11 @@ type testData struct {
func setupTest(t *testing.T) testData {
t.Helper()
DefaultParams := v2.Params{
CodeUploadAccess: v2.AccessConfig{Permission: v2.AccessTypeEverybody},
InstantiateDefaultPermission: v2.AccessTypeEverybody,
}
ctx, keepers := keeper.CreateTestInput(t, false, "iterator,staking,stargate,cosmwasm_1_1,cosmwasm_1_2,cosmwasm_1_3,cosmwasm_1_4")
encConf := keeper.MakeEncodingConfig(t)
queryRouter := baseapp.NewGRPCQueryRouter()
@@ -64,7 +70,7 @@ func setupTest(t *testing.T) testData {
queryRouter.SetInterfaceRegistry(encConf.InterfaceRegistry)
serviceRouter.SetInterfaceRegistry(encConf.InterfaceRegistry)
data := testData{
module: NewAppModule(encConf.Codec, keepers.WasmKeeper, keepers.StakingKeeper, keepers.AccountKeeper, keepers.BankKeeper, nil, newMockSubspace(types.DefaultParams())),
module: NewAppModule(encConf.Codec, keepers.WasmKeeper, keepers.StakingKeeper, keepers.AccountKeeper, keepers.BankKeeper, nil, newMockSubspace(DefaultParams)),
ctx: ctx,
acctKeeper: keepers.AccountKeeper,
keeper: *keepers.WasmKeeper,

View File

@@ -2,7 +2,6 @@ package types
import (
"encoding/json"
"fmt"
"github.com/cosmos/gogoproto/jsonpb"
"github.com/pkg/errors"
@@ -104,25 +103,13 @@ func (p Params) ValidateBasic() error {
if err := validateAccessType(p.InstantiateDefaultPermission); err != nil {
return errors.Wrap(err, "instantiate default permission")
}
if err := validateAccessConfig(p.CodeUploadAccess); err != nil {
if err := p.CodeUploadAccess.ValidateBasic(); err != nil {
return errors.Wrap(err, "upload access")
}
return nil
}
func validateAccessConfig(i interface{}) error {
v, ok := i.(AccessConfig)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
return v.ValidateBasic()
}
func validateAccessType(i interface{}) error {
a, ok := i.(AccessType)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
func validateAccessType(a AccessType) error {
if a == AccessTypeUnspecified {
return errorsmod.Wrap(ErrEmpty, "type")
}

View File

@@ -1,26 +0,0 @@
/*
NOTE: Usage of x/params to manage parameters is deprecated in favor of x/gov
controlled execution of MsgUpdateParams messages. These types remains solely
for migration purposes and will be removed in a future release.
*/
package types
import paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
var (
ParamStoreKeyUploadAccess = []byte("uploadAccess")
ParamStoreKeyInstantiateAccess = []byte("instantiateAccess")
)
// Deprecated: Type declaration for parameters
func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
}
// ParamSetPairs returns the parameter set pairs.
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(ParamStoreKeyUploadAccess, &p.CodeUploadAccess, validateAccessConfig),
paramtypes.NewParamSetPair(ParamStoreKeyInstantiateAccess, &p.InstantiateDefaultPermission, validateAccessType),
}
}