2018-09-04 23:41:17 -07:00
|
|
|
package keeper
|
|
|
|
|
|
|
|
import (
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/x/distribution/types"
|
|
|
|
)
|
|
|
|
|
2018-10-18 12:58:57 -07:00
|
|
|
// check whether a validator has distribution info
|
|
|
|
func (k Keeper) HasValidatorDistInfo(ctx sdk.Context,
|
|
|
|
operatorAddr sdk.ValAddress) (exists bool) {
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
|
|
|
return store.Has(GetValidatorDistInfoKey(operatorAddr))
|
|
|
|
}
|
|
|
|
|
2018-09-04 23:41:17 -07:00
|
|
|
// get the validator distribution info
|
|
|
|
func (k Keeper) GetValidatorDistInfo(ctx sdk.Context,
|
|
|
|
operatorAddr sdk.ValAddress) (vdi types.ValidatorDistInfo) {
|
|
|
|
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
|
|
|
|
2018-09-19 19:54:46 -07:00
|
|
|
b := store.Get(GetValidatorDistInfoKey(operatorAddr))
|
2018-09-04 23:41:17 -07:00
|
|
|
if b == nil {
|
2018-09-28 00:29:52 -07:00
|
|
|
panic("Stored validator-distribution info should not have been nil")
|
2018-09-04 23:41:17 -07:00
|
|
|
}
|
|
|
|
|
2018-11-04 18:28:38 -08:00
|
|
|
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &vdi)
|
2018-09-04 23:41:17 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the validator distribution info
|
|
|
|
func (k Keeper) SetValidatorDistInfo(ctx sdk.Context, vdi types.ValidatorDistInfo) {
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
2018-11-04 18:28:38 -08:00
|
|
|
b := k.cdc.MustMarshalBinaryLengthPrefixed(vdi)
|
2018-09-19 19:54:46 -07:00
|
|
|
store.Set(GetValidatorDistInfoKey(vdi.OperatorAddr), b)
|
2018-09-04 23:41:17 -07:00
|
|
|
}
|
|
|
|
|
2018-09-17 20:02:15 -07:00
|
|
|
// remove a validator distribution info
|
|
|
|
func (k Keeper) RemoveValidatorDistInfo(ctx sdk.Context, valAddr sdk.ValAddress) {
|
2018-11-26 04:13:47 -08:00
|
|
|
|
|
|
|
// defensive check
|
|
|
|
vdi := k.GetValidatorDistInfo(ctx, valAddr)
|
|
|
|
if vdi.DelAccum.Accum.IsPositive() {
|
|
|
|
panic("Should not delete validator with unwithdrawn delegator accum")
|
|
|
|
}
|
|
|
|
|
2018-09-17 20:02:15 -07:00
|
|
|
store := ctx.KVStore(k.storeKey)
|
2018-09-19 19:54:46 -07:00
|
|
|
store.Delete(GetValidatorDistInfoKey(valAddr))
|
2018-09-17 20:02:15 -07:00
|
|
|
}
|
|
|
|
|
2018-10-26 04:42:53 -07:00
|
|
|
// Get the calculated accum of a validator at the current block
|
|
|
|
// without affecting the state.
|
|
|
|
func (k Keeper) GetValidatorAccum(ctx sdk.Context, operatorAddr sdk.ValAddress) (sdk.Dec, sdk.Error) {
|
|
|
|
if !k.HasValidatorDistInfo(ctx, operatorAddr) {
|
|
|
|
return sdk.Dec{}, types.ErrNoValidatorDistInfo(k.codespace)
|
|
|
|
}
|
|
|
|
|
|
|
|
// withdraw self-delegation
|
|
|
|
height := ctx.BlockHeight()
|
|
|
|
lastValPower := k.stakeKeeper.GetLastValidatorPower(ctx, operatorAddr)
|
|
|
|
valInfo := k.GetValidatorDistInfo(ctx, operatorAddr)
|
|
|
|
accum := valInfo.GetValAccum(height, sdk.NewDecFromInt(lastValPower))
|
|
|
|
|
|
|
|
return accum, nil
|
|
|
|
}
|
|
|
|
|
2018-09-17 20:02:15 -07:00
|
|
|
// withdrawal all the validator rewards including the commission
|
2018-10-18 12:58:57 -07:00
|
|
|
func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context, operatorAddr sdk.ValAddress) sdk.Error {
|
|
|
|
|
|
|
|
if !k.HasValidatorDistInfo(ctx, operatorAddr) {
|
|
|
|
return types.ErrNoValidatorDistInfo(k.codespace)
|
|
|
|
}
|
2018-09-04 23:41:17 -07:00
|
|
|
|
|
|
|
// withdraw self-delegation
|
2018-09-19 19:54:46 -07:00
|
|
|
accAddr := sdk.AccAddress(operatorAddr.Bytes())
|
2018-10-26 04:42:53 -07:00
|
|
|
withdraw := k.withdrawDelegationRewardsAll(ctx, accAddr)
|
2018-09-04 23:41:17 -07:00
|
|
|
|
|
|
|
// withdrawal validator commission rewards
|
2018-09-13 23:35:02 -07:00
|
|
|
valInfo := k.GetValidatorDistInfo(ctx, operatorAddr)
|
2018-10-26 04:42:53 -07:00
|
|
|
wc := k.GetWithdrawContext(ctx, operatorAddr)
|
|
|
|
valInfo, feePool, commission := valInfo.WithdrawCommission(wc)
|
2018-09-19 19:54:46 -07:00
|
|
|
withdraw = withdraw.Plus(commission)
|
|
|
|
k.SetValidatorDistInfo(ctx, valInfo)
|
|
|
|
|
2018-10-26 04:42:53 -07:00
|
|
|
k.WithdrawToDelegator(ctx, feePool, accAddr, withdraw)
|
2018-10-18 12:58:57 -07:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-10-26 04:42:53 -07:00
|
|
|
// get all the validator rewards including the commission
|
|
|
|
func (k Keeper) CurrentValidatorRewardsAll(ctx sdk.Context, operatorAddr sdk.ValAddress) (sdk.Coins, sdk.Error) {
|
|
|
|
|
|
|
|
if !k.HasValidatorDistInfo(ctx, operatorAddr) {
|
|
|
|
return sdk.Coins{}, types.ErrNoValidatorDistInfo(k.codespace)
|
2018-10-18 12:58:57 -07:00
|
|
|
}
|
2018-10-26 04:42:53 -07:00
|
|
|
|
|
|
|
// withdraw self-delegation
|
|
|
|
accAddr := sdk.AccAddress(operatorAddr.Bytes())
|
|
|
|
withdraw := k.CurrentDelegationRewardsAll(ctx, accAddr)
|
|
|
|
|
|
|
|
// withdrawal validator commission rewards
|
|
|
|
valInfo := k.GetValidatorDistInfo(ctx, operatorAddr)
|
|
|
|
|
|
|
|
wc := k.GetWithdrawContext(ctx, operatorAddr)
|
|
|
|
commission := valInfo.CurrentCommissionRewards(wc)
|
|
|
|
withdraw = withdraw.Plus(commission)
|
|
|
|
truncated, _ := withdraw.TruncateDecimal()
|
|
|
|
return truncated, nil
|
2018-09-04 23:41:17 -07:00
|
|
|
}
|