Skip to content

Commit 277e43e

Browse files
committed
Improve EsploraSyncClient test coverage
In particular, we now test `register_output` functionality, too.
1 parent 515b38c commit 277e43e

File tree

1 file changed

+114
-16
lines changed

1 file changed

+114
-16
lines changed

lightning-transaction-sync/tests/integration_tests.rs

Lines changed: 114 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![cfg(any(feature = "esplora-blocking", feature = "esplora-async"))]
22
use 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};
55
use lightning::util::test_utils::TestLogger;
66

77
use 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,29 @@ 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 an arbitrary 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, None).unwrap().transaction()
198+
.unwrap();
199+
let prev_script_pubkey = prev_tx.output[prev_outpoint.vout as usize].script_pubkey.clone();
200+
let output = WatchedOutput {
201+
block_hash: Some(block_hash),
202+
outpoint: OutPoint { txid: prev_outpoint.txid, index: prev_outpoint.vout as u16 },
203+
script_pubkey: prev_script_pubkey
204+
};
205+
206+
tx_sync.register_output(output);
207+
tx_sync.sync(vec![&confirmable]).unwrap();
208+
209+
let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
210+
assert_eq!(events.len(), 1);
211+
assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&second_txid));
212+
assert_eq!(confirmable.confirmed_txs.lock().unwrap().len(), 2);
213+
assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
214+
188215
// Check previously confirmed transactions are marked unconfirmed when they are reorged.
189216
let best_block_hash = bitcoind.client.get_best_block_hash().unwrap();
190217
bitcoind.client.invalidate_block(&best_block_hash).unwrap();
@@ -201,32 +228,54 @@ fn test_esplora_syncs() {
201228
assert_ne!(bitcoind.client.get_best_block_hash().unwrap(), best_block_hash);
202229
tx_sync.sync(vec![&confirmable]).unwrap();
203230

204-
// Transaction still confirmed but under new tip.
231+
// Transactions still confirmed but under new tip.
205232
assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&txid));
233+
assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&second_txid));
206234
assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
207235

208236
// Check we got unconfirmed, then reconfirmed in the meantime.
237+
let mut seen_txids = HashSet::new();
209238
let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
210-
assert_eq!(events.len(), 3);
239+
assert_eq!(events.len(), 5);
211240

212241
match events[0] {
213242
TestConfirmableEvent::Unconfirmed(t) => {
214-
assert_eq!(t, txid);
243+
assert!(t == txid || t == second_txid);
244+
assert!(seen_txids.insert(t));
215245
},
216246
_ => panic!("Unexpected event"),
217247
}
218248

219249
match events[1] {
220-
TestConfirmableEvent::BestBlockUpdated(..) => {},
250+
TestConfirmableEvent::Unconfirmed(t) => {
251+
assert!(t == txid || t == second_txid);
252+
assert!(seen_txids.insert(t));
253+
},
221254
_ => panic!("Unexpected event"),
222255
}
223256

224257
match events[2] {
258+
TestConfirmableEvent::BestBlockUpdated(..) => {},
259+
_ => panic!("Unexpected event"),
260+
}
261+
262+
match events[3] {
263+
TestConfirmableEvent::Confirmed(t, _, _) => {
264+
assert!(t == txid || t == second_txid);
265+
assert!(seen_txids.remove(&t));
266+
},
267+
_ => panic!("Unexpected event"),
268+
}
269+
270+
match events[4] {
225271
TestConfirmableEvent::Confirmed(t, _, _) => {
226-
assert_eq!(t, txid);
272+
assert!(t == txid || t == second_txid);
273+
assert!(seen_txids.remove(&t));
227274
},
228275
_ => panic!("Unexpected event"),
229276
}
277+
278+
assert_eq!(seen_txids.len(), 0);
230279
}
231280

232281
#[tokio::test]
@@ -249,8 +298,12 @@ async fn test_esplora_syncs() {
249298
assert_eq!(events.len(), 1);
250299

251300
// 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();
301+
let new_address = bitcoind.client.get_new_address(Some("test"),
302+
Some(AddressType::Legacy)).unwrap();
303+
let txid = bitcoind.client.send_to_address(&new_address, Amount::from_sat(5000), None, None,
304+
None, None, None, None).unwrap();
305+
let second_txid = bitcoind.client.send_to_address(&new_address, Amount::from_sat(5000), None,
306+
None, None, None, None, None).unwrap();
254307
tx_sync.register_tx(&txid, &new_address.script_pubkey());
255308

256309
tx_sync.sync(vec![&confirmable]).await.unwrap();
@@ -268,6 +321,29 @@ async fn test_esplora_syncs() {
268321
assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&txid));
269322
assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
270323

324+
// Now take an arbitrary output of the second transaction and check we'll confirm its spend.
325+
let tx_res = bitcoind.client.get_transaction(&second_txid, None).unwrap();
326+
let block_hash = tx_res.info.blockhash.unwrap();
327+
let tx = tx_res.transaction().unwrap();
328+
let prev_outpoint = tx.input.first().unwrap().previous_output;
329+
let prev_tx = bitcoind.client.get_transaction(&prev_outpoint.txid, None).unwrap().transaction()
330+
.unwrap();
331+
let prev_script_pubkey = prev_tx.output[prev_outpoint.vout as usize].script_pubkey.clone();
332+
let output = WatchedOutput {
333+
block_hash: Some(block_hash),
334+
outpoint: OutPoint { txid: prev_outpoint.txid, index: prev_outpoint.vout as u16 },
335+
script_pubkey: prev_script_pubkey
336+
};
337+
338+
tx_sync.register_output(output);
339+
tx_sync.sync(vec![&confirmable]).await.unwrap();
340+
341+
let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
342+
assert_eq!(events.len(), 1);
343+
assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&second_txid));
344+
assert_eq!(confirmable.confirmed_txs.lock().unwrap().len(), 2);
345+
assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
346+
271347
// Check previously confirmed transactions are marked unconfirmed when they are reorged.
272348
let best_block_hash = bitcoind.client.get_best_block_hash().unwrap();
273349
bitcoind.client.invalidate_block(&best_block_hash).unwrap();
@@ -284,30 +360,52 @@ async fn test_esplora_syncs() {
284360
assert_ne!(bitcoind.client.get_best_block_hash().unwrap(), best_block_hash);
285361
tx_sync.sync(vec![&confirmable]).await.unwrap();
286362

287-
// Transaction still confirmed but under new tip.
363+
// Transactions still confirmed but under new tip.
288364
assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&txid));
365+
assert!(confirmable.confirmed_txs.lock().unwrap().contains_key(&second_txid));
289366
assert!(confirmable.unconfirmed_txs.lock().unwrap().is_empty());
290367

291368
// Check we got unconfirmed, then reconfirmed in the meantime.
369+
let mut seen_txids = HashSet::new();
292370
let events = std::mem::take(&mut *confirmable.events.lock().unwrap());
293-
assert_eq!(events.len(), 3);
371+
assert_eq!(events.len(), 5);
294372

295373
match events[0] {
296374
TestConfirmableEvent::Unconfirmed(t) => {
297-
assert_eq!(t, txid);
375+
assert!(t == txid || t == second_txid);
376+
assert!(seen_txids.insert(t));
298377
},
299378
_ => panic!("Unexpected event"),
300379
}
301380

302381
match events[1] {
303-
TestConfirmableEvent::BestBlockUpdated(..) => {},
382+
TestConfirmableEvent::Unconfirmed(t) => {
383+
assert!(t == txid || t == second_txid);
384+
assert!(seen_txids.insert(t));
385+
},
304386
_ => panic!("Unexpected event"),
305387
}
306388

307389
match events[2] {
390+
TestConfirmableEvent::BestBlockUpdated(..) => {},
391+
_ => panic!("Unexpected event"),
392+
}
393+
394+
match events[3] {
395+
TestConfirmableEvent::Confirmed(t, _, _) => {
396+
assert!(t == txid || t == second_txid);
397+
assert!(seen_txids.remove(&t));
398+
},
399+
_ => panic!("Unexpected event"),
400+
}
401+
402+
match events[4] {
308403
TestConfirmableEvent::Confirmed(t, _, _) => {
309-
assert_eq!(t, txid);
404+
assert!(t == txid || t == second_txid);
405+
assert!(seen_txids.remove(&t));
310406
},
311407
_ => panic!("Unexpected event"),
312408
}
409+
410+
assert_eq!(seen_txids.len(), 0);
313411
}

0 commit comments

Comments
 (0)