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. * [#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 * [\#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. * [\#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. * (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. * (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. * [\#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. * [\#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. * [\#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`. * [\#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`. * [\#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). * (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). * (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/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`. * (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 ### 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. * (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. * (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/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 ### Bug Fixes
* [\#11558](https://github.com/cosmos/cosmos-sdk/pull/11558) Fix `--dry-run` not working when using tx command. * [\#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. * [\#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. * (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. * (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.
@ -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` * [#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 * [#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. * [\#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 * [\#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` * (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. 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 * [\#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`. * [\#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 ### Features
@ -310,7 +311,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`
@ -320,7 +321,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.
* (store) [\#10741](https://github.com/cosmos/cosmos-sdk/pull/10741) Significantly speedup iterator creation after delete heavy workloads. Significantly improves IBC migration times. * (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 ### Bug Fixes

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) error { func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) error {
delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress) delegatorAddress, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
if err != nil { if err != nil {
@ -116,7 +118,7 @@ func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) e
return nil 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, 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)
@ -137,7 +139,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) {
@ -154,7 +156,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)
@ -171,7 +174,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)
@ -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, 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)
@ -198,7 +279,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 {
@ -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 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 {
@ -233,7 +314,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,
@ -252,8 +333,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)
@ -268,14 +350,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}
@ -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 { 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)
@ -318,7 +401,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)
@ -339,7 +422,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)
@ -355,7 +438,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)
@ -372,7 +456,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)
@ -384,7 +468,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 {
@ -396,7 +480,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 {
@ -419,8 +503,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,
@ -439,7 +523,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)
@ -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) { 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 {
@ -478,8 +562,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)
@ -494,14 +579,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)
@ -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 { 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)
@ -636,7 +724,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) {
@ -814,7 +902,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

@ -117,6 +117,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])
@ -162,7 +167,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)
@ -175,6 +181,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])