Skip to content

Commit

Permalink
Merge #757: Enable signing taproot transactions with only `non_witnes…
Browse files Browse the repository at this point in the history
…s_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
  • Loading branch information
afilini committed Sep 23, 2022
2 parents 0a7a1f4 + 5e9965f commit aad5461
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
23 changes: 23 additions & 0 deletions src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4964,6 +4964,29 @@ pub(crate) mod test {
);
}

#[test]
fn test_taproot_sign_using_non_witness_utxo() {
let (wallet, _, prev_txid) = get_funded_wallet(get_test_tr_single_sig());
let addr = wallet.get_address(New).unwrap();
let mut builder = wallet.build_tx();
builder.drain_to(addr.script_pubkey()).drain_wallet();
let (mut psbt, _) = builder.finish().unwrap();

psbt.inputs[0].witness_utxo = None;
psbt.inputs[0].non_witness_utxo = wallet.database().get_raw_tx(&prev_txid).unwrap();
assert!(
psbt.inputs[0].non_witness_utxo.is_some(),
"Previous tx should be present in the database"
);

let result = wallet.sign(&mut psbt, Default::default());
assert!(result.is_ok(), "Signing should have worked");
assert!(
result.unwrap(),
"Should finalize the input since we can produce signatures"
);
}

#[test]
fn test_taproot_foreign_utxo() {
let (wallet1, _, _) = get_funded_wallet(get_test_wpkh());
Expand Down
8 changes: 3 additions & 5 deletions src/wallet/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ use miniscript::{Legacy, MiniscriptKey, Segwitv0, Tap};

use super::utils::SecpCtx;
use crate::descriptor::{DescriptorMeta, XKeyUtils};
use crate::psbt::PsbtUtils;

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

Expand Down

0 comments on commit aad5461

Please sign in to comment.