Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat(app)!: migrate pre-initialized module accounts #2206

Merged
merged 2 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,18 +477,14 @@
upgradeKeeper.SetUpgradeHandler(
upgradeName(app.Version()),
func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
updatedVM, err := app.mm.RunMigrations(ctx, configurator, fromVM)
err := MigratePreInitializedModuleAccounts(ctx, *GetKeeper[authkeeper.AccountKeeper](keepers), []string{nexusTypes.ModuleName})

Check warning on line 480 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L480

Added line #L480 was not covered by tests
if err != nil {
return updatedVM, err
return nil, err

Check warning on line 482 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L482

Added line #L482 was not covered by tests
}

// TODO: remove after v35 upgrade
// Override wasm module default params
if upgradeName(app.Version()) == "v0.35" && IsWasmEnabled() {
GetKeeper[wasm.Keeper](keepers).SetParams(ctx, wasmtypes.Params{
CodeUploadAccess: wasmtypes.AllowNobody,
InstantiateDefaultPermission: wasmtypes.AccessTypeNobody,
})
cjcobb23 marked this conversation as resolved.
Show resolved Hide resolved
updatedVM, err := app.mm.RunMigrations(ctx, configurator, fromVM)
if err != nil {
return updatedVM, err

Check warning on line 487 in app/app.go

View check run for this annotation

Codecov / codecov/patch

app/app.go#L485-L487

Added lines #L485 - L487 were not covered by tests
}

return updatedVM, err
Expand Down
78 changes: 78 additions & 0 deletions app/migrate_module_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package app

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)

// MigratePreInitializedModuleAccounts migrates module accounts that were pre-initialized as BaseAccounts to ModuleAccounts,
// or creates new module accounts if they don't exist.
func MigratePreInitializedModuleAccounts(
ctx sdk.Context,
ak authkeeper.AccountKeeper,
moduleAccountsToInitialize []string,
) error {
for _, module := range moduleAccountsToInitialize {
addr, perms := ak.GetModuleAddressAndPermissions(module)
if addr == nil {
return fmt.Errorf(
"failed to get module address and permissions for module %s",
module,
)
}

Check warning on line 25 in app/migrate_module_account.go

View check run for this annotation

Codecov / codecov/patch

app/migrate_module_account.go#L21-L25

Added lines #L21 - L25 were not covered by tests

acc := ak.GetAccount(ctx, addr)
// The account has not been initialized yet
if acc == nil {
initModuleAccount(ctx, ak, module, perms...)
continue
}
haiyizxx marked this conversation as resolved.
Show resolved Hide resolved

_, isModuleAccount := acc.(authtypes.ModuleAccountI)
if isModuleAccount {
ctx.Logger().Info(fmt.Sprintf(
"account for module %s was correctly initialized, skipping",
module,
))
continue

Check warning on line 40 in app/migrate_module_account.go

View check run for this annotation

Codecov / codecov/patch

app/migrate_module_account.go#L36-L40

Added lines #L36 - L40 were not covered by tests
}

// Migrate from base account to module account
baseAccount, ok := acc.(*authtypes.BaseAccount)
haiyizxx marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
panic(fmt.Sprintf("account %s must be a base account", acc.GetAddress()))

Check warning on line 46 in app/migrate_module_account.go

View check run for this annotation

Codecov / codecov/patch

app/migrate_module_account.go#L46

Added line #L46 was not covered by tests
}

newModuleAccount := authtypes.NewModuleAccount(
baseAccount,
module,
perms...,
)
ak.SetModuleAccount(ctx, newModuleAccount)

ctx.Logger().Info(fmt.Sprintf(
"migrated %s module from base account %+v to module account %+v",
module,
baseAccount,
newModuleAccount,
))
}

return nil
}

// create a new module account
func initModuleAccount(ctx sdk.Context, ak authkeeper.AccountKeeper, moduleName string, perms ...string) {
newModuleAccount := authtypes.NewEmptyModuleAccount(moduleName, perms...)
maccI := (ak.NewAccount(ctx, newModuleAccount)).(authtypes.ModuleAccountI) // set the account number
ak.SetModuleAccount(ctx, maccI)

ctx.Logger().Info(fmt.Sprintf(
"initialized %s module account %+v",
moduleName,
newModuleAccount,
))
}
63 changes: 63 additions & 0 deletions app/migrate_module_account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package app_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
params "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

"github.com/axelarnetwork/axelar-core/app"
"github.com/axelarnetwork/axelar-core/testutils/fake"
nexusTypes "github.com/axelarnetwork/axelar-core/x/nexus/types"
. "github.com/axelarnetwork/utils/test"
)

func TestMigratePreInitializedModuleAccounts(t *testing.T) {
var (
accountK authkeeper.AccountKeeper
ctx sdk.Context
)

Given("an account keeper", func() {
encodingConfig := app.MakeEncodingConfig()
ctx = sdk.NewContext(fake.NewMultiStore(), tmproto.Header{}, false, log.TestingLogger())
storeKey := sdk.NewKVStoreKey(authtypes.StoreKey)

moduleAccPerms := map[string][]string{
"module1": nil,
nexusTypes.ModuleName: {authtypes.Minter, authtypes.Burner},
}

accountK = authkeeper.NewAccountKeeper(
encodingConfig.Codec,
sdk.NewKVStoreKey(authtypes.StoreKey),
params.NewSubspace(encodingConfig.Codec, encodingConfig.Amino, storeKey, storeKey, authtypes.ModuleName),
authtypes.ProtoBaseAccount,
moduleAccPerms,
)
}).When("there is an pre-initialized module account", func() {
account := accountK.NewAccountWithAddress(ctx, authtypes.NewModuleAddress(nexusTypes.ModuleName))
accountK.SetAccount(ctx, account)

account = accountK.GetAccount(ctx, authtypes.NewModuleAddress(nexusTypes.ModuleName))
_, isModuleAccount := account.(authtypes.ModuleAccountI)
assert.False(t, isModuleAccount)

}).Then("migrating pre-initialized base account to module account", func(t *testing.T) {
err := app.MigratePreInitializedModuleAccounts(ctx, accountK, []string{"module1", nexusTypes.ModuleName})
assert.NoError(t, err)

account := accountK.GetAccount(ctx, authtypes.NewModuleAddress(nexusTypes.ModuleName))
_, isModuleAccount := account.(authtypes.ModuleAccountI)
assert.True(t, isModuleAccount)

account = accountK.GetAccount(ctx, authtypes.NewModuleAddress("module1"))
_, isModuleAccount = account.(authtypes.ModuleAccountI)
assert.True(t, isModuleAccount)
}).Run(t)
}
Loading