Skip to content

Commit

Permalink
chore: multiple coins migration (#187)
Browse files Browse the repository at this point in the history
Co-authored-by: mbreithecker <m@breithecker.de>
  • Loading branch information
troykessler and mbreithecker authored Jun 4, 2024
1 parent 87f6718 commit 6bbd4d8
Show file tree
Hide file tree
Showing 16 changed files with 6,089 additions and 38 deletions.
3 changes: 3 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,9 @@ func New(
app.appCodec,
app.GetStoreKeys(),
app.BundlesKeeper,
app.DelegationKeeper,
app.FundersKeeper,
app.StakersKeeper,
app.PoolKeeper,
),
)
Expand Down
161 changes: 130 additions & 31 deletions app/upgrades/v1_5/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,30 @@ import (
"context"
"fmt"

poolKeeper "github.com/KYVENetwork/chain/x/pool/keeper"
poolTypes "github.com/KYVENetwork/chain/x/pool/types"

"github.com/KYVENetwork/chain/app/upgrades/v1_5/v1_4_types/bundles"
"github.com/KYVENetwork/chain/app/upgrades/v1_5/v1_4_types/delegation"
"github.com/KYVENetwork/chain/app/upgrades/v1_5/v1_4_types/funders"
"github.com/KYVENetwork/chain/app/upgrades/v1_5/v1_4_types/pool"
"github.com/KYVENetwork/chain/app/upgrades/v1_5/v1_4_types/stakers"
delegationKeeper "github.com/KYVENetwork/chain/x/delegation/keeper"
delegationTypes "github.com/KYVENetwork/chain/x/delegation/types"
fundersKeeper "github.com/KYVENetwork/chain/x/funders/keeper"
funderTypes "github.com/KYVENetwork/chain/x/funders/types"
fundersTypes "github.com/KYVENetwork/chain/x/funders/types"
globalTypes "github.com/KYVENetwork/chain/x/global/types"
stakersKeeper "github.com/KYVENetwork/chain/x/stakers/keeper"
stakersTypes "github.com/KYVENetwork/chain/x/stakers/types"

"cosmossdk.io/math"

storetypes "cosmossdk.io/store/types"
upgradetypes "cosmossdk.io/x/upgrade/types"

"github.com/KYVENetwork/chain/app/upgrades/v1_5/v1_4_types"
"github.com/KYVENetwork/chain/x/bundles/keeper"
bundlestypes "github.com/KYVENetwork/chain/x/bundles/types"
poolkeeper "github.com/KYVENetwork/chain/x/pool/keeper"
bundlesKeeper "github.com/KYVENetwork/chain/x/bundles/keeper"
bundlesTypes "github.com/KYVENetwork/chain/x/bundles/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
Expand All @@ -22,56 +37,140 @@ const (
UpgradeName = "v1.5.0"
)

func CreateUpgradeHandler(mm *module.Manager, configurator module.Configurator, cdc codec.Codec, storeKeys []storetypes.StoreKey, bundlesKeeper keeper.Keeper, poolKeeper *poolkeeper.Keeper) upgradetypes.UpgradeHandler {
func CreateUpgradeHandler(mm *module.Manager, configurator module.Configurator, cdc codec.Codec, storeKeys []storetypes.StoreKey, bundlesKeeper bundlesKeeper.Keeper, delegationKeeper delegationKeeper.Keeper, fundersKeeper fundersKeeper.Keeper, stakersKeeper *stakersKeeper.Keeper, poolKeeper *poolKeeper.Keeper) upgradetypes.UpgradeHandler {
return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
logger := sdkCtx.Logger().With("upgrade", UpgradeName)
logger.Info(fmt.Sprintf("performing upgrade %v", UpgradeName))

if err := migrateStorageCosts(sdkCtx, bundlesKeeper, poolKeeper, storeKeys, cdc); err != nil {
return nil, err
}

// TODO: migrate gov params
// TODO emit events if necessary

// TODO: migrate fundings
// migrate fundings
MigrateFundersModule(sdkCtx, cdc, MustGetStoreKey(storeKeys, fundersTypes.StoreKey), fundersKeeper)

// TODO: migrate delegation outstanding rewards
// migrate delegations
migrateDelegationModule(sdkCtx, cdc, MustGetStoreKey(storeKeys, delegationTypes.StoreKey), delegationKeeper)

// TODO: migrate network fee and whitelist weights
// migrate stakers
migrateStakersModule(sdkCtx, cdc, MustGetStoreKey(storeKeys, stakersTypes.StoreKey), stakersKeeper)

// TODO: migrate MaxVotingPowerPerPool in pool params
// migrate bundles
migrateBundlesModule(sdkCtx, cdc, MustGetStoreKey(storeKeys, bundlesTypes.StoreKey), bundlesKeeper)

// migrate pool
migrateMaxVotingPowerInPool(sdkCtx, cdc, MustGetStoreKey(storeKeys, poolTypes.StoreKey), *poolKeeper)

return mm.RunMigrations(ctx, configurator, fromVM)
}
}

func migrateStorageCosts(sdkCtx sdk.Context, bundlesKeeper keeper.Keeper, poolKeeper *poolkeeper.Keeper, storeKeys []storetypes.StoreKey, cdc codec.Codec) error {
var bundlesStoreKey storetypes.StoreKey
func MustGetStoreKey(storeKeys []storetypes.StoreKey, storeName string) storetypes.StoreKey {
for _, k := range storeKeys {
if k.Name() == "bundles" {
bundlesStoreKey = k
break
if k.Name() == storeName {
return k
}
}
if bundlesStoreKey == nil {
return fmt.Errorf("store key not found: bundles")

panic(fmt.Sprintf("failed to find store key: %s", fundersTypes.StoreKey))
}

func MigrateFundersModule(sdkCtx sdk.Context, cdc codec.Codec, fundersStoreKey storetypes.StoreKey, fundersKeeper fundersKeeper.Keeper) {
// migrate params
// TODO: define final prices and initial whitelisted coins
oldParams := funders.GetParams(sdkCtx, cdc, fundersStoreKey)
fundersKeeper.SetParams(sdkCtx, fundersTypes.Params{
CoinWhitelist: []*fundersTypes.WhitelistCoinEntry{
{
CoinDenom: globalTypes.Denom,
MinFundingAmount: oldParams.MinFundingAmount,
MinFundingAmountPerBundle: oldParams.MinFundingAmountPerBundle,
CoinWeight: math.LegacyMustNewDecFromStr("0.06"),
},
},
MinFundingMultiple: oldParams.MinFundingMultiple,
})

// migrate fundings
oldFundings := funders.GetAllFundings(sdkCtx, cdc, fundersStoreKey)
for _, f := range oldFundings {
fundersKeeper.SetFunding(sdkCtx, &funderTypes.Funding{
FunderAddress: f.FunderAddress,
PoolId: f.PoolId,
Amounts: sdk.NewCoins(sdk.NewInt64Coin(globalTypes.Denom, int64(f.Amount))),
AmountsPerBundle: sdk.NewCoins(sdk.NewInt64Coin(globalTypes.Denom, int64(f.AmountPerBundle))),
TotalFunded: sdk.NewCoins(sdk.NewInt64Coin(globalTypes.Denom, int64(f.TotalFunded))),
})
}
}

func migrateDelegationModule(sdkCtx sdk.Context, cdc codec.Codec, delegationStoreKey storetypes.StoreKey, delegationKeeper delegationKeeper.Keeper) {
// migrate delegation entries
oldDelegationEntries := delegation.GetAllDelegationEntries(sdkCtx, cdc, delegationStoreKey)
for _, d := range oldDelegationEntries {
delegationKeeper.SetDelegationEntry(sdkCtx, delegationTypes.DelegationEntry{
Staker: d.Staker,
KIndex: d.KIndex,
Value: sdk.NewDecCoins(sdk.NewDecCoinFromDec(globalTypes.Denom, d.Value)),
})
}

// Copy storage cost from old params to new params
// The storage cost of all storage providers will be the same after this migration
oldParams := v1_4_types.GetParams(sdkCtx, bundlesStoreKey, cdc)
newParams := bundlestypes.Params{
// migrate delegation data
oldDelegationData := delegation.GetAllDelegationData(sdkCtx, cdc, delegationStoreKey)
for _, d := range oldDelegationData {
delegationKeeper.SetDelegationData(sdkCtx, delegationTypes.DelegationData{
Staker: d.Staker,
CurrentRewards: sdk.NewCoins(sdk.NewInt64Coin(globalTypes.Denom, int64(d.CurrentRewards))),
TotalDelegation: d.TotalDelegation,
LatestIndexK: d.LatestIndexK,
DelegatorCount: d.DelegatorCount,
LatestIndexWasUndelegation: d.LatestIndexWasUndelegation,
})
}
}

func migrateStakersModule(sdkCtx sdk.Context, cdc codec.Codec, stakersStoreKey storetypes.StoreKey, stakersKeeper *stakersKeeper.Keeper) {
// migrate stakers
oldStakers := stakers.GetAllStakers(sdkCtx, cdc, stakersStoreKey)
for _, s := range oldStakers {
stakersKeeper.Migration_SetStaker(sdkCtx, stakersTypes.Staker{
Address: s.Address,
Commission: s.Commission,
Moniker: s.Moniker,
Website: s.Website,
Identity: s.Identity,
SecurityContact: s.SecurityContact,
Details: s.Details,
CommissionRewards: sdk.NewCoins(sdk.NewInt64Coin(globalTypes.Denom, int64(s.CommissionRewards))),
})
}
}

func migrateBundlesModule(sdkCtx sdk.Context, cdc codec.Codec, bundlesStoreKey storetypes.StoreKey, bundlesKeeper bundlesKeeper.Keeper) {
oldParams := bundles.GetParams(sdkCtx, cdc, bundlesStoreKey)

// TODO: define final storage cost prices
bundlesKeeper.SetParams(sdkCtx, bundlesTypes.Params{
UploadTimeout: oldParams.UploadTimeout,
StorageCosts: []bundlestypes.StorageCost{
// TODO: define value for storage provider id 1 and 2
{StorageProviderId: 1, Cost: math.LegacyMustNewDecFromStr("0.00")},
{StorageProviderId: 2, Cost: math.LegacyMustNewDecFromStr("0.00")},
StorageCosts: []bundlesTypes.StorageCost{
// Arweave: https://arweave.net/price/1048576 -> 699 winston/byte * 40 USD/AR * 1.5 / 10**12
{StorageProviderId: 1, Cost: math.LegacyMustNewDecFromStr("0.000000004194")},
// Irys: https://node1.bundlr.network/price/1048576 -> 1048 winston/byte * 40 USD/AR * 1.5 / 10**12
{StorageProviderId: 2, Cost: math.LegacyMustNewDecFromStr("0.000000006288")},
// KYVE Storage Provider: zero since it is free to use for testnet participants
{StorageProviderId: 3, Cost: math.LegacyMustNewDecFromStr("0.00")},
},
NetworkFee: oldParams.NetworkFee,
MaxPoints: oldParams.MaxPoints,
}
})
}

func migrateMaxVotingPowerInPool(sdkCtx sdk.Context, cdc codec.Codec, poolStoreKey storetypes.StoreKey, poolKeeper poolKeeper.Keeper) {
oldParams := pool.GetParams(sdkCtx, cdc, poolStoreKey)

bundlesKeeper.SetParams(sdkCtx, newParams)
return nil
poolKeeper.SetParams(sdkCtx, poolTypes.Params{
ProtocolInflationShare: oldParams.ProtocolInflationShare,
PoolInflationPayoutRate: oldParams.PoolInflationPayoutRate,
MaxVotingPowerPerPool: math.LegacyMustNewDecFromStr("0.5"),
})
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package v1_4_types
package bundles

import (
storeTypes "cosmossdk.io/store/types"
Expand All @@ -8,7 +8,7 @@ import (
)

// GetParams returns the current x/bundles module parameters.
func GetParams(ctx sdk.Context, storeKey storeTypes.StoreKey, cdc codec.Codec) (params Params) {
func GetParams(ctx sdk.Context, cdc codec.Codec, storeKey storeTypes.StoreKey) (params Params) {
store := ctx.KVStore(storeKey)

bz := store.Get(types.ParamsPrefix)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 6bbd4d8

Please sign in to comment.