@@ -10,10 +10,11 @@ use lightning::chain::chaininterface::{
10
10
use bdk:: blockchain:: { Blockchain , EsploraBlockchain } ;
11
11
use bdk:: database:: BatchDatabase ;
12
12
use bdk:: wallet:: AddressIndex ;
13
- use bdk:: { SignOptions , SyncOptions } ;
13
+ use bdk:: { FeeRate , SignOptions , SyncOptions } ;
14
14
15
15
use bitcoin:: { Script , Transaction } ;
16
16
17
+ use std:: collections:: HashMap ;
17
18
use std:: sync:: { Arc , Mutex } ;
18
19
19
20
pub struct Wallet < D >
24
25
blockchain : EsploraBlockchain ,
25
26
// A BDK on-chain wallet.
26
27
wallet : Mutex < bdk:: Wallet < D > > ,
28
+ // A cache storing the most recently retrieved fee rate estimations.
29
+ fee_rate_cache : Mutex < HashMap < ConfirmationTarget , FeeRate > > ,
27
30
logger : Arc < FilesystemLogger > ,
28
31
}
29
32
35
38
blockchain : EsploraBlockchain , wallet : bdk:: Wallet < D > , logger : Arc < FilesystemLogger > ,
36
39
) -> Self {
37
40
let wallet = Mutex :: new ( wallet) ;
38
- Self {
39
- blockchain,
40
- wallet,
41
- logger,
42
- }
41
+ let fee_rate_cache = Mutex :: new ( HashMap :: new ( ) ) ;
42
+ Self { blockchain, wallet, fee_rate_cache, logger }
43
43
}
44
44
45
45
pub ( crate ) async fn sync ( & self ) -> Result < ( ) , Error > {
@@ -91,11 +91,24 @@ where
91
91
D : BatchDatabase ,
92
92
{
93
93
fn get_est_sat_per_1000_weight ( & self , confirmation_target : ConfirmationTarget ) -> u32 {
94
+ let mut locked_fee_rate_cache = self . fee_rate_cache . lock ( ) . unwrap ( ) ;
94
95
let num_blocks = num_blocks_from_conf_target ( confirmation_target) ;
95
- let fallback_fee = fallback_fee_from_conf_target ( confirmation_target) ;
96
- self . blockchain . estimate_fee ( num_blocks) . map_or ( fallback_fee, |fee_rate| {
97
- ( fee_rate. fee_wu ( 1000 ) as u32 ) . max ( FEERATE_FLOOR_SATS_PER_KW )
98
- } ) as u32
96
+
97
+ // We'll fall back on this, if we really don't have any other information.
98
+ let fallback_rate = fallback_fee_from_conf_target ( confirmation_target) ;
99
+
100
+ let fee_rate = match self . blockchain . estimate_fee ( num_blocks) {
101
+ Ok ( rate) => {
102
+ locked_fee_rate_cache. insert ( confirmation_target, rate) ;
103
+ rate. fee_wu ( 1000 ) as u32
104
+ }
105
+ Err ( _) => locked_fee_rate_cache
106
+ . get ( & confirmation_target)
107
+ . map_or ( fallback_rate, |cached_rate| cached_rate. fee_wu ( 1000 ) as u32 ) ,
108
+ } ;
109
+
110
+ // Never go lower than the floor.
111
+ fee_rate. max ( FEERATE_FLOOR_SATS_PER_KW )
99
112
}
100
113
}
101
114
0 commit comments