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.
This commit is contained in:
parent
92fb6cb373
commit
b45897e6fe
@ -395,6 +395,12 @@ fn determine_tx_anchor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Populate the `graph_update` with associated transactions/anchors of `outpoints`.
|
||||||
|
///
|
||||||
|
/// Transactions in which the outpoint resides, and transactions that spend from the outpoint are
|
||||||
|
/// included. Anchors of the aforementioned transactions are included.
|
||||||
|
///
|
||||||
|
/// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
|
||||||
fn populate_with_outpoints(
|
fn populate_with_outpoints(
|
||||||
client: &impl ElectrumApi,
|
client: &impl ElectrumApi,
|
||||||
cps: &BTreeMap<u32, CheckPoint>,
|
cps: &BTreeMap<u32, CheckPoint>,
|
||||||
@ -403,42 +409,34 @@ fn populate_with_outpoints(
|
|||||||
outpoints: impl IntoIterator<Item = OutPoint>,
|
outpoints: impl IntoIterator<Item = OutPoint>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
for outpoint in outpoints {
|
for outpoint in outpoints {
|
||||||
let txid = outpoint.txid;
|
let op_txid = outpoint.txid;
|
||||||
let tx = client.transaction_get(&txid)?;
|
let op_tx = fetch_tx(client, tx_cache, op_txid)?;
|
||||||
debug_assert_eq!(tx.txid(), txid);
|
let op_txout = match op_tx.output.get(outpoint.vout as usize) {
|
||||||
let txout = match tx.output.get(outpoint.vout as usize) {
|
|
||||||
Some(txout) => txout,
|
Some(txout) => txout,
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
debug_assert_eq!(op_tx.txid(), op_txid);
|
||||||
|
|
||||||
// attempt to find the following transactions (alongside their chain positions), and
|
// attempt to find the following transactions (alongside their chain positions), and
|
||||||
// add to our sparsechain `update`:
|
// add to our sparsechain `update`:
|
||||||
let mut has_residing = false; // tx in which the outpoint resides
|
let mut has_residing = false; // tx in which the outpoint resides
|
||||||
let mut has_spending = false; // tx that spends the outpoint
|
let mut has_spending = false; // tx that spends the outpoint
|
||||||
for res in client.script_get_history(&txout.script_pubkey)? {
|
for res in client.script_get_history(&op_txout.script_pubkey)? {
|
||||||
if has_residing && has_spending {
|
if has_residing && has_spending {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.tx_hash == txid {
|
if !has_residing && res.tx_hash == op_txid {
|
||||||
if has_residing {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
has_residing = true;
|
has_residing = true;
|
||||||
if graph_update.get_tx(res.tx_hash).is_none() {
|
let _ = graph_update.insert_tx(Arc::clone(&op_tx));
|
||||||
let _ = graph_update.insert_tx(tx.clone());
|
if let Some(anchor) = determine_tx_anchor(cps, res.height, res.tx_hash) {
|
||||||
|
let _ = graph_update.insert_anchor(res.tx_hash, anchor);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if has_spending {
|
|
||||||
continue;
|
if !has_spending && res.tx_hash != op_txid {
|
||||||
}
|
let res_tx = fetch_tx(client, tx_cache, res.tx_hash)?;
|
||||||
let res_tx = match graph_update.get_tx(res.tx_hash) {
|
// we exclude txs/anchors that do not spend our specified outpoint(s)
|
||||||
Some(tx) => tx,
|
|
||||||
None => {
|
|
||||||
let res_tx = fetch_tx(client, tx_cache, res.tx_hash)?;
|
|
||||||
let _ = graph_update.insert_tx(Arc::clone(&res_tx));
|
|
||||||
res_tx
|
|
||||||
}
|
|
||||||
};
|
|
||||||
has_spending = res_tx
|
has_spending = res_tx
|
||||||
.input
|
.input
|
||||||
.iter()
|
.iter()
|
||||||
@ -446,16 +444,17 @@ fn populate_with_outpoints(
|
|||||||
if !has_spending {
|
if !has_spending {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
let _ = graph_update.insert_tx(Arc::clone(&res_tx));
|
||||||
|
if let Some(anchor) = determine_tx_anchor(cps, res.height, res.tx_hash) {
|
||||||
if let Some(anchor) = determine_tx_anchor(cps, res.height, res.tx_hash) {
|
let _ = graph_update.insert_anchor(res.tx_hash, anchor);
|
||||||
let _ = graph_update.insert_anchor(res.tx_hash, anchor);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Populate the `graph_update` with transactions/anchors of the provided `txids`.
|
||||||
fn populate_with_txids(
|
fn populate_with_txids(
|
||||||
client: &impl ElectrumApi,
|
client: &impl ElectrumApi,
|
||||||
cps: &BTreeMap<u32, CheckPoint>,
|
cps: &BTreeMap<u32, CheckPoint>,
|
||||||
@ -476,6 +475,8 @@ fn populate_with_txids(
|
|||||||
.map(|txo| &txo.script_pubkey)
|
.map(|txo| &txo.script_pubkey)
|
||||||
.expect("tx must have an output");
|
.expect("tx must have an output");
|
||||||
|
|
||||||
|
// because of restrictions of the Electrum API, we have to use the `script_get_history`
|
||||||
|
// call to get confirmation status of our transaction
|
||||||
let anchor = match client
|
let anchor = match client
|
||||||
.script_get_history(spk)?
|
.script_get_history(spk)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -485,9 +486,7 @@ fn populate_with_txids(
|
|||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
if graph_update.get_tx(txid).is_none() {
|
let _ = graph_update.insert_tx(tx);
|
||||||
let _ = graph_update.insert_tx(tx);
|
|
||||||
}
|
|
||||||
if let Some(anchor) = anchor {
|
if let Some(anchor) = anchor {
|
||||||
let _ = graph_update.insert_anchor(txid, anchor);
|
let _ = graph_update.insert_anchor(txid, anchor);
|
||||||
}
|
}
|
||||||
@ -495,6 +494,9 @@ fn populate_with_txids(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch transaction of given `txid`.
|
||||||
|
///
|
||||||
|
/// We maintain a `tx_cache` so that we won't need to fetch from Electrum with every call.
|
||||||
fn fetch_tx<C: ElectrumApi>(
|
fn fetch_tx<C: ElectrumApi>(
|
||||||
client: &C,
|
client: &C,
|
||||||
tx_cache: &mut TxCache,
|
tx_cache: &mut TxCache,
|
||||||
@ -530,6 +532,13 @@ fn fetch_prev_txout<C: ElectrumApi>(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Populate the `graph_update` with transactions/anchors associated with the given `spks`.
|
||||||
|
///
|
||||||
|
/// Transactions that contains an output with requested spk, or spends form an output with
|
||||||
|
/// requested spk will be added to `graph_update`. Anchors of the aforementioned transactions are
|
||||||
|
/// also included.
|
||||||
|
///
|
||||||
|
/// Checkpoints (in `cps`) are used to create anchors. The `tx_cache` is self-explanatory.
|
||||||
fn populate_with_spks<I: Ord + Clone>(
|
fn populate_with_spks<I: Ord + Clone>(
|
||||||
client: &impl ElectrumApi,
|
client: &impl ElectrumApi,
|
||||||
cps: &BTreeMap<u32, CheckPoint>,
|
cps: &BTreeMap<u32, CheckPoint>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user