Skip to content

Commit

Permalink
feat(app)!: migrate pre-initialized module accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
haiyizxx committed Nov 6, 2024
1 parent d8e91da commit 28bb148
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 9 deletions.
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 @@ func (app *AxelarApp) setUpgradeBehaviour(configurator module.Configurator, keep
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,
})
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
}

_, 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)
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)
}

0 comments on commit 28bb148

Please sign in to comment.