From fdcabf60e075cb30a94cf84c32e20d5edf9e22f4 Mon Sep 17 00:00:00 2001 From: dylanhuang Date: Thu, 4 Jan 2024 13:46:43 +0800 Subject: [PATCH] fix: add logs to sunset fork events and immediate sidechain undelegation (#364) --- x/ibc/endblock.go | 5 ++++- x/stake/cross_stake/cross_stake.go | 16 +++++++++++++--- x/stake/endblock.go | 10 +++++++++- x/stake/handler.go | 6 +++--- x/stake/handler_sidechain.go | 23 +++++++++++++++++++---- x/stake/keeper/delegation.go | 25 +++++++++++++++++++++++-- x/stake/keeper/delegation_test.go | 18 +++++++++--------- x/stake/querier/queryable_test.go | 2 +- 8 files changed, 81 insertions(+), 24 deletions(-) diff --git a/x/ibc/endblock.go b/x/ibc/endblock.go index 11d4d1d5c..549241665 100644 --- a/x/ibc/endblock.go +++ b/x/ibc/endblock.go @@ -63,7 +63,8 @@ func closeChannelOnSideChanAndKeeper(ctx sdk.Context, k Keeper, var events sdk.Events _, err := k.sideKeeper.SaveChannelSettingChangeToIbc(ctx, destChainID, channelID, sdk.ChannelForbidden) if err != nil { - ctx.Logger().Error("failed to save ibc channel change", "err", err.Error()) + ctx.Logger().Error("failed to save ibc channel change after FinalSunsetFork", + "sideChainId", destChainID, "channelId", channelID, "err", err.Error()) events.AppendEvent(sdk.NewEvent(EventTypeSaveIBCChannelSettingFailed, sdk.NewAttribute(AttributeKeySideChainId, fmt.Sprint(destChainID)), sdk.NewAttribute(AttributeKeyChannelId, fmt.Sprint(channelID)), @@ -77,5 +78,7 @@ func closeChannelOnSideChanAndKeeper(ctx sdk.Context, k Keeper, )) // close bc side chain channel k.sideKeeper.SetChannelSendPermission(ctx, destChainID, channelID, sdk.ChannelForbidden) + + ctx.Logger().Info("close side chain channel after FinalSunsetFork", "sideChainId", destChainID, "channelId", channelID) return events } diff --git a/x/stake/cross_stake/cross_stake.go b/x/stake/cross_stake/cross_stake.go index 275f7b8ff..06d4cebfb 100644 --- a/x/stake/cross_stake/cross_stake.go +++ b/x/stake/cross_stake/cross_stake.go @@ -227,9 +227,19 @@ func (app *CrossStakeApp) handleUndelegate(ctx sdk.Context, pack *types.CrossSta }, errCode, nil } - _, err := app.stakeKeeper.BeginUnbonding(ctx.WithCrossStake(true), delAddr, pack.Validator, shares) - if err != nil { - return sdk.ExecuteResult{}, errCode, err + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + // unbound the delegation directly, do not wait for the breathe block + // this is to prevent too many user get the coins back in the breathe block + + _, _, err := app.stakeKeeper.UnboundDelegation(ctx.WithCrossStake(true), delAddr, pack.Validator, shares) + if err != nil { + return sdk.ExecuteResult{}, errCode, err + } + } else { + _, err := app.stakeKeeper.BeginUnbonding(ctx.WithCrossStake(true), delAddr, pack.Validator, shares, true) + if err != nil { + return sdk.ExecuteResult{}, errCode, err + } } // publish undelegate event diff --git a/x/stake/endblock.go b/x/stake/endblock.go index dea407bd7..22611e940 100644 --- a/x/stake/endblock.go +++ b/x/stake/endblock.go @@ -280,20 +280,28 @@ func handleRefundStake(ctx sdk.Context, sideChainPrefix []byte, k keeper.Keeper) var refundEvents sdk.Events count := 0 boundDenom := k.BondDenom(sideChainCtx) + bscSideChainId := k.ScKeeper.BscSideChainId(ctx) for ; iterator.Valid(); iterator.Next() { delegation := types.MustUnmarshalDelegation(k.CDC(), iterator.Key(), iterator.Value()) if delegation.CrossStake { ctx = ctx.WithCrossStake(true) } + result := handleMsgSideChainUndelegate(ctx, types.MsgSideChainUndelegate{ DelegatorAddr: delegation.DelegatorAddr, ValidatorAddr: delegation.ValidatorAddr, Amount: sdk.NewCoin(boundDenom, delegation.GetShares().RawInt()), - SideChainId: k.ScKeeper.BscSideChainId(ctx), + SideChainId: bscSideChainId, }, k) refundEvents = refundEvents.AppendEvents(result.Events) + ctx.Logger().Info("handleRefundStake after SecondSunsetFork", + "delegator", delegation.DelegatorAddr.String(), + "validator", delegation.ValidatorAddr.String(), + "amount", delegation.GetShares().String(), + "sideChainId", bscSideChainId, + ) count++ if count >= maxProcessedRefundCount { break diff --git a/x/stake/handler.go b/x/stake/handler.go index 5f6a9e802..cc9e754a7 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -60,12 +60,12 @@ func NewHandler(k keeper.Keeper, govKeeper gov.Keeper) sdk.Handler { } return handleMsgEditSideChainValidatorWithVoteAddr(ctx, msg, k) case types.MsgSideChainDelegate: - if sdk.IsUpgrade(sdk.SecondSunsetFork) { + if sdk.IsUpgrade(sdk.FirstSunsetFork) { return sdk.ErrMsgNotSupported("").Result() } return handleMsgSideChainDelegate(ctx, msg, k) case types.MsgSideChainRedelegate: - if sdk.IsUpgrade(sdk.SecondSunsetFork) { + if sdk.IsUpgrade(sdk.FirstSunsetFork) { return sdk.ErrMsgNotSupported("").Result() } return handleMsgSideChainRedelegate(ctx, msg, k) @@ -464,7 +464,7 @@ func handleMsgUndelegate(ctx sdk.Context, msg types.MsgUndelegate, k keeper.Keep } func handleMsgBeginUnbonding(ctx sdk.Context, msg types.MsgBeginUnbonding, k keeper.Keeper) sdk.Result { - ubd, err := k.BeginUnbonding(ctx, msg.DelegatorAddr, msg.ValidatorAddr, msg.SharesAmount) + ubd, err := k.BeginUnbonding(ctx, msg.DelegatorAddr, msg.ValidatorAddr, msg.SharesAmount, true) if err != nil { return err.Result() } diff --git a/x/stake/handler_sidechain.go b/x/stake/handler_sidechain.go index a44a91055..2b4582e0f 100644 --- a/x/stake/handler_sidechain.go +++ b/x/stake/handler_sidechain.go @@ -437,9 +437,24 @@ func handleMsgSideChainUndelegate(ctx sdk.Context, msg MsgSideChainUndelegate, k return err.Result() } - ubd, err := k.BeginUnbonding(ctx, msg.DelegatorAddr, msg.ValidatorAddr, shares) - if err != nil { - return err.Result() + var ( + ubd types.UnbondingDelegation + events sdk.Events + ) + + if sdk.IsUpgrade(sdk.FirstSunsetFork) { + // unbound the delegation directly, do not wait for the breathe block + // this is to prevent too many user get the coins back in the breathe block + + ubd, events, err = k.UnboundDelegation(ctx, msg.DelegatorAddr, msg.ValidatorAddr, shares) + if err != nil { + return err.Result() + } + } else { + ubd, err = k.BeginUnbonding(ctx, msg.DelegatorAddr, msg.ValidatorAddr, shares, true) + if err != nil { + return err.Result() + } } finishTime := types.MsgCdc.MustMarshalBinaryLengthPrefixed(ubd.MinTime) @@ -468,7 +483,7 @@ func handleMsgSideChainUndelegate(ctx sdk.Context, msg MsgSideChainUndelegate, k k.PbsbServer.Publish(event) } - return sdk.Result{Data: finishTime, Tags: tags} + return sdk.Result{Data: finishTime, Tags: tags, Events: events} } // we allow the self-delegator delegating/redelegating to its validator. diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 7a377d0a8..a627fac33 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -648,9 +648,25 @@ func (k Keeper) getBeginInfo(ctx sdk.Context, valSrcAddr sdk.ValAddress) ( } } +func (k Keeper) UnboundDelegation(ctx sdk.Context, + delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec, +) (types.UnbondingDelegation, sdk.Events, sdk.Error) { + ubd, err := k.BeginUnbonding(ctx, delAddr, valAddr, sharesAmount, false) + if err != nil { + return ubd, nil, err + } + ubd, events, err := k.CompleteUnbonding(ctx, ubd.DelegatorAddr, ubd.ValidatorAddr) + if err != nil { + return ubd, events, err + } + + return ubd, events, nil +} + // begin unbonding an unbonding record func (k Keeper) BeginUnbonding(ctx sdk.Context, - delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec) (types.UnbondingDelegation, sdk.Error) { + delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec, + enqueue bool) (types.UnbondingDelegation, sdk.Error) { // TODO quick fix, instead we should use an index, see https://github.com/cosmos/cosmos-sdk/issues/1402 _, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr) @@ -667,6 +683,9 @@ func (k Keeper) BeginUnbonding(ctx sdk.Context, balance := sdk.NewCoin(k.BondDenom(ctx), returnAmount.RawInt()) completionTime := ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx)) + if !enqueue { + completionTime = ctx.BlockHeader().Time + } ubd := types.UnbondingDelegation{ DelegatorAddr: delAddr, ValidatorAddr: valAddr, @@ -677,7 +696,9 @@ func (k Keeper) BeginUnbonding(ctx sdk.Context, CrossStake: ctx.CrossStake(), } k.SetUnbondingDelegation(ctx, ubd) - k.InsertUnbondingQueue(ctx, ubd) + if enqueue { + k.InsertUnbondingQueue(ctx, ubd) + } return ubd, nil } diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 6a32c8a3b..687cb07b0 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -283,7 +283,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { keeper.SetDelegation(ctx, delegation) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10)) + _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) // end block @@ -337,7 +337,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { // unbond the all self-delegation to put validator in unbonding state val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10)) + _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) // end block @@ -357,7 +357,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { ctx = ctx.WithBlockTime(blockTime2) // unbond some of the other delegation's shares - _, err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDecWithoutFra(6)) + _, err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDecWithoutFra(6), true) require.NoError(t, err) // retrieve the unbonding delegation @@ -409,7 +409,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { ctx = ctx.WithBlockTime(time.Unix(333, 0)) // unbond the all self-delegation to put validator in unbonding state - _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10)) + _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) // end block @@ -439,7 +439,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { require.Equal(t, 1, len(matureUbds)) // unbond all the other delegation's shares - _, err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDecWithoutFra(10)) + _, err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) @@ -491,7 +491,7 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) { ctx = ctx.WithBlockTime(time.Unix(333, 0)) // unbond the all self-delegation to put validator in unbonding state - _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10)) + _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) // end block @@ -499,7 +499,7 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) { require.Equal(t, 1, len(updates)) // unbond all the remaining delegation - _, err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDecWithoutFra(10)) + _, err = keeper.BeginUnbonding(ctx, addrDels[0], addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) // validator should still be in state and still be in unbonding state @@ -713,7 +713,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { ctx = ctx.WithBlockHeader(header) // unbond the all self-delegation to put validator in unbonding state - _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10)) + _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) // end block @@ -795,7 +795,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { ctx = ctx.WithBlockTime(time.Unix(333, 0)) // unbond the all self-delegation to put validator in unbonding state - _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10)) + _, err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDecWithoutFra(10), true) require.NoError(t, err) // end block diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index cfad6b733..64ebb11da 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -305,7 +305,7 @@ func TestQueryDelegation(t *testing.T) { require.NotNil(t, err) // Query unbonging delegation - keeper.BeginUnbonding(ctx, addrAcc2, val1.OperatorAddr, sdk.NewDec(sdk.NewDecWithoutFra(10).RawInt())) + keeper.BeginUnbonding(ctx, addrAcc2, val1.OperatorAddr, sdk.NewDec(sdk.NewDecWithoutFra(10).RawInt()), true) query = abci.RequestQuery{ Path: "/custom/stake/unbondingDelegation",