mukan-ibc/modules/apps/transfer/keeper/migrations.go
Mukan Erkin Törük 88dd97a9f8
Some checks failed
CodeQL / Analyze (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Has been cancelled
refactor: replace all github.com upstream refs with git.cw.tr/mukan-network
2026-05-11 03:36:22 +03:00

167 lines
5.5 KiB
Go

package keeper
import (
"fmt"
"strings"
"cosmossdk.io/store/prefix"
storetypes "cosmossdk.io/store/types"
"git.cw.tr/mukan-network/mukan-sdk/runtime"
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
banktypes "git.cw.tr/mukan-network/mukan-sdk/x/bank/types"
internaltypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/transfer/internal/types"
"git.cw.tr/mukan-network/mukan-ibc/modules/apps/transfer/types"
)
// Migrator is a struct for handling in-place store migrations.
type Migrator struct {
keeper Keeper
}
// NewMigrator returns a new Migrator.
func NewMigrator(keeper Keeper) Migrator {
return Migrator{
keeper: keeper,
}
}
// MigrateParams migrates the transfer module's parameters from the x/params to self store.
func (m Migrator) MigrateParams(ctx sdk.Context) error {
var params types.Params
m.keeper.legacySubspace.GetParamSet(ctx, &params)
m.keeper.SetParams(ctx, params)
m.keeper.Logger(ctx).Info("successfully migrated transfer app self-manage params")
return nil
}
// MigrateDenomMetadata sets token metadata for all the IBC denom traces
func (m Migrator) MigrateDenomMetadata(ctx sdk.Context) error {
m.keeper.iterateDenomTraces(ctx,
func(dt internaltypes.DenomTrace) (stop bool) {
// check if the metadata for the given denom trace does not already exist
if !m.keeper.BankKeeper.HasDenomMetaData(ctx, dt.IBCDenom()) {
m.keeper.setDenomMetadataWithDenomTrace(ctx, dt)
}
return false
})
m.keeper.Logger(ctx).Info("successfully added metadata to IBC voucher denominations")
return nil
}
// MigrateTotalEscrowForDenom migrates the total amount of source chain tokens in escrow.
func (m Migrator) MigrateTotalEscrowForDenom(ctx sdk.Context) error {
var totalEscrowed sdk.Coins
portID := m.keeper.GetPort(ctx)
transferChannels := m.keeper.channelKeeper.GetAllChannelsWithPortPrefix(ctx, portID)
for _, channel := range transferChannels {
escrowAddress := types.GetEscrowAddress(portID, channel.ChannelId)
escrowBalances := m.keeper.BankKeeper.GetAllBalances(ctx, escrowAddress)
totalEscrowed = totalEscrowed.Add(escrowBalances...)
}
for _, totalEscrow := range totalEscrowed {
m.keeper.SetTotalEscrowForDenom(ctx, totalEscrow)
}
m.keeper.Logger(ctx).Info("successfully set total escrow", "number of denominations", totalEscrowed.Len())
return nil
}
// MigrateDenomTraceToDenom migrates storage from using DenomTrace to Denom.
func (m Migrator) MigrateDenomTraceToDenom(ctx sdk.Context) error {
var (
denoms []types.Denom
denomTraces []internaltypes.DenomTrace
)
m.keeper.iterateDenomTraces(ctx,
func(dt internaltypes.DenomTrace) (stop bool) {
// convert denomTrace to denom
denom := types.ExtractDenomFromPath(dt.GetFullDenomPath())
err := denom.Validate()
if err != nil {
panic(err)
}
// defense in depth
if dt.IBCDenom() != denom.IBCDenom() {
// This migration must not change the SDK coin denom.
// A panic should occur to prevent the chain from using corrupted state.
panic(fmt.Errorf("migration will result in corrupted state. expected: %s, got: %s", denom.IBCDenom(), dt.IBCDenom()))
}
denoms = append(denoms, denom)
denomTraces = append(denomTraces, dt)
return false
})
if len(denoms) != len(denomTraces) {
return fmt.Errorf("length of denoms does not match length of denom traces, %d != %d", len(denoms), len(denomTraces))
}
for i := range denoms {
m.keeper.SetDenom(ctx, denoms[i])
m.keeper.deleteDenomTrace(ctx, denomTraces[i])
}
return nil
}
// setDenomTrace sets a new {trace hash -> denom trace} pair to the store.
func (k Keeper) setDenomTrace(ctx sdk.Context, denomTrace internaltypes.DenomTrace) {
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomTraceKey)
bz := k.cdc.MustMarshal(&denomTrace)
store.Set(denomTrace.Hash(), bz)
}
// deleteDenomTrace deletes the denom trace
func (k Keeper) deleteDenomTrace(ctx sdk.Context, denomTrace internaltypes.DenomTrace) {
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.DenomTraceKey)
store.Delete(denomTrace.Hash())
}
// iterateDenomTraces iterates over the denomination traces in the store
// and performs a callback function.
func (k Keeper) iterateDenomTraces(ctx sdk.Context, cb func(denomTrace internaltypes.DenomTrace) bool) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
iterator := storetypes.KVStorePrefixIterator(store, types.DenomTraceKey)
defer sdk.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
for ; iterator.Valid(); iterator.Next() {
var denomTrace internaltypes.DenomTrace
k.cdc.MustUnmarshal(iterator.Value(), &denomTrace)
if cb(denomTrace) {
break
}
}
}
// setDenomMetadataWithDenomTrace sets an IBC token's denomination metadata
func (k Keeper) setDenomMetadataWithDenomTrace(ctx sdk.Context, denomTrace internaltypes.DenomTrace) {
metadata := banktypes.Metadata{
Description: fmt.Sprintf("IBC token from %s", denomTrace.GetFullDenomPath()),
DenomUnits: []*banktypes.DenomUnit{
{
Denom: denomTrace.BaseDenom,
Exponent: 0,
},
},
// Setting base as IBC hash denom since bank keepers's SetDenomMetadata uses
// Base as key path and the IBC hash is what gives this token uniqueness
// on the executing chain
Base: denomTrace.IBCDenom(),
Display: denomTrace.GetFullDenomPath(),
Name: fmt.Sprintf("%s IBC token", denomTrace.GetFullDenomPath()),
Symbol: strings.ToUpper(denomTrace.BaseDenom),
}
k.BankKeeper.SetDenomMetaData(ctx, metadata)
}