]> Untitled Git - bdk/commitdiff
[signer] Fix signing for `ShWpkh` inputs
authorAlekos Filini <alekos.filini@gmail.com>
Wed, 16 Sep 2020 15:31:43 +0000 (17:31 +0200)
committerAlekos Filini <alekos.filini@gmail.com>
Wed, 16 Sep 2020 15:50:54 +0000 (17:50 +0200)
src/wallet/mod.rs
src/wallet/signer.rs

index e45b97c753c7bccb3c6a3846260731f3d3676cee..d84a62063146060d3f33640162a2a4e318590e43 100644 (file)
@@ -2403,6 +2403,21 @@ mod test {
         assert_eq!(extracted.input[0].witness.len(), 2);
     }
 
+    #[test]
+    fn test_sign_single_xprv_sh_wpkh() {
+        let (wallet, _, _) = get_funded_wallet("sh(wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*))");
+        let addr = wallet.get_new_address().unwrap();
+        let (psbt, _) = wallet
+            .create_tx(TxBuilder::with_recipients(vec![(addr.script_pubkey(), 0)]).send_all())
+            .unwrap();
+
+        let (signed_psbt, finalized) = wallet.sign(psbt, None).unwrap();
+        assert_eq!(finalized, true);
+
+        let extracted = signed_psbt.extract_tx();
+        assert_eq!(extracted.input[0].witness.len(), 2);
+    }
+
     #[test]
     fn test_sign_single_wif() {
         let (wallet, _, _) =
index c290126c5f2bde65cc630f20397c66a616a8ab18..12905151af734da65b8bc0b45252e49438275b1f 100644 (file)
@@ -100,7 +100,7 @@ use bitcoin::hashes::{hash160, Hash};
 use bitcoin::secp256k1::{Message, Secp256k1};
 use bitcoin::util::bip32::{ExtendedPrivKey, Fingerprint};
 use bitcoin::util::{bip143, psbt};
-use bitcoin::{PrivateKey, SigHash, SigHashType};
+use bitcoin::{PrivateKey, Script, SigHash, SigHashType};
 
 use miniscript::descriptor::{DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, KeyMap};
 use miniscript::{Legacy, MiniscriptKey, Segwitv0};
@@ -444,6 +444,16 @@ impl ComputeSighash for Legacy {
     }
 }
 
+fn p2wpkh_script_code(script: &Script) -> Script {
+    ScriptBuilder::new()
+        .push_opcode(opcodes::all::OP_DUP)
+        .push_opcode(opcodes::all::OP_HASH160)
+        .push_slice(&script[2..])
+        .push_opcode(opcodes::all::OP_EQUALVERIFY)
+        .push_opcode(opcodes::all::OP_CHECKSIG)
+        .into_script()
+}
+
 impl ComputeSighash for Segwitv0 {
     fn sighash(
         psbt: &psbt::PartiallySignedTransaction,
@@ -467,13 +477,14 @@ impl ComputeSighash for Segwitv0 {
             &Some(ref witness_script) => witness_script.clone(),
             &None => {
                 if witness_utxo.script_pubkey.is_v0_p2wpkh() {
-                    ScriptBuilder::new()
-                        .push_opcode(opcodes::all::OP_DUP)
-                        .push_opcode(opcodes::all::OP_HASH160)
-                        .push_slice(&witness_utxo.script_pubkey[2..])
-                        .push_opcode(opcodes::all::OP_EQUALVERIFY)
-                        .push_opcode(opcodes::all::OP_CHECKSIG)
-                        .into_script()
+                    p2wpkh_script_code(&witness_utxo.script_pubkey)
+                } else if psbt_input
+                    .redeem_script
+                    .as_ref()
+                    .map(Script::is_v0_p2wpkh)
+                    .unwrap_or(false)
+                {
+                    p2wpkh_script_code(&psbt_input.redeem_script.as_ref().unwrap())
                 } else {
                     return Err(SignerError::MissingWitnessScript);
                 }