-
Notifications
You must be signed in to change notification settings - Fork 15
/
estimatefees.go
104 lines (89 loc) · 2.54 KB
/
estimatefees.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
package main
import (
"encoding/json"
"errors"
"net/http"
"github.com/btcsuite/btcd/btcjson"
)
type EstimatedFees struct {
FeeRateFloor int `json:"feerate_floor"`
FeeRates []FeeRate `json:"feerates"`
}
type FeeRate struct {
Blocks int `json:"blocks"`
FeeRate int `json:"feerate"`
}
func getFeeRates(network string) (*EstimatedFees, error) {
if network == "regtest" {
return &EstimatedFees{
FeeRateFloor: 1000,
FeeRates: []FeeRate{
{Blocks: 2, FeeRate: 1000},
{Blocks: 6, FeeRate: 1000},
{Blocks: 12, FeeRate: 1000},
{Blocks: 100, FeeRate: 1000},
},
}, nil
}
// try bitcoind first
if bitcoind != nil {
in2, err2 := bitcoind.EstimateSmartFee(2, &btcjson.EstimateModeConservative)
in6, err6 := bitcoind.EstimateSmartFee(6, &btcjson.EstimateModeEconomical)
in12, err12 := bitcoind.EstimateSmartFee(12, &btcjson.EstimateModeEconomical)
in100, err100 := bitcoind.EstimateSmartFee(100, &btcjson.EstimateModeEconomical)
if err2 == nil && err6 == nil && err12 == nil && err100 == nil &&
in2.FeeRate != nil && in6.FeeRate != nil && in12.FeeRate != nil && in100.FeeRate != nil {
satPerKbP := func(r *btcjson.EstimateSmartFeeResult) int {
return int(*r.FeeRate * float64(100000000))
}
return &EstimatedFees{
FeeRateFloor: satPerKbP(in100),
FeeRates: []FeeRate{
{Blocks: 2, FeeRate: satPerKbP(in2)},
{Blocks: 6, FeeRate: satPerKbP(in6)},
{Blocks: 12, FeeRate: satPerKbP(in12)},
{Blocks: 100, FeeRate: satPerKbP(in100)},
},
}, nil
}
}
// then try explorers
// (just copy sauron here)
feerates, err := getFeeRatesFromEsplora()
if err != nil {
return nil, err
}
// actually let's be a little more patient here than sauron is
slow := int(feerates["504"] * 1000)
normal := int(feerates["10"] * 1000)
urgent := int(feerates["5"] * 1000)
veryUrgent := int(feerates["2"] * 1000)
return &EstimatedFees{
FeeRateFloor: slow,
FeeRates: []FeeRate{
{Blocks: 2, FeeRate: veryUrgent},
{Blocks: 5, FeeRate: urgent},
{Blocks: 10, FeeRate: normal},
{Blocks: 504, FeeRate: slow},
},
}, nil
}
func getFeeRatesFromEsplora() (feerates map[string]float64, err error) {
for _, endpoint := range esploras(network) {
w, errW := http.Get(endpoint + "/fee-estimates")
if errW != nil {
err = errW
continue
}
defer w.Body.Close()
if w.StatusCode >= 300 {
continue
}
if err := json.NewDecoder(w.Body).Decode(&feerates); err != nil {
continue
} else {
return feerates, nil
}
}
return nil, errors.New("none of the esploras returned usable responses")
}