Skip to content

Commit d8c609b

Browse files
committed
refactor(wallet)!: change WeightedUtxo to use Weight type
1 parent 782eb56 commit d8c609b

File tree

5 files changed

+43
-68
lines changed

5 files changed

+43
-68
lines changed

crates/wallet/src/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use core::convert::AsRef;
1414

1515
use bdk_chain::ConfirmationTime;
1616
use bitcoin::blockdata::transaction::{OutPoint, Sequence, TxOut};
17-
use bitcoin::psbt;
17+
use bitcoin::{psbt, Weight};
1818

1919
use serde::{Deserialize, Serialize};
2020

@@ -72,7 +72,7 @@ pub struct WeightedUtxo {
7272
/// properly maintain the feerate when adding this input to a transaction during coin selection.
7373
///
7474
/// [weight units]: https://en.bitcoin.it/wiki/Weight_units
75-
pub satisfaction_weight: usize,
75+
pub satisfaction_weight: Weight,
7676
/// The UTXO
7777
pub utxo: Utxo,
7878
}

crates/wallet/src/wallet/coin_selection.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,10 @@
5252
//! (&mut selected_amount, &mut additional_weight),
5353
//! |(selected_amount, additional_weight), weighted_utxo| {
5454
//! **selected_amount += weighted_utxo.utxo.txout().value.to_sat();
55-
//! **additional_weight += Weight::from_wu(
56-
//! (TxIn::default().segwit_weight().to_wu()
57-
//! + weighted_utxo.satisfaction_weight as u64)
58-
//! as u64,
59-
//! );
55+
//! **additional_weight += TxIn::default()
56+
//! .segwit_weight()
57+
//! .checked_add(weighted_utxo.satisfaction_weight)
58+
//! .expect("`Weight` addition should not cause an integer overflow");
6059
//! Some(weighted_utxo.utxo)
6160
//! },
6261
//! )
@@ -343,10 +342,10 @@ fn select_sorted_utxos(
343342
|(selected_amount, fee_amount), (must_use, weighted_utxo)| {
344343
if must_use || **selected_amount < target_amount + **fee_amount {
345344
**fee_amount += (fee_rate
346-
* Weight::from_wu(
347-
TxIn::default().segwit_weight().to_wu()
348-
+ weighted_utxo.satisfaction_weight as u64,
349-
))
345+
* (TxIn::default()
346+
.segwit_weight()
347+
.checked_add(weighted_utxo.satisfaction_weight)
348+
.expect("`Weight` addition should not cause an integer overflow")))
350349
.to_sat();
351350
**selected_amount += weighted_utxo.utxo.txout().value.to_sat();
352351
Some(weighted_utxo.utxo)
@@ -389,9 +388,10 @@ struct OutputGroup {
389388
impl OutputGroup {
390389
fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self {
391390
let fee = (fee_rate
392-
* Weight::from_wu(
393-
TxIn::default().segwit_weight().to_wu() + weighted_utxo.satisfaction_weight as u64,
394-
))
391+
* (TxIn::default()
392+
.segwit_weight()
393+
.checked_add(weighted_utxo.satisfaction_weight)
394+
.expect("`Weight` addition should not cause an integer overflow")))
395395
.to_sat();
396396
let effective_value = weighted_utxo.utxo.txout().value.to_sat() as i64 - fee as i64;
397397
OutputGroup {
@@ -766,7 +766,7 @@ mod test {
766766
))
767767
.unwrap();
768768
WeightedUtxo {
769-
satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
769+
satisfaction_weight: Weight::from_wu_usize(P2WPKH_SATISFACTION_SIZE),
770770
utxo: Utxo::Local(LocalOutput {
771771
outpoint,
772772
txout: TxOut {
@@ -826,7 +826,7 @@ mod test {
826826
let mut res = Vec::new();
827827
for i in 0..utxos_number {
828828
res.push(WeightedUtxo {
829-
satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
829+
satisfaction_weight: Weight::from_wu_usize(P2WPKH_SATISFACTION_SIZE),
830830
utxo: Utxo::Local(LocalOutput {
831831
outpoint: OutPoint::from_str(&format!(
832832
"ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:{}",
@@ -857,7 +857,7 @@ mod test {
857857
fn generate_same_value_utxos(utxos_value: u64, utxos_number: usize) -> Vec<WeightedUtxo> {
858858
(0..utxos_number)
859859
.map(|i| WeightedUtxo {
860-
satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
860+
satisfaction_weight: Weight::from_wu_usize(P2WPKH_SATISFACTION_SIZE),
861861
utxo: Utxo::Local(LocalOutput {
862862
outpoint: OutPoint::from_str(&format!(
863863
"ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:{}",
@@ -1512,7 +1512,7 @@ mod test {
15121512
fn test_filter_duplicates() {
15131513
fn utxo(txid: &str, value: u64) -> WeightedUtxo {
15141514
WeightedUtxo {
1515-
satisfaction_weight: 0,
1515+
satisfaction_weight: Weight::ZERO,
15161516
utxo: Utxo::Local(LocalOutput {
15171517
outpoint: OutPoint::new(bitcoin::hashes::Hash::hash(txid.as_bytes()), 0),
15181518
txout: TxOut {

crates/wallet/src/wallet/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,17 @@ use bdk_chain::{
3232
Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeHeightAnchor, FullTxOut,
3333
Indexed, IndexedTxGraph,
3434
};
35-
use bitcoin::secp256k1::{All, Secp256k1};
3635
use bitcoin::sighash::{EcdsaSighashType, TapSighashType};
3736
use bitcoin::{
3837
absolute, psbt, Address, Block, FeeRate, Network, OutPoint, Script, ScriptBuf, Sequence,
3938
Transaction, TxOut, Txid, Witness,
4039
};
4140
use bitcoin::{consensus::encode::serialize, transaction, BlockHash, Psbt};
4241
use bitcoin::{constants::genesis_block, Amount};
42+
use bitcoin::{
43+
secp256k1::{All, Secp256k1},
44+
Weight,
45+
};
4346
use core::fmt;
4447
use core::ops::Deref;
4548
use descriptor::error::Error as DescriptorError;
@@ -1643,8 +1646,7 @@ impl Wallet {
16431646
let satisfaction_weight = self
16441647
.get_descriptor_for_keychain(keychain)
16451648
.max_weight_to_satisfy()
1646-
.unwrap()
1647-
.to_wu() as usize;
1649+
.unwrap();
16481650
WeightedUtxo {
16491651
utxo: Utxo::Local(LocalOutput {
16501652
outpoint: txin.previous_output,
@@ -1658,8 +1660,9 @@ impl Wallet {
16581660
}
16591661
}
16601662
None => {
1661-
let satisfaction_weight =
1662-
serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len();
1663+
let satisfaction_weight = Weight::from_wu_usize(
1664+
serialize(&txin.script_sig).len() * 4 + serialize(&txin.witness).len(),
1665+
);
16631666
WeightedUtxo {
16641667
utxo: Utxo::Foreign {
16651668
outpoint: txin.previous_output,
@@ -1968,15 +1971,14 @@ impl Wallet {
19681971
descriptor.at_derivation_index(child).ok()
19691972
}
19701973

1971-
fn get_available_utxos(&self) -> Vec<(LocalOutput, usize)> {
1974+
fn get_available_utxos(&self) -> Vec<(LocalOutput, Weight)> {
19721975
self.list_unspent()
19731976
.map(|utxo| {
19741977
let keychain = utxo.keychain;
19751978
(utxo, {
19761979
self.get_descriptor_for_keychain(keychain)
19771980
.max_weight_to_satisfy()
19781981
.unwrap()
1979-
.to_wu() as usize
19801982
})
19811983
})
19821984
.collect()

crates/wallet/src/wallet/tx_builder.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ use core::fmt;
4444

4545
use bitcoin::psbt::{self, Psbt};
4646
use bitcoin::script::PushBytes;
47-
use bitcoin::{absolute, Amount, FeeRate, OutPoint, ScriptBuf, Sequence, Transaction, Txid};
47+
use bitcoin::{
48+
absolute, Amount, FeeRate, OutPoint, ScriptBuf, Sequence, Transaction, Txid, Weight,
49+
};
4850

4951
use super::coin_selection::CoinSelectionAlgorithm;
5052
use super::{CreateTxError, Wallet};
@@ -293,9 +295,7 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
293295

294296
for utxo in utxos {
295297
let descriptor = wallet.get_descriptor_for_keychain(utxo.keychain);
296-
297-
let satisfaction_weight =
298-
descriptor.max_weight_to_satisfy().unwrap().to_wu() as usize;
298+
let satisfaction_weight = descriptor.max_weight_to_satisfy().unwrap();
299299
self.params.utxos.push(WeightedUtxo {
300300
satisfaction_weight,
301301
utxo: Utxo::Local(utxo),
@@ -364,7 +364,7 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
364364
&mut self,
365365
outpoint: OutPoint,
366366
psbt_input: psbt::Input,
367-
satisfaction_weight: usize,
367+
satisfaction_weight: Weight,
368368
) -> Result<&mut Self, AddForeignUtxoError> {
369369
self.add_foreign_utxo_with_sequence(
370370
outpoint,
@@ -379,7 +379,7 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
379379
&mut self,
380380
outpoint: OutPoint,
381381
psbt_input: psbt::Input,
382-
satisfaction_weight: usize,
382+
satisfaction_weight: Weight,
383383
sequence: Sequence,
384384
) -> Result<&mut Self, AddForeignUtxoError> {
385385
if psbt_input.witness_utxo.is_none() {

crates/wallet/tests/wallet.rs

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,11 +1375,7 @@ fn test_add_foreign_utxo() {
13751375
builder
13761376
.add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
13771377
.only_witness_utxo()
1378-
.add_foreign_utxo(
1379-
utxo.outpoint,
1380-
psbt_input,
1381-
foreign_utxo_satisfaction.to_wu() as usize,
1382-
)
1378+
.add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
13831379
.unwrap();
13841380
let mut psbt = builder.finish().unwrap();
13851381
wallet1.insert_txout(utxo.outpoint, utxo.txout);
@@ -1455,11 +1451,7 @@ fn test_calculate_fee_with_missing_foreign_utxo() {
14551451
builder
14561452
.add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
14571453
.only_witness_utxo()
1458-
.add_foreign_utxo(
1459-
utxo.outpoint,
1460-
psbt_input,
1461-
foreign_utxo_satisfaction.to_wu() as usize,
1462-
)
1454+
.add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
14631455
.unwrap();
14641456
let psbt = builder.finish().unwrap();
14651457
let tx = psbt.extract_tx().expect("failed to extract tx");
@@ -1476,11 +1468,8 @@ fn test_add_foreign_utxo_invalid_psbt_input() {
14761468
.unwrap();
14771469

14781470
let mut builder = wallet.build_tx();
1479-
let result = builder.add_foreign_utxo(
1480-
outpoint,
1481-
psbt::Input::default(),
1482-
foreign_utxo_satisfaction.to_wu() as usize,
1483-
);
1471+
let result =
1472+
builder.add_foreign_utxo(outpoint, psbt::Input::default(), foreign_utxo_satisfaction);
14841473
assert!(matches!(result, Err(AddForeignUtxoError::MissingUtxo)));
14851474
}
14861475

@@ -1508,7 +1497,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
15081497
non_witness_utxo: Some(tx1.as_ref().clone()),
15091498
..Default::default()
15101499
},
1511-
satisfaction_weight.to_wu() as usize
1500+
satisfaction_weight
15121501
)
15131502
.is_err(),
15141503
"should fail when outpoint doesn't match psbt_input"
@@ -1521,7 +1510,7 @@ fn test_add_foreign_utxo_where_outpoint_doesnt_match_psbt_input() {
15211510
non_witness_utxo: Some(tx2.as_ref().clone()),
15221511
..Default::default()
15231512
},
1524-
satisfaction_weight.to_wu() as usize
1513+
satisfaction_weight
15251514
)
15261515
.is_ok(),
15271516
"should be ok when outpoint does match psbt_input"
@@ -1553,11 +1542,7 @@ fn test_add_foreign_utxo_only_witness_utxo() {
15531542
..Default::default()
15541543
};
15551544
builder
1556-
.add_foreign_utxo(
1557-
utxo2.outpoint,
1558-
psbt_input,
1559-
satisfaction_weight.to_wu() as usize,
1560-
)
1545+
.add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
15611546
.unwrap();
15621547
assert!(
15631548
builder.finish().is_err(),
@@ -1573,11 +1558,7 @@ fn test_add_foreign_utxo_only_witness_utxo() {
15731558
};
15741559
builder
15751560
.only_witness_utxo()
1576-
.add_foreign_utxo(
1577-
utxo2.outpoint,
1578-
psbt_input,
1579-
satisfaction_weight.to_wu() as usize,
1580-
)
1561+
.add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
15811562
.unwrap();
15821563
assert!(
15831564
builder.finish().is_ok(),
@@ -1593,11 +1574,7 @@ fn test_add_foreign_utxo_only_witness_utxo() {
15931574
..Default::default()
15941575
};
15951576
builder
1596-
.add_foreign_utxo(
1597-
utxo2.outpoint,
1598-
psbt_input,
1599-
satisfaction_weight.to_wu() as usize,
1600-
)
1577+
.add_foreign_utxo(utxo2.outpoint, psbt_input, satisfaction_weight)
16011578
.unwrap();
16021579
assert!(
16031580
builder.finish().is_ok(),
@@ -3415,11 +3392,7 @@ fn test_taproot_foreign_utxo() {
34153392
let mut builder = wallet1.build_tx();
34163393
builder
34173394
.add_recipient(addr.script_pubkey(), Amount::from_sat(60_000))
3418-
.add_foreign_utxo(
3419-
utxo.outpoint,
3420-
psbt_input,
3421-
foreign_utxo_satisfaction.to_wu() as usize,
3422-
)
3395+
.add_foreign_utxo(utxo.outpoint, psbt_input, foreign_utxo_satisfaction)
34233396
.unwrap();
34243397
let psbt = builder.finish().unwrap();
34253398
let sent_received =

0 commit comments

Comments
 (0)