Skip to content

Commit f11baaa

Browse files
committed
implement satisfier for psbt
1 parent 63136bd commit f11baaa

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ pub use miniscript::decode::Terminal;
129129
pub use miniscript::satisfy::{Preimage32, Satisfier};
130130
pub use miniscript::Miniscript;
131131

132-
// Use schnorr pubkey as Xonlykey
133-
pub(crate) use bitcoin::schnorr::PublicKey as XOnlyKey;
134132

135133
///Public key trait which can be converted to Hash type
136134
pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Hash {

src/psbt/finalizer.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use util::{script_is_v1_tr, witness_size};
2424
use super::{sanity_check, Psbt};
2525
use super::{Error, InputError, PsbtInputSatisfier};
2626
use bitcoin::blockdata::witness::Witness;
27+
use bitcoin::secp256k1::XOnlyPublicKey;
2728
use bitcoin::secp256k1::{self, Secp256k1};
2829
use bitcoin::util::taproot::LeafVersion;
2930
use bitcoin::{self, PublicKey, Script};
@@ -32,7 +33,6 @@ use interpreter;
3233
use Descriptor;
3334
use Miniscript;
3435
use Satisfier;
35-
use XOnlyKey;
3636
use {BareCtx, Legacy, Segwitv0, Tap};
3737

3838
// Satisfy the taproot descriptor. It is not possible to infer the complete
@@ -47,20 +47,22 @@ fn construct_tap_witness(
4747
assert!(script_is_v1_tr(&spk));
4848

4949
// try the script spend path first
50-
if let Some(sig) = <PsbtInputSatisfier as Satisfier<XOnlyKey>>::lookup_tap_key_spend_sig(sat) {
50+
if let Some(sig) =
51+
<PsbtInputSatisfier as Satisfier<XOnlyPublicKey>>::lookup_tap_key_spend_sig(sat)
52+
{
5153
return Ok(vec![sig.to_vec()]);
5254
}
5355
// Next script spends
5456
let (mut min_wit, mut min_wit_len) = (None, None);
5557
if let Some(block_map) =
56-
<PsbtInputSatisfier as Satisfier<XOnlyKey>>::lookup_tap_control_block_map(sat)
58+
<PsbtInputSatisfier as Satisfier<XOnlyPublicKey>>::lookup_tap_control_block_map(sat)
5759
{
5860
for (control_block, (script, ver)) in block_map {
59-
if *ver != LeafVersion::default() {
61+
if *ver != LeafVersion::TapScript {
6062
// We don't know how to satisfy non default version scripts yet
6163
continue;
6264
}
63-
let ms = match Miniscript::<XOnlyKey, Tap>::parse_insane(script) {
65+
let ms = match Miniscript::<XOnlyPublicKey, Tap>::parse_insane(script) {
6466
Ok(ms) => ms,
6567
Err(..) => continue, // try another script
6668
};

src/psbt/mod.rs

+33
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//! `https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki`
2020
//!
2121
22+
use std::collections::BTreeMap;
2223
use std::{error, fmt};
2324

2425
use bitcoin;
@@ -28,6 +29,7 @@ use bitcoin::secp256k1::{self, Secp256k1};
2829
use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
2930
use bitcoin::Script;
3031

32+
use bitcoin::util::taproot::{ControlBlock, LeafVersion, TapLeafHash};
3133
use interpreter;
3234
use miniscript::limits::SEQUENCE_LOCKTIME_DISABLE_FLAG;
3335
use miniscript::satisfy::{After, Older};
@@ -232,6 +234,37 @@ impl<'psbt> PsbtInputSatisfier<'psbt> {
232234
}
233235

234236
impl<'psbt, Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'psbt> {
237+
fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::SchnorrSig> {
238+
self.psbt.inputs[self.index].tap_key_sig
239+
}
240+
241+
fn lookup_tap_leaf_script_sig(&self, pk: &Pk, lh: &TapLeafHash) -> Option<bitcoin::SchnorrSig> {
242+
self.psbt.inputs[self.index]
243+
.tap_script_sigs
244+
.get(&(pk.to_x_only_pubkey(), *lh))
245+
.map(|x| *x) // replace by copied in 1.36
246+
}
247+
248+
fn lookup_tap_control_block_map(
249+
&self,
250+
) -> Option<&BTreeMap<ControlBlock, (bitcoin::Script, LeafVersion)>> {
251+
Some(&self.psbt.inputs[self.index].tap_scripts)
252+
}
253+
254+
fn lookup_pkh_tap_leaf_script_sig(
255+
&self,
256+
pkh: &(Pk::Hash, TapLeafHash),
257+
) -> Option<(bitcoin::secp256k1::XOnlyPublicKey, bitcoin::SchnorrSig)> {
258+
self.psbt.inputs[self.index]
259+
.tap_script_sigs
260+
.iter()
261+
.filter(|&((pubkey, lh), _sig)| {
262+
pubkey.to_pubkeyhash() == Pk::hash_to_hash160(&pkh.0) && *lh == pkh.1
263+
})
264+
.next()
265+
.map(|((x_only_pk, _leaf_hash), sig)| (*x_only_pk, *sig))
266+
}
267+
235268
fn lookup_ecdsa_sig(&self, pk: &Pk) -> Option<bitcoin::EcdsaSig> {
236269
self.psbt.inputs[self.index]
237270
.partial_sigs

0 commit comments

Comments
 (0)