feat: add (re)delegation getters (#11596)

### Description

This PR adds general helper functions to the `x/staking` module that are used in the Evmos `x/vesting` module and originated from Agoric's custom staking module implementation https://github.com/agoric-labs/cosmos-sdk/blob/4085-true-vesting/x/staking/keeper/delegation.go.

- `GetDelegatorUnbonding`  
- `GetDelegatorBonded`
- `IterateDelegatorUnbondingDelegations`
- `IterateDelegatorDelegations`
- `IterateDelegatorRedelegations`
This commit is contained in:
Daniel Burckhardt 2022-04-12 16:41:08 +02:00 committed by GitHub
parent 06c5d2bebc
commit b8270fc9ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 149 additions and 50 deletions

View File

@ -79,7 +79,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#11179](https://github.com/cosmos/cosmos-sdk/pull/11179) Add state rollback command.
* [\#10794](https://github.com/cosmos/cosmos-sdk/pull/10794) ADR-040: Add State Sync to V2 Store
* [\#11234](https://github.com/cosmos/cosmos-sdk/pull/11234) Add `GRPCClient` field to Client Context. If `GRPCClient` field is set to nil, the `Invoke` method would use ABCI query, otherwise use gprc.
* [\#10962](https://github.com/cosmos/cosmos-sdk/pull/10962) ADR-040: Add state migration from iavl (v1Store) to smt (v2Store)
* [\#10962](https://github.com/cosmos/cosmos-sdk/pull/10962) ADR-040: Add state migration from iavl (v1Store) to smt (v2Store)
* (types) [\#10948](https://github.com/cosmos/cosmos-sdk/issues/10948) Add `app-db-backend` to the `app.toml` config to replace the compile-time `types.DBbackend` variable.
* (authz)[\#11060](https://github.com/cosmos/cosmos-sdk/pull/11060) Support grant with no expire time.
@ -139,7 +139,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#10612](https://github.com/cosmos/cosmos-sdk/pull/10612) `baseapp.NewBaseApp` constructor function doesn't take the `sdk.TxDecoder` anymore. This logic has been moved into the TxDecoderMiddleware.
* [\#10692](https://github.com/cosmos/cosmos-sdk/pull/10612) `SignerData` takes 2 new fields, `Address` and `PubKey`, which need to get populated when using SIGN_MODE_DIRECT_AUX.
* [\#10748](https://github.com/cosmos/cosmos-sdk/pull/10748) Move legacy `x/gov` api to `v1beta1` directory.
* [\#10816](https://github.com/cosmos/cosmos-sdk/pull/10816) Reuse blocked addresses from the bank module. No need to pass them to distribution.
* [\#10816](https://github.com/cosmos/cosmos-sdk/pull/10816) Reuse blocked addresses from the bank module. No need to pass them to distribution.
* [\#10852](https://github.com/cosmos/cosmos-sdk/pull/10852) Move `x/gov/types` to `x/gov/types/v1beta2`.
* [\#10922](https://github.com/cosmos/cosmos-sdk/pull/10922), [/#10957](https://github.com/cosmos/cosmos-sdk/pull/10957) Move key `server.Generate*` functions to testutil and support custom mnemonics in in-process testing network. Moved `TestMnemonic` from `testutil` package to `testdata`.
* (x/bank) [\#10771](https://github.com/cosmos/cosmos-sdk/pull/10771) Add safety check on bank module perms to allow module-specific mint restrictions (e.g. only minting a certain denom).
@ -153,7 +153,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (authz)[\#11060](https://github.com/cosmos/cosmos-sdk/pull/11060) `authz.NewMsgGrant` `expiration` is now a pointer. When `nil` is used then no expiration will be set (grant won't expire).
* (x/distribution)[\#11457](https://github.com/cosmos/cosmos-sdk/pull/11457) Add amount field to `distr.MsgWithdrawDelegatorRewardResponse` and `distr.MsgWithdrawValidatorCommissionResponse`.
* (x/auth/middleware) [#11413](https://github.com/cosmos/cosmos-sdk/pull/11413) Refactor tx middleware to be extensible on tx fee logic. Merged `MempoolFeeMiddleware` and `TxPriorityMiddleware` functionalities into `DeductFeeMiddleware`, make the logic extensible using the `TxFeeChecker` option, the current fee logic is preserved by the default `checkTxFeeWithValidatorMinGasPrices` implementation. Change `RejectExtensionOptionsMiddleware` to `NewExtensionOptionsMiddleware` which is extensible with the `ExtensionOptionChecker` option. Unpack the tx extension options `Any`s to interface `TxExtensionOptionI`.
* (migrations) [#1156](https://github.com/cosmos/cosmos-sdk/pull/11556#issuecomment-1091385011) Remove migration code from 0.42 and below. To use previous migrations, checkout previous versions of the cosmos-sdk.
* (migrations) [#1156](https://github.com/cosmos/cosmos-sdk/pull/11556#issuecomment-1091385011) Remove migration code from 0.42 and below. To use previous migrations, checkout previous versions of the cosmos-sdk.
### Client Breaking Changes
@ -202,12 +202,13 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (types) [\#11200](https://github.com/cosmos/cosmos-sdk/pull/11200) Added `Min()` and `Max()` operations on sdk.Coins.
* (gov) [\#11287](https://github.com/cosmos/cosmos-sdk/pull/11287) Fix error message when no flags are provided while executing `submit-legacy-proposal` transaction.
* (x/auth) [\#11482](https://github.com/cosmos/cosmos-sdk/pull/11482) Improve panic message when attempting to register a method handler for a message that does not implement sdk.Msg
* (x/staking) [\#11596](https://github.com/cosmos/cosmos-sdk/pull/11596) Add (re)delegation getters
### Bug Fixes
* [\#11558](https://github.com/cosmos/cosmos-sdk/pull/11558) Fix `--dry-run` not working when using tx command.
* [\#11354](https://github.com/cosmos/cosmos-sdk/pull/11355) Added missing pagination flag for `bank q total` query.
* [\#11197](https://github.com/cosmos/cosmos-sdk/pull/11197) Signing with multisig now works with multisig address which is not in the keyring.
* [\#11197](https://github.com/cosmos/cosmos-sdk/pull/11197) Signing with multisig now works with multisig address which is not in the keyring.
* (makefile) [\#11285](https://github.com/cosmos/cosmos-sdk/pull/11285) Fix lint-fix make target.
* (client) [\#11283](https://github.com/cosmos/cosmos-sdk/issues/11283) Support multiple keys for tx simulation and setting automatic gas for txs.
* (store) [\#11177](https://github.com/cosmos/cosmos-sdk/pull/11177) Update the prune `everything` strategy to store the last two heights.
@ -263,7 +264,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#10763](https://github.com/cosmos/cosmos-sdk/pull/10763) modify the fields in `TallyParams` to use `string` instead of `bytes`
* [#10770](https://github.com/cosmos/cosmos-sdk/pull/10770) revert tx when block gas limit exceeded
* [\#10868](https://github.com/cosmos/cosmos-sdk/pull/10868) Bump gov to v1beta2. Both v1beta1 and v1beta2 queries and Msgs are accepted.
* [\#11011](https://github.com/cosmos/cosmos-sdk/pull/11011) Remove burning of deposits when qourum is not reached on a governance proposal and when the deposit is not fully met.
* [\#11011](https://github.com/cosmos/cosmos-sdk/pull/11011) Remove burning of deposits when qourum is not reached on a governance proposal and when the deposit is not fully met.
* [\#11019](https://github.com/cosmos/cosmos-sdk/pull/11019) Add `MsgCreatePermanentLockedAccount` and CLI method for creating permanent locked account
* (x/staking) [\#10885] (https://github.com/cosmos/cosmos-sdk/pull/10885) Add new `CancelUnbondingDelegation`
transaction to `x/staking` module. Delegators can now cancel unbonding delegation entry and delegate back to validator.
@ -291,7 +292,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#10561](https://github.com/cosmos/cosmos-sdk/pull/10561) The `CommitMultiStore` interface contains a new `SetIAVLCacheSize` method
* [\#10922](https://github.com/cosmos/cosmos-sdk/pull/10922), [/#10956](https://github.com/cosmos/cosmos-sdk/pull/10956) Deprecate key `server.Generate*` functions and move them to `testutil` and support custom mnemonics in in-process testing network. Moved `TestMnemonic` from `testutil` package to `testdata`.
* [\#11049](https://github.com/cosmos/cosmos-sdk/pull/11049) Add custom tendermint config variables into root command. Allows App developers to set config.toml variables.
* [\#11049](https://github.com/cosmos/cosmos-sdk/pull/11049) Add custom tendermint config variables into root command. Allows App developers to set config.toml variables.
### Features
@ -310,7 +311,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Bug Fixes
* (std/codec) [/#10595](https://github.com/cosmos/cosmos-sdk/pull/10595) Add evidence to std/codec to be able to decode evidence in client interactions.
* (std/codec) [/#10595](https://github.com/cosmos/cosmos-sdk/pull/10595) Add evidence to std/codec to be able to decode evidence in client interactions.
* (types) [\#9627](https://github.com/cosmos/cosmos-sdk/pull/9627) Fix nil pointer panic on `NewBigIntFromInt`.
* [#10725](https://github.com/cosmos/cosmos-sdk/pull/10725) populate `ctx.ConsensusParams` for begin/end blockers.
* [\#9829](https://github.com/cosmos/cosmos-sdk/pull/9829) Fixed Coin denom sorting not being checked during `Balance.Validate` check. Refactored the Validation logic to use `Coins.Validate` for `Balance.Coins`
@ -320,7 +321,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Improvements
* (baseapp) [\#10631](https://github.com/cosmos/cosmos-sdk/pull/10631) Emit ante events even for the failed txs.
* (baseapp) [\#10631](https://github.com/cosmos/cosmos-sdk/pull/10631) Emit ante events even for the failed txs.
* (store) [\#10741](https://github.com/cosmos/cosmos-sdk/pull/10741) Significantly speedup iterator creation after delete heavy workloads. Significantly improves IBC migration times.
### Bug Fixes

View File

@ -10,7 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking/types"
)
// return a specific delegation
// GetDelegation returns a specific delegation.
func (k Keeper) GetDelegation(ctx sdk.Context,
delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation types.Delegation, found bool) {
store := ctx.KVStore(k.storeKey)
@ -26,7 +26,7 @@ func (k Keeper) GetDelegation(ctx sdk.Context,
return delegation, true
}
// IterateAllDelegations iterate through all of the delegations
// IterateAllDelegations iterates through all of the delegations.
func (k Keeper) IterateAllDelegations(ctx sdk.Context, cb func(delegation types.Delegation) (stop bool)) {
store := ctx.KVStore(k.storeKey)
@ -41,7 +41,7 @@ func (k Keeper) IterateAllDelegations(ctx sdk.Context, cb func(delegation types.
}
}
// GetAllDelegations returns all delegations used during genesis dump
// GetAllDelegations returns all delegations used during genesis dump.
func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegation) {
k.IterateAllDelegations(ctx, func(delegation types.Delegation) bool {
delegations = append(delegations, delegation)
@ -51,7 +51,8 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati
return delegations
}
// return all delegations to a specific validator. Useful for querier.
// GetValidatorDelegations returns all delegations to a specific validator.
// Useful for querier.
func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress) (delegations []types.Delegation) { //nolint:interfacer
store := ctx.KVStore(k.storeKey)
@ -68,7 +69,8 @@ func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress)
return delegations
}
// return a given amount of all the delegations from a delegator
// GetDelegatorDelegations returns a given amount of all the delegations from a
// delegator.
func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress,
maxRetrieve uint16) (delegations []types.Delegation) {
delegations = make([]types.Delegation, maxRetrieve)
@ -88,7 +90,7 @@ func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddres
return delegations[:i] // trim if the array length < maxRetrieve
}
// set a delegation
// SetDelegation sets a delegation.
func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
if err != nil {
@ -100,7 +102,7 @@ func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) {
store.Set(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr()), b)
}
// remove a delegation
// RemoveDelegation removes a delegation
func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) error {
delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
if err != nil {
@ -116,7 +118,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) e
return nil
}
// return a given amount of all the delegator unbonding-delegations
// GetUnbondingDelegations returns a given amount of all the delegator unbonding-delegations.
func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress,
maxRetrieve uint16) (unbondingDelegations []types.UnbondingDelegation) {
unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve)
@ -137,7 +139,7 @@ func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddres
return unbondingDelegations[:i] // trim if the array length < maxRetrieve
}
// return a unbonding delegation
// GetUnbondingDelegation returns a unbonding delegation.
func (k Keeper) GetUnbondingDelegation(
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress,
) (ubd types.UnbondingDelegation, found bool) {
@ -154,7 +156,8 @@ func (k Keeper) GetUnbondingDelegation(
return ubd, true
}
// return all unbonding delegations from a particular validator
// GetUnbondingDelegationsFromValidator returns all unbonding delegations from a
// particular validator.
func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAddress) (ubds []types.UnbondingDelegation) {
store := ctx.KVStore(k.storeKey)
@ -171,7 +174,7 @@ func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sd
return ubds
}
// iterate through all of the unbonding delegations
// IterateUnbondingDelegations iterates through all of the unbonding delegations.
func (k Keeper) IterateUnbondingDelegations(ctx sdk.Context, fn func(index int64, ubd types.UnbondingDelegation) (stop bool)) {
store := ctx.KVStore(k.storeKey)
@ -187,7 +190,85 @@ func (k Keeper) IterateUnbondingDelegations(ctx sdk.Context, fn func(index int64
}
}
// HasMaxUnbondingDelegationEntries - check if unbonding delegation has maximum number of entries
// GetDelegatorUnbonding returns the total amount a delegator has unbonding.
func (k Keeper) GetDelegatorUnbonding(ctx sdk.Context, delegator sdk.AccAddress) sdk.Int {
unbonding := sdk.ZeroInt()
k.IterateDelegatorUnbondingDelegations(ctx, delegator, func(ubd types.UnbondingDelegation) bool {
for _, entry := range ubd.Entries {
unbonding = unbonding.Add(entry.Balance)
}
return false
})
return unbonding
}
// IterateDelegatorUnbondingDelegations iterates through a delegator's unbonding delegations.
func (k Keeper) IterateDelegatorUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(ubd types.UnbondingDelegation) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, types.GetUBDsKey(delegator))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
ubd := types.MustUnmarshalUBD(k.cdc, iterator.Value())
if cb(ubd) {
break
}
}
}
// GetDelegatorBonded returs the total amount a delegator has bonded.
func (k Keeper) GetDelegatorBonded(ctx sdk.Context, delegator sdk.AccAddress) sdk.Int {
bonded := sdk.ZeroDec()
k.IterateDelegatorDelegations(ctx, delegator, func(delegation types.Delegation) bool {
validatorAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
if err != nil {
panic(err) // shouldn't happen
}
validator, found := k.GetValidator(ctx, validatorAddr)
if found {
shares := delegation.Shares
tokens := validator.TokensFromSharesTruncated(shares)
bonded = bonded.Add(tokens)
}
return false
})
return bonded.RoundInt()
}
// IterateDelegatorDelegations iterates through one delegator's delegations.
func (k Keeper) IterateDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(delegation types.Delegation) (stop bool)) {
store := ctx.KVStore(k.storeKey)
delegatorPrefixKey := types.GetDelegationsKey(delegator)
iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
delegation := types.MustUnmarshalDelegation(k.cdc, iterator.Value())
if cb(delegation) {
break
}
}
}
// IterateDelegatorRedelegations iterates through one delegator's redelegations.
func (k Keeper) IterateDelegatorRedelegations(ctx sdk.Context, delegator sdk.AccAddress, cb func(red types.Redelegation) (stop bool)) {
store := ctx.KVStore(k.storeKey)
delegatorPrefixKey := types.GetREDsKey(delegator)
iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
red := types.MustUnmarshalRED(k.cdc, iterator.Value())
if cb(red) {
break
}
}
}
// HasMaxUnbondingDelegationEntries - check if unbonding delegation has maximum number of entries.
func (k Keeper) HasMaxUnbondingDelegationEntries(ctx sdk.Context,
delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) bool {
ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
@ -198,7 +279,7 @@ func (k Keeper) HasMaxUnbondingDelegationEntries(ctx sdk.Context,
return len(ubd.Entries) >= int(k.MaxEntries(ctx))
}
// set the unbonding delegation and associated index
// SetUnbondingDelegation sets the unbonding delegation and associated index.
func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress)
if err != nil {
@ -215,7 +296,7 @@ func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDeleg
store.Set(types.GetUBDByValIndexKey(delegatorAddress, addr), []byte{}) // index, store empty bytes
}
// remove the unbonding delegation object and associated index
// RemoveUnbondingDelegation removes the unbonding delegation object and associated index.
func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress)
if err != nil {
@ -233,7 +314,7 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe
}
// SetUnbondingDelegationEntry adds an entry to the unbonding delegation at
// the given addresses. It creates the unbonding delegation if it does not exist
// the given addresses. It creates the unbonding delegation if it does not exist.
func (k Keeper) SetUnbondingDelegationEntry(
ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
creationHeight int64, minTime time.Time, balance sdk.Int,
@ -252,8 +333,9 @@ func (k Keeper) SetUnbondingDelegationEntry(
// unbonding delegation queue timeslice operations
// gets a specific unbonding queue timeslice. A timeslice is a slice of DVPairs
// corresponding to unbonding delegations that expire at a certain time.
// GetUBDQueueTimeSlice gets a specific unbonding queue timeslice. A timeslice
// is a slice of DVPairs corresponding to unbonding delegations that expire at a
// certain time.
func (k Keeper) GetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvPairs []types.DVPair) {
store := ctx.KVStore(k.storeKey)
@ -268,14 +350,15 @@ func (k Keeper) GetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvPa
return pairs.Pairs
}
// Sets a specific unbonding queue timeslice.
// SetUBDQueueTimeSlice sets a specific unbonding queue timeslice.
func (k Keeper) SetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVPair) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshal(&types.DVPairs{Pairs: keys})
store.Set(types.GetUnbondingDelegationTimeKey(timestamp), bz)
}
// Insert an unbonding delegation to the appropriate timeslice in the unbonding queue
// InsertUBDQueue inserts an unbonding delegation to the appropriate timeslice
// in the unbonding queue.
func (k Keeper) InsertUBDQueue(ctx sdk.Context, ubd types.UnbondingDelegation,
completionTime time.Time) {
dvPair := types.DVPair{DelegatorAddress: ubd.DelegatorAddress, ValidatorAddress: ubd.ValidatorAddress}
@ -289,15 +372,15 @@ func (k Keeper) InsertUBDQueue(ctx sdk.Context, ubd types.UnbondingDelegation,
}
}
// Returns all the unbonding queue timeslices from time 0 until endTime
// UBDQueueIterator returns all the unbonding queue timeslices from time 0 until endTime.
func (k Keeper) UBDQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
store := ctx.KVStore(k.storeKey)
return store.Iterator(types.UnbondingQueueKey,
sdk.InclusiveEndBytes(types.GetUnbondingDelegationTimeKey(endTime)))
}
// Returns a concatenated list of all the timeslices inclusively previous to
// currTime, and deletes the timeslices from the queue
// DequeueAllMatureUBDQueue returns a concatenated list of all the timeslices inclusively previous to
// currTime, and deletes the timeslices from the queue.
func (k Keeper) DequeueAllMatureUBDQueue(ctx sdk.Context, currTime time.Time) (matureUnbonds []types.DVPair) {
store := ctx.KVStore(k.storeKey)
@ -318,7 +401,7 @@ func (k Keeper) DequeueAllMatureUBDQueue(ctx sdk.Context, currTime time.Time) (m
return matureUnbonds
}
// return a given amount of all the delegator redelegations
// GetRedelegations returns a given amount of all the delegator redelegations.
func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress,
maxRetrieve uint16) (redelegations []types.Redelegation) {
redelegations = make([]types.Redelegation, maxRetrieve)
@ -339,7 +422,7 @@ func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress,
return redelegations[:i] // trim if the array length < maxRetrieve
}
// return a redelegation
// GetRedelegation returns a redelegation.
func (k Keeper) GetRedelegation(ctx sdk.Context,
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (red types.Redelegation, found bool) {
store := ctx.KVStore(k.storeKey)
@ -355,7 +438,8 @@ func (k Keeper) GetRedelegation(ctx sdk.Context,
return red, true
}
// return all redelegations from a particular validator
// GetRedelegationsFromSrcValidator returns all redelegations from a particular
// validator.
func (k Keeper) GetRedelegationsFromSrcValidator(ctx sdk.Context, valAddr sdk.ValAddress) (reds []types.Redelegation) {
store := ctx.KVStore(k.storeKey)
@ -372,7 +456,7 @@ func (k Keeper) GetRedelegationsFromSrcValidator(ctx sdk.Context, valAddr sdk.Va
return reds
}
// check if validator is receiving a redelegation
// HasReceivingRedelegation checks if validator is receiving a redelegation.
func (k Keeper) HasReceivingRedelegation(ctx sdk.Context,
delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) bool {
store := ctx.KVStore(k.storeKey)
@ -384,7 +468,7 @@ func (k Keeper) HasReceivingRedelegation(ctx sdk.Context,
return iterator.Valid()
}
// HasMaxRedelegationEntries - redelegation has maximum number of entries
// HasMaxRedelegationEntries checks if redelegation has maximum number of entries.
func (k Keeper) HasMaxRedelegationEntries(ctx sdk.Context,
delegatorAddr sdk.AccAddress, validatorSrcAddr,
validatorDstAddr sdk.ValAddress) bool {
@ -396,7 +480,7 @@ func (k Keeper) HasMaxRedelegationEntries(ctx sdk.Context,
return len(red.Entries) >= int(k.MaxEntries(ctx))
}
// set a redelegation and associated index
// SetRedelegation set a redelegation and associated index.
func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(red.DelegatorAddress)
if err != nil {
@ -419,8 +503,8 @@ func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) {
store.Set(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{})
}
// SetUnbondingDelegationEntry adds an entry to the unbonding delegation at
// the given addresses. It creates the unbonding delegation if it does not exist
// SetRedelegationEntry adds an entry to the unbonding delegation at the given
// addresses. It creates the unbonding delegation if it does not exist.
func (k Keeper) SetRedelegationEntry(ctx sdk.Context,
delegatorAddr sdk.AccAddress, validatorSrcAddr,
validatorDstAddr sdk.ValAddress, creationHeight int64,
@ -439,7 +523,7 @@ func (k Keeper) SetRedelegationEntry(ctx sdk.Context,
return red
}
// iterate through all redelegations
// IterateRedelegations iterates through all redelegations.
func (k Keeper) IterateRedelegations(ctx sdk.Context, fn func(index int64, red types.Redelegation) (stop bool)) {
store := ctx.KVStore(k.storeKey)
@ -455,7 +539,7 @@ func (k Keeper) IterateRedelegations(ctx sdk.Context, fn func(index int64, red t
}
}
// remove a redelegation object and associated index
// RemoveRedelegation removes a redelegation object and associated index.
func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(red.DelegatorAddress)
if err != nil {
@ -478,8 +562,9 @@ func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) {
// redelegation queue timeslice operations
// Gets a specific redelegation queue timeslice. A timeslice is a slice of DVVTriplets corresponding to redelegations
// that expire at a certain time.
// GetRedelegationQueueTimeSlice gets a specific redelegation queue timeslice. A
// timeslice is a slice of DVVTriplets corresponding to redelegations that
// expire at a certain time.
func (k Keeper) GetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvvTriplets []types.DVVTriplet) {
store := ctx.KVStore(k.storeKey)
@ -494,14 +579,15 @@ func (k Keeper) GetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Ti
return triplets.Triplets
}
// Sets a specific redelegation queue timeslice.
// SetRedelegationQueueTimeSlice sets a specific redelegation queue timeslice.
func (k Keeper) SetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVVTriplet) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshal(&types.DVVTriplets{Triplets: keys})
store.Set(types.GetRedelegationTimeKey(timestamp), bz)
}
// Insert an redelegation delegation to the appropriate timeslice in the redelegation queue
// InsertRedelegationQueue insert an redelegation delegation to the appropriate
// timeslice in the redelegation queue.
func (k Keeper) InsertRedelegationQueue(ctx sdk.Context, red types.Redelegation,
completionTime time.Time) {
timeSlice := k.GetRedelegationQueueTimeSlice(ctx, completionTime)
@ -518,14 +604,16 @@ func (k Keeper) InsertRedelegationQueue(ctx sdk.Context, red types.Redelegation,
}
}
// Returns all the redelegation queue timeslices from time 0 until endTime
// RedelegationQueueIterator returns all the redelegation queue timeslices from
// time 0 until endTime.
func (k Keeper) RedelegationQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
store := ctx.KVStore(k.storeKey)
return store.Iterator(types.RedelegationQueueKey, sdk.InclusiveEndBytes(types.GetRedelegationTimeKey(endTime)))
}
// Returns a concatenated list of all the timeslices inclusively previous to
// currTime, and deletes the timeslices from the queue
// DequeueAllMatureRedelegationQueue returns a concatenated list of all the
// timeslices inclusively previous to currTime, and deletes the timeslices from
// the queue.
func (k Keeper) DequeueAllMatureRedelegationQueue(ctx sdk.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet) {
store := ctx.KVStore(k.storeKey)
@ -636,7 +724,7 @@ func (k Keeper) Delegate(
return newShares, nil
}
// Unbond a particular delegation and perform associated store operations.
// Unbond unbonds a particular delegation and perform associated store operations.
func (k Keeper) Unbond(
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec,
) (amount sdk.Int, err error) {
@ -814,7 +902,8 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd
return balances, nil
}
// begin unbonding / redelegation; create a redelegation record
// BeginRedelegation begins unbonding / redelegation and creates a redelegation
// record.
func (k Keeper) BeginRedelegation(
ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec,
) (completionTime time.Time, err error) {

View File

@ -117,6 +117,11 @@ func TestDelegation(t *testing.T) {
require.Len(t, resDels, 2)
}
// test total bonded for single delegator
expBonded := bond1to1.Shares.Add(bond2to1.Shares).Add(bond1to3.Shares)
resDelBond := app.StakingKeeper.GetDelegatorBonded(ctx, addrDels[0])
require.Equal(t, expBonded, sdk.NewDecFromInt(resDelBond))
// delete a record
app.StakingKeeper.RemoveDelegation(ctx, bond2to3)
_, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[2])
@ -162,7 +167,8 @@ func TestUnbondingDelegation(t *testing.T) {
require.Equal(t, ubd, resUnbond)
// modify a records, save, and retrieve
ubd.Entries[0].Balance = sdk.NewInt(21)
expUnbond := sdk.NewInt(21)
ubd.Entries[0].Balance = expUnbond
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
resUnbonds := app.StakingKeeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
@ -175,6 +181,9 @@ func TestUnbondingDelegation(t *testing.T) {
require.True(t, found)
require.Equal(t, ubd, resUnbond)
resDelUnbond := app.StakingKeeper.GetDelegatorUnbonding(ctx, delAddrs[0])
require.Equal(t, expUnbond, resDelUnbond)
// delete a record
app.StakingKeeper.RemoveUnbondingDelegation(ctx, ubd)
_, found = app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])