Skip to content

Commit

Permalink
feat(esplora): include previous TxOuts for fee calculation
Browse files Browse the repository at this point in the history
The previous `TxOut` for transactions received from an external
wallet are added as floating `TxOut`s to `TxGraph` to allow for
fee calculation.
  • Loading branch information
LagginTimes committed Jan 31, 2024
1 parent f099b42 commit 6e7075a
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 2 deletions.
26 changes: 25 additions & 1 deletion crates/esplora/src/async_ext.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use async_trait::async_trait;
use bdk_chain::collections::btree_map;
use bdk_chain::{
bitcoin::{BlockHash, OutPoint, ScriptBuf, Txid},
bitcoin::{BlockHash, OutPoint, ScriptBuf, TxOut, Txid},
collections::BTreeMap,
local_chain::{self, CheckPoint},
BlockId, ConfirmationTimeHeightAnchor, TxGraph,
Expand Down Expand Up @@ -204,6 +204,30 @@ impl EsploraAsyncExt for esplora_client::AsyncClient {
if let Some(anchor) = anchor_from_status(&tx.status) {
let _ = graph.insert_anchor(tx.txid, anchor);
}

let previous_outputs: Vec<(OutPoint, TxOut)> = tx
.vin
.iter()
.cloned()
.filter_map(|vin| {
vin.prevout.map(|po| {
(
OutPoint {
txid: vin.txid,
vout: vin.vout,
},
TxOut {
script_pubkey: po.scriptpubkey,
value: po.value,
},
)
})
})
.collect();

for (outpoint, txout) in previous_outputs {
let _ = graph.insert_txout(outpoint, txout);
}
}
}

Expand Down
26 changes: 25 additions & 1 deletion crates/esplora/src/blocking_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::thread::JoinHandle;
use bdk_chain::collections::btree_map;
use bdk_chain::collections::BTreeMap;
use bdk_chain::{
bitcoin::{BlockHash, OutPoint, ScriptBuf, Txid},
bitcoin::{BlockHash, OutPoint, ScriptBuf, TxOut, Txid},
local_chain::{self, CheckPoint},
BlockId, ConfirmationTimeHeightAnchor, TxGraph,
};
Expand Down Expand Up @@ -194,6 +194,30 @@ impl EsploraExt for esplora_client::BlockingClient {
if let Some(anchor) = anchor_from_status(&tx.status) {
let _ = graph.insert_anchor(tx.txid, anchor);
}

let previous_outputs: Vec<(OutPoint, TxOut)> = tx
.vin
.iter()
.cloned()
.filter_map(|vin| {
vin.prevout.map(|po| {
(
OutPoint {
txid: vin.txid,
vout: vin.vout,
},
TxOut {
script_pubkey: po.scriptpubkey,
value: po.value,
},
)
})
})
.collect();

for (outpoint, txout) in previous_outputs {
let _ = graph.insert_txout(outpoint, txout);
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions crates/esplora/tests/async_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ pub async fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> {
)
.await?;

// Check to see if we have the floating txouts available from our two created transactions'
// previous outputs in order to calculate transaction fees.
let fee_calculations = graph_update
.full_txs()
.map(|tx| graph_update.calculate_fee(tx.tx).is_ok())
.collect::<Vec<_>>();

// Ensure there are exactly two fee calculations.
assert_eq!(fee_calculations.len(), 2);

// Ensure that both fee calculations are successful.
assert!(fee_calculations.iter().all(|&is_ok| is_ok));

let mut graph_update_txids: Vec<Txid> = graph_update.full_txs().map(|tx| tx.txid).collect();
graph_update_txids.sort();
let mut expected_txids = vec![txid1, txid2];
Expand Down
13 changes: 13 additions & 0 deletions crates/esplora/tests/blocking_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,19 @@ pub fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> {
1,
)?;

// Check to see if we have the floating txouts available from our two created transactions'
// previous outputs in order to calculate transaction fees.
let fee_calculations = graph_update
.full_txs()
.map(|tx| graph_update.calculate_fee(tx.tx).is_ok())
.collect::<Vec<_>>();

// Ensure there are exactly two fee calculations.
assert_eq!(fee_calculations.len(), 2);

// Ensure that both fee calculations are successful.
assert!(fee_calculations.iter().all(|&is_ok| is_ok));

let mut graph_update_txids: Vec<Txid> = graph_update.full_txs().map(|tx| tx.txid).collect();
graph_update_txids.sort();
let mut expected_txids = vec![txid1, txid2];
Expand Down

0 comments on commit 6e7075a

Please sign in to comment.