sapio_miniscript/interpreter/
mod.rs

1// Miniscript
2// Written in 2019 by
3//     Sanket Kanjular and Andrew Poelstra
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! Interpreter
16//!
17//! Provides a Miniscript-based script interpreter which can be used to
18//! iterate over the set of conditions satisfied by a spending transaction,
19//! assuming that the spent coin was descriptor controlled.
20//!
21
22use bitcoin::blockdata::witness::Witness;
23use bitcoin::util::{sighash, taproot};
24use std::borrow::Borrow;
25use std::fmt;
26use std::str::FromStr;
27
28use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d};
29use bitcoin::{self, secp256k1, TxOut};
30use miniscript::context::NoChecks;
31use miniscript::ScriptContext;
32use Miniscript;
33use Terminal;
34use {Descriptor, ToPublicKey};
35
36mod error;
37mod inner;
38mod stack;
39
40use MiniscriptKey;
41
42pub use self::error::Error;
43use self::error::PkEvalErrInner;
44use self::stack::Stack;
45
46/// An iterable Miniscript-structured representation of the spending of a coin
47pub struct Interpreter<'txin> {
48    inner: inner::Inner,
49    stack: Stack<'txin>,
50    /// For non-Taproot spends, the scriptCode; for Taproot script-spends, this
51    /// is the leaf script; for key-spends it is `None`.
52    script_code: Option<bitcoin::Script>,
53    age: u32,
54    height: u32,
55    txtemplate: sha256::Hash,
56}
57
58// A type representing functions for checking signatures that accept both
59// Ecdsa and Schnorr signatures
60
61/// A type for representing signatures supported as of bitcoin core 22.0
62#[derive(Debug, Clone, Copy, PartialEq, Eq)]
63pub enum KeySigPair {
64    /// A Full public key and corresponding Ecdsa signature
65    Ecdsa(bitcoin::PublicKey, bitcoin::EcdsaSig),
66    /// A x-only key and corresponding Schnorr signature
67    Schnorr(bitcoin::XOnlyPublicKey, bitcoin::SchnorrSig),
68}
69
70impl KeySigPair {
71    /// Obtain a pair of ([`bitcoin::PublicKey`], [`bitcoin::EcdsaSig`]) from [`KeySigPair`]
72    pub fn as_ecdsa(&self) -> Option<(bitcoin::PublicKey, bitcoin::EcdsaSig)> {
73        match self {
74            KeySigPair::Ecdsa(pk, sig) => Some((*pk, *sig)),
75            KeySigPair::Schnorr(_, _) => None,
76        }
77    }
78
79    /// Obtain a pair of ([`bitcoin::XOnlyPublicKey`], [`bitcoin::SchnorrSig`]) from [`KeySigPair`]
80    pub fn as_schnorr(&self) -> Option<(bitcoin::XOnlyPublicKey, bitcoin::SchnorrSig)> {
81        match self {
82            KeySigPair::Ecdsa(_, _) => None,
83            KeySigPair::Schnorr(pk, sig) => Some((*pk, *sig)),
84        }
85    }
86}
87
88// Internally used enum for different types of bitcoin keys
89// Even though we implement MiniscriptKey for BitcoinKey, we make sure that there
90// are little mis-use
91// - The only constructors for this are only called in from_txdata that take care
92//   using the correct enum variant
93// - This does not implement ToPublicKey to avoid context dependant encoding/decoding of 33/32
94//   byte keys. This allows us to keep a single NoChecks context instead of a context for
95//   for NoChecksSchnorr/NoChecksEcdsa.
96// Long term TODO: There really should be not be any need for Miniscript<Pk: MiniscriptKey> struct
97// to have the Pk: MiniscriptKey bound. The bound should be on all of it's methods. That would
98// require changing Miniscript struct to three generics Miniscript<Pk, Pkh, Ctx> and bound on
99// all of the methods of Miniscript to ensure that Pkh = Pk::Hash
100#[derive(Hash, Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Debug)]
101enum BitcoinKey {
102    // Full key
103    Fullkey(bitcoin::PublicKey),
104    // Xonly key
105    XOnlyPublicKey(bitcoin::XOnlyPublicKey),
106}
107
108// Displayed in full 33 byte representation. X-only keys are displayed with 0x02 prefix
109impl fmt::Display for BitcoinKey {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        match self {
112            BitcoinKey::Fullkey(pk) => pk.to_public_key().fmt(f),
113            BitcoinKey::XOnlyPublicKey(pk) => pk.to_public_key().fmt(f),
114        }
115    }
116}
117
118impl From<bitcoin::PublicKey> for BitcoinKey {
119    fn from(pk: bitcoin::PublicKey) -> Self {
120        BitcoinKey::Fullkey(pk)
121    }
122}
123
124impl From<bitcoin::XOnlyPublicKey> for BitcoinKey {
125    fn from(xpk: bitcoin::XOnlyPublicKey) -> Self {
126        BitcoinKey::XOnlyPublicKey(xpk)
127    }
128}
129
130// While parsing we need to remember how to the hash was parsed so that we can
131#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
132enum TypedHash160 {
133    XonlyKey(hash160::Hash),
134    FullKey(hash160::Hash),
135}
136
137impl fmt::Display for TypedHash160 {
138    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139        match self {
140            TypedHash160::FullKey(pkh) | TypedHash160::XonlyKey(pkh) => pkh.fmt(f),
141        }
142    }
143}
144
145impl TypedHash160 {
146    fn hash160(&self) -> hash160::Hash {
147        match self {
148            TypedHash160::XonlyKey(hash) | TypedHash160::FullKey(hash) => *hash,
149        }
150    }
151}
152
153impl MiniscriptKey for BitcoinKey {
154    type Hash = TypedHash160;
155
156    fn to_pubkeyhash(&self) -> Self::Hash {
157        match self {
158            BitcoinKey::Fullkey(pk) => TypedHash160::FullKey(pk.to_pubkeyhash()),
159            BitcoinKey::XOnlyPublicKey(pk) => TypedHash160::XonlyKey(pk.to_pubkeyhash()),
160        }
161    }
162}
163
164impl<'txin> Interpreter<'txin> {
165    /// Constructs an interpreter from the data of a spending transaction
166    ///
167    /// Accepts a signature-validating function. If you are willing to trust
168    /// that ECSDA signatures are valid, this can be set to the constant true
169    /// function; otherwise, it should be a closure containing a sighash and
170    /// secp context, which can actually verify a given signature.
171    pub fn from_txdata(
172        spk: &bitcoin::Script,
173        script_sig: &'txin bitcoin::Script,
174        witness: &'txin Witness,
175        age: u32,
176        height: u32,
177        txtemplate: sha256::Hash,
178    ) -> Result<Self, Error> {
179        let (inner, stack, script_code) = inner::from_txdata(spk, script_sig, witness)?;
180        Ok(Interpreter {
181            inner,
182            stack,
183            script_code,
184            age,
185            height,
186            txtemplate,
187        })
188    }
189
190    /// Same as [`Interpreter::iter`], but allows for a custom verification function.
191    /// See [Self::iter_assume_sigs] for a simpler API without information about Prevouts
192    /// but skips the signature verification
193    pub fn iter_custom<'iter>(
194        &'iter self,
195        verify_sig: Box<dyn FnMut(&KeySigPair) -> bool + 'iter>,
196    ) -> Iter<'txin, 'iter> {
197        Iter {
198            verify_sig: verify_sig,
199            public_key: if let inner::Inner::PublicKey(ref pk, _) = self.inner {
200                Some(pk)
201            } else {
202                None
203            },
204            state: if let inner::Inner::Script(ref script, _) = self.inner {
205                vec![NodeEvaluationState {
206                    node: script,
207                    n_evaluated: 0,
208                    n_satisfied: 0,
209                }]
210            } else {
211                vec![]
212            },
213            // Cloning the references to elements of stack should be fine as it allows
214            // call interpreter.iter() without mutating interpreter
215            stack: self.stack.clone(),
216            age: self.age,
217            height: self.height,
218            has_errored: false,
219            txtemplate: &self.txtemplate,
220        }
221    }
222
223    /// Verify a signature for a given transaction and prevout information
224    /// This is a low level API, [`Interpreter::iter`] or [`Interpreter::iter_assume_sig`]
225    /// should satisfy most use-cases.
226    /// Returns false if
227    /// - the signature verification fails
228    /// - the input index is out of range
229    /// - Insufficient sighash information is present
230    /// - sighash single without corresponding output
231    // TODO: Create a good first isse to change this to error
232    pub fn verify_sig<C: secp256k1::Verification, T: Borrow<TxOut>>(
233        &self,
234        secp: &secp256k1::Secp256k1<C>,
235        tx: &bitcoin::Transaction,
236        input_idx: usize,
237        prevouts: &sighash::Prevouts<T>,
238        sig: &KeySigPair,
239    ) -> bool {
240        fn get_prevout<'u, T: Borrow<TxOut>>(
241            prevouts: &'u sighash::Prevouts<'u, T>,
242            input_index: usize,
243        ) -> Option<&'u T> {
244            match prevouts {
245                sighash::Prevouts::One(index, prevout) => {
246                    if input_index == *index {
247                        Some(prevout)
248                    } else {
249                        None
250                    }
251                }
252                sighash::Prevouts::All(prevouts) => prevouts.get(input_index),
253            }
254        }
255        let mut cache = bitcoin::util::sighash::SighashCache::new(tx);
256        match sig {
257            KeySigPair::Ecdsa(key, ecdsa_sig) => {
258                let script_pubkey = self.script_code.as_ref().expect("Legacy have script code");
259                let sighash = if self.is_legacy() {
260                    let sighash_u32 = ecdsa_sig.hash_ty.to_u32();
261                    cache.legacy_signature_hash(input_idx, &script_pubkey, sighash_u32)
262                } else if self.is_segwit_v0() {
263                    let amt = match get_prevout(prevouts, input_idx) {
264                        Some(txout) => txout.borrow().value,
265                        None => return false,
266                    };
267                    cache.segwit_signature_hash(input_idx, &script_pubkey, amt, ecdsa_sig.hash_ty)
268                } else {
269                    // taproot(or future) signatures in segwitv0 context
270                    return false;
271                };
272                let msg =
273                    sighash.map(|hash| secp256k1::Message::from_slice(&hash).expect("32 byte"));
274                let success =
275                    msg.map(|msg| secp.verify_ecdsa(&msg, &ecdsa_sig.sig, &key.inner).is_ok());
276                success.unwrap_or(false) // unwrap_or checks for errors, while success would have checksig results
277            }
278            KeySigPair::Schnorr(xpk, schnorr_sig) => {
279                let sighash_msg = if self.is_taproot_v1_key_spend() {
280                    cache.taproot_key_spend_signature_hash(input_idx, prevouts, schnorr_sig.hash_ty)
281                } else if self.is_taproot_v1_script_spend() {
282                    let tap_script = self.script_code.as_ref().expect(
283                        "Internal Hack: Saving leaf script instead\
284                        of script code for script spend",
285                    );
286                    let leaf_hash = taproot::TapLeafHash::from_script(
287                        &tap_script,
288                        taproot::LeafVersion::TapScript,
289                    );
290                    cache.taproot_script_spend_signature_hash(
291                        input_idx,
292                        prevouts,
293                        leaf_hash,
294                        schnorr_sig.hash_ty,
295                    )
296                } else {
297                    // schnorr sigs in ecdsa descriptors
298                    return false;
299                };
300                let msg =
301                    sighash_msg.map(|hash| secp256k1::Message::from_slice(&hash).expect("32 byte"));
302                let success =
303                    msg.map(|msg| secp.verify_schnorr(&schnorr_sig.sig, &msg, &xpk).is_ok());
304                success.unwrap_or(false) // unwrap_or_default checks for errors, while success would have checksig results
305            }
306        }
307    }
308
309    /// Creates an iterator over the satisfied spending conditions
310    ///
311    /// Returns all satisfied constraints, even if they were redundant (i.e. did
312    /// not contribute to the script being satisfied). For example, if a signature
313    /// were provided for an `and_b(Pk,false)` fragment, that signature will be
314    /// returned, even though the entire and_b must have failed and must not have
315    /// been used.
316    ///
317    /// In case the script is actually dissatisfied, this may return several values
318    /// before ultimately returning an error.
319    ///
320    /// Not all fields are used by legacy/segwitv0 descriptors; if you are sure this is a legacy
321    /// spend (you can check with the `is_legacy\is_segwitv0` method) you can provide dummy data for
322    /// the amount/prevouts.
323    /// - For legacy outputs, no information about prevouts is required
324    /// - For segwitv0 outputs, prevout at corresponding index with correct amount must be provided
325    /// - For taproot outputs, information about all prevouts must be supplied
326    pub fn iter<'iter, C: secp256k1::Verification, T: Borrow<TxOut>>(
327        &'iter self,
328        secp: &'iter secp256k1::Secp256k1<C>,
329        tx: &'txin bitcoin::Transaction,
330        input_idx: usize,
331        prevouts: &'iter sighash::Prevouts<T>, // actually a 'prevouts, but 'prevouts: 'iter
332    ) -> Iter<'txin, 'iter> {
333        self.iter_custom(Box::new(move |sig| {
334            self.verify_sig(secp, tx, input_idx, prevouts, sig)
335        }))
336    }
337
338    /// Creates an iterator over the satisfied spending conditions without checking signatures
339    pub fn iter_assume_sigs<'iter>(&'iter self) -> Iter<'txin, 'iter> {
340        self.iter_custom(Box::new(|_| true))
341    }
342
343    /// Outputs a "descriptor" string which reproduces the spent coins
344    ///
345    /// This may not represent the original descriptor used to produce the transaction,
346    /// since it cannot distinguish between sorted and unsorted multisigs (and anyway
347    /// it can only see the final keys, keyorigin info is lost in serializing to Bitcoin).
348    ///
349    /// If you are using the interpreter as a sanity check on a transaction,
350    /// it is worthwhile to try to parse this as a descriptor using `from_str`
351    /// which will check standardness and consensus limits, which the interpreter
352    /// does not do on its own. Or use the `inferred_descriptor` method which
353    /// does this for you.
354    pub fn inferred_descriptor_string(&self) -> String {
355        match self.inner {
356            inner::Inner::PublicKey(ref pk, inner::PubkeyType::Pk) => format!("pk({})", pk),
357            inner::Inner::PublicKey(ref pk, inner::PubkeyType::Pkh) => format!("pkh({})", pk),
358            inner::Inner::PublicKey(ref pk, inner::PubkeyType::Wpkh) => format!("wpkh({})", pk),
359            inner::Inner::PublicKey(ref pk, inner::PubkeyType::ShWpkh) => {
360                format!("sh(wpkh({}))", pk)
361            }
362            inner::Inner::PublicKey(ref pk, inner::PubkeyType::Tr) => {
363                // In tr descriptors, normally the internal key is represented inside the tr part
364                // But there is no way to infer the internal key from output descriptor status
365                // instead we infer a rawtr.
366                // Note that rawtr is parsing is currently not supported.
367                format!("rawtr_not_supported_yet({})", pk)
368            }
369            inner::Inner::Script(ref ms, inner::ScriptType::Bare) => format!("{}", ms),
370            inner::Inner::Script(ref ms, inner::ScriptType::Sh) => format!("sh({})", ms),
371            inner::Inner::Script(ref ms, inner::ScriptType::Wsh) => format!("wsh({})", ms),
372            inner::Inner::Script(ref ms, inner::ScriptType::ShWsh) => format!("sh(wsh({}))", ms),
373            inner::Inner::Script(ref ms, inner::ScriptType::Tr) => {
374                // Hidden paths are still under discussion, once the spec is finalized, we can support
375                // rawnode and raw leaf.
376                format!("tr(hidden_paths_not_yet_supported,{})", ms)
377            }
378        }
379    }
380
381    /// Whether this is a pre-segwit spend
382    pub fn is_legacy(&self) -> bool {
383        match self.inner {
384            inner::Inner::PublicKey(_, inner::PubkeyType::Pk) => true,
385            inner::Inner::PublicKey(_, inner::PubkeyType::Pkh) => true,
386            inner::Inner::PublicKey(_, inner::PubkeyType::Wpkh) => false,
387            inner::Inner::PublicKey(_, inner::PubkeyType::ShWpkh) => false, // lol "sorta"
388            inner::Inner::PublicKey(_, inner::PubkeyType::Tr) => false,     // lol "sorta"
389            inner::Inner::Script(_, inner::ScriptType::Bare) => false,
390            inner::Inner::Script(_, inner::ScriptType::Sh) => true,
391            inner::Inner::Script(_, inner::ScriptType::Wsh) => false,
392            inner::Inner::Script(_, inner::ScriptType::ShWsh) => false, // lol "sorta"
393            inner::Inner::Script(_, inner::ScriptType::Tr) => false,
394        }
395    }
396
397    /// Whether this is a segwit spend
398    pub fn is_segwit_v0(&self) -> bool {
399        match self.inner {
400            inner::Inner::PublicKey(_, inner::PubkeyType::Pk) => false,
401            inner::Inner::PublicKey(_, inner::PubkeyType::Pkh) => false,
402            inner::Inner::PublicKey(_, inner::PubkeyType::Wpkh) => true,
403            inner::Inner::PublicKey(_, inner::PubkeyType::ShWpkh) => true, // lol "sorta"
404            inner::Inner::PublicKey(_, inner::PubkeyType::Tr) => false,
405            inner::Inner::Script(_, inner::ScriptType::Bare) => false,
406            inner::Inner::Script(_, inner::ScriptType::Sh) => false,
407            inner::Inner::Script(_, inner::ScriptType::Wsh) => true,
408            inner::Inner::Script(_, inner::ScriptType::ShWsh) => true, // lol "sorta"
409            inner::Inner::Script(_, inner::ScriptType::Tr) => false,
410        }
411    }
412
413    /// Whether this is a taproot key spend
414    pub fn is_taproot_v1_key_spend(&self) -> bool {
415        match self.inner {
416            inner::Inner::PublicKey(_, inner::PubkeyType::Pk) => false,
417            inner::Inner::PublicKey(_, inner::PubkeyType::Pkh) => false,
418            inner::Inner::PublicKey(_, inner::PubkeyType::Wpkh) => false,
419            inner::Inner::PublicKey(_, inner::PubkeyType::ShWpkh) => false,
420            inner::Inner::PublicKey(_, inner::PubkeyType::Tr) => true,
421            inner::Inner::Script(_, inner::ScriptType::Bare) => false,
422            inner::Inner::Script(_, inner::ScriptType::Sh) => false,
423            inner::Inner::Script(_, inner::ScriptType::Wsh) => false,
424            inner::Inner::Script(_, inner::ScriptType::ShWsh) => false,
425            inner::Inner::Script(_, inner::ScriptType::Tr) => false,
426        }
427    }
428
429    /// Whether this is a taproot script spend
430    pub fn is_taproot_v1_script_spend(&self) -> bool {
431        match self.inner {
432            inner::Inner::PublicKey(_, inner::PubkeyType::Pk) => false,
433            inner::Inner::PublicKey(_, inner::PubkeyType::Pkh) => false,
434            inner::Inner::PublicKey(_, inner::PubkeyType::Wpkh) => false,
435            inner::Inner::PublicKey(_, inner::PubkeyType::ShWpkh) => false,
436            inner::Inner::PublicKey(_, inner::PubkeyType::Tr) => false,
437            inner::Inner::Script(_, inner::ScriptType::Bare) => false,
438            inner::Inner::Script(_, inner::ScriptType::Sh) => false,
439            inner::Inner::Script(_, inner::ScriptType::Wsh) => false,
440            inner::Inner::Script(_, inner::ScriptType::ShWsh) => false,
441            inner::Inner::Script(_, inner::ScriptType::Tr) => true,
442        }
443    }
444
445    /// Outputs a "descriptor" which reproduces the spent coins
446    ///
447    /// This may not represent the original descriptor used to produce the transaction,
448    /// since it cannot distinguish between sorted and unsorted multisigs (and anyway
449    /// it can only see the final keys, keyorigin info is lost in serializing to Bitcoin).
450    /// x-only keys are translated to [`bitcoin::PublicKey`] with 0x02 prefix.
451    pub fn inferred_descriptor(&self) -> Result<Descriptor<bitcoin::PublicKey>, ::Error> {
452        Descriptor::from_str(&self.inferred_descriptor_string())
453    }
454}
455
456/// Type of HashLock used for SatisfiedConstraint structure
457#[derive(Copy, Clone, Debug, Eq, PartialEq)]
458pub enum HashLockType {
459    ///SHA 256 hashlock
460    Sha256(sha256::Hash),
461    ///Hash 256 hashlock
462    Hash256(sha256d::Hash),
463    ///Hash160 hashlock
464    Hash160(hash160::Hash),
465    ///Ripemd160 hashlock
466    Ripemd160(ripemd160::Hash),
467}
468
469/// A satisfied Miniscript condition (Signature, Hashlock, Timelock)
470/// 'intp represents the lifetime of descriptor and `stack represents
471/// the lifetime of witness
472#[derive(Copy, Clone, Debug, Eq, PartialEq)]
473pub enum SatisfiedConstraint {
474    ///Public key and corresponding signature
475    PublicKey {
476        /// KeySig pair
477        key_sig: KeySigPair,
478    },
479    ///PublicKeyHash, corresponding pubkey and signature
480    PublicKeyHash {
481        /// The pubkey hash
482        keyhash: hash160::Hash,
483        /// public key and signature
484        key_sig: KeySigPair,
485    },
486    ///Hashlock and preimage for SHA256
487    HashLock {
488        /// The type of Hashlock
489        hash: HashLockType,
490        /// The preimage used for satisfaction
491        preimage: [u8; 32],
492    },
493    ///Relative Timelock for CSV.
494    RelativeTimeLock {
495        /// The value of RelativeTimelock
496        time: u32,
497    },
498    ///Absolute Timelock for CLTV.
499    AbsoluteTimeLock {
500        /// The value of Absolute timelock
501        time: u32,
502    },
503    /// Check Template Verify Covenant
504    TxTemplate {
505        /// The hash value of the transaction
506        hash: sha256::Hash,
507    },
508}
509
510///This is used by the interpreter to know which evaluation state a AstemElem is.
511///This is required because whenever a same node(for eg. OrB) appears on the stack, we don't
512///know if the left child has been evaluated or not. And based on the result on
513///the top of the stack, we need to decide whether to execute right child or not.
514///This is also useful for wrappers and thresholds which push a value on the stack
515///depending on evaluation of the children.
516struct NodeEvaluationState<'intp> {
517    ///The node which is being evaluated
518    node: &'intp Miniscript<BitcoinKey, NoChecks>,
519    ///number of children evaluated
520    n_evaluated: usize,
521    ///number of children satisfied
522    n_satisfied: usize,
523}
524
525/// Iterator over all the constraints satisfied by a completed scriptPubKey
526/// and witness stack
527///
528/// Returns all satisfied constraints, even if they were redundant (i.e. did
529/// not contribute to the script being satisfied). For example, if a signature
530/// were provided for an `and_b(Pk,false)` fragment, that signature will be
531/// returned, even though the entire and_b must have failed and must not have
532/// been used.
533///
534/// In case the script is actually dissatisfied, this may return several values
535/// before ultimately returning an error.
536pub struct Iter<'intp, 'txin: 'intp> {
537    verify_sig: Box<dyn FnMut(&KeySigPair) -> bool + 'intp>,
538    public_key: Option<&'intp BitcoinKey>,
539    state: Vec<NodeEvaluationState<'intp>>,
540    stack: Stack<'txin>,
541    age: u32,
542    height: u32,
543    has_errored: bool,
544    txtemplate: &'intp sha256::Hash,
545}
546
547///Iterator for Iter
548impl<'intp, 'txin: 'intp> Iterator for Iter<'intp, 'txin>
549where
550    NoChecks: ScriptContext,
551{
552    type Item = Result<SatisfiedConstraint, Error>;
553
554    fn next(&mut self) -> Option<Self::Item> {
555        if self.has_errored {
556            // Stop yielding values after the first error
557            None
558        } else {
559            let res = self.iter_next();
560            if let Some(Err(_)) = res {
561                self.has_errored = true;
562            }
563            res
564        }
565    }
566}
567
568impl<'intp, 'txin: 'intp> Iter<'intp, 'txin>
569where
570    NoChecks: ScriptContext,
571{
572    /// Helper function to push a NodeEvaluationState on state stack
573    fn push_evaluation_state(
574        &mut self,
575        node: &'intp Miniscript<BitcoinKey, NoChecks>,
576        n_evaluated: usize,
577        n_satisfied: usize,
578    ) -> () {
579        self.state.push(NodeEvaluationState {
580            node,
581            n_evaluated,
582            n_satisfied,
583        })
584    }
585
586    /// Helper function to step the iterator
587    fn iter_next(&mut self) -> Option<Result<SatisfiedConstraint, Error>> {
588        while let Some(node_state) = self.state.pop() {
589            //non-empty stack
590            match node_state.node.node {
591                Terminal::True => {
592                    debug_assert_eq!(node_state.n_evaluated, 0);
593                    debug_assert_eq!(node_state.n_satisfied, 0);
594                    self.stack.push(stack::Element::Satisfied);
595                }
596                Terminal::False => {
597                    debug_assert_eq!(node_state.n_evaluated, 0);
598                    debug_assert_eq!(node_state.n_satisfied, 0);
599                    self.stack.push(stack::Element::Dissatisfied);
600                }
601                Terminal::PkK(ref pk) => {
602                    debug_assert_eq!(node_state.n_evaluated, 0);
603                    debug_assert_eq!(node_state.n_satisfied, 0);
604                    let res = self.stack.evaluate_pk(&mut self.verify_sig, pk);
605                    if res.is_some() {
606                        return res;
607                    }
608                }
609                Terminal::PkH(ref pkh) => {
610                    debug_assert_eq!(node_state.n_evaluated, 0);
611                    debug_assert_eq!(node_state.n_satisfied, 0);
612                    let res = self.stack.evaluate_pkh(&mut self.verify_sig, pkh);
613                    if res.is_some() {
614                        return res;
615                    }
616                }
617                Terminal::After(ref n) => {
618                    debug_assert_eq!(node_state.n_evaluated, 0);
619                    debug_assert_eq!(node_state.n_satisfied, 0);
620                    let res = self.stack.evaluate_after(n, self.age);
621                    if res.is_some() {
622                        return res;
623                    }
624                }
625                Terminal::Older(ref n) => {
626                    debug_assert_eq!(node_state.n_evaluated, 0);
627                    debug_assert_eq!(node_state.n_satisfied, 0);
628                    let res = self.stack.evaluate_older(n, self.height);
629                    if res.is_some() {
630                        return res;
631                    }
632                }
633                Terminal::Sha256(ref hash) => {
634                    debug_assert_eq!(node_state.n_evaluated, 0);
635                    debug_assert_eq!(node_state.n_satisfied, 0);
636                    let res = self.stack.evaluate_sha256(hash);
637                    if res.is_some() {
638                        return res;
639                    }
640                }
641                Terminal::Hash256(ref hash) => {
642                    debug_assert_eq!(node_state.n_evaluated, 0);
643                    debug_assert_eq!(node_state.n_satisfied, 0);
644                    let res = self.stack.evaluate_hash256(hash);
645                    if res.is_some() {
646                        return res;
647                    }
648                }
649                Terminal::Hash160(ref hash) => {
650                    debug_assert_eq!(node_state.n_evaluated, 0);
651                    debug_assert_eq!(node_state.n_satisfied, 0);
652                    let res = self.stack.evaluate_hash160(hash);
653                    if res.is_some() {
654                        return res;
655                    }
656                }
657                Terminal::Ripemd160(ref hash) => {
658                    debug_assert_eq!(node_state.n_evaluated, 0);
659                    debug_assert_eq!(node_state.n_satisfied, 0);
660                    let res = self.stack.evaluate_ripemd160(hash);
661                    if res.is_some() {
662                        return res;
663                    }
664                }
665                Terminal::Alt(ref sub) | Terminal::Swap(ref sub) | Terminal::Check(ref sub) => {
666                    debug_assert_eq!(node_state.n_evaluated, 0);
667                    debug_assert_eq!(node_state.n_satisfied, 0);
668                    self.push_evaluation_state(sub, 0, 0);
669                }
670                Terminal::DupIf(ref sub) if node_state.n_evaluated == 0 => match self.stack.pop() {
671                    Some(stack::Element::Dissatisfied) => {
672                        self.stack.push(stack::Element::Dissatisfied);
673                    }
674                    Some(stack::Element::Satisfied) => {
675                        self.push_evaluation_state(node_state.node, 1, 1);
676                        self.push_evaluation_state(sub, 0, 0);
677                    }
678                    Some(stack::Element::Push(_v)) => {
679                        return Some(Err(Error::UnexpectedStackElementPush))
680                    }
681                    None => return Some(Err(Error::UnexpectedStackEnd)),
682                },
683                Terminal::DupIf(ref _sub) if node_state.n_evaluated == 1 => {
684                    self.stack.push(stack::Element::Satisfied);
685                }
686                Terminal::ZeroNotEqual(ref sub) | Terminal::Verify(ref sub)
687                    if node_state.n_evaluated == 0 =>
688                {
689                    self.push_evaluation_state(node_state.node, 1, 0);
690                    self.push_evaluation_state(sub, 0, 0);
691                }
692                Terminal::Verify(ref _sub) if node_state.n_evaluated == 1 => {
693                    match self.stack.pop() {
694                        Some(stack::Element::Satisfied) => (),
695                        Some(_) => return Some(Err(Error::VerifyFailed)),
696                        None => return Some(Err(Error::UnexpectedStackEnd)),
697                    }
698                }
699                Terminal::ZeroNotEqual(ref _sub) if node_state.n_evaluated == 1 => {
700                    match self.stack.pop() {
701                        Some(stack::Element::Dissatisfied) => {
702                            self.stack.push(stack::Element::Dissatisfied)
703                        }
704                        Some(_) => self.stack.push(stack::Element::Satisfied),
705                        None => return Some(Err(Error::UnexpectedStackEnd)),
706                    }
707                }
708                Terminal::NonZero(ref sub) => {
709                    debug_assert_eq!(node_state.n_evaluated, 0);
710                    debug_assert_eq!(node_state.n_satisfied, 0);
711                    match self.stack.last() {
712                        Some(&stack::Element::Dissatisfied) => (),
713                        Some(_) => self.push_evaluation_state(sub, 0, 0),
714                        None => return Some(Err(Error::UnexpectedStackEnd)),
715                    }
716                }
717                Terminal::AndV(ref left, ref right) => {
718                    debug_assert_eq!(node_state.n_evaluated, 0);
719                    debug_assert_eq!(node_state.n_satisfied, 0);
720                    self.push_evaluation_state(right, 0, 0);
721                    self.push_evaluation_state(left, 0, 0);
722                }
723                Terminal::OrB(ref left, ref _right) | Terminal::AndB(ref left, ref _right)
724                    if node_state.n_evaluated == 0 =>
725                {
726                    self.push_evaluation_state(node_state.node, 1, 0);
727                    self.push_evaluation_state(left, 0, 0);
728                }
729                Terminal::OrB(ref _left, ref right) | Terminal::AndB(ref _left, ref right)
730                    if node_state.n_evaluated == 1 =>
731                {
732                    match self.stack.pop() {
733                        Some(stack::Element::Dissatisfied) => {
734                            self.push_evaluation_state(node_state.node, 2, 0);
735                            self.push_evaluation_state(right, 0, 0);
736                        }
737                        Some(stack::Element::Satisfied) => {
738                            self.push_evaluation_state(node_state.node, 2, 1);
739                            self.push_evaluation_state(right, 0, 0);
740                        }
741                        Some(stack::Element::Push(_v)) => {
742                            return Some(Err(Error::UnexpectedStackElementPush))
743                        }
744                        None => return Some(Err(Error::UnexpectedStackEnd)),
745                    }
746                }
747                Terminal::AndB(ref _left, ref _right) if node_state.n_evaluated == 2 => {
748                    match self.stack.pop() {
749                        Some(stack::Element::Satisfied) if node_state.n_satisfied == 1 => {
750                            self.stack.push(stack::Element::Satisfied)
751                        }
752                        Some(_) => self.stack.push(stack::Element::Dissatisfied),
753                        None => return Some(Err(Error::UnexpectedStackEnd)),
754                    }
755                }
756                Terminal::AndOr(ref left, ref _right, _)
757                | Terminal::OrC(ref left, ref _right)
758                | Terminal::OrD(ref left, ref _right)
759                    if node_state.n_evaluated == 0 =>
760                {
761                    self.push_evaluation_state(node_state.node, 1, 0);
762                    self.push_evaluation_state(left, 0, 0);
763                }
764                Terminal::OrB(ref _left, ref _right) if node_state.n_evaluated == 2 => {
765                    match self.stack.pop() {
766                        Some(stack::Element::Dissatisfied) if node_state.n_satisfied == 0 => {
767                            self.stack.push(stack::Element::Dissatisfied)
768                        }
769                        Some(_) => {
770                            self.stack.push(stack::Element::Satisfied);
771                        }
772                        None => return Some(Err(Error::UnexpectedStackEnd)),
773                    }
774                }
775                Terminal::OrC(ref _left, ref right) if node_state.n_evaluated == 1 => {
776                    match self.stack.pop() {
777                        Some(stack::Element::Satisfied) => (),
778                        Some(stack::Element::Dissatisfied) => {
779                            self.push_evaluation_state(right, 0, 0)
780                        }
781                        Some(stack::Element::Push(_v)) => {
782                            return Some(Err(Error::UnexpectedStackElementPush))
783                        }
784                        None => return Some(Err(Error::UnexpectedStackEnd)),
785                    }
786                }
787                Terminal::OrD(ref _left, ref right) if node_state.n_evaluated == 1 => {
788                    match self.stack.pop() {
789                        Some(stack::Element::Satisfied) => {
790                            self.stack.push(stack::Element::Satisfied)
791                        }
792                        Some(stack::Element::Dissatisfied) => {
793                            self.push_evaluation_state(right, 0, 0)
794                        }
795                        Some(stack::Element::Push(_v)) => {
796                            return Some(Err(Error::UnexpectedStackElementPush))
797                        }
798                        None => return Some(Err(Error::UnexpectedStackEnd)),
799                    }
800                }
801                Terminal::AndOr(_, ref left, ref right) | Terminal::OrI(ref left, ref right) => {
802                    match self.stack.pop() {
803                        Some(stack::Element::Satisfied) => self.push_evaluation_state(left, 0, 0),
804                        Some(stack::Element::Dissatisfied) => {
805                            self.push_evaluation_state(right, 0, 0)
806                        }
807                        Some(stack::Element::Push(_v)) => {
808                            return Some(Err(Error::UnexpectedStackElementPush))
809                        }
810                        None => return Some(Err(Error::UnexpectedStackEnd)),
811                    }
812                }
813                Terminal::Thresh(ref _k, ref subs) if node_state.n_evaluated == 0 => {
814                    self.push_evaluation_state(node_state.node, 1, 0);
815                    self.push_evaluation_state(&subs[0], 0, 0);
816                }
817                Terminal::Thresh(k, ref subs) if node_state.n_evaluated == subs.len() => {
818                    match self.stack.pop() {
819                        Some(stack::Element::Dissatisfied) if node_state.n_satisfied == k => {
820                            self.stack.push(stack::Element::Satisfied)
821                        }
822                        Some(stack::Element::Satisfied) if node_state.n_satisfied == k - 1 => {
823                            self.stack.push(stack::Element::Satisfied)
824                        }
825                        Some(stack::Element::Satisfied) | Some(stack::Element::Dissatisfied) => {
826                            self.stack.push(stack::Element::Dissatisfied)
827                        }
828                        Some(stack::Element::Push(_v)) => {
829                            return Some(Err(Error::UnexpectedStackElementPush))
830                        }
831                        None => return Some(Err(Error::UnexpectedStackEnd)),
832                    }
833                }
834                Terminal::Thresh(ref _k, ref subs) if node_state.n_evaluated != 0 => {
835                    match self.stack.pop() {
836                        Some(stack::Element::Dissatisfied) => {
837                            self.push_evaluation_state(
838                                node_state.node,
839                                node_state.n_evaluated + 1,
840                                node_state.n_satisfied,
841                            );
842                            self.push_evaluation_state(&subs[node_state.n_evaluated], 0, 0);
843                        }
844                        Some(stack::Element::Satisfied) => {
845                            self.push_evaluation_state(
846                                node_state.node,
847                                node_state.n_evaluated + 1,
848                                node_state.n_satisfied + 1,
849                            );
850                            self.push_evaluation_state(&subs[node_state.n_evaluated], 0, 0);
851                        }
852                        Some(stack::Element::Push(_v)) => {
853                            return Some(Err(Error::UnexpectedStackElementPush))
854                        }
855                        None => return Some(Err(Error::UnexpectedStackEnd)),
856                    }
857                }
858                Terminal::MultiA(k, ref subs) => {
859                    if node_state.n_evaluated == subs.len() {
860                        if node_state.n_satisfied == k {
861                            self.stack.push(stack::Element::Satisfied);
862                        } else {
863                            self.stack.push(stack::Element::Dissatisfied);
864                        }
865                    } else {
866                        // evaluate each key with as a pk
867                        // note that evaluate_pk will error on non-empty incorrect sigs
868                        // push 1 on satisfied sigs and push 0 on empty sigs
869                        match self
870                            .stack
871                            .evaluate_pk(&mut self.verify_sig, &subs[node_state.n_evaluated])
872                        {
873                            Some(Ok(x)) => {
874                                self.push_evaluation_state(
875                                    node_state.node,
876                                    node_state.n_evaluated + 1,
877                                    node_state.n_satisfied + 1,
878                                );
879                                match self.stack.pop() {
880                                    Some(..) => return Some(Ok(x)),
881                                    None => return Some(Err(Error::UnexpectedStackEnd)),
882                                }
883                            }
884                            None => {
885                                self.push_evaluation_state(
886                                    node_state.node,
887                                    node_state.n_evaluated + 1,
888                                    node_state.n_satisfied,
889                                );
890                                match self.stack.pop() {
891                                    Some(..) => {} // not-satisfied, look for next key
892                                    None => return Some(Err(Error::UnexpectedStackEnd)),
893                                }
894                            }
895                            x => return x, //forward errors as is
896                        }
897                    }
898                }
899                Terminal::Multi(ref k, ref subs) if node_state.n_evaluated == 0 => {
900                    let len = self.stack.len();
901                    if len < k + 1 {
902                        return Some(Err(Error::InsufficientSignaturesMultiSig));
903                    } else {
904                        //Non-sat case. If the first sig is empty, others k elements must
905                        //be empty.
906                        match self.stack.last() {
907                            Some(&stack::Element::Dissatisfied) => {
908                                //Remove the extra zero from multi-sig check
909                                let sigs = self.stack.split_off(len - (k + 1));
910                                let nonsat = sigs
911                                    .iter()
912                                    .map(|sig| *sig == stack::Element::Dissatisfied)
913                                    .filter(|empty| *empty)
914                                    .count();
915                                if nonsat == *k + 1 {
916                                    self.stack.push(stack::Element::Dissatisfied);
917                                } else {
918                                    return Some(Err(Error::MissingExtraZeroMultiSig));
919                                }
920                            }
921                            None => return Some(Err(Error::UnexpectedStackEnd)),
922                            _ => {
923                                match self
924                                    .stack
925                                    .evaluate_multi(&mut self.verify_sig, &subs[subs.len() - 1])
926                                {
927                                    Some(Ok(x)) => {
928                                        self.push_evaluation_state(
929                                            node_state.node,
930                                            node_state.n_evaluated + 1,
931                                            node_state.n_satisfied + 1,
932                                        );
933                                        return Some(Ok(x));
934                                    }
935                                    None => self.push_evaluation_state(
936                                        node_state.node,
937                                        node_state.n_evaluated + 1,
938                                        node_state.n_satisfied,
939                                    ),
940                                    x => return x, //forward errors as is
941                                }
942                            }
943                        }
944                    }
945                }
946                Terminal::Multi(k, ref subs) => {
947                    if node_state.n_satisfied == k {
948                        //multi-sig bug: Pop extra 0
949                        if let Some(stack::Element::Dissatisfied) = self.stack.pop() {
950                            self.stack.push(stack::Element::Satisfied);
951                        } else {
952                            return Some(Err(Error::MissingExtraZeroMultiSig));
953                        }
954                    } else if node_state.n_evaluated == subs.len() {
955                        return Some(Err(Error::MultiSigEvaluationError));
956                    } else {
957                        match self.stack.evaluate_multi(
958                            &mut self.verify_sig,
959                            &subs[subs.len() - node_state.n_evaluated - 1],
960                        ) {
961                            Some(Ok(x)) => {
962                                self.push_evaluation_state(
963                                    node_state.node,
964                                    node_state.n_evaluated + 1,
965                                    node_state.n_satisfied + 1,
966                                );
967                                return Some(Ok(x));
968                            }
969                            None => self.push_evaluation_state(
970                                node_state.node,
971                                node_state.n_evaluated + 1,
972                                node_state.n_satisfied,
973                            ),
974                            x => return x, //forward errors as is
975                        }
976                    }
977                }
978                Terminal::TxTemplate(ref h) => {
979                    debug_assert_eq!(node_state.n_evaluated, 0);
980                    debug_assert_eq!(node_state.n_satisfied, 0);
981                    let res = self.stack.evaluate_txtemplate(&h, &self.txtemplate);
982                    if res.is_some() {
983                        return res;
984                    }
985                }
986                //All other match patterns should not be reached in any valid
987                //type checked Miniscript
988                _ => return Some(Err(Error::CouldNotEvaluate)),
989            };
990        }
991
992        //state empty implies that either the execution has terminated or we have a
993        //Pk based descriptor
994        if let Some(pk) = self.public_key {
995            if let Some(stack::Element::Push(sig)) = self.stack.pop() {
996                if let Ok(key_sig) = verify_sersig(&mut self.verify_sig, &pk, &sig) {
997                    //Signature check successful, set public_key to None to
998                    //terminate the next() function in the subsequent call
999                    self.public_key = None;
1000                    self.stack.push(stack::Element::Satisfied);
1001                    return Some(Ok(SatisfiedConstraint::PublicKey { key_sig }));
1002                } else {
1003                    return Some(Err(Error::PkEvaluationError(PkEvalErrInner::from(*pk))));
1004                }
1005            } else {
1006                return Some(Err(Error::UnexpectedStackEnd));
1007            }
1008        } else {
1009            //All the script has been executed.
1010            //Check that the stack must contain exactly 1 satisfied element
1011            if self.stack.pop() == Some(stack::Element::Satisfied) && self.stack.is_empty() {
1012                return None;
1013            } else {
1014                return Some(Err(Error::ScriptSatisfactionError));
1015            }
1016        }
1017    }
1018}
1019
1020/// Helper function to verify serialized signature
1021fn verify_sersig<'txin>(
1022    verify_sig: &mut Box<dyn FnMut(&KeySigPair) -> bool + 'txin>,
1023    pk: &BitcoinKey,
1024    sigser: &[u8],
1025) -> Result<KeySigPair, Error> {
1026    match pk {
1027        BitcoinKey::Fullkey(pk) => {
1028            let ecdsa_sig = bitcoin::EcdsaSig::from_slice(sigser)?;
1029            let key_sig_pair = KeySigPair::Ecdsa(*pk, ecdsa_sig);
1030            if verify_sig(&key_sig_pair) {
1031                Ok(key_sig_pair)
1032            } else {
1033                Err(Error::InvalidEcdsaSignature(*pk))
1034            }
1035        }
1036        BitcoinKey::XOnlyPublicKey(x_only_pk) => {
1037            let schnorr_sig = bitcoin::SchnorrSig::from_slice(sigser)?;
1038            let key_sig_pair = KeySigPair::Schnorr(*x_only_pk, schnorr_sig);
1039            if verify_sig(&key_sig_pair) {
1040                Ok(key_sig_pair)
1041            } else {
1042                Err(Error::InvalidSchnorrSignature(*x_only_pk))
1043            }
1044        }
1045    }
1046}
1047
1048#[cfg(test)]
1049mod tests {
1050
1051    use super::inner::ToNoChecks;
1052    use super::*;
1053    use bitcoin;
1054    use bitcoin::hashes::{hash160, ripemd160, sha256, sha256d, Hash};
1055    use bitcoin::secp256k1::{self, Secp256k1};
1056    use miniscript::context::NoChecks;
1057    use Miniscript;
1058    use MiniscriptKey;
1059    use ToPublicKey;
1060
1061    fn setup_keys_sigs(
1062        n: usize,
1063    ) -> (
1064        Vec<bitcoin::PublicKey>,
1065        Vec<Vec<u8>>,
1066        Vec<bitcoin::EcdsaSig>,
1067        secp256k1::Message,
1068        Secp256k1<secp256k1::All>,
1069        Vec<bitcoin::XOnlyPublicKey>,
1070        Vec<bitcoin::SchnorrSig>,
1071        Vec<Vec<u8>>,
1072    ) {
1073        let secp = secp256k1::Secp256k1::new();
1074        let msg = secp256k1::Message::from_slice(&b"Yoda: btc, I trust. HODL I must!"[..])
1075            .expect("32 bytes");
1076        let mut pks = vec![];
1077        let mut ecdsa_sigs = vec![];
1078        let mut der_sigs = vec![];
1079        let mut x_only_pks = vec![];
1080        let mut schnorr_sigs = vec![];
1081        let mut ser_schnorr_sigs = vec![];
1082
1083        let mut sk = [0; 32];
1084        for i in 1..n + 1 {
1085            sk[0] = i as u8;
1086            sk[1] = (i >> 8) as u8;
1087            sk[2] = (i >> 16) as u8;
1088
1089            let sk = secp256k1::SecretKey::from_slice(&sk[..]).expect("secret key");
1090            let pk = bitcoin::PublicKey {
1091                inner: secp256k1::PublicKey::from_secret_key(&secp, &sk),
1092                compressed: true,
1093            };
1094            let sig = secp.sign_ecdsa(&msg, &sk);
1095            ecdsa_sigs.push(bitcoin::EcdsaSig {
1096                sig,
1097                hash_ty: bitcoin::EcdsaSighashType::All,
1098            });
1099            let mut sigser = sig.serialize_der().to_vec();
1100            sigser.push(0x01); // sighash_all
1101            pks.push(pk);
1102            der_sigs.push(sigser);
1103
1104            let keypair = bitcoin::KeyPair::from_secret_key(&secp, sk);
1105            x_only_pks.push(bitcoin::XOnlyPublicKey::from_keypair(&keypair));
1106            let schnorr_sig = secp.sign_schnorr_with_aux_rand(&msg, &keypair, &[0u8; 32]);
1107            let schnorr_sig = bitcoin::SchnorrSig {
1108                sig: schnorr_sig,
1109                hash_ty: bitcoin::SchnorrSighashType::Default,
1110            };
1111            ser_schnorr_sigs.push(schnorr_sig.to_vec());
1112            schnorr_sigs.push(schnorr_sig);
1113        }
1114        (
1115            pks,
1116            der_sigs,
1117            ecdsa_sigs,
1118            msg,
1119            secp,
1120            x_only_pks,
1121            schnorr_sigs,
1122            ser_schnorr_sigs,
1123        )
1124    }
1125
1126    #[test]
1127    fn sat_constraints() {
1128        let (pks, der_sigs, ecdsa_sigs, sighash, secp, xpks, schnorr_sigs, ser_schnorr_sigs) =
1129            setup_keys_sigs(10);
1130        let secp_ref = &secp;
1131        let vfyfn_ = |pksig: &KeySigPair| match pksig {
1132            KeySigPair::Ecdsa(pk, ecdsa_sig) => secp_ref
1133                .verify_ecdsa(&sighash, &ecdsa_sig.sig, &pk.inner)
1134                .is_ok(),
1135            KeySigPair::Schnorr(xpk, schnorr_sig) => secp_ref
1136                .verify_schnorr(&schnorr_sig.sig, &sighash, xpk)
1137                .is_ok(),
1138        };
1139        let txtmpl_hash: &sha256::Hash = &sha256::Hash::from_inner([34u8; 32]);
1140        fn from_stack<'txin, 'elem>(
1141            verify_fn: Box<dyn FnMut(&KeySigPair) -> bool + 'elem>,
1142            txtmpl_hash: &'elem sha256::Hash,
1143            stack: Stack<'txin>,
1144            ms: &'elem Miniscript<BitcoinKey, NoChecks>,
1145        ) -> Iter<'elem, 'txin> {
1146            Iter {
1147                verify_sig: verify_fn,
1148                stack: stack,
1149                public_key: None,
1150                state: vec![NodeEvaluationState {
1151                    node: &ms,
1152                    n_evaluated: 0,
1153                    n_satisfied: 0,
1154                }],
1155                age: 1002,
1156                height: 1002,
1157                has_errored: false,
1158                // TODO: Replace with actual hash
1159                txtemplate: &txtmpl_hash,
1160            }
1161        }
1162
1163        let pk = no_checks_ms(&format!("c:pk_k({})", pks[0]));
1164        let pkh = no_checks_ms(&format!("c:pk_h({})", pks[1].to_pubkeyhash()));
1165        //Time
1166        let after = no_checks_ms(&format!("after({})", 1000));
1167        let older = no_checks_ms(&format!("older({})", 1000));
1168        //Hashes
1169        let preimage = [0xab as u8; 32];
1170        let sha256_hash = sha256::Hash::hash(&preimage);
1171        let sha256 = no_checks_ms(&format!("sha256({})", sha256_hash));
1172        let sha256d_hash_rev = sha256d::Hash::hash(&preimage);
1173        let mut sha256d_hash_bytes = sha256d_hash_rev.clone().into_inner();
1174        sha256d_hash_bytes.reverse();
1175        let sha256d_hash = sha256d::Hash::from_inner(sha256d_hash_bytes);
1176        let hash256 = no_checks_ms(&format!("hash256({})", sha256d_hash));
1177        let hash160_hash = hash160::Hash::hash(&preimage);
1178        let hash160 = no_checks_ms(&format!("hash160({})", hash160_hash));
1179        let ripemd160_hash = ripemd160::Hash::hash(&preimage);
1180        let ripemd160 = no_checks_ms(&format!("ripemd160({})", ripemd160_hash));
1181        let txtemplate = no_checks_ms(&format!("t:txtmpl({})", txtmpl_hash));
1182
1183        let stack = Stack::from(vec![stack::Element::Push(&der_sigs[0])]);
1184        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1185        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &pk);
1186        let pk_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1187        assert_eq!(
1188            pk_satisfied.unwrap(),
1189            vec![SatisfiedConstraint::PublicKey {
1190                key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1191            }]
1192        );
1193
1194        //Check Pk failure with wrong signature
1195        let stack = Stack::from(vec![stack::Element::Dissatisfied]);
1196        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1197        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &pk);
1198        let pk_err: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1199        assert!(pk_err.is_err());
1200
1201        //Check Pkh
1202        let pk_bytes = pks[1].to_public_key().to_bytes();
1203        let stack = Stack::from(vec![
1204            stack::Element::Push(&der_sigs[1]),
1205            stack::Element::Push(&pk_bytes),
1206        ]);
1207        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1208        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &pkh);
1209        let pkh_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1210        assert_eq!(
1211            pkh_satisfied.unwrap(),
1212            vec![SatisfiedConstraint::PublicKeyHash {
1213                keyhash: pks[1].to_pubkeyhash(),
1214                key_sig: KeySigPair::Ecdsa(pks[1], ecdsa_sigs[1])
1215            }]
1216        );
1217
1218        //Check After
1219        let stack = Stack::from(vec![]);
1220        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1221        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &after);
1222        let after_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1223        assert_eq!(
1224            after_satisfied.unwrap(),
1225            vec![SatisfiedConstraint::AbsoluteTimeLock { time: 1000 }]
1226        );
1227
1228        //Check Older
1229        let stack = Stack::from(vec![]);
1230        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1231        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &older);
1232        let older_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1233        assert_eq!(
1234            older_satisfied.unwrap(),
1235            vec![SatisfiedConstraint::RelativeTimeLock { time: 1000 }]
1236        );
1237
1238        //Check Sha256
1239        let stack = Stack::from(vec![stack::Element::Push(&preimage)]);
1240        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1241        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &sha256);
1242        let sah256_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1243        assert_eq!(
1244            sah256_satisfied.unwrap(),
1245            vec![SatisfiedConstraint::HashLock {
1246                hash: HashLockType::Sha256(sha256_hash),
1247                preimage: preimage,
1248            }]
1249        );
1250
1251        //Check Shad256
1252        let stack = Stack::from(vec![stack::Element::Push(&preimage)]);
1253        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1254        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &hash256);
1255        let sha256d_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1256        assert_eq!(
1257            sha256d_satisfied.unwrap(),
1258            vec![SatisfiedConstraint::HashLock {
1259                hash: HashLockType::Hash256(sha256d_hash_rev),
1260                preimage: preimage,
1261            }]
1262        );
1263
1264        //Check hash160
1265        let stack = Stack::from(vec![stack::Element::Push(&preimage)]);
1266        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1267        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &hash160);
1268        let hash160_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1269        assert_eq!(
1270            hash160_satisfied.unwrap(),
1271            vec![SatisfiedConstraint::HashLock {
1272                hash: HashLockType::Hash160(hash160_hash),
1273                preimage: preimage,
1274            }]
1275        );
1276
1277        //Check ripemd160
1278        let stack = Stack::from(vec![stack::Element::Push(&preimage)]);
1279        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1280        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &ripemd160);
1281        let ripemd160_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1282        assert_eq!(
1283            ripemd160_satisfied.unwrap(),
1284            vec![SatisfiedConstraint::HashLock {
1285                hash: HashLockType::Ripemd160(ripemd160_hash),
1286                preimage: preimage
1287            }]
1288        );
1289
1290        //Check txtemplate
1291        let stack = Stack::from(vec![]);
1292        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1293        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &txtemplate);
1294        let txtemplate_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1295        assert_eq!(
1296            txtemplate_satisfied.unwrap(),
1297            vec![SatisfiedConstraint::TxTemplate {
1298                hash: txtmpl_hash.clone()
1299            }]
1300        );
1301
1302        //Check AndV
1303        let pk_bytes = pks[1].to_public_key().to_bytes();
1304        let stack = Stack::from(vec![
1305            stack::Element::Push(&der_sigs[1]),
1306            stack::Element::Push(&pk_bytes),
1307            stack::Element::Push(&der_sigs[0]),
1308        ]);
1309        let elem = no_checks_ms(&format!(
1310            "and_v(vc:pk_k({}),c:pk_h({}))",
1311            pks[0],
1312            pks[1].to_pubkeyhash()
1313        ));
1314        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1315        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1316
1317        let and_v_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1318        assert_eq!(
1319            and_v_satisfied.unwrap(),
1320            vec![
1321                SatisfiedConstraint::PublicKey {
1322                    key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1323                },
1324                SatisfiedConstraint::PublicKeyHash {
1325                    keyhash: pks[1].to_pubkeyhash(),
1326                    key_sig: KeySigPair::Ecdsa(pks[1], ecdsa_sigs[1])
1327                }
1328            ]
1329        );
1330
1331        //Check AndB
1332        let stack = Stack::from(vec![
1333            stack::Element::Push(&preimage),
1334            stack::Element::Push(&der_sigs[0]),
1335        ]);
1336        let elem = no_checks_ms(&format!(
1337            "and_b(c:pk_k({}),sjtv:sha256({}))",
1338            pks[0], sha256_hash
1339        ));
1340        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1341        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1342
1343        let and_b_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1344        assert_eq!(
1345            and_b_satisfied.unwrap(),
1346            vec![
1347                SatisfiedConstraint::PublicKey {
1348                    key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1349                },
1350                SatisfiedConstraint::HashLock {
1351                    hash: HashLockType::Sha256(sha256_hash),
1352                    preimage: preimage,
1353                }
1354            ]
1355        );
1356
1357        //Check AndOr
1358        let stack = Stack::from(vec![
1359            stack::Element::Push(&preimage),
1360            stack::Element::Push(&der_sigs[0]),
1361        ]);
1362        let elem = no_checks_ms(&format!(
1363            "andor(c:pk_k({}),jtv:sha256({}),c:pk_h({}))",
1364            pks[0],
1365            sha256_hash,
1366            pks[1].to_pubkeyhash(),
1367        ));
1368        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1369        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1370
1371        let and_or_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1372        assert_eq!(
1373            and_or_satisfied.unwrap(),
1374            vec![
1375                SatisfiedConstraint::PublicKey {
1376                    key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1377                },
1378                SatisfiedConstraint::HashLock {
1379                    hash: HashLockType::Sha256(sha256_hash),
1380                    preimage: preimage,
1381                }
1382            ]
1383        );
1384
1385        //AndOr second satisfaction path
1386        let pk_bytes = pks[1].to_public_key().to_bytes();
1387        let stack = Stack::from(vec![
1388            stack::Element::Push(&der_sigs[1]),
1389            stack::Element::Push(&pk_bytes),
1390            stack::Element::Dissatisfied,
1391        ]);
1392        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1393        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1394
1395        let and_or_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1396        assert_eq!(
1397            and_or_satisfied.unwrap(),
1398            vec![SatisfiedConstraint::PublicKeyHash {
1399                keyhash: pks[1].to_pubkeyhash(),
1400                key_sig: KeySigPair::Ecdsa(pks[1], ecdsa_sigs[1])
1401            }]
1402        );
1403
1404        //Check OrB
1405        let stack = Stack::from(vec![
1406            stack::Element::Push(&preimage),
1407            stack::Element::Dissatisfied,
1408        ]);
1409        let elem = no_checks_ms(&format!(
1410            "or_b(c:pk_k({}),sjtv:sha256({}))",
1411            pks[0], sha256_hash
1412        ));
1413        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1414        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1415
1416        let or_b_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1417        assert_eq!(
1418            or_b_satisfied.unwrap(),
1419            vec![SatisfiedConstraint::HashLock {
1420                hash: HashLockType::Sha256(sha256_hash),
1421                preimage: preimage,
1422            }]
1423        );
1424
1425        //Check OrD
1426        let stack = Stack::from(vec![stack::Element::Push(&der_sigs[0])]);
1427        let elem = no_checks_ms(&format!(
1428            "or_d(c:pk_k({}),jtv:sha256({}))",
1429            pks[0], sha256_hash
1430        ));
1431        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1432        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1433
1434        let or_d_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1435        assert_eq!(
1436            or_d_satisfied.unwrap(),
1437            vec![SatisfiedConstraint::PublicKey {
1438                key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1439            }]
1440        );
1441
1442        //Check OrC
1443        let stack = Stack::from(vec![
1444            stack::Element::Push(&der_sigs[0]),
1445            stack::Element::Dissatisfied,
1446        ]);
1447        let elem = no_checks_ms(&format!(
1448            "t:or_c(jtv:sha256({}),vc:pk_k({}))",
1449            sha256_hash, pks[0]
1450        ));
1451        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1452        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1453
1454        let or_c_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1455        assert_eq!(
1456            or_c_satisfied.unwrap(),
1457            vec![SatisfiedConstraint::PublicKey {
1458                key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1459            }]
1460        );
1461
1462        //Check OrI
1463        let stack = Stack::from(vec![
1464            stack::Element::Push(&der_sigs[0]),
1465            stack::Element::Dissatisfied,
1466        ]);
1467        let elem = no_checks_ms(&format!(
1468            "or_i(jtv:sha256({}),c:pk_k({}))",
1469            sha256_hash, pks[0]
1470        ));
1471        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1472        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1473
1474        let or_i_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1475        assert_eq!(
1476            or_i_satisfied.unwrap(),
1477            vec![SatisfiedConstraint::PublicKey {
1478                key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1479            }]
1480        );
1481
1482        //Check Thres
1483        let stack = Stack::from(vec![
1484            stack::Element::Push(&der_sigs[0]),
1485            stack::Element::Push(&der_sigs[1]),
1486            stack::Element::Push(&der_sigs[2]),
1487            stack::Element::Dissatisfied,
1488            stack::Element::Dissatisfied,
1489        ]);
1490        let elem = no_checks_ms(&format!(
1491            "thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({}))",
1492            pks[4], pks[3], pks[2], pks[1], pks[0],
1493        ));
1494        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1495        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1496
1497        let thresh_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1498        assert_eq!(
1499            thresh_satisfied.unwrap(),
1500            vec![
1501                SatisfiedConstraint::PublicKey {
1502                    key_sig: KeySigPair::Ecdsa(pks[2], ecdsa_sigs[2])
1503                },
1504                SatisfiedConstraint::PublicKey {
1505                    key_sig: KeySigPair::Ecdsa(pks[1], ecdsa_sigs[1])
1506                },
1507                SatisfiedConstraint::PublicKey {
1508                    key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1509                }
1510            ]
1511        );
1512
1513        // Check multi
1514        let stack = Stack::from(vec![
1515            stack::Element::Dissatisfied,
1516            stack::Element::Push(&der_sigs[2]),
1517            stack::Element::Push(&der_sigs[1]),
1518            stack::Element::Push(&der_sigs[0]),
1519        ]);
1520        let elem = no_checks_ms(&format!(
1521            "multi(3,{},{},{},{},{})",
1522            pks[4], pks[3], pks[2], pks[1], pks[0],
1523        ));
1524        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1525        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1526
1527        let multi_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1528        assert_eq!(
1529            multi_satisfied.unwrap(),
1530            vec![
1531                SatisfiedConstraint::PublicKey {
1532                    key_sig: KeySigPair::Ecdsa(pks[0], ecdsa_sigs[0])
1533                },
1534                SatisfiedConstraint::PublicKey {
1535                    key_sig: KeySigPair::Ecdsa(pks[1], ecdsa_sigs[1])
1536                },
1537                SatisfiedConstraint::PublicKey {
1538                    key_sig: KeySigPair::Ecdsa(pks[2], ecdsa_sigs[2])
1539                },
1540            ]
1541        );
1542
1543        // Error multi: Invalid order of sigs
1544        let stack = Stack::from(vec![
1545            stack::Element::Dissatisfied,
1546            stack::Element::Push(&der_sigs[0]),
1547            stack::Element::Push(&der_sigs[2]),
1548            stack::Element::Push(&der_sigs[1]),
1549        ]);
1550        let elem = no_checks_ms(&format!(
1551            "multi(3,{},{},{},{},{})",
1552            pks[4], pks[3], pks[2], pks[1], pks[0],
1553        ));
1554        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1555        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1556
1557        let multi_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1558        assert!(multi_error.is_err());
1559
1560        // multi_a tests
1561        let stack = Stack::from(vec![
1562            stack::Element::Dissatisfied,
1563            stack::Element::Dissatisfied,
1564            stack::Element::Push(&ser_schnorr_sigs[2]),
1565            stack::Element::Push(&ser_schnorr_sigs[1]),
1566            stack::Element::Push(&ser_schnorr_sigs[0]),
1567        ]);
1568
1569        let elem = x_only_no_checks_ms(&format!(
1570            "multi_a(3,{},{},{},{},{})",
1571            xpks[0], xpks[1], xpks[2], xpks[3], xpks[4],
1572        ));
1573        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1574        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1575
1576        let multi_a_satisfied: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1577        assert_eq!(
1578            multi_a_satisfied.unwrap(),
1579            vec![
1580                SatisfiedConstraint::PublicKey {
1581                    key_sig: KeySigPair::Schnorr(xpks[0], schnorr_sigs[0])
1582                },
1583                SatisfiedConstraint::PublicKey {
1584                    key_sig: KeySigPair::Schnorr(xpks[1], schnorr_sigs[1])
1585                },
1586                SatisfiedConstraint::PublicKey {
1587                    key_sig: KeySigPair::Schnorr(xpks[2], schnorr_sigs[2])
1588                },
1589            ]
1590        );
1591
1592        // multi_a tests: wrong order of sigs
1593        let stack = Stack::from(vec![
1594            stack::Element::Dissatisfied,
1595            stack::Element::Push(&ser_schnorr_sigs[2]),
1596            stack::Element::Push(&ser_schnorr_sigs[1]),
1597            stack::Element::Push(&ser_schnorr_sigs[0]),
1598            stack::Element::Dissatisfied,
1599        ]);
1600
1601        let elem = x_only_no_checks_ms(&format!(
1602            "multi_a(3,{},{},{},{},{})",
1603            xpks[0], xpks[1], xpks[2], xpks[3], xpks[4],
1604        ));
1605        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1606        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack.clone(), &elem);
1607
1608        let multi_a_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1609        assert!(multi_a_error.is_err());
1610
1611        // multi_a wrong thresh: k = 2, but three sigs
1612        let elem = x_only_no_checks_ms(&format!(
1613            "multi_a(2,{},{},{},{},{})",
1614            xpks[0], xpks[1], xpks[2], xpks[3], xpks[4],
1615        ));
1616        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1617        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack.clone(), &elem);
1618
1619        let multi_a_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1620        assert!(multi_a_error.is_err());
1621
1622        // multi_a correct thresh, but small stack
1623        let elem = x_only_no_checks_ms(&format!(
1624            "multi_a(3,{},{},{},{},{},{})",
1625            xpks[0], xpks[1], xpks[2], xpks[3], xpks[4], xpks[5]
1626        ));
1627        let vfyfn = vfyfn_.clone(); // sigh rust 1.29...
1628        let constraints = from_stack(Box::new(vfyfn), txtmpl_hash, stack, &elem);
1629
1630        let multi_a_error: Result<Vec<SatisfiedConstraint>, Error> = constraints.collect();
1631        assert!(multi_a_error.is_err());
1632    }
1633
1634    // By design there is no support for parse a miniscript with BitcoinKey
1635    // because it does not implement FromStr
1636    fn no_checks_ms(ms: &str) -> Miniscript<BitcoinKey, NoChecks> {
1637        let elem: Miniscript<bitcoin::PublicKey, NoChecks> =
1638            Miniscript::from_str_insane(ms).unwrap();
1639        elem.to_no_checks_ms()
1640    }
1641
1642    fn x_only_no_checks_ms(ms: &str) -> Miniscript<BitcoinKey, NoChecks> {
1643        let elem: Miniscript<bitcoin::XOnlyPublicKey, NoChecks> =
1644            Miniscript::from_str_insane(ms).unwrap();
1645        elem.to_no_checks_ms()
1646    }
1647}