tx_builder: Support setting explicit nSequence for foreign inputs
This commit is contained in:
parent
c6b9ed3b76
commit
9e098a5b6d
@ -14,7 +14,7 @@ use core::convert::AsRef;
|
|||||||
use core::ops::Sub;
|
use core::ops::Sub;
|
||||||
|
|
||||||
use bdk_chain::ConfirmationTime;
|
use bdk_chain::ConfirmationTime;
|
||||||
use bitcoin::blockdata::transaction::{OutPoint, TxOut};
|
use bitcoin::blockdata::transaction::{OutPoint, Sequence, TxOut};
|
||||||
use bitcoin::{psbt, Weight};
|
use bitcoin::{psbt, Weight};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -197,6 +197,8 @@ pub enum Utxo {
|
|||||||
Foreign {
|
Foreign {
|
||||||
/// The location of the output.
|
/// The location of the output.
|
||||||
outpoint: OutPoint,
|
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.
|
/// The information about the input we require to add it to a PSBT.
|
||||||
// Box it to stop the type being too big.
|
// Box it to stop the type being too big.
|
||||||
psbt_input: Box<psbt::Input>,
|
psbt_input: Box<psbt::Input>,
|
||||||
@ -219,6 +221,7 @@ impl Utxo {
|
|||||||
Utxo::Foreign {
|
Utxo::Foreign {
|
||||||
outpoint,
|
outpoint,
|
||||||
psbt_input,
|
psbt_input,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some(prev_tx) = &psbt_input.non_witness_utxo {
|
if let Some(prev_tx) = &psbt_input.non_witness_utxo {
|
||||||
return &prev_tx.output[outpoint.vout as usize];
|
return &prev_tx.output[outpoint.vout as usize];
|
||||||
@ -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)]
|
#[cfg(test)]
|
||||||
|
@ -1400,6 +1400,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) {
|
let n_sequence = match (params.rbf, requirements.csv) {
|
||||||
// No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
|
// No RBF or CSV but there's an nLockTime, so the nSequence cannot be final
|
||||||
(None, None) if lock_time != absolute::LockTime::ZERO => {
|
(None, None) if lock_time != absolute::LockTime::ZERO => {
|
||||||
@ -1558,7 +1559,7 @@ impl<D> Wallet<D> {
|
|||||||
.map(|u| bitcoin::TxIn {
|
.map(|u| bitcoin::TxIn {
|
||||||
previous_output: u.outpoint(),
|
previous_output: u.outpoint(),
|
||||||
script_sig: ScriptBuf::default(),
|
script_sig: ScriptBuf::default(),
|
||||||
sequence: n_sequence,
|
sequence: u.sequence().unwrap_or(n_sequence),
|
||||||
witness: Witness::new(),
|
witness: Witness::new(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -1738,6 +1739,7 @@ impl<D> Wallet<D> {
|
|||||||
satisfaction_weight,
|
satisfaction_weight,
|
||||||
utxo: Utxo::Foreign {
|
utxo: Utxo::Foreign {
|
||||||
outpoint: txin.previous_output,
|
outpoint: txin.previous_output,
|
||||||
|
sequence: Some(txin.sequence),
|
||||||
psbt_input: Box::new(psbt::Input {
|
psbt_input: Box::new(psbt::Input {
|
||||||
witness_utxo: Some(txout.clone()),
|
witness_utxo: Some(txout.clone()),
|
||||||
non_witness_utxo: Some(prev_tx.clone()),
|
non_witness_utxo: Some(prev_tx.clone()),
|
||||||
@ -2218,8 +2220,9 @@ impl<D> Wallet<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Utxo::Foreign {
|
Utxo::Foreign {
|
||||||
psbt_input: foreign_psbt_input,
|
|
||||||
outpoint,
|
outpoint,
|
||||||
|
psbt_input: foreign_psbt_input,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
let is_taproot = foreign_psbt_input
|
let is_taproot = foreign_psbt_input
|
||||||
.witness_utxo
|
.witness_utxo
|
||||||
|
@ -389,6 +389,22 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
|
|||||||
outpoint: OutPoint,
|
outpoint: OutPoint,
|
||||||
psbt_input: psbt::Input,
|
psbt_input: psbt::Input,
|
||||||
satisfaction_weight: usize,
|
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](TxBuilder::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> {
|
) -> Result<&mut Self, AddForeignUtxoError> {
|
||||||
if psbt_input.witness_utxo.is_none() {
|
if psbt_input.witness_utxo.is_none() {
|
||||||
match psbt_input.non_witness_utxo.as_ref() {
|
match psbt_input.non_witness_utxo.as_ref() {
|
||||||
@ -413,6 +429,7 @@ impl<'a, D, Cs: CoinSelectionAlgorithm, Ctx: TxBuilderContext> TxBuilder<'a, D,
|
|||||||
satisfaction_weight,
|
satisfaction_weight,
|
||||||
utxo: Utxo::Foreign {
|
utxo: Utxo::Foreign {
|
||||||
outpoint,
|
outpoint,
|
||||||
|
sequence: Some(sequence),
|
||||||
psbt_input: Box::new(psbt_input),
|
psbt_input: Box::new(psbt_input),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user