Skip to content

Commit

Permalink
fix(auth)!: migrate the distribution account to have burner permission (
Browse files Browse the repository at this point in the history
  • Loading branch information
haiyizxx authored Feb 7, 2025
1 parent eda51d5 commit d23cfcb
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 94 deletions.
5 changes: 1 addition & 4 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,7 @@ 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) {
err := MigratePreInitializedModuleAccounts(ctx, *GetKeeper[authkeeper.AccountKeeper](keepers), []string{nexusTypes.ModuleName})
if err != nil {
return nil, err
}
MigrateDistributionAccountPermission(ctx, *GetKeeper[authkeeper.AccountKeeper](keepers))

updatedVM, err := app.mm.RunMigrations(ctx, configurator, fromVM)
if err != nil {
Expand Down
81 changes: 12 additions & 69 deletions app/migrate_module_account.go
Original file line number Diff line number Diff line change
@@ -1,78 +1,21 @@
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"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/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,
)
}

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
}

// 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()))
}

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,
))
// MigrateDistributionAccountPermission migrates the distribution module account to have the burner permission.
func MigrateDistributionAccountPermission(ctx sdk.Context, ak authkeeper.AccountKeeper) {
acc, _ := ak.GetModuleAccountAndPermissions(ctx, distrtypes.ModuleName)
baseAcc := authtypes.NewBaseAccount(acc.GetAddress(), acc.GetPubKey(), acc.GetAccountNumber(), acc.GetSequence())

moduleAcc := authtypes.NewModuleAccount(
baseAcc,
distrtypes.ModuleName,
InitModuleAccountPermissions()[distrtypes.ModuleName]...,
)
ak.SetModuleAccount(ctx, moduleAcc)
}
36 changes: 15 additions & 21 deletions app/migrate_module_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ import (
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"
distributionTypes "github.com/cosmos/cosmos-sdk/x/distribution/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) {
func TestMigrateDistributionAccountPermission(t *testing.T) {
var (
accountK authkeeper.AccountKeeper
ctx sdk.Context
accNum uint64
)

Given("an account keeper", func() {
Given("a distribution account initialized with minter permission", 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},
distributionTypes.ModuleName: {authtypes.Minter},
}

accountK = authkeeper.NewAccountKeeper(
Expand All @@ -40,24 +40,18 @@ func TestMigratePreInitializedModuleAccounts(t *testing.T) {
authtypes.ProtoBaseAccount,
moduleAccPerms,
)
}).When("there is an pre-initialized module account", func() {
account := accountK.NewAccountWithAddress(ctx, authtypes.NewModuleAddress(nexusTypes.ModuleName))
accountK.SetAccount(ctx, account)
accountK.GetNextAccountNumber(ctx)

account = accountK.GetAccount(ctx, authtypes.NewModuleAddress(nexusTypes.ModuleName))
_, isModuleAccount := account.(authtypes.ModuleAccountI)
assert.False(t, isModuleAccount)
acc := accountK.GetModuleAccount(ctx, distributionTypes.ModuleName)
assert.False(t, acc.HasPermission(authtypes.Burner))
accNum = acc.GetAccountNumber()

}).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)
}).When("run migration", func() {
app.MigrateDistributionAccountPermission(ctx, accountK)

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)
}).Then("distribution account permission should also have burner permission", func(t *testing.T) {
acc := accountK.GetModuleAccount(ctx, distributionTypes.ModuleName)
assert.True(t, acc.HasPermission(authtypes.Burner))
assert.Equal(t, accNum, acc.GetAccountNumber())
}).Run(t)
}

0 comments on commit d23cfcb

Please sign in to comment.