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 } ;
@@ -166,8 +166,12 @@ fn test_esplora_syncs() {
166166 assert_eq ! ( events. len( ) , 1 ) ;
167167
168168 // Check registered confirmed transactions are marked confirmed
169- let new_address = bitcoind. client . get_new_address ( Some ( "test" ) , Some ( AddressType :: Legacy ) ) . unwrap ( ) ;
170- let txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None , None , None , None , None ) . unwrap ( ) ;
169+ let new_address = bitcoind. client . get_new_address ( Some ( "test" ) ,
170+ Some ( AddressType :: Legacy ) ) . unwrap ( ) ;
171+ let txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None ,
172+ None , None , None , None ) . unwrap ( ) ;
173+ let second_txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None ,
174+ None , None , None , None , None ) . unwrap ( ) ;
171175 tx_sync. register_tx ( & txid, & new_address. script_pubkey ( ) ) ;
172176
173177 tx_sync. sync ( vec ! [ & confirmable] ) . unwrap ( ) ;
@@ -185,6 +189,27 @@ fn test_esplora_syncs() {
185189 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
186190 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
187191
192+ // Now take a random output of the second transaction and check we'll confirm its spend.
193+ let tx_res = bitcoind. client . get_transaction ( & second_txid, None ) . unwrap ( ) ;
194+ let block_hash = tx_res. info . blockhash . unwrap ( ) ;
195+ let tx = tx_res. transaction ( ) . unwrap ( ) ;
196+ let prev_outpoint = tx. input . first ( ) . unwrap ( ) . previous_output ;
197+ let prev_tx = bitcoind. client . get_transaction ( & prev_outpoint. txid ,
198+ None ) . unwrap ( ) . transaction ( ) . unwrap ( ) ;
199+ let prev_script_pubkey = prev_tx. output [ prev_outpoint. vout as usize ] . script_pubkey . clone ( ) ;
200+ let output = WatchedOutput { block_hash : Some ( block_hash) , outpoint : OutPoint {
201+ txid : prev_outpoint. txid , index : prev_outpoint. vout as u16 } ,
202+ script_pubkey : prev_script_pubkey } ;
203+
204+ tx_sync. register_output ( output) ;
205+ tx_sync. sync ( vec ! [ & confirmable] ) . unwrap ( ) ;
206+
207+ let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
208+ assert_eq ! ( events. len( ) , 1 ) ;
209+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
210+ assert_eq ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . len( ) , 2 ) ;
211+ assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
212+
188213 // Check previously confirmed transactions are marked unconfirmed when they are reorged.
189214 let best_block_hash = bitcoind. client . get_best_block_hash ( ) . unwrap ( ) ;
190215 bitcoind. client . invalidate_block ( & best_block_hash) . unwrap ( ) ;
@@ -201,29 +226,44 @@ fn test_esplora_syncs() {
201226 assert_ne ! ( bitcoind. client. get_best_block_hash( ) . unwrap( ) , best_block_hash) ;
202227 tx_sync. sync ( vec ! [ & confirmable] ) . unwrap ( ) ;
203228
204- // Transaction still confirmed but under new tip.
229+ // Transactions still confirmed but under new tip.
205230 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
231+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
206232 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
207233
208234 // Check we got unconfirmed, then reconfirmed in the meantime.
209235 let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
210- assert_eq ! ( events. len( ) , 3 ) ;
236+ assert_eq ! ( events. len( ) , 5 ) ;
211237
212238 match events[ 0 ] {
213239 TestConfirmableEvent :: Unconfirmed ( t) => {
214- assert_eq ! ( t, txid) ;
240+ assert ! ( t == txid || t == second_txid ) ;
215241 } ,
216242 _ => panic ! ( "Unexpected event" ) ,
217243 }
218244
219245 match events[ 1 ] {
220- TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
246+ TestConfirmableEvent :: Unconfirmed ( t) => {
247+ assert ! ( t == txid || t == second_txid) ;
248+ } ,
221249 _ => panic ! ( "Unexpected event" ) ,
222250 }
223251
224252 match events[ 2 ] {
253+ TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
254+ _ => panic ! ( "Unexpected event" ) ,
255+ }
256+
257+ match events[ 3 ] {
258+ TestConfirmableEvent :: Confirmed ( t, _, _) => {
259+ assert ! ( t == txid || t == second_txid) ;
260+ } ,
261+ _ => panic ! ( "Unexpected event" ) ,
262+ }
263+
264+ match events[ 4 ] {
225265 TestConfirmableEvent :: Confirmed ( t, _, _) => {
226- assert_eq ! ( t, txid) ;
266+ assert ! ( t == txid || t == second_txid ) ;
227267 } ,
228268 _ => panic ! ( "Unexpected event" ) ,
229269 }
@@ -249,8 +289,12 @@ async fn test_esplora_syncs() {
249289 assert_eq ! ( events. len( ) , 1 ) ;
250290
251291 // Check registered confirmed transactions are marked confirmed
252- let new_address = bitcoind. client . get_new_address ( Some ( "test" ) , Some ( AddressType :: Legacy ) ) . unwrap ( ) ;
253- let txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None , None , None , None , None ) . unwrap ( ) ;
292+ let new_address = bitcoind. client . get_new_address ( Some ( "test" ) ,
293+ Some ( AddressType :: Legacy ) ) . unwrap ( ) ;
294+ let txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None , None ,
295+ None , None , None , None ) . unwrap ( ) ;
296+ let second_txid = bitcoind. client . send_to_address ( & new_address, Amount :: from_sat ( 5000 ) , None ,
297+ None , None , None , None , None ) . unwrap ( ) ;
254298 tx_sync. register_tx ( & txid, & new_address. script_pubkey ( ) ) ;
255299
256300 tx_sync. sync ( vec ! [ & confirmable] ) . await . unwrap ( ) ;
@@ -268,6 +312,27 @@ async fn test_esplora_syncs() {
268312 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
269313 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
270314
315+ // Now take a random output of the second transaction and check we'll confirm its spend.
316+ let tx_res = bitcoind. client . get_transaction ( & second_txid, None ) . unwrap ( ) ;
317+ let block_hash = tx_res. info . blockhash . unwrap ( ) ;
318+ let tx = tx_res. transaction ( ) . unwrap ( ) ;
319+ let prev_outpoint = tx. input . first ( ) . unwrap ( ) . previous_output ;
320+ let prev_tx = bitcoind. client . get_transaction ( & prev_outpoint. txid ,
321+ None ) . unwrap ( ) . transaction ( ) . unwrap ( ) ;
322+ let prev_script_pubkey = prev_tx. output [ prev_outpoint. vout as usize ] . script_pubkey . clone ( ) ;
323+ let output = WatchedOutput { block_hash : Some ( block_hash) , outpoint : OutPoint {
324+ txid : prev_outpoint. txid , index : prev_outpoint. vout as u16 } ,
325+ script_pubkey : prev_script_pubkey } ;
326+
327+ tx_sync. register_output ( output) ;
328+ tx_sync. sync ( vec ! [ & confirmable] ) . await . unwrap ( ) ;
329+
330+ let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
331+ assert_eq ! ( events. len( ) , 1 ) ;
332+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
333+ assert_eq ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . len( ) , 2 ) ;
334+ assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
335+
271336 // Check previously confirmed transactions are marked unconfirmed when they are reorged.
272337 let best_block_hash = bitcoind. client . get_best_block_hash ( ) . unwrap ( ) ;
273338 bitcoind. client . invalidate_block ( & best_block_hash) . unwrap ( ) ;
@@ -284,29 +349,44 @@ async fn test_esplora_syncs() {
284349 assert_ne ! ( bitcoind. client. get_best_block_hash( ) . unwrap( ) , best_block_hash) ;
285350 tx_sync. sync ( vec ! [ & confirmable] ) . await . unwrap ( ) ;
286351
287- // Transaction still confirmed but under new tip.
352+ // Transactions still confirmed but under new tip.
288353 assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & txid) ) ;
354+ assert ! ( confirmable. confirmed_txs. lock( ) . unwrap( ) . contains_key( & second_txid) ) ;
289355 assert ! ( confirmable. unconfirmed_txs. lock( ) . unwrap( ) . is_empty( ) ) ;
290356
291357 // Check we got unconfirmed, then reconfirmed in the meantime.
292358 let events = std:: mem:: take ( & mut * confirmable. events . lock ( ) . unwrap ( ) ) ;
293- assert_eq ! ( events. len( ) , 3 ) ;
359+ assert_eq ! ( events. len( ) , 5 ) ;
294360
295361 match events[ 0 ] {
296362 TestConfirmableEvent :: Unconfirmed ( t) => {
297- assert_eq ! ( t, txid) ;
363+ assert ! ( t == txid || t == second_txid ) ;
298364 } ,
299365 _ => panic ! ( "Unexpected event" ) ,
300366 }
301367
302368 match events[ 1 ] {
303- TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
369+ TestConfirmableEvent :: Unconfirmed ( t) => {
370+ assert ! ( t == txid || t == second_txid) ;
371+ } ,
304372 _ => panic ! ( "Unexpected event" ) ,
305373 }
306374
307375 match events[ 2 ] {
376+ TestConfirmableEvent :: BestBlockUpdated ( ..) => { } ,
377+ _ => panic ! ( "Unexpected event" ) ,
378+ }
379+
380+ match events[ 3 ] {
381+ TestConfirmableEvent :: Confirmed ( t, _, _) => {
382+ assert ! ( t == txid || t == second_txid) ;
383+ } ,
384+ _ => panic ! ( "Unexpected event" ) ,
385+ }
386+
387+ match events[ 4 ] {
308388 TestConfirmableEvent :: Confirmed ( t, _, _) => {
309- assert_eq ! ( t, txid) ;
389+ assert ! ( t == txid || t == second_txid ) ;
310390 } ,
311391 _ => panic ! ( "Unexpected event" ) ,
312392 }
0 commit comments