This repository has been archived by the owner on Sep 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgas.go
125 lines (117 loc) · 2.83 KB
/
gas.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
package seth
import (
"context"
"math/big"
"github.com/montanaflynn/stats"
)
// GasEstimator estimates gas prices
type GasEstimator struct {
Client *Client
BlockGasLimits []uint64
TransactionGasPrice []uint64
}
// NewGasEstimator creates a new gas estimator
func NewGasEstimator(c *Client) *GasEstimator {
return &GasEstimator{Client: c}
}
// Stats prints gas stats
func (m *GasEstimator) Stats(fromNumber uint64, priorityPerc float64) (GasSuggestions, error) {
bn, err := m.Client.Client.BlockNumber(context.Background())
if err != nil {
return GasSuggestions{}, err
}
hist, err := m.Client.Client.FeeHistory(context.Background(), fromNumber, big.NewInt(int64(bn)), []float64{priorityPerc})
if err != nil {
return GasSuggestions{}, err
}
baseFees := make([]float64, 0)
for _, bf := range hist.BaseFee {
if bf == nil {
bf = big.NewInt(0)
}
f := new(big.Float).SetInt(bf)
ff, _ := f.Float64()
baseFees = append(baseFees, ff)
}
gasPercs, err := quantilesFromFloatArray(baseFees)
if err != nil {
return GasSuggestions{}, err
}
tips := make([]float64, 0)
for _, bf := range hist.Reward {
if len(bf) == 0 {
continue
}
if bf[0] == nil {
bf[0] = big.NewInt(0)
}
f := new(big.Float).SetInt(bf[0])
ff, _ := f.Float64()
tips = append(tips, ff)
}
tipPercs, err := quantilesFromFloatArray(tips)
if err != nil {
return GasSuggestions{}, err
}
suggestedGasPrice, err := m.Client.Client.SuggestGasPrice(context.Background())
if err != nil {
return GasSuggestions{}, err
}
suggestedGasTipCap, err := m.Client.Client.SuggestGasTipCap(context.Background())
if err != nil {
return GasSuggestions{}, err
}
L.Trace().
Interface("History", hist).
Msg("Fee history")
return GasSuggestions{
GasPrice: gasPercs,
TipCap: tipPercs,
SuggestedGasPrice: suggestedGasPrice,
SuggestedGasTipCap: suggestedGasTipCap,
}, nil
}
// GasPercentiles contains gas percentiles
type GasPercentiles struct {
Max float64
Perc99 float64
Perc75 float64
Perc50 float64
Perc25 float64
}
type GasSuggestions struct {
GasPrice *GasPercentiles
TipCap *GasPercentiles
SuggestedGasPrice *big.Int
SuggestedGasTipCap *big.Int
}
// quantilesFromFloatArray calculates quantiles from a float array
func quantilesFromFloatArray(fa []float64) (*GasPercentiles, error) {
perMax, err := stats.Max(fa)
if err != nil {
return nil, err
}
perc99, err := stats.Percentile(fa, 99)
if err != nil {
return nil, err
}
perc75, err := stats.Percentile(fa, 75)
if err != nil {
return nil, err
}
perc50, err := stats.Percentile(fa, 50)
if err != nil {
return nil, err
}
perc25, err := stats.Percentile(fa, 25)
if err != nil {
return nil, err
}
return &GasPercentiles{
Max: perMax,
Perc99: perc99,
Perc75: perc75,
Perc50: perc50,
Perc25: perc25,
}, nil
}