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

chore: migrate and cleanup delegations #216

Merged
merged 12 commits into from
Dec 23, 2024
4 changes: 4 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,10 @@ func New(
v2_0.CreateUpgradeHandler(
app.ModuleManager,
app.Configurator(),
app.DelegationKeeper,
app.StakersKeeper,
app.StakingKeeper,
app.BankKeeper,
),
)

Expand Down
85 changes: 83 additions & 2 deletions app/upgrades/v2_0/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import (
"context"
"fmt"

"github.com/KYVENetwork/chain/x/stakers/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"

delegationkeeper "github.com/KYVENetwork/chain/x/delegation/keeper"
globalTypes "github.com/KYVENetwork/chain/x/global/types"
stakerskeeper "github.com/KYVENetwork/chain/x/stakers/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingTypes "github.com/cosmos/cosmos-sdk/x/staking/types"

"cosmossdk.io/log"
upgradetypes "cosmossdk.io/x/upgrade/types"

Expand All @@ -12,14 +21,18 @@ import (
)

const (
UpgradeName = "v1.6.0"
UpgradeName = "v2.0.0"
)

var logger log.Logger

func CreateUpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
delegationKeeper delegationkeeper.Keeper,
stakersKeeper *stakerskeeper.Keeper,
stakingKeeper *stakingkeeper.Keeper,
bankKeeper bankkeeper.Keeper,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
Expand All @@ -30,9 +43,77 @@ func CreateUpgradeHandler(
migratedVersionMap, err := mm.RunMigrations(ctx, configurator, fromVM)

// Run KYVE migrations
migrateProtocolStakers(sdkCtx, delegationKeeper, stakersKeeper, stakingKeeper, bankKeeper)

// TODO: migrate slash params, commission change queues
logger.Info(fmt.Sprintf("finished upgrade %v", UpgradeName))

return migratedVersionMap, err
}
}

func migrateProtocolStakers(ctx sdk.Context, delegationKeeper delegationkeeper.Keeper,
stakersKeeper *stakerskeeper.Keeper,
stakingKeeper *stakingkeeper.Keeper,
bankKeeper bankkeeper.Keeper,
) {
// Process current unbonding queue
delegationKeeper.FullyProcessDelegatorUnbondingQueue(ctx)

validatorMapping := ValidatorMappingsMainnet
if ctx.ChainID() == "kaon-1" {
validatorMapping = ValidatorMappingsKaon
}

totalMigratedStake := uint64(0)
for _, mapping := range validatorMapping {
delegators := delegationKeeper.GetDelegatorsByStaker(ctx, mapping.ProtocolAddress)

for _, delegator := range delegators {
amount := delegationKeeper.PerformFullUndelegation(ctx, mapping.ProtocolAddress, delegator)
totalMigratedStake += amount

stakingServer := stakingkeeper.NewMsgServerImpl(stakingKeeper)
_, err := stakingServer.Delegate(ctx, stakingTypes.NewMsgDelegate(
delegator,
mapping.ConsensusAddress,
sdk.NewInt64Coin(globalTypes.Denom, int64(amount)),
))
if err != nil {
panic(err)
}
}
}
logger.Info(fmt.Sprintf("migrated %d ukyve from protocol to chain", totalMigratedStake))

// Undelegate Remaining
totalReturnedStake := uint64(0)
for _, delegator := range delegationKeeper.GetAllDelegators(ctx) {
amount := delegationKeeper.PerformFullUndelegation(ctx, delegator.Staker, delegator.Delegator)
totalReturnedStake += amount
}
logger.Info(fmt.Sprintf("returned %d ukyve from protocol to users", totalReturnedStake))

// Withdraw Pending Commissions
for _, staker := range stakersKeeper.GetAllLegacyStakers(ctx) {
if err := bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.MustAccAddressFromBech32(staker.Address), staker.CommissionRewards); err != nil {
panic(err)
}
_ = ctx.EventManager().EmitTypedEvent(&types.EventClaimCommissionRewards{
Staker: staker.Address,
Amounts: staker.CommissionRewards.String(),
})
}

// Delete all legacy stakers objects
stakersKeeper.Migration_ResetOldState(ctx)

// Migrate Params
delegationParams := delegationKeeper.GetParams(ctx)
stakersParams := stakersKeeper.GetParams(ctx)

stakersParams.TimeoutSlash = delegationParams.TimeoutSlash
stakersParams.UploadSlash = delegationParams.UploadSlash
stakersParams.VoteSlash = delegationParams.VoteSlash

stakersKeeper.SetParams(ctx, stakersParams)
}
42 changes: 42 additions & 0 deletions app/upgrades/v2_0/validator-proofs/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## Protocol-Consensus Validator Linking

For the Shared Staking update [https://www.mintscan.io/kyve/proposals/43](https://www.mintscan.io/kyve/proposals/43)
it is necessary that every validator links their protocol and consensus validator.

All delegators are then transferred from the protocol validator to the consensus
validator during the upgrade.

If a protocol validator does not link to a chain validator before the upgrade is finalized,
all stake is returned to the original delegators during the migration.

### Steps

1. Enter the `mainnet`-directory and copy the `example-validator.json` config file and name it after your validator.

2. Fill out the `name`, `protocol_address` and `consensus_address`

3. Send 1 $KYVE from the protocol-address to the consensus-validator-operator address using the memo "Shared-Staking"
and put the tx-hash in proof_1.

4. Send 1 $KYVE from the consensus-validator-operator address to the protocol address using the memo "Shared-Staking"
and put the tx-hash in proof_2.

5. Submit a Pull-Request to https://github.com/KYVENetwork/chain

6. (Optional) Perform the same steps for the `kaon` directory with your Kaon validators.

## General Upgrade Procedure

All pending protocol commission will be claimed and returned to the validators
during the upgrade.

During the upgrade, all validators will be kicked out of all pools and
need to manually rejoin after the upgrade. This is due to the fact, that
every validator now has to specify a commission per pool and a stake-fraction.
The stake-fraction is a percentage of how much of the chain-stake a validator
wants to use for a specific pool.

## Questions

If you have any questions feel free to submit an issue or ask them directly while
creating the pull-request.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "My example Kaon validator name - this is just for human-readability",
"consensus_address": "kyvevaloper...",
"protocol_address": "kyve...",
"proof_1": "89644D8598D007F7B744E91BA4490C11513860046C257F29CFAF41EAE37FAE9C",
"proof_2": "36A1110532EC28C4BEDA610720CA31DD1B14D4A49772F8890EB5C62B417D253B"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "My example validator name - this is just for human-readability",
"consensus_address": "kyvevaloper...",
"protocol_address": "kyve...",
"proof_1": "EEA08DDDA94434BBE1FA25AB941B58D85FC5EE48E866B602549CA194CAB41B11",
"proof_2": "21771F8B4B2F72D0F292F3517051FD6D8CAA5BB9EC83B906F2BF38684F1E624E"
}
49 changes: 49 additions & 0 deletions app/upgrades/v2_0/validator_mapping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package v2_0

import (
"embed"
"encoding/json"
"fmt"
)

//go:embed validator-proofs/*
var validatorProofs embed.FS

func init() {
parseDirectory := func(directory string) []ValidatorMapping {
dir, err := validatorProofs.ReadDir(directory)
if err != nil {
panic(err)
}

result := make([]ValidatorMapping, 0)
for _, file := range dir {
readFile, err := validatorProofs.ReadFile(fmt.Sprintf("%s/%s", directory, file.Name()))
if err != nil {
panic(err)
}

var proof ValidatorMapping
if err = json.Unmarshal(readFile, &proof); err != nil {
panic(err)
}
result = append(result, proof)
}
return result
}

ValidatorMappingsMainnet = parseDirectory("validator-proofs/mainnet")
ValidatorMappingsKaon = parseDirectory("validator-proofs/kaon")
}

type ValidatorMapping struct {
Name string `json:"name"`
ConsensusAddress string `json:"consensus_address"`
ProtocolAddress string `json:"protocol_address"`
Proof1 string `json:"proof_1"`
Proof2 string `json:"proof_2"`
}

var ValidatorMappingsMainnet []ValidatorMapping

var ValidatorMappingsKaon []ValidatorMapping
16 changes: 0 additions & 16 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,6 @@
}
}
},
{
"url": "./tmp-swagger-gen/kyve/delegation/v1beta1/query.swagger.json",
"operationIds": {
"rename": {
"Params": "DelegationParams"
}
},
"tags": {
"rename": {
"Query": "QueryDelegation"
}
}
},
{
"url": "./tmp-swagger-gen/kyve/global/v1beta1/query.swagger.json",
"operationIds": {
Expand All @@ -51,9 +38,6 @@
{
"url": "./tmp-swagger-gen/kyve/query/v1beta1/bundles.swagger.json"
},
{
"url": "./tmp-swagger-gen/kyve/query/v1beta1/delegation.swagger.json"
},
{
"url": "./tmp-swagger-gen/kyve/query/v1beta1/params.swagger.json"
},
Expand Down
Loading
Loading