@@ -10,10 +10,11 @@ use lightning::chain::chaininterface::{
1010use bdk:: blockchain:: { Blockchain , EsploraBlockchain } ;
1111use bdk:: database:: BatchDatabase ;
1212use bdk:: wallet:: AddressIndex ;
13- use bdk:: { SignOptions , SyncOptions } ;
13+ use bdk:: { FeeRate , SignOptions , SyncOptions } ;
1414
1515use bitcoin:: { Script , Transaction } ;
1616
17+ use std:: collections:: HashMap ;
1718use std:: sync:: { Arc , Mutex } ;
1819
1920pub struct Wallet < D >
2425 blockchain : EsploraBlockchain ,
2526 // A BDK on-chain wallet.
2627 wallet : Mutex < bdk:: Wallet < D > > ,
28+ // A cache storing the most recently retrieved fee rate estimations.
29+ fee_rate_cache : Mutex < HashMap < ConfirmationTarget , FeeRate > > ,
2730 logger : Arc < FilesystemLogger > ,
2831}
2932
3538 blockchain : EsploraBlockchain , wallet : bdk:: Wallet < D > , logger : Arc < FilesystemLogger > ,
3639 ) -> Self {
3740 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 }
4343 }
4444
4545 pub ( crate ) async fn sync ( & self ) -> Result < ( ) , Error > {
@@ -91,11 +91,24 @@ where
9191 D : BatchDatabase ,
9292{
9393 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 ( ) ;
9495 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 )
99112 }
100113}
101114
0 commit comments