@@ -273,43 +273,76 @@ impl ChainSource {
273273 }
274274 }
275275
276- let channel_manager_best_block_hash =
276+ let mut channel_manager_best_block_hash =
277277 channel_manager. current_best_block ( ) . block_hash ;
278- let sweeper_best_block_hash = output_sweeper. current_best_block ( ) . block_hash ;
279- let onchain_wallet_best_block_hash = onchain_wallet. current_best_block ( ) . block_hash ;
280-
281- let mut chain_listeners = vec ! [
282- (
283- onchain_wallet_best_block_hash,
284- & * * onchain_wallet as & ( dyn Listen + Send + Sync ) ,
285- ) ,
286- (
287- channel_manager_best_block_hash,
288- & * channel_manager as & ( dyn Listen + Send + Sync ) ,
289- ) ,
290- ( sweeper_best_block_hash, & * output_sweeper as & ( dyn Listen + Send + Sync ) ) ,
291- ] ;
278+ let mut sweeper_best_block_hash = output_sweeper. current_best_block ( ) . block_hash ;
279+ let mut onchain_wallet_best_block_hash =
280+ onchain_wallet. current_best_block ( ) . block_hash ;
292281
293- // TODO: Eventually we might want to see if we can synchronize `ChannelMonitor`s
294- // before giving them to `ChainMonitor` it the first place. However, this isn't
295- // trivial as we load them on initialization (in the `Builder`) and only gain
296- // network access during `start`. For now, we just make sure we get the worst known
297- // block hash and sychronize them via `ChainMonitor`.
298- if let Some ( worst_channel_monitor_block_hash) = chain_monitor
299- . list_monitors ( )
300- . iter ( )
301- . flat_map ( |( txo, _) | chain_monitor. get_monitor ( * txo) )
302- . map ( |m| m. current_best_block ( ) )
303- . min_by_key ( |b| b. height )
304- . map ( |b| b. block_hash )
305- {
306- chain_listeners. push ( (
307- worst_channel_monitor_block_hash,
308- & * chain_monitor as & ( dyn Listen + Send + Sync ) ,
309- ) ) ;
310- }
282+ let genesis_block_hash =
283+ bitcoin:: blockdata:: constants:: genesis_block ( config. network ) . block_hash ( ) ;
284+
285+ ' initial_listener_sync: loop {
286+ if channel_manager_best_block_hash == genesis_block_hash
287+ && sweeper_best_block_hash == genesis_block_hash
288+ && onchain_wallet_best_block_hash == genesis_block_hash
289+ {
290+ // If all chain listeners are still at the genesis we're positive this is a
291+ // newly setup node that was never synced to tip before. So we query the best
292+ // tip and continue with it, avoiding to validate the entire header chain back to genesis.
293+ let chain_tip =
294+ match validate_best_block_header ( bitcoind_rpc_client. as_ref ( ) ) . await {
295+ Ok ( tip) => {
296+ * latest_chain_tip. write ( ) . unwrap ( ) = Some ( tip) ;
297+ tip
298+ } ,
299+ Err ( e) => {
300+ log_error ! ( logger, "Failed to poll for chain data: {:?}" , e) ;
301+ tokio:: time:: sleep ( Duration :: from_secs (
302+ CHAIN_POLLING_INTERVAL_SECS ,
303+ ) )
304+ . await ;
305+ continue ' initial_listener_sync;
306+ } ,
307+ } ;
308+
309+ let tip_hash = chain_tip. to_best_block ( ) . block_hash ;
310+ channel_manager_best_block_hash = tip_hash;
311+ sweeper_best_block_hash = tip_hash;
312+ onchain_wallet_best_block_hash = tip_hash;
313+ }
314+
315+ let mut chain_listeners = vec ! [
316+ (
317+ onchain_wallet_best_block_hash,
318+ & * * onchain_wallet as & ( dyn Listen + Send + Sync ) ,
319+ ) ,
320+ (
321+ channel_manager_best_block_hash,
322+ & * channel_manager as & ( dyn Listen + Send + Sync ) ,
323+ ) ,
324+ ( sweeper_best_block_hash, & * output_sweeper as & ( dyn Listen + Send + Sync ) ) ,
325+ ] ;
326+
327+ // TODO: Eventually we might want to see if we can synchronize `ChannelMonitor`s
328+ // before giving them to `ChainMonitor` it the first place. However, this isn't
329+ // trivial as we load them on initialization (in the `Builder`) and only gain
330+ // network access during `start`. For now, we just make sure we get the worst known
331+ // block hash and sychronize them via `ChainMonitor`.
332+ if let Some ( worst_channel_monitor_block_hash) = chain_monitor
333+ . list_monitors ( )
334+ . iter ( )
335+ . flat_map ( |( txo, _) | chain_monitor. get_monitor ( * txo) )
336+ . map ( |m| m. current_best_block ( ) )
337+ . min_by_key ( |b| b. height )
338+ . map ( |b| b. block_hash )
339+ {
340+ chain_listeners. push ( (
341+ worst_channel_monitor_block_hash,
342+ & * chain_monitor as & ( dyn Listen + Send + Sync ) ,
343+ ) ) ;
344+ }
311345
312- loop {
313346 let mut locked_header_cache = header_cache. lock ( ) . await ;
314347 match synchronize_listeners (
315348 bitcoind_rpc_client. as_ref ( ) ,
@@ -347,6 +380,7 @@ impl ChainSource {
347380 log_error ! ( logger, "Failed to synchronize chain listeners: {:?}" , e) ;
348381 tokio:: time:: sleep ( Duration :: from_secs ( CHAIN_POLLING_INTERVAL_SECS ) )
349382 . await ;
383+ continue ' initial_listener_sync;
350384 } ,
351385 }
352386 }
0 commit comments