Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support cosmos lsm #2909

Merged
merged 7 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"
"testing"

iristypes "github.com/irisnet/irishub/v2/types"
coinswaptypes "github.com/irisnet/irismod/modules/coinswap/types"
htlctypes "github.com/irisnet/irismod/modules/htlc/types"
mttypes "github.com/irisnet/irismod/modules/mt/types"
Expand All @@ -20,6 +19,8 @@ import (
tokentypes "github.com/irisnet/irismod/modules/token/types"
"github.com/stretchr/testify/require"

iristypes "github.com/irisnet/irishub/v2/types"

dbm "github.com/cometbft/cometbft-db"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
Expand Down
1 change: 1 addition & 0 deletions app/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func (app *IrisApp) appKeepers() upgrades.AppKeepers {
ReaderWriter: app,
ConsensusParamsKeeper: app.ConsensusParamsKeeper,
ParamsKeeper: app.ParamsKeeper,
StakingKeeper: app.StakingKeeper,
}
}

Expand Down
85 changes: 0 additions & 85 deletions app/upgrades/helper.go

This file was deleted.

2 changes: 2 additions & 0 deletions app/upgrades/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"

Expand Down Expand Up @@ -61,6 +62,7 @@ type AppKeepers struct {
ReaderWriter ConsensusParamsReaderWriter
ConsensusParamsKeeper consensuskeeper.Keeper
ParamsKeeper paramskeeper.Keeper
StakingKeeper *stakingkeeper.Keeper
}

type upgradeRouter struct {
Expand Down
97 changes: 57 additions & 40 deletions app/upgrades/v300/constants.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,59 @@
package v300

var allowMessages = []string{
"/cosmos.authz.v1beta1.MsgExec",
"/cosmos.authz.v1beta1.MsgGrant",
"/cosmos.authz.v1beta1.MsgRevoke",
"/cosmos.bank.v1beta1.MsgSend",
"/cosmos.bank.v1beta1.MsgMultiSend",
"/cosmos.distribution.v1beta1.MsgSetWithdrawAddress",
"/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission",
"/cosmos.distribution.v1beta1.MsgFundCommunityPool",
"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
"/cosmos.feegrant.v1beta1.MsgGrantAllowance",
"/cosmos.feegrant.v1beta1.MsgRevokeAllowance",
"/cosmos.gov.v1beta1.MsgVoteWeighted",
"/cosmos.gov.v1beta1.MsgSubmitProposal",
"/cosmos.gov.v1beta1.MsgDeposit",
"/cosmos.gov.v1beta1.MsgVote",
"/cosmos.gov.v1.MsgVoteWeighted",
"/cosmos.gov.v1.MsgSubmitProposal",
"/cosmos.gov.v1.MsgDeposit",
"/cosmos.gov.v1.MsgVote",
"/cosmos.staking.v1beta1.MsgEditValidator",
"/cosmos.staking.v1beta1.MsgDelegate",
"/cosmos.staking.v1beta1.MsgUndelegate",
"/cosmos.staking.v1beta1.MsgBeginRedelegate",
"/cosmos.staking.v1beta1.MsgCreateValidator",
"/cosmos.vesting.v1beta1.MsgCreateVestingAccount",
"/ibc.applications.transfer.v1.MsgTransfer",
"/irismod.nft.MsgIssueDenom",
"/irismod.nft.MsgTransferDenom",
"/irismod.nft.MsgMintNFT",
"/irismod.nft.MsgEditNFT",
"/irismod.nft.MsgTransferNFT",
"/irismod.nft.MsgBurnNFT",
"/irismod.mt.MsgIssueDenom",
"/irismod.mt.MsgTransferDenom",
"/irismod.mt.MsgMintMT",
"/irismod.mt.MsgEditMT",
"/irismod.mt.MsgTransferMT",
"/irismod.mt.MsgBurnMT",
}
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var (
// ValidatorBondFactor dictates the cap on the liquid shares
// for a validator - determined as a multiple to their validator bond
// (e.g. ValidatorBondShares = 1000, BondFactor = 250 -> LiquidSharesCap: 250,000)
ValidatorBondFactor = sdk.NewDec(250)
// ValidatorLiquidStakingCap represents a cap on the portion of stake that
// comes from liquid staking providers for a specific validator
ValidatorLiquidStakingCap = sdk.MustNewDecFromStr("1") // 100%
// GlobalLiquidStakingCap represents the percentage cap on
// the portion of a chain's total stake can be liquid
GlobalLiquidStakingCap = sdk.MustNewDecFromStr("0.25") // 25%

allowMessages = []string{
"/cosmos.authz.v1beta1.MsgExec",
"/cosmos.authz.v1beta1.MsgGrant",
"/cosmos.authz.v1beta1.MsgRevoke",
"/cosmos.bank.v1beta1.MsgSend",
"/cosmos.bank.v1beta1.MsgMultiSend",
"/cosmos.distribution.v1beta1.MsgSetWithdrawAddress",
"/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission",
"/cosmos.distribution.v1beta1.MsgFundCommunityPool",
"/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward",
"/cosmos.feegrant.v1beta1.MsgGrantAllowance",
"/cosmos.feegrant.v1beta1.MsgRevokeAllowance",
"/cosmos.gov.v1beta1.MsgVoteWeighted",
"/cosmos.gov.v1beta1.MsgSubmitProposal",
"/cosmos.gov.v1beta1.MsgDeposit",
"/cosmos.gov.v1beta1.MsgVote",
"/cosmos.gov.v1.MsgVoteWeighted",
"/cosmos.gov.v1.MsgSubmitProposal",
"/cosmos.gov.v1.MsgDeposit",
"/cosmos.gov.v1.MsgVote",
"/cosmos.staking.v1beta1.MsgEditValidator",
"/cosmos.staking.v1beta1.MsgDelegate",
"/cosmos.staking.v1beta1.MsgUndelegate",
"/cosmos.staking.v1beta1.MsgBeginRedelegate",
"/cosmos.staking.v1beta1.MsgCreateValidator",
"/cosmos.vesting.v1beta1.MsgCreateVestingAccount",
"/ibc.applications.transfer.v1.MsgTransfer",
"/irismod.nft.MsgIssueDenom",
"/irismod.nft.MsgTransferDenom",
"/irismod.nft.MsgMintNFT",
"/irismod.nft.MsgEditNFT",
"/irismod.nft.MsgTransferNFT",
"/irismod.nft.MsgBurnNFT",
"/irismod.mt.MsgIssueDenom",
"/irismod.mt.MsgTransferDenom",
"/irismod.mt.MsgMintMT",
"/irismod.mt.MsgEditMT",
"/irismod.mt.MsgTransferMT",
"/irismod.mt.MsgBurnMT",
}
)
135 changes: 135 additions & 0 deletions app/upgrades/v300/lsm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package v300

import (
"sort"

"github.com/cosmos/cosmos-sdk/codec"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

// keeper contains the staking keeper functions required
// for the migration
type keeper interface {
GetAllDelegations(ctx sdk.Context) []types.Delegation
GetAllValidators(ctx sdk.Context) []types.Validator
SetDelegation(ctx sdk.Context, delegation types.Delegation)
SetValidator(ctx sdk.Context, validator types.Validator)
RefreshTotalLiquidStaked(ctx sdk.Context) error
GetParams(ctx sdk.Context) (params types.Params)
SetParams(ctx sdk.Context, params types.Params) error
}

// MigrateParamsStore migrates the params store to the latest version.
//
// ctx - sdk context
// k - keeper
func MigrateParamsStore(ctx sdk.Context, k keeper) {
params := k.GetParams(ctx)
params.ValidatorBondFactor = ValidatorBondFactor
params.ValidatorLiquidStakingCap = ValidatorLiquidStakingCap
params.GlobalLiquidStakingCap = GlobalLiquidStakingCap
k.SetParams(ctx, params)
}

// MigrateValidators Set each validator's ValidatorBondShares and LiquidShares to 0
func MigrateValidators(ctx sdk.Context, k keeper) {
for _, validator := range k.GetAllValidators(ctx) {
validator.ValidatorBondShares = sdk.ZeroDec()
validator.LiquidShares = sdk.ZeroDec()
k.SetValidator(ctx, validator)
}
}

// MigrateDelegations Set each delegation's ValidatorBond field to false
func MigrateDelegations(ctx sdk.Context, k keeper) {
for _, delegation := range k.GetAllDelegations(ctx) {
delegation.ValidatorBond = false
k.SetDelegation(ctx, delegation)
}
}

// MigrateUBDEntries will remove the ubdEntries with same creation_height
// and create a new ubdEntry with updated balance and initial_balance
func MigrateUBDEntries(ctx sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec) error {
iterator := sdk.KVStorePrefixIterator(store, types.UnbondingDelegationKey)
defer iterator.Close()

for ; iterator.Valid(); iterator.Next() {
ubd := types.MustUnmarshalUBD(cdc, iterator.Value())

entriesAtSameCreationHeight := make(map[int64][]types.UnbondingDelegationEntry)
for _, ubdEntry := range ubd.Entries {
entriesAtSameCreationHeight[ubdEntry.CreationHeight] = append(entriesAtSameCreationHeight[ubdEntry.CreationHeight], ubdEntry)
}

creationHeights := make([]int64, 0, len(entriesAtSameCreationHeight))
for k := range entriesAtSameCreationHeight {
creationHeights = append(creationHeights, k)
}

sort.Slice(creationHeights, func(i, j int) bool { return creationHeights[i] < creationHeights[j] })

ubd.Entries = make([]types.UnbondingDelegationEntry, 0, len(creationHeights))

for _, h := range creationHeights {
ubdEntry := types.UnbondingDelegationEntry{
Balance: sdk.ZeroInt(),
InitialBalance: sdk.ZeroInt(),
}
for _, entry := range entriesAtSameCreationHeight[h] {
ubdEntry.Balance = ubdEntry.Balance.Add(entry.Balance)
ubdEntry.InitialBalance = ubdEntry.InitialBalance.Add(entry.InitialBalance)
ubdEntry.CreationHeight = entry.CreationHeight
ubdEntry.CompletionTime = entry.CompletionTime
}
ubd.Entries = append(ubd.Entries, ubdEntry)
}

// set the new ubd to the store
setUBDToStore(ctx, store, cdc, ubd)
}
return nil
}

func setUBDToStore(_ sdk.Context, store storetypes.KVStore, cdc codec.BinaryCodec, ubd types.UnbondingDelegation) {
delegatorAddress := sdk.MustAccAddressFromBech32(ubd.DelegatorAddress)

bz := types.MustMarshalUBD(cdc, ubd)

addr, err := sdk.ValAddressFromBech32(ubd.ValidatorAddress)
if err != nil {
panic(err)
}

key := types.GetUBDKey(delegatorAddress, addr)

store.Set(key, bz)
}

// MigrateStore performs the in-place store migration for adding LSM support to v0.45.16-ics, including:
// - Adding params ValidatorBondFactor, GlobalLiquidStakingCap, ValidatorLiquidStakingCap
// - Setting each validator's ValidatorBondShares and LiquidShares to 0
// - Setting each delegation's ValidatorBond field to false
// - Calculating the total liquid staked by summing the delegations from ICA accounts
func MigrateStore(ctx sdk.Context, storeKey storetypes.StoreKey, cdc codec.BinaryCodec, k keeper) error {
store := ctx.KVStore(storeKey)

ctx.Logger().Info("Staking LSM Migration: Migrating param store")
MigrateParamsStore(ctx, k)

ctx.Logger().Info("Staking LSM Migration: Migrating validators")
MigrateValidators(ctx, k)

ctx.Logger().Info("Staking LSM Migration: Migrating delegations")
MigrateDelegations(ctx, k)

ctx.Logger().Info("Staking LSM Migration: Migrating UBD entries")
if err := MigrateUBDEntries(ctx, store, cdc); err != nil {
return err
}

ctx.Logger().Info("Staking LSM Migration: Calculating total liquid staked")
return k.RefreshTotalLiquidStaked(ctx)
}
Loading
Loading