Skip to content

Commit

Permalink
tx_builder: Support setting explicit nSequence for foreign inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenroose committed Feb 2, 2024
1 parent 40f0765 commit 2b5716d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
13 changes: 12 additions & 1 deletion crates/bdk/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use core::convert::AsRef;
use core::ops::Sub;

use bdk_chain::ConfirmationTime;
use bitcoin::blockdata::transaction::{OutPoint, TxOut};
use bitcoin::blockdata::transaction::{OutPoint, Sequence, TxOut};
use bitcoin::{psbt, Weight};

use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -197,6 +197,8 @@ pub enum Utxo {
Foreign {
/// The location of the output.
outpoint: OutPoint,
/// The nSequence value to set for this input.
sequence: Option<Sequence>,
/// The information about the input we require to add it to a PSBT.
// Box it to stop the type being too big.
psbt_input: Box<psbt::Input>,
Expand All @@ -219,6 +221,7 @@ impl Utxo {
Utxo::Foreign {
outpoint,
psbt_input,
..
} => {
if let Some(prev_tx) = &psbt_input.non_witness_utxo {
return &prev_tx.output[outpoint.vout as usize];
Expand All @@ -232,6 +235,14 @@ impl Utxo {
}
}
}

/// Get the sequence number if an explicit sequence number has to be set for this input.
pub fn sequence(&self) -> Option<Sequence> {
match self {
Utxo::Local(_) => None,
Utxo::Foreign { sequence, .. } => *sequence,
}
}
}

#[cfg(test)]
Expand Down
7 changes: 5 additions & 2 deletions crates/bdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,7 @@ impl<D> Wallet<D> {
}
};

// The nSequence to be by default for inputs unless an explicit sequence is specified.
let n_sequence = match (params.rbf, requirements.csv) {
// No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
(None, None) if lock_time != absolute::LockTime::ZERO => {
Expand Down Expand Up @@ -1485,7 +1486,7 @@ impl<D> Wallet<D> {
.map(|u| bitcoin::TxIn {
previous_output: u.outpoint(),
script_sig: ScriptBuf::default(),
sequence: n_sequence,
sequence: u.sequence().unwrap_or(n_sequence),
witness: Witness::new(),
})
.collect();
Expand Down Expand Up @@ -1665,6 +1666,7 @@ impl<D> Wallet<D> {
satisfaction_weight,
utxo: Utxo::Foreign {
outpoint: txin.previous_output,
sequence: Some(txin.sequence),
psbt_input: Box::new(psbt::Input {
witness_utxo: Some(txout.clone()),
non_witness_utxo: Some(prev_tx.clone()),
Expand Down Expand Up @@ -2136,8 +2138,9 @@ impl<D> Wallet<D> {
}
}
Utxo::Foreign {
psbt_input: foreign_psbt_input,
outpoint,
psbt_input: foreign_psbt_input,
..
} => {
let is_taproot = foreign_psbt_input
.witness_utxo
Expand Down
17 changes: 17 additions & 0 deletions crates/bdk/src/wallet/tx_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,22 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
outpoint: OutPoint,
psbt_input: psbt::Input,
satisfaction_weight: usize,
) -> Result<&mut Self, AddForeignUtxoError> {
self.add_foreign_utxo_with_sequence(
outpoint,
psbt_input,
satisfaction_weight,
Sequence::MAX,
)
}

/// Same as [add_foreign_utxo] but allows to set the nSequence value.
pub fn add_foreign_utxo_with_sequence(
&mut self,
outpoint: OutPoint,
psbt_input: psbt::Input,
satisfaction_weight: usize,
sequence: Sequence,
) -> Result<&mut Self, AddForeignUtxoError> {
if psbt_input.witness_utxo.is_none() {
match psbt_input.non_witness_utxo.as_ref() {
Expand All @@ -413,6 +429,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
satisfaction_weight,
utxo: Utxo::Foreign {
outpoint,
sequence: Some(sequence),
psbt_input: Box::new(psbt_input),
},
});
Expand Down

0 comments on commit 2b5716d

Please sign in to comment.