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
|
|
|
}
|
|
|
|
|
|
|
|
k.cdc.MustUnmarshalBinary(b, &vdi)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// set the validator distribution info
|
|
|
|
func (k Keeper) SetValidatorDistInfo(ctx sdk.Context, vdi types.ValidatorDistInfo) {
|
|
|
|
store := ctx.KVStore(k.storeKey)
|
|
|
|
b := k.cdc.MustMarshalBinary(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) {
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// 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-10 15:37:58 -07:00
|
|
|
height := ctx.BlockHeight()
|
2018-09-19 21:53:48 -07:00
|
|
|
validator := k.stakeKeeper.Validator(ctx, operatorAddr)
|
2018-10-24 00:04:06 -07:00
|
|
|
lastValPower := sdk.NewDecFromInt(k.stakeKeeper.GetLastValidatorPower(ctx, operatorAddr))
|
2018-09-19 19:54:46 -07:00
|
|
|
accAddr := sdk.AccAddress(operatorAddr.Bytes())
|
2018-10-12 01:11:09 -07:00
|
|
|
withdraw := k.getDelegatorRewardsAll(ctx, accAddr, height)
|
2018-09-04 23:41:17 -07:00
|
|
|
|
|
|
|
// withdrawal validator commission rewards
|
2018-10-23 11:48:50 -07:00
|
|
|
lastTotalPower := sdk.NewDecFromInt(k.stakeKeeper.GetLastTotalPower(ctx))
|
2018-09-13 23:35:02 -07:00
|
|
|
valInfo := k.GetValidatorDistInfo(ctx, operatorAddr)
|
2018-09-10 15:37:58 -07:00
|
|
|
feePool := k.GetFeePool(ctx)
|
2018-10-22 01:18:10 -07:00
|
|
|
valInfo, feePool, commission := valInfo.WithdrawCommission(feePool, height, lastTotalPower,
|
|
|
|
lastValPower, validator.GetCommission())
|
2018-09-19 19:54:46 -07:00
|
|
|
withdraw = withdraw.Plus(commission)
|
|
|
|
k.SetValidatorDistInfo(ctx, valInfo)
|
|
|
|
|
|
|
|
withdrawAddr := k.GetDelegatorWithdrawAddr(ctx, accAddr)
|
2018-10-18 12:58:57 -07:00
|
|
|
truncated, change := withdraw.TruncateDecimal()
|
|
|
|
feePool.CommunityPool = feePool.CommunityPool.Plus(change)
|
|
|
|
k.SetFeePool(ctx, feePool)
|
|
|
|
_, _, err := k.bankKeeper.AddCoins(ctx, withdrawAddr, truncated)
|
2018-09-28 01:02:07 -07:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-10-18 12:58:57 -07:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-10-18 13:08:00 -07:00
|
|
|
// iterate over all the validator distribution infos (inefficient, just used to check invariants)
|
2018-10-18 12:58:57 -07:00
|
|
|
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.MustUnmarshalBinary(iter.Value(), &vdi)
|
|
|
|
if fn(index, vdi) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
index++
|
|
|
|
}
|
2018-09-04 23:41:17 -07:00
|
|
|
}
|