Skip to content

Commit d1c61e4

Browse files
committed
Merge #589: Adding substitution of pkh for taproot
c6bb142 Adding substitution of pkh for taproot (Harshil Jani) Pull request description: Recently , We have introduced the method `substitute_raw_pkh` to deal with the change of pkh to expr_raw_pkh. This is the implementation of that method for the taproot miniscript. Reference PR : #557 ACKs for top commit: sanket1729: utACK c6bb142 apoelstra: ACK c6bb142 Tree-SHA512: 59fb725776dc4b0ecaf01d09321b70fe9e733621af26250eff389f837d1feb29ba797d7bafbb7b0b902f936e7832ee3617d0dd433c708941b2df96ff626f883d
2 parents c15d4ef + c6bb142 commit d1c61e4

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/psbt/finalizer.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ use super::{sanity_check, Error, InputError, Psbt, PsbtInputSatisfier};
2121
use crate::prelude::*;
2222
use crate::util::witness_size;
2323
use crate::{
24-
interpreter, BareCtx, Descriptor, ExtParams, Legacy, Miniscript, Satisfier, Segwitv0, Tap,
24+
interpreter, BareCtx, Descriptor, ExtParams, Legacy, Miniscript, Satisfier, Segwitv0, SigType,
25+
Tap, ToPublicKey,
2526
};
2627

2728
// Satisfy the taproot descriptor. It is not possible to infer the complete
@@ -33,6 +34,22 @@ fn construct_tap_witness(
3334
sat: &PsbtInputSatisfier,
3435
allow_mall: bool,
3536
) -> Result<Vec<Vec<u8>>, InputError> {
37+
// When miniscript tries to finalize the PSBT, it doesn't have the full descriptor (which contained a pkh() fragment)
38+
// and instead resorts to parsing the raw script sig, which is translated into a "expr_raw_pkh" internally.
39+
let mut hash_map: BTreeMap<hash160::Hash, bitcoin::key::XOnlyPublicKey> = BTreeMap::new();
40+
let psbt_inputs = &sat.psbt.inputs;
41+
for psbt_input in psbt_inputs {
42+
// We need to satisfy or dissatisfy any given key. `tap_key_origin` is the only field of PSBT Input which consist of
43+
// all the keys added on a descriptor and thus we get keys from it.
44+
let public_keys = psbt_input.tap_key_origins.keys();
45+
for key in public_keys {
46+
let bitcoin_key = *key;
47+
// Convert PubKeyHash into Hash::hash160
48+
let hash = bitcoin_key.to_pubkeyhash(SigType::Schnorr);
49+
// Insert pair in HashMap
50+
hash_map.insert(hash, bitcoin_key);
51+
}
52+
}
3653
assert!(spk.is_v1_p2tr());
3754

3855
// try the key spend path first
@@ -55,7 +72,7 @@ fn construct_tap_witness(
5572
script,
5673
&ExtParams::allow_all(),
5774
) {
58-
Ok(ms) => ms,
75+
Ok(ms) => ms.substitute_raw_pkh(&hash_map),
5976
Err(..) => continue, // try another script
6077
};
6178
let mut wit = if allow_mall {

0 commit comments

Comments
 (0)