-
Notifications
You must be signed in to change notification settings - Fork 0
/
ante.go
64 lines (53 loc) · 2.12 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
package globalfee
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/furyanrasta/furya/x/globalfee/types"
)
var _ sdk.AnteDecorator = GlobalMinimumChainFeeDecorator{}
// paramSource is a read only subset of paramtypes.Subspace
type paramSource interface {
Get(ctx sdk.Context, key []byte, ptr interface{})
Has(ctx sdk.Context, key []byte) bool
}
// GlobalMinimumChainFeeDecorator Ante decorator that enforces a minimum fee set for all transactions.
// This minimum can be 0 though.
type GlobalMinimumChainFeeDecorator struct {
paramSource paramSource
}
// NewGlobalMinimumChainFeeDecorator constructor
func NewGlobalMinimumChainFeeDecorator(paramSpace paramtypes.Subspace) GlobalMinimumChainFeeDecorator {
if !paramSpace.HasKeyTable() {
panic("paramspace was not set up via module")
}
return GlobalMinimumChainFeeDecorator{
paramSource: paramSpace,
}
}
// AnteHandle method that performs custom pre- and post-processing.
func (g GlobalMinimumChainFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
if !simulate && g.paramSource.Has(ctx, types.ParamStoreKeyMinGasPrices) {
feeTx, ok := tx.(sdk.FeeTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx must be a sdk FeeTx")
}
var minGasPrices sdk.DecCoins
g.paramSource.Get(ctx, types.ParamStoreKeyMinGasPrices, &minGasPrices)
if !minGasPrices.IsZero() {
requiredFees := make(sdk.Coins, len(minGasPrices))
// Determine the required fees by multiplying each required minimum gas
// price by the gas limit, where fee = ceil(minGasPrice * gasLimit).
glDec := sdk.NewDec(int64(feeTx.GetGas()))
for i, gp := range minGasPrices {
fee := gp.Amount.Mul(glDec)
amount := fee.Ceil().RoundInt()
requiredFees[i] = sdk.NewCoin(gp.Denom, amount)
}
if !feeTx.GetFee().IsAnyGTE(requiredFees) {
return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "got: %s required: %s", feeTx.GetFee(), requiredFees)
}
}
}
return next(ctx, tx, simulate)
}