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

* 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`

(cherry picked from commit b8270fc9ba)

# Conflicts:
#	CHANGELOG.md
#	x/staking/keeper/delegation.go

* fix RemoveDelegation method conflict

* fix CHANGELOG conflict

* add new PR in CHANGELOG

Co-authored-by: Daniel Burckhardt <daniel.m.burckhardt@gmail.com>
This commit is contained in:
mergify[bot] 2022-04-13 16:34:42 +02:00 committed by GitHub
parent 3f03714819
commit ac970f52be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 145 additions and 46 deletions

View File

@ -60,16 +60,17 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#11124](https://github.com/cosmos/cosmos-sdk/pull/11124) Add `GetAllVersions` to application store * [\#11124](https://github.com/cosmos/cosmos-sdk/pull/11124) Add `GetAllVersions` to application store
* (x/auth) [\#10880](https://github.com/cosmos/cosmos-sdk/pull/10880) Added a new query to the tx query service that returns a block with transactions fully decoded. * (x/auth) [\#10880](https://github.com/cosmos/cosmos-sdk/pull/10880) Added a new query to the tx query service that returns a block with transactions fully decoded.
* [#11314](https://github.com/cosmos/cosmos-sdk/pull/11314) Add state rollback command. * [#11314](https://github.com/cosmos/cosmos-sdk/pull/11314) Add state rollback command.
* (x/staking) [\#11596](https://github.com/cosmos/cosmos-sdk/pull/11596) Add (re)delegation getters
### Bug Fixes ### Bug Fixes
* [\#11354](https://github.com/cosmos/cosmos-sdk/pull/11355) Added missing pagination flag for `bank q total` query. * [\#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.
* (client) [\#11283](https://github.com/cosmos/cosmos-sdk/issues/11283) Support multiple keys for tx simulation and setting automatic gas for txs. * (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. * (store) [\#11177](https://github.com/cosmos/cosmos-sdk/pull/11177) Update the prune `everything` strategy to store the last two heights.
* (store) [\#11117](https://github.com/cosmos/cosmos-sdk/pull/11117) Fix data race in store trace component * (store) [\#11117](https://github.com/cosmos/cosmos-sdk/pull/11117) Fix data race in store trace component
* (x/authz) [\#11252](https://github.com/cosmos/cosmos-sdk/pull/11252) Allow insufficient funds error for authz simulation * (x/authz) [\#11252](https://github.com/cosmos/cosmos-sdk/pull/11252) Allow insufficient funds error for authz simulation
* (crypto) [\#11298](https://github.com/cosmos/cosmos-sdk/pull/11298) Fix cgo secp signature verification and update libscep256k1 library. * (crypto) [\#11298](https://github.com/cosmos/cosmos-sdk/pull/11298) Fix cgo secp signature verification and update libscep256k1 library.
### Improvements ### Improvements
@ -124,7 +125,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Bug Fixes ### 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`. * (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. * [#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` * [\#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`
@ -134,7 +135,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Improvements ### 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.
### Features ### Features

View File

@ -10,7 +10,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/cosmos-sdk/x/staking/types"
) )
// return a specific delegation // GetDelegation returns a specific delegation.
func (k Keeper) GetDelegation(ctx sdk.Context, func (k Keeper) GetDelegation(ctx sdk.Context,
delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation types.Delegation, found bool) { delAddr sdk.AccAddress, valAddr sdk.ValAddress) (delegation types.Delegation, found bool) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -26,7 +26,7 @@ func (k Keeper) GetDelegation(ctx sdk.Context,
return delegation, true 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)) { func (k Keeper) IterateAllDelegations(ctx sdk.Context, cb func(delegation types.Delegation) (stop bool)) {
store := ctx.KVStore(k.storeKey) 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) { func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegation) {
k.IterateAllDelegations(ctx, func(delegation types.Delegation) bool { k.IterateAllDelegations(ctx, func(delegation types.Delegation) bool {
delegations = append(delegations, delegation) delegations = append(delegations, delegation)
@ -51,7 +51,8 @@ func (k Keeper) GetAllDelegations(ctx sdk.Context) (delegations []types.Delegati
return delegations 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 func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress) (delegations []types.Delegation) { //nolint:interfacer
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -68,7 +69,8 @@ func (k Keeper) GetValidatorDelegations(ctx sdk.Context, valAddr sdk.ValAddress)
return delegations 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, func (k Keeper) GetDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress,
maxRetrieve uint16) (delegations []types.Delegation) { maxRetrieve uint16) (delegations []types.Delegation) {
delegations = make([]types.Delegation, maxRetrieve) 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 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) { func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress) delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
if err != nil { 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) 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) { func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress) delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
if err != nil { if err != nil {
@ -112,7 +114,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) {
store.Delete(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr())) store.Delete(types.GetDelegationKey(delegatorAddress, delegation.GetValidatorAddr()))
} }
// 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, func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddress,
maxRetrieve uint16) (unbondingDelegations []types.UnbondingDelegation) { maxRetrieve uint16) (unbondingDelegations []types.UnbondingDelegation) {
unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve) unbondingDelegations = make([]types.UnbondingDelegation, maxRetrieve)
@ -133,7 +135,7 @@ func (k Keeper) GetUnbondingDelegations(ctx sdk.Context, delegator sdk.AccAddres
return unbondingDelegations[:i] // trim if the array length < maxRetrieve return unbondingDelegations[:i] // trim if the array length < maxRetrieve
} }
// return a unbonding delegation // GetUnbondingDelegation returns a unbonding delegation.
func (k Keeper) GetUnbondingDelegation( func (k Keeper) GetUnbondingDelegation(
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress,
) (ubd types.UnbondingDelegation, found bool) { ) (ubd types.UnbondingDelegation, found bool) {
@ -150,7 +152,8 @@ func (k Keeper) GetUnbondingDelegation(
return ubd, true 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) { func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sdk.ValAddress) (ubds []types.UnbondingDelegation) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -167,7 +170,7 @@ func (k Keeper) GetUnbondingDelegationsFromValidator(ctx sdk.Context, valAddr sd
return ubds 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)) { func (k Keeper) IterateUnbondingDelegations(ctx sdk.Context, fn func(index int64, ubd types.UnbondingDelegation) (stop bool)) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -183,7 +186,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, func (k Keeper) HasMaxUnbondingDelegationEntries(ctx sdk.Context,
delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) bool { delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress) bool {
ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) ubd, found := k.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
@ -194,7 +275,7 @@ func (k Keeper) HasMaxUnbondingDelegationEntries(ctx sdk.Context,
return len(ubd.Entries) >= int(k.MaxEntries(ctx)) 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) { func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress) delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress)
if err != nil { if err != nil {
@ -211,7 +292,7 @@ func (k Keeper) SetUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDeleg
store.Set(types.GetUBDByValIndexKey(delegatorAddress, addr), []byte{}) // index, store empty bytes 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) { func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress) delegatorAddress, err := sdk.AccAddressFromBech32(ubd.DelegatorAddress)
if err != nil { if err != nil {
@ -229,7 +310,7 @@ func (k Keeper) RemoveUnbondingDelegation(ctx sdk.Context, ubd types.UnbondingDe
} }
// SetUnbondingDelegationEntry adds an entry to the unbonding delegation at // 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( func (k Keeper) SetUnbondingDelegationEntry(
ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress, ctx sdk.Context, delegatorAddr sdk.AccAddress, validatorAddr sdk.ValAddress,
creationHeight int64, minTime time.Time, balance sdk.Int, creationHeight int64, minTime time.Time, balance sdk.Int,
@ -248,8 +329,9 @@ func (k Keeper) SetUnbondingDelegationEntry(
// unbonding delegation queue timeslice operations // unbonding delegation queue timeslice operations
// gets a specific unbonding queue timeslice. A timeslice is a slice of DVPairs // GetUBDQueueTimeSlice gets a specific unbonding queue timeslice. A timeslice
// corresponding to unbonding delegations that expire at a certain time. // 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) { func (k Keeper) GetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvPairs []types.DVPair) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -264,14 +346,15 @@ func (k Keeper) GetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvPa
return pairs.Pairs 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) { func (k Keeper) SetUBDQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVPair) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshal(&types.DVPairs{Pairs: keys}) bz := k.cdc.MustMarshal(&types.DVPairs{Pairs: keys})
store.Set(types.GetUnbondingDelegationTimeKey(timestamp), bz) 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, func (k Keeper) InsertUBDQueue(ctx sdk.Context, ubd types.UnbondingDelegation,
completionTime time.Time) { completionTime time.Time) {
dvPair := types.DVPair{DelegatorAddress: ubd.DelegatorAddress, ValidatorAddress: ubd.ValidatorAddress} dvPair := types.DVPair{DelegatorAddress: ubd.DelegatorAddress, ValidatorAddress: ubd.ValidatorAddress}
@ -285,15 +368,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 { func (k Keeper) UBDQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
return store.Iterator(types.UnbondingQueueKey, return store.Iterator(types.UnbondingQueueKey,
sdk.InclusiveEndBytes(types.GetUnbondingDelegationTimeKey(endTime))) sdk.InclusiveEndBytes(types.GetUnbondingDelegationTimeKey(endTime)))
} }
// Returns a concatenated list of all the timeslices inclusively previous to // DequeueAllMatureUBDQueue returns a concatenated list of all the timeslices inclusively previous to
// currTime, and deletes the timeslices from the queue // currTime, and deletes the timeslices from the queue.
func (k Keeper) DequeueAllMatureUBDQueue(ctx sdk.Context, currTime time.Time) (matureUnbonds []types.DVPair) { func (k Keeper) DequeueAllMatureUBDQueue(ctx sdk.Context, currTime time.Time) (matureUnbonds []types.DVPair) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -314,7 +397,7 @@ func (k Keeper) DequeueAllMatureUBDQueue(ctx sdk.Context, currTime time.Time) (m
return matureUnbonds 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, func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress,
maxRetrieve uint16) (redelegations []types.Redelegation) { maxRetrieve uint16) (redelegations []types.Redelegation) {
redelegations = make([]types.Redelegation, maxRetrieve) redelegations = make([]types.Redelegation, maxRetrieve)
@ -335,7 +418,7 @@ func (k Keeper) GetRedelegations(ctx sdk.Context, delegator sdk.AccAddress,
return redelegations[:i] // trim if the array length < maxRetrieve return redelegations[:i] // trim if the array length < maxRetrieve
} }
// return a redelegation // GetRedelegation returns a redelegation.
func (k Keeper) GetRedelegation(ctx sdk.Context, func (k Keeper) GetRedelegation(ctx sdk.Context,
delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (red types.Redelegation, found bool) { delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress) (red types.Redelegation, found bool) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -351,7 +434,8 @@ func (k Keeper) GetRedelegation(ctx sdk.Context,
return red, true 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) { func (k Keeper) GetRedelegationsFromSrcValidator(ctx sdk.Context, valAddr sdk.ValAddress) (reds []types.Redelegation) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -368,7 +452,7 @@ func (k Keeper) GetRedelegationsFromSrcValidator(ctx sdk.Context, valAddr sdk.Va
return reds return reds
} }
// check if validator is receiving a redelegation // HasReceivingRedelegation checks if validator is receiving a redelegation.
func (k Keeper) HasReceivingRedelegation(ctx sdk.Context, func (k Keeper) HasReceivingRedelegation(ctx sdk.Context,
delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) bool { delAddr sdk.AccAddress, valDstAddr sdk.ValAddress) bool {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -380,7 +464,7 @@ func (k Keeper) HasReceivingRedelegation(ctx sdk.Context,
return iterator.Valid() 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, func (k Keeper) HasMaxRedelegationEntries(ctx sdk.Context,
delegatorAddr sdk.AccAddress, validatorSrcAddr, delegatorAddr sdk.AccAddress, validatorSrcAddr,
validatorDstAddr sdk.ValAddress) bool { validatorDstAddr sdk.ValAddress) bool {
@ -392,7 +476,7 @@ func (k Keeper) HasMaxRedelegationEntries(ctx sdk.Context,
return len(red.Entries) >= int(k.MaxEntries(ctx)) 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) { func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(red.DelegatorAddress) delegatorAddress, err := sdk.AccAddressFromBech32(red.DelegatorAddress)
if err != nil { if err != nil {
@ -415,8 +499,8 @@ func (k Keeper) SetRedelegation(ctx sdk.Context, red types.Redelegation) {
store.Set(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{}) store.Set(types.GetREDByValDstIndexKey(delegatorAddress, valSrcAddr, valDestAddr), []byte{})
} }
// SetUnbondingDelegationEntry adds an entry to the unbonding delegation at // SetRedelegationEntry adds an entry to the unbonding delegation at the given
// the given addresses. It creates the unbonding delegation if it does not exist // addresses. It creates the unbonding delegation if it does not exist.
func (k Keeper) SetRedelegationEntry(ctx sdk.Context, func (k Keeper) SetRedelegationEntry(ctx sdk.Context,
delegatorAddr sdk.AccAddress, validatorSrcAddr, delegatorAddr sdk.AccAddress, validatorSrcAddr,
validatorDstAddr sdk.ValAddress, creationHeight int64, validatorDstAddr sdk.ValAddress, creationHeight int64,
@ -435,7 +519,7 @@ func (k Keeper) SetRedelegationEntry(ctx sdk.Context,
return red 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)) { func (k Keeper) IterateRedelegations(ctx sdk.Context, fn func(index int64, red types.Redelegation) (stop bool)) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -451,7 +535,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) { func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) {
delegatorAddress, err := sdk.AccAddressFromBech32(red.DelegatorAddress) delegatorAddress, err := sdk.AccAddressFromBech32(red.DelegatorAddress)
if err != nil { if err != nil {
@ -474,8 +558,9 @@ func (k Keeper) RemoveRedelegation(ctx sdk.Context, red types.Redelegation) {
// redelegation queue timeslice operations // redelegation queue timeslice operations
// Gets a specific redelegation queue timeslice. A timeslice is a slice of DVVTriplets corresponding to redelegations // GetRedelegationQueueTimeSlice gets a specific redelegation queue timeslice. A
// that expire at a certain time. // 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) { func (k Keeper) GetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time) (dvvTriplets []types.DVVTriplet) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -490,14 +575,15 @@ func (k Keeper) GetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Ti
return triplets.Triplets 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) { func (k Keeper) SetRedelegationQueueTimeSlice(ctx sdk.Context, timestamp time.Time, keys []types.DVVTriplet) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshal(&types.DVVTriplets{Triplets: keys}) bz := k.cdc.MustMarshal(&types.DVVTriplets{Triplets: keys})
store.Set(types.GetRedelegationTimeKey(timestamp), bz) 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, func (k Keeper) InsertRedelegationQueue(ctx sdk.Context, red types.Redelegation,
completionTime time.Time) { completionTime time.Time) {
timeSlice := k.GetRedelegationQueueTimeSlice(ctx, completionTime) timeSlice := k.GetRedelegationQueueTimeSlice(ctx, completionTime)
@ -514,14 +600,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 { func (k Keeper) RedelegationQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
return store.Iterator(types.RedelegationQueueKey, sdk.InclusiveEndBytes(types.GetRedelegationTimeKey(endTime))) return store.Iterator(types.RedelegationQueueKey, sdk.InclusiveEndBytes(types.GetRedelegationTimeKey(endTime)))
} }
// Returns a concatenated list of all the timeslices inclusively previous to // DequeueAllMatureRedelegationQueue returns a concatenated list of all the
// currTime, and deletes the timeslices from the queue // 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) { func (k Keeper) DequeueAllMatureRedelegationQueue(ctx sdk.Context, currTime time.Time) (matureRedelegations []types.DVVTriplet) {
store := ctx.KVStore(k.storeKey) store := ctx.KVStore(k.storeKey)
@ -626,7 +714,7 @@ func (k Keeper) Delegate(
return newShares, nil 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( func (k Keeper) Unbond(
ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec, ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec,
) (amount sdk.Int, err error) { ) (amount sdk.Int, err error) {
@ -800,7 +888,8 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd
return balances, nil return balances, nil
} }
// begin unbonding / redelegation; create a redelegation record // BeginRedelegation begins unbonding / redelegation and creates a redelegation
// record.
func (k Keeper) BeginRedelegation( func (k Keeper) BeginRedelegation(
ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec, ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec,
) (completionTime time.Time, err error) { ) (completionTime time.Time, err error) {

View File

@ -107,6 +107,11 @@ func TestDelegation(t *testing.T) {
require.Len(t, resDels, 2) 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 // delete a record
app.StakingKeeper.RemoveDelegation(ctx, bond2to3) app.StakingKeeper.RemoveDelegation(ctx, bond2to3)
_, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[2]) _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[2])
@ -152,7 +157,8 @@ func TestUnbondingDelegation(t *testing.T) {
require.Equal(t, ubd, resUnbond) require.Equal(t, ubd, resUnbond)
// modify a records, save, and retrieve // 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) app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
resUnbonds := app.StakingKeeper.GetUnbondingDelegations(ctx, delAddrs[0], 5) resUnbonds := app.StakingKeeper.GetUnbondingDelegations(ctx, delAddrs[0], 5)
@ -165,6 +171,9 @@ func TestUnbondingDelegation(t *testing.T) {
require.True(t, found) require.True(t, found)
require.Equal(t, ubd, resUnbond) require.Equal(t, ubd, resUnbond)
resDelUnbond := app.StakingKeeper.GetDelegatorUnbonding(ctx, delAddrs[0])
require.Equal(t, expUnbond, resDelUnbond)
// delete a record // delete a record
app.StakingKeeper.RemoveUnbondingDelegation(ctx, ubd) app.StakingKeeper.RemoveUnbondingDelegation(ctx, ubd)
_, found = app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0]) _, found = app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0])