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

147 lines
5.3 KiB
Go
Raw Normal View History

package keeper
2018-09-17 20:02:15 -07:00
2018-09-18 09:46:04 -07:00
import (
"fmt"
2018-09-18 09:46:04 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
)
2018-09-13 23:35:02 -07:00
// Create a new validator distribution record
func (k Keeper) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
2018-09-17 20:02:15 -07:00
// defensive check for existence
if k.HasValidatorDistInfo(ctx, valAddr) {
panic("validator dist info already exists (not cleaned up properly)")
}
2018-09-17 20:02:15 -07:00
height := ctx.BlockHeight()
vdi := types.ValidatorDistInfo{
OperatorAddr: valAddr,
FeePoolWithdrawalHeight: height,
2018-10-23 06:50:35 -07:00
DelAccum: types.NewTotalAccum(height),
DelPool: types.DecCoins{},
ValCommission: types.DecCoins{},
2018-09-17 20:02:15 -07:00
}
k.SetValidatorDistInfo(ctx, vdi)
}
// Withdraw all validator rewards
func (k Keeper) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
// Move the validator's rewards from the global pool to the validator's pools
// (dist info), but without actually withdrawing the rewards. This does not
// need to happen during the genesis block.
2018-10-22 17:49:53 -07:00
if ctx.BlockHeight() > 0 {
if err := k.takeValidatorFeePoolRewards(ctx, valAddr); err != nil {
2018-10-22 17:49:53 -07:00
panic(err)
}
}
2018-09-17 20:02:15 -07:00
}
// Withdraw all validator rewards
func (k Keeper) AfterValidatorBonded(ctx sdk.Context, valAddr sdk.ValAddress) {
2019-01-11 12:08:01 -08:00
lastPower := k.stakingKeeper.GetLastValidatorPower(ctx, valAddr)
if !lastPower.Equal(sdk.ZeroInt()) {
panic("expected last power to be 0 for validator entering bonded state")
}
k.BeforeValidatorModified(ctx, valAddr)
}
// Sanity check, very useful!
func (k Keeper) AfterValidatorPowerDidChange(ctx sdk.Context, valAddr sdk.ValAddress) {
vi := k.GetValidatorDistInfo(ctx, valAddr)
if vi.FeePoolWithdrawalHeight != ctx.BlockHeight() {
panic(fmt.Sprintf("expected validator (%v) dist info FeePoolWithdrawalHeight to be updated to %v, but was %v.",
valAddr.String(), ctx.BlockHeight(), vi.FeePoolWithdrawalHeight))
}
}
2018-09-17 20:02:15 -07:00
// Withdrawal all validator distribution rewards and cleanup the distribution record
func (k Keeper) AfterValidatorRemoved(ctx sdk.Context, valAddr sdk.ValAddress) {
k.RemoveValidatorDistInfo(ctx, valAddr)
2018-09-17 20:02:15 -07:00
}
//_________________________________________________________________________________________
2018-09-18 09:46:04 -07:00
// Create a new delegator distribution record
func (k Keeper) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress,
2018-09-18 09:46:04 -07:00
valAddr sdk.ValAddress) {
2018-10-05 17:32:06 -07:00
ddi := types.DelegationDistInfo{
DelegatorAddr: delAddr,
ValOperatorAddr: valAddr,
DelPoolWithdrawalHeight: ctx.BlockHeight(),
2018-09-13 23:35:02 -07:00
}
2018-10-05 17:32:06 -07:00
k.SetDelegationDistInfo(ctx, ddi)
2018-09-13 23:35:02 -07:00
}
2018-09-18 09:46:04 -07:00
// Withdrawal all validator rewards
func (k Keeper) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress,
2018-09-18 09:46:04 -07:00
valAddr sdk.ValAddress) {
2018-09-13 23:35:02 -07:00
if err := k.WithdrawDelegationReward(ctx, delAddr, valAddr); err != nil {
panic(err)
}
2018-09-13 23:35:02 -07:00
}
2018-09-18 09:46:04 -07:00
// Withdrawal all validator distribution rewards and cleanup the distribution record
func (k Keeper) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress,
2018-09-18 09:46:04 -07:00
valAddr sdk.ValAddress) {
// Withdraw validator commission when validator self-bond is removed.
// Because we maintain the invariant that all delegations must be removed
// before a validator is deleted, this ensures that commission will be withdrawn
// before the validator is deleted (and the corresponding ValidatorDistInfo removed).
// If we change other parts of the code such that a self-delegation might remain after
// a validator is deleted, this logic will no longer be safe.
// TODO: Consider instead implementing this in a "BeforeValidatorRemoved" hook.
if valAddr.Equals(sdk.ValAddress(delAddr)) {
feePool, commission := k.withdrawValidatorCommission(ctx, valAddr)
k.WithdrawToDelegator(ctx, feePool, delAddr, commission)
}
2018-09-13 23:35:02 -07:00
2018-10-05 17:32:06 -07:00
k.RemoveDelegationDistInfo(ctx, delAddr, valAddr)
2018-09-17 20:02:15 -07:00
}
//_________________________________________________________________________________________
2018-09-18 09:46:04 -07:00
// Wrapper struct
type Hooks struct {
2018-09-17 20:02:15 -07:00
k Keeper
}
2018-10-09 18:59:07 -07:00
var _ sdk.StakingHooks = Hooks{}
2018-09-18 14:54:28 -07:00
// New Validator Hooks
2018-09-19 21:53:48 -07:00
func (k Keeper) Hooks() Hooks { return Hooks{k} }
2018-09-18 14:54:28 -07:00
2018-09-17 20:02:15 -07:00
// nolint
func (h Hooks) AfterValidatorCreated(ctx sdk.Context, valAddr sdk.ValAddress) {
h.k.AfterValidatorCreated(ctx, valAddr)
2018-09-18 09:46:04 -07:00
}
func (h Hooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress) {
h.k.BeforeValidatorModified(ctx, valAddr)
2018-09-18 09:46:04 -07:00
}
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
h.k.AfterValidatorRemoved(ctx, valAddr)
2018-09-18 09:46:04 -07:00
}
func (h Hooks) BeforeDelegationCreated(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.k.BeforeValidatorModified(ctx, valAddr)
h.k.BeforeDelegationCreated(ctx, delAddr, valAddr)
2018-09-17 20:02:15 -07:00
}
func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.k.BeforeValidatorModified(ctx, valAddr)
h.k.BeforeDelegationSharesModified(ctx, delAddr, valAddr)
2018-09-17 20:02:15 -07:00
}
func (h Hooks) BeforeDelegationRemoved(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) {
h.k.BeforeDelegationRemoved(ctx, delAddr, valAddr)
2018-09-13 23:35:02 -07:00
}
func (h Hooks) AfterValidatorBeginUnbonding(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
h.k.BeforeValidatorModified(ctx, valAddr)
}
func (h Hooks) AfterValidatorBonded(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
h.k.AfterValidatorBonded(ctx, valAddr)
}
func (h Hooks) AfterValidatorPowerDidChange(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) {
h.k.AfterValidatorPowerDidChange(ctx, valAddr)
2018-10-22 19:48:28 -07:00
}