-
Notifications
You must be signed in to change notification settings - Fork 109
/
abci.go
141 lines (111 loc) · 4.61 KB
/
abci.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package reward
import (
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
abci "github.com/tendermint/tendermint/abci/types"
multisigTypes "github.com/axelarnetwork/axelar-core/x/multisig/types"
"github.com/axelarnetwork/axelar-core/x/reward/exported"
"github.com/axelarnetwork/axelar-core/x/reward/types"
snapshot "github.com/axelarnetwork/axelar-core/x/snapshot/exported"
"github.com/axelarnetwork/utils/funcs"
"github.com/axelarnetwork/utils/slices"
)
// BeginBlocker is called at the beginning of every block
func BeginBlocker(ctx sdk.Context, _ abci.RequestBeginBlock, _ types.Rewarder) {}
// EndBlocker is called at the end of every block, process external chain voting inflation
func EndBlocker(ctx sdk.Context, _ abci.RequestEndBlock, k types.Rewarder, n types.Nexus, m types.Minter, s types.Staker, slasher types.Slasher, msig types.MultiSig, ss types.Snapshotter) []abci.ValidatorUpdate {
handleExternalChainVotingInflation(ctx, k, n, m, s, slasher, ss)
handleKeyMgmtInflation(ctx, k, m, s, slasher, msig, ss)
return nil
}
func addRewardsByConsensusPower(ctx sdk.Context, s types.Staker, rewardPool exported.RewardPool, validators []snapshot.ValidatorI, totalReward sdk.DecCoin) {
totalAmount := totalReward.Amount
denom := totalReward.Denom
validatorsWithConsensusPower := slices.Filter(validators, func(v snapshot.ValidatorI) bool {
return v.GetConsensusPower(s.PowerReduction(ctx)) > 0
})
totalConsensusPower := slices.Reduce(validatorsWithConsensusPower, sdk.ZeroInt(), func(total sdk.Int, v snapshot.ValidatorI) sdk.Int {
return total.AddRaw(v.GetConsensusPower(s.PowerReduction(ctx)))
})
slices.ForEach(validatorsWithConsensusPower, func(v snapshot.ValidatorI) {
// Each validator receives reward weighted by consensus power
amount := totalAmount.MulInt64(v.GetConsensusPower(s.PowerReduction(ctx))).QuoInt(totalConsensusPower).RoundInt()
rewardPool.AddReward(
v.GetOperator(),
sdk.NewCoin(denom, amount),
)
})
}
func excludeJailedOrTombstoned(ctx sdk.Context, slasher types.Slasher, v snapshot.ValidatorI) bool {
isTombstoned := func(v snapshot.ValidatorI) bool {
consAdd, err := v.GetConsAddr()
if err != nil {
return true
}
return slasher.IsTombstoned(ctx, consAdd)
}
filter := funcs.Or(
snapshot.ValidatorI.IsJailed,
isTombstoned,
)
return filter(v)
}
func handleKeyMgmtInflation(ctx sdk.Context, k types.Rewarder, m types.Minter, s types.Staker, slasher types.Slasher, mSig types.MultiSig, ss types.Snapshotter) {
rewardPool := k.GetPool(ctx, multisigTypes.ModuleName)
minter := m.GetMinter(ctx)
mintParams := m.GetParams(ctx)
totalAmount := minter.BlockProvision(mintParams).Amount.ToDec().Mul(k.GetParams(ctx).KeyMgmtRelativeInflationRate)
isKeygenParticipant := func(v snapshot.ValidatorI) bool {
proxy, isActive := ss.GetProxy(ctx, v.GetOperator())
return isActive && !mSig.HasOptedOut(ctx, proxy)
}
var validators []snapshot.ValidatorI
validatorIterFn := func(_ int64, validator stakingtypes.ValidatorI) bool {
if excludeJailedOrTombstoned(ctx, slasher, validator) {
return false
}
if !isKeygenParticipant(validator) {
return false
}
validators = append(validators, validator)
return false
}
s.IterateBondedValidatorsByPower(ctx, validatorIterFn)
addRewardsByConsensusPower(ctx, s, rewardPool, validators, sdk.NewDecCoinFromDec(mintParams.MintDenom, totalAmount))
}
func handleExternalChainVotingInflation(ctx sdk.Context, k types.Rewarder, n types.Nexus, m types.Minter, s types.Staker, slasher types.Slasher, ss types.Snapshotter) {
totalStakingSupply := m.StakingTokenSupply(ctx)
blocksPerYear := m.GetParams(ctx).BlocksPerYear
inflationRate := k.GetParams(ctx).ExternalChainVotingInflationRate
denom := m.GetParams(ctx).MintDenom
amountPerChain := totalStakingSupply.ToDec().Mul(inflationRate).QuoInt64(int64(blocksPerYear))
for _, chain := range n.GetChains(ctx) {
// ignore inactive chain
if !n.IsChainActivated(ctx, chain) {
continue
}
rewardPool := k.GetPool(ctx, chain.Name.String())
maintainers := n.GetChainMaintainers(ctx, chain)
if len(maintainers) == 0 {
continue
}
var validators []snapshot.ValidatorI
for _, maintainer := range maintainers {
v := s.Validator(ctx, maintainer)
if v == nil {
continue
}
if !v.IsBonded() {
continue
}
if excludeJailedOrTombstoned(ctx, slasher, v) {
continue
}
if _, isProxyActive := ss.GetProxy(ctx, v.GetOperator()); !isProxyActive {
continue
}
validators = append(validators, v)
}
addRewardsByConsensusPower(ctx, s, rewardPool, validators, sdk.NewDecCoinFromDec(denom, amountPerChain))
}
}