From dd870957d123ed360e16b4b235834b93cec51977 Mon Sep 17 00:00:00 2001 From: puneetmahajan Date: Sat, 7 Dec 2024 08:47:05 +0400 Subject: [PATCH] add code to force unbond and withdraw --- x/liquidstakeibc/keeper/abci.go | 10 +++--- x/liquidstakeibc/keeper/icq.go | 5 +-- x/liquidstakeibc/keeper/keeper.go | 4 ++- x/liquidstakeibc/keeper/msg_server.go | 44 +++++++++++++++++++++++++++ x/liquidstakeibc/types/keys.go | 3 ++ x/liquidstakeibc/types/msgs.go | 26 ++++++++++++++++ 6 files changed, 83 insertions(+), 9 deletions(-) diff --git a/x/liquidstakeibc/keeper/abci.go b/x/liquidstakeibc/keeper/abci.go index f497cb64..c4d333f9 100644 --- a/x/liquidstakeibc/keeper/abci.go +++ b/x/liquidstakeibc/keeper/abci.go @@ -18,17 +18,15 @@ import ( func (k *Keeper) BeginBlock(ctx sdk.Context) { // perform BeginBlocker tasks for each chain for _, hc := range k.GetAllHostChains(ctx) { - if !hc.Active { - // don't do anything on inactive chains - continue + if hc.Active { + // attempt to delegate + k.DoDelegate(ctx, hc) + } // attempt to recreate closed ICA channels k.DoRecreateICA(ctx, hc) - // attempt to delegate - k.DoDelegate(ctx, hc) - // attempt to automatically claim matured undelegations k.DoClaim(ctx, hc) diff --git a/x/liquidstakeibc/keeper/icq.go b/x/liquidstakeibc/keeper/icq.go index 5bb8759a..f9b5e2d0 100644 --- a/x/liquidstakeibc/keeper/icq.go +++ b/x/liquidstakeibc/keeper/icq.go @@ -114,8 +114,9 @@ func DelegationCallback(k Keeper, ctx sdk.Context, data []byte, query icqtypes.Q k.SetHostChainValidator(ctx, hc, validator) // update the c value for the slashed chain - k.UpdateCValue(ctx, hc) - + if hc.Active { + k.UpdateCValue(ctx, hc) + } ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeSlashing, diff --git a/x/liquidstakeibc/keeper/keeper.go b/x/liquidstakeibc/keeper/keeper.go index dfdac7bf..de4d5796 100644 --- a/x/liquidstakeibc/keeper/keeper.go +++ b/x/liquidstakeibc/keeper/keeper.go @@ -255,7 +255,9 @@ func (k *Keeper) UpdateCValues(ctx sdk.Context) { hostChains := k.GetAllHostChains(ctx) for _, hc := range hostChains { - k.UpdateCValue(ctx, hc) + if hc.Active { + k.UpdateCValue(ctx, hc) + } } } diff --git a/x/liquidstakeibc/keeper/msg_server.go b/x/liquidstakeibc/keeper/msg_server.go index 3467c5f7..3019efe7 100644 --- a/x/liquidstakeibc/keeper/msg_server.go +++ b/x/liquidstakeibc/keeper/msg_server.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/cosmos/gogoproto/proto" "strconv" "strings" @@ -331,7 +332,50 @@ func (k msgServer) UpdateHostChain( if err := k.QueryValidatorDelegationUpdate(ctx, hc, val); err != nil { return nil, fmt.Errorf("unable to send ICQ query for validator delegation update") } + case types.KeyForceUnbond: + if hc.Active { + return nil, fmt.Errorf("cannot force unbond to active host chain") + } + validator, coin, valid := strings.Cut(update.Value, ",") + if !valid { + return nil, fmt.Errorf("invalid force unbond value, expected form \"cosmovaloperxx,123denom\" ") + } + val, found := hc.GetValidator(validator) + if !found { + return nil, types.ErrValidatorNotFound + } + amount, err := sdktypes.ParseCoinNormalized(coin) + if err != nil { + return nil, err + } + msgUnbond := &stakingtypes.MsgUndelegate{ + DelegatorAddress: hc.DelegationAccount.Address, + ValidatorAddress: val.OperatorAddress, + Amount: amount, + } + _, err = k.GenerateAndExecuteICATx(ctx, hc.ConnectionId, hc.DelegationAccount.Owner, []proto.Message{msgUnbond}) + if err != nil { + return nil, err + } + case types.KeyForceICATransfer: + amount, err := sdktypes.ParseCoinNormalized(update.Value) + if err != nil { + return nil, err + } + _, err = k.SendICATransfer(ctx, hc, amount, hc.DelegationAccount.Address, k.GetUndelegationModuleAccount(ctx).GetAddress().String(), hc.DelegationAccount.Owner) + if err != nil { + return nil, err + } + case types.KeyForceICATransferRewards: + amount, err := sdktypes.ParseCoinNormalized(update.Value) + if err != nil { + return nil, err + } + _, err = k.SendICATransfer(ctx, hc, amount, hc.RewardsAccount.Address, k.GetUndelegationModuleAccount(ctx).GetAddress().String(), hc.RewardsAccount.Owner) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("invalid or unexpected update key: %s", update.Key) } diff --git a/x/liquidstakeibc/types/keys.go b/x/liquidstakeibc/types/keys.go index a7f730e9..d1dde07a 100644 --- a/x/liquidstakeibc/types/keys.go +++ b/x/liquidstakeibc/types/keys.go @@ -87,6 +87,9 @@ const ( KeyFlags string = "flags" KeyRewardParams string = "reward_params" KeyForceUpdateValidator string = "force_update_validator" + KeyForceUnbond string = "force_unbond" + KeyForceICATransfer string = "force_ica_transfer" + KeyForceICATransferRewards string = "force_ica_transfer_rewards" ) var ( diff --git a/x/liquidstakeibc/types/msgs.go b/x/liquidstakeibc/types/msgs.go index 810ba984..a4dd4582 100644 --- a/x/liquidstakeibc/types/msgs.go +++ b/x/liquidstakeibc/types/msgs.go @@ -396,6 +396,32 @@ func (m *MsgUpdateHostChain) ValidateBasic() error { if err != nil { return err } + case KeyForceUnbond: + // expected "chainvaloper1xxx,1234denom" + validator, coin, valid := strings.Cut(update.Value, ",") + if !valid { + return fmt.Errorf("invalid force unbond value, expected form \"cosmovaloperxx,123denom\" ") + } + _, _, err := bech32.DecodeAndConvert(validator) + if err != nil { + return err + } + _, err = sdk.ParseCoinNormalized(coin) + if err != nil { + return err + } + case KeyForceICATransfer: + // expected "1234denom" + _, err := sdk.ParseCoinNormalized(update.Value) + if err != nil { + return err + } + case KeyForceICATransferRewards: + // expected "1234denom" + _, err := sdk.ParseCoinNormalized(update.Value) + if err != nil { + return err + } default: return fmt.Errorf("invalid or unexpected update key: %s", update.Key) }