Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: return undelegate amount with MsgUndelegateResponse #14590

Merged
merged 18 commits into from
Jan 23, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,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
0xmuralik marked this conversation as resolved.
Show resolved Hide resolved
0xmuralik marked this conversation as resolved.
Show resolved Hide resolved

### State Machine Breaking

Expand All @@ -160,6 +161,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 @@ -225,6 +227,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.

### CLI 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];
0xmuralik marked this conversation as resolved.
Show resolved Hide resolved
0xmuralik marked this conversation as resolved.
Show resolved Hide resolved
}

// 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