From 292ec3cb3a41d7b9f42cfea536c39b27dba16d4c Mon Sep 17 00:00:00 2001 From: valued mammal Date: Sat, 7 Sep 2024 19:21:04 -0400 Subject: [PATCH] refactor(wallet): use `Amount` everywhere --- crates/wallet/src/wallet/mod.rs | 26 +++++++++---------- crates/wallet/src/wallet/tx_builder.rs | 17 +++++------- crates/wallet/src/wallet/utils.rs | 10 +++++-- example-crates/wallet_electrum/src/main.rs | 14 ++++------ .../wallet_esplora_async/src/main.rs | 6 ++--- .../wallet_esplora_blocking/src/main.rs | 10 +++---- example-crates/wallet_rpc/src/main.rs | 4 +-- 7 files changed, 41 insertions(+), 46 deletions(-) diff --git a/crates/wallet/src/wallet/mod.rs b/crates/wallet/src/wallet/mod.rs index 9f12fac4e..318d75ed1 100644 --- a/crates/wallet/src/wallet/mod.rs +++ b/crates/wallet/src/wallet/mod.rs @@ -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, }); } } @@ -1423,7 +1423,7 @@ impl Wallet { }); } } - (rate, 0) + (rate, Amount::ZERO) } }; @@ -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(¶ms, Some(current_height.to_consensus_u32())); @@ -1490,7 +1490,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, @@ -1503,7 +1503,7 @@ 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, @@ -1511,7 +1511,7 @@ impl Wallet { } }, }; - fee_amount += coin_selection.fee_amount; + fee_amount += Amount::from_sat(coin_selection.fee_amount); let excess = &coin_selection.excess; tx.input = coin_selection @@ -1553,12 +1553,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 { @@ -1740,11 +1740,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() diff --git a/crates/wallet/src/wallet/tx_builder.rs b/crates/wallet/src/wallet/tx_builder.rs index 9d0adc729..08b0f3249 100644 --- a/crates/wallet/src/wallet/tx_builder.rs +++ b/crates/wallet/src/wallet/tx_builder.rs @@ -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, pub(crate) fee_policy: Option, @@ -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 { @@ -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 } @@ -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 } diff --git a/crates/wallet/src/wallet/utils.rs b/crates/wallet/src/wallet/utils.rs index b3ec51cb0..bca07b48a 100644 --- a/crates/wallet/src/wallet/utils.rs +++ b/crates/wallet/src/wallet/utils.rs @@ -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}; @@ -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) } } diff --git a/example-crates/wallet_electrum/src/main.rs b/example-crates/wallet_electrum/src/main.rs index 47cbfa15d..f3320d821 100644 --- a/example-crates/wallet_electrum/src/main.rs +++ b/example-crates/wallet_electrum/src/main.rs @@ -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}; @@ -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)?); @@ -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()?; diff --git a/example-crates/wallet_esplora_async/src/main.rs b/example-crates/wallet_esplora_async/src/main.rs index 6fd215dff..4133982c6 100644 --- a/example-crates/wallet_esplora_async/src/main.rs +++ b/example-crates/wallet_esplora_async/src/main.rs @@ -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()?; @@ -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); diff --git a/example-crates/wallet_esplora_blocking/src/main.rs b/example-crates/wallet_esplora_blocking/src/main.rs index 45e4685b7..d12dbd926 100644 --- a/example-crates/wallet_esplora_blocking/src/main.rs +++ b/example-crates/wallet_esplora_blocking/src/main.rs @@ -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(); @@ -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); diff --git a/example-crates/wallet_rpc/src/main.rs b/example-crates/wallet_rpc/src/main.rs index 388ccaf67..d12573c13 100644 --- a/example-crates/wallet_rpc/src/main.rs +++ b/example-crates/wallet_rpc/src/main.rs @@ -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!( @@ -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(),