-
Notifications
You must be signed in to change notification settings - Fork 413
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add migration for AccessConfig #1395
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package v3 | ||
|
||
import ( | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
|
||
"github.com/CosmWasm/wasmd/x/wasm/types" | ||
) | ||
|
||
// StoreCodeInfoFn stores code info | ||
type StoreCodeInfoFn func(ctx sdk.Context, codeID uint64, codeInfo types.CodeInfo) | ||
|
||
// Keeper abstract keeper | ||
type wasmKeeper interface { | ||
IterateCodeInfos(ctx sdk.Context, cb func(uint64, types.CodeInfo) bool) | ||
GetParams(ctx sdk.Context) types.Params | ||
SetParams(ctx sdk.Context, ps types.Params) error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good abstraction! |
||
} | ||
|
||
// Migrator is a struct for handling in-place store migrations. | ||
type Migrator struct { | ||
keeper wasmKeeper | ||
storeCodeInfoFn StoreCodeInfoFn | ||
} | ||
|
||
// NewMigrator returns a new Migrator. | ||
func NewMigrator(k wasmKeeper, fn StoreCodeInfoFn) Migrator { | ||
return Migrator{keeper: k, storeCodeInfoFn: fn} | ||
} | ||
|
||
// Migrate3to4 migrates from version 3 to 4. | ||
func (m Migrator) Migrate3to4(ctx sdk.Context) error { | ||
params := m.keeper.GetParams(ctx) | ||
if params.CodeUploadAccess.Permission == types.AccessTypeOnlyAddress { | ||
params.CodeUploadAccess.Permission = types.AccessTypeAnyOfAddresses | ||
params.CodeUploadAccess.Addresses = []string{params.CodeUploadAccess.Address} | ||
params.CodeUploadAccess.Address = "" | ||
} | ||
|
||
if params.InstantiateDefaultPermission == types.AccessTypeOnlyAddress { | ||
params.InstantiateDefaultPermission = types.AccessTypeAnyOfAddresses | ||
} | ||
|
||
err := m.keeper.SetParams(ctx, params) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
m.keeper.IterateCodeInfos(ctx, func(codeID uint64, info types.CodeInfo) bool { | ||
if info.InstantiateConfig.Permission == types.AccessTypeOnlyAddress { | ||
info.InstantiateConfig.Permission = types.AccessTypeAnyOfAddresses | ||
info.InstantiateConfig.Addresses = []string{info.InstantiateConfig.Address} | ||
info.InstantiateConfig.Address = "" | ||
|
||
m.storeCodeInfoFn(ctx, codeID, info) | ||
} | ||
return false | ||
}) | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package v3_test | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
|
||
"github.com/CosmWasm/wasmd/x/wasm/keeper" | ||
"github.com/CosmWasm/wasmd/x/wasm/keeper/wasmtesting" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/cosmos/cosmos-sdk/types/address" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/CosmWasm/wasmd/x/wasm/types" | ||
) | ||
|
||
func TestMigrate3To4(t *testing.T) { | ||
const AvailableCapabilities = "iterator,staking,stargate,cosmwasm_1_1" | ||
ctx, keepers := keeper.CreateTestInput(t, false, AvailableCapabilities) | ||
wasmKeeper := keepers.WasmKeeper | ||
|
||
deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000)) | ||
creator := sdk.AccAddress(bytes.Repeat([]byte{1}, address.Len)) | ||
keepers.Faucet.Fund(ctx, creator, deposit...) | ||
|
||
var mock wasmtesting.MockWasmer | ||
wasmtesting.MakeInstantiable(&mock) | ||
|
||
// contract with only address permission | ||
onlyAddrPermission := types.AccessTypeOnlyAddress.With(creator) | ||
contract1 := keeper.StoreRandomContractWithAccessConfig(t, ctx, keepers, &mock, &onlyAddrPermission) | ||
|
||
// contract with any addresses permission | ||
anyAddrsPermission := types.AccessTypeAnyOfAddresses.With(creator) | ||
contract2 := keeper.StoreRandomContractWithAccessConfig(t, ctx, keepers, &mock, &anyAddrsPermission) | ||
|
||
// contract with everybody permission | ||
everybodyPermission := types.AllowEverybody | ||
contract3 := keeper.StoreRandomContractWithAccessConfig(t, ctx, keepers, &mock, &everybodyPermission) | ||
|
||
// contract with nobody permission | ||
nobodyPermission := types.AllowNobody | ||
contract4 := keeper.StoreRandomContractWithAccessConfig(t, ctx, keepers, &mock, &nobodyPermission) | ||
|
||
// set only address permission params | ||
params := types.Params{ | ||
CodeUploadAccess: types.AccessTypeOnlyAddress.With(creator), | ||
InstantiateDefaultPermission: types.AccessTypeOnlyAddress, | ||
} | ||
err := wasmKeeper.SetParams(ctx, params) | ||
require.NoError(t, err) | ||
|
||
// when | ||
err = keeper.NewMigrator(*wasmKeeper, nil).Migrate3to4(ctx) | ||
|
||
// then | ||
require.NoError(t, err) | ||
|
||
expParams := types.Params{ | ||
CodeUploadAccess: types.AccessTypeAnyOfAddresses.With(creator), | ||
InstantiateDefaultPermission: types.AccessTypeAnyOfAddresses, | ||
} | ||
|
||
// params are migrated | ||
assert.Equal(t, expParams, wasmKeeper.GetParams(ctx)) | ||
|
||
// access config for only address is migrated | ||
info1 := wasmKeeper.GetCodeInfo(ctx, contract1.CodeID) | ||
assert.Equal(t, anyAddrsPermission, info1.InstantiateConfig) | ||
|
||
// access config for any addresses is not migrated | ||
info2 := wasmKeeper.GetCodeInfo(ctx, contract2.CodeID) | ||
assert.Equal(t, anyAddrsPermission, info2.InstantiateConfig) | ||
|
||
// access config for allow everybody is not migrated | ||
info3 := wasmKeeper.GetCodeInfo(ctx, contract3.CodeID) | ||
assert.Equal(t, types.AllowEverybody, info3.InstantiateConfig) | ||
|
||
// access config for allow nobody is not migrated | ||
info4 := wasmKeeper.GetCodeInfo(ctx, contract4.CodeID) | ||
assert.Equal(t, types.AllowNobody, info4.InstantiateConfig) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good test cases! |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,7 +147,7 @@ func (am AppModule) IsAppModule() { // marker | |
// module. It should be incremented on each consensus-breaking change | ||
// introduced by the module. To avoid wrong/empty versions, the initial version | ||
// should be set to 1. | ||
func (AppModule) ConsensusVersion() uint64 { return 3 } | ||
func (AppModule) ConsensusVersion() uint64 { return 4 } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Important |
||
|
||
func (am AppModule) RegisterServices(cfg module.Configurator) { | ||
types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) | ||
|
@@ -162,6 +162,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { | |
if err != nil { | ||
panic(err) | ||
} | ||
err = cfg.RegisterMigration(types.ModuleName, 3, m.Migrate3to4) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
// RegisterInvariants registers the wasm module invariants. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a subset of cases that are covered in v3/store_test already.
No need to replicate them all. Some kind of a smoke test would be good enough.
A serialized ContractInfo with legacy AccessType could be used for example.