Skip to content

Commit 54ad691

Browse files
committed
Adding substitution of pkh for taproot
Signed-off-by: Harshil Jani <[email protected]>
1 parent feae54c commit 54ad691

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

src/psbt/finalizer.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ use bitcoin::key::XOnlyPublicKey;
1515
use bitcoin::secp256k1::{self, Secp256k1};
1616
use bitcoin::sighash::Prevouts;
1717
use bitcoin::taproot::LeafVersion;
18-
use bitcoin::{PublicKey, Script, ScriptBuf, TxOut, Witness};
18+
use bitcoin::{psbt, PublicKey, Script, ScriptBuf, TxOut, Witness};
1919

2020
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,23 @@ 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+
// Which can't be satisfied anymore since the planning code doesn't support raw pkh.
40+
let mut hash_map: BTreeMap<hash160::Hash, bitcoin::key::XOnlyPublicKey> = BTreeMap::new();
41+
let psbt_inputs = &sat.psbt.inputs;
42+
for psbt_input in psbt_inputs {
43+
// We need to satisfy or dissatisfy any given key. `tap_key_origin` is the only field of PSBT Input which consist of
44+
// all the keys added on a descriptor and thus we get keys from it.
45+
let public_keys = psbt_input.tap_key_origins.keys();
46+
for key in public_keys {
47+
let bitcoin_key = *key;
48+
// Convert PubKeyHash into Hash::hash160
49+
let hash = bitcoin_key.to_pubkeyhash(SigType::Schnorr);
50+
// Insert pair in HashMap
51+
hash_map.insert(hash, bitcoin_key);
52+
}
53+
}
3654
assert!(spk.is_v1_p2tr());
3755

3856
// try the key spend path first
@@ -55,7 +73,7 @@ fn construct_tap_witness(
5573
script,
5674
&ExtParams::allow_all(),
5775
) {
58-
Ok(ms) => ms,
76+
Ok(ms) => ms.substitute_raw_pkh(&hash_map),
5977
Err(..) => continue, // try another script
6078
};
6179
let mut wit = if allow_mall {

0 commit comments

Comments
 (0)