[signer] Fix signing for ShWpkh inputs

This commit is contained in:
Alekos Filini 2020-09-16 17:31:43 +02:00
parent cf2a8bccac
commit 33a5ba6cd2
No known key found for this signature in database
GPG Key ID: 5E8AFC3034FDFA4F
2 changed files with 34 additions and 8 deletions

View File

@ -2403,6 +2403,21 @@ mod test {
assert_eq!(extracted.input[0].witness.len(), 2); 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] #[test]
fn test_sign_single_wif() { fn test_sign_single_wif() {
let (wallet, _, _) = let (wallet, _, _) =

View File

@ -100,7 +100,7 @@ use bitcoin::hashes::{hash160, Hash};
use bitcoin::secp256k1::{Message, Secp256k1}; use bitcoin::secp256k1::{Message, Secp256k1};
use bitcoin::util::bip32::{ExtendedPrivKey, Fingerprint}; use bitcoin::util::bip32::{ExtendedPrivKey, Fingerprint};
use bitcoin::util::{bip143, psbt}; 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::descriptor::{DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, KeyMap};
use miniscript::{Legacy, MiniscriptKey, Segwitv0}; 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 { impl ComputeSighash for Segwitv0 {
fn sighash( fn sighash(
psbt: &psbt::PartiallySignedTransaction, psbt: &psbt::PartiallySignedTransaction,
@ -467,13 +477,14 @@ impl ComputeSighash for Segwitv0 {
&Some(ref witness_script) => witness_script.clone(), &Some(ref witness_script) => witness_script.clone(),
&None => { &None => {
if witness_utxo.script_pubkey.is_v0_p2wpkh() { if witness_utxo.script_pubkey.is_v0_p2wpkh() {
ScriptBuilder::new() p2wpkh_script_code(&witness_utxo.script_pubkey)
.push_opcode(opcodes::all::OP_DUP) } else if psbt_input
.push_opcode(opcodes::all::OP_HASH160) .redeem_script
.push_slice(&witness_utxo.script_pubkey[2..]) .as_ref()
.push_opcode(opcodes::all::OP_EQUALVERIFY) .map(Script::is_v0_p2wpkh)
.push_opcode(opcodes::all::OP_CHECKSIG) .unwrap_or(false)
.into_script() {
p2wpkh_script_code(&psbt_input.redeem_script.as_ref().unwrap())
} else { } else {
return Err(SignerError::MissingWitnessScript); return Err(SignerError::MissingWitnessScript);
} }