Skip to content

Commit b51fa22

Browse files
committed
fix(wallet): remove TxBuilder allow_shrinking function and unneeded context param
1 parent 80e190b commit b51fa22

File tree

3 files changed

+103
-159
lines changed

3 files changed

+103
-159
lines changed

crates/bdk/src/wallet/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub use utils::IsDust;
5757
#[allow(deprecated)]
5858
use coin_selection::DefaultCoinSelectionAlgorithm;
5959
use signer::{SignOptions, SignerOrdering, SignersContainer, TransactionSigner};
60-
use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxParams};
60+
use tx_builder::{FeePolicy, TxBuilder, TxParams};
6161
use utils::{check_nsequence_rbf, After, Older, SecpCtx};
6262

6363
use crate::descriptor::policy::BuildSatisfaction;
@@ -1252,12 +1252,11 @@ impl<D> Wallet<D> {
12521252
/// ```
12531253
///
12541254
/// [`TxBuilder`]: crate::TxBuilder
1255-
pub fn build_tx(&mut self) -> TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, CreateTx> {
1255+
pub fn build_tx(&mut self) -> TxBuilder<'_, D, DefaultCoinSelectionAlgorithm> {
12561256
TxBuilder {
12571257
wallet: alloc::rc::Rc::new(core::cell::RefCell::new(self)),
12581258
params: TxParams::default(),
12591259
coin_selection: DefaultCoinSelectionAlgorithm::default(),
1260-
phantom: core::marker::PhantomData,
12611260
}
12621261
}
12631262

@@ -1662,7 +1661,7 @@ impl<D> Wallet<D> {
16621661
pub fn build_fee_bump(
16631662
&mut self,
16641663
txid: Txid,
1665-
) -> Result<TxBuilder<'_, D, DefaultCoinSelectionAlgorithm, BumpFee>, BuildFeeBumpError> {
1664+
) -> Result<TxBuilder<'_, D, DefaultCoinSelectionAlgorithm>, BuildFeeBumpError> {
16661665
let graph = self.indexed_graph.graph();
16671666
let txout_index = &self.indexed_graph.index;
16681667
let chain_tip = self.chain.tip().block_id();
@@ -1786,7 +1785,6 @@ impl<D> Wallet<D> {
17861785
wallet: alloc::rc::Rc::new(core::cell::RefCell::new(self)),
17871786
params,
17881787
coin_selection: DefaultCoinSelectionAlgorithm::default(),
1789-
phantom: core::marker::PhantomData,
17901788
})
17911789
}
17921790

crates/bdk/src/wallet/tx_builder.rs

Lines changed: 78 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,13 @@
4343
use alloc::{boxed::Box, rc::Rc, string::String, vec::Vec};
4444
use core::cell::RefCell;
4545
use core::fmt;
46-
use core::marker::PhantomData;
4746

4847
use bdk_chain::PersistBackend;
4948
use bitcoin::psbt::{self, PartiallySignedTransaction as Psbt};
5049
use bitcoin::script::PushBytes;
5150
use bitcoin::{absolute, FeeRate, OutPoint, ScriptBuf, Sequence, Transaction, Txid};
5251

53-
use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
52+
use super::coin_selection::CoinSelectionAlgorithm;
5453
use super::{ChangeSet, CreateTxError, Wallet};
5554
use crate::collections::{BTreeMap, HashSet};
5655
use crate::{KeychainKind, LocalOutput, Utxo, WeightedUtxo};
@@ -124,11 +123,10 @@ impl TxBuilderContext for BumpFee {}
124123
/// [`finish`]: Self::finish
125124
/// [`coin_selection`]: Self::coin_selection
126125
#[derive(Debug)]
127-
pub struct TxBuilder<'a, D, Cs, Ctx> {
126+
pub struct TxBuilder<'a, D, Cs> {
128127
pub(crate) wallet: Rc<RefCell<&'a mut Wallet<D>>>,
129128
pub(crate) params: TxParams,
130129
pub(crate) coin_selection: Cs,
131-
pub(crate) phantom: PhantomData<Ctx>,
132130
}
133131

134132
/// The parameters for transaction creation sans coin selection algorithm.
@@ -176,19 +174,18 @@ impl Default for FeePolicy {
176174
}
177175
}
178176

179-
impl<'a, D, Cs: Clone, Ctx> Clone for TxBuilder<'a, D, Cs, Ctx> {
177+
impl<'a, D, Cs: Clone> Clone for TxBuilder<'a, D, Cs> {
180178
fn clone(&self) -> Self {
181179
TxBuilder {
182180
wallet: self.wallet.clone(),
183181
params: self.params.clone(),
184182
coin_selection: self.coin_selection.clone(),
185-
phantom: PhantomData,
186183
}
187184
}
188185
}
189186

190-
// methods supported by both contexts, for any CoinSelectionAlgorithm
191-
impl<'a, D, Cs, Ctx> TxBuilder<'a, D, Cs, Ctx> {
187+
// methods supported for any CoinSelectionAlgorithm
188+
impl<'a, D, Cs> TxBuilder<'a, D, Cs> {
192189
/// Set a custom fee rate.
193190
///
194191
/// This method sets the mining fee paid by the transaction as a rate on its size.
@@ -561,12 +558,11 @@ impl<'a, D, Cs, Ctx> TxBuilder<'a, D, Cs, Ctx> {
561558
pub fn coin_selection<P: CoinSelectionAlgorithm>(
562559
self,
563560
coin_selection: P,
564-
) -> TxBuilder<'a, D, P, Ctx> {
561+
) -> TxBuilder<'a, D, P> {
565562
TxBuilder {
566563
wallet: self.wallet,
567564
params: self.params,
568565
coin_selection,
569-
phantom: PhantomData,
570566
}
571567
}
572568

@@ -614,9 +610,80 @@ impl<'a, D, Cs, Ctx> TxBuilder<'a, D, Cs, Ctx> {
614610
self.params.allow_dust = allow_dust;
615611
self
616612
}
613+
614+
/// Replace the recipients already added with a new list
615+
pub fn set_recipients(&mut self, recipients: Vec<(ScriptBuf, u64)>) -> &mut Self {
616+
self.params.recipients = recipients;
617+
self
618+
}
619+
620+
/// Add a recipient to the internal list
621+
pub fn add_recipient(&mut self, script_pubkey: ScriptBuf, amount: u64) -> &mut Self {
622+
self.params.recipients.push((script_pubkey, amount));
623+
self
624+
}
625+
626+
/// Add data as an output, using OP_RETURN
627+
pub fn add_data<T: AsRef<PushBytes>>(&mut self, data: &T) -> &mut Self {
628+
let script = ScriptBuf::new_op_return(data);
629+
self.add_recipient(script, 0u64);
630+
self
631+
}
632+
633+
/// Sets the address to *drain* excess coins to.
634+
///
635+
/// Usually, when there are excess coins they are sent to a change address generated by the
636+
/// wallet. This option replaces the usual change address with an arbitrary `script_pubkey` of
637+
/// your choosing. Just as with a change output, if the drain output is not needed (the excess
638+
/// coins are too small) it will not be included in the resulting transaction. The only
639+
/// difference is that it is valid to use `drain_to` without setting any ordinary recipients
640+
/// with [`add_recipient`] (but it is perfectly fine to add recipients as well).
641+
///
642+
/// If you choose not to set any recipients, you should provide the utxos that the
643+
/// transaction should spend via [`add_utxos`].
644+
///
645+
/// # Example
646+
///
647+
/// `drain_to` is very useful for draining all the coins in a wallet with [`drain_wallet`] to a
648+
/// single address.
649+
///
650+
/// ```
651+
/// # use std::str::FromStr;
652+
/// # use bitcoin::*;
653+
/// # use bdk::*;
654+
/// # use bdk::wallet::ChangeSet;
655+
/// # use bdk::wallet::error::CreateTxError;
656+
/// # use bdk::wallet::tx_builder::CreateTx;
657+
/// # use bdk_chain::PersistBackend;
658+
/// # use anyhow::Error;
659+
/// # let to_address =
660+
/// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
661+
/// .unwrap()
662+
/// .assume_checked();
663+
/// # let mut wallet = doctest_wallet!();
664+
/// let mut tx_builder = wallet.build_tx();
665+
///
666+
/// tx_builder
667+
/// // Spend all outputs in this wallet.
668+
/// .drain_wallet()
669+
/// // Send the excess (which is all the coins minus the fee) to this address.
670+
/// .drain_to(to_address.script_pubkey())
671+
/// .fee_rate(FeeRate::from_sat_per_vb(5).expect("valid feerate"))
672+
/// .enable_rbf();
673+
/// let psbt = tx_builder.finish()?;
674+
/// # Ok::<(), anyhow::Error>(())
675+
/// ```
676+
///
677+
/// [`add_recipient`]: Self::add_recipient
678+
/// [`add_utxos`]: Self::add_utxos
679+
/// [`drain_wallet`]: Self::drain_wallet
680+
pub fn drain_to(&mut self, script_pubkey: ScriptBuf) -> &mut Self {
681+
self.params.drain_to = Some(script_pubkey);
682+
self
683+
}
617684
}
618685

619-
impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx> TxBuilder<'a, D, Cs, Ctx> {
686+
impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs> {
620687
/// Finish building the transaction.
621688
///
622689
/// Returns a new [`Psbt`] per [`BIP174`].
@@ -694,137 +761,6 @@ impl fmt::Display for AddForeignUtxoError {
694761
#[cfg(feature = "std")]
695762
impl std::error::Error for AddForeignUtxoError {}
696763

697-
#[derive(Debug)]
698-
/// Error returned from [`TxBuilder::allow_shrinking`]
699-
pub enum AllowShrinkingError {
700-
/// Script/PubKey was not in the original transaction
701-
MissingScriptPubKey(ScriptBuf),
702-
}
703-
704-
impl fmt::Display for AllowShrinkingError {
705-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
706-
match self {
707-
Self::MissingScriptPubKey(script_buf) => write!(
708-
f,
709-
"Script/PubKey was not in the original transaction: {}",
710-
script_buf,
711-
),
712-
}
713-
}
714-
}
715-
716-
#[cfg(feature = "std")]
717-
impl std::error::Error for AllowShrinkingError {}
718-
719-
impl<'a, D, Cs: CoinSelectionAlgorithm> TxBuilder<'a, D, Cs, CreateTx> {
720-
/// Replace the recipients already added with a new list
721-
pub fn set_recipients(&mut self, recipients: Vec<(ScriptBuf, u64)>) -> &mut Self {
722-
self.params.recipients = recipients;
723-
self
724-
}
725-
726-
/// Add a recipient to the internal list
727-
pub fn add_recipient(&mut self, script_pubkey: ScriptBuf, amount: u64) -> &mut Self {
728-
self.params.recipients.push((script_pubkey, amount));
729-
self
730-
}
731-
732-
/// Add data as an output, using OP_RETURN
733-
pub fn add_data<T: AsRef<PushBytes>>(&mut self, data: &T) -> &mut Self {
734-
let script = ScriptBuf::new_op_return(data);
735-
self.add_recipient(script, 0u64);
736-
self
737-
}
738-
739-
/// Sets the address to *drain* excess coins to.
740-
///
741-
/// Usually, when there are excess coins they are sent to a change address generated by the
742-
/// wallet. This option replaces the usual change address with an arbitrary `script_pubkey` of
743-
/// your choosing. Just as with a change output, if the drain output is not needed (the excess
744-
/// coins are too small) it will not be included in the resulting transaction. The only
745-
/// difference is that it is valid to use `drain_to` without setting any ordinary recipients
746-
/// with [`add_recipient`] (but it is perfectly fine to add recipients as well).
747-
///
748-
/// If you choose not to set any recipients, you should either provide the utxos that the
749-
/// transaction should spend via [`add_utxos`], or set [`drain_wallet`] to spend all of them.
750-
///
751-
/// When bumping the fees of a transaction made with this option, you probably want to
752-
/// use [`allow_shrinking`] to allow this output to be reduced to pay for the extra fees.
753-
///
754-
/// # Example
755-
///
756-
/// `drain_to` is very useful for draining all the coins in a wallet with [`drain_wallet`] to a
757-
/// single address.
758-
///
759-
/// ```
760-
/// # use std::str::FromStr;
761-
/// # use bitcoin::*;
762-
/// # use bdk::*;
763-
/// # use bdk::wallet::ChangeSet;
764-
/// # use bdk::wallet::error::CreateTxError;
765-
/// # use bdk::wallet::tx_builder::CreateTx;
766-
/// # use bdk_chain::PersistBackend;
767-
/// # use anyhow::Error;
768-
/// # let to_address =
769-
/// Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt")
770-
/// .unwrap()
771-
/// .assume_checked();
772-
/// # let mut wallet = doctest_wallet!();
773-
/// let mut tx_builder = wallet.build_tx();
774-
///
775-
/// tx_builder
776-
/// // Spend all outputs in this wallet.
777-
/// .drain_wallet()
778-
/// // Send the excess (which is all the coins minus the fee) to this address.
779-
/// .drain_to(to_address.script_pubkey())
780-
/// .fee_rate(FeeRate::from_sat_per_vb(5).expect("valid feerate"))
781-
/// .enable_rbf();
782-
/// let psbt = tx_builder.finish()?;
783-
/// # Ok::<(), anyhow::Error>(())
784-
/// ```
785-
///
786-
/// [`allow_shrinking`]: Self::allow_shrinking
787-
/// [`add_recipient`]: Self::add_recipient
788-
/// [`add_utxos`]: Self::add_utxos
789-
/// [`drain_wallet`]: Self::drain_wallet
790-
pub fn drain_to(&mut self, script_pubkey: ScriptBuf) -> &mut Self {
791-
self.params.drain_to = Some(script_pubkey);
792-
self
793-
}
794-
}
795-
796-
// methods supported only by bump_fee
797-
impl<'a, D> TxBuilder<'a, D, DefaultCoinSelectionAlgorithm, BumpFee> {
798-
/// Explicitly tells the wallet that it is allowed to reduce the amount of the output matching this
799-
/// `script_pubkey` in order to bump the transaction fee. Without specifying this the wallet
800-
/// will attempt to find a change output to shrink instead.
801-
///
802-
/// **Note** that the output may shrink to below the dust limit and therefore be removed. If it is
803-
/// preserved then it is currently not guaranteed to be in the same position as it was
804-
/// originally.
805-
///
806-
/// Returns an `Err` if `script_pubkey` can't be found among the recipients of the
807-
/// transaction we are bumping.
808-
pub fn allow_shrinking(
809-
&mut self,
810-
script_pubkey: ScriptBuf,
811-
) -> Result<&mut Self, AllowShrinkingError> {
812-
match self
813-
.params
814-
.recipients
815-
.iter()
816-
.position(|(recipient_script, _)| *recipient_script == script_pubkey)
817-
{
818-
Some(position) => {
819-
self.params.recipients.remove(position);
820-
self.params.drain_to = Some(script_pubkey);
821-
Ok(self)
822-
}
823-
None => Err(AllowShrinkingError::MissingScriptPubKey(script_pubkey)),
824-
}
825-
}
826-
}
827-
828764
/// Ordering of the transaction's inputs and outputs
829765
#[derive(Default, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
830766
pub enum TxOrdering {

0 commit comments

Comments
 (0)