From 90e38337a403a2d6faeec46204564fef7199ed9a Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 31 Jan 2020 10:27:36 -0500 Subject: [PATCH 1/6] Track and emit total unbonding amount event --- x/staking/keeper/delegation.go | 23 +++++++++++++++++------ x/staking/keeper/val_state_change.go | 3 ++- x/staking/spec/07_events.md | 25 +++++++++++++------------ 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index faf8ba415ef7..b5168c3327eb 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -660,14 +660,16 @@ func (k Keeper) Undelegate( return completionTime, nil } -// CompleteUnbonding completes the unbonding of all mature entries in the -// retrieved unbonding delegation object. -func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { +// CompleteUnbondingWithAmount completes the unbonding of all mature entries in +// the retrieved unbonding delegation object and returns the total unbonding +// balance or an error upon failure. +func (k Keeper) CompleteUnbondingWithAmount(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) { ubd, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr) if !found { - return types.ErrNoUnbondingDelegation + return nil, types.ErrNoUnbondingDelegation } + balances := sdk.NewCoins() ctxTime := ctx.BlockHeader().Time // loop through all the entries and complete unbonding mature entries @@ -682,8 +684,10 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd amt := sdk.NewCoins(sdk.NewCoin(k.GetParams(ctx).BondDenom, entry.Balance)) err := k.supplyKeeper.UndelegateCoinsFromModuleToAccount(ctx, types.NotBondedPoolName, ubd.DelegatorAddress, amt) if err != nil { - return err + return nil, err } + + balances = balances.Add(amt...) } } } @@ -695,7 +699,14 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd k.SetUnbondingDelegation(ctx, ubd) } - return nil + return balances, nil +} + +// CompleteUnbonding performs the same logic as CompleteUnbondingWithAmount except +// it does not return the total unbonding amount. +func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error { + _, err := k.CompleteUnbondingWithAmount(ctx, delAddr, valAddr) + return err } // begin unbonding / redelegation; create a redelegation record diff --git a/x/staking/keeper/val_state_change.go b/x/staking/keeper/val_state_change.go index ed630f15ce22..33737ad5a215 100644 --- a/x/staking/keeper/val_state_change.go +++ b/x/staking/keeper/val_state_change.go @@ -31,7 +31,7 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate { // Remove all mature unbonding delegations from the ubd queue. matureUnbonds := k.DequeueAllMatureUBDQueue(ctx, ctx.BlockHeader().Time) for _, dvPair := range matureUnbonds { - err := k.CompleteUnbonding(ctx, dvPair.DelegatorAddress, dvPair.ValidatorAddress) + balances, err := k.CompleteUnbondingWithAmount(ctx, dvPair.DelegatorAddress, dvPair.ValidatorAddress) if err != nil { continue } @@ -39,6 +39,7 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate { ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeCompleteUnbonding, + sdk.NewAttribute(sdk.AttributeKeyAmount, balances.String()), sdk.NewAttribute(types.AttributeKeyValidator, dvPair.ValidatorAddress.String()), sdk.NewAttribute(types.AttributeKeyDelegator, dvPair.DelegatorAddress.String()), ), diff --git a/x/staking/spec/07_events.md b/x/staking/spec/07_events.md index e16cf009570d..1c6076a57f6c 100644 --- a/x/staking/spec/07_events.md +++ b/x/staking/spec/07_events.md @@ -8,20 +8,21 @@ The staking module emits the following events: ## EndBlocker -| Type | Attribute Key | Attribute Value | -|-----------------------|-----------------------|-----------------------| -| complete_unbonding | validator | {validatorAddress} | -| complete_unbonding | delegator | {delegatorAddress} | -| complete_redelegation | source_validator | {srcValidatorAddress} | -| complete_redelegation | destination_validator | {dstValidatorAddress} | -| complete_redelegation | delegator | {delegatorAddress} | +| Type | Attribute Key | Attribute Value | +| --------------------- | --------------------- | ---------------------- | +| complete_unbonding | amount | {totalUnbondingAmount} | +| complete_unbonding | validator | {validatorAddress} | +| complete_unbonding | delegator | {delegatorAddress} | +| complete_redelegation | source_validator | {srcValidatorAddress} | +| complete_redelegation | destination_validator | {dstValidatorAddress} | +| complete_redelegation | delegator | {delegatorAddress} | ## Handlers ### MsgCreateValidator | Type | Attribute Key | Attribute Value | -|------------------|---------------|--------------------| +| ---------------- | ------------- | ------------------ | | create_validator | validator | {validatorAddress} | | create_validator | amount | {delegationAmount} | | message | module | staking | @@ -31,7 +32,7 @@ The staking module emits the following events: ### MsgEditValidator | Type | Attribute Key | Attribute Value | -|----------------|---------------------|---------------------| +| -------------- | ------------------- | ------------------- | | edit_validator | commission_rate | {commissionRate} | | edit_validator | min_self_delegation | {minSelfDelegation} | | message | module | staking | @@ -41,7 +42,7 @@ The staking module emits the following events: ### MsgDelegate | Type | Attribute Key | Attribute Value | -|----------|---------------|--------------------| +| -------- | ------------- | ------------------ | | delegate | validator | {validatorAddress} | | delegate | amount | {delegationAmount} | | message | module | staking | @@ -51,7 +52,7 @@ The staking module emits the following events: ### MsgUndelegate | Type | Attribute Key | Attribute Value | -|---------|---------------------|--------------------| +| ------- | ------------------- | ------------------ | | unbond | validator | {validatorAddress} | | unbond | amount | {unbondAmount} | | unbond | completion_time [0] | {completionTime} | @@ -64,7 +65,7 @@ The staking module emits the following events: ### MsgBeginRedelegate | Type | Attribute Key | Attribute Value | -|------------|-----------------------|-----------------------| +| ---------- | --------------------- | --------------------- | | redelegate | source_validator | {srcValidatorAddress} | | redelegate | destination_validator | {dstValidatorAddress} | | redelegate | amount | {unbondAmount} | From e3c1100797e94c3ff05b3bb7a955ede7afb23a6c Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 31 Jan 2020 10:43:09 -0500 Subject: [PATCH 2/6] Emit event on redelegation completion --- x/staking/keeper/delegation.go | 29 ++++++++++++++++++++++------ x/staking/keeper/val_state_change.go | 9 +++++++-- x/staking/spec/07_events.md | 17 ++++++++-------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index b5168c3327eb..a9a99eab1e38 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -766,17 +766,19 @@ func (k Keeper) BeginRedelegation( return completionTime, nil } -// CompleteRedelegation completes the unbonding of all mature entries in the -// retrieved unbonding delegation object. -func (k Keeper) CompleteRedelegation( +// CompleteRedelegation completes the redelegations of all mature entries in the +// retrieved redelegation object and returns the total redelegation (initial) +// balance or an error upon failure. +func (k Keeper) CompleteRedelegationWithAmount( ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, -) error { +) (sdk.Coins, error) { red, found := k.GetRedelegation(ctx, delAddr, valSrcAddr, valDstAddr) if !found { - return types.ErrNoRedelegation + return nil, types.ErrNoRedelegation } + balances := sdk.NewCoins() ctxTime := ctx.BlockHeader().Time // loop through all the entries and complete mature redelegation entries @@ -785,6 +787,11 @@ func (k Keeper) CompleteRedelegation( if entry.IsMature(ctxTime) { red.RemoveEntry(int64(i)) i-- + + if !entry.InitialBalance.IsZero() { + amt := sdk.NewCoins(sdk.NewCoin(k.GetParams(ctx).BondDenom, entry.InitialBalance)) + balances = balances.Add(amt...) + } } } @@ -795,7 +802,17 @@ func (k Keeper) CompleteRedelegation( k.SetRedelegation(ctx, red) } - return nil + return balances, nil +} + +// CompleteRedelegation performs the same logic as CompleteRedelegationWithAmount +// except it does not return the +func (k Keeper) CompleteRedelegation( + ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, +) error { + + _, err := k.CompleteRedelegationWithAmount(ctx, delAddr, valSrcAddr, valDstAddr) + return err } // ValidateUnbondAmount validates that a given unbond or redelegation amount is diff --git a/x/staking/keeper/val_state_change.go b/x/staking/keeper/val_state_change.go index 33737ad5a215..101bc139215a 100644 --- a/x/staking/keeper/val_state_change.go +++ b/x/staking/keeper/val_state_change.go @@ -49,8 +49,12 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate { // Remove all mature redelegations from the red queue. matureRedelegations := k.DequeueAllMatureRedelegationQueue(ctx, ctx.BlockHeader().Time) for _, dvvTriplet := range matureRedelegations { - err := k.CompleteRedelegation(ctx, dvvTriplet.DelegatorAddress, - dvvTriplet.ValidatorSrcAddress, dvvTriplet.ValidatorDstAddress) + balances, err := k.CompleteRedelegationWithAmount( + ctx, + dvvTriplet.DelegatorAddress, + dvvTriplet.ValidatorSrcAddress, + dvvTriplet.ValidatorDstAddress, + ) if err != nil { continue } @@ -58,6 +62,7 @@ func (k Keeper) BlockValidatorUpdates(ctx sdk.Context) []abci.ValidatorUpdate { ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeCompleteRedelegation, + sdk.NewAttribute(sdk.AttributeKeyAmount, balances.String()), sdk.NewAttribute(types.AttributeKeyDelegator, dvvTriplet.DelegatorAddress.String()), sdk.NewAttribute(types.AttributeKeySrcValidator, dvvTriplet.ValidatorSrcAddress.String()), sdk.NewAttribute(types.AttributeKeyDstValidator, dvvTriplet.ValidatorDstAddress.String()), diff --git a/x/staking/spec/07_events.md b/x/staking/spec/07_events.md index 1c6076a57f6c..fe716baf9180 100644 --- a/x/staking/spec/07_events.md +++ b/x/staking/spec/07_events.md @@ -8,14 +8,15 @@ The staking module emits the following events: ## EndBlocker -| Type | Attribute Key | Attribute Value | -| --------------------- | --------------------- | ---------------------- | -| complete_unbonding | amount | {totalUnbondingAmount} | -| complete_unbonding | validator | {validatorAddress} | -| complete_unbonding | delegator | {delegatorAddress} | -| complete_redelegation | source_validator | {srcValidatorAddress} | -| complete_redelegation | destination_validator | {dstValidatorAddress} | -| complete_redelegation | delegator | {delegatorAddress} | +| Type | Attribute Key | Attribute Value | +| --------------------- | --------------------- | ------------------------- | +| complete_unbonding | amount | {totalUnbondingAmount} | +| complete_unbonding | validator | {validatorAddress} | +| complete_unbonding | delegator | {delegatorAddress} | +| complete_redelegation | amount | {totalRedelegationAmount} | +| complete_redelegation | source_validator | {srcValidatorAddress} | +| complete_redelegation | destination_validator | {dstValidatorAddress} | +| complete_redelegation | delegator | {delegatorAddress} | ## Handlers From e1c8c3182e3a2683d68c0e4b933ab43d639981dd Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 31 Jan 2020 10:46:41 -0500 Subject: [PATCH 3/6] Linting --- x/staking/keeper/delegation.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index a9a99eab1e38..8f5a09d373eb 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -669,6 +669,7 @@ func (k Keeper) CompleteUnbondingWithAmount(ctx sdk.Context, delAddr sdk.AccAddr return nil, types.ErrNoUnbondingDelegation } + bondDenom := k.GetParams(ctx).BondDenom balances := sdk.NewCoins() ctxTime := ctx.BlockHeader().Time @@ -681,13 +682,15 @@ func (k Keeper) CompleteUnbondingWithAmount(ctx sdk.Context, delAddr sdk.AccAddr // track undelegation only when remaining or truncated shares are non-zero if !entry.Balance.IsZero() { - amt := sdk.NewCoins(sdk.NewCoin(k.GetParams(ctx).BondDenom, entry.Balance)) - err := k.supplyKeeper.UndelegateCoinsFromModuleToAccount(ctx, types.NotBondedPoolName, ubd.DelegatorAddress, amt) + amt := sdk.NewCoin(bondDenom, entry.Balance) + err := k.supplyKeeper.UndelegateCoinsFromModuleToAccount( + ctx, types.NotBondedPoolName, ubd.DelegatorAddress, sdk.NewCoins(amt), + ) if err != nil { return nil, err } - balances = balances.Add(amt...) + balances = balances.Add(amt) } } } @@ -778,6 +781,7 @@ func (k Keeper) CompleteRedelegationWithAmount( return nil, types.ErrNoRedelegation } + bondDenom := k.GetParams(ctx).BondDenom balances := sdk.NewCoins() ctxTime := ctx.BlockHeader().Time @@ -789,8 +793,8 @@ func (k Keeper) CompleteRedelegationWithAmount( i-- if !entry.InitialBalance.IsZero() { - amt := sdk.NewCoins(sdk.NewCoin(k.GetParams(ctx).BondDenom, entry.InitialBalance)) - balances = balances.Add(amt...) + amt := sdk.NewCoin(bondDenom, entry.InitialBalance) + balances = balances.Add(amt) } } } From 01d81ec2b8dac1f26e2e7f9aa6cc9c6e4fc569de Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 31 Jan 2020 10:47:21 -0500 Subject: [PATCH 4/6] Linting --- x/staking/keeper/delegation.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 8f5a09d373eb..2dc2ee50c004 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -793,8 +793,7 @@ func (k Keeper) CompleteRedelegationWithAmount( i-- if !entry.InitialBalance.IsZero() { - amt := sdk.NewCoin(bondDenom, entry.InitialBalance) - balances = balances.Add(amt) + balances = balances.Add(sdk.NewCoin(bondDenom, entry.InitialBalance)) } } } From 6ee6eadd68ca0293fee33428d61043f0071f6c38 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Fri, 31 Jan 2020 10:49:44 -0500 Subject: [PATCH 5/6] Add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1764c8d33313..fc45a176b45d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,9 @@ balances or a single balance by denom when the `denom` query parameter is presen ### Improvements +* (modules) [\#5597](https://github.com/cosmos/cosmos-sdk/pull/5597) Add `amount` event attribute to the `complete_unbonding` +and `complete_redelegation` events that reflect the total balances of the completed unbondings and redelegations +respectively. * (types) [\#5581](https://github.com/cosmos/cosmos-sdk/pull/5581) Add convenience functions {,Must}Bech32ifyAddressBytes. * (staking) [\#5584](https://github.com/cosmos/cosmos-sdk/pull/5584) Add util function `ToTmValidator` that converts a `staking.Validator` type to `*tmtypes.Validator`. * (client) [\#5585](https://github.com/cosmos/cosmos-sdk/pull/5585) IBC additions: From 0bc66c108e4390b3ca13ff525478038d9d1c2b25 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Fri, 31 Jan 2020 16:59:59 +0100 Subject: [PATCH 6/6] Apply suggestions from code review --- x/staking/keeper/delegation.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 2dc2ee50c004..219beef71271 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -769,7 +769,7 @@ func (k Keeper) BeginRedelegation( return completionTime, nil } -// CompleteRedelegation completes the redelegations of all mature entries in the +// CompleteRedelegationWithAmount completes the redelegations of all mature entries in the // retrieved redelegation object and returns the total redelegation (initial) // balance or an error upon failure. func (k Keeper) CompleteRedelegationWithAmount( @@ -809,7 +809,7 @@ func (k Keeper) CompleteRedelegationWithAmount( } // CompleteRedelegation performs the same logic as CompleteRedelegationWithAmount -// except it does not return the +// except it does not return the total redelegation amount. func (k Keeper) CompleteRedelegation( ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, ) error {