-
Notifications
You must be signed in to change notification settings - Fork 170
/
fee_utils.go
128 lines (109 loc) · 3.27 KB
/
fee_utils.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
package ante
import (
"encoding/json"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// ContainZeroCoins returns true if the given coins are empty or contain zero coins,
// Note that the coins denoms must be validated, see sdk.ValidateDenom
func ContainZeroCoins(coins sdk.Coins) bool {
if len(coins) == 0 {
return true
}
for _, coin := range coins {
if coin.IsZero() {
return true
}
}
return false
}
// PrettyPrint returns a pretty printed representation of the given coins.
func PrettyPrint(coins sdk.Coins) string {
arr := make([]string, len(coins))
for idx, coin := range coins {
arr[idx] = fmt.Sprintf("%s%s", coin.Amount.String(), coin.Denom)
}
bz, err := json.MarshalIndent(arr, "", " ")
if err != nil {
return ""
}
return string(bz)
}
// CombinedFeeRequirement returns the global fee and min_gas_price combined and sorted.
// Both globalFees and minGasPrices must be valid, but CombinedFeeRequirement
// does not validate them, so it may return 0denom.
// if globalfee is empty, CombinedFeeRequirement return sdk.Coins{}
func CombinedFeeRequirement(globalFees, minGasPrices sdk.Coins) sdk.Coins {
// empty min_gas_price
if len(minGasPrices) == 0 {
return globalFees
}
// empty global fee is not possible if we set default global fee
if len(globalFees) == 0 && len(minGasPrices) != 0 {
return sdk.Coins{}
}
// if min_gas_price denom is in globalfee, and the amount is higher than globalfee, add min_gas_price to allFees
var allFees sdk.Coins
for _, fee := range globalFees {
// min_gas_price denom in global fee
ok, c := Find(minGasPrices, fee.Denom)
if ok && c.Amount.GT(fee.Amount) {
allFees = append(allFees, c)
} else {
allFees = append(allFees, fee)
}
}
return allFees.Sort()
}
// Find replaces the functionality of Coins.Find from SDK v0.46.x
func Find(coins sdk.Coins, denom string) (bool, sdk.Coin) {
switch len(coins) {
case 0:
return false, sdk.Coin{}
case 1:
coin := coins[0]
if coin.Denom == denom {
return true, coin
}
return false, sdk.Coin{}
default:
midIdx := len(coins) / 2 // 2:1, 3:1, 4:2
coin := coins[midIdx]
switch {
case denom < coin.Denom:
return Find(coins[:midIdx], denom)
case denom == coin.Denom:
return true, coin
default:
return Find(coins[midIdx+1:], denom)
}
}
}
// splitCoinsByDenoms returns the given coins split in two whether
// their demon is or isn't found in the given denom map.
func splitCoinsByDenoms(feeCoins sdk.Coins, denomMap map[string]bool) (sdk.Coins, sdk.Coins) {
feeCoinsNonZeroDenom, feeCoinsZeroDenom := sdk.Coins{}, sdk.Coins{}
for _, fc := range feeCoins {
_, found := denomMap[fc.Denom]
if found {
feeCoinsZeroDenom = append(feeCoinsZeroDenom, fc)
} else {
feeCoinsNonZeroDenom = append(feeCoinsNonZeroDenom, fc)
}
}
return feeCoinsNonZeroDenom.Sort(), feeCoinsZeroDenom.Sort()
}
// getNonZeroFees returns the given fees nonzero coins
// and a map storing the zero coins's denoms
func getNonZeroFees(fees sdk.Coins) (sdk.Coins, map[string]bool) {
requiredFeesNonZero := sdk.Coins{}
requiredFeesZeroDenom := map[string]bool{}
for _, gf := range fees {
if gf.IsZero() {
requiredFeesZeroDenom[gf.Denom] = true
} else {
requiredFeesNonZero = append(requiredFeesNonZero, gf)
}
}
return requiredFeesNonZero.Sort(), requiredFeesZeroDenom
}