Skip to content

Commit

Permalink
Merge pull request #841 from persistenceOne/puneet/force-update
Browse files Browse the repository at this point in the history
feat: add validator force update.
  • Loading branch information
puneet2019 authored May 30, 2024
2 parents 0281264 + d4c40c2 commit aa6da8a
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### Improvements

- [831](https://github.com/persistenceOne/pstake-native/pull/831) Add amino tags for protobuf msgs for compiling in js using telescope
- [841](https://github.com/persistenceOne/pstake-native/pull/841) add type ForceUpdateValidatorDelegations to MsgUpdateHostChain


## [v2.13.0] - 2024-05-01

### Bug Fixes
Expand Down
29 changes: 28 additions & 1 deletion x/liquidstakeibc/keeper/icq.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
const (
Validator = "validator"
Delegation = "validator-delegation"
DelegationUpdate = "validator-delegation-update"
RewardAccountBalances = "reward-balances"
NonCompoundableRewardAccountBalances = "non-compoundable-reward-balances"
DelegationAccountBalances = "delegation-balances"
Expand Down Expand Up @@ -55,7 +56,8 @@ func (c Callbacks) RegisterCallbacks() icqtypes.QueryCallbacks {
AddCallback(RewardAccountBalances, CallbackFn(RewardsAccountBalanceCallback)).
AddCallback(NonCompoundableRewardAccountBalances, CallbackFn(NonCompoundableRewardsAccountBalanceCallback)).
AddCallback(DelegationAccountBalances, CallbackFn(DelegationAccountBalanceCallback)).
AddCallback(Delegation, CallbackFn(DelegationCallback))
AddCallback(Delegation, CallbackFn(DelegationCallback)).
AddCallback(DelegationUpdate, CallbackFn(DelegationUpdateCallback))

return a.(Callbacks)
}
Expand Down Expand Up @@ -240,3 +242,28 @@ func NonCompoundableRewardsAccountBalanceCallback(k Keeper, ctx sdk.Context, dat

return nil
}

func DelegationUpdateCallback(k Keeper, ctx sdk.Context, data []byte, query icqtypes.Query) error {
hc, found := k.GetHostChain(ctx, query.ChainId)
if !found {
return fmt.Errorf("host chain with id %s is not registered", query.ChainId)
}

delegation, err := stakingtypes.UnmarshalDelegation(k.cdc, data)
if err != nil {
return fmt.Errorf("could not unmarshall ICQ delegation response: %w", err)
}

validator, found := hc.GetValidator(delegation.ValidatorAddress)
if !found {
return fmt.Errorf(
"delegation for validator %s for host chain %s not found",
delegation.ValidatorAddress,
query.ChainId,
)
}
validator.DelegatedAmount = delegation.Shares.Mul(validator.ExchangeRate).TruncateInt()

k.SetHostChainValidator(ctx, hc, validator)
return nil
}
31 changes: 31 additions & 0 deletions x/liquidstakeibc/keeper/icq_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,37 @@ func (k *Keeper) QueryValidatorDelegation(
return nil
}

// QueryValidatorDelegationUpdate sends an ICQ query to get a validator delegation
func (k *Keeper) QueryValidatorDelegationUpdate(
ctx sdk.Context,
hc *types.HostChain,
validator *types.Validator,
) error {
_, delegatorAddr, err := bech32.DecodeAndConvert(hc.DelegationAccount.Address)
if err != nil {
return err
}

_, validatorAddr, err := bech32.DecodeAndConvert(validator.OperatorAddress)
if err != nil {
return err
}

k.icqKeeper.MakeRequest(
ctx,
hc.ConnectionId,
hc.ChainId,
types.StakingStoreQuery,
stakingtypes.GetDelegationKey(delegatorAddr, validatorAddr),
sdk.NewInt(int64(-1)),
types.ModuleName,
DelegationUpdate,
0,
)

return nil
}

// QueryDelegationHostChainAccountBalance sends an ICQ query to get the delegation host account balance
func (k *Keeper) QueryDelegationHostChainAccountBalance(
ctx sdk.Context,
Expand Down
42 changes: 42 additions & 0 deletions x/liquidstakeibc/keeper/icq_queries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,45 @@ func (suite *IntegrationTestSuite) TestKeeper_QueryNonCompoundableRewardsHostCha
})
}
}

func (suite *IntegrationTestSuite) TestKeeper_QueryValidatorDelegationUpdate() {
pstakeApp, ctx := suite.app, suite.ctx
k := pstakeApp.LiquidStakeIBCKeeper
hc, found := k.GetHostChain(ctx, suite.chainB.ChainID)
suite.Require().Equal(found, true)

hc2 := types.HostChain{DelegationAccount: &types.ICAAccount{Address: "invalid"}}

type args struct {
hc *types.HostChain
validator *types.Validator
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Success",
args: args{
hc: hc,
validator: hc.Validators[0],
},
wantErr: false,
}, {
name: "Invalid delegator addr",
args: args{
hc: &hc2,
validator: hc.Validators[0],
},
wantErr: true,
},
}
for _, tt := range tests {
suite.Run(tt.name, func() {
if err := k.QueryValidatorDelegationUpdate(ctx, tt.args.hc, tt.args.validator); (err != nil) != tt.wantErr {
suite.T().Errorf("QueryValidatorDelegationUpdate() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
10 changes: 10 additions & 0 deletions x/liquidstakeibc/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,16 @@ func (k msgServer) UpdateHostChain(

hc.RewardParams = &params
k.SetHostChain(ctx, hc)
case types.KeyForceUpdateValidator:
val, found := hc.GetValidator(update.Value)
if !found {
return nil, types.ErrValidatorNotFound
}

if err := k.QueryValidatorDelegationUpdate(ctx, hc, val); err != nil {
return nil, fmt.Errorf("unable to send ICQ query for validator delegation update")
}

default:
return nil, fmt.Errorf("invalid or unexpected update key: %s", update.Key)
}
Expand Down
26 changes: 17 additions & 9 deletions x/liquidstakeibc/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package keeper_test
import (
"context"
"fmt"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"reflect"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
ibctfrtypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"
transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types"

Expand Down Expand Up @@ -166,7 +166,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: &types.MsgLiquidStakeLSMResponse{},
wantErr: false,
}, {
},
{
name: "Invalid IBC denom",
args: args{
goCtx: ctx,
Expand All @@ -180,7 +181,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: nil,
wantErr: true,
}, {
},
{
name: "Invalid IBC hex hash",
args: args{
goCtx: ctx,
Expand All @@ -194,7 +196,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: nil,
wantErr: true,
}, {
},
{
name: "No IBC denom trace",
args: args{
goCtx: ctx,
Expand All @@ -208,7 +211,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: nil,
wantErr: true,
}, {
},
{
name: "Host chain not active",
args: args{
goCtx: ctx,
Expand All @@ -222,7 +226,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: nil,
wantErr: true,
}, {
},
{
name: "Host chain LSM flag not active",
args: args{
goCtx: ctx,
Expand All @@ -236,7 +241,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: nil,
wantErr: true,
}, {
},
{
name: "Not enough balance",
args: args{
goCtx: ctx,
Expand All @@ -250,7 +256,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: nil,
wantErr: true,
}, {
},
{
name: "Deposit already exists",
args: args{
goCtx: ctx,
Expand All @@ -264,7 +271,8 @@ func (suite *IntegrationTestSuite) Test_msgServer_LiquidStakeLSM() {
},
want: nil,
wantErr: true,
}, {
},
{
name: "Less than min amount",
args: args{
goCtx: ctx,
Expand Down
1 change: 1 addition & 0 deletions x/liquidstakeibc/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const (
KeyAutocompoundFactor string = "autocompound_factor"
KeyFlags string = "flags"
KeyRewardParams string = "reward_params"
KeyForceUpdateValidator string = "force_update_validator"
)

var (
Expand Down
5 changes: 5 additions & 0 deletions x/liquidstakeibc/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,11 @@ func (m *MsgUpdateHostChain) ValidateBasic() error {
if err := sdk.ValidateDenom(params.Denom); err != nil {
return fmt.Errorf("invalid rewards denom: %s", err.Error())
}
case KeyForceUpdateValidator:
_, _, err := bech32.DecodeAndConvert(update.Value)
if err != nil {
return err
}
default:
return fmt.Errorf("invalid or unexpected update key: %s", update.Key)
}
Expand Down

0 comments on commit aa6da8a

Please sign in to comment.