handle descriptor xkey origin

This commit is contained in:
davemo88 2021-03-11 17:39:02 -05:00
parent 9cf62ce874
commit 396ffb42f9
No known key found for this signature in database
GPG Key ID: 2DE8C063FF02FB83
2 changed files with 34 additions and 3 deletions

View File

@ -3316,6 +3316,23 @@ mod test {
assert_eq!(extracted.input[0].witness.len(), 2);
}
#[test]
fn test_sign_single_xprv_with_master_fingerprint_and_path() {
let (wallet, _, _) = get_funded_wallet("wpkh([d34db33f/84h/1h/0h]tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/*)");
let addr = wallet.get_new_address().unwrap();
let mut builder = wallet.build_tx();
builder
.set_single_recipient(addr.script_pubkey())
.drain_wallet();
let (psbt, _) = builder.finish().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_xprv_bip44_path() {
let (wallet, _, _) = get_funded_wallet("wpkh(tprv8ZgxMBicQKsPd3EupYiPRhaMooHKUHJxNsTfYuScep13go8QFfHdtkG9nRkFGb7busX4isf6X9dURGCoKgitaApQ6MupRhZMcELAxTBRJgS/44'/0'/0'/0/*)");

View File

@ -92,7 +92,7 @@ use bitcoin::blockdata::opcodes;
use bitcoin::blockdata::script::Builder as ScriptBuilder;
use bitcoin::hashes::{hash160, Hash};
use bitcoin::secp256k1::{Message, Secp256k1};
use bitcoin::util::bip32::{ExtendedPrivKey, Fingerprint};
use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, Fingerprint};
use bitcoin::util::{bip143, psbt};
use bitcoin::{PrivateKey, Script, SigHash, SigHashType};
@ -206,7 +206,7 @@ impl Signer for DescriptorXKey<ExtendedPrivKey> {
return Err(SignerError::InputIndexOutOfRange);
}
let (public_key, deriv_path) = match psbt.inputs[input_index]
let (public_key, full_path) = match psbt.inputs[input_index]
.bip32_derivation
.iter()
.filter_map(|(pk, &(fingerprint, ref path))| {
@ -222,7 +222,21 @@ impl Signer for DescriptorXKey<ExtendedPrivKey> {
None => return Ok(()),
};
let derived_key = self.xkey.derive_priv(&secp, &deriv_path).unwrap();
let derived_key = match self.origin.clone() {
Some((_fingerprint, path)) => {
let split_origin_path: Vec<&ChildNumber> = path.into_iter().collect();
let mut deriv_path = DerivationPath::default();
for (i, child) in full_path.into_iter().cloned().enumerate() {
match split_origin_path.get(i) {
Some(_) => continue,
None => deriv_path = deriv_path.extend(&[child]),
}
}
self.xkey.derive_priv(&secp, &deriv_path).unwrap()
}
None => self.xkey.derive_priv(&secp, &full_path).unwrap(),
};
if &derived_key.private_key.public_key(&secp) != public_key {
Err(SignerError::InvalidKey)
} else {