Skip to content

Commit d5c0e72

Browse files
committed
feat: use Amount on spk_txout_index and related
- update `wallet.rs` fns: `sent_and_received` fn - update `keychain` `txout_index` fn: `sent_and_received and `net_value`
1 parent 8a33d98 commit d5c0e72

File tree

5 files changed

+125
-69
lines changed

5 files changed

+125
-69
lines changed

crates/bdk/src/wallet/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ impl Wallet {
953953
.map(|fee| Amount::from_sat(fee) / tx.weight())
954954
}
955955

956-
/// Compute the `tx`'s sent and received amounts (in satoshis).
956+
/// Compute the `tx`'s sent and received [`Amount`]s.
957957
///
958958
/// This method returns a tuple `(sent, received)`. Sent is the sum of the txin amounts
959959
/// that spend from previous txouts tracked by this wallet. Received is the summation
@@ -978,7 +978,7 @@ impl Wallet {
978978
/// let tx = &psbt.clone().extract_tx().expect("tx");
979979
/// let (sent, received) = wallet.sent_and_received(tx);
980980
/// ```
981-
pub fn sent_and_received(&self, tx: &Transaction) -> (u64, u64) {
981+
pub fn sent_and_received(&self, tx: &Transaction) -> (Amount, Amount) {
982982
self.indexed_graph.index.sent_and_received(tx, ..)
983983
}
984984

crates/bdk/tests/wallet.rs

Lines changed: 73 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ fn test_get_funded_wallet_balance() {
207207
fn test_get_funded_wallet_sent_and_received() {
208208
let (wallet, txid) = get_funded_wallet(get_test_wpkh());
209209

210-
let mut tx_amounts: Vec<(Txid, (u64, u64))> = wallet
210+
let mut tx_amounts: Vec<(Txid, (Amount, Amount))> = wallet
211211
.transactions()
212212
.map(|ct| (ct.tx_node.txid, wallet.sent_and_received(&ct.tx_node)))
213213
.collect();
@@ -219,8 +219,8 @@ fn test_get_funded_wallet_sent_and_received() {
219219
// The funded wallet contains a tx with a 76_000 sats input and two outputs, one spending 25_000
220220
// to a foreign address and one returning 50_000 back to the wallet as change. The remaining 1000
221221
// sats are the transaction fee.
222-
assert_eq!(sent, 76_000);
223-
assert_eq!(received, 50_000);
222+
assert_eq!(sent.to_sat(), 76_000);
223+
assert_eq!(received.to_sat(), 50_000);
224224
}
225225

226226
#[test]
@@ -1034,7 +1034,8 @@ fn test_create_tx_add_utxo() {
10341034
"should add an additional input since 25_000 < 30_000"
10351035
);
10361036
assert_eq!(
1037-
sent_received.0, 75_000,
1037+
sent_received.0,
1038+
Amount::from_sat(75_000),
10381039
"total should be sum of both inputs"
10391040
);
10401041
}
@@ -1225,7 +1226,7 @@ fn test_add_foreign_utxo() {
12251226
wallet1.sent_and_received(&psbt.clone().extract_tx().expect("failed to extract tx"));
12261227

12271228
assert_eq!(
1228-
sent_received.0 - sent_received.1,
1229+
(sent_received.0 - sent_received.1).to_sat(),
12291230
10_000 + fee.unwrap_or(0),
12301231
"we should have only net spent ~10_000"
12311232
);
@@ -1622,8 +1623,8 @@ fn test_bump_fee_reduce_change() {
16221623

16231624
assert_eq!(sent_received.0, original_sent_received.0);
16241625
assert_eq!(
1625-
sent_received.1 + fee.unwrap_or(0),
1626-
original_sent_received.1 + original_fee.unwrap_or(0)
1626+
sent_received.1 + Amount::from_sat(fee.unwrap_or(0)),
1627+
original_sent_received.1 + Amount::from_sat(original_fee.unwrap_or(0))
16271628
);
16281629
assert!(fee.unwrap_or(0) > original_fee.unwrap_or(0));
16291630

@@ -1642,8 +1643,7 @@ fn test_bump_fee_reduce_change() {
16421643
.iter()
16431644
.find(|txout| txout.script_pubkey != addr.script_pubkey())
16441645
.unwrap()
1645-
.value
1646-
.to_sat(),
1646+
.value,
16471647
sent_received.1
16481648
);
16491649

@@ -1659,8 +1659,8 @@ fn test_bump_fee_reduce_change() {
16591659

16601660
assert_eq!(sent_received.0, original_sent_received.0);
16611661
assert_eq!(
1662-
sent_received.1 + fee.unwrap_or(0),
1663-
original_sent_received.1 + original_fee.unwrap_or(0)
1662+
sent_received.1 + Amount::from_sat(fee.unwrap_or(0)),
1663+
original_sent_received.1 + Amount::from_sat(original_fee.unwrap_or(0))
16641664
);
16651665
assert!(
16661666
fee.unwrap_or(0) > original_fee.unwrap_or(0),
@@ -1684,8 +1684,7 @@ fn test_bump_fee_reduce_change() {
16841684
.iter()
16851685
.find(|txout| txout.script_pubkey != addr.script_pubkey())
16861686
.unwrap()
1687-
.value
1688-
.to_sat(),
1687+
.value,
16891688
sent_received.1
16901689
);
16911690

@@ -1729,7 +1728,7 @@ fn test_bump_fee_reduce_single_recipient() {
17291728
let tx = &psbt.unsigned_tx;
17301729
assert_eq!(tx.output.len(), 1);
17311730
assert_eq!(
1732-
tx.output[0].value.to_sat() + fee.unwrap_or(0),
1731+
tx.output[0].value + Amount::from_sat(fee.unwrap_or(0)),
17331732
sent_received.0
17341733
);
17351734

@@ -1771,7 +1770,7 @@ fn test_bump_fee_absolute_reduce_single_recipient() {
17711770

17721771
assert_eq!(tx.output.len(), 1);
17731772
assert_eq!(
1774-
tx.output[0].value.to_sat() + fee.unwrap_or(0),
1773+
tx.output[0].value + Amount::from_sat(fee.unwrap_or(0)),
17751774
sent_received.0
17761775
);
17771776

@@ -1825,7 +1824,7 @@ fn test_bump_fee_drain_wallet() {
18251824
wallet
18261825
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
18271826
.unwrap();
1828-
assert_eq!(original_sent_received.0, 25_000);
1827+
assert_eq!(original_sent_received.0, Amount::from_sat(25_000));
18291828

18301829
// for the new feerate, it should be enough to reduce the output, but since we specify
18311830
// `drain_wallet` we expect to spend everything
@@ -1838,7 +1837,7 @@ fn test_bump_fee_drain_wallet() {
18381837
let psbt = builder.finish().unwrap();
18391838
let sent_received = wallet.sent_and_received(&psbt.extract_tx().expect("failed to extract tx"));
18401839

1841-
assert_eq!(sent_received.0, 75_000);
1840+
assert_eq!(sent_received.0, Amount::from_sat(75_000));
18421841
}
18431842

18441843
#[test]
@@ -1895,7 +1894,7 @@ fn test_bump_fee_remove_output_manually_selected_only() {
18951894
wallet
18961895
.insert_tx(tx, ConfirmationTime::Unconfirmed { last_seen: 0 })
18971896
.unwrap();
1898-
assert_eq!(original_sent_received.0, 25_000);
1897+
assert_eq!(original_sent_received.0, Amount::from_sat(25_000));
18991898

19001899
let mut builder = wallet.build_fee_bump(txid).unwrap();
19011900
builder
@@ -1949,8 +1948,14 @@ fn test_bump_fee_add_input() {
19491948
let sent_received =
19501949
wallet.sent_and_received(&psbt.clone().extract_tx().expect("failed to extract tx"));
19511950
let fee = check_fee!(wallet, psbt);
1952-
assert_eq!(sent_received.0, original_details.0 + 25_000);
1953-
assert_eq!(fee.unwrap_or(0) + sent_received.1, 30_000);
1951+
assert_eq!(
1952+
sent_received.0,
1953+
original_details.0 + Amount::from_sat(25_000)
1954+
);
1955+
assert_eq!(
1956+
Amount::from_sat(fee.unwrap_or(0)) + sent_received.1,
1957+
Amount::from_sat(30_000)
1958+
);
19541959

19551960
let tx = &psbt.unsigned_tx;
19561961
assert_eq!(tx.input.len(), 2);
@@ -1968,8 +1973,7 @@ fn test_bump_fee_add_input() {
19681973
.iter()
19691974
.find(|txout| txout.script_pubkey != addr.script_pubkey())
19701975
.unwrap()
1971-
.value
1972-
.to_sat(),
1976+
.value,
19731977
sent_received.1
19741978
);
19751979

@@ -2002,8 +2006,14 @@ fn test_bump_fee_absolute_add_input() {
20022006
wallet.sent_and_received(&psbt.clone().extract_tx().expect("failed to extract tx"));
20032007
let fee = check_fee!(wallet, psbt);
20042008

2005-
assert_eq!(sent_received.0, original_sent_received.0 + 25_000);
2006-
assert_eq!(fee.unwrap_or(0) + sent_received.1, 30_000);
2009+
assert_eq!(
2010+
sent_received.0,
2011+
original_sent_received.0 + Amount::from_sat(25_000)
2012+
);
2013+
assert_eq!(
2014+
Amount::from_sat(fee.unwrap_or(0)) + sent_received.1,
2015+
Amount::from_sat(30_000)
2016+
);
20072017

20082018
let tx = &psbt.unsigned_tx;
20092019
assert_eq!(tx.input.len(), 2);
@@ -2021,8 +2031,7 @@ fn test_bump_fee_absolute_add_input() {
20212031
.iter()
20222032
.find(|txout| txout.script_pubkey != addr.script_pubkey())
20232033
.unwrap()
2024-
.value
2025-
.to_sat(),
2034+
.value,
20262035
sent_received.1
20272036
);
20282037

@@ -2065,11 +2074,15 @@ fn test_bump_fee_no_change_add_input_and_change() {
20652074
wallet.sent_and_received(&psbt.clone().extract_tx().expect("failed to extract tx"));
20662075
let fee = check_fee!(wallet, psbt);
20672076

2068-
let original_send_all_amount = original_sent_received.0 - original_fee.unwrap_or(0);
2069-
assert_eq!(sent_received.0, original_sent_received.0 + 50_000);
2077+
let original_send_all_amount =
2078+
original_sent_received.0 - Amount::from_sat(original_fee.unwrap_or(0));
2079+
assert_eq!(
2080+
sent_received.0,
2081+
original_sent_received.0 + Amount::from_sat(50_000)
2082+
);
20702083
assert_eq!(
20712084
sent_received.1,
2072-
75_000 - original_send_all_amount - fee.unwrap_or(0)
2085+
Amount::from_sat(75_000) - original_send_all_amount - Amount::from_sat(fee.unwrap_or(0))
20732086
);
20742087

20752088
let tx = &psbt.unsigned_tx;
@@ -2081,16 +2094,15 @@ fn test_bump_fee_no_change_add_input_and_change() {
20812094
.find(|txout| txout.script_pubkey == addr.script_pubkey())
20822095
.unwrap()
20832096
.value,
2084-
Amount::from_sat(original_send_all_amount)
2097+
original_send_all_amount
20852098
);
20862099
assert_eq!(
20872100
tx.output
20882101
.iter()
20892102
.find(|txout| txout.script_pubkey != addr.script_pubkey())
20902103
.unwrap()
2091-
.value
2092-
.to_sat(),
2093-
75_000 - original_send_all_amount - fee.unwrap_or(0)
2104+
.value,
2105+
Amount::from_sat(75_000) - original_send_all_amount - Amount::from_sat(fee.unwrap_or(0))
20942106
);
20952107

20962108
assert_fee_rate!(psbt, fee.unwrap_or(0), FeeRate::from_sat_per_vb_unchecked(50), @add_signature);
@@ -2145,11 +2157,17 @@ fn test_bump_fee_add_input_change_dust() {
21452157
wallet.sent_and_received(&psbt.clone().extract_tx().expect("failed to extract tx"));
21462158
let fee = check_fee!(wallet, psbt);
21472159

2148-
assert_eq!(original_sent_received.1, 5_000 - original_fee.unwrap_or(0));
2160+
assert_eq!(
2161+
original_sent_received.1,
2162+
Amount::from_sat(5_000 - original_fee.unwrap_or(0))
2163+
);
21492164

2150-
assert_eq!(sent_received.0, original_sent_received.0 + 25_000);
2165+
assert_eq!(
2166+
sent_received.0,
2167+
original_sent_received.0 + Amount::from_sat(25_000)
2168+
);
21512169
assert_eq!(fee.unwrap_or(0), 30_000);
2152-
assert_eq!(sent_received.1, 0);
2170+
assert_eq!(sent_received.1, Amount::ZERO);
21532171

21542172
let tx = &psbt.unsigned_tx;
21552173
assert_eq!(tx.input.len(), 2);
@@ -2200,8 +2218,14 @@ fn test_bump_fee_force_add_input() {
22002218
wallet.sent_and_received(&psbt.clone().extract_tx().expect("failed to extract tx"));
22012219
let fee = check_fee!(wallet, psbt);
22022220

2203-
assert_eq!(sent_received.0, original_sent_received.0 + 25_000);
2204-
assert_eq!(fee.unwrap_or(0) + sent_received.1, 30_000);
2221+
assert_eq!(
2222+
sent_received.0,
2223+
original_sent_received.0 + Amount::from_sat(25_000)
2224+
);
2225+
assert_eq!(
2226+
Amount::from_sat(fee.unwrap_or(0)) + sent_received.1,
2227+
Amount::from_sat(30_000)
2228+
);
22052229

22062230
let tx = &psbt.unsigned_tx;
22072231
assert_eq!(tx.input.len(), 2);
@@ -2219,8 +2243,7 @@ fn test_bump_fee_force_add_input() {
22192243
.iter()
22202244
.find(|txout| txout.script_pubkey != addr.script_pubkey())
22212245
.unwrap()
2222-
.value
2223-
.to_sat(),
2246+
.value,
22242247
sent_received.1
22252248
);
22262249

@@ -2260,8 +2283,14 @@ fn test_bump_fee_absolute_force_add_input() {
22602283
wallet.sent_and_received(&psbt.clone().extract_tx().expect("failed to extract tx"));
22612284
let fee = check_fee!(wallet, psbt);
22622285

2263-
assert_eq!(sent_received.0, original_sent_received.0 + 25_000);
2264-
assert_eq!(fee.unwrap_or(0) + sent_received.1, 30_000);
2286+
assert_eq!(
2287+
sent_received.0,
2288+
original_sent_received.0 + Amount::from_sat(25_000)
2289+
);
2290+
assert_eq!(
2291+
Amount::from_sat(fee.unwrap_or(0)) + sent_received.1,
2292+
Amount::from_sat(30_000)
2293+
);
22652294

22662295
let tx = &psbt.unsigned_tx;
22672296
assert_eq!(tx.input.len(), 2);
@@ -2279,8 +2308,7 @@ fn test_bump_fee_absolute_force_add_input() {
22792308
.iter()
22802309
.find(|txout| txout.script_pubkey != addr.script_pubkey())
22812310
.unwrap()
2282-
.value
2283-
.to_sat(),
2311+
.value,
22842312
sent_received.1
22852313
);
22862314

@@ -3228,7 +3256,7 @@ fn test_taproot_foreign_utxo() {
32283256

32293257
assert_eq!(
32303258
sent_received.0 - sent_received.1,
3231-
10_000 + fee.unwrap_or(0),
3259+
Amount::from_sat(10_000 + fee.unwrap_or(0)),
32323260
"we should have only net spent ~10_000"
32333261
);
32343262

crates/chain/src/keychain/txout_index.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
spk_iter::BIP32_MAX_INDEX,
66
SpkIterator, SpkTxOutIndex,
77
};
8-
use bitcoin::{OutPoint, Script, Transaction, TxOut, Txid};
8+
use bitcoin::{Amount, OutPoint, Script, SignedAmount, Transaction, TxOut, Txid};
99
use core::{
1010
fmt::Debug,
1111
ops::{Bound, RangeBounds},
@@ -273,7 +273,11 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
273273
/// *received* when it is on an output. For `sent` to be computed correctly, the output being
274274
/// spent must have already been scanned by the index. Calculating received just uses the
275275
/// [`Transaction`] outputs directly, so it will be correct even if it has not been scanned.
276-
pub fn sent_and_received(&self, tx: &Transaction, range: impl RangeBounds<K>) -> (u64, u64) {
276+
pub fn sent_and_received(
277+
&self,
278+
tx: &Transaction,
279+
range: impl RangeBounds<K>,
280+
) -> (Amount, Amount) {
277281
self.inner
278282
.sent_and_received(tx, Self::map_to_inner_bounds(range))
279283
}
@@ -285,7 +289,7 @@ impl<K: Clone + Ord + Debug> KeychainTxOutIndex<K> {
285289
/// This calls [`SpkTxOutIndex::net_value`] internally.
286290
///
287291
/// [`sent_and_received`]: Self::sent_and_received
288-
pub fn net_value(&self, tx: &Transaction, range: impl RangeBounds<K>) -> i64 {
292+
pub fn net_value(&self, tx: &Transaction, range: impl RangeBounds<K>) -> SignedAmount {
289293
self.inner.net_value(tx, Self::map_to_inner_bounds(range))
290294
}
291295
}

0 commit comments

Comments
 (0)