Skip to content

Commit

Permalink
fix: QCK-425 update delegations on redelegation (#428)
Browse files Browse the repository at this point in the history
* debug: Additional logging in panic statement for GetUnlockedTokensForZone [QCK-425]

* fix: update delegation records on MsgBeginRedelegation callback

* add upgrade handler for v1.4.2-rc6 to reset all delegation records

* gofumpt

* fix: reorder handlequeuedunbondings to avoid bad state in error case QCK-437

---------

Co-authored-by: Alex Johnson <[email protected]>
  • Loading branch information
Joe Bowman and Alex Johnson authored May 12, 2023
1 parent 04e0e7e commit 2722a77
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 7 deletions.
1 change: 1 addition & 0 deletions app/upgrades/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
V010402rc3UpgradeName = "v1.4.2-rc3"
V010402rc4UpgradeName = "v1.4.2-rc4"
V010402rc5UpgradeName = "v1.4.2-rc5"
V010402rc6UpgradeName = "v1.4.2-rc6"
)

// Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal
Expand Down
35 changes: 35 additions & 0 deletions app/upgrades/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/types/query"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/ingenuity-build/quicksilver/app/keepers"
Expand All @@ -21,6 +23,7 @@ func Upgrades() []Upgrade {
{UpgradeName: V010402rc3UpgradeName, CreateUpgradeHandler: V010402rc3UpgradeHandler},
{UpgradeName: V010402rc4UpgradeName, CreateUpgradeHandler: V010402rc4UpgradeHandler},
{UpgradeName: V010402rc5UpgradeName, CreateUpgradeHandler: V010402rc5UpgradeHandler},
{UpgradeName: V010402rc6UpgradeName, CreateUpgradeHandler: V010402rc6UpgradeHandler},
}
}

Expand Down Expand Up @@ -214,6 +217,38 @@ func V010402rc5UpgradeHandler(
}
}

func V010402rc6UpgradeHandler(
mm *module.Manager,
configurator module.Configurator,
appKeepers *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
if isTestnet(ctx) || isTest(ctx) {
// for each zone, trigger an icq request to update all delegations.
appKeepers.InterchainstakingKeeper.IterateZones(ctx, func(index int64, zone *types.Zone) (stop bool) {
vals := appKeepers.InterchainstakingKeeper.GetValidators(ctx, zone.ChainId)
delegationQuery := stakingtypes.QueryDelegatorDelegationsRequest{DelegatorAddr: zone.DelegationAddress.Address, Pagination: &query.PageRequest{Limit: uint64(len(vals))}}
bz := appKeepers.InterchainstakingKeeper.GetCodec().MustMarshal(&delegationQuery)

appKeepers.InterchainstakingKeeper.ICQKeeper.MakeRequest(
ctx,
zone.ConnectionId,
zone.ChainId,
"cosmos.staking.v1beta1.Query/DelegatorDelegations",
bz,
sdk.NewInt(-1),
types.ModuleName,
"delegations",
0,
)
return false
})
}

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

// func V010400UpgradeHandler(
// mm *module.Manager,
// configurator module.Configurator,
Expand Down
58 changes: 55 additions & 3 deletions x/interchainstaking/keeper/ibc_packet_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,13 +594,65 @@ func (k *Keeper) HandleBeginRedelegate(ctx sdk.Context, msg sdk.Msg, completion
record.CompletionTime = completion
k.SetRedelegationRecord(ctx, record)

delegation, found := k.GetDelegation(ctx, zone, redelegateMsg.DelegatorAddress, redelegateMsg.ValidatorDstAddress)
tgtDelegation, found := k.GetDelegation(ctx, zone, redelegateMsg.DelegatorAddress, redelegateMsg.ValidatorDstAddress)
if !found {
k.Logger(ctx).Error("unable to find delegation record", "chain", zone.ChainId, "source", redelegateMsg.ValidatorSrcAddress, "dst", redelegateMsg.ValidatorDstAddress, "epoch_number", epochNumber)
return fmt.Errorf("unable to find delegation record for chain %s, src: %s, dst: %s, at epoch %d", zone.ChainId, redelegateMsg.ValidatorSrcAddress, redelegateMsg.ValidatorDstAddress, epochNumber)
}
delegation.RedelegationEnd = completion.Unix() // this field should be a timestamp, but let's avoid unnecessary state changes.
k.SetDelegation(ctx, zone, delegation)
// TODO: is the field below actually used?
tgtDelegation.Amount = tgtDelegation.Amount.Add(redelegateMsg.Amount)
tgtDelegation.RedelegationEnd = completion.Unix() // this field should be a timestamp, but let's avoid unnecessary state changes.
k.SetDelegation(ctx, zone, tgtDelegation)

delAddr, err := utils.AccAddressFromBech32(redelegateMsg.DelegatorAddress, zone.AccountPrefix)
if err != nil {
return err
}
valAddr, err := utils.ValAddressFromBech32(redelegateMsg.ValidatorDstAddress, zone.AccountPrefix+"valoper")
if err != nil {
return err
}
data := stakingtypes.GetDelegationKey(delAddr, valAddr)

// send request to update delegation record for target del/val tuple.
k.ICQKeeper.MakeRequest(
ctx,
zone.ConnectionId,
zone.ChainId,
"store/staking/key",
data,
sdk.NewInt(-1),
types.ModuleName,
"delegation",
0,
)

srcDelegation, found := k.GetDelegation(ctx, zone, redelegateMsg.DelegatorAddress, redelegateMsg.ValidatorDstAddress)
if !found {
k.Logger(ctx).Error("unable to find delegation record", "chain", zone.ChainId, "source", redelegateMsg.ValidatorSrcAddress, "dst", redelegateMsg.ValidatorDstAddress, "epoch_number", epochNumber)
return fmt.Errorf("unable to find delegation record for chain %s, src: %s, dst: %s, at epoch %d", zone.ChainId, redelegateMsg.ValidatorSrcAddress, redelegateMsg.ValidatorDstAddress, epochNumber)
}
srcDelegation.Amount = tgtDelegation.Amount.Sub(redelegateMsg.Amount)
k.SetDelegation(ctx, zone, srcDelegation)

valAddr, err = utils.ValAddressFromBech32(redelegateMsg.ValidatorDstAddress, zone.AccountPrefix+"valoper")
if err != nil {
return err
}
data = stakingtypes.GetDelegationKey(delAddr, valAddr)

// send request to update delegation record for src del/val tuple.
k.ICQKeeper.MakeRequest(
ctx,
zone.ConnectionId,
zone.ChainId,
"store/staking/key",
data,
sdk.NewInt(-1),
types.ModuleName,
"delegation",
0,
)
return nil
}

Expand Down
18 changes: 14 additions & 4 deletions x/interchainstaking/keeper/redemptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func (k *Keeper) GetUnlockedTokensForZone(ctx sdk.Context, zone *types.Zone) (ma
if found {
availablePerValidator[redelegation.Destination] = thisAvailable.Sub(sdk.NewInt(redelegation.Amount))
if availablePerValidator[redelegation.Destination].LT(sdk.ZeroInt()) {
panic("negative available amount; unable to continue")
panic(fmt.Sprintf("negative available amount [chain: %s, validator: %s, amount: %s]; unable to continue", zone.ChainId, redelegation.Destination, availablePerValidator[redelegation.Destination].String()))
}
total = total.Sub(sdk.NewInt(redelegation.Amount))
}
Expand Down Expand Up @@ -232,15 +232,25 @@ WITHDRAWAL:
var msgs []sdk.Msg
for _, valoper := range utils.Keys(valOutCoinsMap) {
if !valOutCoinsMap[valoper].Amount.IsZero() {
sort.Strings(txHashes[valoper])
k.SetUnbondingRecord(ctx, types.UnbondingRecord{ChainId: zone.ChainId, EpochNumber: epoch, Validator: valoper, RelatedTxhash: txHashes[valoper]})
msgs = append(msgs, &stakingtypes.MsgUndelegate{DelegatorAddress: zone.DelegationAddress.Address, ValidatorAddress: valoper, Amount: valOutCoinsMap[valoper]})
}
}

k.Logger(ctx).Info("unbonding messages to send", "msg", msgs)

return k.SubmitTx(ctx, msgs, zone.DelegationAddress, fmt.Sprintf("withdrawal/%d", epoch), zone.MessagesPerTx)
err = k.SubmitTx(ctx, msgs, zone.DelegationAddress, fmt.Sprintf("withdrawal/%d", epoch), zone.MessagesPerTx)
if err != nil {
return err
}

for _, valoper := range utils.Keys(valOutCoinsMap) {
if !valOutCoinsMap[valoper].Amount.IsZero() {
sort.Strings(txHashes[valoper])
k.SetUnbondingRecord(ctx, types.UnbondingRecord{ChainId: zone.ChainId, EpochNumber: epoch, Validator: valoper, RelatedTxhash: txHashes[valoper]})
}
}

return nil
}

func (k *Keeper) GCCompletedUnbondings(ctx sdk.Context, zone *types.Zone) error {
Expand Down

0 comments on commit 2722a77

Please sign in to comment.