miniscript/
lib.rs

1// Written in 2019 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! Miniscript and Output Descriptors
5//!
6//! ## Bitcoin Script
7//!
8//! In Bitcoin, spending policies are defined and enforced by means of a
9//! stack-based programming language known as Bitcoin Script. While this
10//! language appears to be designed with tractable analysis in mind (e.g.
11//! there are no looping or jumping constructions), in practice this is
12//! extremely difficult. As a result, typical wallet software supports only
13//! a small set of script templates, cannot interoperate with other similar
14//! software, and each wallet contains independently written ad-hoc manually
15//! verified code to handle these templates. Users who require more complex
16//! spending policies, or who want to combine signing infrastructure which
17//! was not explicitly designed to work together, are simply out of luck.
18//!
19//! ## Miniscript
20//!
21//! Miniscript is an alternative to Bitcoin Script which eliminates these
22//! problems. It can be efficiently and simply encoded as Script to ensure
23//! that it works on the Bitcoin blockchain, but its design is very different.
24//! Essentially, a Miniscript is a monotone function (tree of ANDs, ORs and
25//! thresholds) of signature requirements, hash preimage requirements, and
26//! timelocks.
27//!
28//! A [full description of Miniscript is available here](https://bitcoin.sipa.be/miniscript).
29//!
30//! Miniscript also admits a more human-readable encoding.
31//!
32//! ## Output Descriptors
33//!
34//! While spending policies in Bitcoin are entirely defined by Script; there
35//! are multiple ways of embedding these Scripts in transaction outputs; for
36//! example, P2SH or Segwit v0. These different embeddings are expressed by
37//! *Output Descriptors*, [which are described here](https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md).
38//!
39//! # Examples
40//!
41//! ## Deriving an address from a descriptor
42//!
43//! ```rust
44//! use std::str::FromStr;
45//!
46//! let desc = miniscript::Descriptor::<bitcoin::PublicKey>::from_str("\
47//!     sh(wsh(or_d(\
48//!     c:pk_k(020e0338c96a8870479f2396c373cc7696ba124e8635d41b0ea581112b67817261),\
49//!     c:pk_k(0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352)\
50//!     )))\
51//!     ").unwrap();
52//!
53//! // Derive the P2SH address.
54//! assert_eq!(
55//!     desc.address(bitcoin::Network::Bitcoin).unwrap().to_string(),
56//!     "3CJxbQBfWAe1ZkKiGQNEYrioV73ZwvBWns"
57//! );
58//!
59//! // Check whether the descriptor is safe. This checks whether all spend paths are accessible in
60//! // the Bitcoin network. It may be possible that some of the spend paths require more than 100
61//! // elements in Wsh scripts or they contain a combination of timelock and heightlock.
62//! assert!(desc.sanity_check().is_ok());
63//!
64//! // Estimate the satisfaction cost.
65//! // scriptSig: OP_PUSH34 <OP_0 OP_32 <32-byte-hash>>
66//! // = (1 + 1 + 1 + 32) * 4 = 140 WU
67//! // redeemScript: varint <OP_33 <pk1> OP_CHECKSIG OP_IFDUP OP_NOTIF OP_33 <pk2> OP_CHECKSIG OP_ENDIF>
68//! // = 1 + (1 + 33 + 1 + 1 + 1 + 1 + 33 + 1 + 1) = 74 WU
69//! // stackItem[Sig]: varint <sig+sighash>
70//! // = 1 + 73 = 74 WU
71//! // Expected satisfaction weight: 140 + 74 + 74 = 288
72//! assert_eq!(desc.max_weight_to_satisfy().unwrap().to_wu(), 288);
73//! ```
74//!
75
76#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
77// Experimental features we need.
78#![cfg_attr(bench, feature(test))]
79// Coding conventions
80#![warn(missing_docs)]
81#![deny(unsafe_code)]
82// Clippy lints that we have disabled
83#![allow(clippy::iter_kv_map)] // https://github.com/rust-lang/rust-clippy/issues/11752
84#![allow(clippy::manual_range_contains)] // I hate this lint -asp
85#![allow(unexpected_cfgs)] // This one is just batshit.
86
87#[cfg(target_pointer_width = "16")]
88compile_error!(
89    "rust-miniscript currently only supports architectures with pointers wider than 16 bits"
90);
91
92pub use {bitcoin, hex};
93
94#[cfg(not(feature = "std"))]
95#[macro_use]
96extern crate alloc;
97
98#[cfg(any(feature = "std", test))]
99extern crate core;
100
101#[cfg(feature = "serde")]
102pub use serde;
103
104#[cfg(bench)]
105extern crate test;
106
107#[macro_use]
108mod macros;
109
110#[macro_use]
111mod pub_macros;
112
113#[cfg(bench)]
114mod benchmarks;
115mod blanket_traits;
116pub mod descriptor;
117mod error;
118pub mod expression;
119pub mod interpreter;
120pub mod iter;
121pub mod miniscript;
122pub mod plan;
123pub mod policy;
124mod primitives;
125pub mod psbt;
126
127#[cfg(test)]
128mod test_utils;
129mod util;
130
131use core::{fmt, hash, str};
132
133use bitcoin::hashes::{hash160, ripemd160, sha256, Hash};
134
135pub use crate::blanket_traits::FromStrKey;
136pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey};
137pub use crate::error::ParseError;
138pub use crate::expression::{ParseNumError, ParseThresholdError, ParseTreeError};
139pub use crate::interpreter::Interpreter;
140pub use crate::miniscript::analyzable::{AnalysisError, ExtParams};
141pub use crate::miniscript::context::{BareCtx, Legacy, ScriptContext, Segwitv0, SigType, Tap};
142pub use crate::miniscript::decode::Terminal;
143pub use crate::miniscript::satisfy::{Preimage32, Satisfier};
144pub use crate::miniscript::{hash256, Miniscript};
145use crate::prelude::*;
146pub use crate::primitives::absolute_locktime::{AbsLockTime, AbsLockTimeError};
147pub use crate::primitives::relative_locktime::{RelLockTime, RelLockTimeError};
148pub use crate::primitives::threshold::{Threshold, ThresholdError};
149
150/// Public key trait which can be converted to Hash type
151pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Hash {
152    /// Returns true if the pubkey is uncompressed. Defaults to `false`.
153    fn is_uncompressed(&self) -> bool { false }
154
155    /// Returns true if the pubkey is an x-only pubkey. Defaults to `false`.
156    // This is required to know what in DescriptorPublicKey to know whether the inner
157    // key in allowed in descriptor context
158    fn is_x_only_key(&self) -> bool { false }
159
160    /// Returns the number of different derivation paths in this key. Only >1 for keys
161    /// in BIP389 multipath descriptors.
162    fn num_der_paths(&self) -> usize { 0 }
163
164    /// The associated [`bitcoin::hashes::sha256::Hash`] for this [`MiniscriptKey`], used in the
165    /// sha256 fragment.
166    type Sha256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
167
168    /// The associated [`miniscript::hash256::Hash`] for this [`MiniscriptKey`], used in the
169    /// hash256 fragment.
170    type Hash256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
171
172    /// The associated [`bitcoin::hashes::ripemd160::Hash`] for this [`MiniscriptKey`] type, used
173    /// in the ripemd160 fragment.
174    type Ripemd160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
175
176    /// The associated [`bitcoin::hashes::hash160::Hash`] for this [`MiniscriptKey`] type, used in
177    /// the hash160 fragment.
178    type Hash160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
179}
180
181impl MiniscriptKey for bitcoin::secp256k1::PublicKey {
182    type Sha256 = sha256::Hash;
183    type Hash256 = hash256::Hash;
184    type Ripemd160 = ripemd160::Hash;
185    type Hash160 = hash160::Hash;
186}
187
188impl MiniscriptKey for bitcoin::PublicKey {
189    /// Returns the compressed-ness of the underlying secp256k1 key.
190    fn is_uncompressed(&self) -> bool { !self.compressed }
191
192    type Sha256 = sha256::Hash;
193    type Hash256 = hash256::Hash;
194    type Ripemd160 = ripemd160::Hash;
195    type Hash160 = hash160::Hash;
196}
197
198impl MiniscriptKey for bitcoin::secp256k1::XOnlyPublicKey {
199    type Sha256 = sha256::Hash;
200    type Hash256 = hash256::Hash;
201    type Ripemd160 = ripemd160::Hash;
202    type Hash160 = hash160::Hash;
203
204    fn is_x_only_key(&self) -> bool { true }
205}
206
207impl MiniscriptKey for String {
208    type Sha256 = String; // specify hashes as string
209    type Hash256 = String;
210    type Ripemd160 = String;
211    type Hash160 = String;
212}
213
214/// Trait describing public key types which can be converted to bitcoin pubkeys
215pub trait ToPublicKey: MiniscriptKey {
216    /// Converts an object to a public key
217    fn to_public_key(&self) -> bitcoin::PublicKey;
218
219    /// Convert an object to x-only pubkey
220    fn to_x_only_pubkey(&self) -> bitcoin::secp256k1::XOnlyPublicKey {
221        let pk = self.to_public_key();
222        bitcoin::secp256k1::XOnlyPublicKey::from(pk.inner)
223    }
224
225    /// Obtain the public key hash for this MiniscriptKey
226    /// Expects an argument to specify the signature type.
227    /// This would determine whether to serialize the key as 32 byte x-only pubkey
228    /// or regular public key when computing the hash160
229    fn to_pubkeyhash(&self, sig_type: SigType) -> hash160::Hash {
230        match sig_type {
231            SigType::Ecdsa => hash160::Hash::hash(&self.to_public_key().to_bytes()),
232            SigType::Schnorr => hash160::Hash::hash(&self.to_x_only_pubkey().serialize()),
233        }
234    }
235
236    /// Converts the generic associated [`MiniscriptKey::Sha256`] to [`sha256::Hash`]
237    fn to_sha256(hash: &<Self as MiniscriptKey>::Sha256) -> sha256::Hash;
238
239    /// Converts the generic associated [`MiniscriptKey::Hash256`] to [`hash256::Hash`]
240    fn to_hash256(hash: &<Self as MiniscriptKey>::Hash256) -> hash256::Hash;
241
242    /// Converts the generic associated [`MiniscriptKey::Ripemd160`] to [`ripemd160::Hash`]
243    fn to_ripemd160(hash: &<Self as MiniscriptKey>::Ripemd160) -> ripemd160::Hash;
244
245    /// Converts the generic associated [`MiniscriptKey::Hash160`] to [`hash160::Hash`]
246    fn to_hash160(hash: &<Self as MiniscriptKey>::Hash160) -> hash160::Hash;
247}
248
249impl ToPublicKey for bitcoin::PublicKey {
250    fn to_public_key(&self) -> bitcoin::PublicKey { *self }
251
252    fn to_sha256(hash: &sha256::Hash) -> sha256::Hash { *hash }
253
254    fn to_hash256(hash: &hash256::Hash) -> hash256::Hash { *hash }
255
256    fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash { *hash }
257
258    fn to_hash160(hash: &hash160::Hash) -> hash160::Hash { *hash }
259}
260
261impl ToPublicKey for bitcoin::secp256k1::PublicKey {
262    fn to_public_key(&self) -> bitcoin::PublicKey { bitcoin::PublicKey::new(*self) }
263
264    fn to_sha256(hash: &sha256::Hash) -> sha256::Hash { *hash }
265
266    fn to_hash256(hash: &hash256::Hash) -> hash256::Hash { *hash }
267
268    fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash { *hash }
269
270    fn to_hash160(hash: &hash160::Hash) -> hash160::Hash { *hash }
271}
272
273impl ToPublicKey for bitcoin::secp256k1::XOnlyPublicKey {
274    fn to_public_key(&self) -> bitcoin::PublicKey {
275        // This code should never be used.
276        // But is implemented for completeness
277        let mut data: Vec<u8> = vec![0x02];
278        data.extend(self.serialize().iter());
279        bitcoin::PublicKey::from_slice(&data)
280            .expect("Failed to construct 33 Publickey from 0x02 appended x-only key")
281    }
282
283    fn to_x_only_pubkey(&self) -> bitcoin::secp256k1::XOnlyPublicKey { *self }
284
285    fn to_sha256(hash: &sha256::Hash) -> sha256::Hash { *hash }
286
287    fn to_hash256(hash: &hash256::Hash) -> hash256::Hash { *hash }
288
289    fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash { *hash }
290
291    fn to_hash160(hash: &hash160::Hash) -> hash160::Hash { *hash }
292}
293
294/// Describes an object that can translate various keys and hashes from one key to the type
295/// associated with the other key. Used by the [`TranslatePk`] trait to do the actual translations.
296pub trait Translator<P: MiniscriptKey> {
297    /// The public key (and associated hash types that this translator converts to.
298    type TargetPk: MiniscriptKey;
299    /// An error that may occur during translation.
300    type Error;
301
302    /// Translates keys.
303    fn pk(&mut self, pk: &P) -> Result<Self::TargetPk, Self::Error>;
304
305    /// Translates SHA256 hashes.
306    fn sha256(
307        &mut self,
308        sha256: &P::Sha256,
309    ) -> Result<<Self::TargetPk as MiniscriptKey>::Sha256, Self::Error>;
310
311    /// Translates HASH256 hashes.
312    fn hash256(
313        &mut self,
314        hash256: &P::Hash256,
315    ) -> Result<<Self::TargetPk as MiniscriptKey>::Hash256, Self::Error>;
316
317    /// Translates RIPEMD160 hashes.
318    fn ripemd160(
319        &mut self,
320        ripemd160: &P::Ripemd160,
321    ) -> Result<<Self::TargetPk as MiniscriptKey>::Ripemd160, Self::Error>;
322
323    /// Translates HASH160 hashes.
324    fn hash160(
325        &mut self,
326        hash160: &P::Hash160,
327    ) -> Result<<Self::TargetPk as MiniscriptKey>::Hash160, Self::Error>;
328}
329
330/// An enum for representing translation errors
331pub enum TranslateErr<E> {
332    /// Error inside in the underlying key translation
333    TranslatorErr(E),
334    /// Error in the final translated structure. In some cases, the translated
335    /// structure might not be valid under the given context. For example, translating
336    /// from string keys to x-only keys in wsh descriptors.
337    OuterError(Error),
338}
339
340impl<E> TranslateErr<E> {
341    /// Enum used to capture errors from the [`Translator`] trait as well as
342    /// context errors from the translated structure.
343    /// The errors occurred in translation are captured in the [`TranslateErr::TranslatorErr`]
344    /// while the errors in the translated structure are captured in the [`TranslateErr::OuterError`]
345    ///
346    /// As of taproot upgrade: The following rules apply to the translation of descriptors:
347    /// - Legacy/Bare does not allow x_only keys
348    /// - SegwitV0 does not allow uncompressed keys and x_only keys
349    /// - Tapscript does not allow uncompressed keys
350    /// - Translating into multi-path descriptors should have same number of path
351    ///   for all the keys in the descriptor
352    ///
353    /// # Panics
354    ///
355    /// This function will panic if the Error is OutError.
356    pub fn expect_translator_err(self, msg: &str) -> E {
357        match self {
358            Self::TranslatorErr(v) => v,
359            Self::OuterError(ref e) => {
360                panic!("Unexpected Miniscript error when translating: {}\nMessage: {}", e, msg)
361            }
362        }
363    }
364}
365
366impl TranslateErr<core::convert::Infallible> {
367    /// Remove the impossible "translator error" case and return a context error.
368    ///
369    /// When the translator error type is [`core::convert::Infallible`], which is
370    /// impossible to construct, allows unwrapping the outer error without any
371    /// panic paths.
372    pub fn into_outer_err(self) -> Error {
373        match self {
374            Self::TranslatorErr(impossible) => match impossible {},
375            Self::OuterError(e) => e,
376        }
377    }
378}
379
380impl TranslateErr<Error> {
381    /// If we are doing a translation where our "outer error" is the generic
382    /// Miniscript error, eliminate the `TranslateErr` type which is just noise.
383    pub fn flatten(self) -> Error {
384        match self {
385            Self::TranslatorErr(e) => e,
386            Self::OuterError(e) => e,
387        }
388    }
389}
390
391impl<E> From<E> for TranslateErr<E> {
392    fn from(v: E) -> Self { Self::TranslatorErr(v) }
393}
394
395// Required for unwrap
396impl<E: fmt::Debug> fmt::Debug for TranslateErr<E> {
397    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
398        match self {
399            Self::TranslatorErr(e) => write!(f, "TranslatorErr({:?})", e),
400            Self::OuterError(e) => write!(f, "OuterError({:?})", e),
401        }
402    }
403}
404
405/// Converts a descriptor using abstract keys to one using specific keys. Uses translator `t` to do
406/// the actual translation function calls.
407#[deprecated(since = "TBD", note = "This trait no longer needs to be imported.")]
408pub trait TranslatePk<P, Q>
409where
410    P: MiniscriptKey,
411    Q: MiniscriptKey,
412{
413}
414
415/// Trait describing the ability to iterate over every key
416pub trait ForEachKey<Pk: MiniscriptKey> {
417    /// Run a predicate on every key in the descriptor, returning whether
418    /// the predicate returned true for every key
419    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
420    where
421        Pk: 'a;
422
423    /// Run a predicate on every key in the descriptor, returning whether
424    /// the predicate returned true for any key
425    fn for_any_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
426    where
427        Pk: 'a,
428    {
429        !self.for_each_key(|key| !pred(key))
430    }
431}
432
433/// Miniscript
434
435#[derive(Debug)]
436pub enum Error {
437    /// Error when lexing a bitcoin Script.
438    ScriptLexer(crate::miniscript::lex::Error),
439    /// rust-bitcoin address error
440    AddrError(bitcoin::address::ParseError),
441    /// rust-bitcoin p2sh address error
442    AddrP2shError(bitcoin::address::P2shError),
443    /// While parsing backward, hit beginning of script
444    UnexpectedStart,
445    /// Got something we were not expecting
446    Unexpected(String),
447    /// Encountered a wrapping character that we don't recognize
448    UnknownWrapper(char),
449    /// Parsed a miniscript and the result was not of type T
450    NonTopLevel(String),
451    /// Parsed a miniscript but there were more script opcodes after it
452    Trailing(String),
453    /// Could not satisfy a script (fragment) because of a missing signature
454    MissingSig(bitcoin::PublicKey),
455    /// General failure to satisfy
456    CouldNotSatisfy,
457    /// Typechecking failed
458    TypeCheck(String),
459    /// Forward-secp related errors
460    Secp(bitcoin::secp256k1::Error),
461    #[cfg(feature = "compiler")]
462    /// Compiler related errors
463    CompilerError(crate::policy::compiler::CompilerError),
464    /// Errors related to policy
465    ConcretePolicy(policy::concrete::PolicyError),
466    /// Errors related to lifting
467    LiftError(policy::LiftError),
468    /// Forward script context related errors
469    ContextError(miniscript::context::ScriptContextError),
470    /// Tried to construct a Taproot tree which was too deep.
471    TapTreeDepthError(crate::descriptor::TapTreeDepthError),
472    /// Recursion depth exceeded when parsing policy/miniscript from string
473    MaxRecursiveDepthExceeded,
474    /// Anything but c:pk(key) (P2PK), c:pk_h(key) (P2PKH), and thresh_m(k,...)
475    /// up to n=3 is invalid by standardness (bare)
476    NonStandardBareScript,
477    /// Analysis Error
478    AnalysisError(miniscript::analyzable::AnalysisError),
479    /// Miniscript is equivalent to false. No possible satisfaction
480    ImpossibleSatisfaction,
481    /// Bare descriptors don't have any addresses
482    BareDescriptorAddr,
483    /// PubKey invalid under current context
484    PubKeyCtxError(miniscript::decode::KeyError, &'static str),
485    /// No script code for Tr descriptors
486    TrNoScriptCode,
487    /// At least two BIP389 key expressions in the descriptor contain tuples of
488    /// derivation indexes of different lengths.
489    MultipathDescLenMismatch,
490    /// Invalid absolute locktime
491    AbsoluteLockTime(AbsLockTimeError),
492    /// Invalid absolute locktime
493    RelativeLockTime(RelLockTimeError),
494    /// Invalid threshold.
495    Threshold(ThresholdError),
496    /// Invalid threshold.
497    ParseThreshold(ParseThresholdError),
498    /// Invalid expression tree.
499    Parse(ParseError),
500}
501
502#[doc(hidden)] // will be removed when we remove Error
503impl From<ParseThresholdError> for Error {
504    fn from(e: ParseThresholdError) -> Self { Self::ParseThreshold(e) }
505}
506
507// https://github.com/sipa/miniscript/pull/5 for discussion on this number
508const MAX_RECURSION_DEPTH: u32 = 402;
509
510impl fmt::Display for Error {
511    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
512        match *self {
513            Error::ScriptLexer(ref e) => e.fmt(f),
514            Error::AddrError(ref e) => fmt::Display::fmt(e, f),
515            Error::AddrP2shError(ref e) => fmt::Display::fmt(e, f),
516            Error::UnexpectedStart => f.write_str("unexpected start of script"),
517            Error::Unexpected(ref s) => write!(f, "unexpected «{}»", s),
518            Error::UnknownWrapper(ch) => write!(f, "unknown wrapper «{}:»", ch),
519            Error::NonTopLevel(ref s) => write!(f, "non-T miniscript: {}", s),
520            Error::Trailing(ref s) => write!(f, "trailing tokens: {}", s),
521            Error::MissingSig(ref pk) => write!(f, "missing signature for key {:?}", pk),
522            Error::CouldNotSatisfy => f.write_str("could not satisfy"),
523            Error::TypeCheck(ref e) => write!(f, "typecheck: {}", e),
524            Error::Secp(ref e) => fmt::Display::fmt(e, f),
525            Error::ContextError(ref e) => fmt::Display::fmt(e, f),
526            Error::TapTreeDepthError(ref e) => fmt::Display::fmt(e, f),
527            #[cfg(feature = "compiler")]
528            Error::CompilerError(ref e) => fmt::Display::fmt(e, f),
529            Error::ConcretePolicy(ref e) => fmt::Display::fmt(e, f),
530            Error::LiftError(ref e) => fmt::Display::fmt(e, f),
531            Error::MaxRecursiveDepthExceeded => write!(
532                f,
533                "Recursive depth over {} not permitted",
534                MAX_RECURSION_DEPTH
535            ),
536            Error::NonStandardBareScript => write!(
537                f,
538                "Anything but c:pk(key) (P2PK), c:pk_h(key) (P2PKH), and thresh_m(k,...) \
539                up to n=3 is invalid by standardness (bare).
540                "
541            ),
542            Error::AnalysisError(ref e) => e.fmt(f),
543            Error::ImpossibleSatisfaction => write!(f, "Impossible to satisfy Miniscript"),
544            Error::BareDescriptorAddr => write!(f, "Bare descriptors don't have address"),
545            Error::PubKeyCtxError(ref pk, ref ctx) => {
546                write!(f, "Pubkey error: {} under {} scriptcontext", pk, ctx)
547            }
548            Error::TrNoScriptCode => write!(f, "No script code for Tr descriptors"),
549            Error::MultipathDescLenMismatch => write!(f, "At least two BIP389 key expressions in the descriptor contain tuples of derivation indexes of different lengths"),
550            Error::AbsoluteLockTime(ref e) => e.fmt(f),
551            Error::RelativeLockTime(ref e) => e.fmt(f),
552            Error::Threshold(ref e) => e.fmt(f),
553            Error::ParseThreshold(ref e) => e.fmt(f),
554            Error::Parse(ref e) => e.fmt(f),
555        }
556    }
557}
558
559#[cfg(feature = "std")]
560impl std::error::Error for Error {
561    fn cause(&self) -> Option<&dyn std::error::Error> {
562        use self::Error::*;
563
564        match self {
565            UnexpectedStart
566            | Unexpected(_)
567            | UnknownWrapper(_)
568            | NonTopLevel(_)
569            | Trailing(_)
570            | MissingSig(_)
571            | CouldNotSatisfy
572            | TypeCheck(_)
573            | MaxRecursiveDepthExceeded
574            | NonStandardBareScript
575            | ImpossibleSatisfaction
576            | BareDescriptorAddr
577            | TrNoScriptCode
578            | MultipathDescLenMismatch => None,
579            ScriptLexer(e) => Some(e),
580            AddrError(e) => Some(e),
581            AddrP2shError(e) => Some(e),
582            Secp(e) => Some(e),
583            #[cfg(feature = "compiler")]
584            CompilerError(e) => Some(e),
585            ConcretePolicy(e) => Some(e),
586            LiftError(e) => Some(e),
587            ContextError(e) => Some(e),
588            TapTreeDepthError(e) => Some(e),
589            AnalysisError(e) => Some(e),
590            PubKeyCtxError(e, _) => Some(e),
591            AbsoluteLockTime(e) => Some(e),
592            RelativeLockTime(e) => Some(e),
593            Threshold(e) => Some(e),
594            ParseThreshold(e) => Some(e),
595            Parse(e) => Some(e),
596        }
597    }
598}
599
600#[doc(hidden)]
601impl From<miniscript::lex::Error> for Error {
602    fn from(e: miniscript::lex::Error) -> Error { Error::ScriptLexer(e) }
603}
604
605#[doc(hidden)]
606impl From<miniscript::types::Error> for Error {
607    fn from(e: miniscript::types::Error) -> Error { Error::TypeCheck(e.to_string()) }
608}
609
610#[doc(hidden)]
611impl From<policy::LiftError> for Error {
612    fn from(e: policy::LiftError) -> Error { Error::LiftError(e) }
613}
614
615#[doc(hidden)]
616impl From<crate::descriptor::TapTreeDepthError> for Error {
617    fn from(e: crate::descriptor::TapTreeDepthError) -> Error { Error::TapTreeDepthError(e) }
618}
619
620#[doc(hidden)]
621impl From<miniscript::context::ScriptContextError> for Error {
622    fn from(e: miniscript::context::ScriptContextError) -> Error { Error::ContextError(e) }
623}
624
625#[doc(hidden)]
626impl From<miniscript::analyzable::AnalysisError> for Error {
627    fn from(e: miniscript::analyzable::AnalysisError) -> Error { Error::AnalysisError(e) }
628}
629
630#[doc(hidden)]
631impl From<bitcoin::secp256k1::Error> for Error {
632    fn from(e: bitcoin::secp256k1::Error) -> Error { Error::Secp(e) }
633}
634
635#[doc(hidden)]
636impl From<bitcoin::address::ParseError> for Error {
637    fn from(e: bitcoin::address::ParseError) -> Error { Error::AddrError(e) }
638}
639
640#[doc(hidden)]
641impl From<bitcoin::address::P2shError> for Error {
642    fn from(e: bitcoin::address::P2shError) -> Error { Error::AddrP2shError(e) }
643}
644
645#[doc(hidden)]
646#[cfg(feature = "compiler")]
647impl From<crate::policy::compiler::CompilerError> for Error {
648    fn from(e: crate::policy::compiler::CompilerError) -> Error { Error::CompilerError(e) }
649}
650
651/// The size of an encoding of a number in Script
652pub fn script_num_size(n: usize) -> usize {
653    match n {
654        n if n <= 0x10 => 1,      // OP_n
655        n if n < 0x80 => 2,       // OP_PUSH1 <n>
656        n if n < 0x8000 => 3,     // OP_PUSH2 <n>
657        n if n < 0x800000 => 4,   // OP_PUSH3 <n>
658        n if n < 0x80000000 => 5, // OP_PUSH4 <n>
659        _ => 6,                   // OP_PUSH5 <n>
660    }
661}
662
663/// Returns the size of the smallest push opcode used to push a given number of bytes onto the stack
664///
665/// For sizes ≤ 75, there are dedicated single-byte opcodes, so the push size is one. Otherwise,
666/// if the size can fit into 1, 2 or 4 bytes, we use the `PUSHDATA{1,2,4}` opcode respectively,
667/// followed by the actual size encoded in that many bytes.
668fn push_opcode_size(script_size: usize) -> usize {
669    if script_size < 76 {
670        1
671    } else if script_size < 0x100 {
672        2
673    } else if script_size < 0x10000 {
674        3
675    } else {
676        5
677    }
678}
679
680/// Helper function used by tests
681#[cfg(test)]
682fn hex_script(s: &str) -> bitcoin::ScriptBuf { bitcoin::ScriptBuf::from_hex(s).unwrap() }
683
684#[cfg(test)]
685mod tests {
686    use core::str::FromStr;
687
688    use super::*;
689
690    #[test]
691    fn regression_bitcoin_key_hash() {
692        use bitcoin::PublicKey;
693
694        // Uncompressed key.
695        let pk = PublicKey::from_str(
696            "042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133"
697        ).unwrap();
698
699        let want = hash160::Hash::from_str("ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a").unwrap();
700        let got = pk.to_pubkeyhash(SigType::Ecdsa);
701        assert_eq!(got, want)
702    }
703
704    #[test]
705    fn regression_secp256k1_key_hash() {
706        use bitcoin::secp256k1::PublicKey;
707
708        // Compressed key.
709        let pk = PublicKey::from_str(
710            "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
711        )
712        .unwrap();
713
714        let want = hash160::Hash::from_str("9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4").unwrap();
715        let got = pk.to_pubkeyhash(SigType::Ecdsa);
716        assert_eq!(got, want)
717    }
718
719    #[test]
720    fn regression_xonly_key_hash() {
721        use bitcoin::secp256k1::XOnlyPublicKey;
722
723        let pk = XOnlyPublicKey::from_str(
724            "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115",
725        )
726        .unwrap();
727
728        let want = hash160::Hash::from_str("eb8ac65f971ae688a94aeabf223506865e7e08f2").unwrap();
729        let got = pk.to_pubkeyhash(SigType::Schnorr);
730        assert_eq!(got, want)
731    }
732}
733
734#[allow(unused_imports)] // this is an internal prelude module; not all imports are used with every feature combination
735mod prelude {
736    // Mutex implementation from LDK
737    // https://github.com/lightningdevkit/rust-lightning/blob/9bdce47f0e0516e37c89c09f1975dfc06b5870b1/lightning-invoice/src/sync.rs
738    #[cfg(all(not(feature = "std"), not(test)))]
739    mod mutex {
740        use core::cell::{RefCell, RefMut};
741        use core::ops::{Deref, DerefMut};
742
743        pub type LockResult<Guard> = Result<Guard, ()>;
744
745        /// `Mutex` is not a real mutex as it cannot be used in a multi-threaded
746        /// context. `Mutex` is a dummy implementation of [`std::sync::Mutex`]
747        /// for `no_std` environments.
748        pub struct Mutex<T: ?Sized> {
749            inner: RefCell<T>,
750        }
751
752        #[must_use = "if unused the Mutex will immediately unlock"]
753        pub struct MutexGuard<'a, T: ?Sized + 'a> {
754            lock: RefMut<'a, T>,
755        }
756
757        impl<T: ?Sized> Deref for MutexGuard<'_, T> {
758            type Target = T;
759
760            fn deref(&self) -> &T { self.lock.deref() }
761        }
762
763        impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
764            fn deref_mut(&mut self) -> &mut T { self.lock.deref_mut() }
765        }
766
767        impl<T> Mutex<T> {
768            pub fn new(inner: T) -> Mutex<T> { Mutex { inner: RefCell::new(inner) } }
769
770            pub fn lock(&self) -> LockResult<MutexGuard<'_, T>> {
771                Ok(MutexGuard { lock: self.inner.borrow_mut() })
772            }
773        }
774    }
775
776    #[cfg(all(not(feature = "std"), not(test)))]
777    pub use alloc::{
778        borrow::{Borrow, Cow, ToOwned},
779        boxed::Box,
780        collections::{btree_map, vec_deque::VecDeque, BTreeMap, BTreeSet, BinaryHeap},
781        rc, slice,
782        string::{String, ToString},
783        sync,
784        vec::Vec,
785    };
786    #[cfg(any(feature = "std", test))]
787    pub use std::{
788        borrow::{Borrow, Cow, ToOwned},
789        boxed::Box,
790        collections::{
791            btree_map, vec_deque::VecDeque, BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet,
792        },
793        rc, slice,
794        string::{String, ToString},
795        sync,
796        sync::Mutex,
797        vec::Vec,
798    };
799
800    #[cfg(all(not(feature = "std"), not(test)))]
801    pub use self::mutex::Mutex;
802}