/
params.go
158 lines (129 loc) · 4.72 KB
/
params.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
package types
import (
"fmt"
"strings"
ibcclienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
ibcchanneltypes "github.com/cosmos/ibc-go/v4/modules/core/04-channel/types"
errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
gaiaerrors "github.com/cosmos/gaia/v14/types/errors"
)
var (
// ParamStoreKeyMinGasPrices store key
ParamStoreKeyMinGasPrices = []byte("MinimumGasPricesParam")
ParamStoreKeyBypassMinFeeMsgTypes = []byte("BypassMinFeeMsgTypes")
ParamStoreKeyMaxTotalBypassMinFeeMsgGasUsage = []byte("MaxTotalBypassMinFeeMsgGasUsage")
// DefaultMinGasPrices is set at runtime to the staking token with zero amount i.e. "0uatom"
// see DefaultZeroGlobalFee method in gaia/x/globalfee/ante/fee.go.
DefaultMinGasPrices = sdk.DecCoins{}
DefaultBypassMinFeeMsgTypes = []string{
sdk.MsgTypeURL(&ibcchanneltypes.MsgRecvPacket{}),
sdk.MsgTypeURL(&ibcchanneltypes.MsgAcknowledgement{}),
sdk.MsgTypeURL(&ibcclienttypes.MsgUpdateClient{}),
sdk.MsgTypeURL(&ibcchanneltypes.MsgTimeout{}),
sdk.MsgTypeURL(&ibcchanneltypes.MsgTimeoutOnClose{}),
}
// maxTotalBypassMinFeeMsgGasUsage is the allowed maximum gas usage
// for all the bypass msgs in a transactions.
// A transaction that contains only bypass message types and the gas usage does not
// exceed maxTotalBypassMinFeeMsgGasUsage can be accepted with a zero fee.
// For details, see gaiafeeante.NewFeeDecorator()
DefaultmaxTotalBypassMinFeeMsgGasUsage uint64 = 1_000_000
)
// DefaultParams returns default parameters
func DefaultParams() Params {
return Params{
MinimumGasPrices: DefaultMinGasPrices,
BypassMinFeeMsgTypes: DefaultBypassMinFeeMsgTypes,
MaxTotalBypassMinFeeMsgGasUsage: DefaultmaxTotalBypassMinFeeMsgGasUsage,
}
}
func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
}
// ValidateBasic performs basic validation.
func (p Params) ValidateBasic() error {
if err := validateMinimumGasPrices(p.MinimumGasPrices); err != nil {
return err
}
if err := validateBypassMinFeeMsgTypes(p.BypassMinFeeMsgTypes); err != nil {
return err
}
return validateMaxTotalBypassMinFeeMsgGasUsage(p.MaxTotalBypassMinFeeMsgGasUsage)
}
// ParamSetPairs returns the parameter set pairs.
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(
ParamStoreKeyMinGasPrices, &p.MinimumGasPrices, validateMinimumGasPrices,
),
paramtypes.NewParamSetPair(
ParamStoreKeyBypassMinFeeMsgTypes, &p.BypassMinFeeMsgTypes, validateBypassMinFeeMsgTypes,
),
paramtypes.NewParamSetPair(
ParamStoreKeyMaxTotalBypassMinFeeMsgGasUsage, &p.MaxTotalBypassMinFeeMsgGasUsage, validateMaxTotalBypassMinFeeMsgGasUsage,
),
}
}
func validateMinimumGasPrices(i interface{}) error {
v, ok := i.(sdk.DecCoins)
if !ok {
return errorsmod.Wrapf(gaiaerrors.ErrInvalidType, "type: %T, expected sdk.DecCoins", i)
}
dec := DecCoins(v)
return dec.Validate()
}
type BypassMinFeeMsgTypes []string
// validateBypassMinFeeMsgTypes checks that bypass msg types aren't empty
func validateBypassMinFeeMsgTypes(i interface{}) error {
bypassMinFeeMsgTypes, ok := i.([]string)
if !ok {
return errorsmod.Wrapf(gaiaerrors.ErrInvalidType, "type: %T, expected []sdk.Msg", i)
}
for _, msgType := range bypassMinFeeMsgTypes {
if msgType == "" {
return fmt.Errorf("invalid empty bypass msg type")
}
if !strings.HasPrefix(msgType, sdk.MsgTypeURL(nil)) {
return fmt.Errorf("invalid bypass msg type name %s", msgType)
}
}
return nil
}
func validateMaxTotalBypassMinFeeMsgGasUsage(i interface{}) error {
_, ok := i.(uint64)
if !ok {
return errorsmod.Wrapf(gaiaerrors.ErrInvalidType, "type: %T, expected uint64", i)
}
return nil
}
type DecCoins sdk.DecCoins
// Validate checks that the DecCoins are sorted, have nonnegtive amount, with a valid and unique
// denomination (i.e no duplicates). Otherwise, it returns an error.
func (coins DecCoins) Validate() error {
if len(coins) == 0 {
return nil
}
lowDenom := ""
seenDenoms := make(map[string]bool)
for i, coin := range coins {
if seenDenoms[coin.Denom] {
return fmt.Errorf("duplicate denomination %s", coin.Denom)
}
if err := sdk.ValidateDenom(coin.Denom); err != nil {
return err
}
// skip the denom order check for the first denom in the coins list
if i != 0 && coin.Denom <= lowDenom {
return fmt.Errorf("denomination %s is not sorted", coin.Denom)
}
if coin.IsNegative() {
return fmt.Errorf("coin %s amount is negative", coin.Amount)
}
// we compare each coin against the last denom
lowDenom = coin.Denom
seenDenoms[coin.Denom] = true
}
return nil
}