@@ -106,8 +106,18 @@ where
106106 // Update the known tip to the newest one.
107107 if tip_is_new {
108108 // First check for any unconfirmed transactions and act on it immediately.
109- match maybe_await ! ( self . sync_unconfirmed_transactions( & mut sync_state, & confirmables) ) {
110- Ok ( ( ) ) => { } ,
109+ match maybe_await ! ( self . get_unconfirmed_transactions( & confirmables) ) {
110+ Ok ( unconfirmed_txs) => {
111+ // Double-check the tip hash. If if it changed, a reorg happened since
112+ // we started syncing and we need to restart last-minute.
113+ let check_tip_hash = maybe_await ! ( self . client. get_tip_hash( ) ) ?;
114+ if check_tip_hash != tip_hash {
115+ tip_hash = check_tip_hash;
116+ continue ;
117+ }
118+
119+ self . sync_unconfirmed_transactions ( & mut sync_state, & confirmables, unconfirmed_txs) ;
120+ } ,
111121 Err ( err) => {
112122 // (Semi-)permanent failure, retry later.
113123 log_error ! ( self . logger, "Failed during transaction sync, aborting." ) ;
@@ -301,34 +311,42 @@ where
301311 }
302312
303313 #[ maybe_async]
304- fn sync_unconfirmed_transactions (
305- & self , sync_state : & mut SyncState , confirmables : & Vec < & ( dyn Confirm + Sync + Send ) > ,
306- ) -> Result < ( ) , InternalError > {
314+ fn get_unconfirmed_transactions (
315+ & self , confirmables : & Vec < & ( dyn Confirm + Sync + Send ) > ,
316+ ) -> Result < Vec < Txid > , InternalError > {
307317 // Query the interface for relevant txids and check whether the relevant blocks are still
308- // in the best chain, mark them unconfirmed otherwise. If the transactions have been
309- // reconfirmed in another block, we'll confirm them in the next sync iteration.
318+ // in the best chain, mark them unconfirmed otherwise
310319 let relevant_txids = confirmables
311320 . iter ( )
312321 . flat_map ( |c| c. get_relevant_txids ( ) )
313322 . collect :: < HashSet < ( Txid , Option < BlockHash > ) > > ( ) ;
314323
324+ let mut unconfirmed_txs = Vec :: new ( ) ;
325+
315326 for ( txid, block_hash_opt) in relevant_txids {
316327 if let Some ( block_hash) = block_hash_opt {
317328 let block_status = maybe_await ! ( self . client. get_block_status( & block_hash) ) ?;
318329 if block_status. in_best_chain {
319330 // Skip if the block in question is still confirmed.
320331 continue ;
321332 }
333+
334+ unconfirmed_txs. push ( txid) ;
322335 }
336+ }
337+ Ok ( unconfirmed_txs)
338+ }
323339
340+ fn sync_unconfirmed_transactions (
341+ & self , sync_state : & mut SyncState , confirmables : & Vec < & ( dyn Confirm + Sync + Send ) > , unconfirmed_txs : Vec < Txid > ,
342+ ) {
343+ for txid in unconfirmed_txs {
324344 for c in confirmables {
325345 c. transaction_unconfirmed ( & txid) ;
326346 }
327347
328348 sync_state. watched_transactions . insert ( txid) ;
329349 }
330-
331- Ok ( ( ) )
332350 }
333351
334352 /// Returns a reference to the underlying esplora client.
0 commit comments