From d0ea3895f78d4ff7ce91fe028450f1d69c1ea2bb Mon Sep 17 00:00:00 2001 From: Segfault <5221072+Segfaultd@users.noreply.github.com> Date: Tue, 12 Sep 2023 16:47:28 +0200 Subject: [PATCH] [LUM-827] Patch the chicken-egg issue on pools migrations (#53) * Patch everything in the same call * Patch the pool type --- x/millions/keeper/keeper_pool.go | 21 +++------------------ x/millions/migrations/v160/store.go | 9 +++------ x/millions/types/pool.go | 2 +- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/x/millions/keeper/keeper_pool.go b/x/millions/keeper/keeper_pool.go index f6dcc741..68a7a98b 100644 --- a/x/millions/keeper/keeper_pool.go +++ b/x/millions/keeper/keeper_pool.go @@ -628,25 +628,9 @@ func (k Keeper) UnsafeUpdatePoolPortIds(ctx sdk.Context, poolID uint64, icaDepos return pool, nil } -// UnsafeUpdatePoolType raw updates the provided pooltype -// Unsafe method to be used only during migration -func (k Keeper) UnsafeUpdatePoolType(ctx sdk.Context, poolID uint64, poolType types.PoolType) (types.Pool, error) { - // Grab our pool instance - pool, err := k.GetPool(ctx, poolID) - if err != nil { - return types.Pool{}, err - } - - // Patch and update our pool entity - pool.PoolType = poolType - k.updatePool(ctx, &pool) - - return pool, nil -} - -// UnsafeUpdatePoolUnbondingFrequency raw updates the UnbondingDuration and mexUnbonding entries +// UnsafeUpdatePoolUnbondingFrequencyAndType raw updates the UnbondingDuration, mexUnbonding and pool type entries // Unsafe and should only be used for store migration -func (k Keeper) UnsafeUpdatePoolUnbondingFrequency(ctx sdk.Context, poolID uint64, UnbondingDuration time.Duration, maxUnbondingEntries math.Int) (types.Pool, error) { +func (k Keeper) UnsafeUpdatePoolUnbondingFrequencyAndType(ctx sdk.Context, poolID uint64, UnbondingDuration time.Duration, maxUnbondingEntries math.Int, poolType types.PoolType) (types.Pool, error) { // Grab our pool instance pool, err := k.GetPool(ctx, poolID) if err != nil { @@ -656,6 +640,7 @@ func (k Keeper) UnsafeUpdatePoolUnbondingFrequency(ctx sdk.Context, poolID uint6 // Patch and update our pool entity pool.UnbondingDuration = UnbondingDuration pool.MaxUnbondingEntries = maxUnbondingEntries + pool.PoolType = poolType k.updatePool(ctx, &pool) return pool, nil diff --git a/x/millions/migrations/v160/store.go b/x/millions/migrations/v160/store.go index bf65ec0a..58153d11 100644 --- a/x/millions/migrations/v160/store.go +++ b/x/millions/migrations/v160/store.go @@ -10,13 +10,10 @@ import ( func MigratePoolTypeAndUnbondingFrequency(ctx sdk.Context, k millionskeeper.Keeper) error { ctx.Logger().Info("Processing unbonding frequency migration on pools") k.IteratePools(ctx, func(pool millionstypes.Pool) bool { - // First update pool type as the RegisterPoolRunners relies on it - if _, err := k.UnsafeUpdatePoolType(ctx, pool.GetPoolId(), millionstypes.PoolType_Staking); err != nil { - panic(err) - } - // Unbonding frequency here is Cosmos Hub (unbonding time/7)+1 - if _, err := k.UnsafeUpdatePoolUnbondingFrequency(ctx, pool.GetPoolId(), millionstypes.DefaultUnbondingDuration, sdk.NewInt(millionstypes.DefaultMaxUnbondingEntries)); err != nil { + // Pool type is staking + // We have to do this in the same operation to avoid chicken-egg problem when it comes to ValidateBasic + if _, err := k.UnsafeUpdatePoolUnbondingFrequencyAndType(ctx, pool.GetPoolId(), millionstypes.DefaultUnbondingDuration, sdk.NewInt(millionstypes.DefaultMaxUnbondingEntries), millionstypes.PoolType_Staking); err != nil { panic(err) } return false diff --git a/x/millions/types/pool.go b/x/millions/types/pool.go index 07557e2f..2cf2b964 100644 --- a/x/millions/types/pool.go +++ b/x/millions/types/pool.go @@ -47,7 +47,7 @@ func (pool *Pool) ValidateBasic(params Params) error { return errorsmod.Wrapf(ErrInvalidPoolParams, "min deposit denom must be gte %d", params.MinDepositAmount.Int64()) } if pool.UnbondingDuration < MinUnbondingDuration { - return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "unbonding duration cannot be lower than %s", MinUnbondingDuration) + return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "unbonding duration cannot be lower than %s (is %s)", MinUnbondingDuration, pool.UnbondingDuration.String()) } if pool.MaxUnbondingEntries.IsNegative() || pool.MaxUnbondingEntries.GT(sdk.NewInt(DefaultMaxUnbondingEntries)) { return errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "Unbonding entries cannot be negative or greated than %d", DefaultMaxUnbondingEntries)