Skip to content

Commit aad5461

Browse files
committed
Merge #757: Enable signing taproot transactions with only non_witness_utxos
5e9965f Enable signing taproot transactions with only `non_witness_utxos` (Alekos Filini) Pull request description: ### Description Some wallets may only specify the `non_witness_utxo` for a PSBT input. If that's the case, BDK should still be able to sign. This was pointed out in the discussion of #734 ### Changelog notice - Enable signing taproot transactions that only specify the `non_witness_utxo` ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### Bugfixes: * [ ] This pull request breaks the existing API * [x] I've added tests to reproduce the issue which are now passing * [x] I'm linking the issue being fixed by this PR ACKs for top commit: danielabrozzoni: tACK 5e9965f - the code looks good to me, I played around with the test you provided (inspecting the PSBT, adding/removing the witness and non-witness utxos, etc) and everything works as expected. Tree-SHA512: 2f205286263bfee4c76de8e8c81ae1349b1c3b255b72045488f8d629c05cab64c6f775307e831674dc036e5a3a760f95d9cdc1beaf48afb4c475aee838131a33
2 parents 0a7a1f4 + 5e9965f commit aad5461

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

src/wallet/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4964,6 +4964,29 @@ pub(crate) mod test {
49644964
);
49654965
}
49664966

4967+
#[test]
4968+
fn test_taproot_sign_using_non_witness_utxo() {
4969+
let (wallet, _, prev_txid) = get_funded_wallet(get_test_tr_single_sig());
4970+
let addr = wallet.get_address(New).unwrap();
4971+
let mut builder = wallet.build_tx();
4972+
builder.drain_to(addr.script_pubkey()).drain_wallet();
4973+
let (mut psbt, _) = builder.finish().unwrap();
4974+
4975+
psbt.inputs[0].witness_utxo = None;
4976+
psbt.inputs[0].non_witness_utxo = wallet.database().get_raw_tx(&prev_txid).unwrap();
4977+
assert!(
4978+
psbt.inputs[0].non_witness_utxo.is_some(),
4979+
"Previous tx should be present in the database"
4980+
);
4981+
4982+
let result = wallet.sign(&mut psbt, Default::default());
4983+
assert!(result.is_ok(), "Signing should have worked");
4984+
assert!(
4985+
result.unwrap(),
4986+
"Should finalize the input since we can produce signatures"
4987+
);
4988+
}
4989+
49674990
#[test]
49684991
fn test_taproot_foreign_utxo() {
49694992
let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());

src/wallet/signer.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ use miniscript::{Legacy, MiniscriptKey, Segwitv0, Tap};
103103

104104
use super::utils::SecpCtx;
105105
use crate::descriptor::{DescriptorMeta, XKeyUtils};
106+
use crate::psbt::PsbtUtils;
106107

107108
/// Identifier of a signer in the `SignersContainers`. Used as a key to find the right signer among
108109
/// multiple of them
@@ -921,11 +922,8 @@ impl ComputeSighash for Tap {
921922
.unwrap_or_else(|| SchnorrSighashType::Default.into())
922923
.schnorr_hash_ty()
923924
.map_err(|_| SignerError::InvalidSighash)?;
924-
let witness_utxos = psbt
925-
.inputs
926-
.iter()
927-
.cloned()
928-
.map(|i| i.witness_utxo)
925+
let witness_utxos = (0..psbt.inputs.len())
926+
.map(|i| psbt.get_utxo_for(i))
929927
.collect::<Vec<_>>();
930928
let mut all_witness_utxos = vec![];
931929

0 commit comments

Comments
 (0)