bells_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](http://bitcoin.sipa.be/miniscript/miniscript.html).
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::<bellscoin::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(bellscoin::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(), 288);
73//! ```
74//!
75
76#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
77#![cfg_attr(all(test, feature = "unstable"), feature(test))]
78// Coding conventions
79#![deny(unsafe_code)]
80#![deny(non_upper_case_globals)]
81#![deny(non_camel_case_types)]
82#![deny(non_snake_case)]
83#![deny(unused_mut)]
84#![deny(unused_imports)]
85#![deny(missing_docs)]
86
87#[cfg(target_pointer_width = "16")]
88compile_error!(
89    "rust-miniscript currently only supports architectures with pointers wider than 16 bits"
90);
91
92#[cfg(not(any(feature = "std", feature = "no-std")))]
93compile_error!("at least one of the `std` or `no-std` features must be enabled");
94
95pub use bellscoin;
96
97#[cfg(not(feature = "std"))]
98#[macro_use]
99extern crate alloc;
100
101#[cfg(not(feature = "std"))]
102extern crate hashbrown;
103
104#[cfg(any(feature = "std", test))]
105extern crate core;
106
107#[cfg(feature = "serde")]
108pub use actual_serde as serde;
109#[cfg(all(test, feature = "unstable"))]
110extern crate test;
111
112#[macro_use]
113mod macros;
114
115#[macro_use]
116mod pub_macros;
117
118use internals::hex::exts::DisplayHex;
119
120pub mod descriptor;
121pub mod expression;
122pub mod interpreter;
123pub mod miniscript;
124pub mod policy;
125pub mod psbt;
126
127#[cfg(test)]
128mod test_utils;
129mod util;
130
131use core::{cmp, fmt, hash, str};
132#[cfg(feature = "std")]
133use std::error;
134
135use bellscoin::blockdata::{opcodes, script};
136use bellscoin::hashes::{hash160, ripemd160, sha256, Hash};
137use bellscoin::locktime::absolute;
138
139pub use crate::descriptor::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey};
140pub use crate::interpreter::Interpreter;
141pub use crate::miniscript::analyzable::{AnalysisError, ExtParams};
142pub use crate::miniscript::context::{BareCtx, Legacy, ScriptContext, Segwitv0, SigType, Tap};
143pub use crate::miniscript::decode::Terminal;
144pub use crate::miniscript::satisfy::{Preimage32, Satisfier};
145pub use crate::miniscript::{hash256, Miniscript};
146use crate::prelude::*;
147
148///Public key trait which can be converted to Hash type
149pub trait MiniscriptKey: Clone + Eq + Ord + fmt::Debug + fmt::Display + hash::Hash {
150    /// Returns true if the pubkey is uncompressed. Defaults to `false`.
151    fn is_uncompressed(&self) -> bool {
152        false
153    }
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 {
159        false
160    }
161
162    /// Returns the number of different derivation paths in this key. Only >1 for keys
163    /// in BIP389 multipath descriptors.
164    fn num_der_paths(&self) -> usize;
165
166    /// The associated [`bellscoin::hashes::sha256::Hash`] for this [`MiniscriptKey`], used in the
167    /// sha256 fragment.
168    type Sha256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
169
170    /// The associated [`miniscript::hash256::Hash`] for this [`MiniscriptKey`], used in the
171    /// hash256 fragment.
172    type Hash256: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
173
174    /// The associated [`bellscoin::hashes::ripemd160::Hash`] for this [`MiniscriptKey`] type, used
175    /// in the ripemd160 fragment.
176    type Ripemd160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
177
178    /// The associated [`bellscoin::hashes::hash160::Hash`] for this [`MiniscriptKey`] type, used in
179    /// the hash160 fragment.
180    type Hash160: Clone + Eq + Ord + fmt::Display + fmt::Debug + hash::Hash;
181}
182
183impl MiniscriptKey for bellscoin::secp256k1::PublicKey {
184    type Sha256 = sha256::Hash;
185    type Hash256 = hash256::Hash;
186    type Ripemd160 = ripemd160::Hash;
187    type Hash160 = hash160::Hash;
188
189    fn num_der_paths(&self) -> usize {
190        0
191    }
192}
193
194impl MiniscriptKey for bellscoin::PublicKey {
195    /// Returns the compressed-ness of the underlying secp256k1 key.
196    fn is_uncompressed(&self) -> bool {
197        !self.compressed
198    }
199
200    fn num_der_paths(&self) -> usize {
201        0
202    }
203
204    type Sha256 = sha256::Hash;
205    type Hash256 = hash256::Hash;
206    type Ripemd160 = ripemd160::Hash;
207    type Hash160 = hash160::Hash;
208}
209
210impl MiniscriptKey for bellscoin::secp256k1::XOnlyPublicKey {
211    type Sha256 = sha256::Hash;
212    type Hash256 = hash256::Hash;
213    type Ripemd160 = ripemd160::Hash;
214    type Hash160 = hash160::Hash;
215
216    fn is_x_only_key(&self) -> bool {
217        true
218    }
219
220    fn num_der_paths(&self) -> usize {
221        0
222    }
223}
224
225impl MiniscriptKey for String {
226    type Sha256 = String; // specify hashes as string
227    type Hash256 = String;
228    type Ripemd160 = String;
229    type Hash160 = String;
230
231    fn num_der_paths(&self) -> usize {
232        0
233    }
234}
235
236/// Trait describing public key types which can be converted to bitcoin pubkeys
237pub trait ToPublicKey: MiniscriptKey {
238    /// Converts an object to a public key
239    fn to_public_key(&self) -> bellscoin::PublicKey;
240
241    /// Convert an object to x-only pubkey
242    fn to_x_only_pubkey(&self) -> bellscoin::secp256k1::XOnlyPublicKey {
243        let pk = self.to_public_key();
244        bellscoin::secp256k1::XOnlyPublicKey::from(pk.inner)
245    }
246
247    /// Obtain the public key hash for this MiniscriptKey
248    /// Expects an argument to specify the signature type.
249    /// This would determine whether to serialize the key as 32 byte x-only pubkey
250    /// or regular public key when computing the hash160
251    fn to_pubkeyhash(&self, sig_type: SigType) -> hash160::Hash {
252        match sig_type {
253            SigType::Ecdsa => hash160::Hash::hash(&self.to_public_key().to_bytes()),
254            SigType::Schnorr => hash160::Hash::hash(&self.to_x_only_pubkey().serialize()),
255        }
256    }
257
258    /// Converts the generic associated [`MiniscriptKey::Sha256`] to [`sha256::Hash`]
259    fn to_sha256(hash: &<Self as MiniscriptKey>::Sha256) -> sha256::Hash;
260
261    /// Converts the generic associated [`MiniscriptKey::Hash256`] to [`hash256::Hash`]
262    fn to_hash256(hash: &<Self as MiniscriptKey>::Hash256) -> hash256::Hash;
263
264    /// Converts the generic associated [`MiniscriptKey::Ripemd160`] to [`ripemd160::Hash`]
265    fn to_ripemd160(hash: &<Self as MiniscriptKey>::Ripemd160) -> ripemd160::Hash;
266
267    /// Converts the generic associated [`MiniscriptKey::Hash160`] to [`hash160::Hash`]
268    fn to_hash160(hash: &<Self as MiniscriptKey>::Hash160) -> hash160::Hash;
269}
270
271impl ToPublicKey for bellscoin::PublicKey {
272    fn to_public_key(&self) -> bellscoin::PublicKey {
273        *self
274    }
275
276    fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {
277        *hash
278    }
279
280    fn to_hash256(hash: &hash256::Hash) -> hash256::Hash {
281        *hash
282    }
283
284    fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash {
285        *hash
286    }
287
288    fn to_hash160(hash: &hash160::Hash) -> hash160::Hash {
289        *hash
290    }
291}
292
293impl ToPublicKey for bellscoin::secp256k1::PublicKey {
294    fn to_public_key(&self) -> bellscoin::PublicKey {
295        bellscoin::PublicKey::new(*self)
296    }
297
298    fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {
299        *hash
300    }
301
302    fn to_hash256(hash: &hash256::Hash) -> hash256::Hash {
303        *hash
304    }
305
306    fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash {
307        *hash
308    }
309
310    fn to_hash160(hash: &hash160::Hash) -> hash160::Hash {
311        *hash
312    }
313}
314
315impl ToPublicKey for bellscoin::secp256k1::XOnlyPublicKey {
316    fn to_public_key(&self) -> bellscoin::PublicKey {
317        // This code should never be used.
318        // But is implemented for completeness
319        let mut data: Vec<u8> = vec![0x02];
320        data.extend(self.serialize().iter());
321        bellscoin::PublicKey::from_slice(&data)
322            .expect("Failed to construct 33 Publickey from 0x02 appended x-only key")
323    }
324
325    fn to_x_only_pubkey(&self) -> bellscoin::secp256k1::XOnlyPublicKey {
326        *self
327    }
328
329    fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {
330        *hash
331    }
332
333    fn to_hash256(hash: &hash256::Hash) -> hash256::Hash {
334        *hash
335    }
336
337    fn to_ripemd160(hash: &ripemd160::Hash) -> ripemd160::Hash {
338        *hash
339    }
340
341    fn to_hash160(hash: &hash160::Hash) -> hash160::Hash {
342        *hash
343    }
344}
345
346/// Describes an object that can translate various keys and hashes from one key to the type
347/// associated with the other key. Used by the [`TranslatePk`] trait to do the actual translations.
348pub trait Translator<P, Q, E>
349where
350    P: MiniscriptKey,
351    Q: MiniscriptKey,
352{
353    /// Translates public keys P -> Q.
354    fn pk(&mut self, pk: &P) -> Result<Q, E>;
355
356    /// Provides the translation from P::Sha256 -> Q::Sha256
357    fn sha256(&mut self, sha256: &P::Sha256) -> Result<Q::Sha256, E>;
358
359    /// Provides the translation from P::Hash256 -> Q::Hash256
360    fn hash256(&mut self, hash256: &P::Hash256) -> Result<Q::Hash256, E>;
361
362    /// Translates ripemd160 hashes from P::Ripemd160 -> Q::Ripemd160
363    fn ripemd160(&mut self, ripemd160: &P::Ripemd160) -> Result<Q::Ripemd160, E>;
364
365    /// Translates hash160 hashes from P::Hash160 -> Q::Hash160
366    fn hash160(&mut self, hash160: &P::Hash160) -> Result<Q::Hash160, E>;
367}
368
369/// An enum for representing translation errors
370pub enum TranslateErr<E> {
371    /// Error inside in the underlying key translation
372    TranslatorErr(E),
373    /// Error in the final translated structure. In some cases, the translated
374    /// structure might not be valid under the given context. For example, translating
375    /// from string keys to x-only keys in wsh descriptors.
376    OuterError(Error),
377}
378
379impl<E> TranslateErr<E> {
380    /// Enum used to capture errors from the [`Translator`] trait as well as
381    /// context errors from the translated structure.
382    /// The errors occurred in translation are captured in the [`TranslateErr::TranslatorErr`]
383    /// while the errors in the translated structure are captured in the [`TranslateErr::OuterError`]
384    ///
385    /// As of taproot upgrade: The following rules apply to the translation of descriptors:
386    /// - Legacy/Bare does not allow x_only keys
387    /// - SegwitV0 does not allow uncompressed keys and x_only keys
388    /// - Tapscript does not allow uncompressed keys
389    /// - Translating into multi-path descriptors should have same number of path
390    /// for all the keys in the descriptor
391    ///
392    /// # Panics
393    ///
394    /// This function will panic if the Error is OutError.
395    pub fn expect_translator_err(self, msg: &str) -> E {
396        if let Self::TranslatorErr(v) = self {
397            v
398        } else {
399            panic!("{}", msg)
400        }
401    }
402}
403
404impl<E> From<E> for TranslateErr<E> {
405    fn from(v: E) -> Self {
406        Self::TranslatorErr(v)
407    }
408}
409
410// Required for unwrap
411impl<E: fmt::Debug> fmt::Debug for TranslateErr<E> {
412    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
413        match self {
414            Self::TranslatorErr(e) => write!(f, "TranslatorErr({:?})", e),
415            Self::OuterError(e) => write!(f, "OuterError({:?})", e),
416        }
417    }
418}
419
420/// Converts a descriptor using abstract keys to one using specific keys. Uses translator `t` to do
421/// the actual translation function calls.
422pub trait TranslatePk<P, Q>
423where
424    P: MiniscriptKey,
425    Q: MiniscriptKey,
426{
427    /// The associated output type. This must be `Self<Q>`.
428    type Output;
429
430    /// Translates a struct from one generic to another where the translations
431    /// for Pk are provided by the given [`Translator`].
432    fn translate_pk<T, E>(&self, translator: &mut T) -> Result<Self::Output, TranslateErr<E>>
433    where
434        T: Translator<P, Q, E>;
435}
436
437/// Either a key or keyhash, but both contain Pk
438// pub struct ForEach<'a, Pk: MiniscriptKey>(&'a Pk);
439
440// impl<'a, Pk: MiniscriptKey<Hash = Pk>> ForEach<'a, Pk> {
441//     /// Convenience method to avoid distinguishing between keys and hashes when these are the same type
442//     pub fn as_key(&self) -> &'a Pk {
443//         self.0
444//     }
445// }
446
447/// Trait describing the ability to iterate over every key
448pub trait ForEachKey<Pk: MiniscriptKey> {
449    /// Run a predicate on every key in the descriptor, returning whether
450    /// the predicate returned true for every key
451    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
452    where
453        Pk: 'a;
454
455    /// Run a predicate on every key in the descriptor, returning whether
456    /// the predicate returned true for any key
457    fn for_any_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
458    where
459        Pk: 'a,
460    {
461        !self.for_each_key(|key| !pred(key))
462    }
463}
464
465/// Miniscript
466
467#[derive(Debug, PartialEq)]
468pub enum Error {
469    /// Opcode appeared which is not part of the script subset
470    InvalidOpcode(opcodes::All),
471    /// Some opcode occurred followed by `OP_VERIFY` when it had
472    /// a `VERIFY` version that should have been used instead
473    NonMinimalVerify(String),
474    /// Push was illegal in some context
475    InvalidPush(Vec<u8>),
476    /// rust-bitcoin script error
477    Script(script::Error),
478    /// rust-bitcoin address error
479    AddrError(bellscoin::address::Error),
480    /// A `CHECKMULTISIG` opcode was preceded by a number > 20
481    CmsTooManyKeys(u32),
482    /// A tapscript multi_a cannot support more than MAX_BLOCK_WEIGHT/32 keys
483    MultiATooManyKeys(u32),
484    /// Encountered unprintable character in descriptor
485    Unprintable(u8),
486    /// expected character while parsing descriptor; didn't find one
487    ExpectedChar(char),
488    /// While parsing backward, hit beginning of script
489    UnexpectedStart,
490    /// Got something we were not expecting
491    Unexpected(String),
492    /// Name of a fragment contained `:` multiple times
493    MultiColon(String),
494    /// Name of a fragment contained `@` multiple times
495    MultiAt(String),
496    /// Name of a fragment contained `@` but we were not parsing an OR
497    AtOutsideOr(String),
498    /// Encountered a `l:0` which is syntactically equal to `u:0` except stupid
499    LikelyFalse,
500    /// Encountered a wrapping character that we don't recognize
501    UnknownWrapper(char),
502    /// Parsed a miniscript and the result was not of type T
503    NonTopLevel(String),
504    /// Parsed a miniscript but there were more script opcodes after it
505    Trailing(String),
506    /// Failed to parse a push as a public key
507    BadPubkey(bellscoin::key::Error),
508    /// Could not satisfy a script (fragment) because of a missing hash preimage
509    MissingHash(sha256::Hash),
510    /// Could not satisfy a script (fragment) because of a missing signature
511    MissingSig(bellscoin::PublicKey),
512    /// Could not satisfy, relative locktime not met
513    RelativeLocktimeNotMet(u32),
514    /// Could not satisfy, absolute locktime not met
515    AbsoluteLocktimeNotMet(u32),
516    /// General failure to satisfy
517    CouldNotSatisfy,
518    /// Typechecking failed
519    TypeCheck(String),
520    /// General error in creating descriptor
521    BadDescriptor(String),
522    /// Forward-secp related errors
523    Secp(bellscoin::secp256k1::Error),
524    #[cfg(feature = "compiler")]
525    /// Compiler related errors
526    CompilerError(crate::policy::compiler::CompilerError),
527    /// Errors related to policy
528    PolicyError(policy::concrete::PolicyError),
529    /// Errors related to lifting
530    LiftError(policy::LiftError),
531    /// Forward script context related errors
532    ContextError(miniscript::context::ScriptContextError),
533    /// Recursion depth exceeded when parsing policy/miniscript from string
534    MaxRecursiveDepthExceeded,
535    /// Script size too large
536    ScriptSizeTooLarge,
537    /// Anything but c:pk(key) (P2PK), c:pk_h(key) (P2PKH), and thresh_m(k,...)
538    /// up to n=3 is invalid by standardness (bare)
539    NonStandardBareScript,
540    /// Analysis Error
541    AnalysisError(miniscript::analyzable::AnalysisError),
542    /// Miniscript is equivalent to false. No possible satisfaction
543    ImpossibleSatisfaction,
544    /// Bare descriptors don't have any addresses
545    BareDescriptorAddr,
546    /// PubKey invalid under current context
547    PubKeyCtxError(miniscript::decode::KeyParseError, &'static str),
548    /// Attempted to call function that requires PreComputed taproot info
549    TaprootSpendInfoUnavialable,
550    /// No script code for Tr descriptors
551    TrNoScriptCode,
552    /// No explicit script for Tr descriptors
553    TrNoExplicitScript,
554    /// At least two BIP389 key expressions in the descriptor contain tuples of
555    /// derivation indexes of different lengths.
556    MultipathDescLenMismatch,
557}
558
559// https://github.com/sipa/miniscript/pull/5 for discussion on this number
560const MAX_RECURSION_DEPTH: u32 = 402;
561// https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
562const MAX_SCRIPT_SIZE: u32 = 10000;
563
564impl fmt::Display for Error {
565    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
566        match *self {
567            Error::InvalidOpcode(op) => write!(f, "invalid opcode {}", op),
568            Error::NonMinimalVerify(ref tok) => write!(f, "{} VERIFY", tok),
569            Error::InvalidPush(ref push) => {
570                write!(f, "invalid push {:x}", push.as_hex())
571            },
572            Error::Script(ref e) => fmt::Display::fmt(e, f),
573            Error::AddrError(ref e) => fmt::Display::fmt(e, f),
574            Error::CmsTooManyKeys(n) => write!(f, "checkmultisig with {} keys", n),
575            Error::Unprintable(x) => write!(f, "unprintable character 0x{:02x}", x),
576            Error::ExpectedChar(c) => write!(f, "expected {}", c),
577            Error::UnexpectedStart => f.write_str("unexpected start of script"),
578            Error::Unexpected(ref s) => write!(f, "unexpected «{}»", s),
579            Error::MultiColon(ref s) => write!(f, "«{}» has multiple instances of «:»", s),
580            Error::MultiAt(ref s) => write!(f, "«{}» has multiple instances of «@»", s),
581            Error::AtOutsideOr(ref s) => write!(f, "«{}» contains «@» in non-or() context", s),
582            Error::LikelyFalse => write!(f, "0 is not very likely (use «u:0»)"),
583            Error::UnknownWrapper(ch) => write!(f, "unknown wrapper «{}:»", ch),
584            Error::NonTopLevel(ref s) => write!(f, "non-T miniscript: {}", s),
585            Error::Trailing(ref s) => write!(f, "trailing tokens: {}", s),
586            Error::MissingHash(ref h) => write!(f, "missing preimage of hash {}", h),
587            Error::MissingSig(ref pk) => write!(f, "missing signature for key {:?}", pk),
588            Error::RelativeLocktimeNotMet(n) => {
589                write!(f, "required relative locktime CSV of {} blocks, not met", n)
590            }
591            Error::AbsoluteLocktimeNotMet(n) => write!(
592                f,
593                "required absolute locktime CLTV of {} blocks, not met",
594                n
595            ),
596            Error::CouldNotSatisfy => f.write_str("could not satisfy"),
597            Error::BadPubkey(ref e) => fmt::Display::fmt(e, f),
598            Error::TypeCheck(ref e) => write!(f, "typecheck: {}", e),
599            Error::BadDescriptor(ref e) => write!(f, "Invalid descriptor: {}", e),
600            Error::Secp(ref e) => fmt::Display::fmt(e, f),
601            Error::ContextError(ref e) => fmt::Display::fmt(e, f),
602            #[cfg(feature = "compiler")]
603            Error::CompilerError(ref e) => fmt::Display::fmt(e, f),
604            Error::PolicyError(ref e) => fmt::Display::fmt(e, f),
605            Error::LiftError(ref e) => fmt::Display::fmt(e, f),
606            Error::MaxRecursiveDepthExceeded => write!(
607                f,
608                "Recursive depth over {} not permitted",
609                MAX_RECURSION_DEPTH
610            ),
611            Error::ScriptSizeTooLarge => write!(
612                f,
613                "Standardness rules imply bitcoin than {} bytes",
614                MAX_SCRIPT_SIZE
615            ),
616            Error::NonStandardBareScript => write!(
617                f,
618                "Anything but c:pk(key) (P2PK), c:pk_h(key) (P2PKH), and thresh_m(k,...) \
619                up to n=3 is invalid by standardness (bare).
620                "
621            ),
622            Error::AnalysisError(ref e) => e.fmt(f),
623            Error::ImpossibleSatisfaction => write!(f, "Impossible to satisfy Miniscript"),
624            Error::BareDescriptorAddr => write!(f, "Bare descriptors don't have address"),
625            Error::PubKeyCtxError(ref pk, ref ctx) => {
626                write!(f, "Pubkey error: {} under {} scriptcontext", pk, ctx)
627            }
628            Error::MultiATooManyKeys(k) => write!(f, "MultiA too many keys {}", k),
629            Error::TaprootSpendInfoUnavialable => write!(f, "Taproot Spend Info not computed."),
630            Error::TrNoScriptCode => write!(f, "No script code for Tr descriptors"),
631            Error::TrNoExplicitScript => write!(f, "No script code for Tr descriptors"),
632            Error::MultipathDescLenMismatch => write!(f, "At least two BIP389 key expressions in the descriptor contain tuples of derivation indexes of different lengths"),
633        }
634    }
635}
636
637#[cfg(feature = "std")]
638impl error::Error for Error {
639    fn cause(&self) -> Option<&dyn error::Error> {
640        use self::Error::*;
641
642        match self {
643            InvalidOpcode(_)
644            | NonMinimalVerify(_)
645            | InvalidPush(_)
646            | CmsTooManyKeys(_)
647            | MultiATooManyKeys(_)
648            | Unprintable(_)
649            | ExpectedChar(_)
650            | UnexpectedStart
651            | Unexpected(_)
652            | MultiColon(_)
653            | MultiAt(_)
654            | AtOutsideOr(_)
655            | LikelyFalse
656            | UnknownWrapper(_)
657            | NonTopLevel(_)
658            | Trailing(_)
659            | MissingHash(_)
660            | MissingSig(_)
661            | RelativeLocktimeNotMet(_)
662            | AbsoluteLocktimeNotMet(_)
663            | CouldNotSatisfy
664            | TypeCheck(_)
665            | BadDescriptor(_)
666            | MaxRecursiveDepthExceeded
667            | ScriptSizeTooLarge
668            | NonStandardBareScript
669            | ImpossibleSatisfaction
670            | BareDescriptorAddr
671            | TaprootSpendInfoUnavialable
672            | TrNoScriptCode
673            | TrNoExplicitScript
674            | MultipathDescLenMismatch => None,
675            Script(e) => Some(e),
676            AddrError(e) => Some(e),
677            BadPubkey(e) => Some(e),
678            Secp(e) => Some(e),
679            #[cfg(feature = "compiler")]
680            CompilerError(e) => Some(e),
681            PolicyError(e) => Some(e),
682            LiftError(e) => Some(e),
683            ContextError(e) => Some(e),
684            AnalysisError(e) => Some(e),
685            PubKeyCtxError(e, _) => Some(e),
686        }
687    }
688}
689
690#[doc(hidden)]
691impl<Pk, Ctx> From<miniscript::types::Error<Pk, Ctx>> for Error
692where
693    Pk: MiniscriptKey,
694    Ctx: ScriptContext,
695{
696    fn from(e: miniscript::types::Error<Pk, Ctx>) -> Error {
697        Error::TypeCheck(e.to_string())
698    }
699}
700
701#[doc(hidden)]
702impl From<policy::LiftError> for Error {
703    fn from(e: policy::LiftError) -> Error {
704        Error::LiftError(e)
705    }
706}
707
708#[doc(hidden)]
709impl From<miniscript::context::ScriptContextError> for Error {
710    fn from(e: miniscript::context::ScriptContextError) -> Error {
711        Error::ContextError(e)
712    }
713}
714
715#[doc(hidden)]
716impl From<miniscript::analyzable::AnalysisError> for Error {
717    fn from(e: miniscript::analyzable::AnalysisError) -> Error {
718        Error::AnalysisError(e)
719    }
720}
721
722#[doc(hidden)]
723impl From<bellscoin::secp256k1::Error> for Error {
724    fn from(e: bellscoin::secp256k1::Error) -> Error {
725        Error::Secp(e)
726    }
727}
728
729#[doc(hidden)]
730impl From<bellscoin::address::Error> for Error {
731    fn from(e: bellscoin::address::Error) -> Error {
732        Error::AddrError(e)
733    }
734}
735
736#[doc(hidden)]
737#[cfg(feature = "compiler")]
738impl From<crate::policy::compiler::CompilerError> for Error {
739    fn from(e: crate::policy::compiler::CompilerError) -> Error {
740        Error::CompilerError(e)
741    }
742}
743
744#[doc(hidden)]
745impl From<policy::concrete::PolicyError> for Error {
746    fn from(e: policy::concrete::PolicyError) -> Error {
747        Error::PolicyError(e)
748    }
749}
750
751fn errstr(s: &str) -> Error {
752    Error::Unexpected(s.to_owned())
753}
754
755/// The size of an encoding of a number in Script
756pub fn script_num_size(n: usize) -> usize {
757    match n {
758        n if n <= 0x10 => 1,      // OP_n
759        n if n < 0x80 => 2,       // OP_PUSH1 <n>
760        n if n < 0x8000 => 3,     // OP_PUSH2 <n>
761        n if n < 0x800000 => 4,   // OP_PUSH3 <n>
762        n if n < 0x80000000 => 5, // OP_PUSH4 <n>
763        _ => 6,                   // OP_PUSH5 <n>
764    }
765}
766
767/// Returns the size of the smallest push opcode used to push a given number of bytes onto the stack
768///
769/// For sizes ≤ 75, there are dedicated single-byte opcodes, so the push size is one. Otherwise,
770/// if the size can fit into 1, 2 or 4 bytes, we use the `PUSHDATA{1,2,4}` opcode respectively,
771/// followed by the actual size encoded in that many bytes.
772fn push_opcode_size(script_size: usize) -> usize {
773    if script_size < 76 {
774        1
775    } else if script_size < 0x100 {
776        2
777    } else if script_size < 0x10000 {
778        3
779    } else {
780        5
781    }
782}
783
784/// Helper function used by tests
785#[cfg(test)]
786fn hex_script(s: &str) -> bellscoin::ScriptBuf {
787    let v: Vec<u8> = bellscoin::hashes::hex::FromHex::from_hex(s).unwrap();
788    bellscoin::ScriptBuf::from(v)
789}
790
791/// An absolute locktime that implements `Ord`.
792#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
793pub struct AbsLockTime(absolute::LockTime);
794
795impl AbsLockTime {
796    /// Constructs an `AbsLockTime` from an nLockTime value or the argument to OP_CHEKCLOCKTIMEVERIFY.
797    pub fn from_consensus(n: u32) -> Self {
798        Self(absolute::LockTime::from_consensus(n))
799    }
800
801    /// Returns the inner `u32` value. This is the value used when creating this `LockTime`
802    /// i.e., `n OP_CHECKLOCKTIMEVERIFY` or nLockTime.
803    ///
804    /// This calls through to `absolute::LockTime::to_consensus_u32()` and the same usage warnings
805    /// apply.
806    pub fn to_consensus_u32(self) -> u32 {
807        self.0.to_consensus_u32()
808    }
809
810    /// Returns the inner `u32` value.
811    ///
812    /// Equivalent to `AbsLockTime::to_consensus_u32()`.
813    pub fn to_u32(self) -> u32 {
814        self.to_consensus_u32()
815    }
816}
817
818impl From<absolute::LockTime> for AbsLockTime {
819    fn from(lock_time: absolute::LockTime) -> Self {
820        Self(lock_time)
821    }
822}
823
824impl From<AbsLockTime> for absolute::LockTime {
825    fn from(lock_time: AbsLockTime) -> absolute::LockTime {
826        lock_time.0
827    }
828}
829
830impl cmp::PartialOrd for AbsLockTime {
831    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
832        Some(self.cmp(other))
833    }
834}
835
836impl cmp::Ord for AbsLockTime {
837    fn cmp(&self, other: &Self) -> cmp::Ordering {
838        let this = self.0.to_consensus_u32();
839        let that = other.0.to_consensus_u32();
840        this.cmp(&that)
841    }
842}
843
844impl fmt::Display for AbsLockTime {
845    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
846        fmt::Display::fmt(&self.0, f)
847    }
848}
849
850#[cfg(test)]
851mod tests {
852    use core::str::FromStr;
853
854    use super::*;
855
856    #[test]
857    fn regression_bitcoin_key_hash() {
858        use bellscoin::PublicKey;
859
860        // Uncompressed key.
861        let pk = PublicKey::from_str(
862            "042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133"
863        ).unwrap();
864
865        let want = hash160::Hash::from_str("ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a").unwrap();
866        let got = pk.to_pubkeyhash(SigType::Ecdsa);
867        assert_eq!(got, want)
868    }
869
870    #[test]
871    fn regression_secp256k1_key_hash() {
872        use bellscoin::secp256k1::PublicKey;
873
874        // Compressed key.
875        let pk = PublicKey::from_str(
876            "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
877        )
878        .unwrap();
879
880        let want = hash160::Hash::from_str("9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4").unwrap();
881        let got = pk.to_pubkeyhash(SigType::Ecdsa);
882        assert_eq!(got, want)
883    }
884
885    #[test]
886    fn regression_xonly_key_hash() {
887        use bellscoin::secp256k1::XOnlyPublicKey;
888
889        let pk = XOnlyPublicKey::from_str(
890            "cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115",
891        )
892        .unwrap();
893
894        let want = hash160::Hash::from_str("eb8ac65f971ae688a94aeabf223506865e7e08f2").unwrap();
895        let got = pk.to_pubkeyhash(SigType::Schnorr);
896        assert_eq!(got, want)
897    }
898}
899
900#[allow(unused_imports)] // this is an internal prelude module; not all imports are used with every feature combination
901mod prelude {
902    // Mutex implementation from LDK
903    // https://github.com/lightningdevkit/rust-lightning/blob/9bdce47f0e0516e37c89c09f1975dfc06b5870b1/lightning-invoice/src/sync.rs
904    #[cfg(all(not(feature = "std"), not(test)))]
905    mod mutex {
906        use core::cell::{RefCell, RefMut};
907        use core::ops::{Deref, DerefMut};
908
909        pub type LockResult<Guard> = Result<Guard, ()>;
910
911        /// `Mutex` is not a real mutex as it cannot be used in a multi-threaded
912        /// context. `Mutex` is a dummy implementation of [`std::sync::Mutex`]
913        /// for `no_std` environments.
914        pub struct Mutex<T: ?Sized> {
915            inner: RefCell<T>,
916        }
917
918        #[must_use = "if unused the Mutex will immediately unlock"]
919        pub struct MutexGuard<'a, T: ?Sized + 'a> {
920            lock: RefMut<'a, T>,
921        }
922
923        impl<T: ?Sized> Deref for MutexGuard<'_, T> {
924            type Target = T;
925
926            fn deref(&self) -> &T {
927                &self.lock.deref()
928            }
929        }
930
931        impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
932            fn deref_mut(&mut self) -> &mut T {
933                self.lock.deref_mut()
934            }
935        }
936
937        impl<T> Mutex<T> {
938            pub fn new(inner: T) -> Mutex<T> {
939                Mutex {
940                    inner: RefCell::new(inner),
941                }
942            }
943
944            pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
945                Ok(MutexGuard {
946                    lock: self.inner.borrow_mut(),
947                })
948            }
949        }
950    }
951
952    #[cfg(all(not(feature = "std"), not(test)))]
953    pub use alloc::{
954        borrow::{Borrow, Cow, ToOwned},
955        boxed::Box,
956        collections::{vec_deque::VecDeque, BTreeMap, BTreeSet, BinaryHeap},
957        rc, slice,
958        string::{String, ToString},
959        sync,
960        vec::Vec,
961    };
962    #[cfg(any(feature = "std", test))]
963    pub use std::{
964        borrow::{Borrow, ToOwned},
965        boxed::Box,
966        collections::{vec_deque::VecDeque, BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet},
967        string::{String, ToString},
968        sync,
969        sync::Mutex,
970        vec::Vec,
971    };
972
973    #[cfg(all(not(feature = "std"), not(test)))]
974    pub use hashbrown::{HashMap, HashSet};
975
976    #[cfg(all(not(feature = "std"), not(test)))]
977    pub use self::mutex::Mutex;
978}