Skip to content

Commit

Permalink
fix: return undelegate amount with MsgUndelegateResponse (#14590)
Browse files Browse the repository at this point in the history
Closes #14153
  • Loading branch information
0xmuralik authored Jan 23, 2023
1 parent 4f6f6c0 commit e3b37dc
Show file tree
Hide file tree
Showing 13 changed files with 418 additions and 240 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (store) [#14439](https://github.com/cosmos/cosmos-sdk/pull/14439) Remove global metric gatherer from store.
* By default store has a no op metric gatherer, the application developer must set another metric gatherer or us the provided one in `store/metrics`.
* [#14406](https://github.com/cosmos/cosmos-sdk/issues/14406) Migrate usage of types/store.go to store/types/..
* (x/staking) [#14590](https://github.com/cosmos/cosmos-sdk/pull/14590) Return undelegate amount in MsgUndelegateResponse

### State Machine Breaking

Expand All @@ -161,6 +162,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/group) [#13876](https://github.com/cosmos/cosmos-sdk/pull/13876) Fix group MinExecutionPeriod that is checked on execution now, instead of voting period end.
* (x/feegrant) [#14294](https://github.com/cosmos/cosmos-sdk/pull/14294) Moved the logic of rejecting duplicate grant from `msg_server` to `keeper` method.
* (store) [#14378](https://github.com/cosmos/cosmos-sdk/pull/14378) The `CacheKV` store is thread-safe again, which includes improved iteration and deletion logic. Iteration is on a strictly isolated view now, which is breaking from previous behavior.
* (x/staking) [#14590](https://github.com/cosmos/cosmos-sdk/pull/14590) `MsgUndelegateResponse` now includes undelegated amount. `x/staking` module's `keeper.Undelegate` now returns 3 values (completionTime,undelegateAmount,error) instead of 2.

### API Breaking Changes

Expand Down Expand Up @@ -226,6 +228,7 @@ extension interfaces. `module.Manager.Modules` is now of type `map[string]interf
* (snapshots) [14048](https://github.com/cosmos/cosmos-sdk/pull/14048) Move the Snapshot package to the store package. This is done in an effort group all storage related logic under one package.
* (baseapp) [#14050](https://github.com/cosmos/cosmos-sdk/pull/14050) refactor `ABCIListener` interface to accept go contexts
* (store/streaming)[#14603](https://github.com/cosmos/cosmos-sdk/pull/14603) `StoreDecoderRegistry` moved from store to `types/simulations` this breaks the `AppModuleSimulation` interface.
* (x/staking) [#14590](https://github.com/cosmos/cosmos-sdk/pull/14590) `MsgUndelegateResponse` now includes undelegated amount. `x/staking` module's `keeper.Undelegate` now returns 3 values (completionTime,undelegateAmount,error) instead of 2.

### Client Breaking Changes

Expand Down
351 changes: 223 additions & 128 deletions api/cosmos/staking/v1beta1/tx.pulsar.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions proto/cosmos/staking/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ message MsgUndelegate {
message MsgUndelegateResponse {
google.protobuf.Timestamp completion_time = 1
[(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdtime) = true];

// amount returns the amount of undelegated coins
//
// Since: cosmos-sdk 0.48
cosmos.base.v1beta1.Coin amount = 2 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true];
}

// MsgCancelUnbondingDelegation defines the SDK message for performing a cancel unbonding delegation for delegator
Expand Down
11 changes: 8 additions & 3 deletions tests/integration/staking/keeper/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,28 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {

// should all pass
var completionTime time.Time
totalUnbonded := math.NewInt(0)
for i := int64(0); i < int64(maxEntries); i++ {
var err error
ctx = ctx.WithBlockHeight(i)
completionTime, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
var amount math.Int
completionTime, amount, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
totalUnbonded = totalUnbonded.Add(amount)
assert.NilError(t, err)
}

newBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
newNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
assert.Assert(math.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries))))
assert.Assert(math.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries))))
assert.Assert(math.IntEq(t, totalUnbonded, oldBonded.Sub(newBonded)))
assert.Assert(math.IntEq(t, totalUnbonded, newNotBonded.Sub(oldNotBonded)))

oldBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount

// an additional unbond should fail due to max entries
_, err := app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
_, _, err := app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
assert.Error(t, err, "too many unbonding delegation entries for (delegator, validator) tuple")

newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
Expand All @@ -87,7 +92,7 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) {
oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount

// unbonding should work again
_, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
_, _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], math.LegacyNewDec(1))
assert.NilError(t, err)

newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
Expand Down
14 changes: 7 additions & 7 deletions tests/integration/staking/keeper/determinstic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ func TestGRPCValidatorUnbondingDelegations(t *testing.T) {
shares, err := createDelegationAndDelegate(rt, f, t, delegator, validator)
assert.NilError(t, err)

_, err = f.stakingKeeper.Undelegate(f.ctx, delegator, validator.GetOperator(), shares)
_, _, err = f.stakingKeeper.Undelegate(f.ctx, delegator, validator.GetOperator(), shares)
assert.NilError(t, err)
}

Expand All @@ -356,13 +356,13 @@ func TestGRPCValidatorUnbondingDelegations(t *testing.T) {
shares1, err := fundAccountAndDelegate(f, t, delegatorAddr1, validator, f.amt1)
assert.NilError(t, err)

_, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr1, validatorAddr1, shares1)
_, _, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr1, validatorAddr1, shares1)
assert.NilError(t, err)

shares2, err := fundAccountAndDelegate(f, t, delegatorAddr2, validator, f.amt2)
assert.NilError(t, err)

_, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr2, validatorAddr1, shares2)
_, _, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr2, validatorAddr1, shares2)
assert.NilError(t, err)

req := &stakingtypes.QueryValidatorUnbondingDelegationsRequest{
Expand Down Expand Up @@ -414,7 +414,7 @@ func TestGRPCUnbondingDelegation(t *testing.T) {
shares, err := createDelegationAndDelegate(rt, f, t, delegator, validator)
assert.NilError(t, err)

_, err = f.stakingKeeper.Undelegate(f.ctx, delegator, validator.GetOperator(), shares)
_, _, err = f.stakingKeeper.Undelegate(f.ctx, delegator, validator.GetOperator(), shares)
assert.NilError(t, err)

req := &stakingtypes.QueryUnbondingDelegationRequest{
Expand All @@ -431,7 +431,7 @@ func TestGRPCUnbondingDelegation(t *testing.T) {
shares1, err := fundAccountAndDelegate(f, t, delegatorAddr1, validator, f.amt1)
assert.NilError(t, err)

_, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr1, validatorAddr1, shares1)
_, _, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr1, validatorAddr1, shares1)
assert.NilError(t, err)

req := &stakingtypes.QueryUnbondingDelegationRequest{
Expand Down Expand Up @@ -524,7 +524,7 @@ func TestGRPCDelegatorUnbondingDelegations(t *testing.T) {
shares, err := createDelegationAndDelegate(rt, f, t, delegator, validator)
assert.NilError(t, err)

_, err = f.stakingKeeper.Undelegate(f.ctx, delegator, validator.GetOperator(), shares)
_, _, err = f.stakingKeeper.Undelegate(f.ctx, delegator, validator.GetOperator(), shares)
assert.NilError(t, err)
}

Expand All @@ -542,7 +542,7 @@ func TestGRPCDelegatorUnbondingDelegations(t *testing.T) {
shares1, err := fundAccountAndDelegate(f, t, delegatorAddr1, validator, f.amt1)
assert.NilError(t, err)

_, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr1, validatorAddr1, shares1)
_, _, err = f.stakingKeeper.Undelegate(f.ctx, delegatorAddr1, validatorAddr1, shares1)
assert.NilError(t, err)

req := &stakingtypes.QueryDelegatorUnbondingDelegationsRequest{
Expand Down
8 changes: 4 additions & 4 deletions tests/integration/staking/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ func TestGRPCQueryUnbondingDelegation(t *testing.T) {
unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
valAddr, err1 := sdk.ValAddressFromBech32(addrVal2)
assert.NilError(t, err1)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, valAddr, sdk.NewDecFromInt(unbondingTokens))
_, _, err := app.StakingKeeper.Undelegate(ctx, addrAcc2, valAddr, sdk.NewDecFromInt(unbondingTokens))
assert.NilError(t, err)

unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, valAddr)
Expand Down Expand Up @@ -496,11 +496,11 @@ func TestGRPCQueryDelegatorUnbondingDelegations(t *testing.T) {
unbondingTokens := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
valAddr1, err1 := sdk.ValAddressFromBech32(addrVal)
assert.NilError(t, err1)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr1, sdk.NewDecFromInt(unbondingTokens))
_, _, err := app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr1, sdk.NewDecFromInt(unbondingTokens))
assert.NilError(t, err)
valAddr2, err1 := sdk.ValAddressFromBech32(addrVal2)
assert.NilError(t, err1)
_, err = app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr2, sdk.NewDecFromInt(unbondingTokens))
_, _, err = app.StakingKeeper.Undelegate(ctx, addrAcc, valAddr2, sdk.NewDecFromInt(unbondingTokens))
assert.NilError(t, err)

unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc, valAddr1)
Expand Down Expand Up @@ -775,7 +775,7 @@ func TestGRPCQueryValidatorUnbondingDelegations(t *testing.T) {

// undelegate
undelAmount := app.StakingKeeper.TokensFromConsensusPower(ctx, 2)
_, err := app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), sdk.NewDecFromInt(undelAmount))
_, _, err := app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), sdk.NewDecFromInt(undelAmount))
assert.NilError(t, err)
applyValidatorSetUpdates(t, ctx, app.StakingKeeper, -1)

Expand Down
5 changes: 3 additions & 2 deletions tests/integration/staking/keeper/unbonding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ func doUnbondingDelegation(
notBondedAmt1 := bankKeeper.GetBalance(ctx, stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount

var err error
completionTime, err = stakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1))
undelegateAmount := sdk.NewDec(1)
completionTime, undelegatedAmount, err := stakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], undelegateAmount)
assert.NilError(t, err)

assert.Assert(t, undelegateAmount.Equal(math.LegacyNewDecFromInt(undelegatedAmount)))
// check that the unbonding actually happened
bondedAmt2 := bankKeeper.GetBalance(ctx, stakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount
notBondedAmt2 := bankKeeper.GetBalance(ctx, stakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/staking/keeper/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func bootstrapValidatorTest(t testing.TB, power int64, numAddrs int) (*simapp.Si
assert.Assert(t, len(delegations) == 1)
delegation := delegations[0]

_, err := app.StakingKeeper.Undelegate(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr(), delegation.Shares)
_, _, err := app.StakingKeeper.Undelegate(ctx, delegation.GetDelegatorAddr(), delegation.GetValidatorAddr(), delegation.Shares)
assert.NilError(t, err)

// end block to unbond genesis validator
Expand Down
2 changes: 1 addition & 1 deletion x/auth/migrations/v2/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ func TestMigrateVestingAccounts(t *testing.T) {
require.NoError(t, err)

// un-delegation of the original vesting
_, err = stakingKeeper.Undelegate(ctx, delegatorAddr, valAddr, sdk.NewDecFromInt(sdk.NewInt(300)))
_, _, err = stakingKeeper.Undelegate(ctx, delegatorAddr, valAddr, sdk.NewDecFromInt(sdk.NewInt(300)))
require.NoError(t, err)
},
cleartTrackingFields,
Expand Down
10 changes: 5 additions & 5 deletions x/staking/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -815,19 +815,19 @@ func (k Keeper) getBeginInfo(
// processed during the staking EndBlocker.
func (k Keeper) Undelegate(
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec,
) (time.Time, error) {
) (time.Time, math.Int, error) {
validator, found := k.GetValidator(ctx, valAddr)
if !found {
return time.Time{}, types.ErrNoDelegatorForAddress
return time.Time{}, math.Int{}, types.ErrNoDelegatorForAddress
}

if k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) {
return time.Time{}, types.ErrMaxUnbondingDelegationEntries
return time.Time{}, math.Int{}, types.ErrMaxUnbondingDelegationEntries
}

returnAmount, err := k.Unbond(ctx, delAddr, valAddr, sharesAmount)
if err != nil {
return time.Time{}, err
return time.Time{}, math.Int{}, err
}

// transfer the validator tokens to the not bonded pool
Expand All @@ -839,7 +839,7 @@ func (k Keeper) Undelegate(
ubd := k.SetUnbondingDelegationEntry(ctx, delAddr, valAddr, ctx.BlockHeight(), completionTime, returnAmount)
k.InsertUBDQueue(ctx, ubd, completionTime)

return completionTime, nil
return completionTime, returnAmount, nil
}

// CompleteUnbonding completes the unbonding of all mature entries in the
Expand Down
30 changes: 20 additions & 10 deletions x/staking/keeper/delegation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func (s *KeeperTestSuite) TestUndelegateSelfDelegationBelowMinSelfDelegation() {

val0AccAddr := sdk.AccAddress(addrVals[0].Bytes())
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
_, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(keeper.TokensFromConsensusPower(ctx, 6)))
_, _, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(keeper.TokensFromConsensusPower(ctx, 6)))
require.NoError(err)

// end block
Expand Down Expand Up @@ -315,8 +315,9 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondingValidator() {
// unbond the all self-delegation to put validator in unbonding state
val0AccAddr := sdk.AccAddress(addrVals[0])
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
_, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens))
_, amount, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens))
require.NoError(err)
require.Equal(amount, delTokens)

// end block
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
Expand All @@ -334,8 +335,10 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondingValidator() {
ctx = ctx.WithBlockTime(blockTime2)

// unbond some of the other delegation's shares
_, err = keeper.Undelegate(ctx, addrDels[1], addrVals[0], math.LegacyNewDec(6))
undelegateAmount := math.LegacyNewDec(6)
_, undelegatedAmount, err := keeper.Undelegate(ctx, addrDels[1], addrVals[0], undelegateAmount)
require.NoError(err)
require.Equal(math.LegacyNewDecFromInt(undelegatedAmount), undelegateAmount)

// retrieve the unbonding delegation
ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[1], addrVals[0])
Expand Down Expand Up @@ -382,8 +385,9 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondedValidator() {

// unbond the all self-delegation to put validator in unbonding state
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
_, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(valTokens))
_, amount, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(valTokens))
require.NoError(err)
require.Equal(amount, valTokens)

// end block
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
Expand All @@ -406,13 +410,15 @@ func (s *KeeperTestSuite) TestUndelegateFromUnbondedValidator() {

// unbond some of the other delegation's shares
unbondTokens := keeper.TokensFromConsensusPower(ctx, 6)
_, err = keeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(unbondTokens))
_, amount2, err := keeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(unbondTokens))
require.NoError(err)
require.Equal(amount2, unbondTokens)

// unbond rest of the other delegation's shares
remainingTokens := delTokens.Sub(unbondTokens)
_, err = keeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(remainingTokens))
_, amount3, err := keeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(remainingTokens))
require.NoError(err)
require.Equal(amount3, remainingTokens)

// now validator should be deleted from state
validator, found = keeper.GetValidator(ctx, addrVals[0])
Expand Down Expand Up @@ -458,16 +464,18 @@ func (s *KeeperTestSuite) TestUnbondingAllDelegationFromValidator() {

// unbond the all self-delegation to put validator in unbonding state
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
_, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(valTokens))
_, amount, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(valTokens))
require.NoError(err)
require.Equal(amount, valTokens)

// end block
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
s.applyValidatorSetUpdates(ctx, keeper, 1)

// unbond all the remaining delegation
_, err = keeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(delTokens))
_, amount2, err := keeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDecFromInt(delTokens))
require.NoError(err)
require.Equal(amount2, delTokens)

// validator should still be in state and still be in unbonding state
validator, found := keeper.GetValidator(ctx, addrVals[0])
Expand Down Expand Up @@ -744,8 +752,9 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondingValidator() {

// unbond the all self-delegation to put validator in unbonding state
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
_, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens))
_, amount, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens))
require.NoError(err)
require.Equal(amount, delTokens)

// end block
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
Expand Down Expand Up @@ -820,8 +829,9 @@ func (s *KeeperTestSuite) TestRedelegateFromUnbondedValidator() {

// unbond the all self-delegation to put validator in unbonding state
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
_, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens))
_, amount, err := keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.NewDecFromInt(delTokens))
require.NoError(err)
require.Equal(amount, delTokens)

// end block
s.bankKeeper.EXPECT().SendCoinsFromModuleToModule(gomock.Any(), stakingtypes.BondedPoolName, stakingtypes.NotBondedPoolName, gomock.Any())
Expand Down
7 changes: 5 additions & 2 deletions x/staking/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,13 @@ func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (
)
}

completionTime, err := k.Keeper.Undelegate(ctx, delegatorAddress, addr, shares)
completionTime, undelegatedAmt, err := k.Keeper.Undelegate(ctx, delegatorAddress, addr, shares)
if err != nil {
return nil, err
}

undelegatedCoin := sdk.NewCoin(msg.Amount.Denom, undelegatedAmt)

if msg.Amount.Amount.IsInt64() {
defer func() {
telemetry.IncrCounter(1, types.ModuleName, "undelegate")
Expand All @@ -353,13 +355,14 @@ func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (
sdk.NewEvent(
types.EventTypeUnbond,
sdk.NewAttribute(types.AttributeKeyValidator, msg.ValidatorAddress),
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Amount.String()),
sdk.NewAttribute(sdk.AttributeKeyAmount, undelegatedCoin.String()),
sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.Format(time.RFC3339)),
),
})

return &types.MsgUndelegateResponse{
CompletionTime: completionTime,
Amount: undelegatedCoin,
}, nil
}

Expand Down
Loading

0 comments on commit e3b37dc

Please sign in to comment.