miniscript_qtum/interpreter/
mod.rs

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