github.com/Finschia/finschia-sdk@v0.48.1/x/staking/keeper/delegation.go (about)

     1  package keeper
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"time"
     7  
     8  	sdk "github.com/Finschia/finschia-sdk/types"
     9  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    10  	"github.com/Finschia/finschia-sdk/x/staking/types"
    11  )
    12  
    13  // GetDelegation returns a specific delegation.
    14  func (k Keeper) GetDelegation(ctx sdk.Context,
    15  	delAddr sdk.AccAddress, valAddr sdk.ValAddress,
    16  ) (delegation types.Delegation, found bool) {
    17  	store := ctx.KVStore(k.storeKey)
    18  	key := types.GetDelegationKey(delAddr, valAddr)
    19  
    20  	value := store.Get(key)
    21  	if value == nil {
    22  		return delegation, false
    23  	}
    24  
    25  	delegation = types.MustUnmarshalDelegation(k.cdc, value)
    26  
    27  	return delegation, true
    28  }
    29  
    30  // IterateAllDelegations iterates through all of the delegations.
    31  func (k Keeper) IterateAllDelegations(ctx sdk.Context, cb func(delegation types.Delegation) (stop bool)) {
    32  	store := ctx.KVStore(k.storeKey)
    33  
    34  	iterator := sdk.KVStorePrefixIterator(store, types.DelegationKey)
    35  	defer iterator.Close()
    36  
    37  	for ; iterator.Valid(); iterator.Next() {
    38  		delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
    39  		if cb(delegation) {
    40  			break
    41  		}
    42  	}
    43  }
    44  
    45  // GetAllDelegations returns all delegations used during genesis dump.
    46  func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegation) {
    47  	k.IterateAllDelegations(ctx, func(delegation types.Delegation) bool {
    48  		delegations = append(delegations, delegation)
    49  		return false
    50  	})
    51  
    52  	return delegations
    53  }
    54  
    55  // GetValidatorDelegations returns all delegations to a specific validator.
    56  // Useful for querier.
    57  func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress) (delegations []types.Delegation) { //nolint:interfacer
    58  	store := ctx.KVStore(k.storeKey)
    59  
    60  	iterator := sdk.KVStorePrefixIterator(store, types.DelegationKey)
    61  	defer iterator.Close()
    62  
    63  	for ; iterator.Valid(); iterator.Next() {
    64  		delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
    65  		if delegation.GetValidatorAddr().Equals(valAddr) {
    66  			delegations = append(delegations, delegation)
    67  		}
    68  	}
    69  
    70  	return delegations
    71  }
    72  
    73  // GetDelegatorDelegations returns a given amount of all the delegations from a
    74  // delegator.
    75  func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress,
    76  	maxRetrieve uint16,
    77  ) (delegations []types.Delegation) {
    78  	delegations = make([]types.Delegation, maxRetrieve)
    79  	store := ctx.KVStore(k.storeKey)
    80  	delegatorPrefixKey := types.GetDelegationsKey(delegator)
    81  
    82  	iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey)
    83  	defer iterator.Close()
    84  
    85  	i := 0
    86  	for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() {
    87  		delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
    88  		delegations[i] = delegation
    89  		i++
    90  	}
    91  
    92  	return delegations[:i] // trim if the array length < maxRetrieve
    93  }
    94  
    95  // SetDelegation sets a delegation.
    96  func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) {
    97  	delegatorAddress := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)
    98  
    99  	store := ctx.KVStore(k.storeKey)
   100  	b := types.MustMarshalDelegation(k.cdc, delegation)
   101  	store.Set(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr()), b)
   102  }
   103  
   104  // RemoveDelegation removes a delegation.
   105  func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) {
   106  	delegatorAddress := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)
   107  
   108  	k.BeforeDelegationRemoved(ctx, delegatorAddress, delegation.GetValidatorAddr())
   109  	store := ctx.KVStore(k.storeKey)
   110  	store.Delete(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr()))
   111  }
   112  
   113  // GetUnbondingDelegations returns a given amount of all the delegator unbonding-delegations.
   114  func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress,
   115  	maxRetrieve uint16,
   116  ) (unbondingDelegations []types.UnbondingDelegation) {
   117  	unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve)
   118  
   119  	store := ctx.KVStore(k.storeKey)
   120  	delegatorPrefixKey := types.GetUBDsKey(delegator)
   121  
   122  	iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey)
   123  	defer iterator.Close()
   124  
   125  	i := 0
   126  	for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() {
   127  		unbondingDelegation := types.MustUnmarshalUBD(k.cdc, iterator.Value())
   128  		unbondingDelegations[i] = unbondingDelegation
   129  		i++
   130  	}
   131  
   132  	return unbondingDelegations[:i] // trim if the array length < maxRetrieve
   133  }
   134  
   135  // GetUnbondingDelegation returns a unbonding delegation.
   136  func (k Keeper) GetUnbondingDelegation(
   137  	ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress,
   138  ) (ubd types.UnbondingDelegation, found bool) {
   139  	store := ctx.KVStore(k.storeKey)
   140  	key := types.GetUBDKey(delAddr, valAddr)
   141  	value := store.Get(key)
   142  
   143  	if value == nil {
   144  		return ubd, false
   145  	}
   146  
   147  	ubd = types.MustUnmarshalUBD(k.cdc, value)
   148  
   149  	return ubd, true
   150  }
   151  
   152  // GetUnbondingDelegationsFromValidator returns all unbonding delegations from a
   153  // particular validator.
   154  func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAddress) (ubds []types.UnbondingDelegation) {
   155  	store := ctx.KVStore(k.storeKey)
   156  
   157  	iterator := sdk.KVStorePrefixIterator(store, types.GetUBDsByValIndexKey(valAddr))
   158  	defer iterator.Close()
   159  
   160  	for ; iterator.Valid(); iterator.Next() {
   161  		key := types.GetUBDKeyFromValIndexKey(iterator.Key())
   162  		value := store.Get(key)
   163  		ubd := types.MustUnmarshalUBD(k.cdc, value)
   164  		ubds = append(ubds, ubd)
   165  	}
   166  
   167  	return ubds
   168  }
   169  
   170  // IterateUnbondingDelegations iterates through all of the unbonding delegations.
   171  func (k Keeper) IterateUnbondingDelegations(ctx sdk.Context, fn func(index int64, ubd types.UnbondingDelegation) (stop bool)) {
   172  	store := ctx.KVStore(k.storeKey)
   173  
   174  	iterator := sdk.KVStorePrefixIterator(store, types.UnbondingDelegationKey)
   175  	defer iterator.Close()
   176  
   177  	for i := int64(0); iterator.Valid(); iterator.Next() {
   178  		ubd := types.MustUnmarshalUBD(k.cdc, iterator.Value())
   179  		if stop := fn(i, ubd); stop {
   180  			break
   181  		}
   182  		i++
   183  	}
   184  }
   185  
   186  // GetDelegatorUnbonding returns the total amount a delegator has unbonding.
   187  func (k Keeper) GetDelegatorUnbonding(ctx sdk.Context, delegator sdk.AccAddress) sdk.Int {
   188  	unbonding := sdk.ZeroInt()
   189  	k.IterateDelegatorUnbondingDelegations(ctx, delegator, func(ubd types.UnbondingDelegation) bool {
   190  		for _, entry := range ubd.Entries {
   191  			unbonding = unbonding.Add(entry.Balance)
   192  		}
   193  		return false
   194  	})
   195  	return unbonding
   196  }
   197  
   198  // IterateDelegatorUnbondingDelegations iterates through a delegator's unbonding delegations.
   199  func (k Keeper) IterateDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(ubd types.UnbondingDelegation) (stop bool)) {
   200  	store := ctx.KVStore(k.storeKey)
   201  
   202  	iterator := sdk.KVStorePrefixIterator(store, types.GetUBDsKey(delegator))
   203  	defer iterator.Close()
   204  
   205  	for ; iterator.Valid(); iterator.Next() {
   206  		ubd := types.MustUnmarshalUBD(k.cdc, iterator.Value())
   207  		if cb(ubd) {
   208  			break
   209  		}
   210  	}
   211  }
   212  
   213  // GetDelegatorBonded returs the total amount a delegator has bonded.
   214  func (k Keeper) GetDelegatorBonded(ctx sdk.Context, delegator sdk.AccAddress) sdk.Int {
   215  	bonded := sdk.ZeroDec()
   216  
   217  	k.IterateDelegatorDelegations(ctx, delegator, func(delegation types.Delegation) bool {
   218  		validatorAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
   219  		if err != nil {
   220  			panic(err) // shouldn't happen
   221  		}
   222  		validator, found := k.GetValidator(ctx, validatorAddr)
   223  		if found {
   224  			shares := delegation.Shares
   225  			tokens := validator.TokensFromSharesTruncated(shares)
   226  			bonded = bonded.Add(tokens)
   227  		}
   228  		return false
   229  	})
   230  	return bonded.RoundInt()
   231  }
   232  
   233  // IterateDelegatorDelegations iterates through one delegator's delegations.
   234  func (k Keeper) IterateDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(delegation types.Delegation) (stop bool)) {
   235  	store := ctx.KVStore(k.storeKey)
   236  	delegatorPrefixKey := types.GetDelegationsKey(delegator)
   237  	iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey)
   238  	defer iterator.Close()
   239  
   240  	for ; iterator.Valid(); iterator.Next() {
   241  		delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
   242  		if cb(delegation) {
   243  			break
   244  		}
   245  	}
   246  }
   247  
   248  // IterateDelegatorRedelegations iterates through one delegator's redelegations.
   249  func (k Keeper) IterateDelegatorRedelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(red types.Redelegation) (stop bool)) {
   250  	store := ctx.KVStore(k.storeKey)
   251  	delegatorPrefixKey := types.GetREDsKey(delegator)
   252  
   253  	iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey)
   254  	defer iterator.Close()
   255  
   256  	for ; iterator.Valid(); iterator.Next() {
   257  		red := types.MustUnmarshalRED(k.cdc, iterator.Value())
   258  		if cb(red) {
   259  			break
   260  		}
   261  	}
   262  }
   263  
   264  // HasMaxUnbondingDelegationEntries - check if unbonding delegation has maximum number of entries.
   265  func (k Keeper) HasMaxUnbondingDelegationEntries(ctx sdk.Context,
   266  	delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
   267  ) bool {
   268  	ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
   269  	if !found {
   270  		return false
   271  	}
   272  
   273  	return len(ubd.Entries) >= int(k.MaxEntries(ctx))
   274  }
   275  
   276  // SetUnbondingDelegation sets the unbonding delegation and associated index.
   277  func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) {
   278  	delegatorAddress := sdk.MustAccAddressFromBech32(ubd.DelegatorAddress)
   279  
   280  	store := ctx.KVStore(k.storeKey)
   281  	bz := types.MustMarshalUBD(k.cdc, ubd)
   282  	addr, err := sdk.ValAddressFromBech32(ubd.ValidatorAddress)
   283  	if err != nil {
   284  		panic(err)
   285  	}
   286  	key := types.GetUBDKey(delegatorAddress, addr)
   287  	store.Set(key, bz)
   288  	store.Set(types.GetUBDByValIndexKey(delegatorAddress, addr), []byte{}) // index, store empty bytes
   289  }
   290  
   291  // RemoveUnbondingDelegation removes the unbonding delegation object and associated index.
   292  func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) {
   293  	delegatorAddress := sdk.MustAccAddressFromBech32(ubd.DelegatorAddress)
   294  
   295  	store := ctx.KVStore(k.storeKey)
   296  	addr, err := sdk.ValAddressFromBech32(ubd.ValidatorAddress)
   297  	if err != nil {
   298  		panic(err)
   299  	}
   300  	key := types.GetUBDKey(delegatorAddress, addr)
   301  	store.Delete(key)
   302  	store.Delete(types.GetUBDByValIndexKey(delegatorAddress, addr))
   303  }
   304  
   305  // SetUnbondingDelegationEntry adds an entry to the unbonding delegation at
   306  // the given addresses. It creates the unbonding delegation if it does not exist.
   307  func (k Keeper) SetUnbondingDelegationEntry(
   308  	ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
   309  	creationHeight int64, minTime time.Time, balance sdk.Int,
   310  ) types.UnbondingDelegation {
   311  	ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
   312  	if found {
   313  		ubd.AddEntry(creationHeight, minTime, balance)
   314  	} else {
   315  		ubd = types.NewUnbondingDelegation(delegatorAddr, validatorAddr, creationHeight, minTime, balance)
   316  	}
   317  
   318  	k.SetUnbondingDelegation(ctx, ubd)
   319  
   320  	return ubd
   321  }
   322  
   323  // unbonding delegation queue timeslice operations
   324  
   325  // GetUBDQueueTimeSlice gets a specific unbonding queue timeslice. A timeslice
   326  // is a slice of DVPairs corresponding to unbonding delegations that expire at a
   327  // certain time.
   328  func (k Keeper) GetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvPairs []types.DVPair) {
   329  	store := ctx.KVStore(k.storeKey)
   330  
   331  	bz := store.Get(types.GetUnbondingDelegationTimeKey(timestamp))
   332  	if bz == nil {
   333  		return []types.DVPair{}
   334  	}
   335  
   336  	pairs := types.DVPairs{}
   337  	k.cdc.MustUnmarshal(bz, &pairs)
   338  
   339  	return pairs.Pairs
   340  }
   341  
   342  // SetUBDQueueTimeSlice sets a specific unbonding queue timeslice.
   343  func (k Keeper) SetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVPair) {
   344  	store := ctx.KVStore(k.storeKey)
   345  	bz := k.cdc.MustMarshal(&types.DVPairs{Pairs: keys})
   346  	store.Set(types.GetUnbondingDelegationTimeKey(timestamp), bz)
   347  }
   348  
   349  // InsertUBDQueue inserts an unbonding delegation to the appropriate timeslice
   350  // in the unbonding queue.
   351  func (k Keeper) InsertUBDQueue(ctx sdk.Context, ubd types.UnbondingDelegation,
   352  	completionTime time.Time,
   353  ) {
   354  	dvPair := types.DVPair{DelegatorAddress: ubd.DelegatorAddress, ValidatorAddress: ubd.ValidatorAddress}
   355  
   356  	timeSlice := k.GetUBDQueueTimeSlice(ctx, completionTime)
   357  	if len(timeSlice) == 0 {
   358  		k.SetUBDQueueTimeSlice(ctx, completionTime, []types.DVPair{dvPair})
   359  	} else {
   360  		timeSlice = append(timeSlice, dvPair)
   361  		k.SetUBDQueueTimeSlice(ctx, completionTime, timeSlice)
   362  	}
   363  }
   364  
   365  // UBDQueueIterator returns all the unbonding queue timeslices from time 0 until endTime.
   366  func (k Keeper) UBDQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
   367  	store := ctx.KVStore(k.storeKey)
   368  	return store.Iterator(types.UnbondingQueueKey,
   369  		sdk.InclusiveEndBytes(types.GetUnbondingDelegationTimeKey(endTime)))
   370  }
   371  
   372  // DequeueAllMatureUBDQueue returns a concatenated list of all the timeslices inclusively previous to
   373  // currTime, and deletes the timeslices from the queue.
   374  func (k Keeper) DequeueAllMatureUBDQueue(ctx sdk.Context, currTime time.Time) (matureUnbonds []types.DVPair) {
   375  	store := ctx.KVStore(k.storeKey)
   376  
   377  	// gets an iterator for all timeslices from time 0 until the current Blockheader time
   378  	unbondingTimesliceIterator := k.UBDQueueIterator(ctx, ctx.BlockHeader().Time)
   379  	defer unbondingTimesliceIterator.Close()
   380  
   381  	for ; unbondingTimesliceIterator.Valid(); unbondingTimesliceIterator.Next() {
   382  		timeslice := types.DVPairs{}
   383  		value := unbondingTimesliceIterator.Value()
   384  		k.cdc.MustUnmarshal(value, &timeslice)
   385  
   386  		matureUnbonds = append(matureUnbonds, timeslice.Pairs...)
   387  
   388  		store.Delete(unbondingTimesliceIterator.Key())
   389  	}
   390  
   391  	return matureUnbonds
   392  }
   393  
   394  // GetRedelegations returns a given amount of all the delegator redelegations.
   395  func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress,
   396  	maxRetrieve uint16,
   397  ) (redelegations []types.Redelegation) {
   398  	redelegations = make([]types.Redelegation, maxRetrieve)
   399  
   400  	store := ctx.KVStore(k.storeKey)
   401  	delegatorPrefixKey := types.GetREDsKey(delegator)
   402  
   403  	iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey)
   404  	defer iterator.Close()
   405  
   406  	i := 0
   407  	for ; iterator.Valid() && i < int(maxRetrieve); iterator.Next() {
   408  		redelegation := types.MustUnmarshalRED(k.cdc, iterator.Value())
   409  		redelegations[i] = redelegation
   410  		i++
   411  	}
   412  
   413  	return redelegations[:i] // trim if the array length < maxRetrieve
   414  }
   415  
   416  // GetRedelegation returns a redelegation.
   417  func (k Keeper) GetRedelegation(ctx sdk.Context,
   418  	delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress,
   419  ) (red types.Redelegation, found bool) {
   420  	store := ctx.KVStore(k.storeKey)
   421  	key := types.GetREDKey(delAddr, valSrcAddr, valDstAddr)
   422  
   423  	value := store.Get(key)
   424  	if value == nil {
   425  		return red, false
   426  	}
   427  
   428  	red = types.MustUnmarshalRED(k.cdc, value)
   429  
   430  	return red, true
   431  }
   432  
   433  // GetRedelegationsFromSrcValidator returns all redelegations from a particular
   434  // validator.
   435  func (k Keeper) GetRedelegationsFromSrcValidator(ctx sdk.Context, valAddr sdk.ValAddress) (reds []types.Redelegation) {
   436  	store := ctx.KVStore(k.storeKey)
   437  
   438  	iterator := sdk.KVStorePrefixIterator(store, types.GetREDsFromValSrcIndexKey(valAddr))
   439  	defer iterator.Close()
   440  
   441  	for ; iterator.Valid(); iterator.Next() {
   442  		key := types.GetREDKeyFromValSrcIndexKey(iterator.Key())
   443  		value := store.Get(key)
   444  		red := types.MustUnmarshalRED(k.cdc, value)
   445  		reds = append(reds, red)
   446  	}
   447  
   448  	return reds
   449  }
   450  
   451  // HasReceivingRedelegation checks if validator is receiving a redelegation.
   452  func (k Keeper) HasReceivingRedelegation(ctx sdk.Context,
   453  	delAddr sdk.AccAddress, valDstAddr sdk.ValAddress,
   454  ) bool {
   455  	store := ctx.KVStore(k.storeKey)
   456  	prefix := types.GetREDsByDelToValDstIndexKey(delAddr, valDstAddr)
   457  
   458  	iterator := sdk.KVStorePrefixIterator(store, prefix)
   459  	defer iterator.Close()
   460  
   461  	return iterator.Valid()
   462  }
   463  
   464  // HasMaxRedelegationEntries checks if redelegation has maximum number of entries.
   465  func (k Keeper) HasMaxRedelegationEntries(ctx sdk.Context,
   466  	delegatorAddr sdk.AccAddress, validatorSrcAddr,
   467  	validatorDstAddr sdk.ValAddress,
   468  ) bool {
   469  	red, found := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr)
   470  	if !found {
   471  		return false
   472  	}
   473  
   474  	return len(red.Entries) >= int(k.MaxEntries(ctx))
   475  }
   476  
   477  // SetRedelegation set a redelegation and associated index.
   478  func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) {
   479  	delegatorAddress := sdk.MustAccAddressFromBech32(red.DelegatorAddress)
   480  
   481  	store := ctx.KVStore(k.storeKey)
   482  	bz := types.MustMarshalRED(k.cdc, red)
   483  	valSrcAddr, err := sdk.ValAddressFromBech32(red.ValidatorSrcAddress)
   484  	if err != nil {
   485  		panic(err)
   486  	}
   487  	valDestAddr, err := sdk.ValAddressFromBech32(red.ValidatorDstAddress)
   488  	if err != nil {
   489  		panic(err)
   490  	}
   491  	key := types.GetREDKey(delegatorAddress, valSrcAddr, valDestAddr)
   492  	store.Set(key, bz)
   493  	store.Set(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{})
   494  	store.Set(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{})
   495  }
   496  
   497  // SetRedelegationEntry adds an entry to the unbonding delegation at the given
   498  // addresses. It creates the unbonding delegation if it does not exist.
   499  func (k Keeper) SetRedelegationEntry(ctx sdk.Context,
   500  	delegatorAddr sdk.AccAddress, validatorSrcAddr,
   501  	validatorDstAddr sdk.ValAddress, creationHeight int64,
   502  	minTime time.Time, balance sdk.Int,
   503  	sharesSrc, sharesDst sdk.Dec,
   504  ) types.Redelegation {
   505  	red, found := k.GetRedelegation(ctx, delegatorAddr, validatorSrcAddr, validatorDstAddr)
   506  	if found {
   507  		red.AddEntry(creationHeight, minTime, balance, sharesDst)
   508  	} else {
   509  		red = types.NewRedelegation(delegatorAddr, validatorSrcAddr,
   510  			validatorDstAddr, creationHeight, minTime, balance, sharesDst)
   511  	}
   512  
   513  	k.SetRedelegation(ctx, red)
   514  
   515  	return red
   516  }
   517  
   518  // IterateRedelegations iterates through all redelegations.
   519  func (k Keeper) IterateRedelegations(ctx sdk.Context, fn func(index int64, red types.Redelegation) (stop bool)) {
   520  	store := ctx.KVStore(k.storeKey)
   521  
   522  	iterator := sdk.KVStorePrefixIterator(store, types.RedelegationKey)
   523  	defer iterator.Close()
   524  
   525  	for i := int64(0); iterator.Valid(); iterator.Next() {
   526  		red := types.MustUnmarshalRED(k.cdc, iterator.Value())
   527  		if stop := fn(i, red); stop {
   528  			break
   529  		}
   530  		i++
   531  	}
   532  }
   533  
   534  // RemoveRedelegation removes a redelegation object and associated index.
   535  func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) {
   536  	delegatorAddress := sdk.MustAccAddressFromBech32(red.DelegatorAddress)
   537  
   538  	store := ctx.KVStore(k.storeKey)
   539  	valSrcAddr, err := sdk.ValAddressFromBech32(red.ValidatorSrcAddress)
   540  	if err != nil {
   541  		panic(err)
   542  	}
   543  	valDestAddr, err := sdk.ValAddressFromBech32(red.ValidatorDstAddress)
   544  	if err != nil {
   545  		panic(err)
   546  	}
   547  	redKey := types.GetREDKey(delegatorAddress, valSrcAddr, valDestAddr)
   548  	store.Delete(redKey)
   549  	store.Delete(types.GetREDByValSrcIndexKey(delegatorAddress, valSrcAddr, valDestAddr))
   550  	store.Delete(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr))
   551  }
   552  
   553  // redelegation queue timeslice operations
   554  
   555  // GetRedelegationQueueTimeSlice gets a specific redelegation queue timeslice. A
   556  // timeslice is a slice of DVVTriplets corresponding to redelegations that
   557  // expire at a certain time.
   558  func (k Keeper) GetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvvTriplets []types.DVVTriplet) {
   559  	store := ctx.KVStore(k.storeKey)
   560  
   561  	bz := store.Get(types.GetRedelegationTimeKey(timestamp))
   562  	if bz == nil {
   563  		return []types.DVVTriplet{}
   564  	}
   565  
   566  	triplets := types.DVVTriplets{}
   567  	k.cdc.MustUnmarshal(bz, &triplets)
   568  
   569  	return triplets.Triplets
   570  }
   571  
   572  // SetRedelegationQueueTimeSlice sets a specific redelegation queue timeslice.
   573  func (k Keeper) SetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVVTriplet) {
   574  	store := ctx.KVStore(k.storeKey)
   575  	bz := k.cdc.MustMarshal(&types.DVVTriplets{Triplets: keys})
   576  	store.Set(types.GetRedelegationTimeKey(timestamp), bz)
   577  }
   578  
   579  // InsertRedelegationQueue insert an redelegation delegation to the appropriate
   580  // timeslice in the redelegation queue.
   581  func (k Keeper) InsertRedelegationQueue(ctx sdk.Context, red types.Redelegation,
   582  	completionTime time.Time,
   583  ) {
   584  	timeSlice := k.GetRedelegationQueueTimeSlice(ctx, completionTime)
   585  	dvvTriplet := types.DVVTriplet{
   586  		DelegatorAddress:    red.DelegatorAddress,
   587  		ValidatorSrcAddress: red.ValidatorSrcAddress,
   588  		ValidatorDstAddress: red.ValidatorDstAddress,
   589  	}
   590  
   591  	if len(timeSlice) == 0 {
   592  		k.SetRedelegationQueueTimeSlice(ctx, completionTime, []types.DVVTriplet{dvvTriplet})
   593  	} else {
   594  		timeSlice = append(timeSlice, dvvTriplet)
   595  		k.SetRedelegationQueueTimeSlice(ctx, completionTime, timeSlice)
   596  	}
   597  }
   598  
   599  // RedelegationQueueIterator returns all the redelegation queue timeslices from
   600  // time 0 until endTime.
   601  func (k Keeper) RedelegationQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
   602  	store := ctx.KVStore(k.storeKey)
   603  	return store.Iterator(types.RedelegationQueueKey, sdk.InclusiveEndBytes(types.GetRedelegationTimeKey(endTime)))
   604  }
   605  
   606  // DequeueAllMatureRedelegationQueue returns a concatenated list of all the
   607  // timeslices inclusively previous to currTime, and deletes the timeslices from
   608  // the queue.
   609  func (k Keeper) DequeueAllMatureRedelegationQueue(ctx sdk.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet) {
   610  	store := ctx.KVStore(k.storeKey)
   611  
   612  	// gets an iterator for all timeslices from time 0 until the current Blockheader time
   613  	redelegationTimesliceIterator := k.RedelegationQueueIterator(ctx, ctx.BlockHeader().Time)
   614  	defer redelegationTimesliceIterator.Close()
   615  
   616  	for ; redelegationTimesliceIterator.Valid(); redelegationTimesliceIterator.Next() {
   617  		timeslice := types.DVVTriplets{}
   618  		value := redelegationTimesliceIterator.Value()
   619  		k.cdc.MustUnmarshal(value, &timeslice)
   620  
   621  		matureRedelegations = append(matureRedelegations, timeslice.Triplets...)
   622  
   623  		store.Delete(redelegationTimesliceIterator.Key())
   624  	}
   625  
   626  	return matureRedelegations
   627  }
   628  
   629  // Delegate performs a delegation, set/update everything necessary within the store.
   630  // tokenSrc indicates the bond status of the incoming funds.
   631  func (k Keeper) Delegate(
   632  	ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Int, tokenSrc types.BondStatus,
   633  	validator types.Validator, subtractAccount bool,
   634  ) (newShares sdk.Dec, err error) {
   635  	// In some situations, the exchange rate becomes invalid, e.g. if
   636  	// Validator loses all tokens due to slashing. In this case,
   637  	// make all future delegations invalid.
   638  	if validator.InvalidExRate() {
   639  		return sdk.ZeroDec(), types.ErrDelegatorShareExRateInvalid
   640  	}
   641  
   642  	// Get or create the delegation object
   643  	delegation, found := k.GetDelegation(ctx, delAddr, validator.GetOperator())
   644  	if !found {
   645  		delegation = types.NewDelegation(delAddr, validator.GetOperator(), sdk.ZeroDec())
   646  	}
   647  
   648  	// call the appropriate hook if present
   649  	if found {
   650  		k.BeforeDelegationSharesModified(ctx, delAddr, validator.GetOperator())
   651  	} else {
   652  		k.BeforeDelegationCreated(ctx, delAddr, validator.GetOperator())
   653  	}
   654  
   655  	delegatorAddress := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)
   656  
   657  	// if subtractAccount is true then we are
   658  	// performing a delegation and not a redelegation, thus the source tokens are
   659  	// all non bonded
   660  	if subtractAccount {
   661  		if tokenSrc == types.Bonded {
   662  			panic("delegation token source cannot be bonded")
   663  		}
   664  
   665  		var sendName string
   666  
   667  		switch {
   668  		case validator.IsBonded():
   669  			sendName = types.BondedPoolName
   670  		case validator.IsUnbonding(), validator.IsUnbonded():
   671  			sendName = types.NotBondedPoolName
   672  		default:
   673  			panic("invalid validator status")
   674  		}
   675  
   676  		coins := sdk.NewCoins(sdk.NewCoin(k.BondDenom(ctx), bondAmt))
   677  		if err := k.bankKeeper.DelegateCoinsFromAccountToModule(ctx, delegatorAddress, sendName, coins); err != nil {
   678  			return sdk.Dec{}, err
   679  		}
   680  	} else {
   681  		// potentially transfer tokens between pools, if
   682  		switch {
   683  		case tokenSrc == types.Bonded && validator.IsBonded():
   684  			// do nothing
   685  		case (tokenSrc == types.Unbonded || tokenSrc == types.Unbonding) && !validator.IsBonded():
   686  			// do nothing
   687  		case (tokenSrc == types.Unbonded || tokenSrc == types.Unbonding) && validator.IsBonded():
   688  			// transfer pools
   689  			k.notBondedTokensToBonded(ctx, bondAmt)
   690  		case tokenSrc == types.Bonded && !validator.IsBonded():
   691  			// transfer pools
   692  			k.bondedTokensToNotBonded(ctx, bondAmt)
   693  		default:
   694  			panic("unknown token source bond status")
   695  		}
   696  	}
   697  
   698  	_, newShares = k.AddValidatorTokensAndShares(ctx, validator, bondAmt)
   699  
   700  	// Update delegation
   701  	delegation.Shares = delegation.Shares.Add(newShares)
   702  	k.SetDelegation(ctx, delegation)
   703  
   704  	// Call the after-modification hook
   705  	k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr())
   706  
   707  	return newShares, nil
   708  }
   709  
   710  // Unbond unbonds a particular delegation and perform associated store operations.
   711  func (k Keeper) Unbond(
   712  	ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec,
   713  ) (amount sdk.Int, err error) {
   714  	// check if a delegation object exists in the store
   715  	delegation, found := k.GetDelegation(ctx, delAddr, valAddr)
   716  	if !found {
   717  		return amount, types.ErrNoDelegatorForAddress
   718  	}
   719  
   720  	// call the before-delegation-modified hook
   721  	k.BeforeDelegationSharesModified(ctx, delAddr, valAddr)
   722  
   723  	// ensure that we have enough shares to remove
   724  	if delegation.Shares.LT(shares) {
   725  		return amount, sdkerrors.Wrap(types.ErrNotEnoughDelegationShares, delegation.Shares.String())
   726  	}
   727  
   728  	// get validator
   729  	validator, found := k.GetValidator(ctx, valAddr)
   730  	if !found {
   731  		return amount, types.ErrNoValidatorFound
   732  	}
   733  
   734  	// subtract shares from delegation
   735  	delegation.Shares = delegation.Shares.Sub(shares)
   736  
   737  	delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
   738  	if err != nil {
   739  		return amount, err
   740  	}
   741  
   742  	isValidatorOperator := delegatorAddress.Equals(validator.GetOperator())
   743  
   744  	// If the delegation is the operator of the validator and undelegating will decrease the validator's
   745  	// self-delegation below their minimum, we jail the validator.
   746  	if isValidatorOperator && !validator.Jailed &&
   747  		validator.TokensFromShares(delegation.Shares).TruncateInt().LT(validator.MinSelfDelegation) {
   748  		k.jailValidator(ctx, validator)
   749  		validator = k.mustGetValidator(ctx, validator.GetOperator())
   750  	}
   751  
   752  	// remove the delegation
   753  	if delegation.Shares.IsZero() {
   754  		k.RemoveDelegation(ctx, delegation)
   755  	} else {
   756  		k.SetDelegation(ctx, delegation)
   757  		// call the after delegation modification hook
   758  		k.AfterDelegationModified(ctx, delegatorAddress, delegation.GetValidatorAddr())
   759  	}
   760  
   761  	// remove the shares and coins from the validator
   762  	// NOTE that the amount is later (in keeper.Delegation) moved between staking module pools
   763  	validator, amount = k.RemoveValidatorTokensAndShares(ctx, validator, shares)
   764  
   765  	if validator.DelegatorShares.IsZero() && validator.IsUnbonded() {
   766  		// if not unbonded, we must instead remove validator in EndBlocker once it finishes its unbonding period
   767  		k.RemoveValidator(ctx, validator.GetOperator())
   768  	}
   769  
   770  	return amount, nil
   771  }
   772  
   773  // getBeginInfo returns the completion time and height of a redelegation, along
   774  // with a boolean signaling if the redelegation is complete based on the source
   775  // validator.
   776  func (k Keeper) getBeginInfo(
   777  	ctx sdk.Context, valSrcAddr sdk.ValAddress,
   778  ) (completionTime time.Time, height int64, completeNow bool) {
   779  	validator, found := k.GetValidator(ctx, valSrcAddr)
   780  
   781  	// TODO: When would the validator not be found?
   782  	switch {
   783  	case !found || validator.IsBonded():
   784  		// the longest wait - just unbonding period from now
   785  		completionTime = ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx))
   786  		height = ctx.BlockHeight()
   787  
   788  		return completionTime, height, false
   789  
   790  	case validator.IsUnbonded():
   791  		return completionTime, height, true
   792  
   793  	case validator.IsUnbonding():
   794  		return validator.UnbondingTime, validator.UnbondingHeight, false
   795  
   796  	default:
   797  		panic(fmt.Sprintf("unknown validator status: %s", validator.Status))
   798  	}
   799  }
   800  
   801  // Undelegate unbonds an amount of delegator shares from a given validator. It
   802  // will verify that the unbonding entries between the delegator and validator
   803  // are not exceeded and unbond the staked tokens (based on shares) by creating
   804  // an unbonding object and inserting it into the unbonding queue which will be
   805  // processed during the staking EndBlocker.
   806  func (k Keeper) Undelegate(
   807  	ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec,
   808  ) (time.Time, error) {
   809  	validator, found := k.GetValidator(ctx, valAddr)
   810  	if !found {
   811  		return time.Time{}, types.ErrNoDelegatorForAddress
   812  	}
   813  
   814  	if k.HasMaxUnbondingDelegationEntries(ctx, delAddr, valAddr) {
   815  		return time.Time{}, types.ErrMaxUnbondingDelegationEntries
   816  	}
   817  
   818  	returnAmount, err := k.Unbond(ctx, delAddr, valAddr, sharesAmount)
   819  	if err != nil {
   820  		return time.Time{}, err
   821  	}
   822  
   823  	// transfer the validator tokens to the not bonded pool
   824  	if validator.IsBonded() {
   825  		k.bondedTokensToNotBonded(ctx, returnAmount)
   826  	}
   827  
   828  	completionTime := ctx.BlockHeader().Time.Add(k.UnbondingTime(ctx))
   829  	ubd := k.SetUnbondingDelegationEntry(ctx, delAddr, valAddr, ctx.BlockHeight(), completionTime, returnAmount)
   830  	k.InsertUBDQueue(ctx, ubd, completionTime)
   831  
   832  	return completionTime, nil
   833  }
   834  
   835  // CompleteUnbonding completes the unbonding of all mature entries in the
   836  // retrieved unbonding delegation object and returns the total unbonding balance
   837  // or an error upon failure.
   838  func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) (sdk.Coins, error) {
   839  	ubd, found := k.GetUnbondingDelegation(ctx, delAddr, valAddr)
   840  	if !found {
   841  		return nil, types.ErrNoUnbondingDelegation
   842  	}
   843  
   844  	bondDenom := k.GetParams(ctx).BondDenom
   845  	balances := sdk.NewCoins()
   846  	ctxTime := ctx.BlockHeader().Time
   847  
   848  	delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress)
   849  	if err != nil {
   850  		return nil, err
   851  	}
   852  
   853  	// loop through all the entries and complete unbonding mature entries
   854  	for i := 0; i < len(ubd.Entries); i++ {
   855  		entry := ubd.Entries[i]
   856  		if entry.IsMature(ctxTime) {
   857  			ubd.RemoveEntry(int64(i))
   858  			i--
   859  
   860  			// track undelegation only when remaining or truncated shares are non-zero
   861  			if !entry.Balance.IsZero() {
   862  				amt := sdk.NewCoin(bondDenom, entry.Balance)
   863  				if err := k.bankKeeper.UndelegateCoinsFromModuleToAccount(
   864  					ctx, types.NotBondedPoolName, delegatorAddress, sdk.NewCoins(amt),
   865  				); err != nil {
   866  					return nil, err
   867  				}
   868  
   869  				balances = balances.Add(amt)
   870  			}
   871  		}
   872  	}
   873  
   874  	// set the unbonding delegation or remove it if there are no more entries
   875  	if len(ubd.Entries) == 0 {
   876  		k.RemoveUnbondingDelegation(ctx, ubd)
   877  	} else {
   878  		k.SetUnbondingDelegation(ctx, ubd)
   879  	}
   880  
   881  	return balances, nil
   882  }
   883  
   884  // BeginRedelegation begins unbonding / redelegation and creates a redelegation
   885  // record.
   886  func (k Keeper) BeginRedelegation(
   887  	ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec,
   888  ) (completionTime time.Time, err error) {
   889  	if bytes.Equal(valSrcAddr, valDstAddr) {
   890  		return time.Time{}, types.ErrSelfRedelegation
   891  	}
   892  
   893  	dstValidator, found := k.GetValidator(ctx, valDstAddr)
   894  	if !found {
   895  		return time.Time{}, types.ErrBadRedelegationDst
   896  	}
   897  
   898  	srcValidator, found := k.GetValidator(ctx, valSrcAddr)
   899  	if !found {
   900  		return time.Time{}, types.ErrBadRedelegationDst
   901  	}
   902  
   903  	// check if this is a transitive redelegation
   904  	if k.HasReceivingRedelegation(ctx, delAddr, valSrcAddr) {
   905  		return time.Time{}, types.ErrTransitiveRedelegation
   906  	}
   907  
   908  	if k.HasMaxRedelegationEntries(ctx, delAddr, valSrcAddr, valDstAddr) {
   909  		return time.Time{}, types.ErrMaxRedelegationEntries
   910  	}
   911  
   912  	returnAmount, err := k.Unbond(ctx, delAddr, valSrcAddr, sharesAmount)
   913  	if err != nil {
   914  		return time.Time{}, err
   915  	}
   916  
   917  	if returnAmount.IsZero() {
   918  		return time.Time{}, types.ErrTinyRedelegationAmount
   919  	}
   920  
   921  	sharesCreated, err := k.Delegate(ctx, delAddr, returnAmount, srcValidator.GetStatus(), dstValidator, false)
   922  	if err != nil {
   923  		return time.Time{}, err
   924  	}
   925  
   926  	// create the unbonding delegation
   927  	completionTime, height, completeNow := k.getBeginInfo(ctx, valSrcAddr)
   928  
   929  	if completeNow { // no need to create the redelegation object
   930  		return completionTime, nil
   931  	}
   932  
   933  	red := k.SetRedelegationEntry(
   934  		ctx, delAddr, valSrcAddr, valDstAddr,
   935  		height, completionTime, returnAmount, sharesAmount, sharesCreated,
   936  	)
   937  	k.InsertRedelegationQueue(ctx, red, completionTime)
   938  
   939  	return completionTime, nil
   940  }
   941  
   942  // CompleteRedelegation completes the redelegations of all mature entries in the
   943  // retrieved redelegation object and returns the total redelegation (initial)
   944  // balance or an error upon failure.
   945  func (k Keeper) CompleteRedelegation(
   946  	ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress,
   947  ) (sdk.Coins, error) {
   948  	red, found := k.GetRedelegation(ctx, delAddr, valSrcAddr, valDstAddr)
   949  	if !found {
   950  		return nil, types.ErrNoRedelegation
   951  	}
   952  
   953  	bondDenom := k.GetParams(ctx).BondDenom
   954  	balances := sdk.NewCoins()
   955  	ctxTime := ctx.BlockHeader().Time
   956  
   957  	// loop through all the entries and complete mature redelegation entries
   958  	for i := 0; i < len(red.Entries); i++ {
   959  		entry := red.Entries[i]
   960  		if entry.IsMature(ctxTime) {
   961  			red.RemoveEntry(int64(i))
   962  			i--
   963  
   964  			if !entry.InitialBalance.IsZero() {
   965  				balances = balances.Add(sdk.NewCoin(bondDenom, entry.InitialBalance))
   966  			}
   967  		}
   968  	}
   969  
   970  	// set the redelegation or remove it if there are no more entries
   971  	if len(red.Entries) == 0 {
   972  		k.RemoveRedelegation(ctx, red)
   973  	} else {
   974  		k.SetRedelegation(ctx, red)
   975  	}
   976  
   977  	return balances, nil
   978  }
   979  
   980  // ValidateUnbondAmount validates that a given unbond or redelegation amount is
   981  // valied based on upon the converted shares. If the amount is valid, the total
   982  // amount of respective shares is returned, otherwise an error is returned.
   983  func (k Keeper) ValidateUnbondAmount(
   984  	ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk.Int,
   985  ) (shares sdk.Dec, err error) {
   986  	validator, found := k.GetValidator(ctx, valAddr)
   987  	if !found {
   988  		return shares, types.ErrNoValidatorFound
   989  	}
   990  
   991  	del, found := k.GetDelegation(ctx, delAddr, valAddr)
   992  	if !found {
   993  		return shares, types.ErrNoDelegation
   994  	}
   995  
   996  	shares, err = validator.SharesFromTokens(amt)
   997  	if err != nil {
   998  		return shares, err
   999  	}
  1000  
  1001  	sharesTruncated, err := validator.SharesFromTokensTruncated(amt)
  1002  	if err != nil {
  1003  		return shares, err
  1004  	}
  1005  
  1006  	delShares := del.GetShares()
  1007  	if sharesTruncated.GT(delShares) {
  1008  		return shares, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid shares amount")
  1009  	}
  1010  
  1011  	// Cap the shares at the delegation's shares. Shares being greater could occur
  1012  	// due to rounding, however we don't want to truncate the shares or take the
  1013  	// minimum because we want to allow for the full withdraw of shares from a
  1014  	// delegation.
  1015  	if shares.GT(delShares) {
  1016  		shares = delShares
  1017  	}
  1018  
  1019  	return shares, nil
  1020  }