Skip to content

Commit

Permalink
spend: a nicer interface for providing fee informations
Browse files Browse the repository at this point in the history
Allows for a clearer interface: you explicitly set whether you are
creating a replacement, and you don't have dangling 0s when you don't
which necessitate a comment to explain what they correspond to.
  • Loading branch information
darosior committed Nov 30, 2023
1 parent f8dcdf9 commit a5b0a46
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 12 deletions.
11 changes: 4 additions & 7 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
descriptors,
spend::{
create_spend, AddrInfo, CandidateCoin, CreateSpendRes, InsaneFeeInfo, SpendCreationError,
SpendOutputAddress, TxGetter,
SpendOutputAddress, SpendTxFees, TxGetter,
},
DaemonControl, VERSION,
};
Expand Down Expand Up @@ -517,8 +517,7 @@ impl DaemonControl {
&mut tx_getter,
&destinations_checked,
&candidate_coins,
feerate_vb,
0, // No min fee required.
SpendTxFees::Regular(feerate_vb),
change_address,
)?;
for (addr, _) in destinations_checked {
Expand Down Expand Up @@ -830,8 +829,7 @@ impl DaemonControl {
&mut tx_getter,
&destinations,
&candidate_coins,
feerate_vb,
min_fee,
SpendTxFees::Rbf(feerate_vb, min_fee),
change_address.clone(),
) {
Ok(psbt) => psbt,
Expand Down Expand Up @@ -1003,8 +1001,7 @@ impl DaemonControl {
&mut tx_getter,
&[], // No destination, only the change address.
&sweepable_coins,
feerate_vb,
0, // No min fee required.
SpendTxFees::Regular(feerate_vb),
sweep_addr,
)?;
if has_change {
Expand Down
22 changes: 17 additions & 5 deletions src/spend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,17 @@ pub trait TxGetter {
fn get_tx(&mut self, tx: &bitcoin::Txid) -> Option<bitcoin::Transaction>;
}

/// Specify the fee requirements for a transactions. In both cases set a target feerate in satoshi
/// per virtual byte. For RBF also set a minimum fee in satoshis for this transaction. See
/// https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md for more
/// information about how it should be set.
pub enum SpendTxFees {
/// The target feerate in sats/vb for this transaction.
Regular(u64),
/// The (target feerate, minimum absolute fees) for this transactions. Both in sats.
Rbf(u64, u64),
}

pub struct CreateSpendRes {
/// The created PSBT.
pub psbt: Psbt,
Expand All @@ -411,9 +422,7 @@ pub struct CreateSpendRes {
/// `destinations` is empty, they will all be included as inputs of the transaction. Otherwise, a
/// coin selection algorithm will be ran to spend the most efficient subset of them to meet the
/// `destinations` requirements.
/// * `feerate_vb`: the feerate to target for this transaction, in satoshi per virtual byte.
/// * `min_fee`: the minimum absolute fee for this transaction. Can be set to 0 for anything but an
/// RBF transaction.
/// * `fees`: the target feerate (in sats/vb) and, if necessary, minimum absolute fee for this tx.
/// * `change_addr`: the address to use for either a change output if we need to create one. Can be
/// set to an external address (if combined with an empty list of `destinations` it's useful to
/// sweep some or all coins of a wallet to an external address).
Expand All @@ -423,8 +432,7 @@ pub fn create_spend(
tx_getter: &mut impl TxGetter,
destinations: &[(SpendOutputAddress, bitcoin::Amount)],
candidate_coins: &[CandidateCoin],
feerate_vb: u64,
min_fee: u64,
fees: SpendTxFees,
change_addr: SpendOutputAddress,
) -> Result<CreateSpendRes, SpendCreationError> {
// This method does quite a few things. In addition, we support different modes (coin control
Expand All @@ -441,6 +449,10 @@ pub fn create_spend(
// 3. Add the selected coins as inputs to the transaction.
// 4. Finalize the PSBT and sanity check it before returning it.

let (feerate_vb, min_fee) = match fees {
SpendTxFees::Regular(feerate) => (feerate, 0),
SpendTxFees::Rbf(feerate, fee) => (feerate, fee),
};
let is_self_send = destinations.is_empty();
if feerate_vb < 1 {
return Err(SpendCreationError::InvalidFeerate(feerate_vb));
Expand Down

0 comments on commit a5b0a46

Please sign in to comment.