-
Notifications
You must be signed in to change notification settings - Fork 0
/
ante.go
164 lines (128 loc) · 4.02 KB
/
ante.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package fee
import (
sdk "github.com/ayher/anatha/types"
sdkerrors "github.com/ayher/anatha/types/errors"
"github.com/ayher/anatha/x/auth/types"
"github.com/ayher/anatha/x/bank"
"github.com/ayher/anatha/x/supply"
"github.com/ayher/project-anatha/config"
types2 "github.com/ayher/project-anatha/x/fee/internal/types"
"github.com/ayher/project-anatha/x/hra"
"github.com/ayher/project-anatha/x/treasury"
)
type FeeDecorator struct {
feeKeeper Keeper
bankKeeper bank.Keeper
hraKeeper hra.Keeper
supplyKeeper supply.Keeper
feeCollectorModule string
}
func NewFeeDecorator(fk Keeper, bk bank.Keeper, hk hra.Keeper, sk supply.Keeper, feeCollectorModule string) FeeDecorator {
if addr := sk.GetModuleAddress(feeCollectorModule); addr == nil {
panic("the fee collector module account has not been set")
}
return FeeDecorator{
feeKeeper: fk,
bankKeeper: bk,
hraKeeper: hk,
supplyKeeper: sk,
feeCollectorModule: feeCollectorModule,
}
}
func (d FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
stdTx, ok := tx.(types.StdTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a StdTx")
}
msgs := stdTx.GetMsgs()
feePayer := stdTx.FeePayer()
txFees := sdk.NewCoins()
systemFees := sdk.NewCoins()
namesOwnedCount := d.hraKeeper.GetNamesByAddressCount(ctx, feePayer)
credits := d.hraKeeper.GetCredits(ctx, feePayer)
for _, msg := range msgs {
msgFee := sdk.NewCoins()
switch msg := msg.(type) {
case hra.MsgRegisterName:
if namesOwnedCount == 0 {
namesOwnedCount++
credits = d.hraKeeper.AddressCredits(ctx)
}
msgFee = msgFee.Add(d.hraKeeper.NameInfoRegistrationFee(ctx)...)
case hra.MsgRenewName:
msgFee = msgFee.Add(d.hraKeeper.NameInfoRenewalFee(ctx)...)
case hra.MsgBuyName:
fee, err := d.hraKeeper.GetPrice(ctx, msg.Name)
if err != nil {
return ctx, err
}
if namesOwnedCount == 0 {
namesOwnedCount++
credits = d.hraKeeper.AddressCredits(ctx)
}
msgFee = msgFee.Add(fee...)
case hra.MsgRegisterAddress:
if credits.LTE(sdk.ZeroInt()) {
msgFee = msgFee.Add(d.hraKeeper.AddressRegistrationFee(ctx)...)
}
credits = credits.Sub(sdk.OneInt())
case hra.MsgTransferName:
if namesOwnedCount == 1 {
namesOwnedCount--
credits = sdk.ZeroInt()
}
case hra.MsgDeleteName:
if namesOwnedCount == 1 {
namesOwnedCount--
credits = sdk.ZeroInt()
}
case bank.MsgSend:
msgFee = msgFee.Add(msg.Amount...)
case bank.MsgMultiSend:
for _, input := range msg.Inputs {
msgFee = msgFee.Add(input.Coins...)
}
case treasury.MsgCreateSellOrder:
msgFee = msgFee.Add(msg.Amount...)
}
txFees = txFees.Add(msgFee...)
if ! d.feeKeeper.IsMessageFeeExcluded(ctx, msg) {
systemFees = systemFees.Add(d.CalculateSystemFee(ctx, msgFee)...)
}
}
totalFees := txFees.Add(systemFees...)
if ! d.bankKeeper.HasCoins(ctx, feePayer, totalFees) {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; required: %s", totalFees)
}
err = d.supplyKeeper.SendCoinsFromAccountToModule(
ctx,
feePayer,
d.feeCollectorModule,
systemFees, // we deduct only system fees in the ante handler!
)
if err != nil {
return ctx, err
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types2.AttributeValueModule,
sdk.NewAttribute(types2.AttributeKeyTotalFee, totalFees.String()),
sdk.NewAttribute(types2.AttributeKeySystemFee, systemFees.String()),
),
)
return next(ctx, tx, simulate)
}
func (d FeeDecorator) CalculateSystemFee(ctx sdk.Context, txFee sdk.Coins) sdk.Coins {
feePercentage := d.feeKeeper.FeePercentage(ctx)
systemFeeInt := txFee.AmountOf(config.DefaultDenom).ToDec().Mul(feePercentage).TruncateInt()
systemFee := sdk.NewCoins(sdk.NewCoin(config.DefaultDenom, systemFeeInt))
minimumFee := d.feeKeeper.MinimumFee(ctx)
maximumFee := d.feeKeeper.MaximumFee(ctx)
if systemFee.IsAllLT(minimumFee) {
return minimumFee
}
if systemFee.IsAllGT(maximumFee) {
return maximumFee
}
return systemFee
}