11#![ cfg( any( feature = "esplora-blocking" , feature = "esplora-async" ) ) ]
22use lightning_transaction_sync:: EsploraSyncClient ;
3- use lightning:: chain:: { Confirm , Filter } ;
4- use lightning:: chain:: transaction:: TransactionData ;
3+ use lightning:: chain:: { Confirm , Filter , WatchedOutput } ;
4+ use lightning:: chain:: transaction:: { OutPoint , TransactionData } ;
55use lightning:: util:: test_utils:: TestLogger ;
66
77use electrsd:: { bitcoind, bitcoind:: BitcoinD , ElectrsD } ;
@@ -168,6 +168,7 @@ fn test_esplora_syncs() {
168168 // Check registered confirmed transactions are marked confirmed
169169 let new_address = bitcoind. client . get_new_address ( Some ( "test" ) , Some ( AddressType :: Legacy ) ) . unwrap ( ) ;
170170 let txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None , None , None , None , None ) . unwrap ( ) ;
171+ let second_txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None , None , None , None , None ) . unwrap ( ) ;
171172 tx_sync. register_tx ( & txid, & new_address. script_pubkey ( ) ) ;
172173
173174 tx_sync. sync ( vec ! [ & confirmable] ) . unwrap ( ) ;
@@ -185,6 +186,24 @@ fn test_esplora_syncs() {
185186 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
186187 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
187188
189+ // Now take a random output of the second transaction and check we'll confirm its spend.
190+ let tx_res = bitcoind. client . get_transaction ( & second_txid, None ) . unwrap ( ) ;
191+ let block_hash = tx_res. info . blockhash . unwrap ( ) ;
192+ let tx = tx_res. transaction ( ) . unwrap ( ) ;
193+ let prev_outpoint = tx. input . first ( ) . unwrap ( ) . previous_output ;
194+ let prev_tx = bitcoind. client . get_transaction ( & prev_outpoint. txid , None ) . unwrap ( ) . transaction ( ) . unwrap ( ) ;
195+ let prev_script_pubkey = prev_tx. output [ prev_outpoint. vout as usize ] . script_pubkey . clone ( ) ;
196+ let output = WatchedOutput { block_hash : Some ( block_hash) , outpoint : OutPoint { txid : prev_outpoint. txid , index : prev_outpoint. vout as u16 } , script_pubkey : prev_script_pubkey } ;
197+
198+ tx_sync. register_output ( output) ;
199+ tx_sync. sync ( vec ! [ & confirmable] ) . unwrap ( ) ;
200+
201+ let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
202+ assert_eq ! ( events. len( ) , 1 ) ;
203+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
204+ assert_eq ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . len( ) , 2 ) ;
205+ assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
206+
188207 // Check previously confirmed transactions are marked unconfirmed when they are reorged.
189208 let best_block_hash = bitcoind. client . get_best_block_hash ( ) . unwrap ( ) ;
190209 bitcoind. client . invalidate_block ( & best_block_hash) . unwrap ( ) ;
@@ -201,29 +220,44 @@ fn test_esplora_syncs() {
201220 assert_ne ! ( bitcoind. client. get_best_block_hash( ) . unwrap( ) , best_block_hash) ;
202221 tx_sync. sync ( vec ! [ & confirmable] ) . unwrap ( ) ;
203222
204- // Transaction still confirmed but under new tip.
223+ // Transactions still confirmed but under new tip.
205224 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
225+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
206226 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
207227
208228 // Check we got unconfirmed, then reconfirmed in the meantime.
209229 let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
210- assert_eq ! ( events. len( ) , 3 ) ;
230+ assert_eq ! ( events. len( ) , 5 ) ;
211231
212232 match events[ 0 ] {
213233 TestConfirmableEvent :: Unconfirmed ( t) => {
214- assert_eq ! ( t, txid) ;
234+ assert ! ( t == txid || t == second_txid ) ;
215235 } ,
216236 _ => panic ! ( "Unexpected event" ) ,
217237 }
218238
219239 match events[ 1 ] {
220- TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
240+ TestConfirmableEvent :: Unconfirmed ( t) => {
241+ assert ! ( t == txid || t == second_txid) ;
242+ } ,
221243 _ => panic ! ( "Unexpected event" ) ,
222244 }
223245
224246 match events[ 2 ] {
247+ TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
248+ _ => panic ! ( "Unexpected event" ) ,
249+ }
250+
251+ match events[ 3 ] {
252+ TestConfirmableEvent :: Confirmed ( t, _, _) => {
253+ assert ! ( t == txid || t == second_txid) ;
254+ } ,
255+ _ => panic ! ( "Unexpected event" ) ,
256+ }
257+
258+ match events[ 4 ] {
225259 TestConfirmableEvent :: Confirmed ( t, _, _) => {
226- assert_eq ! ( t, txid) ;
260+ assert ! ( t == txid || t == second_txid ) ;
227261 } ,
228262 _ => panic ! ( "Unexpected event" ) ,
229263 }
@@ -251,6 +285,7 @@ async fn test_esplora_syncs() {
251285 // Check registered confirmed transactions are marked confirmed
252286 let new_address = bitcoind. client . get_new_address ( Some ( "test" ) , Some ( AddressType :: Legacy ) ) . unwrap ( ) ;
253287 let txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None , None , None , None , None ) . unwrap ( ) ;
288+ let second_txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None , None , None , None , None ) . unwrap ( ) ;
254289 tx_sync. register_tx ( & txid, & new_address. script_pubkey ( ) ) ;
255290
256291 tx_sync. sync ( vec ! [ & confirmable] ) . await . unwrap ( ) ;
@@ -268,6 +303,24 @@ async fn test_esplora_syncs() {
268303 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
269304 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
270305
306+ // Now take a random output of the second transaction and check we'll confirm its spend.
307+ let tx_res = bitcoind. client . get_transaction ( & second_txid, None ) . unwrap ( ) ;
308+ let block_hash = tx_res. info . blockhash . unwrap ( ) ;
309+ let tx = tx_res. transaction ( ) . unwrap ( ) ;
310+ let prev_outpoint = tx. input . first ( ) . unwrap ( ) . previous_output ;
311+ let prev_tx = bitcoind. client . get_transaction ( & prev_outpoint. txid , None ) . unwrap ( ) . transaction ( ) . unwrap ( ) ;
312+ let prev_script_pubkey = prev_tx. output [ prev_outpoint. vout as usize ] . script_pubkey . clone ( ) ;
313+ let output = WatchedOutput { block_hash : Some ( block_hash) , outpoint : OutPoint { txid : prev_outpoint. txid , index : prev_outpoint. vout as u16 } , script_pubkey : prev_script_pubkey } ;
314+
315+ tx_sync. register_output ( output) ;
316+ tx_sync. sync ( vec ! [ & confirmable] ) . await . unwrap ( ) ;
317+
318+ let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
319+ assert_eq ! ( events. len( ) , 1 ) ;
320+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
321+ assert_eq ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . len( ) , 2 ) ;
322+ assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
323+
271324 // Check previously confirmed transactions are marked unconfirmed when they are reorged.
272325 let best_block_hash = bitcoind. client . get_best_block_hash ( ) . unwrap ( ) ;
273326 bitcoind. client . invalidate_block ( & best_block_hash) . unwrap ( ) ;
@@ -284,29 +337,44 @@ async fn test_esplora_syncs() {
284337 assert_ne ! ( bitcoind. client. get_best_block_hash( ) . unwrap( ) , best_block_hash) ;
285338 tx_sync. sync ( vec ! [ & confirmable] ) . await . unwrap ( ) ;
286339
287- // Transaction still confirmed but under new tip.
340+ // Transactions still confirmed but under new tip.
288341 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
342+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
289343 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
290344
291345 // Check we got unconfirmed, then reconfirmed in the meantime.
292346 let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
293- assert_eq ! ( events. len( ) , 3 ) ;
347+ assert_eq ! ( events. len( ) , 5 ) ;
294348
295349 match events[ 0 ] {
296350 TestConfirmableEvent :: Unconfirmed ( t) => {
297- assert_eq ! ( t, txid) ;
351+ assert ! ( t == txid || t == second_txid ) ;
298352 } ,
299353 _ => panic ! ( "Unexpected event" ) ,
300354 }
301355
302356 match events[ 1 ] {
303- TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
357+ TestConfirmableEvent :: Unconfirmed ( t) => {
358+ assert ! ( t == txid || t == second_txid) ;
359+ } ,
304360 _ => panic ! ( "Unexpected event" ) ,
305361 }
306362
307363 match events[ 2 ] {
364+ TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
365+ _ => panic ! ( "Unexpected event" ) ,
366+ }
367+
368+ match events[ 3 ] {
369+ TestConfirmableEvent :: Confirmed ( t, _, _) => {
370+ assert ! ( t == txid || t == second_txid) ;
371+ } ,
372+ _ => panic ! ( "Unexpected event" ) ,
373+ }
374+
375+ match events[ 4 ] {
308376 TestConfirmableEvent :: Confirmed ( t, _, _) => {
309- assert_eq ! ( t, txid) ;
377+ assert ! ( t == txid || t == second_txid ) ;
310378 } ,
311379 _ => panic ! ( "Unexpected event" ) ,
312380 }
0 commit comments