Skip to content

Commit b45897e

Browse files
committed
feat(electrum): update docs and simplify logic of ElectrumExt
Helper method docs are updated to explain what they are updating. Logic is simplified as we do not need to check whether a tx exists already in `update_graph` before inserting it.
1 parent 92fb6cb commit b45897e

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

crates/electrum/src/electrum_ext.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,12 @@ fn determine_tx_anchor(
395395
}
396396
}
397397

398+
/// Populate the `graph_update` with associated transactions/anchors of `outpoints`.
399+
///
400+
/// Transactions in which the outpoint resides, and transactions that spend from the outpoint are
401+
/// included. Anchors of the aforementioned transactions are included.
402+
///
403+
/// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
398404
fn populate_with_outpoints(
399405
client: &impl ElectrumApi,
400406
cps: &BTreeMap<u32, CheckPoint>,
@@ -403,59 +409,52 @@ fn populate_with_outpoints(
403409
outpoints: impl IntoIterator<Item = OutPoint>,
404410
) -> Result<(), Error> {
405411
for outpoint in outpoints {
406-
let txid = outpoint.txid;
407-
let tx = client.transaction_get(&txid)?;
408-
debug_assert_eq!(tx.txid(), txid);
409-
let txout = match tx.output.get(outpoint.vout as usize) {
412+
let op_txid = outpoint.txid;
413+
let op_tx = fetch_tx(client, tx_cache, op_txid)?;
414+
let op_txout = match op_tx.output.get(outpoint.vout as usize) {
410415
Some(txout) => txout,
411416
None => continue,
412417
};
418+
debug_assert_eq!(op_tx.txid(), op_txid);
419+
413420
// attempt to find the following transactions (alongside their chain positions), and
414421
// add to our sparsechain `update`:
415422
let mut has_residing = false; // tx in which the outpoint resides
416423
let mut has_spending = false; // tx that spends the outpoint
417-
for res in client.script_get_history(&txout.script_pubkey)? {
424+
for res in client.script_get_history(&op_txout.script_pubkey)? {
418425
if has_residing && has_spending {
419426
break;
420427
}
421428

422-
if res.tx_hash == txid {
423-
if has_residing {
424-
continue;
425-
}
429+
if !has_residing && res.tx_hash == op_txid {
426430
has_residing = true;
427-
if graph_update.get_tx(res.tx_hash).is_none() {
428-
let _ = graph_update.insert_tx(tx.clone());
431+
let _ = graph_update.insert_tx(Arc::clone(&op_tx));
432+
if let Some(anchor) = determine_tx_anchor(cps, res.height, res.tx_hash) {
433+
let _ = graph_update.insert_anchor(res.tx_hash, anchor);
429434
}
430-
} else {
431-
if has_spending {
432-
continue;
433-
}
434-
let res_tx = match graph_update.get_tx(res.tx_hash) {
435-
Some(tx) => tx,
436-
None => {
437-
let res_tx = fetch_tx(client, tx_cache, res.tx_hash)?;
438-
let _ = graph_update.insert_tx(Arc::clone(&res_tx));
439-
res_tx
440-
}
441-
};
435+
}
436+
437+
if !has_spending && res.tx_hash != op_txid {
438+
let res_tx = fetch_tx(client, tx_cache, res.tx_hash)?;
439+
// we exclude txs/anchors that do not spend our specified outpoint(s)
442440
has_spending = res_tx
443441
.input
444442
.iter()
445443
.any(|txin| txin.previous_output == outpoint);
446444
if !has_spending {
447445
continue;
448446
}
449-
};
450-
451-
if let Some(anchor) = determine_tx_anchor(cps, res.height, res.tx_hash) {
452-
let _ = graph_update.insert_anchor(res.tx_hash, anchor);
447+
let _ = graph_update.insert_tx(Arc::clone(&res_tx));
448+
if let Some(anchor) = determine_tx_anchor(cps, res.height, res.tx_hash) {
449+
let _ = graph_update.insert_anchor(res.tx_hash, anchor);
450+
}
453451
}
454452
}
455453
}
456454
Ok(())
457455
}
458456

457+
/// Populate the `graph_update` with transactions/anchors of the provided `txids`.
459458
fn populate_with_txids(
460459
client: &impl ElectrumApi,
461460
cps: &BTreeMap<u32, CheckPoint>,
@@ -476,6 +475,8 @@ fn populate_with_txids(
476475
.map(|txo| &txo.script_pubkey)
477476
.expect("tx must have an output");
478477

478+
// because of restrictions of the Electrum API, we have to use the `script_get_history`
479+
// call to get confirmation status of our transaction
479480
let anchor = match client
480481
.script_get_history(spk)?
481482
.into_iter()
@@ -485,16 +486,17 @@ fn populate_with_txids(
485486
None => continue,
486487
};
487488

488-
if graph_update.get_tx(txid).is_none() {
489-
let _ = graph_update.insert_tx(tx);
490-
}
489+
let _ = graph_update.insert_tx(tx);
491490
if let Some(anchor) = anchor {
492491
let _ = graph_update.insert_anchor(txid, anchor);
493492
}
494493
}
495494
Ok(())
496495
}
497496

497+
/// Fetch transaction of given `txid`.
498+
///
499+
/// We maintain a `tx_cache` so that we won't need to fetch from Electrum with every call.
498500
fn fetch_tx<C: ElectrumApi>(
499501
client: &C,
500502
tx_cache: &mut TxCache,
@@ -530,6 +532,13 @@ fn fetch_prev_txout<C: ElectrumApi>(
530532
Ok(())
531533
}
532534

535+
/// Populate the `graph_update` with transactions/anchors associated with the given `spks`.
536+
///
537+
/// Transactions that contains an output with requested spk, or spends form an output with
538+
/// requested spk will be added to `graph_update`. Anchors of the aforementioned transactions are
539+
/// also included.
540+
///
541+
/// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
533542
fn populate_with_spks<I: Ord + Clone>(
534543
client: &impl ElectrumApi,
535544
cps: &BTreeMap<u32, CheckPoint>,

0 commit comments

Comments
 (0)