Skip to content

Commit

Permalink
feat: add v3 upgrade handler (#214)
Browse files Browse the repository at this point in the history
## Description

This PR adds v3 software upgrade handler which does the following:
- Remove invalid IBC denoms from the various modules' parameters
(x/operators, x/services, x/restaking)
- Update the x/liquidvesting params to remove the trusted delegates
following #215.
- Update the jail duration time to be increased from 10 minutes to 1
hour (600s).

Closes: MILK-158

<!-- Add a description of the changes that this PR introduces and the
files that
are the most critical to review. -->

---

### Author Checklist

*All items are required. Please add a note to the item if the item is
not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type
prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json)
in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR
Targeting](https://github.com/milkyway-labs/milkyway/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building
modules](https://docs.cosmos.network/v0.44/building-modules/intro.html)
- [ ] included the necessary unit and integration
[tests](https://github.com/milkyway-labs/milkyway/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go
code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable
and please add
your handle next to the items reviewed if you only reviewed selected
items.*

I have...

- [ ] confirmed the correct [type
prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json)
in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)

---------

Co-authored-by: Manuel <[email protected]>
  • Loading branch information
hallazzang and manu0466 committed Dec 11, 2024
1 parent 1994228 commit e27213e
Show file tree
Hide file tree
Showing 7 changed files with 323 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: feat
module: none
pull_request: 214
description: Implement v3 upgrade handler
backward_compatible: true
date: 2024-12-06T09:24:52.695953Z
5 changes: 4 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import (
milkywayabci "github.com/milkyway-labs/milkyway/v3/app/abci"
"github.com/milkyway-labs/milkyway/v3/app/keepers"
"github.com/milkyway-labs/milkyway/v3/app/upgrades"
v3 "github.com/milkyway-labs/milkyway/v3/app/upgrades/v3"
_ "github.com/milkyway-labs/milkyway/v3/client/docs/statik"
liquidvestingtypes "github.com/milkyway-labs/milkyway/v3/x/liquidvesting/types"
)
Expand All @@ -76,7 +77,9 @@ var (
// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string

Upgrades []upgrades.Upgrade
Upgrades = []upgrades.Upgrade{
v3.Upgrade,
}
)

var (
Expand Down
18 changes: 18 additions & 0 deletions app/upgrades/v3/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package v3

import (
storetypes "cosmossdk.io/store/types"

"github.com/milkyway-labs/milkyway/v3/app/upgrades"
)

const UpgradeName = "v3"

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: storetypes.StoreUpgrades{
Added: []string{},
Deleted: []string{},
},
}
123 changes: 123 additions & 0 deletions app/upgrades/v3/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package v3

import (
"context"
"slices"
"time"

upgradetypes "cosmossdk.io/x/upgrade/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"

"github.com/milkyway-labs/milkyway/v3/app/keepers"
"github.com/milkyway-labs/milkyway/v3/utils"
operatorskeeper "github.com/milkyway-labs/milkyway/v3/x/operators/keeper"
restakingkeeper "github.com/milkyway-labs/milkyway/v3/x/restaking/keeper"
rewardskeeper "github.com/milkyway-labs/milkyway/v3/x/rewards/keeper"
serviceskeeper "github.com/milkyway-labs/milkyway/v3/x/services/keeper"
)

func CreateUpgradeHandler(
mm *module.Manager,
configuration module.Configurator,
keepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
vm, err := mm.RunMigrations(ctx, configuration, fromVM)
if err != nil {
return nil, err
}

denomsToRemove := []string{
"ibc/9ACD338BC3B488E0F50A54DE9A844C8326AF0739D917922A9CE04D42AD66017E", // miscalculated TIA
"ibc/84FBEC4BBB48BD7CC534ED7518F339CCF6C45529DC00C7BFB8605C9EE7D68AFC", // miscalculated stTIA
}

err = removeDenomsFromOperatorsModule(ctx, keepers.OperatorsKeeper, denomsToRemove)
if err != nil {
return nil, err
}

err = removeDenomsFromServicesModule(ctx, keepers.ServicesKeeper, denomsToRemove)
if err != nil {
return nil, err
}

err = removeDenomsFromRestakingModule(ctx, keepers.RestakingKeeper, denomsToRemove)
if err != nil {
return nil, err
}

err = removeDenomsFromRewardsModule(ctx, keepers.RewardsKeeper, denomsToRemove)
if err != nil {
return nil, err
}

// Set trusted delegate for liquid vesting module.
liquidVestingParams, err := keepers.LiquidVestingKeeper.GetParams(ctx)
if err != nil {
return nil, err
}
err = keepers.LiquidVestingKeeper.SetParams(ctx, liquidVestingParams)
if err != nil {
return nil, err
}

// Increase downtime jail duration from 1 minute to 1 hour.
slashingParams, err := keepers.SlashingKeeper.GetParams(ctx)
if err != nil {
return nil, err
}
slashingParams.DowntimeJailDuration = time.Hour
err = keepers.SlashingKeeper.SetParams(ctx, slashingParams)
if err != nil {
return nil, err
}

return vm, nil
}
}

func removeDenomsFromOperatorsModule(ctx context.Context, ok *operatorskeeper.Keeper, denomsToRemove []string) error {
params, err := ok.GetParams(ctx)
if err != nil {
return err
}
params.OperatorRegistrationFee = utils.Filter(params.OperatorRegistrationFee, func(coin sdk.Coin) bool {
return !slices.Contains(denomsToRemove, coin.Denom)
})
return ok.SetParams(ctx, params)
}

func removeDenomsFromServicesModule(ctx context.Context, sk *serviceskeeper.Keeper, denomsToRemove []string) error {
params, err := sk.GetParams(ctx)
if err != nil {
return err
}
params.ServiceRegistrationFee = utils.Filter(params.ServiceRegistrationFee, func(coin sdk.Coin) bool {
return !slices.Contains(denomsToRemove, coin.Denom)
})
return sk.SetParams(ctx, params)
}

func removeDenomsFromRestakingModule(ctx context.Context, rk *restakingkeeper.Keeper, denomsToRemove []string) error {
params, err := rk.GetParams(ctx)
if err != nil {
return err
}
params.AllowedDenoms = utils.Filter(params.AllowedDenoms, func(denom string) bool {
return !slices.Contains(denomsToRemove, denom)
})
return rk.SetParams(ctx, params)
}

func removeDenomsFromRewardsModule(ctx context.Context, rk *rewardskeeper.Keeper, denomsToRemove []string) error {
params, err := rk.GetParams(ctx)
if err != nil {
return err
}
params.RewardsPlanCreationFee = utils.Filter(params.RewardsPlanCreationFee, func(coin sdk.Coin) bool {
return !slices.Contains(denomsToRemove, coin.Denom)
})
return rk.SetParams(ctx, params)
}
144 changes: 144 additions & 0 deletions app/upgrades/v3/upgrades_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package v3_test

import (
"testing"
"time"

"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/header"
"cosmossdk.io/x/upgrade"
upgradetypes "cosmossdk.io/x/upgrade/types"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"

milkywayapp "github.com/milkyway-labs/milkyway/v3/app"
"github.com/milkyway-labs/milkyway/v3/app/helpers"
v3 "github.com/milkyway-labs/milkyway/v3/app/upgrades/v3"
)

func TestUpgradeTestSuite(t *testing.T) {
suite.Run(t, new(UpgradeTestSuite))
}

type UpgradeTestSuite struct {
suite.Suite

App *milkywayapp.MilkyWayApp
Ctx sdk.Context
UpgradeModule appmodule.HasPreBlocker
}

func (suite *UpgradeTestSuite) SetupTest() {
suite.App = helpers.Setup(suite.T())
suite.Ctx = suite.App.NewUncachedContext(true, tmproto.Header{})
suite.Ctx = suite.Ctx.WithHeaderInfo(header.Info{Height: 1})
suite.UpgradeModule = upgrade.NewAppModule(suite.App.UpgradeKeeper, suite.App.AccountKeeper.AddressCodec())
}

func (suite *UpgradeTestSuite) TestUpgradeV3() {
operatorsParams, err := suite.App.OperatorsKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
operatorsParams.OperatorRegistrationFee = sdk.NewCoins(
sdk.NewInt64Coin("ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F", 1000000),
sdk.NewInt64Coin("ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5", 1000000),
sdk.NewInt64Coin("ibc/84FBEC4BBB48BD7CC534ED7518F339CCF6C45529DC00C7BFB8605C9EE7D68AFC", 1000000),
sdk.NewInt64Coin("ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157", 1000000),
sdk.NewInt64Coin("ibc/9ACD338BC3B488E0F50A54DE9A844C8326AF0739D917922A9CE04D42AD66017E", 1000000),
)
err = suite.App.OperatorsKeeper.SetParams(suite.Ctx, operatorsParams)
suite.Require().NoError(err)

servicesParams, err := suite.App.ServicesKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
servicesParams.ServiceRegistrationFee = sdk.NewCoins(
sdk.NewInt64Coin("ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F", 1000000),
sdk.NewInt64Coin("ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5", 1000000),
sdk.NewInt64Coin("ibc/84FBEC4BBB48BD7CC534ED7518F339CCF6C45529DC00C7BFB8605C9EE7D68AFC", 1000000),
sdk.NewInt64Coin("ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157", 1000000),
sdk.NewInt64Coin("ibc/9ACD338BC3B488E0F50A54DE9A844C8326AF0739D917922A9CE04D42AD66017E", 1000000),
)
err = suite.App.ServicesKeeper.SetParams(suite.Ctx, servicesParams)
suite.Require().NoError(err)

restakingParams, err := suite.App.RestakingKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
restakingParams.AllowedDenoms = []string{
"ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F",
"ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5",
"ibc/84FBEC4BBB48BD7CC534ED7518F339CCF6C45529DC00C7BFB8605C9EE7D68AFC",
"ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157",
"ibc/9ACD338BC3B488E0F50A54DE9A844C8326AF0739D917922A9CE04D42AD66017E",
"locked/ibc/F1183DB3D428313A6FD329DF18219F9D6B83257D07D292EA9EC1D877E89EC2B0",
}
err = suite.App.RestakingKeeper.SetParams(suite.Ctx, restakingParams)
suite.Require().NoError(err)

rewardsParams, err := suite.App.RewardsKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
rewardsParams.RewardsPlanCreationFee = sdk.NewCoins(
sdk.NewInt64Coin("ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F", 1000000),
sdk.NewInt64Coin("ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5", 1000000),
sdk.NewInt64Coin("ibc/84FBEC4BBB48BD7CC534ED7518F339CCF6C45529DC00C7BFB8605C9EE7D68AFC", 1000000),
sdk.NewInt64Coin("ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157", 1000000),
sdk.NewInt64Coin("ibc/9ACD338BC3B488E0F50A54DE9A844C8326AF0739D917922A9CE04D42AD66017E", 1000000),
)
err = suite.App.RewardsKeeper.SetParams(suite.Ctx, rewardsParams)
suite.Require().NoError(err)

suite.performUpgrade()

operatorsParams, err = suite.App.OperatorsKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
suite.Require().Equal(sdk.NewCoins(
sdk.NewInt64Coin("ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F", 1000000),
sdk.NewInt64Coin("ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5", 1000000),
sdk.NewInt64Coin("ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157", 1000000),
), operatorsParams.OperatorRegistrationFee)

servicesParams, err = suite.App.ServicesKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
suite.Require().Equal(sdk.NewCoins(
sdk.NewInt64Coin("ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F", 1000000),
sdk.NewInt64Coin("ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5", 1000000),
sdk.NewInt64Coin("ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157", 1000000),
), servicesParams.ServiceRegistrationFee)

restakingParams, err = suite.App.RestakingKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
suite.Require().Equal([]string{
"ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F",
"ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5",
"ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157",
"locked/ibc/F1183DB3D428313A6FD329DF18219F9D6B83257D07D292EA9EC1D877E89EC2B0",
}, restakingParams.AllowedDenoms)

rewardsParams, err = suite.App.RewardsKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
suite.Require().Equal(sdk.NewCoins(
sdk.NewInt64Coin("ibc/16065EE5282C5217685C8F084FC44864C25C706AC37356B0D62811D50B96920F", 1000000),
sdk.NewInt64Coin("ibc/6C349F0EB135C5FA99301758F35B87DB88403D690E5E314AB080401FEE4066E5", 1000000),
sdk.NewInt64Coin("ibc/8D4FC51F696E03711B9B37A5787FB89BD2DDBAF788813478B002D552A12F9157", 1000000),
), rewardsParams.RewardsPlanCreationFee)

_, err = suite.App.LiquidVestingKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)

slashingParams, err := suite.App.SlashingKeeper.GetParams(suite.Ctx)
suite.Require().NoError(err)
suite.Require().Equal(time.Hour, slashingParams.DowntimeJailDuration)
}

func (suite *UpgradeTestSuite) performUpgrade() {
upgradeHeight := suite.Ctx.HeaderInfo().Height + 1
plan := upgradetypes.Plan{Name: v3.UpgradeName, Height: upgradeHeight}
err := suite.App.UpgradeKeeper.ScheduleUpgrade(suite.Ctx, plan)
suite.Require().NoError(err)
_, err = suite.App.UpgradeKeeper.GetUpgradePlan(suite.Ctx)
suite.Require().NoError(err)

suite.Ctx = suite.Ctx.WithHeaderInfo(header.Info{Height: upgradeHeight})
// PreBlocker triggers the upgrade
_, err = suite.UpgradeModule.PreBlock(suite.Ctx)
suite.Require().NoError(err)
}
2 changes: 1 addition & 1 deletion x/liquidvesting/types/params.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package types

import (
fmt "fmt"
"fmt"
"slices"

"cosmossdk.io/math"
Expand Down
27 changes: 27 additions & 0 deletions x/rewards/keeper/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package keeper

import (
"context"
"errors"

"cosmossdk.io/collections"

"github.com/milkyway-labs/milkyway/v3/x/rewards/types"
)

// SetParams sets module parameters
func (k *Keeper) SetParams(ctx context.Context, params types.Params) error {
return k.Params.Set(ctx, params)
}

// GetParams returns the module parameters
func (k *Keeper) GetParams(ctx context.Context) (p types.Params, err error) {
p, err = k.Params.Get(ctx)
if err != nil {
if errors.Is(err, collections.ErrNotFound) {
return types.DefaultParams(), nil
}
return types.Params{}, err
}
return p, nil
}

0 comments on commit e27213e

Please sign in to comment.