github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/btc/alternativefeeprovider.go (about) 1 package btc 2 3 import ( 4 "fmt" 5 "math/big" 6 "sync" 7 "time" 8 9 "github.com/golang/glog" 10 "github.com/juju/errors" 11 "github.com/trezor/blockbook/bchain" 12 ) 13 14 type alternativeFeeProviderFee struct { 15 blocks int 16 feePerKB int 17 } 18 19 type alternativeFeeProvider struct { 20 fees []alternativeFeeProviderFee 21 lastSync time.Time 22 chain bchain.BlockChain 23 mux sync.Mutex 24 } 25 26 type alternativeFeeProviderInterface interface { 27 compareToDefault() 28 estimateFee(blocks int) (big.Int, error) 29 } 30 31 func (p *alternativeFeeProvider) compareToDefault() { 32 output := "" 33 for _, fee := range p.fees { 34 conservative, err := p.chain.(*BitcoinRPC).blockchainEstimateSmartFee(fee.blocks, true) 35 if err != nil { 36 glog.Error(err) 37 return 38 } 39 economical, err := p.chain.(*BitcoinRPC).blockchainEstimateSmartFee(fee.blocks, false) 40 if err != nil { 41 glog.Error(err) 42 return 43 } 44 output += fmt.Sprintf("Blocks %d: alternative %d, conservative %s, economical %s\n", fee.blocks, fee.feePerKB, conservative.String(), economical.String()) 45 } 46 glog.Info("alternativeFeeProviderCompareToDefault\n", output) 47 } 48 49 func (p *alternativeFeeProvider) estimateFee(blocks int) (big.Int, error) { 50 var r big.Int 51 p.mux.Lock() 52 defer p.mux.Unlock() 53 if len(p.fees) == 0 { 54 return r, errors.New("alternativeFeeProvider: no fees") 55 } 56 if p.lastSync.Before(time.Now().Add(time.Duration(-10) * time.Minute)) { 57 return r, errors.Errorf("alternativeFeeProvider: Missing recent value, last sync at %v", p.lastSync) 58 } 59 for i := range p.fees { 60 if p.fees[i].blocks >= blocks { 61 r = *big.NewInt(int64(p.fees[i].feePerKB)) 62 return r, nil 63 } 64 } 65 // use the last value as fallback 66 r = *big.NewInt(int64(p.fees[len(p.fees)-1].feePerKB)) 67 return r, nil 68 }