@@ -106,8 +106,18 @@ where
106
106
// Update the known tip to the newest one.
107
107
if tip_is_new {
108
108
// 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
+ } ,
111
121
Err ( err) => {
112
122
// (Semi-)permanent failure, retry later.
113
123
log_error ! ( self . logger, "Failed during transaction sync, aborting." ) ;
@@ -301,34 +311,42 @@ where
301
311
}
302
312
303
313
#[ 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 > {
307
317
// 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
310
319
let relevant_txids = confirmables
311
320
. iter ( )
312
321
. flat_map ( |c| c. get_relevant_txids ( ) )
313
322
. collect :: < HashSet < ( Txid , Option < BlockHash > ) > > ( ) ;
314
323
324
+ let mut unconfirmed_txs = Vec :: new ( ) ;
325
+
315
326
for ( txid, block_hash_opt) in relevant_txids {
316
327
if let Some ( block_hash) = block_hash_opt {
317
328
let block_status = maybe_await ! ( self . client. get_block_status( & block_hash) ) ?;
318
329
if block_status. in_best_chain {
319
330
// Skip if the block in question is still confirmed.
320
331
continue ;
321
332
}
333
+
334
+ unconfirmed_txs. push ( txid) ;
322
335
}
336
+ }
337
+ Ok ( unconfirmed_txs)
338
+ }
323
339
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 {
324
344
for c in confirmables {
325
345
c. transaction_unconfirmed ( & txid) ;
326
346
}
327
347
328
348
sync_state. watched_transactions . insert ( txid) ;
329
349
}
330
-
331
- Ok ( ( ) )
332
350
}
333
351
334
352
/// Returns a reference to the underlying esplora client.
0 commit comments