github.com/cosmos/cosmos-sdk@v0.50.10/x/group/migrations/v2/migrate.go (about)

     1  package v2
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  
     7  	storetypes "cosmossdk.io/store/types"
     8  
     9  	sdk "github.com/cosmos/cosmos-sdk/types"
    10  	"github.com/cosmos/cosmos-sdk/types/address"
    11  	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    12  	"github.com/cosmos/cosmos-sdk/x/group"
    13  	"github.com/cosmos/cosmos-sdk/x/group/internal/orm"
    14  )
    15  
    16  const (
    17  	ModuleName = "group"
    18  
    19  	// Group Policy Table
    20  	GroupPolicyTablePrefix    byte = 0x20
    21  	GroupPolicyTableSeqPrefix byte = 0x21
    22  )
    23  
    24  // Migrate migrates the x/group module state from the consensus version 1 to version 2.
    25  // Specifically, it changes the group policy account from module account to base account.
    26  func Migrate(
    27  	ctx sdk.Context,
    28  	storeKey storetypes.StoreKey,
    29  	accountKeeper group.AccountKeeper,
    30  	groupPolicySeq orm.Sequence,
    31  	groupPolicyTable orm.PrimaryKeyTable,
    32  ) error {
    33  	store := ctx.KVStore(storeKey)
    34  	curAccVal := groupPolicySeq.CurVal(store)
    35  	groupPolicyAccountDerivationKey := make(map[string][]byte, 0)
    36  	policyKey := []byte{GroupPolicyTablePrefix}
    37  	for i := uint64(0); i <= curAccVal; i++ {
    38  		derivationKey := make([]byte, 8)
    39  		binary.BigEndian.PutUint64(derivationKey, i)
    40  		groupPolicyAcc := sdk.AccAddress(address.Module(group.ModuleName, policyKey, derivationKey))
    41  		groupPolicyAccountDerivationKey[groupPolicyAcc.String()] = derivationKey
    42  	}
    43  
    44  	// get all group policies
    45  	var groupPolicies []*group.GroupPolicyInfo
    46  	if _, err := groupPolicyTable.Export(store, &groupPolicies); err != nil {
    47  		return fmt.Errorf("failed to get group policies: %w", err)
    48  	}
    49  
    50  	for _, policy := range groupPolicies {
    51  		addr, err := accountKeeper.AddressCodec().StringToBytes(policy.Address)
    52  		if err != nil {
    53  			return fmt.Errorf("failed to convert group policy account address: %w", err)
    54  		}
    55  
    56  		// get the account address by acc id
    57  		oldAcc := accountKeeper.GetAccount(ctx, addr)
    58  		// remove the old account
    59  		accountKeeper.RemoveAccount(ctx, oldAcc)
    60  
    61  		// create the group policy account
    62  		derivationKey, ok := groupPolicyAccountDerivationKey[policy.Address]
    63  		if !ok {
    64  			// should never happen
    65  			panic(fmt.Errorf("group policy account %s derivation key not found", policy.Address))
    66  		}
    67  
    68  		ac, err := authtypes.NewModuleCredential(group.ModuleName, []byte{GroupPolicyTablePrefix}, derivationKey)
    69  		if err != nil {
    70  			return err
    71  		}
    72  		baseAccount, err := authtypes.NewBaseAccountWithPubKey(ac)
    73  		if err != nil {
    74  			return fmt.Errorf("failed to create new group policy account: %w", err)
    75  		}
    76  
    77  		// set account number
    78  		err = baseAccount.SetAccountNumber(oldAcc.GetAccountNumber())
    79  		if err != nil {
    80  			return err
    81  		}
    82  
    83  		// NOTE: we do not call NewAccount because we do not want to bump the account number
    84  
    85  		// set new account
    86  		// because we have only changed the account type, so we can use:
    87  		//   - the same account number
    88  		//   - the same address
    89  		accountKeeper.SetAccount(ctx, baseAccount)
    90  	}
    91  
    92  	return nil
    93  }