elements_miniscript/miniscript/types/
mod.rs

1// Written in 2019 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! Miniscript Types
5//! Contains structures representing Miniscript types and utility functions
6//! Contains all the type checking rules for correctness and malleability
7//! Implemented as per rules on bitcoin.sipa.be/miniscript
8pub mod correctness;
9pub mod extra_props;
10pub mod malleability;
11
12use std::{error, fmt};
13
14use elements::{LockTime, Sequence};
15
16pub use self::correctness::{Base, Correctness, Input};
17pub use self::extra_props::ExtData;
18pub use self::malleability::{Dissat, Malleability};
19use super::ScriptContext;
20use crate::{Extension, MiniscriptKey, NoExt, Terminal};
21
22/// Detailed type of a typechecker error
23#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
24pub enum ErrorKind {
25    /// Relative or absolute timelock had an invalid time value (either 0, or >=0x80000000)
26    InvalidTime,
27    /// Passed a `z` argument to a `d` wrapper when `z` was expected
28    NonZeroDupIf,
29    /// Multisignature or threshold policy had a `k` value of 0
30    ZeroThreshold,
31    /// Multisignature or threshold policy has a `k` value in
32    /// excess of the number of subfragments
33    OverThreshold(usize, usize),
34    /// Attempted to construct a disjunction (or `andor`) for which
35    /// none of the child nodes were strong. This means that a 3rd
36    /// party could produce a satisfaction for any branch, meaning
37    /// that no matter which one an honest signer chooses, it is
38    /// possible to malleate the transaction.
39    NoStrongChild,
40    /// Many fragments (all disjunctions except `or_i` as well as
41    /// `andor` require their left child be dissatisfiable.
42    LeftNotDissatisfiable,
43    /// `or_b` requires its right child be dissatisfiable
44    RightNotDissatisfiable,
45    /// Tried to use the `s:` modifier on a fragment that takes more
46    /// than one input
47    SwapNonOne,
48    /// Tried to use the `j:` (`SIZE 0NOTEQUAL IF`) wrapper on something
49    /// that may be satisfied by a 0 input
50    NonZeroZero,
51    /// Many fragments require their left child to be a unit. This
52    /// was not the case.
53    LeftNotUnit,
54    /// Attempted to construct a wrapper, but the child had
55    /// an invalid type
56    ChildBase1(Base),
57    /// Attempted to construct a conjunction or disjunction, but
58    /// the fragments' children were of invalid types
59    ChildBase2(Base, Base),
60    /// Attempted to construct an `andor` but the fragments'
61    /// children were of invalid types
62    ChildBase3(Base, Base, Base),
63    /// The nth child of a threshold fragment had an invalid type (the
64    /// first must be `B` and the rest `W`s)
65    ThresholdBase(usize, Base),
66    /// The nth child of a threshold fragment did not have a unique
67    /// satisfaction
68    ThresholdDissat(usize),
69    /// The nth child of a threshold fragment was not a unit
70    ThresholdNonUnit(usize),
71    /// Insufficiently many children of a threshold fragment were strong
72    ThresholdNotStrong {
73        /// Threshold parameter
74        k: usize,
75        /// Number of children
76        n: usize,
77        /// Number of strong children
78        n_strong: usize,
79    },
80}
81
82/// Error type for typechecking
83#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
84pub struct Error<Pk: MiniscriptKey, Ctx: ScriptContext, Ext: Extension = NoExt> {
85    /// The fragment that failed typecheck
86    pub fragment: Terminal<Pk, Ctx, Ext>,
87    /// The reason that typechecking failed
88    pub error: ErrorKind,
89}
90
91impl<Pk, Ctx, Ext> fmt::Display for Error<Pk, Ctx, Ext>
92where
93    Pk: MiniscriptKey,
94    Ctx: ScriptContext,
95    Ext: Extension,
96{
97    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98        match self.error {
99            ErrorKind::InvalidTime => write!(
100                f,
101                "fragment «{}» represents a timelock which value is invalid (time must be in [1; 0x80000000])",
102                self.fragment,
103            ),
104            ErrorKind::NonZeroDupIf => write!(
105                f,
106                "fragment «{}» represents needs to be `z`, needs to consume zero elements from the stack",
107                self.fragment,
108            ),
109            ErrorKind::ZeroThreshold => write!(
110                f,
111                "fragment «{}» has a threshold value of 0",
112                self.fragment,
113            ),
114            ErrorKind::OverThreshold(k, n) => write!(
115                f,
116                "fragment «{}» is a {}-of-{} threshold, which does not
117                 make sense",
118                self.fragment, k, n,
119            ),
120            ErrorKind::NoStrongChild => write!(
121                f,
122                "fragment «{}» requires at least one strong child \
123                 (a 3rd party cannot create a witness without having \
124                 seen one before) to prevent malleability",
125                self.fragment,
126            ),
127            ErrorKind::LeftNotDissatisfiable => write!(
128                f,
129                "fragment «{}» requires its left child be dissatisfiable",
130                self.fragment,
131            ),
132            ErrorKind::RightNotDissatisfiable => write!(
133                f,
134                "fragment «{}» requires its right child be dissatisfiable",
135                self.fragment,
136            ),
137            ErrorKind::SwapNonOne => write!(
138                f,
139                "fragment «{}» attempts to use `SWAP` to prefix something
140                 which does not take exactly one input",
141                self.fragment,
142            ),
143            ErrorKind::NonZeroZero => write!(
144                f,
145                "fragment «{}» attempts to use use the `j:` wrapper around a
146                 fragment which might be satisfied by an input of size zero",
147                self.fragment,
148            ),
149            ErrorKind::LeftNotUnit => write!(
150                f,
151                "fragment «{}» requires its left child be a unit (outputs
152                 exactly 1 given a satisfying input)",
153                self.fragment,
154            ),
155            ErrorKind::ChildBase1(base) => write!(
156                f,
157                "fragment «{}» cannot wrap a fragment of type {:?}",
158                self.fragment, base,
159            ),
160            ErrorKind::ChildBase2(base1, base2) => write!(
161                f,
162                "fragment «{}» cannot accept children of types {:?} and {:?}",
163                self.fragment, base1, base2,
164            ),
165            ErrorKind::ChildBase3(base1, base2, base3) => write!(
166                f,
167                "fragment «{}» cannot accept children of types {:?}, {:?} and {:?}",
168                self.fragment, base1, base2, base3,
169            ),
170            ErrorKind::ThresholdBase(idx, base) => write!(
171                f,
172                "fragment «{}» sub-fragment {} has type {:?} rather than {:?}",
173                self.fragment,
174                idx,
175                base,
176                if idx == 0 { Base::B } else { Base::W },
177            ),
178            ErrorKind::ThresholdDissat(idx) => write!(
179                f,
180                "fragment «{}» sub-fragment {} can not be dissatisfied \
181                 and cannot be used in a threshold",
182                self.fragment, idx,
183            ),
184            ErrorKind::ThresholdNonUnit(idx) => write!(
185                f,
186                "fragment «{}» sub-fragment {} is not a unit (does not put \
187                 exactly 1 on the stack given a satisfying input)",
188                self.fragment, idx,
189            ),
190            ErrorKind::ThresholdNotStrong { k, n, n_strong } => write!(
191                f,
192                "fragment «{}» is a {}-of-{} threshold, and needs {} of \
193                 its children to be strong to prevent malleability; however \
194                 only {} children were strong.",
195                self.fragment,
196                k,
197                n,
198                n - k,
199                n_strong,
200            ),
201        }
202    }
203}
204
205impl<Pk: MiniscriptKey, Ctx: ScriptContext> error::Error for Error<Pk, Ctx> {
206    fn cause(&self) -> Option<&dyn error::Error> {
207        None
208    }
209}
210
211/// Structure representing the type of a Miniscript fragment, including all
212/// properties relevant to the main codebase
213#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
214pub struct Type {
215    /// Correctness/soundness properties
216    pub corr: Correctness,
217    /// Malleability properties
218    pub mall: Malleability,
219}
220
221impl Type {
222    /// Check whether the `self` is a subtype of `other` argument .
223    /// This checks whether the argument `other` has attributes which are present
224    /// in the given `Type`. This returns `true` on same arguments
225    /// `a.is_subtype(a)` is `true`.
226    pub fn is_subtype(&self, other: Self) -> bool {
227        self.corr.is_subtype(other.corr) && self.mall.is_subtype(other.mall)
228    }
229}
230/// Trait representing a type property, which defines how the property
231/// propagates from terminals to the root of a Miniscript
232pub trait Property: Sized {
233    /// Any extra sanity checks/assertions that should be applied after
234    /// typechecking
235    fn sanity_checks(&self) {
236        // no checks by default
237    }
238
239    /// Type property of the `True` fragment
240    fn from_true() -> Self;
241
242    /// Type property of the `False` fragment
243    fn from_false() -> Self;
244
245    /// Type property of the `PkK` fragment
246    fn from_pk_k<Ctx: ScriptContext>() -> Self;
247
248    /// Type property of the `PkH` fragment
249    fn from_pk_h<Ctx: ScriptContext>() -> Self;
250
251    /// Type property of a `Multi` fragment
252    fn from_multi(k: usize, n: usize) -> Self;
253
254    /// Type property of a `MultiA` fragment
255    fn from_multi_a(k: usize, n: usize) -> Self;
256
257    /// Type property of a hash fragment
258    fn from_hash() -> Self;
259
260    /// Type property of a `Sha256` hash. Default implementation simply
261    /// passes through to `from_hash`
262    fn from_sha256() -> Self {
263        Self::from_hash()
264    }
265
266    /// Type property of a `Hash256` hash. Default implementation simply
267    /// passes through to `from_hash`
268    fn from_hash256() -> Self {
269        Self::from_hash()
270    }
271
272    /// Type property of a `Ripemd160` hash. Default implementation simply
273    /// passes through to `from_hash`
274    fn from_ripemd160() -> Self {
275        Self::from_hash()
276    }
277
278    /// Type property of a `Hash160` hash. Default implementation simply
279    /// passes through to `from_hash`
280    fn from_hash160() -> Self {
281        Self::from_hash()
282    }
283
284    /// Type property of a timelock
285    fn from_time(t: u32) -> Self;
286
287    /// Type property of an absolute timelock. Default implementation simply
288    /// passes through to `from_time`
289    fn from_after(t: LockTime) -> Self {
290        Self::from_time(t.to_consensus_u32())
291    }
292
293    /// Type property of a relative timelock. Default implementation simply
294    /// passes through to `from_time`
295    fn from_older(t: Sequence) -> Self {
296        Self::from_time(t.to_consensus_u32())
297    }
298
299    /// Cast using the `Alt` wrapper
300    fn cast_alt(self) -> Result<Self, ErrorKind>;
301
302    /// Cast using the `Swap` wrapper
303    fn cast_swap(self) -> Result<Self, ErrorKind>;
304
305    /// Cast using the `Check` wrapper
306    fn cast_check(self) -> Result<Self, ErrorKind>;
307
308    /// Cast using the `DupIf` wrapper
309    fn cast_dupif(self) -> Result<Self, ErrorKind>;
310
311    /// Cast using the `Verify` wrapper
312    fn cast_verify(self) -> Result<Self, ErrorKind>;
313
314    /// Cast using the `NonZero` wrapper
315    fn cast_nonzero(self) -> Result<Self, ErrorKind>;
316
317    /// Cast using the `ZeroNotEqual` wrapper
318    fn cast_zeronotequal(self) -> Result<Self, ErrorKind>;
319
320    /// Cast by changing `[X]` to `AndV([X], True)`
321    fn cast_true(self) -> Result<Self, ErrorKind> {
322        Self::and_v(self, Self::from_true())
323    }
324
325    /// Cast by changing `[X]` to `or_i([X], 0)` or `or_i(0, [X])`
326    fn cast_or_i_false(self) -> Result<Self, ErrorKind>;
327
328    /// Cast by changing `[X]` to `or_i([X], 0)`. Default implementation
329    /// simply passes through to `cast_or_i_false`
330    fn cast_unlikely(self) -> Result<Self, ErrorKind> {
331        Self::or_i(self, Self::from_false())
332    }
333
334    /// Cast by changing `[X]` to `or_i(0, [X])`. Default implementation
335    /// simply passes through to `cast_or_i_false`
336    fn cast_likely(self) -> Result<Self, ErrorKind> {
337        Self::or_i(Self::from_false(), self)
338    }
339
340    /// Computes the type of an `AndB` fragment
341    fn and_b(left: Self, right: Self) -> Result<Self, ErrorKind>;
342
343    /// Computes the type of an `AndV` fragment
344    fn and_v(left: Self, right: Self) -> Result<Self, ErrorKind>;
345
346    /// Computes the type of an `AndN` fragment
347    fn and_n(left: Self, right: Self) -> Result<Self, ErrorKind> {
348        Self::and_or(left, right, Self::from_false())
349    }
350
351    /// Computes the type of an `OrB` fragment
352    fn or_b(left: Self, right: Self) -> Result<Self, ErrorKind>;
353
354    /// Computes the type of an `OrD` fragment
355    fn or_d(left: Self, right: Self) -> Result<Self, ErrorKind>;
356
357    /// Computes the type of an `OrC` fragment
358    fn or_c(left: Self, right: Self) -> Result<Self, ErrorKind>;
359
360    /// Computes the type of an `OrI` fragment
361    fn or_i(left: Self, right: Self) -> Result<Self, ErrorKind>;
362
363    /// Computes the type of an `AndOr` fragment
364    fn and_or(a: Self, b: Self, c: Self) -> Result<Self, ErrorKind>;
365
366    /// Computes the type of an `Thresh` fragment
367    fn threshold<S>(k: usize, n: usize, sub_ck: S) -> Result<Self, ErrorKind>
368    where
369        S: FnMut(usize) -> Result<Self, ErrorKind>;
370
371    /// Compute the type of an extension
372    /// Extensions are always leaf, they should have a fixed type property and hence
373    /// should not fail
374    fn from_ext<E: Extension>(e: &E) -> Self;
375}
376
377impl Property for Type {
378    fn sanity_checks(&self) {
379        debug_assert!(!self.corr.dissatisfiable || self.mall.dissat != Dissat::None);
380        debug_assert!(self.mall.dissat == Dissat::None || self.corr.base != Base::V);
381        debug_assert!(self.mall.safe || self.corr.base != Base::K);
382        debug_assert!(self.mall.non_malleable || self.corr.input != Input::Zero);
383    }
384
385    fn from_true() -> Self {
386        Type {
387            corr: Property::from_true(),
388            mall: Property::from_true(),
389        }
390    }
391
392    fn from_false() -> Self {
393        Type {
394            corr: Property::from_false(),
395            mall: Property::from_false(),
396        }
397    }
398
399    fn from_pk_k<Ctx: ScriptContext>() -> Self {
400        Type {
401            corr: Property::from_pk_k::<Ctx>(),
402            mall: Property::from_pk_k::<Ctx>(),
403        }
404    }
405
406    fn from_pk_h<Ctx: ScriptContext>() -> Self {
407        Type {
408            corr: Property::from_pk_h::<Ctx>(),
409            mall: Property::from_pk_h::<Ctx>(),
410        }
411    }
412
413    fn from_multi(k: usize, n: usize) -> Self {
414        Type {
415            corr: Property::from_multi(k, n),
416            mall: Property::from_multi(k, n),
417        }
418    }
419
420    fn from_multi_a(k: usize, n: usize) -> Self {
421        Type {
422            corr: Property::from_multi_a(k, n),
423            mall: Property::from_multi_a(k, n),
424        }
425    }
426
427    fn from_hash() -> Self {
428        Type {
429            corr: Property::from_hash(),
430            mall: Property::from_hash(),
431        }
432    }
433
434    fn from_sha256() -> Self {
435        Type {
436            corr: Property::from_sha256(),
437            mall: Property::from_sha256(),
438        }
439    }
440
441    fn from_hash256() -> Self {
442        Type {
443            corr: Property::from_hash256(),
444            mall: Property::from_hash256(),
445        }
446    }
447
448    fn from_ripemd160() -> Self {
449        Type {
450            corr: Property::from_ripemd160(),
451            mall: Property::from_ripemd160(),
452        }
453    }
454
455    fn from_hash160() -> Self {
456        Type {
457            corr: Property::from_hash160(),
458            mall: Property::from_hash160(),
459        }
460    }
461
462    fn from_time(t: u32) -> Self {
463        Type {
464            corr: Property::from_time(t),
465            mall: Property::from_time(t),
466        }
467    }
468
469    fn from_after(t: LockTime) -> Self {
470        Type {
471            corr: Property::from_after(t),
472            mall: Property::from_after(t),
473        }
474    }
475
476    fn from_older(t: Sequence) -> Self {
477        Type {
478            corr: Property::from_older(t),
479            mall: Property::from_older(t),
480        }
481    }
482
483    fn cast_alt(self) -> Result<Self, ErrorKind> {
484        Ok(Type {
485            corr: Property::cast_alt(self.corr)?,
486            mall: Property::cast_alt(self.mall)?,
487        })
488    }
489
490    fn cast_swap(self) -> Result<Self, ErrorKind> {
491        Ok(Type {
492            corr: Property::cast_swap(self.corr)?,
493            mall: Property::cast_swap(self.mall)?,
494        })
495    }
496
497    fn cast_check(self) -> Result<Self, ErrorKind> {
498        Ok(Type {
499            corr: Property::cast_check(self.corr)?,
500            mall: Property::cast_check(self.mall)?,
501        })
502    }
503
504    fn cast_dupif(self) -> Result<Self, ErrorKind> {
505        Ok(Type {
506            corr: Property::cast_dupif(self.corr)?,
507            mall: Property::cast_dupif(self.mall)?,
508        })
509    }
510
511    fn cast_verify(self) -> Result<Self, ErrorKind> {
512        Ok(Type {
513            corr: Property::cast_verify(self.corr)?,
514            mall: Property::cast_verify(self.mall)?,
515        })
516    }
517
518    fn cast_nonzero(self) -> Result<Self, ErrorKind> {
519        Ok(Type {
520            corr: Property::cast_nonzero(self.corr)?,
521            mall: Property::cast_nonzero(self.mall)?,
522        })
523    }
524
525    fn cast_zeronotequal(self) -> Result<Self, ErrorKind> {
526        Ok(Type {
527            corr: Property::cast_zeronotequal(self.corr)?,
528            mall: Property::cast_zeronotequal(self.mall)?,
529        })
530    }
531
532    fn cast_true(self) -> Result<Self, ErrorKind> {
533        Ok(Type {
534            corr: Property::cast_true(self.corr)?,
535            mall: Property::cast_true(self.mall)?,
536        })
537    }
538
539    fn cast_or_i_false(self) -> Result<Self, ErrorKind> {
540        Ok(Type {
541            corr: Property::cast_or_i_false(self.corr)?,
542            mall: Property::cast_or_i_false(self.mall)?,
543        })
544    }
545
546    fn cast_unlikely(self) -> Result<Self, ErrorKind> {
547        Ok(Type {
548            corr: Property::cast_unlikely(self.corr)?,
549            mall: Property::cast_unlikely(self.mall)?,
550        })
551    }
552
553    fn cast_likely(self) -> Result<Self, ErrorKind> {
554        Ok(Type {
555            corr: Property::cast_likely(self.corr)?,
556            mall: Property::cast_likely(self.mall)?,
557        })
558    }
559
560    fn and_b(left: Self, right: Self) -> Result<Self, ErrorKind> {
561        Ok(Type {
562            corr: Property::and_b(left.corr, right.corr)?,
563            mall: Property::and_b(left.mall, right.mall)?,
564        })
565    }
566
567    fn and_v(left: Self, right: Self) -> Result<Self, ErrorKind> {
568        Ok(Type {
569            corr: Property::and_v(left.corr, right.corr)?,
570            mall: Property::and_v(left.mall, right.mall)?,
571        })
572    }
573
574    fn or_b(left: Self, right: Self) -> Result<Self, ErrorKind> {
575        Ok(Type {
576            corr: Property::or_b(left.corr, right.corr)?,
577            mall: Property::or_b(left.mall, right.mall)?,
578        })
579    }
580
581    fn or_d(left: Self, right: Self) -> Result<Self, ErrorKind> {
582        Ok(Type {
583            corr: Property::or_d(left.corr, right.corr)?,
584            mall: Property::or_d(left.mall, right.mall)?,
585        })
586    }
587
588    fn or_c(left: Self, right: Self) -> Result<Self, ErrorKind> {
589        Ok(Type {
590            corr: Property::or_c(left.corr, right.corr)?,
591            mall: Property::or_c(left.mall, right.mall)?,
592        })
593    }
594
595    fn or_i(left: Self, right: Self) -> Result<Self, ErrorKind> {
596        Ok(Type {
597            corr: Property::or_i(left.corr, right.corr)?,
598            mall: Property::or_i(left.mall, right.mall)?,
599        })
600    }
601
602    fn and_or(a: Self, b: Self, c: Self) -> Result<Self, ErrorKind> {
603        Ok(Type {
604            corr: Property::and_or(a.corr, b.corr, c.corr)?,
605            mall: Property::and_or(a.mall, b.mall, c.mall)?,
606        })
607    }
608
609    fn threshold<S>(k: usize, n: usize, mut sub_ck: S) -> Result<Self, ErrorKind>
610    where
611        S: FnMut(usize) -> Result<Self, ErrorKind>,
612    {
613        Ok(Type {
614            corr: Property::threshold(k, n, |n| Ok(sub_ck(n)?.corr))?,
615            mall: Property::threshold(k, n, |n| Ok(sub_ck(n)?.mall))?,
616        })
617    }
618
619    fn from_ext<E: Extension>(e: &E) -> Self {
620        Type {
621            corr: Property::from_ext(e),
622            mall: Property::from_ext(e),
623        }
624    }
625}
626impl Type {
627    /// Compute the type of a fragment assuming all the children of
628    /// Miniscript have been computed already.
629    pub fn type_check<Pk, Ctx, Ext>(
630        fragment: &Terminal<Pk, Ctx, Ext>,
631    ) -> Result<Self, Error<Pk, Ctx, Ext>>
632    where
633        Pk: MiniscriptKey,
634        Ctx: ScriptContext,
635        Ext: Extension,
636    {
637        let wrap_err = |result: Result<Self, ErrorKind>| {
638            result.map_err(|kind| Error {
639                fragment: fragment.clone(),
640                error: kind,
641            })
642        };
643
644        let ret = match *fragment {
645            Terminal::True => Ok(Self::from_true()),
646            Terminal::False => Ok(Self::from_false()),
647            Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
648            Terminal::PkH(..) | Terminal::RawPkH(..) => Ok(Self::from_pk_h::<Ctx>()),
649            Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
650                if k == 0 {
651                    return Err(Error {
652                        fragment: fragment.clone(),
653                        error: ErrorKind::ZeroThreshold,
654                    });
655                }
656                if k > pks.len() {
657                    return Err(Error {
658                        fragment: fragment.clone(),
659                        error: ErrorKind::OverThreshold(k, pks.len()),
660                    });
661                }
662                match *fragment {
663                    Terminal::Multi(..) => Ok(Self::from_multi(k, pks.len())),
664                    Terminal::MultiA(..) => Ok(Self::from_multi_a(k, pks.len())),
665                    _ => unreachable!(),
666                }
667            }
668            Terminal::After(t) => {
669                // Note that for CLTV this is a limitation not of Bitcoin but Miniscript. The
670                // number on the stack would be a 5 bytes signed integer but Miniscript's B type
671                // only consumes 4 bytes from the stack.
672                if t == LockTime::ZERO.into() {
673                    return Err(Error {
674                        fragment: fragment.clone(),
675                        error: ErrorKind::InvalidTime,
676                    });
677                }
678                Ok(Self::from_after(t.into()))
679            }
680            Terminal::Older(t) => {
681                if t == Sequence::ZERO || !t.is_relative_lock_time() {
682                    return Err(Error {
683                        fragment: fragment.clone(),
684                        error: ErrorKind::InvalidTime,
685                    });
686                }
687                Ok(Self::from_older(t))
688            }
689            Terminal::Sha256(..) => Ok(Self::from_sha256()),
690            Terminal::Hash256(..) => Ok(Self::from_hash256()),
691            Terminal::Ripemd160(..) => Ok(Self::from_ripemd160()),
692            Terminal::Hash160(..) => Ok(Self::from_hash160()),
693            Terminal::Alt(ref sub) => wrap_err(Self::cast_alt(sub.ty)),
694            Terminal::Swap(ref sub) => wrap_err(Self::cast_swap(sub.ty)),
695            Terminal::Check(ref sub) => wrap_err(Self::cast_check(sub.ty)),
696            Terminal::DupIf(ref sub) => wrap_err(Self::cast_dupif(sub.ty)),
697            Terminal::Verify(ref sub) => wrap_err(Self::cast_verify(sub.ty)),
698            Terminal::NonZero(ref sub) => wrap_err(Self::cast_nonzero(sub.ty)),
699            Terminal::ZeroNotEqual(ref sub) => wrap_err(Self::cast_zeronotequal(sub.ty)),
700            Terminal::AndB(ref l, ref r) => {
701                let ltype = l.ty;
702                let rtype = r.ty;
703                wrap_err(Self::and_b(ltype, rtype))
704            }
705            Terminal::AndV(ref l, ref r) => {
706                let ltype = l.ty;
707                let rtype = r.ty;
708                wrap_err(Self::and_v(ltype, rtype))
709            }
710            Terminal::OrB(ref l, ref r) => {
711                let ltype = l.ty;
712                let rtype = r.ty;
713                wrap_err(Self::or_b(ltype, rtype))
714            }
715            Terminal::OrD(ref l, ref r) => {
716                let ltype = l.ty;
717                let rtype = r.ty;
718                wrap_err(Self::or_d(ltype, rtype))
719            }
720            Terminal::OrC(ref l, ref r) => {
721                let ltype = l.ty;
722                let rtype = r.ty;
723                wrap_err(Self::or_c(ltype, rtype))
724            }
725            Terminal::OrI(ref l, ref r) => {
726                let ltype = l.ty;
727                let rtype = r.ty;
728                wrap_err(Self::or_i(ltype, rtype))
729            }
730            Terminal::AndOr(ref a, ref b, ref c) => {
731                let atype = a.ty;
732                let btype = b.ty;
733                let ctype = c.ty;
734                wrap_err(Self::and_or(atype, btype, ctype))
735            }
736            Terminal::Thresh(k, ref subs) => {
737                if k == 0 {
738                    return Err(Error {
739                        fragment: fragment.clone(),
740                        error: ErrorKind::ZeroThreshold,
741                    });
742                }
743                if k > subs.len() {
744                    return Err(Error {
745                        fragment: fragment.clone(),
746                        error: ErrorKind::OverThreshold(k, subs.len()),
747                    });
748                }
749
750                let res = Self::threshold(k, subs.len(), |n| Ok(subs[n].ty));
751
752                res.map_err(|kind| Error {
753                    fragment: fragment.clone(),
754                    error: kind,
755                })
756            }
757            Terminal::Ext(ref e) => Ok(Self::from_ext(e)),
758        };
759        if let Ok(ref ret) = ret {
760            ret.sanity_checks()
761        }
762        ret
763    }
764}