-
Notifications
You must be signed in to change notification settings - Fork 2
/
hooks.go
117 lines (91 loc) · 3.38 KB
/
hooks.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
distributiontypes "github.com/cvn-network/cvn/v2/x/distribution/types"
)
type Hooks struct {
keeper.Hooks
k Keeper
}
var _ stakingtypes.StakingHooks = Hooks{}
// Hooks create new distribution hooks
func (k Keeper) Hooks() Hooks {
return Hooks{
Hooks: k.Keeper.Hooks(),
k: k,
}
}
// AfterValidatorRemoved performs clean up after a validator is removed
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, _ sdk.ConsAddress, valAddr sdk.ValAddress) error {
// fetch outstanding
outstanding := h.k.GetValidatorOutstandingRewardsCoins(ctx, valAddr)
// force-withdraw commission
commission := h.k.GetValidatorAccumulatedCommission(ctx, valAddr).Commission
if !commission.IsZero() {
// subtract from outstanding
outstanding = outstanding.Sub(commission)
// split into integral & remainder
coins, remainder := commission.TruncateDecimal()
// remainder to community pool
feePool := h.k.GetFeePool(ctx)
feePool.CommunityPool = feePool.CommunityPool.Add(remainder...)
h.k.SetFeePool(ctx, feePool)
// add to validator account
if !coins.IsZero() {
accAddr := sdk.AccAddress(valAddr)
withdrawAddr := h.k.GetDelegatorWithdrawAddr(ctx, accAddr)
if err := h.k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, withdrawAddr, coins); err != nil {
return err
}
if err := h.k.AfterWithdrawValidatorCommission(ctx, valAddr, coins); err != nil {
return err
}
}
}
// Add outstanding to community pool
// The validator is removed only after it has no more delegations.
// This operation sends only the remaining dust to the community pool.
feePool := h.k.GetFeePool(ctx)
feePool.CommunityPool = feePool.CommunityPool.Add(outstanding...)
h.k.SetFeePool(ctx, feePool)
// delete outstanding
h.k.DeleteValidatorOutstandingRewards(ctx, valAddr)
// remove commission record
h.k.DeleteValidatorAccumulatedCommission(ctx, valAddr)
// clear slashes
h.k.DeleteValidatorSlashEvents(ctx, valAddr)
// clear historical rewards
h.k.DeleteValidatorHistoricalRewards(ctx, valAddr)
// clear current rewards
h.k.DeleteValidatorCurrentRewards(ctx, valAddr)
return nil
}
// BeforeDelegationSharesModified withdraw delegation rewards (which also increments period)
func (h Hooks) BeforeDelegationSharesModified(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
val := h.k.stakingKeeper.Validator(ctx, valAddr)
del := h.k.stakingKeeper.Delegation(ctx, delAddr, valAddr)
rewards, err := h.k.withdrawDelegationRewards(ctx, val, del)
if err != nil {
return err
}
if err = h.k.AfterWithdrawDelegationRewards(ctx, delAddr, valAddr, rewards); err != nil {
return err
}
return nil
}
var _ distributiontypes.DistributionHooks = Keeper{}
func (k Keeper) AfterWithdrawDelegationRewards(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, rewards sdk.Coins) error {
if k.hooks != nil {
return k.hooks.AfterWithdrawDelegationRewards(ctx, delAddr, valAddr, rewards)
}
return nil
}
func (k Keeper) AfterWithdrawValidatorCommission(ctx sdk.Context, valAddr sdk.ValAddress, commission sdk.Coins) error {
if k.hooks != nil {
return k.hooks.AfterWithdrawValidatorCommission(ctx, valAddr, commission)
}
return nil
}