cosmos-sdk/x/distribution/keeper/validator.go

163 lines
5.2 KiB
Go
Raw Normal View History

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"
)
// 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)
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
}
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)
b := k.cdc.MustMarshalBinaryLengthPrefixed(vdi)
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) {
// 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)
store.Delete(GetValidatorDistInfoKey(valAddr))
2018-09-17 20:02:15 -07:00
}
// remove all validator distribution infos
func (k Keeper) RemoveValidatorDistInfos(ctx sdk.Context) {
store := ctx.KVStore(k.storeKey)
iter := sdk.KVStorePrefixIterator(store, ValidatorDistInfoKey)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
store.Delete(iter.Key())
}
}
// iterate over all the validator distribution infos
func (k Keeper) IterateValidatorDistInfos(ctx sdk.Context,
fn func(index int64, distInfo types.ValidatorDistInfo) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iter := sdk.KVStorePrefixIterator(store, ValidatorDistInfoKey)
defer iter.Close()
index := int64(0)
for ; iter.Valid(); iter.Next() {
var vdi types.ValidatorDistInfo
k.cdc.MustUnmarshalBinaryLengthPrefixed(iter.Value(), &vdi)
if fn(index, vdi) {
return
}
index++
}
}
// 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
}
// takeValidatorFeePoolRewards updates the validator's distribution info
// from the global fee pool without withdrawing any rewards. This will be called
// from a onValidatorModified hook.
func (k Keeper) takeValidatorFeePoolRewards(ctx sdk.Context, operatorAddr sdk.ValAddress) sdk.Error {
if !k.HasValidatorDistInfo(ctx, operatorAddr) {
return types.ErrNoValidatorDistInfo(k.codespace)
}
accAddr := sdk.AccAddress(operatorAddr.Bytes())
// withdraw reward for self-delegation
if k.HasDelegationDistInfo(ctx, accAddr, operatorAddr) {
fp, vi, di, withdraw :=
k.withdrawDelegationReward(ctx, accAddr, operatorAddr)
k.SetFeePool(ctx, fp)
k.SetValidatorDistInfo(ctx, vi)
k.SetDelegationDistInfo(ctx, di)
k.WithdrawToDelegator(ctx, fp, accAddr, withdraw)
}
// withdrawal validator commission rewards
valInfo := k.GetValidatorDistInfo(ctx, operatorAddr)
wc := k.GetWithdrawContext(ctx, operatorAddr)
valInfo, feePool := valInfo.TakeFeePoolRewards(wc)
k.SetFeePool(ctx, feePool)
k.SetValidatorDistInfo(ctx, valInfo)
return nil
}
2018-09-17 20:02:15 -07:00
// withdrawal all the validator rewards including the commission
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
accAddr := sdk.AccAddress(operatorAddr.Bytes())
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)
wc := k.GetWithdrawContext(ctx, operatorAddr)
valInfo, feePool, commission := valInfo.WithdrawCommission(wc)
withdraw = withdraw.Plus(commission)
k.SetValidatorDistInfo(ctx, valInfo)
k.WithdrawToDelegator(ctx, feePool, accAddr, withdraw)
return nil
}
// 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)
}
// 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
}