55// http://opensource.org/licenses/MIT>, at your option. You may not use this file except in
66// accordance with one or both of these licenses.
77
8- use std:: collections:: { HashMap , VecDeque } ;
8+ use std:: collections:: HashMap ;
99use std:: fmt;
1010use std:: future:: Future ;
1111use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
@@ -16,7 +16,7 @@ use base64::prelude::BASE64_STANDARD;
1616use base64:: Engine ;
1717use bitcoin:: { BlockHash , FeeRate , Network , OutPoint , Transaction , Txid } ;
1818use lightning:: chain:: chaininterface:: ConfirmationTarget as LdkConfirmationTarget ;
19- use lightning:: chain:: { BestBlock , Listen } ;
19+ use lightning:: chain:: { BestBlock as BlockLocator , Listen } ;
2020use lightning:: util:: ser:: Writeable ;
2121use lightning_block_sync:: gossip:: UtxoSource ;
2222use lightning_block_sync:: http:: { HttpClientError , JsonResponse } ;
@@ -25,7 +25,7 @@ use lightning_block_sync::poll::{ChainPoller, ChainTip, ValidatedBlockHeader};
2525use lightning_block_sync:: rest:: RestClient ;
2626use lightning_block_sync:: rpc:: { RpcClient , RpcClientError } ;
2727use lightning_block_sync:: {
28- BlockData , BlockHeaderData , BlockSource , BlockSourceError , BlockSourceErrorKind , Cache ,
28+ BlockData , BlockHeaderData , BlockSource , BlockSourceError , BlockSourceErrorKind , HeaderCache ,
2929 SpvClient ,
3030} ;
3131use serde:: Serialize ;
@@ -49,7 +49,6 @@ const CHAIN_POLLING_TIMEOUT_SECS: u64 = 10;
4949
5050pub ( super ) struct BitcoindChainSource {
5151 api_client : Arc < BitcoindClient > ,
52- header_cache : tokio:: sync:: Mutex < BoundedHeaderCache > ,
5352 latest_chain_tip : RwLock < Option < ValidatedBlockHeader > > ,
5453 wallet_polling_status : Mutex < WalletSyncStatus > ,
5554 fee_estimator : Arc < OnchainFeeEstimator > ,
@@ -72,12 +71,10 @@ impl BitcoindChainSource {
7271 rpc_password. clone ( ) ,
7372 ) ) ;
7473
75- let header_cache = tokio:: sync:: Mutex :: new ( BoundedHeaderCache :: new ( ) ) ;
7674 let latest_chain_tip = RwLock :: new ( None ) ;
7775 let wallet_polling_status = Mutex :: new ( WalletSyncStatus :: Completed ) ;
7876 Self {
7977 api_client,
80- header_cache,
8178 latest_chain_tip,
8279 wallet_polling_status,
8380 fee_estimator,
@@ -103,13 +100,11 @@ impl BitcoindChainSource {
103100 rpc_password,
104101 ) ) ;
105102
106- let header_cache = tokio:: sync:: Mutex :: new ( BoundedHeaderCache :: new ( ) ) ;
107103 let latest_chain_tip = RwLock :: new ( None ) ;
108104 let wallet_polling_status = Mutex :: new ( WalletSyncStatus :: Completed ) ;
109105
110106 Self {
111107 api_client,
112- header_cache,
113108 latest_chain_tip,
114109 wallet_polling_status,
115110 fee_estimator,
@@ -153,46 +148,43 @@ impl BitcoindChainSource {
153148 return ;
154149 }
155150
156- let channel_manager_best_block_hash = channel_manager . current_best_block ( ) . block_hash ;
157- let sweeper_best_block_hash = output_sweeper . current_best_block ( ) . block_hash ;
158- let onchain_wallet_best_block_hash = onchain_wallet . current_best_block ( ) . block_hash ;
151+ let onchain_wallet_best_block = onchain_wallet . current_best_block ( ) ;
152+ let channel_manager_best_block = channel_manager . current_best_block ( ) ;
153+ let sweeper_best_block = output_sweeper . current_best_block ( ) ;
159154
160155 let mut chain_listeners = vec ! [
161- ( onchain_wallet_best_block_hash , & * onchain_wallet as & ( dyn Listen + Send + Sync ) ) ,
162- ( channel_manager_best_block_hash , & * channel_manager as & ( dyn Listen + Send + Sync ) ) ,
163- ( sweeper_best_block_hash , & * output_sweeper as & ( dyn Listen + Send + Sync ) ) ,
156+ ( onchain_wallet_best_block , & * onchain_wallet as & ( dyn Listen + Send + Sync ) ) ,
157+ ( channel_manager_best_block , & * channel_manager as & ( dyn Listen + Send + Sync ) ) ,
158+ ( sweeper_best_block , & * output_sweeper as & ( dyn Listen + Send + Sync ) ) ,
164159 ] ;
165160
166161 // TODO: Eventually we might want to see if we can synchronize `ChannelMonitor`s
167162 // before giving them to `ChainMonitor` it the first place. However, this isn't
168163 // trivial as we load them on initialization (in the `Builder`) and only gain
169164 // network access during `start`. For now, we just make sure we get the worst known
170165 // block hash and sychronize them via `ChainMonitor`.
171- if let Some ( worst_channel_monitor_block_hash ) = chain_monitor
166+ if let Some ( worst_channel_monitor_best_block ) = chain_monitor
172167 . list_monitors ( )
173168 . iter ( )
174169 . flat_map ( |channel_id| chain_monitor. get_monitor ( * channel_id) )
175170 . map ( |m| m. current_best_block ( ) )
176171 . min_by_key ( |b| b. height )
177- . map ( |b| b. block_hash )
178172 {
179173 chain_listeners. push ( (
180- worst_channel_monitor_block_hash ,
174+ worst_channel_monitor_best_block ,
181175 & * chain_monitor as & ( dyn Listen + Send + Sync ) ,
182176 ) ) ;
183177 }
184178
185- let mut locked_header_cache = self . header_cache . lock ( ) . await ;
186179 let now = SystemTime :: now ( ) ;
187180 match synchronize_listeners (
188181 self . api_client . as_ref ( ) ,
189182 self . config . network ,
190- & mut * locked_header_cache,
191183 chain_listeners. clone ( ) ,
192184 )
193185 . await
194186 {
195- Ok ( chain_tip) => {
187+ Ok ( ( _header_cache , chain_tip) ) => {
196188 {
197189 let elapsed_ms = now. elapsed ( ) . map ( |d| d. as_millis ( ) ) . unwrap_or ( 0 ) ;
198190 log_info ! (
@@ -333,7 +325,7 @@ impl BitcoindChainSource {
333325 }
334326 }
335327
336- pub ( super ) async fn poll_best_block ( & self ) -> Result < BestBlock , Error > {
328+ pub ( super ) async fn poll_best_block ( & self ) -> Result < BlockLocator , Error > {
337329 self . poll_chain_tip ( ) . await . map ( |tip| tip. to_best_block ( ) )
338330 }
339331
@@ -400,7 +392,6 @@ impl BitcoindChainSource {
400392 let chain_tip =
401393 if let Some ( tip) = latest_chain_tip_opt { tip } else { self . poll_chain_tip ( ) . await ? } ;
402394
403- let mut locked_header_cache = self . header_cache . lock ( ) . await ;
404395 let chain_poller = ChainPoller :: new ( Arc :: clone ( & self . api_client ) , self . config . network ) ;
405396 let chain_listener = ChainListener {
406397 onchain_wallet : Arc :: clone ( & onchain_wallet) ,
@@ -409,7 +400,7 @@ impl BitcoindChainSource {
409400 output_sweeper,
410401 } ;
411402 let mut spv_client =
412- SpvClient :: new ( chain_tip, chain_poller, & mut * locked_header_cache , & chain_listener) ;
403+ SpvClient :: new ( chain_tip, chain_poller, HeaderCache :: new ( ) , & chain_listener) ;
413404
414405 let now = SystemTime :: now ( ) ;
415406 match spv_client. poll_best_tip ( ) . await {
@@ -1350,46 +1341,6 @@ pub(crate) enum FeeRateEstimationMode {
13501341 Conservative ,
13511342}
13521343
1353- const MAX_HEADER_CACHE_ENTRIES : usize = 100 ;
1354-
1355- pub ( crate ) struct BoundedHeaderCache {
1356- header_map : HashMap < BlockHash , ValidatedBlockHeader > ,
1357- recently_seen : VecDeque < BlockHash > ,
1358- }
1359-
1360- impl BoundedHeaderCache {
1361- pub ( crate ) fn new ( ) -> Self {
1362- let header_map = HashMap :: new ( ) ;
1363- let recently_seen = VecDeque :: new ( ) ;
1364- Self { header_map, recently_seen }
1365- }
1366- }
1367-
1368- impl Cache for BoundedHeaderCache {
1369- fn look_up ( & self , block_hash : & BlockHash ) -> Option < & ValidatedBlockHeader > {
1370- self . header_map . get ( block_hash)
1371- }
1372-
1373- fn block_connected ( & mut self , block_hash : BlockHash , block_header : ValidatedBlockHeader ) {
1374- self . recently_seen . push_back ( block_hash) ;
1375- self . header_map . insert ( block_hash, block_header) ;
1376-
1377- if self . header_map . len ( ) >= MAX_HEADER_CACHE_ENTRIES {
1378- // Keep dropping old entries until we've actually removed a header entry.
1379- while let Some ( oldest_entry) = self . recently_seen . pop_front ( ) {
1380- if self . header_map . remove ( & oldest_entry) . is_some ( ) {
1381- break ;
1382- }
1383- }
1384- }
1385- }
1386-
1387- fn block_disconnected ( & mut self , block_hash : & BlockHash ) -> Option < ValidatedBlockHeader > {
1388- self . recently_seen . retain ( |e| e != block_hash) ;
1389- self . header_map . remove ( block_hash)
1390- }
1391- }
1392-
13931344pub ( crate ) struct ChainListener {
13941345 pub ( crate ) onchain_wallet : Arc < Wallet > ,
13951346 pub ( crate ) channel_manager : Arc < ChannelManager > ,
0 commit comments