Skip to content

Commit 7aca884

Browse files
Merge bitcoindevkit#1308: feat(esplora): include previous TxOuts for fee calculation
552f11c feat(esplora): include previous `TxOut`s for fee calculation The previous `TxOut` for transactions received from an external wallet are added as floating `TxOut`s to `TxGraph` to allow for fee calculation. (Wei Chen) Pull request description: ### Description Partially implements bitcoindevkit#1265. The previous `TxOut` for transactions received from an external wallet are added as floating `TxOut`s to `TxGraph` to allow for fee calculation. ### Notes to the reviewers Currently only the `esplora` portion of bitcoindevkit#1265 has been implemented. The `electrum` portion will potentially be done in a new PR, as discussed on the 1/30/24 Lib call. ### Checklists #### To Do: * [ ] Implement `electrum` portion of bitcoindevkit#1265. #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [x] I've added tests for the new feature * [x] I've added docs for the new feature ACKs for top commit: evanlinjin: re-ACK 552f11c danielabrozzoni: ACK 552f11c Tree-SHA512: 752a24ebd0b9ad7952c1b093ecb251473e346c77b860c1a80c73418130189227405a0f0d7652967cf8c7b89994e8c37df96cd52b52b6daff9cc8c88b5194069a
2 parents b3278a4 + 552f11c commit 7aca884

File tree

4 files changed

+82
-2
lines changed

4 files changed

+82
-2
lines changed

Diff for: crates/esplora/src/async_ext.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use async_trait::async_trait;
22
use bdk_chain::collections::btree_map;
33
use bdk_chain::{
4-
bitcoin::{BlockHash, OutPoint, ScriptBuf, Txid},
4+
bitcoin::{BlockHash, OutPoint, ScriptBuf, TxOut, Txid},
55
collections::BTreeMap,
66
local_chain::{self, CheckPoint},
77
BlockId, ConfirmationTimeHeightAnchor, TxGraph,
@@ -204,6 +204,24 @@ impl EsploraAsyncExt for esplora_client::AsyncClient {
204204
if let Some(anchor) = anchor_from_status(&tx.status) {
205205
let _ = graph.insert_anchor(tx.txid, anchor);
206206
}
207+
208+
let previous_outputs = tx.vin.iter().filter_map(|vin| {
209+
let prevout = vin.prevout.as_ref()?;
210+
Some((
211+
OutPoint {
212+
txid: vin.txid,
213+
vout: vin.vout,
214+
},
215+
TxOut {
216+
script_pubkey: prevout.scriptpubkey.clone(),
217+
value: prevout.value,
218+
},
219+
))
220+
});
221+
222+
for (outpoint, txout) in previous_outputs {
223+
let _ = graph.insert_txout(outpoint, txout);
224+
}
207225
}
208226
}
209227

Diff for: crates/esplora/src/blocking_ext.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::thread::JoinHandle;
33
use bdk_chain::collections::btree_map;
44
use bdk_chain::collections::BTreeMap;
55
use bdk_chain::{
6-
bitcoin::{BlockHash, OutPoint, ScriptBuf, Txid},
6+
bitcoin::{BlockHash, OutPoint, ScriptBuf, TxOut, Txid},
77
local_chain::{self, CheckPoint},
88
BlockId, ConfirmationTimeHeightAnchor, TxGraph,
99
};
@@ -194,6 +194,24 @@ impl EsploraExt for esplora_client::BlockingClient {
194194
if let Some(anchor) = anchor_from_status(&tx.status) {
195195
let _ = graph.insert_anchor(tx.txid, anchor);
196196
}
197+
198+
let previous_outputs = tx.vin.iter().filter_map(|vin| {
199+
let prevout = vin.prevout.as_ref()?;
200+
Some((
201+
OutPoint {
202+
txid: vin.txid,
203+
vout: vin.vout,
204+
},
205+
TxOut {
206+
script_pubkey: prevout.scriptpubkey.clone(),
207+
value: prevout.value,
208+
},
209+
))
210+
});
211+
212+
for (outpoint, txout) in previous_outputs {
213+
let _ = graph.insert_txout(outpoint, txout);
214+
}
197215
}
198216
}
199217

Diff for: crates/esplora/tests/async_ext.rs

+22
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,28 @@ pub async fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> {
109109
)
110110
.await?;
111111

112+
// Check to see if we have the floating txouts available from our two created transactions'
113+
// previous outputs in order to calculate transaction fees.
114+
for tx in graph_update.full_txs() {
115+
// Retrieve the calculated fee from `TxGraph`, which will panic if we do not have the
116+
// floating txouts available from the transactions' previous outputs.
117+
let fee = graph_update.calculate_fee(tx.tx).expect("Fee must exist");
118+
119+
// Retrieve the fee in the transaction data from `bitcoind`.
120+
let tx_fee = env
121+
.bitcoind
122+
.client
123+
.get_transaction(&tx.txid, None)
124+
.expect("Tx must exist")
125+
.fee
126+
.expect("Fee must exist")
127+
.abs()
128+
.to_sat() as u64;
129+
130+
// Check that the calculated fee matches the fee from the transaction data.
131+
assert_eq!(fee, tx_fee);
132+
}
133+
112134
let mut graph_update_txids: Vec<Txid> = graph_update.full_txs().map(|tx| tx.txid).collect();
113135
graph_update_txids.sort();
114136
let mut expected_txids = vec![txid1, txid2];

Diff for: crates/esplora/tests/blocking_ext.rs

+22
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,28 @@ pub fn test_update_tx_graph_without_keychain() -> anyhow::Result<()> {
136136
1,
137137
)?;
138138

139+
// Check to see if we have the floating txouts available from our two created transactions'
140+
// previous outputs in order to calculate transaction fees.
141+
for tx in graph_update.full_txs() {
142+
// Retrieve the calculated fee from `TxGraph`, which will panic if we do not have the
143+
// floating txouts available from the transactions' previous outputs.
144+
let fee = graph_update.calculate_fee(tx.tx).expect("Fee must exist");
145+
146+
// Retrieve the fee in the transaction data from `bitcoind`.
147+
let tx_fee = env
148+
.bitcoind
149+
.client
150+
.get_transaction(&tx.txid, None)
151+
.expect("Tx must exist")
152+
.fee
153+
.expect("Fee must exist")
154+
.abs()
155+
.to_sat() as u64;
156+
157+
// Check that the calculated fee matches the fee from the transaction data.
158+
assert_eq!(fee, tx_fee);
159+
}
160+
139161
let mut graph_update_txids: Vec<Txid> = graph_update.full_txs().map(|tx| tx.txid).collect();
140162
graph_update_txids.sort();
141163
let mut expected_txids = vec![txid1, txid2];

0 commit comments

Comments
 (0)