Skip to content

Commit

Permalink
Merge #1595: refactor(wallet): use Amount everywhere
Browse files Browse the repository at this point in the history
292ec3c refactor(wallet): use `Amount` everywhere (valued mammal)

Pull request description:

  This is a followup to #1426 that refactors wallet internals to use `bitcoin::Amount` (nearly) everywhere. I chose not to change any public types in `coin_selection.rs` that still use `u64` as that might require more discussion.

  partially addresses #1432
  fixes #1434

  ### Checklists

  #### 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

ACKs for top commit:
  oleonardolima:
    ACK 292ec3c
  notmandatory:
    ACK 292ec3c

Tree-SHA512: e84c543e796e151803321ad238023bd5f446448b4430dd6c62929180d159ee1ef867e98f69a4ef3b152c3146b8e30bbf01ce7952ac00b726847a224dca7e3be4
  • Loading branch information
notmandatory committed Sep 9, 2024
2 parents b49b64b + 292ec3c commit 90a89bf
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 46 deletions.
26 changes: 13 additions & 13 deletions crates/wallet/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@ impl Wallet {
if let Some(previous_fee) = params.bumping_fee {
if fee < previous_fee.absolute {
return Err(CreateTxError::FeeTooLow {
required: Amount::from_sat(previous_fee.absolute),
required: previous_fee.absolute,
});
}
}
Expand All @@ -1423,7 +1423,7 @@ impl Wallet {
});
}
}
(rate, 0)
(rate, Amount::ZERO)
}
};

Expand All @@ -1449,20 +1449,20 @@ impl Wallet {
}

if self.is_mine(script_pubkey.clone()) {
received += Amount::from_sat(value);
received += value;
}

let new_out = TxOut {
script_pubkey: script_pubkey.clone(),
value: Amount::from_sat(value),
value,
};

tx.output.push(new_out);

outgoing += Amount::from_sat(value);
outgoing += value;
}

fee_amount += (fee_rate * tx.weight()).to_sat();
fee_amount += fee_rate * tx.weight();

let (required_utxos, optional_utxos) =
self.preselect_utxos(&params, Some(current_height.to_consensus_u32()));
Expand Down Expand Up @@ -1501,7 +1501,7 @@ impl Wallet {
required_utxos.clone(),
optional_utxos.clone(),
fee_rate,
outgoing.to_sat() + fee_amount,
outgoing.to_sat() + fee_amount.to_sat(),
&drain_script,
) {
Ok(res) => res,
Expand All @@ -1514,15 +1514,15 @@ impl Wallet {
coin_selection::single_random_draw(
required_utxos,
optional_utxos,
outgoing.to_sat() + fee_amount,
outgoing.to_sat() + fee_amount.to_sat(),
&drain_script,
fee_rate,
rng,
)
}
},
};
fee_amount += coin_selection.fee_amount;
fee_amount += Amount::from_sat(coin_selection.fee_amount);
let excess = &coin_selection.excess;

tx.input = coin_selection
Expand Down Expand Up @@ -1564,12 +1564,12 @@ impl Wallet {
match excess {
NoChange {
remaining_amount, ..
} => fee_amount += remaining_amount,
} => fee_amount += Amount::from_sat(*remaining_amount),
Change { amount, fee } => {
if self.is_mine(drain_script.clone()) {
received += Amount::from_sat(*amount);
}
fee_amount += fee;
fee_amount += Amount::from_sat(*fee);

// create drain output
let drain_output = TxOut {
Expand Down Expand Up @@ -1763,11 +1763,11 @@ impl Wallet {
recipients: tx
.output
.into_iter()
.map(|txout| (txout.script_pubkey, txout.value.to_sat()))
.map(|txout| (txout.script_pubkey, txout.value))
.collect(),
utxos: original_utxos,
bumping_fee: Some(tx_builder::PreviousFee {
absolute: fee.to_sat(),
absolute: fee,
rate: fee_rate,
}),
..Default::default()
Expand Down
17 changes: 6 additions & 11 deletions crates/wallet/src/wallet/tx_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub struct TxBuilder<'a, Cs> {
//TODO: TxParams should eventually be exposed publicly.
#[derive(Default, Debug, Clone)]
pub(crate) struct TxParams {
pub(crate) recipients: Vec<(ScriptBuf, u64)>,
pub(crate) recipients: Vec<(ScriptBuf, Amount)>,
pub(crate) drain_wallet: bool,
pub(crate) drain_to: Option<ScriptBuf>,
pub(crate) fee_policy: Option<FeePolicy>,
Expand All @@ -147,14 +147,14 @@ pub(crate) struct TxParams {

#[derive(Clone, Copy, Debug)]
pub(crate) struct PreviousFee {
pub absolute: u64,
pub absolute: Amount,
pub rate: FeeRate,
}

#[derive(Debug, Clone, Copy)]
pub(crate) enum FeePolicy {
FeeRate(FeeRate),
FeeAmount(u64),
FeeAmount(Amount),
}

impl Default for FeePolicy {
Expand Down Expand Up @@ -200,7 +200,7 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
/// overshoot it slightly since adding a change output to drain the remaining
/// excess might not be viable.
pub fn fee_absolute(&mut self, fee_amount: Amount) -> &mut Self {
self.params.fee_policy = Some(FeePolicy::FeeAmount(fee_amount.to_sat()));
self.params.fee_policy = Some(FeePolicy::FeeAmount(fee_amount));
self
}

Expand Down Expand Up @@ -601,18 +601,13 @@ impl<'a, Cs> TxBuilder<'a, Cs> {

/// Replace the recipients already added with a new list
pub fn set_recipients(&mut self, recipients: Vec<(ScriptBuf, Amount)>) -> &mut Self {
self.params.recipients = recipients
.into_iter()
.map(|(script, amount)| (script, amount.to_sat()))
.collect();
self.params.recipients = recipients;
self
}

/// Add a recipient to the internal list
pub fn add_recipient(&mut self, script_pubkey: ScriptBuf, amount: Amount) -> &mut Self {
self.params
.recipients
.push((script_pubkey, amount.to_sat()));
self.params.recipients.push((script_pubkey, amount));
self
}

Expand Down
10 changes: 8 additions & 2 deletions crates/wallet/src/wallet/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// licenses.

use bitcoin::secp256k1::{All, Secp256k1};
use bitcoin::{absolute, relative, Script, Sequence};
use bitcoin::{absolute, relative, Amount, Script, Sequence};

use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};

Expand All @@ -26,9 +26,15 @@ pub trait IsDust {
fn is_dust(&self, script: &Script) -> bool;
}

impl IsDust for Amount {
fn is_dust(&self, script: &Script) -> bool {
*self < script.minimal_non_dust()
}
}

impl IsDust for u64 {
fn is_dust(&self, script: &Script) -> bool {
*self < script.minimal_non_dust().to_sat()
Amount::from_sat(*self).is_dust(script)
}
}

Expand Down
14 changes: 5 additions & 9 deletions example-crates/wallet_electrum/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use bdk_wallet::file_store::Store;
use bdk_wallet::Wallet;
use std::io::Write;
use std::str::FromStr;

use bdk_electrum::electrum_client;
use bdk_electrum::BdkElectrumClient;
use bdk_wallet::bitcoin::Amount;
use bdk_wallet::bitcoin::Network;
use bdk_wallet::bitcoin::{Address, Amount};
use bdk_wallet::chain::collections::HashSet;
use bdk_wallet::{KeychainKind, SignOptions};

Expand Down Expand Up @@ -43,7 +42,7 @@ fn main() -> Result<(), anyhow::Error> {
println!("Generated Address: {}", address);

let balance = wallet.balance();
println!("Wallet balance before syncing: {} sats", balance.total());
println!("Wallet balance before syncing: {}", balance.total());

print!("Syncing...");
let client = BdkElectrumClient::new(electrum_client::Client::new(ELECTRUM_URL)?);
Expand Down Expand Up @@ -72,22 +71,19 @@ fn main() -> Result<(), anyhow::Error> {
wallet.persist(&mut db)?;

let balance = wallet.balance();
println!("Wallet balance after syncing: {} sats", balance.total());
println!("Wallet balance after syncing: {}", balance.total());

if balance.total() < SEND_AMOUNT {
println!(
"Please send at least {} sats to the receiving address",
"Please send at least {} to the receiving address",
SEND_AMOUNT
);
std::process::exit(0);
}

let faucet_address = Address::from_str("mkHS9ne12qx9pS9VojpwU5xtRd4T7X7ZUt")?
.require_network(Network::Testnet)?;

let mut tx_builder = wallet.build_tx();
tx_builder
.add_recipient(faucet_address.script_pubkey(), SEND_AMOUNT)
.add_recipient(address.script_pubkey(), SEND_AMOUNT)
.enable_rbf();

let mut psbt = tx_builder.finish()?;
Expand Down
6 changes: 3 additions & 3 deletions example-crates/wallet_esplora_async/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn main() -> Result<(), anyhow::Error> {
println!("Next unused address: ({}) {}", address.index, address);

let balance = wallet.balance();
println!("Wallet balance before syncing: {} sats", balance.total());
println!("Wallet balance before syncing: {}", balance.total());

print!("Syncing...");
let client = esplora_client::Builder::new(ESPLORA_URL).build_async()?;
Expand All @@ -66,11 +66,11 @@ async fn main() -> Result<(), anyhow::Error> {
println!();

let balance = wallet.balance();
println!("Wallet balance after syncing: {} sats", balance.total());
println!("Wallet balance after syncing: {}", balance.total());

if balance.total() < SEND_AMOUNT {
println!(
"Please send at least {} sats to the receiving address",
"Please send at least {} to the receiving address",
SEND_AMOUNT
);
std::process::exit(0);
Expand Down
10 changes: 4 additions & 6 deletions example-crates/wallet_esplora_blocking/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn main() -> Result<(), anyhow::Error> {
);

let balance = wallet.balance();
println!("Wallet balance before syncing: {} sats", balance.total());
println!("Wallet balance before syncing: {}", balance.total());

print!("Syncing...");
let client = esplora_client::Builder::new(ESPLORA_URL).build_blocking();
Expand All @@ -62,17 +62,15 @@ fn main() -> Result<(), anyhow::Error> {
let update = client.full_scan(request, STOP_GAP, PARALLEL_REQUESTS)?;

wallet.apply_update(update)?;
if let Some(changeset) = wallet.take_staged() {
db.append_changeset(&changeset)?;
}
wallet.persist(&mut db)?;
println!();

let balance = wallet.balance();
println!("Wallet balance after syncing: {} sats", balance.total());
println!("Wallet balance after syncing: {}", balance.total());

if balance.total() < SEND_AMOUNT {
println!(
"Please send at least {} sats to the receiving address",
"Please send at least {} to the receiving address",
SEND_AMOUNT
);
std::process::exit(0);
Expand Down
4 changes: 2 additions & 2 deletions example-crates/wallet_rpc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ fn main() -> anyhow::Result<()> {
);

let balance = wallet.balance();
println!("Wallet balance before syncing: {} sats", balance.total());
println!("Wallet balance before syncing: {}", balance.total());

let wallet_tip = wallet.latest_checkpoint();
println!(
Expand Down Expand Up @@ -179,7 +179,7 @@ fn main() -> anyhow::Result<()> {
wallet_tip_end.height(),
wallet_tip_end.hash()
);
println!("Wallet balance is {} sats", balance.total());
println!("Wallet balance is {}", balance.total());
println!(
"Wallet has {} transactions and {} utxos",
wallet.transactions().count(),
Expand Down

0 comments on commit 90a89bf

Please sign in to comment.